symdbg.c

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

C
1,175
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"

#include <assert.h>

#include "errdefns.h"
#include "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "pragdefn.h"
#include "cginfo.h"
#include "carve.h"
#include "ppops.h"
#include "ring.h"
#include "vfun.h"
#include "symdbg.h"
#include "dbgsupp.h"

typedef struct fwd_info FWD_INFO;
struct fwd_info {
    FWD_INFO    *next;
    TYPE        type;
    dbg_name    dn;
    dbg_type    dt;
    dbg_name    comp_dn;
};

// carve storage for fwd_info structures
#define BLOCK_FWD_INFO      16
static carve_t carveFWD_INFO;

static FWD_INFO *prevFwdInfo;
static dbg_type scopeEnum;
static dbg_type scopeUnion;
static dbg_type scopeStruct;
static dbg_type scopeClass;
static TYPE     vf_FieldType;
static TYPE     pvf_FieldType;
static unsigned vf_FieldTypeSize;
static TYPE     vb_FieldType;
static TYPE     pvb_FieldType;
static unsigned vb_FieldTypeSize;

// prototypes
static dbg_loc symbolicDebugSetSegment( dbg_loc dl, SYMBOL sym );
static dbg_loc symbolicDebugSetCodeSegment( dbg_loc dl );
static dbg_type symbolicDebugClassType( TYPE type );
static void doSymbolicDebugFundamentalType( TYPE type, void *data );
static void symbolicDebugFundamentalType( void );
static void doSymbolicDebugNamedType( TYPE type, void *data );
static void symbolicDebugNamedType( void );
static void symbolicDebugSymbol( void );

void SymbolicDebugInit( void )
/****************************/
{
    assert( sizeof( vf_FieldType->dbg.handle ) == sizeof( dbg_type ) );

    if( GenSwitches & DBG_TYPES ) {
        scopeEnum = DBScope( "enum" );
        scopeUnion = DBScope( "union" );
        scopeStruct = DBScope( "struct" );
        scopeClass = DBScope( "class" );

        DbgSuppInit( DSI_NULL );
    }

    if( GenSwitches & DBG_LOCALS ) {
        pvf_FieldType = MakeVFTableFieldType( TRUE );
        vf_FieldType = PointerTypeEquivalent( pvf_FieldType )->of;
        vf_FieldTypeSize = CgTypeSize( vf_FieldType );

        pvb_FieldType = MakeVBTableFieldType( TRUE );
        vb_FieldType = PointerTypeEquivalent( pvb_FieldType )->of;
        vb_FieldTypeSize = CgTypeSize( vb_FieldType );
    }
    carveFWD_INFO  = CarveCreate( sizeof( FWD_INFO ), BLOCK_FWD_INFO );

}

void SymbolicDebugFini( void )
/****************************/
{
#ifndef NDEBUG
    CarveVerifyAllGone( carveFWD_INFO, "FWD_INFO" );
#endif
    CarveDestroy( carveFWD_INFO );
}

static cg_sym_handle symbolicDebugSymAlias( SYMBOL sym )
/******************************************************/
{
    SYMBOL check;

    sym = SymDeAlias( sym );
    check = SymIsAnonymous( sym );
    if( check != NULL ) {
        sym = check;
    }
    return( (cg_sym_handle)sym );
}

static dbg_loc symbolicDebugSetSegment( dbg_loc dl, SYMBOL sym )
/**************************************************************/
{
    dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
    dl = DBLocOp( dl, DB_OP_XCHG, 1 );
    dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
    return( dl );
}

static dbg_loc symbolicDebugSetCodeSegment( dbg_loc dl )
/******************************************************/
{
    if( !IsBigCode() ) {
        dl = symbolicDebugSetSegment( dl, DefaultCodeSymbol );
        DbgAddrTaken( DefaultCodeSymbol );
    }
    return( dl );
}

dbg_loc SymbolicDebugSetDataSegment( dbg_loc dl )
/***********************************************/
{
    if( !IsBigData() ) {
        dl = symbolicDebugSetSegment( dl, DefaultDataSymbol );
        DefaultDataSymbol->flag |= SF_REFERENCED;
    }
    return( dl );
}

