void AssignSeg( SYM_ENTRY *sym ) { SetFarHuge( sym, 1 ); if( (sym->stg_class == SC_AUTO) || (sym->stg_class == SC_REGISTER) || (sym->stg_class == SC_TYPEDEF) ) { /* if stack/register var, there is no segment */ sym->u.var.segment = 0; } else if( sym->stg_class != SC_EXTERN ) { /* if not imported */ if( (sym->flags & SYM_INITIALIZED) == 0 ) { if( sym->u.var.segment == 0 ) { /* 15-mar-92 */ SetSegment( sym ); } if( sym->u.var.segment == SEG_DATA ) { sym->u.var.segment = SEG_BSS; CompFlags.bss_segment_used = 1; } SetSegAlign( sym ); /* 02-feb-92 */ } } else if( sym->attrib & (FLAG_FAR | FLAG_HUGE) ) { sym->u.var.segment = SegImport; --SegImport; } else if( (SegData != 0) && (sym->attrib & FLAG_NEAR) ) { // imported and near sym->u.var.segment = SegData; } }
void AssignSeg( SYMPTR sym ) { SetFarHuge( sym, TRUE ); if( (sym->attribs.stg_class == SC_AUTO) || (sym->attribs.stg_class == SC_REGISTER) || (sym->attribs.stg_class == SC_TYPEDEF) ) { /* if stack/register var, there is no segment */ sym->u.var.segid = SEG_UNKNOWN; } else if( sym->attribs.stg_class != SC_EXTERN ) { /* if not imported */ if( (sym->flags & SYM_INITIALIZED) == 0 ) { if( sym->u.var.segid == SEG_UNKNOWN ) { SetSegment( sym ); } if( sym->u.var.segid == SEG_DATA ) { sym->u.var.segid = SEG_BSS; CompFlags.bss_segment_used = 1; } SetSegAlign( sym ); } } else if( sym->mods & (FLAG_FAR | FLAG_HUGE) ) { sym->u.var.segid = SegImport--; } else if( (SegData != SEG_UNKNOWN) && (sym->mods & FLAG_NEAR) ) { // imported and near sym->u.var.segid = SegData; } }
local void InitArrayVar( SYMPTR sym, SYM_HANDLE sym_handle, TYPEPTR typ ) { unsigned i; unsigned n; TYPEPTR typ2; SYM_HANDLE sym2_handle; SYM_ENTRY sym2; TREEPTR opnd; TREEPTR value; TOKEN token; typ2 = typ->object; SKIP_TYPEDEFS( typ2 ); switch( typ2->decl_type ) { case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: case TYPE_USHORT: case TYPE_INT: case TYPE_UINT: case TYPE_LONG: case TYPE_ULONG: case TYPE_LONG64: case TYPE_ULONG64: case TYPE_FLOAT: case TYPE_DOUBLE: case TYPE_POINTER: case TYPE_LONG_DOUBLE: case TYPE_FIMAGINARY: case TYPE_DIMAGINARY: case TYPE_LDIMAGINARY: case TYPE_BOOL: NextToken(); // skip over T_LEFT_BRACE if( CharArray( typ->object ) ) { sym2_handle = MakeNewSym( &sym2, 'X', typ, SC_STATIC ); sym2.flags |= SYM_INITIALIZED; if( sym2.u.var.segment == 0 ) { /* 01-dec-91 */ SetFarHuge( &sym2, 0 ); SetSegment( &sym2 ); SetSegAlign( &sym2 ); /* 02-feb-92 */ } SymReplace( &sym2, sym2_handle ); GenStaticDataQuad( sym2_handle ); InitCharArray( typ ); AssignAggregate( VarLeaf( sym, sym_handle ), VarLeaf( &sym2, sym2_handle ), typ ); } else if( WCharArray( typ->object ) ) { sym2_handle = MakeNewSym( &sym2, 'X', typ, SC_STATIC ); sym2.flags |= SYM_INITIALIZED; if( sym2.u.var.segment == 0 ) { /* 01-dec-91 */ SetFarHuge( &sym2, 0 ); SetSegment( &sym2 ); SetSegAlign( &sym2 ); /* 02-feb-92 */ } SymReplace( &sym2, sym2_handle ); GenStaticDataQuad( sym2_handle ); InitWCharArray( typ ); AssignAggregate( VarLeaf( sym, sym_handle ), VarLeaf( &sym2, sym2_handle ), typ ); } else { n = typ->u.array->dimension; i = 0; for( ;; ) { // accept some C++ { {1},.. } token = CurToken; if( token == T_LEFT_BRACE ) NextToken(); opnd = VarLeaf( sym, sym_handle ); value = CommaExpr(); opnd = ExprNode( opnd, OPR_INDEX, IntLeaf( i ) ); 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 ); ++i; if( CurToken == T_EOF ) break; if( CurToken == T_RIGHT_BRACE )break; MustRecog( T_COMMA ); if( CurToken == T_RIGHT_BRACE )break; if( i == n ) { CErr1( ERR_TOO_MANY_INITS ); } } if( typ->u.array->unspecified_dim ) { typ->u.array->dimension = i; } else { while( i < n ) { value = IntLeaf( 0 ); opnd = VarLeaf( sym, sym_handle ); opnd = ExprNode( opnd, OPR_INDEX, IntLeaf( i ) ); opnd->expr_type = typ2; opnd->op.result_type = typ2; AddStmt( AsgnOp( opnd, T_ASSIGN_LAST, value ) ); ++i; } } } MustRecog( T_RIGHT_BRACE ); break; case TYPE_FCOMPLEX: case TYPE_DCOMPLEX: case TYPE_LDCOMPLEX: case TYPE_STRUCT: case TYPE_UNION: if( SimpleStruct( typ2 ) ) { unsigned base; unsigned size; NextToken(); // skip over T_LEFT_BRACE n = typ->u.array->dimension; i = 0; base = 0; size = SizeOfArg( typ2 ); for( ;; ) { token = CurToken; if( token == T_LEFT_BRACE ) { NextToken(); } InitStructVar( base, sym, sym_handle, typ2 ); if( token == T_LEFT_BRACE ) { MustRecog( T_RIGHT_BRACE ); } ++i; if( CurToken == T_EOF ) break; if( CurToken == T_RIGHT_BRACE ) break; MustRecog( T_COMMA ); if( CurToken == T_RIGHT_BRACE ) break; if( i == n ) { CErr1( ERR_TOO_MANY_INITS ); } base += size; } if( typ->u.array->unspecified_dim ) { typ->u.array->dimension = i; } else { while( i < n ) { // mop up base += size; InitStructVar( base, sym, sym_handle, typ2 ); ++i; } } NextToken(); // skip over T_RIGHT_BRACE break; } default: AggregateVarDeclEquals( sym, sym_handle ); break; } }
void StaticInit( SYMPTR sym, SYM_HANDLE sym_handle ) { TYPEPTR typ; TYPEPTR struct_typ; TYPEPTR last_array; GenStaticDataQuad( sym_handle ); CompFlags.non_zero_data = 0; struct_typ = NULL; last_array = NULL; typ = sym->sym_type; /* Follow chain of typedefs/structs/arrays */ for( ;; ) { SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_ARRAY ) { /* Remember innermost array type */ last_array = typ; typ = typ->object; } else if( typ->decl_type == TYPE_STRUCT ) { FIELDPTR field; /* Remember outermost structure type */ if( struct_typ == NULL ) { /* last_array cannot to be outside this struct! */ last_array = NULL; struct_typ = typ; } /* Determine the type of the last field in the struct */ field = typ->u.tag->u.field_list; if( field == NULL ) break; /* 10-sep-92 */ while( field->next_field != NULL ) field = field->next_field; typ = field->field_type; } else { break; } } typ = last_array; /* If innermost array had unspecified dimension, create new types whose * dimensions will be determined by number of initializers */ if( (typ != NULL) && typ->u.array->unspecified_dim ) { if( struct_typ == NULL ) { /* Array was not inside struct */ sym->sym_type = ArrayNode( typ->object ); /* 18-oct-88 */ sym->sym_type->u.array->unspecified_dim = TRUE; } else { typ = sym->sym_type; /* Create new structure type */ sym->sym_type = TypeNode( TYPE_STRUCT, ArrayNode( last_array->object ) ); sym->sym_type->u.tag = struct_typ->u.tag; struct_typ = sym->sym_type; /* Create new array types as necessary */ for( ;; ) { SKIP_TYPEDEFS( typ ); if( typ->decl_type != TYPE_ARRAY ) break; sym->sym_type = ArrayNode( sym->sym_type ); sym->sym_type->u.array->unspecified_dim = TRUE; typ = typ->object; } typ = last_array; } } else { struct_typ = NULL; } SymReplace( sym, sym_handle ); /* 31-aug-88 */ InitSymData( sym->sym_type, sym->sym_type, 0 ); SymGet( sym, sym_handle ); /* 31-aug-88 */ if( struct_typ != NULL ) { /* 17-mar-92 */ /* Structure contains an unspecified length array as last field */ struct_typ->object->u.array->dimension = typ->u.array->dimension; typ->u.array->unspecified_dim = TRUE; typ->u.array->dimension = 0; /* Reset back to 0 */ } if( sym->u.var.segment == 0 ) { /* 01-dec-91 */ SetFarHuge( sym, 0 ); SetSegment( sym ); SetSegAlign( sym ); /* 02-feb-92 */ } }