xref: /llvm-project/clang/test/CodeGenCXX/builtin-source-location.cpp (revision 49c86eab627b0c4089c8d25dac48728c656448a9)
1 // RUN: %clang_cc1 -no-opaque-pointers -std=c++2a -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll
2 
3 // This needs to be performed before #line directives which alter filename
4 // RUN: %clang_cc1 -no-opaque-pointers -fno-file-reproducible -fmacro-prefix-map=%p=/UNLIKELY/PATH -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-PREFIX-MAP
5 //
6 // CHECK-PREFIX-MAP: /UNLIKELY/PATH{{/|\\\\}}builtin-source-location.cpp
7 void testRemap() {
8   const char *file = __builtin_FILE();
9 }
10 
11 #line 8 "builtin-source-location.cpp"
12 
13 namespace std {
14 class source_location {
15 public:
16   static constexpr source_location current(const void *__p = __builtin_source_location()) noexcept {
17     source_location __loc;
18     __loc.__m_impl = static_cast<const __impl *>(__p);
19     return __loc;
20   }
21   static source_location bad_current(const void *__p = __builtin_source_location()) noexcept {
22     return current(__p);
23   }
24   constexpr source_location() = default;
25   constexpr source_location(source_location const &) = default;
26   constexpr unsigned int line() const noexcept { return __m_impl->_M_line; }
27   constexpr unsigned int column() const noexcept { return __m_impl->_M_column; }
28   constexpr const char *file() const noexcept { return __m_impl->_M_file_name; }
29   constexpr const char *function() const noexcept { return __m_impl->_M_function_name; }
30 
31 private:
32   // Note: The type name "std::source_location::__impl", and its constituent
33   // field-names are required by __builtin_source_location().
34   struct __impl {
35     const char *_M_file_name;
36     const char *_M_function_name;
37     unsigned _M_line;
38     unsigned _M_column;
39   };
40   const __impl *__m_impl = nullptr;
41 };
42 } // namespace std
43 
44 using SL = std::source_location;
45 
46 extern "C" int sink(...);
47 
48 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-ONE
49 //
50 // CHECK-GLOBAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_const_init.cpp\00"
51 // CHECK-GLOBAL-ONE-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
52 // CHECK-GLOBAL-ONE-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 1000, i32 {{[0-9]+}} }, align 8
53 // CHECK-GLOBAL-ONE: @const_init_global ={{.*}} global %"class.std::source_location" { %"struct.std::source_location::__impl"* @[[IMPL]] }, align 8
54 #line 1000 "test_const_init.cpp"
55 SL const_init_global = SL::current();
56 
57 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-TWO
58 //
59 // CHECK-GLOBAL-TWO-DAG: @runtime_init_global ={{.*}} global %"class.std::source_location" zeroinitializer, align 8
60 //
61 // CHECK-GLOBAL-TWO-DAG: @[[FILE:.*]] = {{.*}}c"test_runtime_init.cpp\00"
62 // CHECK-GLOBAL-TWO-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
63 // CHECK-GLOBAL-TWO-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 1100, i32 {{[0-9]+}} }, align 8
64 //
65 // CHECK-GLOBAL-TWO: define internal void @__cxx_global_var_init()
66 // CHECK-GLOBAL-TWO-NOT: ret
67 // CHECK-GLOBAL-TWO: %call = call %"struct.std::source_location::__impl"* @_ZNSt15source_location11bad_currentEPKv({{.*}} @[[IMPL]]
68 // CHECK-GLOBAL-TWO: store %"struct.std::source_location::__impl"* %call, {{.*}} @runtime_init_global
69 
70 #line 1100 "test_runtime_init.cpp"
71 SL runtime_init_global = SL::bad_current();
72 
73 #line 2000 "test_function.cpp"
74 extern "C" void test_function() {
75 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-LOCAL-ONE
76 //
77 // CHECK-LOCAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_current.cpp\00"
78 // CHECK-LOCAL-ONE-DAG: @[[FUNC:.*]] = {{.*}}c"void test_function()\00"
79 // CHECK-LOCAL-ONE-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 2100, i32 {{[0-9]+}} }, align 8
80 //
81 // CHECK-LOCAL-ONE:  define {{.*}} @test_function
82 // CHECK-LOCAL-ONE:  call %"struct.std::source_location::__impl"* @_ZNSt15source_location7currentEPKv({{.*}} @[[IMPL]]
83 #line 2100 "test_current.cpp"
84   SL local = SL::current();
85 }
86 
87 #line 3000 "TestInitClass.cpp"
88 struct TestInit {
89   SL info = SL::current();
90   SL arg_info;
91 
92 #line 3100 "TestInitCtor.cpp"
93   TestInit(SL arg_info = SL::current()) : arg_info(arg_info) {}
94 };
95 
96 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-GLOBAL
97 //
98 // CHECK-CTOR-GLOBAL-DAG: @GlobalInitVal ={{.*}} global %struct.TestInit zeroinitializer, align 8
99 // CHECK-CTOR-GLOBAL-DAG: @[[FILE:.*]] = {{.*}}c"GlobalInitVal.cpp\00"
100 // CHECK-CTOR-GLOBAL-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
101 // CHECK-CTOR-GLOBAL-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 3400, i32 {{[0-9]+}} }, align 8
102 //
103 // CHECK-CTOR-GLOBAL: define internal void @__cxx_global_var_init.{{[0-9]+}}()
104 // CHECK-CTOR-GLOBAL-NOT: ret
105 //
106 // CHECK-CTOR-GLOBAL: call %"struct.std::source_location::__impl"* @_ZNSt15source_location7currentEPKv({{.*}} @[[IMPL]]
107 // CHECK-CTOR-GLOBAL-NOT: ret
108 // CHECK-CTOR-GLOBAL: call void @_ZN8TestInitC1ESt15source_location(%struct.TestInit* {{[^,]*}} @GlobalInitVal, %"struct.std::source_location::__impl"*
109 #line 3400 "GlobalInitVal.cpp"
110 TestInit GlobalInitVal;
111 
112 extern "C" void test_init_function() {
113 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-LOCAL
114 //
115 // CHECK-CTOR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"LocalInitVal.cpp\00"
116 // CHECK-CTOR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"void test_init_function()\00"
117 // CHECK-CTOR-LOCAL-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 3500, i32 {{[0-9]+}} }, align 8
118 //
119 // CHECK-CTOR-LOCAL: define{{.*}} void @test_init_function()
120 // CHECK-CTOR-LOCAL-NOT: ret
121 //
122 // CHECK-CTOR-LOCAL: call %"struct.std::source_location::__impl"* @_ZNSt15source_location7currentEPKv({{.*}} @[[IMPL]]
123 // CHECK-CTOR-LOCAL-NOT: ret
124 // CHECK-CTOR-LOCAL: call void @_ZN8TestInitC1ESt15source_location(%struct.TestInit* {{[^,]*}} %init_local, %"struct.std::source_location::__impl"*
125 
126 #line 3500 "LocalInitVal.cpp"
127   TestInit init_local;
128   sink(init_local);
129 }
130 
131 #line 4000 "ConstexprClass.cpp"
132 struct TestInitConstexpr {
133   SL info = SL::current();
134   SL arg_info;
135 #line 4200 "ConstexprCtor.cpp"
136   constexpr TestInitConstexpr(SL arg_info = SL::current()) : arg_info(arg_info) {}
137 };
138 
139 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-T2
140 //
141 // CHECK-CONSTEXPR-T2-DAG: @[[FILE_INIT:.*]] = {{.*}}c"ConstexprCtor.cpp\00"
142 // CHECK-CONSTEXPR-T2-DAG: @[[FUNC_INIT:.*]] = {{.*}}c"TestInitConstexpr::TestInitConstexpr(SL)\00"
143 // CHECK-CONSTEXPR-T2-DAG: @[[IMPL_INIT:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE_INIT]], {{[^@]*}}@[[FUNC_INIT]], {{.*}} i32 4200, i32 {{[0-9]+}} }, align 8
144 // CHECK-CONSTEXPR-T2-DAG: @[[FILE_ARG:.*]] = {{.*}}c"ConstexprGlobal.cpp\00"
145 // CHECK-CONSTEXPR-T2-DAG: @[[EMPTY:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
146 // CHECK-CONSTEXPR-T2-DAG: @[[IMPL_ARG:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE_ARG]], {{[^@]*}}@[[EMPTY]], {{.*}} i32 4400, i32 {{[0-9]+}} }, align 8
147 //
148 // CHECK-CONSTEXPR-T2: @ConstexprGlobal ={{.*}} global %struct.TestInitConstexpr {
149 // CHECK-CONSTEXPR-T2-SAME: %"class.std::source_location" { %"struct.std::source_location::__impl"* @[[IMPL_INIT]] },
150 // CHECK-CONSTEXPR-T2-SAME: %"class.std::source_location" { %"struct.std::source_location::__impl"* @[[IMPL_ARG]] }
151 #line 4400 "ConstexprGlobal.cpp"
152 TestInitConstexpr ConstexprGlobal;
153 
154 extern "C" void test_init_function_constexpr() {
155 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-LOCAL
156 //
157 // CHECK-CONSTEXPR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"void test_init_function_constexpr()\00"
158 // CHECK-CONSTEXPR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"ConstexprLocal.cpp\00"
159 // CHECK-CONSTEXPR-LOCAL-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 4600, i32 {{[0-9]+}} }, align 8
160 //
161 // CHECK-CONSTEXPR-LOCAL: define{{.*}} void @test_init_function_constexpr()
162 // CHECK-CONSTEXPR-LOCAL-NOT: ret
163 // CHECK-CONSTEXPR-LOCAL: call %"struct.std::source_location::__impl"* @_ZNSt15source_location7currentEPKv({{.*}} @[[IMPL]]
164 // CHECK-CONSTEXPR-LOCAL-NOT: ret
165 // CHECK-CONSTEXPR-LOCAL: call void @_ZN17TestInitConstexprC1ESt15source_location(%struct.TestInitConstexpr* {{[^,]*}} %local_val, %"struct.std::source_location::__impl"*
166 #line 4600 "ConstexprLocal.cpp"
167   TestInitConstexpr local_val;
168 }
169 
170 #line 5000 "TestInitAgg.cpp"
171 struct TestInitAgg {
172 #line 5100 "i1.cpp"
173   SL i1;
174 #line 5200 "i2.cpp"
175   SL i2 = SL::current();
176 #line 5300 "TestInitAggEnd.cpp"
177 };
178 
179 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-DEFAULT
180 //
181 // CHECK-AGG-DEFAULT-DAG: @[[FILE:.*]] = {{.*}}c"TestInitAgg.cpp\00"
182 // CHECK-AGG-DEFAULT-DAG: @[[FUNC:.*]] = {{.*}}c"TestInitAgg::TestInitAgg()\00"
183 // CHECK-AGG-DEFAULT-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 5000, i32 {{[0-9]+}} }, align 8
184 //
185 // CHECK-AGG-DEFAULT: @GlobalAggDefault ={{.*}} global %struct.TestInitAgg {
186 // CHECK-AGG-DEFAULT-SAME: %"class.std::source_location" zeroinitializer,
187 // CHECK-AGG-DEFAULT-SAME: %"class.std::source_location" { %"struct.std::source_location::__impl"* @[[IMPL]] }
188 #line 5400 "GlobalAggDefault.cpp"
189 TestInitAgg GlobalAggDefault;
190 
191 #line 5500 "test_agg_init_test.cpp"
192 extern "C" void test_agg_init() {
193 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-INIT
194 
195 // CHECK-AGG-INIT-DAG: @[[FUNC:.*]] = {{.*}}c"void test_agg_init()\00"
196 
197 // CHECK-AGG-INIT-DAG: @[[FILE:.*]] = {{.*}}c"BraceInitEnd.cpp\00"
198 // CHECK-AGG-INIT-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 5700, i32 {{[0-9]+}} }, align 8
199 
200 #line 5600 "BraceInitStart.cpp"
201   TestInitAgg local_brace_init{
202 #line 5700 "BraceInitEnd.cpp"
203   };
204 
205 // CHECK-AGG-INIT-DAG: @[[FILE:.*]] = {{.*}}c"EqualInitEnd.cpp\00"
206 // CHECK-AGG-INIT-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 5900, i32 {{[0-9]+}} }, align 8
207 
208 #line 5800 "EqualInitStart.cpp"
209   TestInitAgg local_equal_init =
210       {
211 #line 5900 "EqualInitEnd.cpp"
212       };
213 
214 
215 // CHECK-AGG-INIT-DAG: @[[FILE_DEFAULT:.*]] = {{.*}}c"InitListEnd.cpp\00"
216 // CHECK-AGG-INIT-DAG: @[[FILE_ELEM:.*]] = {{.*}}c"ListElem.cpp\00"
217 // CHECK-AGG-INIT-DAG: @[[IMPL_DEFAULT:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE_ELEM]], {{[^@]*}}@[[FUNC]], {{.*}} i32 6100, i32 {{[0-9]+}} }, align 8
218 // CHECK-AGG-INIT-DAG: @[[IMPL_ELEM:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE_DEFAULT]], {{[^@]*}}@[[FUNC]], {{.*}} i32 6200, i32 {{[0-9]+}} }, align 8
219 
220 #line 6000 "InitListStart.cpp"
221   TestInitAgg local_list_init =
222       {
223 #line 6100 "ListElem.cpp"
224           {SL::current()}
225 #line 6200 "InitListEnd.cpp"
226       };
227 }
228 
229 #line 7000 "TestTemplate.cpp"
230 template <class Tp, int>
231 struct TestTemplate {
232   Tp info = Tp::current();
233   Tp arg_info;
234 #line 7100 "TestTemplateCtor.cpp"
235   constexpr TestTemplate(Tp arg_info = Tp::current()) : arg_info(arg_info) {}
236 };
237 
238 #line 7200 "test_template.cpp"
239 template <class T, int V>
240 void test_template() {
241 
242 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=0
243 // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=1
244 //
245 // CHECK-TEMPL-DAG: @[[FILE:.*]] = {{.*}}c"local_templ.cpp\00"
246 // CHECK-TEMPL-DAG: @[[FUNC:.*]] = {{.*}}c"void test_template() [T = std::source_location, V = [[INT_ID]]]\00"
247 // CHECK-TEMPL-DAG: @[[IMPL:.*]] = private unnamed_addr constant %"struct.std::source_location::__impl" { {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], {{.*}} i32 7300, i32 {{[0-9]+}} }, align 8
248 #line 7300 "local_templ.cpp"
249   TestTemplate<T, V> local_templ;
250 }
251 #line 7400 "EndTestTemplate.cpp"
252 template void test_template<SL, 0>();
253 template void test_template<SL, 1>();
254