diff options
author | Adrian Prantl <aprantl@apple.com> | 2013-05-09 23:16:27 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2013-05-09 23:16:27 +0000 |
commit | 0a050f7d56039bab7556e08b359e06d329977b6b (patch) | |
tree | 6def5ef873c299c1349a03ee6d25d873b2b72be7 /test/CodeGenCXX/debug-info-decl-nested.cpp | |
parent | 192b030c8a887aa34db56d709136e533a454b2f3 (diff) | |
download | clang-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.cpp | 61 |
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() { } |