1f4a2713aSLionel Sambuc // RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck %s
2f4a2713aSLionel Sambuc // PR14471
3f4a2713aSLionel Sambuc
4f4a2713aSLionel Sambuc enum X {
5f4a2713aSLionel Sambuc Y
6f4a2713aSLionel Sambuc };
7f4a2713aSLionel Sambuc class C
8f4a2713aSLionel Sambuc {
9f4a2713aSLionel Sambuc static int a;
10f4a2713aSLionel Sambuc const static bool const_a = true;
11f4a2713aSLionel Sambuc protected:
12f4a2713aSLionel Sambuc static int b;
13f4a2713aSLionel Sambuc const static float const_b = 3.14;
14f4a2713aSLionel Sambuc public:
15f4a2713aSLionel Sambuc static int c;
16f4a2713aSLionel Sambuc const static int const_c = 18;
17f4a2713aSLionel Sambuc int d;
18f4a2713aSLionel Sambuc static X x_a;
19f4a2713aSLionel Sambuc };
20f4a2713aSLionel Sambuc
21f4a2713aSLionel Sambuc int C::a = 4;
22f4a2713aSLionel Sambuc int C::b = 2;
23f4a2713aSLionel Sambuc int C::c = 1;
24f4a2713aSLionel Sambuc
main()25f4a2713aSLionel Sambuc int main()
26f4a2713aSLionel Sambuc {
27f4a2713aSLionel Sambuc C instance_C;
28f4a2713aSLionel Sambuc instance_C.d = 8;
29f4a2713aSLionel Sambuc return C::c;
30f4a2713aSLionel Sambuc }
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc // The definition of C::a drives the emission of class C, which is
33f4a2713aSLionel Sambuc // why the definition of "a" comes before the declarations while
34f4a2713aSLionel Sambuc // "b" and "c" come after.
35f4a2713aSLionel Sambuc
36*0a6a1f1dSLionel Sambuc // CHECK: !"_ZTS1X"} ; [ DW_TAG_enumeration_type ] [X]
37*0a6a1f1dSLionel Sambuc // CHECK: !"_ZTS1C"} ; [ DW_TAG_class_type ] [C]
38*0a6a1f1dSLionel Sambuc // CHECK: ![[DECL_A:[0-9]+]] = {{.*}} [ DW_TAG_member ] [a] [line {{.*}}, size 0, align 0, offset 0] [static]
39*0a6a1f1dSLionel Sambuc // CHECK: !"0xd\00const_a\00{{.*}}", {{.*}}, i1 true} ; [ DW_TAG_member ] [const_a] [line {{.*}}, size 0, align 0, offset 0] [static]
40*0a6a1f1dSLionel Sambuc // CHECK: ![[DECL_B:[0-9]+]] = !{!"0xd\00b\00{{.*}}", {{.*}} [ DW_TAG_member ] [b] [line {{.*}}, size 0, align 0, offset 0] [protected] [static]
41*0a6a1f1dSLionel Sambuc // CHECK: !"0xd\00const_b\00{{.*}}", {{.*}}, float 0x{{.*}}} ; [ DW_TAG_member ] [const_b] [line {{.*}}, size 0, align 0, offset 0] [protected] [static]
42*0a6a1f1dSLionel Sambuc // CHECK: ![[DECL_C:[0-9]+]] = !{!"0xd\00c\00{{.*}}", {{.*}} [ DW_TAG_member ] [c] [line {{.*}}, size 0, align 0, offset 0] [public] [static]
43*0a6a1f1dSLionel Sambuc // CHECK: !"0xd\00const_c\00{{.*}}", {{.*}} [ DW_TAG_member ] [const_c] [line {{.*}}, size 0, align 0, offset 0] [public] [static]
44*0a6a1f1dSLionel Sambuc // CHECK: !"0xd\00x_a\00{{.*}}", {{.*}} [ DW_TAG_member ] [x_a] {{.*}} [public] [static]
45*0a6a1f1dSLionel Sambuc
46*0a6a1f1dSLionel Sambuc // CHECK: ; [ DW_TAG_structure_type ] [static_decl_templ<int>] {{.*}} [def]
47*0a6a1f1dSLionel Sambuc // CHECK: ; [ DW_TAG_member ] [static_decl_templ_var]
48*0a6a1f1dSLionel Sambuc
49*0a6a1f1dSLionel Sambuc // CHECK: [[NS_X:![0-9]+]] = {{.*}} ; [ DW_TAG_namespace ] [x]
50*0a6a1f1dSLionel Sambuc
51*0a6a1f1dSLionel Sambuc // Test this in an anonymous namespace to ensure the type is retained even when
52*0a6a1f1dSLionel Sambuc // it doesn't get automatically retained by the string type reference machinery.
53*0a6a1f1dSLionel Sambuc namespace {
54*0a6a1f1dSLionel Sambuc struct anon_static_decl_struct {
55*0a6a1f1dSLionel Sambuc static const int anon_static_decl_var = 117;
56*0a6a1f1dSLionel Sambuc };
57*0a6a1f1dSLionel Sambuc }
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc
60*0a6a1f1dSLionel Sambuc // CHECK: ; [ DW_TAG_structure_type ] [anon_static_decl_struct] {{.*}} [def]
61*0a6a1f1dSLionel Sambuc // CHECK: ; [ DW_TAG_member ] [anon_static_decl_var]
62*0a6a1f1dSLionel Sambuc
ref()63*0a6a1f1dSLionel Sambuc int ref() {
64*0a6a1f1dSLionel Sambuc return anon_static_decl_struct::anon_static_decl_var;
65*0a6a1f1dSLionel Sambuc }
66*0a6a1f1dSLionel Sambuc
67*0a6a1f1dSLionel Sambuc template<typename T>
68*0a6a1f1dSLionel Sambuc struct static_decl_templ {
69*0a6a1f1dSLionel Sambuc static const int static_decl_templ_var = 7;
70*0a6a1f1dSLionel Sambuc };
71*0a6a1f1dSLionel Sambuc
72*0a6a1f1dSLionel Sambuc template<typename T>
73*0a6a1f1dSLionel Sambuc const int static_decl_templ<T>::static_decl_templ_var;
74*0a6a1f1dSLionel Sambuc
static_decl_templ_ref()75*0a6a1f1dSLionel Sambuc int static_decl_templ_ref() {
76*0a6a1f1dSLionel Sambuc return static_decl_templ<int>::static_decl_templ_var;
77*0a6a1f1dSLionel Sambuc }
78*0a6a1f1dSLionel Sambuc
79*0a6a1f1dSLionel Sambuc // CHECK: !"0x34\00a\00{{.*}}", null, {{.*}} @_ZN1C1aE, ![[DECL_A]]} ; [ DW_TAG_variable ] [a] {{.*}} [def]
80*0a6a1f1dSLionel Sambuc // CHECK: !"0x34\00b\00{{.*}}", null, {{.*}} @_ZN1C1bE, ![[DECL_B]]} ; [ DW_TAG_variable ] [b] {{.*}} [def]
81*0a6a1f1dSLionel Sambuc // CHECK: !"0x34\00c\00{{.*}}", null, {{.*}} @_ZN1C1cE, ![[DECL_C]]} ; [ DW_TAG_variable ] [c] {{.*}} [def]
82*0a6a1f1dSLionel Sambuc
83*0a6a1f1dSLionel Sambuc // CHECK-NOT: ; [ DW_TAG_variable ] [anon_static_decl_var]
84*0a6a1f1dSLionel Sambuc
85*0a6a1f1dSLionel Sambuc // Verify that even when a static member declaration is created lazily when
86*0a6a1f1dSLionel Sambuc // creating the definition, the declaration line is that of the canonical
87*0a6a1f1dSLionel Sambuc // declaration, not the definition. Also, since we look at the canonical
88*0a6a1f1dSLionel Sambuc // definition, we should also correctly emit the constant value (42) into the
89*0a6a1f1dSLionel Sambuc // debug info.
90*0a6a1f1dSLionel Sambuc struct V {
91*0a6a1f1dSLionel Sambuc virtual ~V(); // cause the definition of 'V' to be omitted by no-standalone-debug optimization
92*0a6a1f1dSLionel Sambuc static const int const_va = 42;
93*0a6a1f1dSLionel Sambuc };
94*0a6a1f1dSLionel Sambuc // CHECK: i32 42} ; [ DW_TAG_member ] [const_va] [line [[@LINE-2]],
95*0a6a1f1dSLionel Sambuc const int V::const_va;
96*0a6a1f1dSLionel Sambuc
97*0a6a1f1dSLionel Sambuc namespace x {
98*0a6a1f1dSLionel Sambuc struct y {
99*0a6a1f1dSLionel Sambuc static int z;
100*0a6a1f1dSLionel Sambuc };
101*0a6a1f1dSLionel Sambuc int y::z;
102*0a6a1f1dSLionel Sambuc }
103*0a6a1f1dSLionel Sambuc
104*0a6a1f1dSLionel Sambuc // CHECK: !"0x34\00z\00{{.*}}", [[NS_X]], {{.*}} ; [ DW_TAG_variable ] [z] {{.*}} [def]
105