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

📄 cexpr2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        break;
    case BASED_NONE:
        break;
    case BASED_SELFSEG:       //__based( (__segment) __self ) use seg of self
        tree->op.flags &= ~OPFLAG_RVALUE;
        based_sym = ExprNode( tree, OPR_DUPE, NULL );
        based_sym->op.flags |= OPFLAG_RVALUE;
        based_sym->op.result_type = tree->op.result_type;
        tree = MakeFarOp( based_sym, tree );
        tree->right = NULL;
        break;
    case BASED_VAR:              //__based( <var> )             add offset to var pointer
      {
        TYPEPTR     typ;
        TYPEPTR     old;

        old = tree->expr_type;
        while( old->decl_type == TYPE_TYPEDEF ) old = old->object;
        sym = SymGetPtr( sym_handle );
        based_sym = VarLeaf( sym, sym_handle );
        based_sym->op.opr = OPR_PUSHSYM;
        typ = sym->sym_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->u.p.decl_flags & FLAG_BASED ){
            based_sym  = BasedPtrNode( typ, based_sym );
            typ = based_sym->expr_type;
            while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        }
        old = PtrNode( old->object, typ->u.p.decl_flags, 0 );
        tree = ExprNode( based_sym, OPR_ADD, tree );
        tree->expr_type = old;
        tree->op.result_type = old;
      } break;
    case BASED_SEGVAR:           //__based( <var> )             add offset to seg var
        sym = SymGetPtr( sym_handle );
        based_sym = VarLeaf( sym, sym_handle );
        based_sym->op.opr = OPR_PUSHSYM;
        tree = MakeFarOp( based_sym, tree );
        break;
    case BASED_VARSEG:        //__based( (__segment) <var> ) ) use seg of var
        sym = SymGetPtr( sym_handle );
        based_sym = FarPtrCvt( sym, sym_handle );
        tree = MakeFarOp( based_sym, tree );
        break;
    case BASED_SEGNAME:       //__based( __segname( "name" )   use seg of segname
        if( sym_handle != 0 ){
            sym = SymGetPtr( sym_handle );
            based_sym = VarLeaf( sym, sym_handle );
            based_sym->op.opr = OPR_PUSHSEG;
        }else{ //error I guess
            based_sym = LeafNode( OPR_PUSHINT );
            based_sym->op.const_type = TYPE_INT;
            based_sym->op.long_value = segid;
            based_sym->expr_type =  GetType( TYPE_USHORT );
        }
        tree = MakeFarOp( based_sym, tree );
    }
    return( tree  );
}

TREEPTR PtrOp( TREEPTR tree )
{
    TYPEPTR         ptrtyp;
    TYPEPTR         typ;
    type_modifiers  flags;

    if( tree->op.opr == OPR_ERROR )  return( tree );
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type != TYPE_POINTER ) {
        CErr1( ERR_EXPR_MUST_BE_POINTER_TO );
        return( ErrorNode( tree ) );
    }
    ptrtyp = typ;
    flags = typ->u.p.decl_flags & PTR_FLAGS;
    if( flags & FLAG_BASED ) {
        tree = BasedPtrNode( typ, tree );
        flags &= ~(FLAG_NEAR | FLAG_BASED);
        flags |= FLAG_FAR;
    }
    tree = ExprNode( tree, OPR_POINTS, NULL );
    typ = typ->object;
//  while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    tree->expr_type = typ;
    tree->op.result_type = ptrtyp;
    tree->op.flags = OpFlags( flags );
    if( SizeOfCount == 0 ) {
        if( tree->op.flags & OPFLAG_VOLATILE){
            CompFlags.useful_side_effect = 1;
        }
    }
    return( tree );
}



FIELDPTR SearchFields( TYPEPTR *class_typ, unsigned long *field_offset,
                             char *name )
{
    FIELDPTR    field;
    FIELDPTR    subfield;
    TYPEPTR     typ;
    TAGPTR      tag;

    tag = (*class_typ)->u.tag;
    field = tag->u.field_list;
    while( field != NULL ) {
        typ = field->field_type;
        while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
        if( field->name[0] == '\0' ) {  /* if nameless field: 15-sep-90 */
            if( typ->decl_type == TYPE_STRUCT  ||
                typ->decl_type == TYPE_UNION ) {
                subfield = SearchFields( &typ, field_offset, name );
                if( subfield != NULL ) {
                    *field_offset += field->offset;
                    *class_typ = typ;
                    return( subfield );
                }
            }
        } else if( strcmp( name, field->name ) == 0 ) {
            if( typ->decl_type != TYPE_FUNCTION ) {
                *field_offset += field->offset;
            }
            return( field );
        }
        field = field->next_field;
    }
    return( NULL );
}


