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

📄 cdinit.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        if( info.state == IS_VALUE ){ // must be foldable  into addr+offset
            info.is_error = TRUE;
        }
        if( info.is_str ){ // need to fix cgen an DATAQUADS to handle str+off
            if( info.offset != 0 ){
                info.is_error = TRUE;
            }
        }
        if( info.is_error ){
            CErr1( ERR_NOT_A_CONSTANT_EXPR );
            dq.opr = T_ID;
            dq.u.var.sym_handle = 0;
            dq.u.var.offset = 0;
        }else{
            if( info.is_str ){
                dq.opr = T_STRING;
                dq.u.string_leaf = info.str_h;
            }else{
                dq.opr = T_ID;
                dq.u.var.sym_handle = info.sym_h;
                dq.u.var.offset = info.offset;
            }
        }
    }
    if( typ->decl_type == TYPE_POINTER ) {
        GenDataQuad( &dq );
    } else if( dq.opr == T_STRING ) {           /* 05-jun-91 */
        if( TypeSize( typ ) != DataPtrSize  ||  CompFlags.strict_ANSI ) {
            CErr1( ERR_INVALID_INITIALIZER );
        }
        GenDataQuad( &dq );
    } else { /* dq.opr == T_ID */
        if( dq.u.var.sym_handle != 0 ) {
            if( TypeSize( typ ) != DataPtrSize ) {
                CErr1( ERR_INVALID_INITIALIZER );
            }
            GenDataQuad( &dq );
        } else {
            StoreIValue( int_type, dq.u.var.offset );
        }
    }
}

local void StoreInt64( TYPEPTR typ )
{
    TREEPTR     tree;
    auto DATA_QUAD dq;

    dq.opr = T___INT64;
    dq.flags = Q_DATA;
    U32ToU64( 0, &dq.u.long64 );
    if( CurToken != T_RIGHT_BRACE ) {
        tree = SingleExpr();
        tree = InitAsgn( typ, tree ); // as if we are assigning
        if( tree->op.opr == OPR_PUSHINT || tree->op.opr == OPR_PUSHFLOAT ) {
            CastConstValue( tree, typ->decl_type );
            dq.u.long64 = tree->op.ulong64_value;
        }else{
            CErr1( ERR_NOT_A_CONSTANT_EXPR );
        }
        FreeExprTree( tree );
        CompFlags.non_zero_data = 1;
    }
    GenDataQuad( &dq );
}

local FIELDPTR InitBitField( FIELDPTR field )
{
    TYPEPTR             typ;
    unsigned long       value;
    uint64              value64;
    unsigned long       bit_value;
    unsigned long       offset;
    int                 token;
    TOKEN               int_type = T_NULL;

    token = CurToken;
    if( CurToken == T_LEFT_BRACE ) NextToken();
    typ = field->field_type;
    switch( typ->u.f.field_type ) {
    case TYPE_CHAR:
    case TYPE_UCHAR:
        int_type = T_CHAR;
        break;
    case TYPE_SHORT:
    case TYPE_USHORT:
        int_type = T_SHORT;
        break;
    case TYPE_INT:
    case TYPE_UINT:
        int_type = T_INT;
        break;
    case TYPE_LONG:
    case TYPE_ULONG:
        int_type = T_LONG;
        break;
    case TYPE_LONG64:
    case TYPE_ULONG64:
        int_type = T___INT64;
        U32ToU64( 0, &value64 );
        break;
    }
    offset = field->offset;
    value = 0;
    while( typ->decl_type == TYPE_FIELD ||
           typ->decl_type == TYPE_UFIELD ) {
        bit_value = 0;
        if( CurToken != T_RIGHT_BRACE ) bit_value = ConstExpr();
        ChkConstant( bit_value, BitMask[ typ->u.f.field_width - 1 ] );
        bit_value &= BitMask[ typ->u.f.field_width - 1 ];
        if( int_type == T___INT64 ){
            uint64 tmp;
            U32ToU64( bit_value, &tmp );
            U64ShiftL( &tmp, typ->u.f.field_start, &tmp );
            value64.u._32[L] |= tmp.u._32[L];
            value64.u._32[H] |= tmp.u._32[H];
        }else{
            value |= bit_value << typ->u.f.field_start;
        }
        field = field->next_field;
        if( field == NULL ) break;
        if( field->offset != offset ) break;    /* bit field done */
        typ = field->field_type;
        if( CurToken == T_EOF ) break;
        if( CurToken != T_RIGHT_BRACE ) MustRecog( T_COMMA );
    }
    if( int_type == T___INT64 ){
        StoreIValue64( value64 );
    }else{
        StoreIValue( int_type, value );
    }
    if( token == T_LEFT_BRACE ) {
        if( CurToken == T_COMMA ) NextToken();
        MustRecog( T_RIGHT_BRACE );
    }
    return( field );
}


