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 + -
显示快捷键?