dwarf.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,009 行 · 第 1/5 页

C
2,009
字号
            while( p != NULL ){
                if( p->id == TYP_TYPEDEF ){
                    SCOPE sc;

                    sc = p->u.t.scope;
                    if( sc->id == SCOPE_TEMPLATE_PARM ){
                        dwarfType( p, DC_DEFINE|DC_FAKE );
                    }
                }
                p = p->of;
            }
        }
    }
}
#endif

static boolean dwarfClassInfoFriend( TYPE type, boolean addfriend )
/*****************************************************************/
{
    dw_handle   dh;
    FRIEND      *friend;
    boolean     check_friends;

    check_friends = FALSE;
    if( !InDebug ){ /* TODO: if debug need handle */
        RingIterBeg( ScopeFriends( type->u.c.scope ), friend ) {
            check_friends = TRUE;
            if( addfriend ) {
                dh = dwarfSymbol( friend->sym, DC_DEFAULT );
                if( dh ) {
                    DWAddFriend( Client, dh );
                }
            } else {
                dh = dwarfSymbol( friend->sym, DC_DEFINE );
            }
        } RingIterEnd( friend )
    }
    return( check_friends );
}

static boolean dwarfClassInfo( TYPE type )
/****************************************/
{
    dw_handle       dh;
    SYMBOL          stop, curr;
    BASE_CLASS     *base;
    dw_loc_id       locid;
    dw_loc_handle   dl;
    CLASSINFO      *info;
    boolean         check_friends;

    // define any template typedefs
    for(;;) {
        SCOPE scope;
        if( (type->flag & TF1_INSTANTIATION) == 0 ) break;
        scope = type->u.c.scope->enclosing;
        if( !ScopeType( scope, SCOPE_TEMPLATE_INST ) ) break;
        scope = scope->enclosing;
        if( !ScopeType( scope, SCOPE_TEMPLATE_PARM ) ) break;
        stop = ScopeOrderedStart( scope );
        curr = ScopeOrderedNext( stop, NULL );
        while( curr != NULL ) {
            if( SymIsTypedef( curr ) ) {
                dwarfTypedef( curr->sym_type, DC_DEFINE|DC_FAKE );
            }
            curr = ScopeOrderedNext( stop, curr );
        }
        break;
    }

    // define all the bases
    info = type->u.c.info;
    RingIterBeg( ScopeInherits( type->u.c.scope ), base ) {
        uint flags = 0;
        switch( base->flag & IN_ACCESS_SPECIFIED ) {
        case IN_PRIVATE:
            flags |= DW_FLAG_PRIVATE;
            break;
        case IN_PROTECTED:
            flags |= DW_FLAG_PROTECTED;
            break;
        case IN_PUBLIC:
            flags |= DW_FLAG_PUBLIC;
            break;
        default:
            if( type->flag & TF1_UNION || type->flag & TF1_STRUCT ) {
                flags |= DW_FLAG_PUBLIC;
            } else {
                flags |= DW_FLAG_PRIVATE;
            }
            break;
        }
        if( _IsDirectVirtualBase( base ) ) {
            flags |= DW_FLAG_VIRTUAL;
            locid = DWLocInit( Client );
            DWLocConstS( Client, locid, info->vb_offset );
            DWLocOp0( Client, locid, DW_LOC_plus );
            DWLocOp0( Client, locid, DW_LOC_dup );
            DWLocOp0( Client, locid, DW_LOC_deref );
            DWLocConstS( Client, locid, base->vb_index * vb_FieldTypeSize );
            DWLocOp0( Client, locid, DW_LOC_plus );
            DWLocOp0( Client, locid, DW_LOC_deref );
            if( info->vb_offset != 0 ) {
                DWLocConstS( Client, locid, info->vb_offset );
                DWLocOp0( Client, locid, DW_LOC_plus );
            }
            DWLocOp0( Client, locid, DW_LOC_plus );
            dl = DWLocFini( Client, locid );
            DWAddInheritance( Client,
                              dwarfType( base->type, DC_DEFAULT ),
                              dl,
                              flags );
            DWLocTrash( Client, dl );
        } else if( _IsDirectNonVirtualBase( base ) ) {
            locid = DWLocInit( Client );
            DWLocConstS( Client, locid, base->delta );
            DWLocOp0( Client, locid, DW_LOC_plus );
            dl = DWLocFini( Client, locid );
            DWAddInheritance( Client,
                              dwarfType( base->type, DC_DEFAULT ),
                              dl,
                              flags );
            DWLocTrash( Client, dl );
        }
    } RingIterEnd( base )

    // forward reference all the friends
    check_friends = dwarfClassInfoFriend( type, TRUE );

    // hidden data members
    if( info->has_vbptr ) {
        locid = DWLocInit( Client );
        DWLocConstS( Client, locid, info->vb_offset );
        DWLocOp0( Client, locid, DW_LOC_plus );
        dl = DWLocFini( Client, locid );
        dh = dwarfType( pvb_FieldType, DC_DEFAULT );/* CppName no reentrant */
        dh = DWAddField( Client,
                         dh,
                         dl,
                         "__vbptr",
                         DW_FLAG_ARTIFICIAL );
        DWLocTrash( Client, dl );
    }
    if( info->has_vfptr ) {
        locid = DWLocInit( Client );
        DWLocConstS( Client, locid, info->vf_offset );
        DWLocOp0( Client, locid, DW_LOC_plus );
        dl = DWLocFini( Client, locid );
        dh = dwarfType( pvf_FieldType, DC_DEFAULT );/* CppName no reentrant */
        dh = DWAddField( Client,
                         dh,
                         dl,
                         "__vfptr",
                         DW_FLAG_ARTIFICIAL );
        DWLocTrash( Client, dl );
    }

    // define all the fields
    stop = ScopeOrderedStart( type->u.c.scope );
    curr = ScopeOrderedNext( stop, NULL );
    while( curr != NULL ) {
        sym_reset( curr );
        if( !IsCppNameInterestingDebug( curr ) ) {
             dh = 0;
        }else if( !InDebug && (curr->flag2 & SF2_TOKEN_LOCN)==0 )  {
             dh = 0;
        } else if( SymIsClassDefinition( curr ) ) {
            dh = dwarfSymbol( curr, DC_DEFINE );
        } else if( SymIsEnumDefinition( curr ) ) {
            dh = dwarfSymbol( curr, DC_DEFINE );
        } else if( SymIsEnumeration( curr ) ) {
            // do nothing, handled by SymIsEnumDefinition
            dh = 0;
        } else if( SymIsFunction( curr ) ) {
//          dwarfPumpArgTypes( curr->sym_type );
            if( InDebug ){ /* gen a short defn */
                dh = dwarfDebugMemberFuncDef( info, curr );
                dh = 0;   // if debug we don't want to clash with cg_handle
            }else{
                dh = dwarfSymbol( curr, DC_DEFINE );
            }
        } else if( SymIsTypedef( curr ) ) {
            dh = dwarfSymbol( curr, DC_DEFINE );
        } else if( SymIsData( curr ) ) {
            uint            flags;
            TYPE            pt;

            if( !InDebug ){
                dwarfLocation( curr );
            }
            if( curr->flag & SF_PRIVATE ) {
                flags = DW_FLAG_PRIVATE;
            } else if( curr->flag & SF_PROTECTED ) {
                flags = DW_FLAG_PROTECTED;
            } else {
                flags = DW_FLAG_PUBLIC;
            }
            if( SymIsStaticMember( curr ) ) {
                dw_loc_handle   dl_seg;

                flags |= DW_FLAG_STATIC;
                dl_seg = NULL;
                if( InDebug ){
                    dl = dwarfDebugStaticLoc( curr );
#if _INTEL_CPU
                    if(!( TargetSwitches & FLAT_MODEL )) {
                        dl_seg =  dwarfDebugStaticSeg( curr );
                    }
#endif
                }else{ /* fake up loc for browser */
                    locid = DWLocInit( Client );
                    dl = DWLocFini( Client, locid );
                }
                dh = dwarfType( curr->sym_type, DC_DEFAULT );/* CppName no reentrant */
                dh = DWVariable( Client,
                         dh,
                         dl,
                         NULL,
                         dl_seg,
                         CppNameDebug( curr ),
                         0,
                         flags );
                if( dl_seg != NULL ){
                    DWLocTrash( Client, dl_seg );
                }
                if( InDebug ){
                    dh = 0;   // if debug we don't want to clash with cg_handle
                }
            } else if( SymIsThisDataMember( curr ) ){
                TYPE sym_type = curr->sym_type;
                TYPE btf = TypedefModifierRemoveOnly( sym_type );

                locid = DWLocInit( Client );
                DWLocOp( Client, locid, DW_LOC_plus_uconst,
                                         curr->u.offset );
                pt = PointerTypeEquivalent( sym_type );
                if( pt
                 && pt->id == TYP_POINTER
                 && (pt->flag & TF1_REFERENCE) ) {
                     DWLocOp0( Client, locid, DW_LOC_deref );
                }
                dl = DWLocFini( Client, locid );
                if( btf->id == TYP_BITFIELD ) {
                    int  strt;
                    int  tsize;

                    tsize = CgTypeSize( btf->of );
                    strt = 8*tsize-(btf->u.b.field_start+btf->u.b.field_width);
                    dh = dwarfType( sym_type, DC_DEFAULT );/* CppName no reentrant */
                    dh = DWAddBitField( Client,
                                   dh,
                                   dl,
                                   tsize,
                                   strt,
                                   btf->u.b.field_width,
                                   CppNameDebug( curr ),
                                   flags );
                } else {
                    dh = dwarfType( sym_type, DC_DEFAULT );/* CppName no reentrant */
                    dh = DWAddField( Client,
                                dh,
                                dl,
                                CppNameDebug( curr ),
                                flags );
                }
            }
            DWLocTrash( Client, dl );
        } else if( curr->id == SC_ACCESS ) {
            // fixme: access modifiers ignored for now
            dh = 0;
        } else {
            dh = 0;
            #ifndef NDEBUG
                DumpSymbol( curr );
                CFatal( "dwarf: illegal member" );
            #endif
        }
        if( dh != 0 ) {
            sym_reset( curr );
            sym_update( curr, SF2_DW_HANDLE_DEF, dh );
        }
        curr = ScopeOrderedNext( stop, curr );
    }
    return( check_friends );
}

