drdecnam.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,033 行 · 第 1/5 页
C
2,033 行
/****************************************************************************
*
* 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: Decode names in DWARF debug info. Language dependent.
*
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <watcom.h>
#include <dwarf.h>
#include "drpriv.h"
#include "drutils.h"
#include "drscope.h"
#include "drdecnam.h"
/*----------------*
* type definitions
*----------------*/
/*
* A simple string type to store a pointer to the string and its length
*/
typedef struct {
char * s; /* the string */
unsigned short l; /* length of the string (excluding \0) */
} String;
typedef struct Node_S {
struct Node_S *next;
bool user_def; /* TRUE if defined by user */
dr_handle entry; /* if this is user-def'd, the entry */
dr_sym_type sym_type; /* if u_def'd, the type of symbol */
String buf; /* may contain several (non usr-def) words */
} *Node_T; /* note - a pointer to Node_S */
/*
* Put new nodes at front or back?
*/
typedef enum { LIST_HEAD, LIST_TAIL } ListEnd_T;
typedef struct {
Node_T head; /* head */
Node_T tail; /* tail */
ListEnd_T end; /* end to add at */
} List_T;
/*
* this structure stores the various parts of a name.
*/
typedef struct {
List_T dec_plg; /* prolog for the declaration .. this is stored */
/* in forward order, not reversed */
List_T type_plg; /* prolog of type .. eg extern, const, volatile */
List_T type_bas; /* base part of type .. int * */
List_T type_ptr; /* pointer part of type *, & */
List_T type_elg; /* epilog of type .. const, volatile */
List_T type_inh; /* list of base classes */
List_T var_plg; /* prolog for variable name .. eg (* */
List_T var_bas; /* base of variable name .. foo */
List_T var_elg; /* epilog for variable name .. eg ) (param list) */
/*
* these are stored in forward order, and the space is put on at
* the front
*/
List_T func_plg; /* plg for function paragmeters "(" */
List_T func_bas; /* base of function's parameters */
List_T func_elg; /* elg for function parms " )" */
} BrokenName_T;
static BrokenName_T Empty_Broken_Name = {
{ NULL, NULL, LIST_TAIL }, /* dec_plg */
{ NULL, NULL, LIST_HEAD }, /* type_plg */
{ NULL, NULL, LIST_HEAD }, /* type_bas */
{ NULL, NULL, LIST_HEAD }, /* type_ptr */
{ NULL, NULL, LIST_TAIL }, /* type_elg */
{ NULL, NULL, LIST_TAIL }, /* type_inh */
{ NULL, NULL, LIST_HEAD }, /* var_plg */
{ NULL, NULL, LIST_HEAD }, /* var_bas */
{ NULL, NULL, LIST_HEAD }, /* var_elg */
{ NULL, NULL, LIST_TAIL }, /* func_plg */
{ NULL, NULL, LIST_TAIL }, /* func_bas */
{ NULL, NULL, LIST_TAIL } /* func_elg*/
};
/*
* this structure holds the current location
*/
typedef struct {
dr_handle parent; /* containing die */
dr_handle entry_st; /* start of the die */
dr_handle entry_cr; /* location in the die */
dr_handle abbrev_st; /* start of the abbrev */
dr_handle abbrev_cr; /* location within the abbrev */
dr_handle tag; /* the tag */
unsigned_8 child; /* DW_children_yes if entry has children */
bool inParam; /* decorating parameters? (only used for FORTRAN)*/
} Loc_T;
/*
* put new symbols to left or right of base type?
*/
typedef enum { TYPE_PLG, TYPE_BAS, TYPE_PTR, TYPE_ELG } TypeSide_T;
typedef struct {
BrokenName_T *decname;
int firstTime;
} BaseSearchInfo;
/*----------------*
* static functions
*----------------*/
static BrokenName_T BuildList( dr_handle, dr_handle );
static void BuildCList( BrokenName_T *, Loc_T * );
static void BuildFortranList( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateVariable( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateMember( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateTypedef( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateNameSpace( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateLabel( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateFunction( BrokenName_T *, Loc_T * );
static List_T StartFunctionParms( Loc_T * );
static List_T DecorateParameter( Loc_T * );
static BrokenName_T *DecorateType( BrokenName_T *, Loc_T *, dr_handle );
static void SwapModifier( BrokenName_T * );
static BrokenName_T *AddPtrModifier( BrokenName_T *, Loc_T * );
static BrokenName_T *DecSubroutineType( BrokenName_T *, Loc_T *, dr_handle );
static void AddTypeString( BrokenName_T *, String, TypeSide_T);
static BrokenName_T *DecorateCompoundType( BrokenName_T *, Loc_T *,
String, dr_sym_type );
static BrokenName_T *DecorateBases( BrokenName_T *, Loc_T * );
static int baseHook( dr_sym_type, dr_handle, char *, dr_handle, void * );
static BrokenName_T *DecorateArray( BrokenName_T *, Loc_T * );
static BrokenName_T *DecoratePtrToMember( BrokenName_T *, Loc_T * );
static void ReadBlock( unsigned_8 **buf, dr_handle entry, unsigned len );
static void FORDecVariable( BrokenName_T *, Loc_T * );
static void FORAddConstVal( BrokenName_T * decname, Loc_T * loc, Loc_T * type_loc );
static void FORDecParam( BrokenName_T *, Loc_T * );
static void FORDecMember( BrokenName_T *, Loc_T * );
static void FORDecSubprogram( BrokenName_T *, Loc_T * );
static void FORDecEntryPoint( BrokenName_T *, Loc_T * );
static void FORDecStructure( BrokenName_T *, Loc_T * );
static void FORDecNameList( BrokenName_T *, Loc_T * );
static void FORDecRecord( BrokenName_T *, Loc_T * );
static void FORDecUnion( BrokenName_T *, Loc_T * );
static void FORDecType( BrokenName_T *, Loc_T * );
static void FORDecArray( BrokenName_T *, Loc_T * );
static void FORDecString( BrokenName_T *, Loc_T * );
static void FORDecCommon( BrokenName_T *, Loc_T * );
static String FormName( BrokenName_T * );
static List_T FormList( BrokenName_T * );
static void FillLoc( Loc_T *, dr_handle );
static void FreeList( List_T );
static void IterateList( void (*)( void *, char *,
int, dr_handle, dr_sym_type ),
void *, List_T );
static void ReallocStr( String * );
static void ListConcat( List_T *, String );
static void ListAdd( List_T *, Node_T );
static void EndNode( List_T *, bool, dr_handle, dr_sym_type );
static Node_T DeleteTail( List_T * );
/*-----------------*
* static variables
*-----------------*/
static String const ArrayLeftKwd = { "[", 1 };
static String const ArrayRightKwd = { "]", 1 };
static String const BaseKwd = { " : ", 3 };
static String const BaseSepKwd = { ", ", 2 };
static String const ClassKwd = { " ssalc", 6 };
static String const ConstKwd = { "const ", 6 };
static String const EnumKwd = { " mune", 5 };
static String const ExternKwd = { "extern ", 7 };
static String const FarKwd = { " raf", 4 };
static String const FuncEndKwd = { ")", 1 };
static String const FuncStartKwd = { "(", 1 };
static String const HugeKwd = { " eguh", 5 };
static String const LabelKwd = { " :", 2 };
static String const MemberKwd = { "::", 2 };
static String const NearKwd = { " raen", 5 };
static String const ParmSepKwd = { ", ", 2 };
static String const PtrKwd = { "*", 1 };
static String const RefKwd = { "&", 1 };
static String const SpaceKwd = { " ", 1 };
static String const StructKwd = { " tcurts", 7 };
static String const TypedefKwd = { "typedef ", 8 };
static String const NameSpaceKwd = { "namespace ", 10 };
static String const UnionKwd = { " noinu", 6 };
static String const UnspecParamKwd = { "...", 3 };
static String const VolatileKwd = { "volatile ", 9 };
static String const FORArrayLeftKwd = { "(", 1 };
static String const FORArrayRightKwd = { ")", 1 };
static String const FORAllocArrKwd = { ":", 1 }; /* allocatable array */
static String const FORAssumeArrKwd = { "*", 1 }; /* assumed-size array */
static String const FORSepKwd = { ",", 1 };
static String const FORFuncStartKwd = { "(", 1 };
static String const FORFuncEndKwd = { ")", 1 };
static String const FORFuncKwd = { " NOITCNUF", 9 };
static String const FORSubprogramKwd = { " ENITUORBUS", 11 };
static String const FOREntryPointKwd = { " YRTNE", 6 };
static String const FORMemberKwd = { ".", 1 };
static String const FORParmSepKwd = { ", ", 2 };
static String const FORSlashKwd = { "/", 1 };
static String const FORStructKwd = { " ERUTCURTS", 10 };
static String const FORNameListKwd = { " TSILEMAN", 9 };
static String const FORCommonKwd = { " NOMMOC", 7 };
static String const FORRecordKwd = { " DROCER", 7 };
static String const FORUnionKwd = { "NOINU", 5 };
static String const FORStringKwd = { "*RETCARAHC", 10 };
static String const FORParamKwd = { " RETEMARAP", 10 };
static String const FOREqualKwd = { "=", 1 };
static const char *FORMainProgMatch = "MARGORP NIAM";
static String const * const AddressClasses[] = {
NULL, /* ADDR_none */
&NearKwd, /* ADDR_near16 */
&FarKwd, /* ADDR_far16 */
&HugeKwd, /* ADDR_huge16 */
&NearKwd, /* ADDR_near32 */
&FarKwd /* ADDR_far32 */
};
static const char *LBLFunction = "Function";
static const char *LBLSubprogram = "Subprogram";
static const char *LBLTypedef = "Typedef";
static const char *LBLEnum = "Enum";
static const char *LBLUnion = "Union";
static const char *LBLStructure = "Structure";
static const char *LBLClass = "Class";
static const char *LBLCommonBlock = "Common Block";
static const char *LBLVariable = "Variable";
static const char *LBLParameter = "Parameter";
extern void DRDecorateLabel( dr_handle die, char *buf )
/*****************************************************/
{
Loc_T loc;
dr_language lang;
compunit_info *compunit;
const char *label;
dr_handle tmp_abbrev;
dr_handle tmp_entry;
FillLoc( &loc, die );
compunit = DWRFindCompileInfo( die );
lang = DRGetLanguageAT( compunit->start + COMPILE_UNIT_HDR_SIZE );
switch( loc.tag ) {
case DW_TAG_subprogram:
switch( lang ) {
case DR_LANG_C:
case DR_LANG_CPLUSPLUS:
label = LBLFunction;
break;
case DR_LANG_FORTRAN:
tmp_abbrev = loc.abbrev_cr;
tmp_entry = loc.entry_cr;
if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type ) ) {
label = LBLFunction;
} else {
label = LBLSubprogram;
}
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
break;
case DW_TAG_typedef:
label = LBLTypedef;
break;
case DW_TAG_enumeration_type:
label = LBLEnum;
break;
case DW_TAG_union_type:
label = LBLUnion;
break;
case DW_TAG_structure_type:
label = LBLStructure;
break;
case DW_TAG_class_type:
label = LBLClass;
break;
case DW_TAG_common_block:
label = LBLCommonBlock;
break;
case DW_TAG_formal_parameter:
case DW_TAG_member:
case DW_TAG_variable:
switch( lang ) {
case DR_LANG_C:
case DR_LANG_CPLUSPLUS:
label = LBLVariable;
break;
case DR_LANG_FORTRAN:
tmp_abbrev = loc.abbrev_cr;
tmp_entry = loc.entry_cr;
if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_const_value ) ) {
label = LBLParameter;
} else {
label = LBLVariable;
}
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
strncpy( buf, label, DRDECLABELLEN );
}
extern char * DRDecoratedName( dr_handle die, dr_handle parent )
/**************************************************************/
{
BrokenName_T decstruct;
char *retstr;
decstruct = BuildList( die, parent );
retstr = ( FormName( &decstruct ) ).s;
return( retstr );
}
extern void DRDecoratedNameList( void *obj, dr_handle die, dr_handle parent,
void (* cb)( void *, char *,
int, dr_handle,
dr_sym_type ) )
/**************************************************************************/
{
BrokenName_T decstruct;
List_T list;
decstruct = BuildList( die, parent );
list = FormList( &decstruct );
IterateList( cb, obj, list );
}
static BrokenName_T BuildList( dr_handle die, dr_handle parent )
/**************************************************************/
{
Loc_T loc;
BrokenName_T decstruct = Empty_Broken_Name;
compunit_info *compunit;
dr_language lang;
FillLoc( &loc, die );
loc.parent = parent;
compunit = DWRFindCompileInfo( die );
lang = DRGetLanguageAT( compunit->start + COMPILE_UNIT_HDR_SIZE );
switch( lang ) {
case DR_LANG_CPLUSPLUS:
case DR_LANG_C:
BuildCList( &decstruct, &loc );
break;
case DR_LANG_FORTRAN:
BuildFortranList( &decstruct, &loc );
break;
default:
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
return( decstruct );
}
static void BuildFortranList( BrokenName_T *decname, Loc_T *loc )
/***************************************************************/
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?