1 // RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck %s 2 // RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck %s 3 // RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s 4 // PR14471 5 6 // CHECK: @_ZN1C1aE = global i32 4, align 4, !dbg [[A:![0-9]+]] 7 // CHECK: @_ZN1C1bE = global i32 2, align 4, !dbg [[B:![0-9]+]] 8 // CHECK: @_ZN1C1cE = global i32 1, align 4, !dbg [[C:![0-9]+]] 9 10 enum X { 11 Y 12 }; 13 class C 14 { 15 static int a; 16 const static bool const_a = true; 17 protected: 18 static int b; 19 #if __cplusplus >= 201103L 20 constexpr static float const_b = 3.14; 21 #else 22 const static float const_b = 3.14; 23 #endif 24 public: 25 static int c; 26 const static int const_c = 18; 27 int d; 28 static X x_a; 29 }; 30 31 // The definition of C::a drives the emission of class C, which is 32 // why the definition of "a" comes before the declarations while 33 // "b" and "c" come after. 34 35 // CHECK: [[A]] = distinct !DIGlobalVariable(name: "a", {{.*}} declaration: ![[DECL_A:[0-9]+]]) 36 // 37 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X") 38 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" 39 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" 40 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_decl_templ<int>" 41 // CHECK-NOT: DIFlagFwdDecl 42 // CHECK-SAME: ){{$}} 43 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var" 44 45 int C::a = 4; 46 // CHECK: [[B]] = distinct !DIGlobalVariable(name: "b", {{.*}} declaration: ![[DECL_B:[0-9]+]]) 47 // CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b" 48 // CHECK-NOT: size: 49 // CHECK-NOT: align: 50 // CHECK-NOT: offset: 51 // CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember) 52 // 53 // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C") 54 // 55 // CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a" 56 // CHECK-NOT: size: 57 // CHECK-NOT: align: 58 // CHECK-NOT: offset: 59 // CHECK-SAME: flags: DIFlagStaticMember) 60 // 61 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a" 62 // CHECK-NOT: size: 63 // CHECK-NOT: align: 64 // CHECK-NOT: offset: 65 // CHECK-SAME: flags: DIFlagStaticMember, 66 // CHECK-SAME: extraData: i1 true) 67 68 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b" 69 // CHECK-NOT: size: 70 // CHECK-NOT: align: 71 // CHECK-NOT: offset: 72 // CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember, 73 // CHECK-SAME: extraData: float 0x{{.*}}) 74 75 // CHECK: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c" 76 // CHECK-NOT: size: 77 // CHECK-NOT: align: 78 // CHECK-NOT: offset: 79 // CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember) 80 // 81 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_c" 82 // CHECK-NOT: size: 83 // CHECK-NOT: align: 84 // CHECK-NOT: offset: 85 // CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember, 86 // CHECK-SAME: extraData: i32 18) 87 // 88 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a" 89 // CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember) 90 91 int C::b = 2; 92 // CHECK: [[C]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]]) 93 int C::c = 1; 94 95 int main() 96 { 97 C instance_C; 98 instance_C.d = 8; 99 return C::c; 100 } 101 102 // CHECK-NOT: !DIGlobalVariable(name: "anon_static_decl_var" 103 104 // Test this in an anonymous namespace to ensure the type is retained even when 105 // it doesn't get automatically retained by the string type reference machinery. 106 namespace { 107 struct anon_static_decl_struct { 108 static const int anon_static_decl_var = 117; 109 }; 110 } 111 112 113 int ref() { 114 return anon_static_decl_struct::anon_static_decl_var; 115 } 116 117 template<typename T> 118 struct static_decl_templ { 119 static const int static_decl_templ_var = 7; 120 }; 121 122 template<typename T> 123 const int static_decl_templ<T>::static_decl_templ_var; 124 125 int static_decl_templ_ref() { 126 return static_decl_templ<int>::static_decl_templ_var; 127 } 128 129 // Verify that even when a static member declaration is created lazily when 130 // creating the definition, the declaration line is that of the canonical 131 // declaration, not the definition. Also, since we look at the canonical 132 // definition, we should also correctly emit the constant value (42) into the 133 // debug info. 134 struct V { 135 virtual ~V(); // cause the definition of 'V' to be omitted by no-standalone-debug optimization 136 static const int const_va = 42; 137 }; 138 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_va", 139 // CHECK-SAME: line: [[@LINE-3]] 140 // CHECK-SAME: extraData: i32 42 141 const int V::const_va; 142 143 namespace x { 144 struct y { 145 // CHECK: !DIGlobalVariable(name: "z", 146 // CHECK-SAME: scope: [[NS_X:![0-9]+]] 147 // CHECK: [[NS_X]] = !DINamespace(name: "x" 148 static int z; 149 }; 150 int y::z; 151 } 152