static dw_handle dwarfClass( TYPE type, DC_CONTROL control )
/**********************************************************/
{
    dw_handle       dh;
    char            *name;
    boolean         defined;
    boolean         check_friends;

    type_reset( type );
    if( type->dbgflag & TF2_DWARF ) {
        dh = type->dbg.handle;
    } else {
        uint    kind;
        if( type->flag & TF1_UNION ) {
            kind = DW_ST_UNION;
        } else if( type->flag & TF1_STRUCT ) {
            kind = DW_ST_STRUCT;
        } else {
            kind = DW_ST_CLASS;
        }
        dh = DWStruct( Client, kind );
        type_update( type, TF2_DWARF_FWD, dh );
    }
    if( type->dbgflag & TF2_DWARF_DEF ) {
        return( dh );
    }
    defined = (type->u.c.info->defined != 0);
    if( !defined || type->u.c.info->unnamed
       || (control & DC_DEFINE) ) {
        type_update( type, TF2_DWARF_DEF, dh );
        if( (type->u.c.info->anonymous == 0)
          &&(type->u.c.info->unnamed == 0) ) {
            name = SimpleTypeName( type );
        } else {
            name = NULL;
        }
        DWBeginStruct( Client,
                       dh,
                       CgTypeSize( type ),
                       name,
                       0,
                       (defined ? 0 : DW_FLAG_DECLARATION ) );
        check_friends = FALSE;
        if( defined ) {
            check_friends = dwarfClassInfo( type );
        }
        DWEndStruct( Client );
        if( check_friends ) {
            dwarfClassInfoFriend( type, FALSE );
        }
    }
    return( dh );
}

