summaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/debug-info-decl-nested.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2013-05-09 23:16:27 +0000
committerAdrian Prantl <aprantl@apple.com>2013-05-09 23:16:27 +0000
commit0a050f7d56039bab7556e08b359e06d329977b6b (patch)
tree6def5ef873c299c1349a03ee6d25d873b2b72be7 /test/CodeGenCXX/debug-info-decl-nested.cpp
parent192b030c8a887aa34db56d709136e533a454b2f3 (diff)
downloadclang-0a050f7d56039bab7556e08b359e06d329977b6b.tar.gz
Debug Info: Fix a problem that resulted in missing DW_AT_specifications
for C++ constructors. If the DIType for a class was generated by CGDebugInfo::createContextChain(), the cache contains only a limited DIType wihtout any declarations. Since EmitFunctionStart() needs to find the canonical declaration for each method, we construct the complete type before emitting any method. rdar://problem/13116508 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181561 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/debug-info-decl-nested.cpp')
-rw-r--r--test/CodeGenCXX/debug-info-decl-nested.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/test/CodeGenCXX/debug-info-decl-nested.cpp b/test/CodeGenCXX/debug-info-decl-nested.cpp
new file mode 100644
index 0000000000..7c8bd1facf
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-decl-nested.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -g -O0 -emit-llvm -g -triple x86_64-apple-darwin %s -o %t
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK0
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK1
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK2
+//
+// This test ensures that we associate a declaration with the
+// definition of the constructor for OuterClass. The declaration is
+// necessary so the backend can emit the DW_AT_specification attribute
+// for the definition.
+//
+// rdar://problem/13116508
+
+class Foo;
+class OuterClass
+{
+ static class InnerClass {
+ public:
+ InnerClass(); // Here createContextChain() generates a limited type for OuterClass.
+ } theInnerClass;
+// CHECK0: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [private] [OuterClass]
+ OuterClass(const Foo *); // line 10
+};
+OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated.
+// CHECK0: metadata {{.*}}, metadata ![[DECL]], metadata {{.*}}, i32 [[@LINE+1]]} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [OuterClass]
+OuterClass::OuterClass(const Foo *meta) { } // line 13
+
+
+
+
+
+class Foo1;
+class OuterClass1
+{
+ static class InnerClass1 {
+ public:
+ InnerClass1();
+ } theInnerClass1;
+// CHECK1: metadata {{.*}}, metadata ![[DECL:[0-9]+]], metadata {{.*}}, i32 [[@LINE+5]]} ; [ DW_TAG_subprogram ] [line [[@LINE+5]]] [def] [Bar]
+ void Bar(const Foo1 *);
+};
+OuterClass1::InnerClass1 OuterClass1::theInnerClass1;
+// CHECK1: [[DECL]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE-3]]] [private] [Bar]
+void OuterClass1::Bar(const Foo1 *meta) { }
+
+
+
+
+
+class Foo2;
+class OuterClass2
+{
+ static class InnerClass2 {
+ public:
+ InnerClass2();
+ } theInnerClass2;
+// CHECK2: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [private] [~OuterClass2]
+ ~OuterClass2(); // line 10
+};
+OuterClass2::InnerClass2 OuterClass2::theInnerClass2;
+// CHECK2: metadata {{.*}}, metadata ![[DECL]], metadata {{.*}}, i32 [[@LINE+1]]} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [~OuterClass2]
+OuterClass2::~OuterClass2() { }