⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecl2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                switch( sym->declspec ){
                case DECLSPEC_DLLIMPORT:
                case DECLSPEC_THREAD:
                    CErr2p( ERR_MODIFIERS_DISAGREE, sym->name );
                    break;
                case DECLSPEC_DLLEXPORT:
                    if( old_sym.declspec == DECLSPEC_DLLIMPORT ){
                        old_sym.declspec = DECLSPEC_DLLEXPORT;
                    }else{
                        CErr2p( ERR_MODIFIERS_DISAGREE, sym->name );
                    }
                    break;
                }
            }
        }
        SetDiagPop();
    }
    if( ( old_sym_handle != 0 )  &&
        ( stg_class == SC_NULL || stg_class == SC_EXTERN ||
          (stg_class == SC_STATIC  &&  SymLevel == 0 ) ) ) {

/*              make sure sym->sym_type same type as old_sym->sym_type */

        SetDiagSymbol( &old_sym, old_sym_handle );
        which = VerifyType( sym->sym_type, old_sym.sym_type, sym );
        SetDiagPop();
        if( which == 0 && old_sym.level == SymLevel ) { /* 06-jul-88 AFS */
            /* new symbol's type supersedes old type */
            old_sym.sym_type = sym->sym_type;
            if( (old_sym.flags & SYM_FUNCTION) ) {
                old_sym = *sym;  // ditch old sym
            }
            SymReplace( &old_sym, old_sym_handle );
        }
        if( stg_class == SC_EXTERN  &&  SymLevel != 0 ) goto new_var;
        CMemFree( sym->name );
        memcpy( sym, &old_sym, sizeof( SYM_ENTRY ) );
        sym_handle = old_sym_handle;
        if( stg_class == SC_NULL  ||  stg_class == SC_STATIC ) {
            if( sym->stg_class == SC_EXTERN ) {
                sym->stg_class = /*SC_NULL*/ stg_class; /* 03-oct-88 */
            } else if( sym->stg_class == SC_STATIC ) {
                if( stg_class == SC_NULL ) {
                    CErrSymName( ERR_STG_CLASS_DISAGREES, sym, sym_handle );
                }
            }
        }
    } else {
        if( stg_class == SC_EXTERN  &&  SymLevel != 0 ) {
            ; /* do nothing  29-jan-93 */
        } else {
            VfyNewSym( sym->info.hash_value, sym->name );
        }
new_var:
        old_sym_handle = 0;
        sym->flags |= SYM_DEFINED;
        typ = SkipDummyTypedef( sym->sym_type );        /* 25-nov-94 */
        if( typ->decl_type == TYPE_TYPEDEF ) {          /* 12-mar-92 */
            SymGet( &sym2, typ->u.typedefn );
            if( sym->u.var.segment == 0  &&  sym2.u.var.segment != 0 ) {
                sym->u.var.segment = sym2.u.var.segment;
            }
            while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        }
        if( typ->decl_type == TYPE_VOID ) {
            CErr2p( ERR_VAR_CANT_BE_VOID, sym->name );
            sym->sym_type = TypeDefault();
        }
        sym->stg_class = stg_class;
        sym_handle = SymAdd( sym->info.hash_value, sym );
    }
    if( sym->u.var.segment == 0  &&     /* 22-oct-92 */
    (stg_class == SC_STATIC ||
     stg_class == SC_NULL   ||
     stg_class == SC_EXTERN) ) {
        if( DefDataSegment != 0 ) {
            sym->u.var.segment = DefDataSegment;
            SymReplace( sym, sym_handle );
        }
    }
    if( CurToken == T_EQUAL ) {
        if( stg_class == SC_EXTERN ) {
            stg_class = SC_STATIC;
            if( SymLevel == 0 ) {
                CompFlags.external_defn_found = 1;
                stg_class = SC_NULL;
            } else {
                CErr1( ERR_CANT_INITIALIZE_EXTERN_VAR );
            }
        }
        sym->stg_class = stg_class;
        NextToken();
        VarDeclEquals( sym, sym_handle );
        sym->flags |=  SYM_ASSIGNED;
    }
    SymReplace( sym, sym_handle );                      /* 06-jul-88 */
    if( old_sym_handle != 0 ) sym_handle = 0;
    return( sym_handle );
}