local TYPEPTR Ptr2Struct( TYPEPTR typ )
{
    if( typ->decl_type != TYPE_POINTER ) {
        return( NULL );
    }
    typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_STRUCT  ||
        typ->decl_type == TYPE_UNION ) {
            return( typ );
    }
    return( NULL );
}



TREEPTR DotOp( TREEPTR tree )
{
    TYPEPTR             typ;
    TYPEPTR             get_typ;
    FIELDPTR            field;
    unsigned long       offset;
    op_flags            opflag;
    SYM_ENTRY           sym;

    if( CurToken != T_ID ) {
        CErr1( ERR_EXPECTING_ID );
        return( ErrorNode( tree ) );
    }
    if( tree->op.opr == OPR_ERROR )  return( tree );
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) {
        typ = typ->object;
    }
    if( typ->decl_type != TYPE_STRUCT  &&
        typ->decl_type != TYPE_UNION ) {
        CErr1( ERR_MUST_BE_STRUCT_OR_UNION );
        return( ErrorNode( tree ) );
    }
    get_typ = typ;
    offset = 0;
    field = SearchFields( &get_typ, &offset, Buffer );
    if( field == NULL ) {
        CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, Buffer, typ->u.tag->name );
        return( ErrorNode( tree ) );
    }
    typ = field->field_type;
    opflag = tree->op.flags | OpFlags( field->attrib );
    if( CompFlags.emit_browser_info ) {                 /* 27-oct-94 */
        field->xref->next_xref = NewXref( field->xref->next_xref );
    }
    if( tree->op.opr == OPR_DOT || tree->op.opr == OPR_ARROW ) {
        tree->right->op.ulong_value += offset;
    } else {
        if( tree->op.opr == OPR_PUSHADDR ) {
            SymGet( &sym, tree->op.sym_handle );
            if( !(sym.flags & SYM_ASSIGNED) ) {
                sym.flags |= SYM_ASSIGNED;
                SymReplace( &sym, tree->op.sym_handle );
            }
        }
        tree = ExprNode( tree, OPR_DOT, UIntLeaf( offset ) );
    }
    tree->expr_type = typ;
    tree->op.result_type = typ;
    tree->op.flags = opflag;
    return( tree );
}


TREEPTR DotOpNamed( TREEPTR tree, char *name )
{
    TYPEPTR             typ;
    TYPEPTR             get_typ;
    FIELDPTR            field;
    unsigned long       offset;
    op_flags            opflag;
    SYM_ENTRY           sym;

    typ = tree->expr_type;
    get_typ = typ;
    offset = 0;
    field = SearchFields( &get_typ, &offset, name );
    if( field == NULL ) {
        CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, name, typ->u.tag->name );
        return( ErrorNode( tree ) );
    }
    typ = field->field_type;
    opflag = tree->op.flags | OpFlags( field->attrib );
    if( CompFlags.emit_browser_info ) {                 /* 27-oct-94 */
        field->xref->next_xref = NewXref( field->xref->next_xref );
    }
    if( tree->op.opr == OPR_DOT || tree->op.opr == OPR_ARROW ) {
        tree->right->op.ulong_value += offset;
    } else {
        if( tree->op.opr == OPR_PUSHADDR ) {
            SymGet( &sym, tree->op.sym_handle );
            if( !(sym.flags & SYM_ASSIGNED) ) {
                sym.flags |= SYM_ASSIGNED;
                SymReplace( &sym, tree->op.sym_handle );
            }
        }
        tree = ExprNode( tree, OPR_DOT, UIntLeaf( offset ) );
    }
    tree->expr_type = typ;
    tree->op.result_type = typ;
    tree->op.flags = opflag;
    return( tree );
}


TREEPTR ArrowOp( TREEPTR tree )
{
    TYPEPTR             typ;
    TYPEPTR             get_typ;
    FIELDPTR            field;
    unsigned long       offset;
    type_modifiers      flags;

    if( CurToken != T_ID ) {
        CErr1( ERR_EXPECTING_ID );
        return( ErrorNode( tree ) );
    }
    if( tree->op.opr == OPR_ERROR )  return( tree );
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) {
        typ = typ->object;
    }
    if( Ptr2Struct( typ ) == NULL ) {
        CErr1( ERR_MUST_BE_PTR_TO_STRUCT_OR_UNION );
        return( ErrorNode( tree ) );
    }
    if( tree->op.opr == OPR_PUSHADDR ) {
        tree->op.opr = OPR_PUSHSYM;
    }
    flags = typ->u.p.decl_flags & PTR_FLAGS; // get pointer flags
    if( flags & FLAG_BASED ) {
        tree = BasedPtrNode( typ, tree );
        flags &= ~(FLAG_NEAR | FLAG_BASED);
        flags |= FLAG_FAR;
    }
    typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF ) {
        typ = typ->object;
    }
    get_typ = typ;
    offset = 0;
    field = SearchFields( &get_typ, &offset, Buffer );
    if( field == NULL ) {
        CErr( ERR_NAME_NOT_FOUND_IN_STRUCT, Buffer, typ->u.tag->name );
        return( ErrorNode( tree ) );
    }
    if( CompFlags.emit_browser_info ) {                 /* 27-oct-94 */
        field->xref->next_xref = NewXref( field->xref->next_xref );
    }
    tree = ExprNode( tree, OPR_ARROW, UIntLeaf( offset ) );
    typ = field->field_type;
    tree->expr_type = typ;
    tree->op.result_type = typ;
    flags |= field->attrib;
    tree->op.flags |= OpFlags( flags );
    return( tree );
}

TREEPTR IncDec( TREEPTR tree, TOKEN opr )
{
    op_flags volatile_flag;

    volatile_flag = tree->op.flags & OPFLAG_VOLATILE;
    ChkConst( tree );
    tree = AddOp( tree, opr, IntLeaf( 1 ) );
    tree->op.flags |= volatile_flag;
    CompFlags.meaningless_stmt = 0;
    CompFlags.useful_side_effect = 1;
    return( tree );
}
//-----------------------------CEXPR-----------------------------------

bool ConstExprAndType( const_val *val )
{
    TREEPTR     tree;
    call_list  **save;
    bool        ret;

    save = FirstCallLnk;
    ++Level;                    /* allow for nested expressions */
    tree = SingleExpr();
    --Level;                    /* put Level back */
    FirstCallLnk = save;
    val->type = TYPE_INT;
    switch( tree->op.opr ) {
    case OPR_PUSHINT:
        val->type = tree->op.const_type;
        if( tree->op.const_type == TYPE_LONG64
         ||  tree->op.const_type == TYPE_ULONG64 ){
            val->val64 = tree->op.long64_value;
        }else{
            val->val32 = tree->op.long_value;
        }
        ret = TRUE;
        break;
    case OPR_PUSHFLOAT:
        CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
        val->val32 = (long)atof( tree->op.float_value->string );
        ret = FALSE;
        break;
    default:
        if( tree->op.opr != OPR_ERROR ){
            CErr1( ERR_NOT_A_CONSTANT_EXPR );
        }
        val->val32 = 0;
        ret = FALSE;
        break;
    }
    FreeExprTree( tree );
    return( ret );
}

long int ConstExpr()
{
    const_val   val;

    ConstExprAndType( &val );
    return( val.val32 );
}



TREEPTR Expr()
{
    Class[ Level ] = TC_START;
    return( GetExpr() );
}


TREEPTR CommaExpr()
{
    Class[ Level ] = TC_START1;
    return( GetExpr() );
}


TREEPTR AddrExpr()
{
    return( SingleExpr() );
}


TREEPTR SingleExpr()
{
    TREEPTR     tree;

    Class[ Level ] = TC_START2;
    tree = GetExpr();
    FoldExprTree( tree );
    return( tree );
}


local TREEPTR GetExpr()
{
    TREEPTR     tree, op1;
    TYPEPTR     typ;
    char        curclass;
    auto TYPEPTR *plist;

    CompFlags.useful_side_effect = 0;
    FirstCallLnk = LastCallLnk;
    tree = 0;
    plist = NULL;

⌨️ 快捷键说明

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