📄 cdinit.c
字号:
dq.u.long_values[0] = value;
GenDataQuad( &dq );
++i;
}
if( i < size ) {
ZeroBytes( (size - i) * sizeof(unsigned short) );
}
FreeLiteral( str_lit );
}
local void StoreFloat( int float_type )
{
TREEPTR tree;
auto DATA_QUAD dq;
dq.opr = float_type;
dq.flags = Q_DATA;
dq.u.double_value = 0.0;
if( CurToken != T_RIGHT_BRACE ) {
tree = SingleExpr();
switch( tree->op.opr ) {
case OPR_PUSHINT:
if( tree->op.const_type == TYPE_ULONG ) {
dq.u.double_value = tree->op.ulong_value;
} else {
dq.u.double_value = tree->op.long_value;
}
break;
case OPR_PUSHFLOAT:
if( tree->op.float_value->len != 0 ) {
dq.u.double_value = atof( tree->op.float_value->string );
} else {
#ifdef _LONG_DOUBLE_
long_double ld;
ld = tree->op.float_value->ld;
__LDFD( (long_double near *)&ld,
(double near *)&dq.u.double_value );
#else
dq.u.double_value = tree->op.float_value->ld.value;
#endif
}
break;
default:
CErr1( ERR_NOT_A_CONSTANT_EXPR );
break;
}
FreeExprTree( tree );
if( dq.u.double_value != 0.0 ) CompFlags.non_zero_data = 1;
}
GenDataQuad( &dq );
}
local void GenStaticDataQuad( SYM_HANDLE sym_handle )
{
auto DATA_QUAD dq;
dq.opr = T_STATIC;
dq.flags = Q_DATA;
dq.u.var.sym_handle = sym_handle;
dq.u.var.offset = 0;
GenDataQuad( &dq );
}
void StaticInit( SYMPTR sym, SYM_HANDLE sym_handle )
{
TYPEPTR typ;
TYPEPTR struct_typ;
FIELDPTR field;
GenStaticDataQuad( sym_handle );
CompFlags.non_zero_data = 0;
struct_typ = NULL;
typ = sym->sym_type;
for(;;) {
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type != TYPE_STRUCT ) break; /* 17-mar-92 */
if( struct_typ == NULL ) struct_typ = typ;
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;
}
if( typ->decl_type == TYPE_ARRAY && TypeSize( typ ) == 0 ) {
if( struct_typ == NULL ) {
sym->sym_type = ArrayNode( typ->object ); /* 18-oct-88 */
} else {
sym->sym_type = TypeNode( TYPE_STRUCT,
ArrayNode( typ->object ) );
sym->sym_type->u.tag = struct_typ->u.tag;
struct_typ = sym->sym_type;
}
} else {
struct_typ = NULL;
}
SymReplace( sym, sym_handle ); /* 31-aug-88 */
InitSymData( sym->sym_type, 0 );
SymGet( sym, sym_handle ); /* 31-aug-88 */
if( struct_typ != NULL ) { /* 17-mar-92 */
/* structure contains a unspecified length array as last field */
struct_typ->object->u.array->dimension = typ->u.array->dimension;
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;
while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
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;
while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
}
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;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
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;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
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;
while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
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( n == 0 ){
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( n == 0 ){
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;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
/* 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -