dwarf.c

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

C
2,009
字号
/****************************************************************************
*
*                            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 <setjmp.h>
#include <assert.h>

#include "preproc.h"
#include "errdefns.h"
#include "cgfront.h"
#include "template.h"
#include "codegen.h"
#include "pragdefn.h"
#include "cginfo.h"
#include "cgback.h"
#include "ring.h"
#include "dbg.h"
#include "dw.h"
#include "cppdwarf.h"
#include "dwarfdbg.h"
#include "browsio.h"
#include "vfun.h"
#include "dbgsupp.h"
#include "pcheader.h"
#include "name.h"
#include "icopmask.h"
#include "fmttype.h"

#define _typeHasForwardDwarfHandle( type ) \
( ((type)->dbgflag & (TF2_SYMDBG|TF2_DWARF_FWD)) == (TF2_SYMDBG|TF2_DWARF_FWD) )
#define _typeHasDefinedDwarfHandle( type ) \
( ((type)->dbgflag & (TF2_SYMDBG|TF2_DWARF_DEF)) == (TF2_SYMDBG|TF2_DWARF_DEF) )

#define _typeHasPCHDwarfHandle( type ) \
( CompFlags.pch_debug_info_read && ((type)->dbgflag & TF2_DBG_IN_PCH ) != 0 )


extern pointer DFClient( void );
extern void DFDwarfLocal( dw_client client, dw_loc_id locid, cg_sym_handle sym  );

typedef enum
{   DC_RETURN           = 0x01,         // this is a return type
    DC_DEFINE           = 0x02,         // generate definition
    DC_FAKE             = 0x04,         // flag as artificial
    DC_DEFAULT          = 0x00          // default behaviour
} DC_CONTROL;


static uint      dwarfMarkInternalName( SYMBOL, uint );
static boolean   dwarfClassInfoFriend( TYPE, boolean );
static boolean   dwarfClassInfo( TYPE );
static dw_handle dwarfClass( TYPE, DC_CONTROL );
static dw_handle dwarfEnum( TYPE, DC_CONTROL );
static dw_handle dwarfTypedef( TYPE, DC_CONTROL );
static dw_handle dwarfTypeArray( TYPE );
static dw_handle dwarfTypeFunction( TYPE );
static dw_handle dwarfTypeModifier( TYPE );
static dw_handle dwarfTypeMemberPointer( TYPE );
static dw_handle dwarfType( TYPE, DC_CONTROL );
static void      dwarfLocation( SYMBOL );
static dw_handle dwarfData( SYMBOL );
static dw_handle dwarfFunctionDefine( SYMBOL, CGFILE * );
static dw_handle dwarfFunction( SYMBOL, DC_CONTROL );
static dw_handle dwarfSymbol( SYMBOL, DC_CONTROL );
static void      dwarfEmitSymbolScope( SCOPE );

static TYPE             vf_FieldType;
static unsigned         vf_FieldTypeSize;
static TYPE             pvf_FieldType;
static TYPE             vb_FieldType;
static unsigned         vb_FieldTypeSize;
static TYPE             pvb_FieldType;

static bool             InDebug;
static dw_client        Client;
static dw_loc_handle    dummyLoc;
static SRCFILE          currentFile;

static void virtTblTypes( void ){
    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 );
}

static void initDwarf( bool debug, dsi_control control ) {
    virtTblTypes();
    InDebug = debug;
    currentFile = NULL;
    DbgSuppInit( control );
}

static void type_reset( TYPE type )
/*********************************/
{
    if( InDebug ){
        if( !(type->dbgflag & TF2_SYMDBG ) ){
            if(( type->dbgflag & TF2_PCH_DBG_EXTERN ) && CompFlags.pch_debug_info_read ){
                type->dbgflag |= TF2_SYMDBG | TF2_DWARF_DEF;
                type->dbg.handle = DWRefPCH( Client, type->dbg.pch_handle );
            }else{
                type->dbgflag = (type->dbgflag & ~TF2_DWARF) | TF2_SYMDBG;
            }
        }
    }
}

static void type_update( TYPE type, type_dbgflag mask, dw_handle dh )
/*******************************************************************/
{
    type->dbgflag = (type->dbgflag & ~TF2_DWARF ) | mask;
    type->dbg.handle = dh;
}

static void sym_reset( SYMBOL sym )
/*********************************/
{
    if( InDebug ){
        if( !(sym->flag2 & SF2_SYMDBG) ){
            sym->flag2 = (sym->flag2 & ~SF2_DW_HANDLE) | SF2_SYMDBG;
        }
    }
}

static void sym_update( SYMBOL sym, symbol_flag2 mask, dw_handle dh )
/*******************************************************************/
{
    #ifndef NDEBUG
    if( sym->flag2 & SF2_CG_HANDLE ){
        DumpSymbol( sym );
        CFatal( "dwarf: handle for sym busy" );
    }
    #endif
    sym->flag2 |= mask;
    if( sym->flag2 & SF2_TOKEN_LOCN ){
        sym->locn->dwh = dh;
    }
}

static void dwarfTokenLocation( TOKEN_LOCN *locn )
/************************************************/
{

    if( currentFile != locn->src_file ) {
        DWDeclFile( Client, SrcFileFullName( locn->src_file ) );
        currentFile = locn->src_file;
    }
    DWDeclPos( Client, locn->line, locn->column );
}

static void dwarfLocation( SYMBOL sym )
/*************************************/
{
    if( sym->flag2 & SF2_TOKEN_LOCN ) {
        dwarfTokenLocation( &sym->locn->tl );
    }
}

static uint dwarfMarkInternalName( SYMBOL sym, uint flags )
/*********************************************************/
{
    if( !IsCppNameInterestingDebug( sym ) ) {
        flags |= DW_FLAG_ARTIFICIAL;
    }
    return( flags );
}

