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

📄 cexpr2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            if( sym.stg_class == SC_EXTERN  &&  sym.level > 0 ) {
                sym0_handle = Sym0Look( hash, Buffer );
                if( sym0_handle != 0 ) {
                    sym_handle = sym0_handle;
                    SymGet( &sym, sym_handle );
                }
            }
            if( sym.stg_class == SC_TYPEDEF ) {
                CErr2p( ERR_CANT_USE_TYPEDEF_AS_VAR, Buffer );
                return( IntLeaf( 0 ) );
            }
        }
        NextToken();
    }
    /* if( SizeOfCount == 0 ) */ /* causes defined but not referenced */
    /* always turning it on can cause referenced but not assigned */
    /* for the case:  int i;  j = sizeof(i);  */
/*      sym.flags |= SYM_REFERENCED;            07-jun-89 */
    sym.flags |= SYM_REFERENCED;
    if( sym_handle == 0 ) {
        if( CurToken == T_LEFT_PAREN ) {
            sym.stg_class = SC_FORWARD;     /* indicate forward decl */
            sym_handle = SymAddL0( hash, &sym ); /* add symbol to level 0 */
            sym.flags |= SYM_FUNCTION;
            sym.sym_type = FuncNode( GetType( TYPE_INT ), 0, NULL );
        } else {
            sym.stg_class = SC_EXTERN;      /* indicate extern decl */
            CErr2p( ERR_UNDECLARED_SYM, sym.name );
            sym_handle = SymAdd( hash, &sym ); /* add sym to current level*/
            sym.sym_type = GetType( TYPE_INT );
        }
    }
    IncSymWeight( &sym );
    tree = VarLeaf( &sym, sym_handle );
    SymReplace( &sym, sym_handle );
    return( tree );
}


local void IncSymWeight( SYMPTR sym )
{
    static int LoopWeights[] = { 1, 0x10, 0x100, 0x1000 };

    if( sym->level != 0 ) {
        if( ! (sym->flags & SYM_FUNCTION) ) {
            if( LoopDepth > 3 ) {
                sym->u.var.offset = ~0u >> 1;
            } else {
                sym->u.var.offset += LoopWeights[ LoopDepth ];
            }
        }
    }
}

//-----------------------------CMATH------------------------------------

static bool IsStruct( TYPEPTR typ ){
/*********************************/
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_STRUCT  ||
        typ->decl_type == TYPE_UNION ) {
            return( TRUE );
    }
    return( FALSE );
}

int IsLValue( TREEPTR tree )
{
    switch( tree->op.opr ) {
    case OPR_ERROR:
    case OPR_ARROW:
    case OPR_INDEX:
    case OPR_PUSHADDR:
    case OPR_POINTS:
        return( 1 );
    case OPR_DOT:
        while( tree->op.opr == OPR_DOT ) tree = tree->left;
        switch( tree->op.opr ) {
        case OPR_CALL:
        case OPR_QUESTION:
        case OPR_COMMA:
            // These are not lvalues
            break;
        default:
            return( 1 );
            break;
        }
        break;
    }
    return( 0 );
}

