Recommit r208506: DebugInfo: Include lexical scopes in inlined subroutines.

This was reverted in r208642 due to regressions surrounding file changes
within lexical scopes causing inlining information to be lost.

The issue was in LexicalScopes::getOrCreateInlinedScope, where I was
previously testing "isLexicalBlock" which is false for
"DILexicalBlockFile" (a scope used to represent changes in the current
file name) and assuming it was then a function (breaking out of the
inlined scope path and reaching for the parent non-inlined scopes). By
inverting the condition and testing for "isSubprogram" the correct
behavior is attained.

(also found some weirdness in Clang, see r208742 when reducing this test
case - the resulting test case doesn't apply with the Clang fix, but
I've added a more realistic test case to inline-scopes.ll which does
reproduce the issue and demonstrate the fix)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208748 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie
2014-05-14 01:08:28 +00:00
parent 22dcd3985f
commit ee8af3e2a0
5 changed files with 173 additions and 21 deletions
+27 -12
View File
@@ -104,6 +104,14 @@ void LexicalScopes::extractLexicalScopes(
}
}
LexicalScope *LexicalScopes::findInlinedScope(DebugLoc DL) {
MDNode *Scope = nullptr;
MDNode *IA = nullptr;
DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
}
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
@@ -119,8 +127,10 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
if (D.isLexicalBlockFile())
Scope = DILexicalBlockFile(Scope).getScope();
if (IA)
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
if (IA) {
auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
}
return findLexicalScope(Scope);
}
@@ -170,21 +180,26 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
}
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode,
MDNode *InlinedAt) {
auto I = LexicalScopeMap.find(InlinedAt);
if (I != LexicalScopeMap.end())
std::pair<const MDNode*, const MDNode*> P(ScopeNode, InlinedAt);
auto I = InlinedLexicalScopeMap.find(P);
if (I != InlinedLexicalScopeMap.end())
return &I->second;
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
LexicalScope *Parent;
DILexicalBlock Scope(ScopeNode);
if (Scope.isSubprogram())
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILocation(InlinedAt));
else
Parent = getOrCreateInlinedScope(Scope.getContext(), InlinedAt);
// FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
// compatibility is no longer required.
I = LexicalScopeMap.emplace(
std::piecewise_construct, std::make_tuple(InlinedAt),
std::make_tuple(getOrCreateLexicalScope(InlinedLoc),
DIDescriptor(Scope), InlinedAt,
false)).first;
InlinedLexicalScopeMap[InlinedLoc] = &I->second;
I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
std::make_tuple(P),
std::make_tuple(Parent, Scope, InlinedAt,
false)).first;
return &I->second;
}