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 ); } } }
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 ); }
static void AddParms( void ) { PARMPTR parm; PARMPTR prev_parm; SYM_HANDLE sym_handle; SYM_HANDLE prev_sym_handle; SYM_HANDLE new_sym_handle; TYPEPTR typ = NULL; int parm_count; id_hash_idx h; parm_list *parmlist; SYM_ENTRY new_sym; CurFunc->u.func.locals = SYM_NULL; CurFunc->u.func.parms = SYM_NULL; parmlist = NULL; prev_sym_handle = SYM_NULL; parm_count = 0; prev_parm = NULL; for( parm = ParmList; parm != NULL; parm = parm->next_parm ) { new_sym_handle = SYM_NULL; parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED; parm->sym.attribs.is_parm = true; h = parm->sym.info.hash; if( parm->sym.name[0] == '\0' ) { /* no name ==> ... */ parm->sym.sym_type = GetType( TYPE_DOT_DOT_DOT ); parm->sym.attribs.stg_class = SC_AUTO; } else if( parm->sym.sym_type == NULL ) { parm->sym.sym_type = TypeDefault(); parm->sym.attribs.stg_class = SC_AUTO; } else { /* go through ParmList again, looking for FLOAT parms change the name to ".P" and duplicate the symbol with type float and generate an assignment statement. */ typ = parm->sym.sym_type; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: if( CompFlags.strict_ANSI ) { parm->sym.sym_type = GetType( TYPE_INT ); } break; case TYPE_USHORT: if( CompFlags.strict_ANSI ) { #if TARGET_SHORT == TARGET_INT parm->sym.sym_type = GetType( TYPE_UINT ); #else parm->sym.sym_type = GetType( TYPE_INT ); #endif } break; case TYPE_FLOAT: memcpy( &new_sym, &parm->sym, sizeof( SYM_ENTRY ) ); new_sym.handle = CurFunc->u.func.locals; new_sym_handle = SymAdd( h, &new_sym ); CurFunc->u.func.locals = new_sym_handle; SymReplace( &new_sym, new_sym_handle ); parm->sym.name = ".P"; parm->sym.flags |= SYM_REFERENCED; parm->sym.sym_type = GetType( TYPE_DOUBLE ); break; default: break; } } sym_handle = SymAdd( h, &parm->sym ); if( new_sym_handle != SYM_NULL ) { TREEPTR tree; tree = ExprNode( VarLeaf( &new_sym, new_sym_handle ), OPR_EQUALS, RValue( VarLeaf( &parm->sym, sym_handle ) ) ); tree->op.u2.result_type = typ; tree->u.expr_type = typ; AddStmt( tree ); } 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_count; parmlist = NewParm( parm->sym.sym_type, parmlist ); } if( prev_parm != NULL ) { prev_parm->sym.handle = SYM_NULL; SymReplace( &prev_parm->sym, prev_sym_handle ); CMemFree( prev_parm ); } typ = CurFunc->sym_type; // TODO not following my scheme CurFunc->sym_type = FuncNode( typ->object, FLAG_NONE, MakeParmList( parmlist, ParmsToBeReversed( CurFunc->mods, NULL ) ) ); if( PrevProtoType != NULL ) { ChkProtoType(); } }
static void ParmDeclList( void ) /* process old style function definitions */ { TYPEPTR typ; PARMPTR parm; decl_state state; SYM_ENTRY sym; decl_info info; size_t len; while( CurToken != T_LEFT_BRACE ) { FullDeclSpecifier( &info ); if( info.stg == SC_NONE && info.typ == NULL ) { if( CurToken == T_ID ) { CErr2p( ERR_MISSING_DATA_TYPE, Buffer ); } } if( info.stg != SC_NONE && info.stg != SC_REGISTER ) { CErr1( ERR_INVALID_STG_CLASS_FOR_PARM ); info.stg = SC_NONE; } state = DECL_STATE_NONE; typ = info.typ; if( typ == NULL ) { state |= DECL_STATE_NOTYPE; typ = TypeDefault(); } if( info.stg == SC_NONE ) info.stg = SC_AUTO; for( ;; ) { if( CurToken == T_SEMI_COLON ) { Chk_Struct_Union_Enum( typ ); } else { sym.name = NULL; Declarator( &sym, info.mod, typ, state ); if( sym.name == NULL || sym.name[0] == '\0' ) { InvDecl(); } else { len = strlen( sym.name ) + 1; for( parm = ParmList; parm != NULL; parm = parm->next_parm ) { if( parm->sym.name != NULL ) { if( memcmp( parm->sym.name, sym.name, len ) == 0 ) { break; } } } if( parm == NULL ) { CErr2p( ERR_SYM_NOT_IN_PARM_LIST, sym.name ); } else if( parm->sym.sym_type != NULL ) { CErr2p( ERR_PARM_ALREADY_DECLARED, sym.name ); } else { ArgPromotion( &sym ); parm->sym.sym_type = sym.sym_type; parm->sym.attribs.stg_class = info.stg; } } CMemFree( sym.name ); } if( CurToken == T_SEMI_COLON ) { NextToken(); break; } if( CurToken == T_LEFT_BRACE ) { CErr1( ERR_MISSING_SEMICOLON ); break; } if( CurToken == T_EOF ) return; MustRecog( T_COMMA ); } } ReverseParms(); if( CurFunc->sym_type->u.fn.parms == NULL ) { CurFunc->flags |= SYM_OLD_STYLE_FUNC; AddParms(); } else { ChkParms(); } ParmList = NULL; if( VarParm( CurFunc ) ) { CurFunc->flags &= ~ SYM_OK_TO_RECURSE; } }