drdecnam.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,033 行 · 第 1/5 页
C
2,033 行
dr_handle containing_entry;
containing_entry = DWRReadReference( tmp_abbrev, tmp_entry );
if( containing_entry != DW_TAG_padding ) {
GetContaining( &decname->var_bas, containing_entry );
}
}
tmp_abbrev = loc->abbrev_cr;
tmp_entry = loc->entry_cr;
if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type ) == DW_AT_type ) {
dr_handle type_entry = DWRReadReference( tmp_abbrev, tmp_entry );
type_entry = SkipPCH( type_entry );
if( type_entry != DW_TAG_padding ) {
FillLoc( &type_loc, type_entry );
DecorateType( decname, &type_loc, DW_TAG_padding );
}
}
parms = StartFunctionParms( loc );
if( decname->func_bas.tail == NULL ) {
decname->func_bas.head = parms.head;
decname->func_bas.tail = parms.tail;
} else {
decname->func_bas.tail->next = parms.head;
decname->func_bas.tail = parms.tail;
}
return( decname );
}
static List_T StartFunctionParms( Loc_T *loc )
/********************************************/
{
List_T ret = { NULL, NULL, LIST_TAIL };
List_T add_parm;
bool first_time = TRUE;
Loc_T parm_loc;
ListConcat( &ret, FuncStartKwd );
if( loc->child == DW_CHILDREN_yes ) {
dr_handle tmp_entry;
dr_handle tmp_abbrev;
tmp_entry = loc->entry_cr;
tmp_abbrev = loc->abbrev_cr;
DWRSkipAttribs( tmp_abbrev, &tmp_entry );
FillLoc( &parm_loc, tmp_entry );
while( parm_loc.entry_st != 0 ) {
add_parm = DecorateParameter( &parm_loc );
if( add_parm.head != NULL ) {
if( first_time ) {
first_time = FALSE;
ListConcat( &ret, SpaceKwd );
} else {
ListConcat( &ret, ParmSepKwd );
}
if( ret.tail == NULL ) {
ret.head = add_parm.head;
ret.tail = add_parm.tail;
} else {
ret.tail->next = add_parm.head;
ret.tail = add_parm.tail;
}
}
}
}
if( !first_time ) {
ListConcat( &ret, SpaceKwd );
}
ListConcat( &ret, FuncEndKwd );
return( ret );
}
/*
* decorate a function's formal parameters.
* loc->entry_st points to a child entry. DecorateParameter considers
* this child -- if it is a parameter, it decorates it and returns a List_T.
* otherwise, it checks siblings. loc is always updated to point to
* the next sibling. If there are no more siblings, it sets
* loc->entry_st to 0.
*/
static List_T DecorateParameter( Loc_T *loc )
/*******************************************/
{
List_T ret = { NULL, NULL };
BrokenName_T decstruct = Empty_Broken_Name;
dr_handle tmp_abbrev;
dr_handle tmp_entry;
tmp_entry = loc->entry_cr;
tmp_abbrev = loc->abbrev_cr;
while( loc->tag != DW_TAG_unspecified_parameters &&
loc->tag != DW_TAG_formal_parameter && loc->abbrev_st != 0 ) {
if( loc->child ) {
DWRSkipChildren( &tmp_abbrev, &tmp_entry );
} else {
DWRSkipAttribs( tmp_abbrev, &tmp_entry );
}
FillLoc( loc, tmp_entry );
tmp_abbrev = loc->abbrev_cr;
tmp_entry = loc->entry_cr;
}
if( loc->abbrev_st != 0 ) {
switch( loc->tag ) {
case DW_TAG_unspecified_parameters:
ListConcat( &ret, UnspecParamKwd );
break;
case DW_TAG_formal_parameter:
DecorateVariable( &decstruct, loc );
ret = FormList( &decstruct );
ret.end = LIST_TAIL;
EndNode( &ret, FALSE, 0, DR_SYM_NOT_SYM );
break;
default:
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
tmp_abbrev = loc->abbrev_cr;
tmp_entry = loc->entry_cr;
if( loc->child ) {
DWRSkipChildren( &tmp_abbrev, &tmp_entry );
} else {
DWRSkipAttribs( tmp_abbrev, &tmp_entry );
}
FillLoc( loc, tmp_entry );
}
return( ret );
}
/*
* decorate a type.
* prev_tag contains the
* previous tag that was handled by the type. This is needed for the
* pointer to subroutine type -- it needs to know if it resolves to a pointer
* to a subroutine, or a subroutine type itself.
*
* WARNING -- this changes the contents of loc.
*/
static BrokenName_T *DecorateType( BrokenName_T *decname, Loc_T *loc,
dr_handle prev_tag )
/*******************************************************************/
{
dr_handle tmp_entry;
dr_handle tmp_abbrev;
dr_handle next_die;
String typename;
bool done = FALSE; /* true when the end of the type chain is reached */
tmp_abbrev = loc->abbrev_cr;
tmp_entry = loc->entry_cr;
switch( loc->tag ) {
case DW_TAG_base_type:
case DW_TAG_typedef:
GrabName( tmp_abbrev, tmp_entry, &typename );
ListConcat( &( decname->type_bas ), SpaceKwd );
if( loc->tag == DW_TAG_typedef ) {
EndNode( &( decname->type_bas ), TRUE, loc->entry_st, DR_SYM_TYPEDEF );
ListConcat( &( decname->type_bas ), typename );
EndNode( &( decname->type_bas ), FALSE, 0, DR_SYM_NOT_SYM );
} else {
ListConcat( &( decname->type_bas ), typename );
}
if( prev_tag == DW_TAG_const_type || prev_tag == DW_TAG_volatile_type ) {
SwapModifier( decname );
}
DWRFREE( typename.s );
done = TRUE;
break;
case DW_TAG_const_type:
if( prev_tag != DW_TAG_const_type && prev_tag != DW_TAG_volatile_type ) {
EndNode( &( decname->type_elg ), FALSE, 0, DR_SYM_NOT_SYM );
}
AddTypeString( decname, ConstKwd, TYPE_ELG );
break;
case DW_TAG_volatile_type:
if( prev_tag != DW_TAG_const_type && prev_tag != DW_TAG_volatile_type ) {
EndNode( &( decname->type_elg ), FALSE, 0, DR_SYM_NOT_SYM );
}
AddTypeString( decname, VolatileKwd, TYPE_ELG );
break;
case DW_TAG_pointer_type:
EndNode( &( decname->type_ptr ), FALSE, 0, DR_SYM_NOT_SYM );
AddTypeString( decname, PtrKwd, TYPE_PTR );
break;
case DW_TAG_reference_type:
EndNode( &( decname->type_ptr ), FALSE, 0, DR_SYM_NOT_SYM );
AddTypeString( decname, RefKwd, TYPE_PTR );
break;
case DW_TAG_ptr_to_member_type:
DecoratePtrToMember( decname, loc );
break;
case DW_TAG_WATCOM_address_class_type:
if( prev_tag != DW_TAG_pointer_type ) {
EndNode( &( decname->type_ptr ), FALSE, 0, DR_SYM_NOT_SYM );
}
AddPtrModifier( decname, loc );
break;
case DW_TAG_enumeration_type:
DecorateCompoundType( decname, loc, EnumKwd, DR_SYM_ENUM );
break;
case DW_TAG_class_type:
DecorateCompoundType( decname, loc, ClassKwd, DR_SYM_CLASS );
break;
case DW_TAG_structure_type:
DecorateCompoundType( decname, loc, StructKwd, DR_SYM_CLASS );
break;
case DW_TAG_union_type:
DecorateCompoundType( decname, loc, UnionKwd, DR_SYM_CLASS );
break;
case DW_TAG_array_type:
DecorateArray( decname, loc );
done = TRUE;
break;
case DW_TAG_subroutine_type:
DecSubroutineType( decname, loc, prev_tag );
break;
default:
DWREXCEPT ( DREXCEP_DWARF_LIB_FAIL );
}
if( !done ) {
tmp_abbrev = loc->abbrev_cr;
tmp_entry = loc->entry_cr;
if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type ) == DW_AT_type ) {
next_die = DWRReadReference( tmp_abbrev, tmp_entry );
next_die = SkipPCH( next_die );
if( next_die != DW_TAG_padding ) {
if( loc->tag == DW_TAG_WATCOM_address_class_type ) {
prev_tag = prev_tag;
} else {
prev_tag = loc->tag;
}
FillLoc( loc, next_die );
DecorateType( decname, loc, prev_tag );
}
}
}
return( decname );
}
/*
* take the last node from type_bas and put it at the end of type_plg.
* this is used for constant and volatile modifiers formed as right
* associative expressions.
*/
static void SwapModifier( BrokenName_T *decname )
/***********************************************/
{
Node_T target;
target = DeleteTail( &( decname->type_elg ) );
if( target == NULL ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
if( decname->type_plg.head == NULL || decname->type_plg.tail == NULL ) {
decname->type_plg.head = target;
decname->type_plg.tail = target;
} else {
target->next = decname->type_plg.head;
decname->type_plg.head = target;
}
strrev( target->buf.s );
}
static BrokenName_T *AddPtrModifier( BrokenName_T *decname, Loc_T *loc )
/**********************************************************************/
{
dr_handle tmp_entry;
dr_handle tmp_abbrev;
unsigned_32 addr_class;
bool spaceit = FALSE;
tmp_entry = loc->entry_cr;
tmp_abbrev = loc->abbrev_cr;
if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_address_class )
== DW_AT_address_class ) {
if( decname->type_ptr.head != NULL ) {
spaceit = TRUE;
}
addr_class = DWRReadConstant( tmp_abbrev, tmp_entry );
ListConcat( &( decname->type_ptr ), *AddressClasses[ addr_class] );
if( spaceit ) {
ListConcat( &( decname->type_ptr ), SpaceKwd );
}
}
return( decname );
}
static BrokenName_T *DecSubroutineType( BrokenName_T *decname, Loc_T *loc,
dr_handle prev_tag )
/************************************************************************/
{
List_T parms;
Node_T target;
if( prev_tag == DW_TAG_pointer_type ) {
target = DeleteTail( &( decname->type_ptr ) );
ListConcat( &( decname->var_plg ), SpaceKwd );
ListAdd( &( decname->var_plg ), target );
ListConcat( &( decname->var_plg ), FuncStartKwd );
} else {
ListConcat( &( decname->var_plg ), FuncStartKwd );
}
ListConcat( &( decname->var_elg ), FuncEndKwd );
parms = StartFunctionParms( loc );
if( decname->func_bas.tail == NULL ) {
decname->func_bas.head = parms.head;
decname->func_bas.tail = parms.tail;
} else {
decname->func_bas.tail->next = parms.head;
decname->func_bas.tail = parms.tail;
}
return( decname );
}
static void AddTypeString( BrokenName_T *dn, String Kwd,
TypeSide_T ts)
/******************************************************/
{
List_T *list;
switch( ts ) {
case TYPE_PLG:
list = &(dn->type_plg);
break;
case TYPE_BAS:
list = &(dn->type_bas);
break;
case TYPE_PTR:
list = &(dn->type_ptr);
break;
case TYPE_ELG:
list = &(dn->type_elg);
break;
default:
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
ListConcat( list, Kwd );
}
/*
* decorate a union, struct or class.
*/
BrokenName_T *DecorateCompoundType( BrokenName_T *decname, Loc_T *loc,
String Kwd, dr_sym_type symtype )
/********************************************************************/
{
String typename;
GrabName( loc->abbrev_cr, loc->entry_cr, &typename );
ListConcat( &( decname->type_bas ), SpaceKwd );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?