static bool IsCallValue( TREEPTR tree )
{
    int ret;

    while( tree->op.opr == OPR_DOT || tree->op.opr == OPR_INDEX ){
        tree = tree->left;
    }
    if( tree->op.opr == OPR_CALL ) {
        ret = TRUE;
    }else{
        ret = FALSE;
    }
    return( ret );
}
// This RVALUE thing is backwards -mjc
local TREEPTR TakeRValue( TREEPTR tree, int void_ok )
{
    TYPEPTR             typ;
    char                sym_flags;
    type_modifiers      decl_flags;
    target_uint         value;
    SYM_ENTRY           sym;

    if( tree->op.opr == OPR_ERROR ) return( tree );     /* 16-mar-88*/
    if( CompFlags.pre_processing ) {            /* 07-feb-89 */
        if( tree->op.opr == OPR_PUSHFLOAT ) {
            CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            return( ErrorNode( tree ) );
        }
    }
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_VOID ) {
        if( ! void_ok ) {
            CErr1( ERR_EXPR_HAS_VOID_TYPE );
            return( ErrorNode( tree ) );
        }
    } else if( typ->decl_type == TYPE_ARRAY ) {

        if( tree->op.opr == OPR_PUSHSTRING ) {
            if( typ->object->decl_type == TYPE_USHORT ) { /* 02-aug-91 */
                typ = PtrNode( typ->object, 0, SEG_DATA );
            } else {
                StringArrayType = typ;
                typ = StringType;
            }
            tree->expr_type = typ;
        } else {

            decl_flags = FlagOps( tree->op.flags );
            if( tree->op.opr == OPR_PUSHADDR ) {
                SymGet( &sym, tree->op.sym_handle );
                sym_flags = sym.flags;
                sym.flags |= SYM_REFERENCED | SYM_ASSIGNED;
                if( sym_flags != sym.flags ) {
                    SymReplace( &sym, tree->op.sym_handle );
                }
            }
            if( IsCallValue( tree ) ){
                CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
            }
            tree = ExprNode( NULL, OPR_ADDROF, tree );
            tree->expr_type = PtrNode( typ->object, decl_flags, SEG_DATA );
        }
    } else if( typ->decl_type == TYPE_FUNCTION ) {

        sym_flags = FLAG_NONE;
        if( tree->op.opr == OPR_PUSHADDR ) {
            SymGet( &sym, tree->op.sym_handle );
            decl_flags = sym.attrib;
            sym_flags = sym.flags;
            sym.flags |= SYM_REFERENCED | SYM_ADDR_TAKEN;
            if( sym_flags != sym.flags ) {
                    SymReplace( &sym, tree->op.sym_handle );
            }
        }else if( tree->op.opr == OPR_POINTS ){
            decl_flags = tree->op.result_type->u.p.decl_flags;
        }
        tree = ExprNode( NULL, OPR_ADDROF, tree );
        tree->expr_type = PtrNode( typ, decl_flags, 0 );
    } else if( TypeSize(typ) == 0 ) {
        CErr1( ERR_INCOMPLETE_EXPR_TYPE );
        return( ErrorNode( tree ) );
    } else {
        if( SizeOfCount == 0 ) {                        /* 05-jan-89 */
            if( tree->op.flags & OPFLAG_VOLATILE){     /* 02-nov-91 */
                CompFlags.useful_side_effect = 1;
            }
        }
        if( tree->op.opr == OPR_PUSHSYM || tree->op.opr == OPR_PUSHADDR ) {
            SymGet( &sym, tree->op.sym_handle );
            sym_flags = sym.flags;
            sym.flags |= SYM_REFERENCED;                /* 07-jun-89 */
            if( CompFlags.label_dropped == 0  &&  SizeOfCount == 0 ) {
                if( sym.level != 0      &&
                    sym.stg_class != SC_STATIC &&       /* 15-feb-88 */
                    sym.stg_class != SC_EXTERN ) {
                    if( !( sym.flags & SYM_ASSIGNED ) ) {
                      /* turn on flag so msg only comes out once per sym */
                        sym.flags |= SYM_ASSIGNED;
                        CWarn( WARN_SYM_NOT_ASSIGNED,
                                ERR_SYM_NOT_ASSIGNED,
                                SymName( &sym, tree->op.sym_handle ) );
                    }
                }
            }
            if( sym_flags != sym.flags ) {
                SymReplace( &sym, tree->op.sym_handle );
            }
        }
    }
    switch( tree->op.opr ) {
    case OPR_PUSHADDR:
        tree->op.opr = OPR_PUSHSYM;
        break;
    case OPR_QUESTION:
    case OPR_COMMA:
    case OPR_EQUALS:
        if( IsStruct( tree->expr_type ) ){
            tree->op.flags |= OPFLAG_RVALUE;
        }
        break;
    case OPR_DOT:                       // sym.field
    case OPR_ARROW:                     // ptr->field
    case OPR_INDEX:                     // array[index]
        tree->op.flags |= OPFLAG_RVALUE;
        break;
    case OPR_CALL:                      // func()
        tree->op.flags |= OPFLAG_RVALUE;
        if( tree->left->op.opr == OPR_FUNCNAME ) {
            SymGet( &sym, tree->left->op.sym_handle );
            if( sym.stg_class == SC_FORWARD && !(sym.flags & SYM_TYPE_GIVEN ) ){
                 sym.flags |= SYM_TYPE_GIVEN;
                 SymReplace( &sym, tree->left->op.sym_handle );
            }
        }
        break;
    case OPR_POINTS:
        if( tree->left->op.opr == OPR_PUSHSTRING ) {    // *"abc"
            STRING_LITERAL      *string;

            string = tree->left->op.string_handle;
            value = string->literal[0];
            typ = tree->left->expr_type;
            if( typ->object->decl_type == TYPE_USHORT ) {  /* 24-jul-92 */
                value = (string->literal[1] << 8) | value;
            }
            FreeExprTree( tree );
            tree = IntLeaf( value );
        } else {
            tree->op.flags |= OPFLAG_RVALUE;
        }
        break;
    }
    return( tree );
}


TREEPTR VoidRValue( TREEPTR tree )
{
    tree =  TakeRValue( tree, 1 );
    return( tree );
}

TREEPTR RValue( TREEPTR tree )
{
    tree =  TakeRValue( tree, 0 );
    return( tree );
}

