summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp21
-rw-r--r--clang/test/CodeGenCXX/linetable-fnbegin.cpp11
2 files changed, 22 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2556cf98508..df6a3ead641 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2497,14 +2497,25 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
FnBeginRegionCount.push_back(LexicalBlockStack.size());
const Decl *D = GD.getDecl();
- // Function may lack declaration in source code if it is created by Clang
- // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
+
+ // Use the location of the start of the function to determine where
+ // the function definition is located. By default use the location
+ // of the declaration as the location for the subprogram. A function
+ // may lack a declaration in the source code if it is created by code
+ // gen. (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
bool HasDecl = (D != 0);
- // Use the location of the declaration.
SourceLocation Loc;
- if (HasDecl)
+ if (HasDecl) {
Loc = D->getLocation();
+ // If this is a function specialization then use the pattern body
+ // as the location for the function.
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
+ if (SpecDecl->hasBody(SpecDecl))
+ Loc = SpecDecl->getLocation();
+ }
+
unsigned Flags = 0;
llvm::DIFile Unit = getOrCreateFile(Loc);
llvm::DIDescriptor FDContext(Unit);
@@ -2585,8 +2596,6 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
// Push the function onto the lexical block stack.
llvm::MDNode *SPN = SP;
LexicalBlockStack.push_back(SPN);
- // Initialize PrevLoc to the location of the function header.
- PrevLoc = Loc;
if (HasDecl)
RegionMap[D] = llvm::WeakVH(SP);
diff --git a/clang/test/CodeGenCXX/linetable-fnbegin.cpp b/clang/test/CodeGenCXX/linetable-fnbegin.cpp
index 81e7f7b82a5..24ca5731268 100644
--- a/clang/test/CodeGenCXX/linetable-fnbegin.cpp
+++ b/clang/test/CodeGenCXX/linetable-fnbegin.cpp
@@ -3,10 +3,13 @@
// right header file.
// CHECK: define{{.*}}bar
// CHECK-NOT: define
-// CHECK: ret {{.*}}, !dbg ![[DBG:.*]]
-// CHECK: ![[HPP:.*]] = metadata !{metadata !"./template.hpp",
-// CHECK: ![[DBG]] = metadata !{i32 23, i32 0, metadata ![[BLOCK:.*]], null}
-// CHECK: ![[BLOCK]] = metadata !{{{.*}}, metadata ![[HPP]], {{.*}}} ; [ DW_TAG_lexical_block ]
+// CHECK: ret {{.*}}, !dbg [[DBG:.*]]
+// CHECK: [[HPP:.*]] = metadata !{metadata !"./template.hpp",
+// CHECK: [[SP:.*]] = metadata !{i32 786478, metadata [[HPP]], metadata !"_ZTS3FooIiE", metadata !"bar", metadata !"bar", metadata !"_ZN3FooIiE3barEv", i32 22, metadata !8, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (%class.Foo*)* @_ZN3FooIiE3barEv, null, metadata !7, metadata !2, i32 22} ; [ DW_TAG_subprogram ] [line 22] [def] [bar]
+// We shouldn't need a lexical block for this function.
+// CHECK: [[DBG]] = metadata !{i32 23, i32 0, metadata [[SP]], null}
+
+
# 1 "./template.h" 1
template <typename T>
class Foo {
OpenPOWER on IntegriCloud