Debug info can now properly represent functions inside classes inside other functions. Partial fix for Radar 7424645.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100048 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Stuart Hastings 2010-03-31 21:10:54 +00:00
parent a0c6057061
commit a88cb38d02
2 changed files with 26 additions and 10 deletions

View File

@ -780,12 +780,26 @@ void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
} else if (Context.isNameSpace()) {
DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
ContextDIE->addChild(Die);
} else if (Context.isSubprogram()) {
DIE *ContextDIE = createSubprogramDIE(DISubprogram(Context.getNode()),
/*MakeDecl=*/false);
ContextDIE->addChild(Die);
} else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
ContextDIE->addChild(Die);
else
ModuleCU->addDie(Die);
}
/// isFunctionContext - True if given Context is nested within a function.
bool DwarfDebug::isFunctionContext(DIE *context) {
if (context == (DIE *)0)
return false;
if (context->getTag() == dwarf::DW_TAG_subprogram)
return true;
else
return isFunctionContext(context->getParent());
}
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
@ -967,6 +981,10 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (DIDescriptor(ContainingType.getNode()).isCompositeType())
addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
getOrCreateTypeDIE(DIType(ContainingType.getNode())));
else {
DIDescriptor Context = CTy.getContext();
addToContextOwner(&Buffer, Context);
}
break;
}
default:
@ -1325,8 +1343,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
// function then gdb prefers the definition at top level and but does not
// expect specification DIE in parent function. So avoid creating
// specification DIE for a function defined inside a function.
if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
!SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
if (SP.isDefinition() && !isFunctionContext(SPDie->getParent())) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments.
@ -1754,19 +1771,15 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
void DwarfDebug::constructSubprogramDIE(MDNode *N) {
DISubprogram SP(N);
// Check for pre-existence.
if (ModuleCU->getDIE(N))
return;
if (!SP.isDefinition())
// This is a method declaration which will be handled while constructing
// class type.
return;
DIE *SubprogramDie = createSubprogramDIE(SP);
// Add to map.
ModuleCU->insertDIE(N, SubprogramDie);
// Check for pre-existence.
DIE *SubprogramDie = ModuleCU->getDIE(N);
if (!SubprogramDie)
SubprogramDie = createSubprogramDIE(SP);
// Add to context owner.
addToContextOwner(SubprogramDie, SP.getContext());

View File

@ -315,6 +315,9 @@ class DwarfDebug : public DwarfPrinter {
/// addToContextOwner - Add Die into the list of its context owner's children.
void addToContextOwner(DIE *Die, DIDescriptor Context);
/// isFunctionContext - True if given Context is nested within a function.
bool isFunctionContext(DIE *context);
/// addType - Add a new type attribute to the specified entity.
void addType(DIE *Entity, DIType Ty);