Rafael Espindola | a3f55b0 | 2013-09-04 04:12:25 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -g -emit-llvm -g -triple x86_64-apple-darwin %s -o %t |
Adrian Prantl | 0a050f7 | 2013-05-09 23:16:27 +0000 | [diff] [blame] | 2 | // RUN: cat %t | FileCheck %s -check-prefix=CHECK0 |
| 3 | // RUN: cat %t | FileCheck %s -check-prefix=CHECK1 |
| 4 | // RUN: cat %t | FileCheck %s -check-prefix=CHECK2 |
| 5 | // |
| 6 | // This test ensures that we associate a declaration with the |
| 7 | // definition of the constructor for OuterClass. The declaration is |
| 8 | // necessary so the backend can emit the DW_AT_specification attribute |
| 9 | // for the definition. |
| 10 | // |
| 11 | // rdar://problem/13116508 |
| 12 | |
| 13 | class Foo; |
| 14 | class OuterClass |
| 15 | { |
| 16 | static class InnerClass { |
| 17 | public: |
| 18 | InnerClass(); // Here createContextChain() generates a limited type for OuterClass. |
| 19 | } theInnerClass; |
| 20 | // CHECK0: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [private] [OuterClass] |
| 21 | OuterClass(const Foo *); // line 10 |
| 22 | }; |
| 23 | OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated. |
| 24 | // CHECK0: metadata {{.*}}, metadata ![[DECL]], metadata {{.*}}, i32 [[@LINE+1]]} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [OuterClass] |
| 25 | OuterClass::OuterClass(const Foo *meta) { } // line 13 |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | class Foo1; |
| 32 | class OuterClass1 |
| 33 | { |
| 34 | static class InnerClass1 { |
| 35 | public: |
| 36 | InnerClass1(); |
| 37 | } theInnerClass1; |
Manman Ren | 83369bf | 2013-08-29 23:19:58 +0000 | [diff] [blame] | 38 | // CHECK1: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+2]]] [private] [Bar] |
| 39 | // CHECK1: metadata {{.*}}, metadata ![[DECL]], metadata {{.*}}, i32 [[@LINE+4]]} ; [ DW_TAG_subprogram ] [line [[@LINE+4]]] [def] [Bar] |
Adrian Prantl | 0a050f7 | 2013-05-09 23:16:27 +0000 | [diff] [blame] | 40 | void Bar(const Foo1 *); |
| 41 | }; |
| 42 | OuterClass1::InnerClass1 OuterClass1::theInnerClass1; |
Adrian Prantl | 0a050f7 | 2013-05-09 23:16:27 +0000 | [diff] [blame] | 43 | void OuterClass1::Bar(const Foo1 *meta) { } |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | class Foo2; |
| 50 | class OuterClass2 |
| 51 | { |
| 52 | static class InnerClass2 { |
| 53 | public: |
| 54 | InnerClass2(); |
| 55 | } theInnerClass2; |
| 56 | // CHECK2: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [private] [~OuterClass2] |
| 57 | ~OuterClass2(); // line 10 |
| 58 | }; |
| 59 | OuterClass2::InnerClass2 OuterClass2::theInnerClass2; |
| 60 | // CHECK2: metadata {{.*}}, metadata ![[DECL]], metadata {{.*}}, i32 [[@LINE+1]]} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [~OuterClass2] |
| 61 | OuterClass2::~OuterClass2() { } |