static SYM_HANDLE InitDeclarator( SYMPTR sym,
                                  decl_info const * const info,
                                  decl_state *state )
{
    SYM_HANDLE  sym_handle;
    SYM_HANDLE  old_sym_handle;
    type_modifiers flags;
    TYPEPTR     typ;
    TYPEPTR     otyp;
    auto SYM_ENTRY old_sym;

    if( ParmList != NULL ) {
        FreeParmList();
    }
    memset( sym, 0, sizeof( SYM_ENTRY ) );              /* 02-apr-91 */
    sym->name = "";
    flags = TypeQualifier();                            /* 08-nov-94 */
    if( flags & info->mod ){
       CErr1( ERR_INV_TYPE );
    }
    flags |= info->mod;
    if( info->decl == DECLSPEC_DLLEXPORT ){
        flags |= FLAG_EXPORT; //need to get rid of this
    }
    Declarator( sym, flags, info->typ, *state );
    if( sym->name[0] == '\0' ) {
        InvDecl();
        return( 0 );
    }
    typ = sym->sym_type;
    /* skip over typedef's  29-aug-89 */
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( info->stg == SC_TYPEDEF ) {
        if( CompFlags.extensions_enabled ) {            /* 24-mar-91 */
            old_sym_handle = SymLook( sym->info.hash_value, sym->name );
            if( old_sym_handle != 0 ) {
                SymGet( &old_sym, old_sym_handle );
                otyp = old_sym.sym_type;        /* skip typedefs 25-sep-92 */
                while( otyp->decl_type == TYPE_TYPEDEF ) otyp = otyp->object;
                if( old_sym.stg_class == SC_TYPEDEF     &&
                    old_sym.level == SymLevel   &&
                    IdenticalType( typ, otyp ) ) {
                    return( 0 );        /* indicate already in symbol tab */
                }
            }
        }
        VfyNewSym( sym->info.hash_value, sym->name );
        sym->stg_class = info->stg;
        sym_handle = SymAdd( sym->info.hash_value, sym );
    } else {
        sym->declspec = info->decl;
        sym->naked = info->naked;
        if( sym->declspec == DECLSPEC_DLLEXPORT ){ //sync up flags
            sym->attrib |= FLAG_EXPORT; //need to get rid of this
        }else if( sym->attrib & FLAG_EXPORT ){
            if( sym->declspec == DECLSPEC_NONE ){
                sym->declspec = DECLSPEC_DLLEXPORT;
            }else if( sym->declspec  != DECLSPEC_DLLEXPORT ){
                 CErr1( ERR_INVALID_DECLSPEC );
            }
        }
        if( typ->decl_type == TYPE_FUNCTION ) {
            sym_handle = FuncDecl( sym, info->stg, state );
        } else {
            sym_handle = VarDecl( sym, info->stg, state );
        }
    }
    return( sym_handle );
}

int DeclList( SYM_HANDLE *sym_head )
{
    decl_state          state;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prevsym_handle;
    unsigned            line_num;
    auto SYM_ENTRY      sym;
    auto SYM_ENTRY      prevsym;
    decl_info           info;

    ParmList = NULL;
    prevsym_handle = 0;
    *sym_head = 0;
    for(;;) {
        for(;;) {
            for(;;) {
                while( CurToken == T_SEMI_COLON ) {
                    if( SymLevel == 0 ) {
                        if( !CompFlags.extensions_enabled ) {  /* 28-nov-94 */
                            CErr2p( ERR_EXPECTING_DECL_BUT_FOUND, ";" );
                        }
                    }
                    NextToken();
                }
                if( CurToken == T_EOF ) return( 0 );
                line_num = TokenLine;
                FullDeclSpecifier( &info );
                if( info.stg != SC_NULL  ||  info.typ != NULL )     break;
                if( SymLevel != 0 )  return( 0 );
                break;
            }
            state = DECL_STATE_NONE;
            if( info.typ == NULL ) {
                state |= DECL_STATE_NOTYPE;
                info.typ = TypeDefault();
            }
            if( info.stg == SC_NULL  && (state & DECL_STATE_NOTYPE) ) {
                switch( CurToken ) {
                case T_ID:
                case T_LEFT_PAREN:
                case T___EXPORT:
                case T___LOADDS:
                case T___NEAR:
                case T___FAR:
                case T___HUGE:
                case T___CDECL:
                case T___PASCAL:
                case T___FORTRAN:
                case T__SYSCALL:                        /* 04-jul-91 */
                case T___STDCALL:                       /* 03-feb-95 */
                case T___FASTCALL:
                case T___INTERRUPT:
                case T___SAVEREGS:
                case T_TIMES:                           /* 30-nov-94 */
                    break;
                case T_IF:
                case T_FOR:
                case T_WHILE:
                case T_DO:
                case T_SWITCH:
                case T_BREAK:
                case T_CONTINUE:
                case T_CASE:
                case T_DEFAULT:
                case T_ELSE:
                case T_GOTO:
                case T_RETURN:
                    FlushBadCode();
                    continue;
                default:
                    CErr2p( ERR_EXPECTING_DECL_BUT_FOUND, Tokens[CurToken] );
                    NextToken();
                    break;
                }
            }
            break;
        }
        if( CurToken != T_SEMI_COLON ) {
            if( info.decl == DECLSPEC_DLLIMPORT ) {
                if(!CompFlags.rent ){
                    if( info.stg == SC_NULL ) info.stg = SC_EXTERN;
                }
            }
            for( ;; ) {
                sym_handle = InitDeclarator( &sym, &info, &state );
                /* NULL is returned if sym already exists in symbol table */
                if( sym_handle != 0 ) {
                    sym.handle = 0;
                    if( (sym.flags & SYM_FUNCTION) ) {
                        if( !(state & DECL_STATE_NOTYPE ) ) {
                            sym.flags |= SYM_TYPE_GIVEN;
                        }
                    } else if( SymLevel > 0 ) { /* variable */
                        if( prevsym_handle != 0 ) {
                            SymGet( &prevsym, prevsym_handle );
                            prevsym.handle = sym_handle;
                            SymReplace( &prevsym, prevsym_handle );
                        }
                        if( *sym_head == 0 ) {
                            *sym_head = sym_handle;
                        }
                        prevsym_handle = sym_handle;
                    }
                    SymReplace( &sym, sym_handle );
                }
                /* case "int x *p" ==> missing ',' msg already given */
                if( CurToken != T_TIMES ) {
                    if( CurToken != T_COMMA ) break;
                    NextToken();
                }
            }
/*              the following is illegal:
                    typedef double math(double);
                    math sin { ; }
            That's the reason for the check
                    "typ->decl_type != TYPE_FUNCTION"
*/
            if( SymLevel == 0  &&  CurToken != T_SEMI_COLON
                               &&  sym_handle != 0 ) {
                if( sym.sym_type->decl_type == TYPE_FUNCTION
                    &&  sym.sym_type != info.typ ) { /* 21-mar-89 */
                    CurFuncHandle = sym_handle;
                    CurFunc = &CurFuncSym;
                    memcpy( CurFunc, &sym, sizeof( SYM_ENTRY ) );
                    return( 1 );        /* indicate this is a function defn */
                }
            }
            MustRecog( T_SEMI_COLON );
        } else {
            Chk_Struct_Union_Enum( info.typ );
            NextToken();                /* skip over ';' */
        }
    }
// can't get here!      return( 0 );
}