local void InitArray( TYPEPTR typ )
{
    unsigned long       n;
    unsigned long       array_size;

    array_size = TypeSize( typ );
    n = 0;
    for( ;; ) {
        InitSymData( typ->object, 1 );
        n++;
        if( n == array_size ){
            break;
        }
        if( CurToken == T_EOF ) break;
        if( CurToken == T_RIGHT_BRACE ) break;
        MustRecog( T_COMMA );
        if( CurToken == T_RIGHT_BRACE ) break;
    }
    if( array_size == 0 ){
        typ->u.array->dimension = n;
    }else if( array_size > n ){
        ZeroBytes( (array_size-n) * SizeOfArg( typ->object ) );
    }
}

local void InitStruct( TYPEPTR typ )
{
    FIELDPTR            field;
    unsigned long       n;
    unsigned            offset;

    n = typ->u.tag->size;      /* get full size of the struct */
    offset = 0;
    for( field = typ->u.tag->u.field_list; field; ) {
        /* The first field might not start at offset 0;  19-mar-91 */
        if( field->offset != offset ) {                 /* 14-dec-88 */
            ZeroBytes( field->offset - offset );        /* padding */
        }
        typ = field->field_type;
        offset = field->offset + SizeOfArg( typ );      /* 19-dec-88 */
        if( typ->decl_type == TYPE_FIELD  ||
            typ->decl_type == TYPE_UFIELD ) {
            field = InitBitField( field );
        } else {
            InitSymData( typ, 1 );
            field = field->next_field;
        }
        if( field == NULL ) break;
        if( CurToken == T_EOF ) break;
        if( CurToken != T_RIGHT_BRACE )  MustRecog( T_COMMA );
    }
    if( (unsigned)n > offset ) {        /* 14-dec-88, 07-jun-92 */
        ZeroBytes( (unsigned)n - offset );      /* padding */
    }
}

local void InitUnion( TYPEPTR typ )
{
    FIELDPTR            field;
    unsigned long       n;

    n = typ->u.tag->size;      /* get full size of the union */
    field = typ->u.tag->u.field_list;
    for(;;) {                           // skip unnamed bit fields
        if( field == NULL ) break;              // 12-nov-94
        typ = field->field_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( field->name[0] != '\0' ) break;
        if( typ->decl_type == TYPE_STRUCT ) break;      /* 03-feb-95 */
        if( typ->decl_type == TYPE_UNION ) break;
        field = field->next_field;
    }
    if( field != NULL ) {               /* 18-oct-94 */
        if( typ->decl_type == TYPE_FIELD  ||    /* 12-nov-94 */
            typ->decl_type == TYPE_UFIELD ) {
            InitBitField( field );
        } else {
            InitSymData( typ, 1 );
        }
        n -= SizeOfArg( typ );  /* subtract size of the first type */
        if( n != 0 ) ZeroBytes( n );/* pad the rest */
    }
}

void InitSymData( TYPEPTR typ, int level )
{
    int                 token;

    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_ENUM ) typ = typ->object;        /* 07-nov-90 */
    token = CurToken;
    if( CurToken == T_LEFT_BRACE ) {
        NextToken();
        if( CurToken == T_RIGHT_BRACE  ||  CurToken == T_COMMA ) {
            CErr1( ERR_EMPTY_INITIALIZER_LIST );
        }
    }
    switch( typ->decl_type ) {
    case TYPE_ARRAY:
        if( CharArray( typ->object ) ) {
            InitCharArray( typ );
        } else if( WCharArray( typ->object ) ) {
            InitWCharArray( typ );
        } else {
            if( token != T_LEFT_BRACE  &&  level == 0 ) {
                CErr1( ERR_NEED_BRACES );
            }
            InitArray( typ );
        }
        break;
    case TYPE_FCOMPLEX:
    case TYPE_DCOMPLEX:
    case TYPE_LDCOMPLEX:
    case TYPE_STRUCT:
        if( token != T_LEFT_BRACE  &&  level == 0 ) {
            CErr1( ERR_NEED_BRACES );
        }
        InitStruct( typ );
        break;
    case TYPE_UNION:
        if( token != T_LEFT_BRACE  &&  level == 0 ) {
            CErr1( ERR_NEED_BRACES );
        }
        InitUnion( typ );
        break;
    case TYPE_CHAR:
    case TYPE_UCHAR:
        StorePointer( typ, T_CHAR );
        break;
    case TYPE_SHORT:
    case TYPE_USHORT:
        StorePointer( typ, T_SHORT );
        break;
    case TYPE_INT:
    case TYPE_UINT:
        StorePointer( typ, T_INT );
        break;
    case TYPE_LONG:
    case TYPE_ULONG:
        StorePointer( typ, T_LONG );
        break;
    case TYPE_LONG64:
    case TYPE_ULONG64:
        StoreInt64( typ );
        break;
    case TYPE_FLOAT:
        StoreFloat( T_FLOAT );
        break;
    case TYPE_DOUBLE:
        StoreFloat( T_DOUBLE );
        break;
    case TYPE_LONG_DOUBLE:
        //StoreFloat( T_LONG_DOUBLE );
        StoreFloat( T_DOUBLE );
        break;
    case TYPE_POINTER:
        StorePointer( typ, T_ID );
        break;
    case TYPE_BOOL:
        StorePointer( typ, T_CHAR );
        break;
    case TYPE_FIMAGINARY:
        StoreFloat( T_FLOAT );
        break;
    case TYPE_DIMAGINARY:
        StoreFloat( T_DOUBLE );
        break;
    case TYPE_LDIMAGINARY:
        //StoreFloat( T_LONG_DOUBLE );
        StoreFloat( T_DOUBLE );
        break;
    default:
        break;
    }
    if( token == T_LEFT_BRACE ) {
        if( CurToken == T_COMMA ) {
            NextToken();
        }
        if( CurToken != T_RIGHT_BRACE ) {
            CErr1( ERR_TOO_MANY_INITS );
        }
        while( CurToken != T_RIGHT_BRACE ){
          if( CurToken == T_EOF ) break;
          if( CurToken == T_SEMI_COLON )break;
          if( CurToken == T_LEFT_BRACE )break;
           NextToken();
        }
        MustRecog( T_RIGHT_BRACE );
    }
}


local int CharArray( TYPEPTR typ )
{
    if( CurToken == T_STRING ) {
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_CHAR || typ->decl_type == TYPE_UCHAR ){
            return( TRUE );
        }
    }
    return( FALSE );
}


local int WCharArray( TYPEPTR typ )
{
    if( CurToken == T_STRING ) {
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_SHORT || typ->decl_type == TYPE_USHORT ) {
            return( 1 );
        }
    }
    return( 0 );
}

local void InitCharArray( TYPEPTR typ )
{
    unsigned            len;
    STRING_LITERAL      *str_lit;
    unsigned long       size;
    auto DATA_QUAD      dq;

/*      This function handles the initialization of statements like:  */
/*              char  name[4] = "abcd";  */

    str_lit = GetLiteral();
    if( CompFlags.wide_char_string )
        CErr1( ERR_TYPE_MISMATCH );
    len = str_lit->length;
    if( typ->u.array->dimension == 0 )  typ->u.array->dimension = len;
    size = typ->u.array->dimension;
    if( len > size ) {
        if( (len - size) > 1 ) {
            CWarn1( WARN_LIT_TOO_LONG, ERR_LIT_TOO_LONG );
        }
        str_lit->length = size; /* chop the string */
    }
    dq.opr = T_CONST;
    dq.flags = Q_DATA;
    dq.u.string_leaf = str_lit;
    GenDataQuad( &dq );
    if( size > len ) {                  /* if array > len of literal */
        ZeroBytes( size - len );
    }
    CompFlags.non_zero_data = 1;
 }

//
local void InitWCharArray( TYPEPTR typ )
{
    unsigned            len;
    unsigned            i;
    STRING_LITERAL      *str_lit;
    unsigned            value;
    unsigned short      *pwc;
    unsigned long       size;
    auto DATA_QUAD      dq;

    dq.opr = T_SHORT;
    dq.flags = Q_DATA;

/*      This function handles the initialization of statements like:  */
/*              wchar_t  name[5] = L"abcd";  */

    str_lit = GetLiteral();
    if( !CompFlags.wide_char_string )
        CErr1( ERR_TYPE_MISMATCH );
    len = str_lit->length / sizeof(unsigned short);
    if( typ->u.array->dimension == 0 ) {
        typ->u.array->dimension = len;
    }
    size = typ->u.array->dimension;
    if( len > size ) {
        if( (len - size) > 1 ) {
            CWarn1( WARN_LIT_TOO_LONG, ERR_LIT_TOO_LONG );
        }
        len = size;
    }
    pwc = (unsigned short *)str_lit->literal;
    i = 0;
    while( i < len ) {
        value = *pwc++;
        if( value != 0 ) CompFlags.non_zero_data = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -