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