⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdinit.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -