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)
llvm-svn: 208748
diff --git a/llvm/lib/CodeGen/LexicalScopes.cpp b/llvm/lib/CodeGen/LexicalScopes.cpp
index 46f864c..d965968 100644
--- a/llvm/lib/CodeGen/LexicalScopes.cpp
+++ b/llvm/lib/CodeGen/LexicalScopes.cpp
@@ -104,6 +104,14 @@
}
}
+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 @@
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 @@
}
/// 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;
}