/* Return the size of function parameters or -1 if size could * not be determined (symbol isn't a function or is variadic) */ static unsigned GetParmsSize( SYM_HANDLE sym_handle ) { unsigned total_parm_size = 0; unsigned parm_size; TYPEPTR fn_typ; TYPEPTR *parm_types; TYPEPTR typ; SYM_ENTRY sym; SymGet( &sym, sym_handle ); fn_typ = sym.sym_type; SKIP_TYPEDEFS( fn_typ ); if( fn_typ->decl_type == TYPE_FUNCTION ) { if( fn_typ->u.fn.parms != NULL ) { for( parm_types = fn_typ->u.fn.parms; (typ = *parm_types) != NULL; ++parm_types ) { if( typ->decl_type == TYPE_DOT_DOT_DOT ) { total_parm_size = (unsigned)-1; break; } SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_VOID ) break; parm_size = _RoundUp( TypeSize( typ ), TARGET_INT ); total_parm_size += parm_size; } } } else { total_parm_size = (unsigned)-1; } return( total_parm_size ); }
static void ChkParms( void ) { PARMPTR parm; PARMPTR prev_parm; SYM_HANDLE sym_handle; SYM_HANDLE prev_sym_handle; TYPEPTR typ; CurFunc->u.func.locals = SYM_NULL; CurFunc->u.func.parms = SYM_NULL; typ = *(CurFunc->sym_type->u.fn.parms); SKIP_TYPEDEFS( typ ); if( typ->decl_type != TYPE_VOID ) { prev_sym_handle = SYM_NULL; prev_parm = NULL; for( parm = ParmList; parm != NULL; parm = parm->next_parm ) { if( parm->sym.name == NULL ) { parm->sym.name = ".J"; parm->sym.flags |= SYM_REFERENCED; } if( parm->sym.name[0] == '\0' ) { parm->sym.name = ".I"; InvDecl(); } if( parm->sym.sym_type == NULL ) { parm->sym.sym_type = TypeDefault(); } /* make sure name not already defined in this SymLevel */ sym_handle = SymAdd( parm->sym.info.hash, &parm->sym ); if( prev_parm == NULL ) { CurFunc->u.func.parms = sym_handle; } else { prev_parm->sym.handle = sym_handle; SymReplace( &prev_parm->sym, prev_sym_handle ); CMemFree( prev_parm ); } prev_parm = parm; prev_sym_handle = sym_handle; parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED; parm->sym.attribs.is_parm = true; } if( prev_parm != NULL ) { #if _CPU == 370 { SYM_ENTRY var_parm; if( VarParm( CurFunc ) ) { typ = ArrayNode( GetType( TYPE_CHAR ) ); typ->u.array->dimension = 160; sym_handle = GetNewSym( &var_parm, 'V', typ, SC_AUTO ); SymReplace( &var_parm, sym_handle ); prev_parm->sym.handle = sym_handle; } } #endif SymReplace( &prev_parm->sym, prev_sym_handle ); CMemFree( prev_parm ); } } }
static void ArgPromotion( SYMPTR sym ) { TYPEPTR typ; TYPEPTR arg_typ; AdjParmType( sym ); arg_typ = sym->sym_type; /* perform default argument promotions */ typ = arg_typ; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { #if 0 case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: #endif case TYPE_ENUM: arg_typ = GetType( TYPE_INT ); break; #if 0 case TYPE_USHORT: arg_typ = GetType( TYPE_UINT ); break; case TYPE_FLOAT: arg_typ = GetType( TYPE_DOUBLE ); break; #endif default: break; } }
static int SimpleStruct( TYPEPTR typ ) { FIELDPTR field; if( typ->decl_type == TYPE_UNION ) { return( 0 ); } for( field = typ->u.tag->u.field_list; field; ) { typ = field->field_type; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_UNION: if( SimpleUnion( typ ) ) { break; // go 1 deep to get by MFC examples } case TYPE_ARRAY: case TYPE_STRUCT: case TYPE_FIELD: case TYPE_UFIELD: return( 0 ); // give up on these default: break; } field = field->next_field; } return( 1 ); }
static bool ChkParmPromotion( TYPEPTR typ ) { SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_BOOL: case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: if( CompFlags.strict_ANSI ) { return( false ); } break; case TYPE_USHORT: #if TARGET_SHORT != TARGET_INT if( CompFlags.strict_ANSI ) { return( false ); } #endif break; case TYPE_FLOAT: return( false ); default: break; } return( true ); }
static TYPEPTR TrueType( TYPEPTR typ ) { TYPEPTR newtyp; if ( typ == NULL ) return typ; if( do_message_output ) { /* For human: smart typedef expansion. Stop before unnamed struct */ while( typ->decl_type == TYPE_TYPEDEF ) { newtyp = typ->object; if( newtyp->decl_type == TYPE_STRUCT || newtyp->decl_type == TYPE_UNION || newtyp->decl_type == TYPE_ENUM ) { if( *newtyp->u.tag->name == '\0' ) { break; } } typ = newtyp; } } else { if( !CompFlags.dump_prototypes ) { /* -zg, not -v */ SKIP_TYPEDEFS( typ ); } } return( typ ); }
TYPEPTR SkipTypeFluff( TYPEPTR typ ) { SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_ENUM ) { typ = typ->object; } return( typ ); }
local int CharArray( TYPEPTR typ ) { if( CurToken == T_STRING ) { SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_CHAR || typ->decl_type == TYPE_UCHAR ) { return( TRUE ); } } return( FALSE ); }
local int WCharArray( TYPEPTR typ ) { if( CurToken == T_STRING ) { SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_SHORT || typ->decl_type == TYPE_USHORT ) { return( 1 ); } } return( 0 ); }
static void ChkProtoType( void ) { TYPEPTR ret1; TYPEPTR ret2; TYPEPTR typ1; TYPEPTR typ2; typ1 = CurFunc->sym_type; SKIP_TYPEDEFS( typ1 ); ret1 = typ1->object; typ2 = PrevProtoType; SKIP_TYPEDEFS( typ2 ); ret2 = typ2->object; typ1->object = NULL; typ2->object = NULL; VerifyType( CurFunc->sym_type, PrevProtoType, CurFunc ); typ1->object = ret1; typ2->object = ret2; }
static cmp_type CompatibleStructs( TAGPTR tag1, TAGPTR tag2 ) { FIELDPTR field1; FIELDPTR field2; TYPEPTR typ1; TYPEPTR typ2; if( tag1 == tag2 ) return( OK ); if( tag1->size != tag2->size ) return( NO ); field1 = tag1->u.field_list; field2 = tag2->u.field_list; /* if either struct is undefined, let's be conservative */ if( (field1 == NULL) || (field2 == NULL) ) return( NO ); for( ;; ) { if( field1 == NULL ) break; if( field2 == NULL ) break; typ1 = field1->field_type; SKIP_TYPEDEFS( typ1 ); typ2 = field2->field_type; SKIP_TYPEDEFS( typ2 ); if( !IdenticalType( typ1, typ2 ) ) { if( ( typ1->decl_type == TYPE_STRUCT && typ2->decl_type == TYPE_STRUCT ) || ( typ1->decl_type == TYPE_UNION && typ2->decl_type == TYPE_UNION ) ) { if( CompatibleStructs( typ1->u.tag, typ2->u.tag ) != OK ) { return( NO ); } } else { /* 11-jul-90 */ return( NO ); } } field1 = field1->next_field; field2 = field2->next_field; } /* one list longer than other (possible with -zp4) */ if( field1 != NULL || field2 != NULL ) return( NO ); return( OK ); }
/* Check parameters of function that were called before a prototype was seen */ extern void ChkCallParms( void ) { call_list *nextcall; nextcall = CallNodeList; while( nextcall != NULL ) { call_list *next; TREEPTR callnode; TREEPTR callsite; SYM_ENTRY sym; TYPEPTR typ; callnode = nextcall->callnode; if( callnode != NULL ) { callsite = callnode->left; // point to OPR_FUNCNAME node SymGet( &sym, callsite->op.sym_handle ); typ = sym.sym_type; SKIP_TYPEDEFS( typ ); if( !(sym.flags & SYM_TEMP) ) SetDiagSymbol( &sym, callsite->op.sym_handle ); if( typ->u.fn.parms != NULL ) { TREEPTR parms; bool reverse; parms = callnode->right; reverse = ( ParmsToBeReversed( sym.attrib, NULL ) && ( parms != NULL ) ); if( reverse ) { parms = reverse_parms_tree( parms ); } CompareParms( typ->u.fn.parms, parms, &nextcall->src_loc ); if( reverse ) { reverse_parms_tree( parms ); } } else { // Unprototyped function called. Note that for indirect calls, there // is no symbol associated with the function and diagnostic information // is hence limited. SetErrLoc( &nextcall->src_loc ); if( sym.flags & SYM_TEMP ) { CWarn( WARN_NONPROTO_FUNC_CALLED_INDIRECT, ERR_NONPROTO_FUNC_CALLED_INDIRECT ); } else { CWarn( WARN_NONPROTO_FUNC_CALLED, ERR_NONPROTO_FUNC_CALLED, SymName( &sym, callsite->op.sym_handle ) ); } } if( !(sym.flags & SYM_TEMP) ) { SetDiagPop(); } } next = nextcall->next; CMemFree( nextcall ); nextcall = next; } }
static void ChkRetValue( void ) { TYPEPTR typ; typ = CurFunc->sym_type; typ = typ->object; SKIP_TYPEDEFS( typ ); if( typ->decl_type != TYPE_VOID ) { CWarn2p( WARN_MISSING_RETURN_VALUE, ERR_MISSING_RETURN_VALUE, CurFunc->name ); } }
static void SetFuncReturnNode( TREEPTR tree ) { TYPEPTR typ; typ = CurFunc->sym_type->object; tree->expr_type = typ; SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_STRUCT || typ->decl_type == TYPE_UNION ) { tree->right = LeafNode( OPR_NOP ); // place holder tree->right->expr_type = NULL; } }
local void InitStructVar( unsigned base, SYMPTR sym, SYM_HANDLE sym_handle, TYPEPTR typ) { TYPEPTR typ2; TREEPTR opnd; TREEPTR value; FIELDPTR field; TOKEN token; for( field = typ->u.tag->u.field_list; field; ) { token = CurToken; if( token == T_LEFT_BRACE ) NextToken(); //allow {}, and extra {expr}..} typ2 = field->field_type; SKIP_TYPEDEFS( typ2 ); if( CurToken == T_RIGHT_BRACE ) { value = IntLeaf( 0 ); } else { value = CommaExpr(); } opnd = VarLeaf( sym, sym_handle ); if( typ2->decl_type == TYPE_UNION ) { FIELDPTR ufield; ufield = typ2->u.tag->u.field_list; typ2 = ufield->field_type; SKIP_TYPEDEFS( typ2 ); } opnd = ExprNode( opnd, OPR_DOT, UIntLeaf( base + field->offset ) ); opnd->expr_type = typ2; opnd->op.result_type = typ2; AddStmt( AsgnOp( opnd, T_ASSIGN_LAST, value ) ); if( token == T_LEFT_BRACE ) MustRecog( T_RIGHT_BRACE ); if( CurToken == T_EOF ) break; field = field->next_field; if( field == NULL ) break; if( CurToken != T_RIGHT_BRACE ) { MustRecog( T_COMMA ); } } }
static void FuncDefn( SYMPTR sym ) { SYM_NAMEPTR sym_name; size_t sym_len; TYPEPTR typ; /* duplicate name in near space */ sym_name = SymName( sym, CurFuncHandle ); sym_len = strlen( sym_name ) + 1; sym->name = CMemAlloc( sym_len ); memcpy( sym->name, sym_name, sym_len ); if( sym->flags & SYM_DEFINED ) { CErr2p( ERR_SYM_ALREADY_DEFINED, sym->name ); } typ = sym->sym_type->object; /* get return type */ SKIP_TYPEDEFS( typ ); if( typ->decl_type != TYPE_VOID ) { if( TypeSize( typ ) == 0 ) { CErr2p( ERR_INCOMPLETE_TYPE, sym_name ); } } sym->flags |= SYM_DEFINED /* | SYM_REFERENCED */; if( (GenSwitches & NO_OPTIMIZATION) == 0 ) { sym->flags |= SYM_OK_TO_RECURSE; } if( sym->attribs.stg_class == SC_EXTERN || sym->attribs.stg_class == SC_FORWARD ) { sym->attribs.stg_class = SC_NONE; /* indicate exported function */ } CompFlags.external_defn_found = 1; if( Toggles & TOGGLE_CHECK_STACK ) sym->flags |= SYM_CHECK_STACK; if( !CompFlags.zu_switch_used ) { if( (sym->mods & FLAG_INTERRUPT) == FLAG_INTERRUPT ) { /* interrupt function */ TargetSwitches |= FLOATING_SS; /* force -zu switch on */ } else { TargetSwitches &= ~FLOATING_SS; /* turn it back off */ } } if( CMPLIT( CurFunc->name, "main" ) == 0 || CMPLIT( CurFunc->name, "wmain" ) == 0 ) { sym->mods &= ~MASK_LANGUAGES; // Turn off any language flags sym->mods |= LANG_WATCALL; // Turn on __watcall calling convention for main } SymReplace( sym, CurFuncHandle ); }
local void FuncDefn( SYMPTR sym ) { SYM_NAMEPTR sym_name; int sym_len; TYPEPTR typ; /* duplicate name in near space */ sym_name = SymName( sym, CurFuncHandle ); sym_len = far_strlen_plus1( sym_name ); sym->name = CMemAlloc( sym_len ); far_memcpy( sym->name, sym_name, sym_len ); if( sym->flags & SYM_DEFINED ) { CErr2p( ERR_SYM_ALREADY_DEFINED, sym->name ); /* 03-aug-88 */ } typ = sym->sym_type->object; /* get return type */ SKIP_TYPEDEFS( typ ); if( typ->decl_type != TYPE_VOID ) { /* 26-mar-91 */ if( TypeSize( typ ) == 0 ) { CErr( ERR_INCOMPLETE_TYPE, sym_name ); } } sym->flags |= /*SYM_REFERENCED | 18-jan-89 */ SYM_DEFINED; if( !(GenSwitches & NO_OPTIMIZATION) ) { sym->flags |= SYM_OK_TO_RECURSE; /* 25-sep-91 */ } if( sym->stg_class == SC_EXTERN || sym->stg_class == SC_FORWARD ) { sym->stg_class = SC_NULL; /* indicate exported function */ } CompFlags.external_defn_found = 1; if( Toggles & TOGGLE_CHECK_STACK ) sym->flags |= SYM_CHECK_STACK; if( !CompFlags.zu_switch_used ) { if( (sym->attrib & FLAG_INTERRUPT) == FLAG_INTERRUPT ) { /* interrupt function */ TargetSwitches |= FLOATING_SS; /* force -zu switch on */ } else { TargetSwitches &= ~FLOATING_SS; /* turn it back off */ } } if( strcmp( CurFunc->name, "main" ) == 0 || strcmp( CurFunc->name, "wmain" ) == 0 ) { sym->attrib &= ~FLAG_LANGUAGES; // Turn off any language flags sym->attrib |= LANG_WATCALL; // Turn on __watcall calling convention for main } SymReplace( sym, CurFuncHandle ); }
static void CompareParms( TYPEPTR *master, TREEPTR parms, bool reverse ) { TYPEPTR typ1; int parmno; TREEPTR parm; if( reverse ) { parms = reverse_parms_tree( parms ); } typ1 = *master++; if( typ1 != NULL ) { if( typ1->decl_type == TYPE_VOID ) { /* type func(void); */ typ1 = NULL; /* indicate no parms */ } } for( parmno = 1, parm = parms; ( typ1 != NULL ) && ( parm != NULL ); parm = parm->left, ++parmno ) { SKIP_TYPEDEFS( typ1 ); // TODO is crap needed or has it been done if( typ1->decl_type == TYPE_FUNCTION ) { typ1 = PtrNode( typ1, FLAG_NONE, SEG_CODE ); } else if( typ1->decl_type == TYPE_ARRAY ) { typ1 = PtrNode( typ1->object, FLAG_WAS_ARRAY, SEG_DATA ); } /* check compatibility of parms */ ParmAsgnCheck( typ1, parm, parmno, false ); typ1 = *master++; if( typ1 != NULL && typ1->decl_type == TYPE_DOT_DOT_DOT ) { typ1 = NULL; parm = NULL; break; } } if( typ1 != NULL || parm != NULL ) { /* should both be NULL now */ #if _CPU == 386 /* can allow wrong number of parms with -3s option */ if( !CompFlags.register_conventions ) { CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING ); } else { CErr1( ERR_PARM_COUNT_MISMATCH ); } #else CErr1( ERR_PARM_COUNT_MISMATCH ); #endif } if( reverse ) { reverse_parms_tree( parms ); } }
static int AsmPtrType( TYPEPTR typ, type_modifiers flags ) /********************************************************/ { SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_FUNCTION ) { return( AsmCodePtrType( flags ) ); } else if( flags & (FLAG_FAR|FLAG_HUGE) ) { return( SYM_DFAR ); } else if( flags & FLAG_NEAR ) { return( SYM_DNEAR ); } else if( TargetSwitches & BIG_DATA ) { return( SYM_DFAR ); } else { return( SYM_DNEAR ); } }
local void InitUnion( TYPEPTR typ, TYPEPTR ctyp ) { FIELDPTR field; TYPEPTR ftyp; field = typ->u.tag->u.field_list; for( ;; ) { // skip unnamed bit fields if( field == NULL ) break; // 12-nov-94 ftyp = field->field_type; SKIP_TYPEDEFS( ftyp ); if( field->name[0] != '\0' ) break; if( ftyp->decl_type == TYPE_STRUCT ) break; /* 03-feb-95 */ if( ftyp->decl_type == TYPE_UNION ) break; field = field->next_field; } InitStructUnion( typ, ctyp, field ); }
void VarDeclEquals( SYMPTR sym, SYM_HANDLE sym_handle ) { TYPEPTR typ; if( SymLevel == 0 || sym->stg_class == SC_STATIC ) { if( sym->flags & SYM_INITIALIZED ) { CErrSymName( ERR_VAR_ALREADY_INITIALIZED, sym, sym_handle ); } sym->flags |= SYM_INITIALIZED; CompFlags.initializing_data = 1; StaticInit( sym, sym_handle ); CompFlags.initializing_data = 0; } else { SymReplace( sym, sym_handle ); /* 31-aug-88 */ SrcLoc = TokenLoc; typ = sym->sym_type; SKIP_TYPEDEFS( typ ); /* 07-jun-89 check for { before checking for array,struct or union */ if( CurToken != T_LEFT_BRACE && typ->decl_type != TYPE_ARRAY ) { /* 27-jun-89 */ AddStmt( AsgnOp( VarLeaf( sym, sym_handle ), T_ASSIGN_LAST, CommaExpr() ) ); } else if( typ->decl_type == TYPE_ARRAY ) { if( CurToken == T_LEFT_BRACE && CompFlags.auto_agg_inits ) { InitArrayVar( sym, sym_handle, typ ); } else { AggregateVarDeclEquals( sym, sym_handle ); } } else if( typ->decl_type == TYPE_STRUCT || typ->decl_type == TYPE_UNION ) { if( CurToken == T_LEFT_BRACE && CompFlags.auto_agg_inits && SimpleStruct( typ ) ) { NextToken(); //T_LEFT_BRACE InitStructVar( 0, sym, sym_handle, typ ); NextToken(); //T_RIGHT_BRACE } else { AggregateVarDeclEquals( sym, sym_handle ); } } else { NextToken(); AddStmt( AsgnOp( VarLeaf( sym, sym_handle ), T_ASSIGN_LAST, CommaExpr() ) ); MustRecog( T_RIGHT_BRACE ); } } }
static void FixupC99MainReturn( SYM_HANDLE func_result, struct return_info *info ) { TREEPTR tree; TYPEPTR main_type; /* In C99 mode, return statement need not be explicit for main()... */ main_type = CurFunc->sym_type->object; SKIP_TYPEDEFS( main_type ); /* ... as long as return type is compatible with int */ if( main_type->decl_type == TYPE_INT ) { tree = IntLeaf( 0 ); /* zero is the default return value */ tree = ExprNode( 0, OPR_RETURN, tree ); tree->expr_type = main_type; tree->op.sym_handle = func_result; AddStmt( tree ); info->with_expr = TRUE; } }
static int SimpleUnion( TYPEPTR typ ) { FIELDPTR field; field = typ->u.tag->u.field_list; typ = field->field_type; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_ARRAY: case TYPE_STRUCT: case TYPE_UNION: case TYPE_FIELD: case TYPE_UFIELD: return( 0 ); // give up on these default: break; } return( 1 ); }
static int ChkParmPromotion( TYPEPTR *plist, int topLevelCheck ) /* 25-nov-94 */ { TYPEPTR typ; int parm_count; parm_count = 1; for( ;; ) { typ = *plist++; if( typ == NULL ) break; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: if( CompFlags.strict_ANSI ) { if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); } break; case TYPE_USHORT: #if TARGET_SHORT != TARGET_INT if( CompFlags.strict_ANSI ) { if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); } #endif break; case TYPE_FLOAT: if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); default: break; } } return( TC_OK ); }
static void ReturnStmt( SYM_HANDLE func_result, struct return_info *info ) { TREEPTR tree; BLOCKPTR block; enum return_with with; NextToken(); if( CurToken != T_SEMI_COLON ) { TYPEPTR func_type; func_type = CurFunc->sym_type->object; SKIP_TYPEDEFS( func_type ); tree = RValue( Expr() ); ChkRetType( tree ); tree = BoolConv( func_type, tree ); tree = FixupAss( tree, func_type ); tree = ExprNode( 0, OPR_RETURN, tree ); tree->expr_type = func_type; tree->op.sym_handle = func_result; AddStmt( tree ); with = RETURN_WITH_EXPR; info->with_expr = TRUE; } else { with = RETURN_WITH_NO_EXPR; } if( info->with == RETURN_WITH_NONE ) { info->with = with; } if( info->with != with ) { CErr1( ERR_INCONSISTENT_USE_OF_RETURN ); } block = BlockStack; /* 16-apr-94 */ while( block != NULL ) { if( (block->block_type == T__TRY) || (block->block_type == T___TRY) ) break; block = block->prev_block; } if( block != NULL ) { UnWindTry( -1 ); } }
/* 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 ); } }
/* // does the specified symbol take variable parameters? manual search. */ bool VarParm( SYMPTR sym ) { TYPEPTR *parm_types; TYPEPTR typ; TYPEPTR fn_typ; if( sym == NULL ) return( FALSE ); if( sym->flags & SYM_FUNCTION ) { fn_typ = sym->sym_type; SKIP_TYPEDEFS( fn_typ ); if( fn_typ->u.fn.parms != NULL ) { for( parm_types = fn_typ->u.fn.parms; (typ = *parm_types) != NULL; ++parm_types ) { if( typ->decl_type == TYPE_DOT_DOT_DOT ) { return( TRUE ); } } } } return( FALSE ); }
/* // does the specified symbol take variable parameters? manual search. */ int VarParm( SYMPTR sym ) { TYPEPTR *parm; TYPEPTR typ; TYPEPTR fn_typ; if( sym == NULL ) return( 0 ); if( sym->flags & SYM_FUNCTION ) { fn_typ = sym->sym_type; SKIP_TYPEDEFS( fn_typ ); parm = fn_typ->u.fn.parms; if( parm != NULL ) { for( ; (typ = *parm); ++parm ) { if( typ->decl_type == TYPE_DOT_DOT_DOT ) { return( 1 ); } } } } return( 0 ); }
local int AsmType( TYPEPTR typ, type_modifiers flags ) /****************************************************/ { SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_STRUCT: case TYPE_UNION: return( SYM_INT1 ); case TYPE_ARRAY: return( AsmType( typ->object, flags ) ); case TYPE_FIELD: case TYPE_UFIELD: return( AsmDataType[typ->u.f.field_type] ); case TYPE_FUNCTION: return( AsmCodePtrType( flags ) ); case TYPE_POINTER: return( AsmPtrType( typ->object, typ->u.p.decl_flags ) ); case TYPE_ENUM: typ = typ->object; /* fall through */ default: return( AsmDataType[typ->decl_type] ); } }
void InitSymData( TYPEPTR typ, TYPEPTR ctyp, int level ) { TOKEN token; unsigned long size; SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_ENUM ) typ = typ->object; /* 07-nov-90 */ token = CurToken; if( CurToken == T_LEFT_BRACE ) { NextToken(); if( CurToken == T_RIGHT_BRACE || CurToken == T_COMMA ) { CErr1( ERR_EMPTY_INITIALIZER_LIST ); } } size = SizeOfArg( typ ); switch( typ->decl_type ) { case TYPE_ARRAY: if( CharArray( typ->object ) ) { InitCharArray( typ ); } else if( WCharArray( typ->object ) ) { InitWCharArray( typ ); } else { if( token == T_LEFT_BRACE ) { ctyp = typ; } else if( level == 0 ) { CErr1( ERR_NEED_BRACES ); } if( typ == ctyp ) { /* initialize new current type */ /* first zero out the whole array; otherwise overlapping fields caused by designated initializers will make life very difficult */ ZeroBytes( size ); RelSeekBytes( -size ); } InitArray( typ, ctyp ); } break; case TYPE_FCOMPLEX: case TYPE_DCOMPLEX: case TYPE_LDCOMPLEX: case TYPE_STRUCT: if( token == T_LEFT_BRACE ) { ctyp = typ; } else if( level == 0 ) { CErr1( ERR_NEED_BRACES ); } if( typ == ctyp ) { /* initialize new current type */ /* zero out all fields; otherwise overlapping fields caused by designated initializers will make life very difficult */ ZeroBytes( size ); RelSeekBytes( -size ); } InitStruct( typ, ctyp ); break; case TYPE_UNION: if( token == T_LEFT_BRACE ) { ctyp = typ; } else if( level == 0 ) { CErr1( ERR_NEED_BRACES ); } InitUnion( typ, ctyp ); break; case TYPE_CHAR: case TYPE_UCHAR: case TYPE_BOOL: case TYPE_SHORT: case TYPE_USHORT: case TYPE_INT: case TYPE_UINT: case TYPE_LONG: case TYPE_ULONG: case TYPE_POINTER: StorePointer( typ, size ); break; case TYPE_LONG64: case TYPE_ULONG64: StoreInt64( typ ); break; case TYPE_FLOAT: case TYPE_DOUBLE: case TYPE_FIMAGINARY: case TYPE_DIMAGINARY: StoreFloat( typ->decl_type, size ); break; case TYPE_LONG_DOUBLE: case TYPE_LDIMAGINARY: //StoreFloat( typ->decl_type, size ); StoreFloat( TYPE_DOUBLE, size ); break; default: break; } if( token == T_LEFT_BRACE ) { if( CurToken == T_COMMA ) { NextToken(); } if( CurToken != T_RIGHT_BRACE ) { CErr1( ERR_TOO_MANY_INITS ); } while( CurToken != T_RIGHT_BRACE ) { if( CurToken == T_EOF ) break; if( CurToken == T_SEMI_COLON )break; if( CurToken == T_LEFT_BRACE )break; NextToken(); } MustRecog( T_RIGHT_BRACE ); } }