static dw_handle dwarfEnum( TYPE type, DC_CONTROL control )
/*********************************************************/
{
    dw_handle       dh;

    type_reset( type );
    if( type->dbgflag & TF2_DWARF ) {
        dh = type->dbg.handle;
    } else {
        dh = DWHandle( Client, DW_ST_NONE );
        type_update( type, TF2_DWARF_FWD, dh );
    }
    if( type->dbgflag & TF2_DWARF_DEF ) {
        return( dh );
    }

    if( (type->flag & TF1_UNNAMED)    //check for enum{ }foo
      || ( control & DC_DEFINE ) ){
        SYMBOL      sym;
        type_update( type, TF2_DWARF_DEF, dh );
        DWHandleSet( Client, dh );
        dh = DWBeginEnumeration( Client,
                                 CgTypeSize( type->of ),
                                 SimpleTypeName( type ),
                                 0,
                                 0 );
        sym = type->u.t.sym->thread;
        while( SymIsEnumeration( sym ) ) {
            // fixme: enums need to be in reverse order
            DWAddConstant( Client, sym->u.sval, sym->name->name );
            sym = sym->thread;
        }
        DWEndEnumeration( Client );
    }
    return( dh );
}

static dw_handle dwarfTypedef( TYPE type, DC_CONTROL control )
/************************************************************/
{
    dw_handle       dh;

    type_reset( type );
    if( type->dbgflag & TF2_DWARF ) {
        dh = type->dbg.handle;
    } else {
        dh = DWHandle( Client, DW_ST_NONE );
        type_update( type, TF2_DWARF_FWD, dh );
    }
    if( type->dbgflag & TF2_DWARF_DEF ) {
        return( dh );
    }

    if( control & DC_DEFINE ) {
        dw_handle of_hdl;
        TYPE      of_type;
        SYMBOL    sym;
        uint      flags;
        type_update( type, TF2_DWARF_DEF, dh );
        sym = type->u.t.sym;
        of_type = StructType( type->of );
        if( (of_type == type->of)

⌨️ 快捷键说明

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