//-----------------------------COPS------------------------------------
static TREEPTR AddrOp( TREEPTR tree )
{
    TYPEPTR         typ;
    TREEPTR         leaf;
    type_modifiers  modifiers;
    int             segid;
    SYM_HANDLE      based_sym;
    SYM_ENTRY       sym;

    if( tree->op.opr == OPR_ERROR )  return( tree );
    typ = tree->expr_type;
    if( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) {
        CErr1( ERR_CANT_TAKE_ADDR_OF_BIT_FIELD );
        return( ErrorNode( tree ) );
    }else if( typ->decl_type == TYPE_VOID ){
        CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
        return( ErrorNode( tree ) );
    }
    if(tree->op.flags & OPFLAG_LVALUE_CAST) {       /* 18-aug-95 */
        if( CompFlags.extensions_enabled ){
            tree->op.flags &= ~(OPFLAG_LVALUE_CAST|OPFLAG_RVALUE);
            CWarn1( WARN_LVALUE_CAST, ERR_LVALUE_CAST );
        }else{
            CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
            return( ErrorNode( tree ) );
        }
    }
    if( (tree->op.opr == OPR_CONVERT || tree->op.opr == OPR_CONVERT_PTR)
      && CompFlags.extensions_enabled ) {
        tree = LCastAdj( tree );
    }
    leaf = tree;
    if( tree->op.opr == OPR_DOT ) {
        if( tree->left->op.opr == OPR_PUSHADDR ) {
            leaf = tree->left;
        }
    } else if( tree->op.opr == OPR_ARROW ) {
        // checking for offsetof macro construct
        // #define offsetof(typ,field) (size_t)&(((typ*)0)->field)
        if( tree->left->op.opr == OPR_PUSHINT ) {
            leaf = tree->left;
            leaf->op.ulong_value += tree->right->op.ulong_value;
            tree->left = NULL;
            FreeExprTree( tree );
            leaf->expr_type = PtrNode( typ, 0, SEG_DATA );
            return( leaf );
        }
    }
    based_sym = 0;
    modifiers  = FLAG_NONE;
    segid = SEG_DATA;
    if( leaf->op.opr == OPR_PUSHADDR ) {
        SymGet( &sym, leaf->op.sym_handle );
        if( sym.stg_class == SC_REGISTER ) {
            CErr1( ERR_CANT_TAKE_ADDR_OF_REGISTER );
        }
        if( sym.level != 0 ) {
            sym.flags |= SYM_ASSIGNED;
        }
        sym.flags |= SYM_ADDR_TAKEN | SYM_REFERENCED;
        SymReplace( &sym, leaf->op.sym_handle );
    }
    if( tree->op.opr == OPR_PUSHADDR ) {
        SymGet( &sym, leaf->op.sym_handle );
        modifiers = sym.attrib;
        if( sym.stg_class == SC_AUTO ) {
            segid = SEG_STACK;
            CompFlags.addr_of_auto_taken = 1;           /* 23-oct-91 */
            if( TargetSwitches & FLOATING_SS ) {        /* 05-oct-88 */
                modifiers |= FLAG_FAR;
            }
        }
        typ = PtrNode( typ, modifiers, segid );
    } else if( tree->op.opr == OPR_POINTS ) {
        typ = tree->op.result_type;
    } else {
        modifiers = FlagOps( tree->op.flags );
        typ = PtrNode( typ, modifiers, SEG_DATA );
    }
    if( IsLValue( tree ) ) {
        tree = ExprNode( NULL, OPR_ADDROF, tree );
    } else {
        CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
        return( ErrorNode( tree ) );
    }
    tree->expr_type = typ;
    return( tree );
}

static TREEPTR FarPtrCvt( SYMPTR sym, SYM_HANDLE sym_handle )
{
    TYPEPTR         typ;
    TREEPTR         tree;

    typ =  sym->sym_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_POINTER ){
        if( (typ->u.p.decl_flags & FLAG_FAR) ){
            tree = VarLeaf( sym, sym_handle );
            tree->op.opr = OPR_PUSHSYM;
        }else if( typ->u.p.decl_flags & FLAG_BASED ){
            tree = VarLeaf( sym, sym_handle );
            tree->op.opr = OPR_PUSHSYM;
            tree = BasedPtrNode( typ, tree );
        }else{
            tree = VarLeaf( sym, sym_handle );
            tree->op.opr = OPR_PUSHSYM;
            tree = ExprNode( NULL, OPR_CONVERT, tree );
            tree->expr_type = typ;
            tree->op.result_type = PtrNode( typ->object, FLAG_FAR, 0 );
        }
    }
    return( tree );
}

static TREEPTR MakeFarOp( TREEPTR based_sym, TREEPTR tree )
{
    TYPEPTR     typ;

    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    typ = PtrNode( typ->object, FLAG_FAR, 0 );
    tree = ExprNode( based_sym, OPR_FARPTR, tree );
    tree->expr_type = typ;
    return( tree );
}

TREEPTR BasedPtrNode( TYPEPTR ptrtyp, TREEPTR tree )
{
    TREEPTR     based_sym;
    SYM_HANDLE sym_handle;
    SYMPTR      sym;
    int        segid;

    sym_handle = ptrtyp->u.p.based_sym;
    segid =  ptrtyp->u.p.segment;
    switch( ptrtyp->u.p.based_kind ){
    case BASED_VOID:          //__based( void )       segment:>offset base op

⌨️ 快捷键说明

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