TYPEPTR TypeName()
{
    TYPEPTR     typ;
    decl_info   info;
    SYM_ENTRY   abs_sym;

    TypeSpecifier( &info );
    typ = info.typ;
    if( typ != NULL ) {
         memset( &abs_sym, 0, sizeof( SYM_ENTRY ) );
         abs_sym.name = "";
         AbsDecl( &abs_sym, info.mod, info.typ  );
         typ = abs_sym.sym_type;
    }
    return( typ );
}


local type_modifiers GetModifiers( void )
{
    type_modifiers        modifier;
    int                   hash;

    static type_modifiers const ModifierFlags[] = {
            0,
            FLAG_NEAR,          // TC_NEAR
            FLAG_FAR,           // TC_FAR
#if _CPU == 8086
            FLAG_HUGE,          // TC_HUGE
#else
            FLAG_FAR,            // TC_HUGE      // close
#endif

#if _CPU == 8086
            FLAG_FAR,           // TC_FAR16      // avoid giving error
#else
            FLAG_FAR16,         // TC_FAR16
#endif
            FLAG_INTERRUPT,     // TC_INTERRUPT
            LANG_CDECL,         // TC_CDECL
            LANG_PASCAL,        // TC_PASCAL
            LANG_FORTRAN,       // TC_FORTRAN
            LANG_SYSCALL,       // TC_SYSCALL           /* 04-jul-91 */
            LANG_STDCALL,       // TC_STDCALL
            LANG_FASTCALL,      // TC_FASTCALL
            LANG_OPTLINK,       // TC_OPTLINK
            FLAG_EXPORT,        // TC_EXPORT
            FLAG_LOADDS,        // TC_LOADDS
            FLAG_SAVEREGS,      // TC_SAVEREGS
    };

    modifier = 0;
    for(;;) {
        hash = TokenClass[ CurToken ];
        if( hash >= TC_MODIFIER ) break;        /* 04-jul-90, c/=/>=/ */
        modifier |= ModifierFlags[ hash ];
        NextToken();
    }
    return( modifier );
}

struct mod_info {
    int             segment;
    type_modifiers  modifier;  // const, vol flags
    BASED_KIND       based_kind;
    SYM_HANDLE       based_sym;
};

local TYPEPTR Pointer( TYPEPTR ptr_typ, struct mod_info *info )
{
    type_modifiers  flags;
    SYM_HANDLE      sym_handle;
    auto SYM_ENTRY  sym;

    sym_handle = 0;
    if( ptr_typ != NULL  &&  ptr_typ->decl_type == TYPE_TYPEDEF ) {
     // get segment from typedef TODO should be done sooner
        TYPEPTR typ;
        SYMPTR  symp;

        typ = SkipDummyTypedef( ptr_typ );              /* 25-nov-94 */
        if( typ->decl_type == TYPE_TYPEDEF ) {          /* 15-mar-92 */
            symp = SymGetPtr( typ->u.typedefn );
            if( info->modifier & FLAG_BASED ) {
                info->segment = symp->u.var.segment;
                sym_handle = SegSymHandle( info->segment );
            }
        }
    }
    for(;;) {
        flags = GetModifiers();   // NEAR FAR CDECL stuff

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -