cdinit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,580 行 · 第 1/4 页
C
1,580 行
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 */
}
}
local void AssignAggregate( TREEPTR lvalue, TREEPTR rvalue, TYPEPTR typ )
{
TREEPTR tree;
tree = ExprNode( lvalue, OPR_EQUALS, rvalue );
tree->right->op.opr = OPR_PUSHSYM;
tree->expr_type = typ;
tree->op.result_type = typ;
AddStmt( tree );
}
local void AggregateVarDeclEquals( SYMPTR sym, SYM_HANDLE sym_handle )
{
SYM_HANDLE sym2_handle;
SYM_ENTRY sym2;
sym2_handle = MakeNewSym( &sym2, 'X', sym->sym_type, SC_STATIC );
sym2.flags |= SYM_INITIALIZED;
CompFlags.initializing_data = 1;
StaticInit( &sym2, sym2_handle );
CompFlags.initializing_data = 0;
SymReplace( &sym2, sym2_handle );
/* StaticInit will change sym2.sym_type if it is an incomplete array type */
sym->sym_type = sym2.sym_type;
AssignAggregate( VarLeaf( sym, sym_handle ),
VarLeaf( &sym2, sym2_handle ), sym->sym_type );
}
local void InitStructVar( unsigned base, SYMPTR sym, SYM_HANDLE sym_handle, TYPEPTR typ)
{
TYPEPTR typ2;
TREEPTR opnd;
TREEPTR value;
FIELDPTR field;
int 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 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 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 );
}
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;
int 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 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 */
SrcLineNum = TokenLine; /* 15-mar-88 */
SrcFno = TokenFno;
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 );
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?