static SYMBOL dwarfDebugSymAlias( SYMBOL sym )
/********************************************/
{
    SYMBOL check;

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

static dw_loc_handle dwarfDebugStaticLoc( SYMBOL sym )
/***********************************************/
{
    TYPE        pt;
    dw_loc_id       locid;
    dw_loc_handle   dl;


    locid = DWLocInit( Client );
    sym = dwarfDebugSymAlias( sym );
    DWLocStatic( Client, locid, (dw_sym_handle) sym );
    pt = PointerTypeEquivalent( sym->sym_type );
    if( pt != NULL
     && pt->id == TYP_POINTER
     && (pt->flag & TF1_REFERENCE) ) {
        DWLocOp0( Client, locid, DW_LOC_deref );
    }
    dl = DWLocFini( Client, locid );
    DbgAddrTaken( sym );
    return( dl );
}

#if _INTEL_CPU
static dw_loc_handle dwarfDebugStaticSeg( SYMBOL sym )
/***********************************************/
{
    dw_loc_id       locid;
    dw_loc_handle   dl;


    locid = DWLocInit( Client );
    sym = dwarfDebugSymAlias( sym );
    DWLocSegment( Client, locid, (dw_sym_handle) sym );
    dl = DWLocFini( Client, locid );
    DbgAddrTaken( sym );
    return( dl );
}
#endif

static uint  dwarfAddressClassFlags( TYPE type ){
/**********************************/
    uint    flags;
    uint    ptr_type;
    uint    offset_type;

    ptr_type = CgTypeOutput( type );
    switch( ptr_type ) {
    case T_HUGE_POINTER:
        flags = DW_PTR_TYPE_HUGE16;
        break;
    case T_LONG_POINTER:
    case T_LONG_CODE_PTR:
        offset_type = CgTypeOffset();
        if( offset_type == T_UINT_4 ){
            flags = DW_PTR_TYPE_FAR32;
        }else{
            flags = DW_PTR_TYPE_FAR16;
        }
        break;
    case T_NEAR_POINTER:
    case T_NEAR_CODE_PTR:
    case T_POINTER:
#if _CPU == _AXP
        flags = DW_PTR_TYPE_DEFAULT;
#else
        if(  TargetSwitches & FLAT_MODEL ) {
            flags = DW_PTR_TYPE_DEFAULT;
        }else{
            offset_type = CgTypeOffset();
            if( offset_type == T_UINT_4 ){
                flags = DW_PTR_TYPE_NEAR32;
            }else{
                flags = DW_PTR_TYPE_NEAR16;
            }
        }
#endif
        break;
    default:
        CFatal( "dwarf: unknown pointer type" );
    }
    return( flags );
}

static dw_handle dwarfDebugMemberFuncDef( CLASSINFO *info, SYMBOL sym )
/********************************************************************/
{
    TYPE        base;
    type_flag   tf;
    dw_handle   return_dh;
    dw_handle   dh;
    uint        call_type;
    uint        flags;
    dw_loc_id       locid;
    dw_loc_handle   dl;
    dw_loc_handle   dl_virt;
    dw_loc_handle   dl_seg;
    char           *name;

    call_type = 0;
    base = TypeModFlags( sym->sym_type, &tf );
    flags = dwarfAddressClassFlags( sym->sym_type );
    if( base->flag & TF1_INLINE ) {
        flags |= DW_FLAG_DECLARED_INLINE;
    }
    if( tf & TF1_NEAR ) {
        call_type |= DW_SB_NEAR_CALL;
    }
    if( tf & TF1_FAR ) {
        call_type |= DW_SB_FAR_CALL;
    }
    if( tf & TF1_FAR16 ) {
        call_type |= DW_SB_FAR16_CALL;
    }
    flags |= DW_FLAG_PROTOTYPED;
    if( SymIsStaticMember( sym ) ) {
        flags |= DW_SUB_STATIC;
    }
    if( sym->flag & SF_PRIVATE ) {
        flags |= DW_FLAG_PRIVATE;
    } else if( sym->flag & SF_PROTECTED ) {
        flags |= DW_FLAG_PROTECTED;
    } else {
        flags |= DW_FLAG_PUBLIC;
    }
    flags = dwarfMarkInternalName( sym, flags );
    flags |= DW_FLAG_DECLARATION;
    return_dh = dwarfType( base->of, DC_DEFAULT );
    name = CppNameDebug( sym );
    if( SymIsVirtual( sym ) ) {
        flags |= DW_FLAG_VIRTUAL;
        locid = DWLocInit( Client );
        DWLocConstS( Client, locid, info->vf_offset );
        DWLocOp0( Client, locid, DW_LOC_plus );
        if( DefaultMemoryFlag( pvf_FieldType ) != TF1_NEAR ){
            DWLocOp0( Client, locid, DW_LOC_xderef );
        }else{
            DWLocOp0( Client, locid, DW_LOC_deref );
        }
        DWLocConstS( Client, locid, ( sym->u.offset - VFUN_BASE ) *
                                    vf_FieldTypeSize );
        DWLocOp0( Client, locid, DW_LOC_plus );
        if( DefaultMemoryFlag( vf_FieldType ) != TF1_NEAR ){
            DWLocOp0( Client, locid, DW_LOC_xderef );
        }else{
            DWLocOp0( Client, locid, DW_LOC_deref );
        }
        dl_virt = DWLocFini( Client, locid );
        dh = DWBeginVirtMemFuncDecl( Client,
                   return_dh,
                   dl_virt,
                   name,
                   flags );
        DWLocTrash( Client, dl_virt );
    }else{
        dl = dwarfDebugStaticLoc( sym );
    #if _CPU == _AXP
        dl_seg = NULL;
    #else
        if(!( TargetSwitches & FLAT_MODEL )) {
            dl_seg =  dwarfDebugStaticSeg( sym );
        }else{
            dl_seg = NULL;
        }
    #endif
        dh = DWBeginMemFuncDecl( Client,
                   return_dh,
                   dl_seg,
                   dl,
                   name,
                   flags );
        DWLocTrash( Client, dl );
        if( dl_seg != NULL ){
            DWLocTrash( Client, dl_seg );
        }
    }
    return( dh );
}
#if 0
static void dwarfPumpArgTypes( TYPE type )
/*************************************/
{ // force out types for args
    arg_list    *alist;
    int         i;
    TYPE        p;

    alist = TypeArgList( type );
    for( i = 0 ; i < alist->num_args ; i++ ) {
        if( alist->type_list[i]->id != TYP_DOT_DOT_DOT ) {
            p = alist->type_list[i];

⌨️ 快捷键说明

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