void CppStackFini( void ) { struct cpp_info *cpp; while( (cpp = CppStack) != NULL ) { SetErrLoc( &cpp->src_loc ); CErr1( ERR_MISSING_CENDIF ); InitErrLoc(); CppStack = cpp->prev_cpp; CMemFree( cpp ); } CppStack = NULL; }
void SetFarHuge( SYMPTR sym, bool report ) { TYPEPTR typ; type_modifiers attrib; target_size size; #if _CPU != 8086 /* unused parameters */ (void)report; #endif #if _CPU == 8086 if( sym->attribs.declspec == DECLSPEC_DLLIMPORT || sym->attribs.declspec == DECLSPEC_DLLEXPORT ) { sym->mods |= FLAG_FAR; } else if( sym->mods & FLAG_EXPORT ) { sym->mods |= FLAG_FAR; } #endif size = SizeOfArg( sym->sym_type ); if( TargetSwitches & BIG_DATA ) { attrib = sym->mods; if( (attrib & MASK_ALL_MEM_MODELS) == 0 ) { if( size == 0 ) { /* unspecified array size */ if( sym->attribs.stg_class == SC_EXTERN ) { typ = sym->sym_type; if( typ->decl_type == TYPE_ARRAY ) { attrib |= FLAG_FAR; } } } else if( size > DataThreshold ) { attrib |= FLAG_FAR; } else if( CompFlags.strings_in_code_segment && ( sym->mods & FLAG_CONST ) ) { attrib |= FLAG_FAR; } #if _CPU == 8086 if( (attrib & FLAG_FAR) && size > 0x10000 ) { attrib &= ~FLAG_FAR; attrib |= FLAG_HUGE; } #endif sym->mods = attrib; } } #if _CPU == 8086 if( report && size > 0x10000 && (sym->mods & FLAG_HUGE) == 0 ) { SetErrLoc( &sym->src_loc ); CErr1( ERR_VAR_TOO_LARGE ); InitErrLoc(); } #endif }
void SetFarHuge( SYMPTR sym, int report ) { TYPEPTR typ; type_modifiers attrib; unsigned long size; report = report; /* in case not used */ #if _CPU == 8086 if( sym->declspec == DECLSPEC_DLLIMPORT || sym->declspec == DECLSPEC_DLLEXPORT ) { /* 16-dec-94 */ sym->attrib |= FLAG_FAR; } else if( sym->attrib & FLAG_EXPORT ) { sym->attrib |= FLAG_FAR; } #endif size = SizeOfArg( sym->sym_type ); if( TargetSwitches & BIG_DATA ) { attrib = sym->attrib; if( (attrib & MASK_ALL_MEM_MODELS) == 0 ) { if( size == 0 ) { /* unspecified array size */ if( sym->stg_class == SC_EXTERN ) { typ = sym->sym_type; if( typ->decl_type == TYPE_ARRAY ) { attrib |= FLAG_FAR; } } } else if( size > DataThreshold ) { attrib |= FLAG_FAR; } else if( CompFlags.strings_in_code_segment && ( sym->attrib & FLAG_CONST ) ) { attrib |= FLAG_FAR; } #if _CPU == 8086 if( (attrib & FLAG_FAR) && size > 0x10000 ) { attrib &= ~FLAG_FAR; attrib |= FLAG_HUGE; } #endif sym->attrib = attrib; } } #if _CPU == 8086 if( report && size > 0x10000 && !(sym->attrib & FLAG_HUGE) ) { SetErrLoc( &sym->src_loc ); CErr1( ERR_VAR_TOO_LARGE ); InitErrLoc(); } #endif }
/* Check parameters of function that were called before a prototype was seen */ extern void ChkCallParms( void ) { call_list *nextcall; call_list *next; for( nextcall = CallNodeList; nextcall != NULL; nextcall = next ) { TREEPTR callnode; TREEPTR callsite; SYM_ENTRY sym; TYPEPTR typ; next = nextcall->next; callnode = nextcall->callnode; if( callnode != NULL ) { callsite = callnode->left; // point to OPR_FUNCNAME node SymGet( &sym, callsite->op.u2.sym_handle ); typ = sym.sym_type; SKIP_TYPEDEFS( typ ); if( (sym.flags & SYM_TEMP) == 0 ) SetDiagSymbol( &sym, callsite->op.u2.sym_handle ); SetErrLoc( &nextcall->src_loc ); if( typ->u.fn.parms != NULL ) { CompareParms( typ->u.fn.parms, callnode->right, ParmsToBeReversed( sym.mods, NULL ) ); } else { // Unprototyped function called. Note that for indirect calls, there // is no symbol associated with the function and diagnostic information // is hence limited. if( sym.flags & SYM_TEMP ) { CWarn1( WARN_NONPROTO_FUNC_CALLED_INDIRECT, ERR_NONPROTO_FUNC_CALLED_INDIRECT ); } else { CWarn2p( WARN_NONPROTO_FUNC_CALLED, ERR_NONPROTO_FUNC_CALLED, SymName( &sym, callsite->op.u2.sym_handle ) ); } } InitErrLoc(); if( (sym.flags & SYM_TEMP) == 0 ) { SetDiagPop(); } } CMemFree( nextcall ); } }
void InitGlobalVars( void ) { PCH_Start = NULL; // start of precompiled memory block PCH_End = NULL; // end of precompiled memory block PCH_Macros = NULL; // macros loaded from pre-compiled header PCH_FileName = NULL; // name to use for pre-compiled header IncFileList = NULL; // list of primary include files for PCH PCH_SymArray = NULL; // array of symbol table pointers from PCH PCH_MaxSymHandle = 0; // number of symbols in PCH_SymArray DebugFlag = 0; CurToken = T_NULL; BadTokenInfo = 0; TokenLen = 0; TokenLoc.line = 0; TokenLoc.fno = 0; SrcFileLoc.line = 0; SrcFileLoc.fno = 0; CommentLoc.line = 0; CommentLoc.fno = 0; CurrChar = 0; ConstType = 0; Constant = 0; MainSrcFile = NULL; /* primary source file being compiled */ SrcFile = NULL; SrcFName = NULL; /* source file name without suffix */ DefFName = NULL; /* .def file name (prototypes) */ WholeFName = NULL; /* whole file name with suffix */ ForceInclude = NULL; #if _CPU == 370 AuxName = NULL; #endif FNames = NULL; /* list of file names processed */ ErrFile = NULL; /* error file */ DefFile = NULL; /* output for func prototypes */ CppFile = NULL; /* output for preprocessor */ CppStack = NULL; /* #if structure control stack */ IncPathList = NULL; /* list of path names to try for include files */ SrcLoc.line = 0; SrcLoc.fno = 0; SrcLineCount = 0; /* # of lines in primary source file */ IncLineCount = 0; /* # of lines in all included files */ ErrCount = 0; /* total # of errors encountered */ WngCount = 0; /* total # of warnings encountered */ WngLevel = 0; /* warning severity level */ TypeCount = 0; /* total # of type nodes allocated */ GblSymCount = 0; /* total # of global symbols */ LclSymCount = 0; /* total # of local and temporary symbols */ FuncCount = 0; /* total # of functions defined in module */ SizeOfCount = 0; /* # of nested sizeof() expressions */ SymLevel = 0; /* current lex level (# of nested {) */ HashValue = 0; /* hash value for identifier */ MacHashValue = 0; /* hash value for macro name */ SavedId = NULL; /* saved id when doing look ahead */ SavedHash = 0; /* hash value for saved id */ SavedTokenLoc.line = 0; /* value of TokenLine when id saved */ SavedTokenLoc.fno = 0; /* value of TokenFno when id saved */ LAToken = 0; /* look ahead token */ LabelHead = NULL; /* list of all labels defined in function */ TagHead = NULL; /* list of all struct, union, enum tags */ DeadTags = NULL; /* list of all tags that are out of scope */ CurFunc = NULL; /* current function being worked on */ ParmList = NULL; /* list of parms for function */ GlobalSym = SYM_NULL; /* global symbol table list head */ #if _CPU == 386 SymSTOD = SYM_NULL; /* builtin symbol for 'rep stosd' */ SymSTOSB = SYM_NULL; /* builtin symbol for '__STOSB' */ SymSTOSD = SYM_NULL; /* builtin symbol for '__STOSD' */ #endif #ifdef __SEH__ SymTryInit = SYM_NULL; /* builtin symbol for '__TryInit' */ SymTryFini = SYM_NULL; /* builtin symbol for '__TryFini' */ SymExcept = SYM_NULL; /* builtin symbol for '__Except' */ SymFinally = SYM_NULL; /* builtin symbol for '__Finally' */ SymTryUnwind = SYM_NULL; /* builtin symbol for '__TryUnwind' */ TrySymHandle = SYM_NULL; /* builtin symbol for local try block */ TryScope = 0; /* current scope of _try blocks */ TryCount = 0; /* current number of _try blocks */ #endif SymSTOW = SYM_NULL; /* builtin symbol for 'rep stosw' */ SymSTOWB = SYM_NULL; /* builtin symbol for 'rep stosw, stosb' */ SymMIN = SYM_NULL; /* builtin symbol for 'min(a,b)' */ SymMAX = SYM_NULL; /* builtin symbol for 'max(a,b)' */ SymMEMCMP = SYM_NULL; /* builtin symbol for 'memcmp' func */ SpecialSyms = SYM_NULL; /* builtin symbols (thread linked) */ CharSymHandle = SYM_NULL; /* sym handle for "char" typedef */ Sym_CS = SYM_NULL; /* sym handle for __segname("_CODE") ie. CS */ Sym_SS = SYM_NULL; /* sym handle for __segname("_STACK")ie. SS */ SymCover = SYM_NULL; /* sym handle for '__COVERAGE' */ SymDFAbbr = SYM_NULL; /* sym handle for '__DFABBREV' */ SymChipBug = SYM_NULL; /* sym handle for '__chipbug' */ ErrSym = NULL; #if _CPU == 386 FunctionProfileBlock = NULL; /* handle for profiling data block */ FunctionProfileSegment = SEG_UNKNOWN; /* segment for profiling data block */ #endif MacroDepth = 0; NextMacro = NULL; HashTab = NULL; GenSwitches = 0; /* target independant switches for code generator */ TargetSwitches = 0; /* target specific code generator switches */ ProcRevision = 0; /* processor revision for c.g. */ GenCodeGroup = NULL; /* pointer to code group name */ ProEpiDataSize = 0; /* data to be alloc'd for pro/epi hook */ Toggles = 0; /* global toggle flags */ ErrLimit = 0; DataThreshold = 0; /* sizeof(obj) > this ==> separate segment */ Inline_Threshold = 0; /* -oe=num for function inlining */ DataPtrSize = 0; CodePtrSize = 0; DeadCode = 0; /* non-zero => next stmt is unreachable */ TmpSymCount = 0; LitCount = 0; LitPoolSize = 0; MacroSize = 0; SegmentNum = 0; /* next PRIVATE segment number to use */ FarStringSegment = SEG_UNKNOWN; Environment = NULL; /* var for Suicide() */ /* The following 3 arrays are also used by CGEN for saving _try block info */ ExprLevel = 0; SegListHead = NULL; SegImport = SEG_UNKNOWN; /* next segment # for import sym */ SegData = SEG_UNKNOWN; /* data seg # for -nd option */ ScopeStruct = 0; ScopeUnion = 0; ScopeEnum = 0; B_Int_1 = 0; B_UInt_1 = 0; B_Short = 0; B_UShort = 0; B_Int = 0; B_UInt = 0; B_Int32 = 0; B_UInt32 = 0; B_Int64 = 0; B_UInt64 = 0; B_Bool = 0; OptSize = 0; /* 100 => make pgm small as possible */ MsgFlags = NULL; /* Bit mask of disabled messages */ MacSegList = NULL; /* pointer to list of macro segments */ LoopDepth = 0; /* current nesting of loop constructs */ HeadLibs = 0; /* list of library search records */ AliasHead = 0; /* list of symbol alias records */ CurFuncHandle = SYM_NULL; /* sym_handle for current function */ LastFuncOutOfMem = NULL; /* cinfo: */ HashFreeList = NULL; /* list of available hash entries */ SymBufSegNum = 0; /* segment # containing buffer */ StringType = NULL; /* "unsigned char *" for use by literals */ ConstCharType = NULL; /* "const char" type */ StringArrayType = NULL; /* "unsigned char []" used by literals */ NestedParms = NULL; TextSegName = NULL; /* name of the text segment */ DataSegName = NULL; /* name of the data segment */ CodeClassName = NULL; /* name of the code class */ ModuleName = NULL; /* name of module */ ObjectFileName = NULL; /* name of object file */ DependFileName = NULL; /* Name of make style auto depend file */ DependHeaderPath = NULL; /* If no path is part of an included file, use this*/ DependForceSlash = 0; PackAmount = 0; /* current packing alignment */ GblPackAmount = 0; /* packing alignment given on command line */ Column = 0; /* skip to Column when reading */ Trunc = 0; /* stop at Trunc when reading */ PrevProtoType = NULL; /* prev func prototype */ TargSys = TS_OTHER; DefDataSegment = SEG_UNKNOWN; /* #pragma data_seg("segname","class") */ DefCodeSegment = NULL; /* #pragma code_seg("seg","c") */ UnrollCount = 0; /* #pragma unroll(#); */ InitialMacroFlag = MFLAG_NONE; Stack87 = 0; ErrorFileName = NULL; UndefNames = NULL; Check_global_prototype = 0; memset( &CompFlags, 0, sizeof( CompFlags ) ); InitStmt(); InitErrLoc(); }
TYPEPTR EnumDecl( int flags ) { TYPEPTR typ; TAGPTR tag; flags = flags; NextToken(); if( CurToken == T_ID ) { /* could be: (1) "enum" <id> ";" (2) "enum" <id> <variable_name> ";" (3) "enum" <id> "{" <enum_const_decl> ... "}" */ tag = TagLookup(); NextToken(); if( CurToken != T_LEFT_BRACE ) { typ = tag->sym_type; if( typ == NULL ) { CErr1( ERR_INCOMPLETE_ENUM_DECL ); typ = TypeDefault(); } else { if( typ->decl_type != TYPE_ENUM ) { /* 18-jan-89 */ CErr2p( ERR_DUPLICATE_TAG, tag->name ); } typ->u.tag = tag; } return( typ ); } tag = VfyNewTag( tag, TYPE_ENUM ); } else { tag = NullTag(); } typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) ); typ->u.tag = tag; tag->sym_type = typ; tag->size = TARGET_INT; tag->u.enum_list = NULL; if( CurToken == T_LEFT_BRACE ) { const_val val; enum enum_rng index; enum enum_rng const_index; enum enum_rng start_index; enum enum_rng step; enum enum_rng error; uint64 n; uint64 Inc; bool minus; bool has_sign; ENUMPTR *prev_lnk; ENUMPTR esym; source_loc error_loc; char buff[50]; if( CompFlags.make_enums_an_int ) { start_index = ENUM_INT; } else { start_index = ENUM_S8; } const_index = ENUM_UNDEF; NextToken(); if( CurToken == T_RIGHT_BRACE ) { CErr1( ERR_EMPTY_ENUM_LIST ); } U32ToU64( 1, &Inc ); U64Clear( n ); minus = FALSE; has_sign = FALSE; step = 1; prev_lnk = &esym; esym = NULL; while( CurToken == T_ID ) { esym = EnumLkAdd( tag ); *prev_lnk = esym; prev_lnk = &esym->thread; error_loc = TokenLoc; NextToken(); if( CurToken == T_EQUAL ) { NextToken(); error_loc = TokenLoc; ConstExprAndType( &val ); switch( val.type ){ case TYPE_ULONG: case TYPE_UINT: case TYPE_ULONG64: minus = FALSE; break; default: if( val.value.u.sign.v ) { minus = TRUE; step = 2; } else { minus = FALSE; } break; } n = val.value; } else if( has_sign ) { if( n.u.sign.v ) { minus = TRUE; } else { minus = FALSE; } } for( index = start_index; index < ENUM_SIZE; index += step ) { if( minus ) { if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break; } else { if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break; } } error = ENUM_UNDEF; if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) { error = ENUM_INT; } if( index >= ENUM_SIZE ) { // overflow signed maximum range if( error == ENUM_UNDEF ) { error = const_index; } } else if(( const_index == ENUM_SIZE - 1 ) && minus ) { // overflow unsigned maximum range by any negative signed value if( error == ENUM_UNDEF ) error = const_index; step = 1; } else { if( !has_sign && minus) { has_sign = TRUE; if( index < const_index ) { // round up to signed index = ( const_index + 1 ) & ~1; } } if( index > const_index ) { const_index = index; typ->object = GetType( ItypeTable[const_index].decl_type ); tag->size = ItypeTable[const_index].size; } } if( error != ENUM_UNDEF ) { SetErrLoc( &error_loc ); get_msg_range( buff, error ); CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff ); InitErrLoc(); } esym->value = n; EnumTable[ esym->hash ] = esym; /* 08-nov-94 */ if( CurToken == T_RIGHT_BRACE ) break; U64Add( &n, &Inc, &n ); MustRecog( T_COMMA ); if( !CompFlags.extensions_enabled && !CompFlags.c99_extensions && ( CurToken == T_RIGHT_BRACE )) { ExpectIdentifier(); /* 13-may-91 */ } } MustRecog( T_RIGHT_BRACE ); } return( typ ); }
void Statement( void ) { LABEL_INDEX end_of_func_label; SYM_HANDLE func_result; TREEPTR tree; bool return_at_outer_level; bool skip_to_next_token; bool declaration_allowed; struct return_info return_info; SYM_ENTRY sym; #ifndef NDEBUG if( DebugFlag >= 1 ) { printf( "***** line %u, func=%s\n", TokenLoc.line, CurFunc->name ); PrintStats(); } #endif ++FuncCount; return_info.with = RETURN_WITH_NONE; /* indicate no return statements */ return_info.with_expr = FALSE; CompFlags.label_dropped = 0; CompFlags.addr_of_auto_taken = 0; /* 23-oct-91 */ end_of_func_label = 0; return_at_outer_level = FALSE; /* 28-feb-92 */ declaration_allowed = FALSE; DeadCode = 0; LoopDepth = 0; LabelIndex = 0; BlockStack = NULL; LoopStack = NULL; SwitchStack = NULL; #ifdef __SEH__ TryCount = -1; TryScope = -1; #endif StartNewBlock(); NextToken(); // skip over { ++SymLevel; tree = LeafNode( OPR_LABELCOUNT ); AddStmt( tree ); if( GrabLabels() == 0 ) { /* 29-nov-94 */ GetLocalVarDecls(); } func_result = MakeNewSym( &sym, 'R', CurFunc->sym_type->object, SC_AUTO ); sym.flags |= SYM_FUNC_RETURN_VAR; /* 25-oct-91 */ SymReplace( &sym, func_result ); for( ;; ) { CompFlags.pending_dead_code = 0; if( GrabLabels() == 0 && declaration_allowed && IsDeclarator( CurToken ) ) { GetLocalVarDecls(); } if( CompFlags.c99_extensions ) { declaration_allowed = TRUE; } skip_to_next_token = FALSE; switch( CurToken ) { case T_IF: StartNewBlock(); NextToken(); BlockStack->break_label = NextLabel(); JumpFalse( BracketExpr(), BlockStack->break_label ); /* 23-dec-88, only issue msg if ';' is on same line as 'if' */ if( CurToken == T_SEMI_COLON && SrcLoc.line == TokenLoc.line && SrcLoc.fno == TokenLoc.fno ) { SetErrLoc( &TokenLoc ); NextToken(); /* look ahead for else keyword */ if( CurToken != T_ELSE ) { /* 02-apr-91 */ ChkUseful(); /* 08-dec-88 */ } InitErrLoc(); break; } declaration_allowed = FALSE; continue; case T_WHILE: NewLoop(); NextToken(); BlockStack->break_label = NextLabel(); if( !JumpFalse( BracketExpr(), BlockStack->break_label ) ) { BlockStack->break_label = 0; /* 09-sep-92 */ } if( CurToken == T_SEMI_COLON ) { /* 08-dec-88 */ if( ! CompFlags.useful_side_effect ) { CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS ); } } declaration_allowed = FALSE; continue; case T_DO: NewLoop(); NextToken(); if( CurToken == T_RIGHT_BRACE ) { CErr1( ERR_STMT_REQUIRED_AFTER_DO ); break; } declaration_allowed = FALSE; continue; case T_FOR: ForStmt(); declaration_allowed = FALSE; continue; case T_SWITCH: SwitchStmt(); DeadCode = 1; declaration_allowed = FALSE; continue; case T_CASE: DeadCode = 0; CaseStmt(); declaration_allowed = FALSE; continue; case T_DEFAULT: DefaultStmt(); declaration_allowed = FALSE; continue; case T_BREAK: BreakStmt(); DeadCode = 1; if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; case T_CONTINUE: ContinueStmt(); DeadCode = 1; if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; #ifdef __SEH__ case T__LEAVE: case T___LEAVE: LeaveStmt(); DeadCode = 1; if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; #endif case T_RETURN: ReturnStmt( func_result, &return_info ); if( BlockStack->prev_block == NULL ) { /* 28-feb-92 */ return_at_outer_level = TRUE; } MustRecog( T_SEMI_COLON ); if( SymLevel != 1 || CurToken != T_RIGHT_BRACE || BlockStack->block_type != T_LEFT_BRACE ) { if( end_of_func_label == 0 ) { end_of_func_label = NextLabel(); } Jump( end_of_func_label ); } if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; case T_GOTO: GotoStmt(); if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; case T_SEMI_COLON: NextToken(); if( BlockStack->block_type != T_LEFT_BRACE ) { if( CurToken == T_ELSE ) { declaration_allowed = FALSE; } break; } continue; case T_LEFT_BRACE: LeftBrace(); continue; case T_RIGHT_BRACE: if( BlockStack->block_type != T_LEFT_BRACE ) { CErr1( ERR_MISPLACED_RIGHT_BRACE ); } if( BlockStack->prev_block == NULL ) { skip_to_next_token = TRUE; } else { NextToken(); } break; case T_EXTERN: case T_STATIC: case T_AUTO: case T_REGISTER: case T_VOID: case T_CHAR: case T_SHORT: case T_INT: case T_LONG: case T_FLOAT: case T_DOUBLE: case T_SIGNED: case T_UNSIGNED: if( CompFlags.c99_extensions ) CErr1( ERR_UNEXPECTED_DECLARATION ); else CErr1( ERR_MISSING_RIGHT_BRACE ); break; case T_EOF: CErr1( ERR_MISSING_RIGHT_BRACE ); break; #ifdef __SEH__ case T__TRY: case T___TRY: TryStmt(); continue; #endif case T___ASM: AsmStmt(); continue; default: if( DeadCode == 1 ) { DeadMsg(); } StmtExpr(); if( BlockStack->block_type != T_LEFT_BRACE ) break; continue; } EndOfStmt(); if( BlockStack == NULL ) break; if( skip_to_next_token ) { NextToken(); } } /* C99 has special semantics for return value of main() */ if( CompFlags.c99_extensions && !strcmp( CurFunc->name, "main" ) ) { if( !return_at_outer_level ) { FixupC99MainReturn( func_result, &return_info ); return_at_outer_level = TRUE; } } if( !return_info.with_expr ) { /* no return values present */ if( !DeadCode && !CurFunc->naked ) { ChkRetValue(); } } else if( ! return_at_outer_level ) { /* 28-feb-92 */ if( ! DeadCode && !CurFunc->naked ) { CWarn( WARN_MISSING_RETURN_VALUE, ERR_MISSING_RETURN_VALUE, CurFunc->name ); } } if( end_of_func_label != 0 ) { DropLabel( end_of_func_label ); } DeadCode = 0; tree->op.label_count = LabelIndex; tree = LeafNode( OPR_FUNCEND ); if( !return_info.with_expr ) { tree->expr_type = NULL; tree->op.sym_handle = 0; } else { tree->op.sym_handle = func_result; SetFuncReturnNode( tree ); } AddStmt( tree ); AddSymList( CurFunc->u.func.locals ); SrcLoc = TokenLoc; FreeLabels(); if( skip_to_next_token ) { NextToken(); } if( CompFlags.generate_prototypes ) { if( DefFile == NULL ) { OpenDefFile(); } if( DefFile != NULL && CurFunc->stg_class == SC_NULL ) { /* function exported */ DumpFuncDefn(); } } if( Toggles & TOGGLE_INLINE ) { if( Inline_Threshold < NodeCount ) { CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE; } } if( VarParm( CurFunc ) ) { CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE; } NodeCount = 0; if( CompFlags.addr_of_auto_taken ) { /* 23-oct-91 */ CurFunc->flags &= ~ SYM_OK_TO_RECURSE; } }
static void CompareParms( TYPEPTR *master, TREEPTR parm, source_loc *src_loc ) { TYPEPTR typ; TYPEPTR typ2; int parm_num; cmp_type cmp; typ = *master++; if( typ != NULL ) { /* 27-feb-90 */ if( typ->decl_type == TYPE_VOID ) { /* type func(void); */ typ = NULL; /* indicate no parms */ } } parm_num = 1; while( ( typ != NULL ) && ( parm != NULL ) ) { SKIP_TYPEDEFS( typ ); // TODO is crap needed or has it been done if( typ->decl_type == TYPE_FUNCTION ) { typ = PtrNode( typ, FLAG_NONE, SEG_CODE ); } else if( typ->decl_type == TYPE_ARRAY ) { typ = PtrNode( typ->object, FLAG_WAS_ARRAY, SEG_DATA ); } typ2 = parm->expr_type; // typ2 will be NULL if parm is OPR_ERROR in which case an error // has already been generated if( typ2 != NULL ) { /* check compatibility of parms */ SetErrLoc( src_loc ); SetDiagType2 ( typ2, typ ); cmp = CompatibleType( typ, typ2, TRUE, IsNullConst( parm ) ); switch( cmp ) { case NO: case PT: case PX: case AC: CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); break; case PQ: if( !CompFlags.no_check_qualifiers ) { // else f**k em CWarn2( WARN_QUALIFIER_MISMATCH, ERR_PARM_QUALIFIER_MISMATCH, parm_num ); } break; case PM: /* 16-may-91 */ CWarn2( WARN_POINTER_TYPE_MISMATCH, ERR_PARM_POINTER_TYPE_MISMATCH, parm_num ); break; case PS: CWarn2( WARN_SIGN_MISMATCH, ERR_PARM_SIGN_MISMATCH, parm_num ); break; case PW: CWarn2( WARN_PARM_INCONSISTENT_INDIRECTION_LEVEL, ERR_PARM_INCONSISTENT_INDIRECTION_LEVEL, parm_num ); break; case PC: /* Allow only "void *p = int 0"; */ if( IsPointer( typ ) && parm->right->op.opr == OPR_PUSHINT ) { if( TypeSize(typ) != TypeSize(typ2) ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); } else if( parm->right->op.ulong_value != 0 ) { CWarn1( WARN_NONPORTABLE_PTR_CONV, ERR_NONPORTABLE_PTR_CONV ); } } else { if( TypeSize(typ->object) == TypeSize(typ2->object) ) { CWarn2( WARN_POINTER_TYPE_MISMATCH, ERR_PARM_POINTER_TYPE_MISMATCH, parm_num ); } else { CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); } } break; case OK: break; } SetDiagPop(); InitErrLoc(); } typ = *master++; if( typ != NULL && typ->decl_type == TYPE_DOT_DOT_DOT ) return; parm = parm->left; ++parm_num; } if( typ != NULL || parm != NULL ) { /* should both be NULL now */ SetErrLoc( src_loc ); #if _CPU == 386 /* can allow wrong number of parms with -3s option; 06-dec-91 */ if( !CompFlags.register_conventions ) { CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING ); return; } #endif CErr1( ERR_PARM_COUNT_MISMATCH ); /* 18-feb-90 */ } }