1 | // RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11 |
2 | // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17 |
3 | |
4 | struct A { |
5 | static const int Foo = 123; |
6 | }; |
7 | // CHECK: @_ZN1A3FooE = constant i32 123, align 4 |
8 | const int *p = &A::Foo; // emit available_externally |
9 | const int A::Foo; // convert to full definition |
10 | |
11 | struct PODWithInit { |
12 | int g = 42; |
13 | char h = 43; |
14 | }; |
15 | struct CreatePOD { |
16 | // Deferred initialization of the structure here requires changing |
17 | // the type of the global variable: the initializer list does not include |
18 | // the tail padding. |
19 | // CXX11: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 }, |
20 | static constexpr PODWithInit pod{}; |
21 | }; |
22 | const int *p_pod = &CreatePOD::pod.g; |
23 | |
24 | struct Bar { |
25 | int b; |
26 | }; |
27 | |
28 | struct MutableBar { |
29 | mutable int b; |
30 | }; |
31 | |
32 | struct Foo { |
33 | // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42, |
34 | // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42, |
35 | static constexpr int ConstexprStaticMember = 42; |
36 | // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43, |
37 | static const int ConstStaticMember = 43; |
38 | |
39 | // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 }, |
40 | // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 }, |
41 | static constexpr Bar ConstStaticStructMember = {44}; |
42 | |
43 | // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar, |
44 | // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 }, |
45 | static constexpr MutableBar ConstexprStaticMutableStructMember = {45}; |
46 | }; |
47 | // CHECK: @_ZL15ConstStaticexpr = internal constant i32 46, |
48 | static constexpr int ConstStaticexpr = 46; |
49 | // CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4 |
50 | static const int ConstExpr = 46; |
51 | |
52 | // CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 }, |
53 | static constexpr Bar ConstexprStaticStruct = {47}; |
54 | |
55 | // CHECK: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 }, |
56 | static constexpr MutableBar ConstexprStaticMutableStruct = {48}; |
57 | |
58 | void use(const int &); |
59 | void foo() { |
60 | use(Foo::ConstexprStaticMember); |
61 | use(Foo::ConstStaticMember); |
62 | use(Foo::ConstStaticStructMember.b); |
63 | use(Foo::ConstexprStaticMutableStructMember.b); |
64 | use(ConstStaticexpr); |
65 | use(ConstExpr); |
66 | use(ConstexprStaticStruct.b); |
67 | use(ConstexprStaticMutableStruct.b); |
68 | } |
69 | |