static dbg_loc symbolicDebugSymAddr( dbg_loc dl, SYMBOL sym )
/***********************************************************/
{
#ifdef DISABLE_CGRF
    if( SymIsReferenced( sym ) ) {
        DbgAddrTaken( sym );
        dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
        if( SymIsInitialized( sym ) ) {
            cgfile = CgioLocateFile( sym );
            if( cgfile != NULL ) {
                cgfile->refed = TRUE;
            }
        }
    }
#else
    DbgAddrTaken( sym );
    dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
#endif
    return( dl );
}


static dbg_type symWVDebugClassType( TYPE type )
/*************************************************/
{ // Dump WV class
    dbg_type    dt;
    dbg_struct  ds;
    dbg_loc     dl;
    SYMBOL      stop, curr;
    BASE_CLASS  *base;
    CLASSINFO   *info;
    CLASSINFO   *base_info;
    TYPE        root = TypedefModifierRemoveOnly( type );

    ds = DBBegStruct( CgTypeOutput( type ), !(root->flag & TF1_UNION) );
    dt = DBStructForward( ds );
    info = root->u.c.info;
    if( dt != DBG_NIL_TYPE  ){
        info->dbg_no_vbases = dt;
        type->dbg.handle = dt;
    }

    // define all the members
    // first data members
    stop = ScopeOrderedStart( root->u.c.scope );
    curr = ScopeOrderedNext( stop, NULL );
    while( curr != NULL ) {
        if( SymIsClassMember( curr ) &&
            SymIsData( curr ) &&
            !SymIsEnumeration( curr ) &&
            IsCppNameInterestingDebug( curr ) ) {
            uint    attribute;
            byte    offset = 0;
            byte    length = 0;
            if( curr->flag & SF_PRIVATE ) {
                attribute = FIELD_ATTR_PRIVATE;
            } else if( curr->flag & SF_PROTECTED ) {
                attribute = FIELD_ATTR_PROTECTED;
            } else {
                attribute = FIELD_ATTR_PUBLIC;
            }
            if( curr->sym_type->id == TYP_BITFIELD ) {
                offset = curr->sym_type->u.b.field_start;
                length = curr->sym_type->u.b.field_width;
            }
            dl = DBLocInit();
            if( SymIsStaticDataMember( curr ) ) {
                DbgAddrTaken( curr );
                dl = DBLocSym( dl, symbolicDebugSymAlias( curr ) );
            } else if( SymIsThisDataMember( curr ) ){
                TYPE pt;
                if( curr->u.offset != 0 ) {
                    dl = DBLocConst( dl, curr->u.offset );
                    dl = DBLocOp( dl, DB_OP_ADD, 0 );
                }
                pt = PointerTypeEquivalent( curr->sym_type );
                if( pt
                 && pt->id == TYP_POINTER
                 && (pt->flag & TF1_REFERENCE) ) {
                    dl = DBLocOp( dl, DB_OP_POINTS,
                                  CgTypeOutput( curr->sym_type ) );
                    dl = SymbolicDebugSetDataSegment( dl );
                }
            } else {
                CFatal( "symdbg: illegal data member symbol" );
            }
            DBAddLocField( ds,
                           dl,
                           attribute,
                           offset,
                           length,
                           CppNameDebug( curr ),
                           SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
            DBLocFini( dl );
        }
        curr = ScopeOrderedNext( stop, curr );
    }
    if( info->has_vbptr ) {
        dl = DBLocInit();
        if( info->vb_offset != 0 ) {
            dl = DBLocConst( dl, info->vb_offset );
            dl = DBLocOp( dl, DB_OP_ADD, 0 );
        }
        DBAddLocField( ds, dl, FIELD_ATTR_INTERNAL, 0, 0, "__vbptr",
                       SymbolicDebugType( pvb_FieldType, SD_DEFAULT ) );
        DBLocFini( dl );
    }
    if( info->has_vfptr ) {
        dl = DBLocInit();
        if( info->vf_offset != 0 ) {
            dl = DBLocConst( dl, info->vf_offset );
            dl = DBLocOp( dl, DB_OP_ADD, 0 );
        }
        DBAddLocField( ds, dl, FIELD_ATTR_INTERNAL, 0, 0, "__vfptr",
                       SymbolicDebugType( pvf_FieldType, SD_DEFAULT ) );
        DBLocFini( dl );
    }

    // now function members
    stop = ScopeOrderedStart( root->u.c.scope );
    curr = ScopeOrderedNext( stop, NULL );
    while( curr != NULL ) {
        if( SymIsClassMember( curr ) &&
            !SymIsData( curr ) &&
            IsCppNameInterestingDebug( curr ) ) {
            if( SymIsEnumeration( curr ) ) {
                SymbolicDebugType( curr->sym_type, SD_DEFAULT );
            } else {
                uint    attribute;
                if( curr->flag & SF_PRIVATE ) {
                    attribute = FIELD_ATTR_PRIVATE;
                } else if( curr->flag & SF_PROTECTED ) {
                    attribute = FIELD_ATTR_PROTECTED;
                } else {
                    attribute = FIELD_ATTR_PUBLIC;
                }
                dl = DBLocInit();
                if( SymIsStaticFuncMember( curr ) ) {
                    dl = symbolicDebugSymAddr( dl, curr );
                } else if( SymIsThisFuncMember( curr ) ) {
                    if( SymIsVirtual( curr ) ) {
                        if( info->vf_offset != 0 ) {
                            dl = DBLocConst( dl, info->vf_offset );
                            dl = DBLocOp( dl, DB_OP_ADD, 0 );
                        }
                        dl = DBLocOp( dl, DB_OP_POINTS,
                                      CgTypeOutput( pvf_FieldType ) );
                        dl = DBLocConst( dl, ( curr->u.offset - VFUN_BASE ) *
                                             vf_FieldTypeSize );
                        dl = DBLocOp( dl, DB_OP_ADD, 0 );
                        dl = DBLocOp( dl, DB_OP_POINTS,
                                      CgTypeOutput( vf_FieldType ) );
                        dl = symbolicDebugSetCodeSegment( dl );
                    } else {
                        dl = symbolicDebugSymAddr( dl, curr );
                    }
                } else {
                    CFatal( "symdbg: illegal function member symbol" );
                }
                DBAddLocField( ds,
                               dl,
                               attribute,
                               0,
                               0,
                               CppNameDebug( curr ),
                               SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
                DBLocFini( dl );
            }
        }
        curr = ScopeOrderedNext( stop, curr );
    }

    // define all the direct non-virtual bases
    RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
        if( _IsDirectNonVirtualBase( base ) ) {
            dl = DBLocInit();
            dl = DBLocConst( dl, base->delta );
            SymbolicDebugType( base->type, SD_DEFAULT );
            base_info = StructType( base->type )->u.c.info;
            DBAddInheritance( ds, base_info->dbg_no_vbases,
                   FIELD_ATTR_PUBLIC, INHERIT_DBASE,  dl );
            DBLocFini( dl );
        }
    } RingIterEnd( base )
    dt = DBEndStruct( ds );
    info->dbg_no_vbases= dt;

    if( ScopeHasVirtualBases( root->u.c.scope ) ) {
        ds = DBBegStruct( CgTypeOutput( type ), !(root->flag & TF1_UNION) );

        // define own component
        dl = DBLocInit();
        dl = DBLocConst( dl, 0 );
        DBAddInheritance( ds, info->dbg_no_vbases,
                   FIELD_ATTR_PUBLIC, INHERIT_DBASE,  dl );
        DBLocFini( dl );

        // define all the direct+indirect virtual bases
        RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
            if( _IsVirtualBase( base ) ) {
                dl = DBLocInit();
                if( info->vb_offset != 0 ) {
                    dl = DBLocConst( dl, info->vb_offset );
                    dl = DBLocOp( dl, DB_OP_ADD, 0 );
                }
                dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( pvb_FieldType ) );
                dl = DBLocConst( dl, base->vb_index * vb_FieldTypeSize );
                dl = DBLocOp( dl, DB_OP_ADD, 0 );
                dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( vb_FieldType ) );
                if( info->vb_offset != 0 ) {
                    dl = DBLocConst( dl, info->vb_offset );
                    dl = DBLocOp( dl, DB_OP_ADD, 0 );
                }
                SymbolicDebugType( base->type, SD_DEFAULT );
                base_info = StructType( base->type )->u.c.info;
                DBAddInheritance( ds, base_info->dbg_no_vbases,
                            FIELD_ATTR_PUBLIC, INHERIT_IVBASE,  dl );
                DBLocFini( dl );
            }
        } RingIterEnd( base )
        dt = DBEndStruct( ds );
    }
    root->dbgflag |= TF2_SYMDBG;
    root->dbg.handle = dt;
    type->dbg.handle = dt;

    return( dt );
}


⌨️ 快捷键说明

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