cdecl2.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,744 行 · 第 1/5 页
C
1,744 行
/*
// Local variables in stack will be far when SS != DS (/zu)
// (applies only to auto vars, functions params are handled
// NOT here but in "cexpr.c" [OPR_PUSHADDR])
*/
if( TargetSwitches & FLOATING_SS ) {
sym->attrib |= FLAG_FAR;
}
}
/*
// static class variables can be thread local also
*/
if( (stg_class == SC_STATIC) && (sym->declspec == DECLSPEC_THREAD) ) { /* 06-JAN-03 */
if( !CompFlags.thread_data_present ) {
ThreadSeg = DefThreadSeg();
CompFlags.thread_data_present = 1;
}
sym->u.var.segment = ThreadSeg;
}
}
if( (Toggles & TOGGLE_UNREFERENCED) == 0 ) {
sym->flags |= SYM_IGNORE_UNREFERENCE; /* 25-apr-91 */
}
old_sym_handle = SymLook( sym->info.hash_value, sym->name );
if( old_sym_handle != 0 ) { /* 28-feb-94 */
SymGet( &old_sym, old_sym_handle );
if( old_sym.level == SymLevel ) {
SetDiagSymbol( &old_sym, old_sym_handle );
if( old_sym.stg_class == SC_EXTERN && stg_class == SC_EXTERN ) {
if( ! IdenticalType( old_sym.sym_type, sym->sym_type ) ) {
CErr2p( ERR_TYPE_DOES_NOT_AGREE, sym->name );
}
} else if( old_sym.stg_class == SC_TYPEDEF ) {
CErr2p( ERR_SYM_ALREADY_DEFINED, sym->name );
}
SetDiagPop();
}
}
if( stg_class == SC_EXTERN ) { /* 27-oct-88 */
old_sym_handle = Sym0Look( sym->info.hash_value, sym->name );
}
if( old_sym_handle != 0 ) {
SymGet( &old_sym, old_sym_handle );
SetDiagSymbol( &old_sym, old_sym_handle );
if( old_sym.level == SymLevel /* 28-mar-88 */
|| stg_class == SC_EXTERN ) { /* 12-dec-88 */
if( (sym->attrib & ATTRIB_MASK) !=
(old_sym.attrib & ATTRIB_MASK) ) {
CErr2p( ERR_MODIFIERS_DISAGREE, sym->name );
}
if( (sym->attrib & FLAG_LANGUAGES) != (old_sym.attrib & FLAG_LANGUAGES) ) {
// just inherit old lang flags
// if new != 0 then it's possible someone saw a different prototype
if( (sym->attrib & FLAG_LANGUAGES) != 0 ) {
CErr2p( ERR_MODIFIERS_DISAGREE, sym->name );
}
}
if( sym->declspec != old_sym.declspec ) {
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;
SetDiagSymbol( &old_sym, old_sym_handle );
/* verify that newly specified storage class doesn't conflict */
if( (stg_class == SC_NULL) || (stg_class == SC_STATIC) ) {
if( sym->stg_class == SC_EXTERN ) {
/* was extern, OK to change to none */
if( stg_class == SC_NULL ) {
sym->stg_class = stg_class; /* 03-oct-88 */
} else {
/* was extern, not OK to make static */
CErrSymName( ERR_STG_CLASS_DISAGREES, sym, sym_handle );
}
} else if( sym->stg_class == SC_STATIC && stg_class == SC_NULL ) {
/* was static, not OK to redefine */
CErrSymName( ERR_STG_CLASS_DISAGREES, sym, sym_handle );
} else if( sym->stg_class == SC_NULL && stg_class == SC_STATIC ) {
/* was extern linkage, not OK to to make static */
CErrSymName( ERR_STG_CLASS_DISAGREES, sym, sym_handle );
}
}
SetDiagPop();
} 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;
}
SKIP_TYPEDEFS( typ );
}
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 );
}
local void AdjSymTypeNode( SYMPTR sym, type_modifiers decl_mod )
{
TYPEPTR typ;
if( decl_mod ) {
typ = sym->sym_type;
if( typ->decl_type == TYPE_FUNCTION ) {
if( (sym->attrib & FLAG_LANGUAGES) != decl_mod ) {
if( sym->attrib & FLAG_LANGUAGES ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
sym->attrib |= decl_mod;
if( (typ->u.fn.decl_flags & FLAG_LANGUAGES) != decl_mod ) {
if( typ->u.fn.decl_flags & FLAG_LANGUAGES ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
sym->sym_type = FuncNode( typ->object, typ->u.fn.decl_flags | decl_mod, typ->u.fn.parms );
}
}
}
}
} else {
TYPEPTR *xtyp;
xtyp = &sym->sym_type;
while( ( typ->object != NULL ) && ( typ->decl_type == TYPE_POINTER ) ) {
xtyp = &typ->object;
typ = typ->object;
}
if( typ->decl_type == TYPE_FUNCTION ) {
if( (typ->u.fn.decl_flags & FLAG_LANGUAGES) != decl_mod ) {
if( typ->u.fn.decl_flags & FLAG_LANGUAGES ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
*xtyp = FuncNode( typ->object, typ->u.fn.decl_flags | decl_mod, typ->u.fn.parms );
}
}
} else {
if( sym->attrib & FLAG_LANGUAGES ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
sym->attrib |= decl_mod;
}
}
}
}
}
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;
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 */
SKIP_TYPEDEFS( typ );
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 */
SKIP_TYPEDEFS( otyp );
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;
AdjSymTypeNode( sym, info->decl_mod );
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 );
}
}
AdjSymTypeNode( sym, info->decl_mod );
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) ) {
if( TokenClass[ CurToken ] == TC_MODIFIER ) {
} else {
switch( CurToken ) {
case T_ID:
case T_LEFT_PAREN:
case T_TIMES:
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] );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?