[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / source_location.cpp
blobccb385f60dc4becf1f73259315f8abf045cb57ab
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
2 // expected-no-diagnostics
4 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
5 #define CURRENT_FROM_MACRO() SL::current()
6 #define FORWARD(...) __VA_ARGS__
8 template <unsigned>
9 struct Printer;
11 namespace std {
12 class source_location {
13 struct __impl;
15 public:
16 static constexpr source_location current(const __impl *__p = __builtin_source_location()) noexcept {
17 source_location __loc;
18 __loc.__m_impl = __p;
19 return __loc;
21 constexpr source_location() = default;
22 constexpr source_location(source_location const &) = default;
23 constexpr unsigned int line() const noexcept { return __m_impl ? __m_impl->_M_line : 0; }
24 constexpr unsigned int column() const noexcept { return __m_impl ? __m_impl->_M_column : 0; }
25 constexpr const char *file() const noexcept { return __m_impl ? __m_impl->_M_file_name : ""; }
26 constexpr const char *function() const noexcept { return __m_impl ? __m_impl->_M_function_name : ""; }
28 private:
29 // Note: The type name "std::source_location::__impl", and its constituent
30 // field-names are required by __builtin_source_location().
31 struct __impl {
32 const char *_M_file_name;
33 const char *_M_function_name;
34 unsigned _M_line;
35 unsigned _M_column;
37 const __impl *__m_impl = nullptr;
39 public:
40 using public_impl_alias = __impl;
42 } // namespace std
44 using SL = std::source_location;
46 #include "Inputs/source-location-file.h"
47 namespace SLF = source_location_file;
49 constexpr bool is_equal(const char *LHS, const char *RHS) {
50 while (*LHS != 0 && *RHS != 0) {
51 if (*LHS != *RHS)
52 return false;
53 ++LHS;
54 ++RHS;
56 return *LHS == 0 && *RHS == 0;
59 template <class T>
60 constexpr T identity(T t) {
61 return t;
64 template <class T, class U>
65 struct Pair {
66 T first;
67 U second;
70 template <class T, class U>
71 constexpr bool is_same = false;
72 template <class T>
73 constexpr bool is_same<T, T> = true;
75 // test types
76 static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
77 static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);
78 static_assert(is_same<decltype(__builtin_FILE()), const char *>);
79 static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
80 static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
82 // test noexcept
83 static_assert(noexcept(__builtin_LINE()));
84 static_assert(noexcept(__builtin_COLUMN()));
85 static_assert(noexcept(__builtin_FILE()));
86 static_assert(noexcept(__builtin_FUNCTION()));
87 static_assert(noexcept(__builtin_source_location()));
89 //===----------------------------------------------------------------------===//
90 // __builtin_LINE()
91 //===----------------------------------------------------------------------===//
93 namespace test_line {
94 static_assert(SL::current().line() == __LINE__);
95 static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());
97 static constexpr SL GlobalS = SL::current();
99 static_assert(GlobalS.line() == __LINE__ - 2);
101 // clang-format off
102 constexpr bool test_line_fn() {
103 constexpr SL S = SL::current();
104 static_assert(S.line() == (__LINE__ - 1), "");
105 // The start of the call expression to `current()` begins at the token `SL`
106 constexpr int ExpectLine = __LINE__ + 3;
107 constexpr SL S2
109 SL // Call expression starts here
111 current
116 static_assert(S2.line() == ExpectLine, "");
118 static_assert(
119 FORWARD(
120 __builtin_LINE
124 == __LINE__ - 1, "");
125 static_assert(\
127 __builtin_LINE()\
129 == __LINE__ - 2, "");
130 static_assert(\
132 _builtin_LINE()
133 == __LINE__ - 2, "");
135 return true;
137 // clang-format on
138 static_assert(test_line_fn());
140 static_assert(__builtin_LINE() == __LINE__, "");
142 constexpr int baz() { return 101; }
144 constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {
145 return x;
147 void bar() {
148 static_assert(test_line_fn_simple() == __LINE__, "");
149 static_assert(test_line_fn_simple() == __LINE__, "");
152 struct CallExpr {
153 constexpr int operator()(int x = __builtin_LINE()) const { return x; }
155 constexpr CallExpr get_call() { return CallExpr{}; }
156 static_assert(get_call()() == __LINE__, "");
158 template <class T>
159 constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {
160 return Expect == L;
162 static_assert(test_line_fn_template(__LINE__));
164 struct InMemInit {
165 constexpr bool check(int expect) const {
166 return info.line() == expect;
168 SL info = SL::current();
169 InMemInit() = default;
170 constexpr InMemInit(int) {}
172 static_assert(InMemInit{}.check(__LINE__ - 3), "");
173 static_assert(InMemInit{42}.check(__LINE__ - 3), "");
175 template <class T, class U = SL>
176 struct InMemInitTemplate {
177 constexpr bool check(int expect) const {
178 return info.line() == expect;
180 U info = U::current();
181 InMemInitTemplate() = default;
182 constexpr InMemInitTemplate(T) {}
183 constexpr InMemInitTemplate(T, T) : info(U::current()) {}
184 template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current())
185 : info(info) {}
187 void test_mem_init_template() {
188 constexpr int line_offset = 8;
189 static_assert(InMemInitTemplate<int>{}.check(__LINE__ - line_offset), "");
190 static_assert(InMemInitTemplate<unsigned>{42}.check(__LINE__ - line_offset), "");
191 static_assert(InMemInitTemplate<unsigned>{42, 42}.check(__LINE__ - line_offset), "");
192 static_assert(InMemInitTemplate<unsigned>{42, 42, 42}.check(__LINE__), "");
195 struct AggInit {
196 int x;
197 int y = __builtin_LINE();
198 constexpr bool check(int expect) const {
199 return y == expect;
202 constexpr AggInit AI{42};
203 static_assert(AI.check(__LINE__ - 1), "");
205 template <class T, class U = SL>
206 struct AggInitTemplate {
207 constexpr bool check(int expect) const {
208 return expect == info.line();
210 T x;
211 U info = U::current();
214 template <class T, class U = SL>
215 constexpr U test_fn_template(T, U u = U::current()) {
216 return u;
218 void fn_template_tests() {
219 static_assert(test_fn_template(42).line() == __LINE__, "");
222 struct TestMethodTemplate {
223 template <class T, class U = SL, class U2 = SL>
224 constexpr U get(T, U u = U::current(), U2 u2 = identity(U2::current())) const {
225 assert(u.line() == u2.line());
226 return u;
229 void method_template_tests() {
230 static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");
233 struct InStaticInit {
234 static constexpr int LINE = __LINE__;
235 static constexpr const int x1 = __builtin_LINE();
236 static constexpr const int x2 = identity(__builtin_LINE());
237 static const int x3;
238 const int x4 = __builtin_LINE();
239 int x5 = __builtin_LINE();
241 const int InStaticInit::x3 = __builtin_LINE();
242 static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");
243 static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");
245 template <class T, int N = __builtin_LINE(), int Expect = -1>
246 constexpr void check_fn_template_param(T) {
247 constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;
248 static_assert(N == RealExpect);
250 template void check_fn_template_param(int);
251 template void check_fn_template_param<long, 42, 42>(long);
253 #line 100
254 struct AggBase {
255 #line 200
256 int x = __builtin_LINE();
257 int y = __builtin_LINE();
258 int z = __builtin_LINE();
260 #line 300
261 struct AggDer : AggBase {
263 #line 400
264 static_assert(AggDer{}.x == 400, "");
266 struct ClassBase {
267 #line 400
268 int x = __builtin_LINE();
269 int y = 0;
270 int z = 0;
271 #line 500
272 ClassBase() = default;
273 constexpr ClassBase(int yy, int zz = __builtin_LINE())
274 : y(yy), z(zz) {}
276 struct ClassDer : ClassBase {
277 #line 600
278 ClassDer() = default;
279 constexpr ClassDer(int yy) : ClassBase(yy) {}
280 constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}
282 #line 700
283 static_assert(ClassDer{}.x == 500, "");
284 static_assert(ClassDer{42}.x == 501, "");
285 static_assert(ClassDer{42}.z == 601, "");
286 static_assert(ClassDer{42, 42}.x == 501, "");
288 struct ClassAggDer : AggBase {
289 #line 800
290 ClassAggDer() = default;
291 constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}
293 static_assert(ClassAggDer{}.x == 100, "");
295 } // namespace test_line
297 //===----------------------------------------------------------------------===//
298 // __builtin_FILE()
299 //===----------------------------------------------------------------------===//
301 namespace test_file {
302 constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {
303 return __f;
305 void test_function() {
306 #line 900
307 static_assert(is_equal(test_file_simple(), __FILE__));
308 static_assert(is_equal(SLF::test_function().file(), __FILE__), "");
309 static_assert(is_equal(SLF::test_function_template(42).file(), __FILE__), "");
311 static_assert(is_equal(SLF::test_function_indirect().file(), SLF::global_info.file()), "");
312 static_assert(is_equal(SLF::test_function_template_indirect(42).file(), SLF::global_info.file()), "");
314 static_assert(test_file_simple() != nullptr);
315 static_assert(!is_equal(test_file_simple(), "source_location.cpp"));
318 void test_class() {
319 #line 315
320 using SLF::TestClass;
321 constexpr TestClass Default;
322 constexpr TestClass InParam{42};
323 constexpr TestClass Template{42, 42};
324 constexpr auto *F = Default.info.file();
325 constexpr auto Char = F[0];
326 static_assert(is_equal(Default.info.file(), SLF::FILE), "");
327 static_assert(is_equal(InParam.info.file(), SLF::FILE), "");
328 static_assert(is_equal(InParam.ctor_info.file(), __FILE__), "");
331 void test_aggr_class() {
332 using Agg = SLF::AggrClass<>;
333 constexpr Agg Default{};
334 constexpr Agg InitOne{42};
335 static_assert(is_equal(Default.init_info.file(), __FILE__), "");
336 static_assert(is_equal(InitOne.init_info.file(), __FILE__), "");
339 } // namespace test_file
341 //===----------------------------------------------------------------------===//
342 // __builtin_FUNCTION()
343 //===----------------------------------------------------------------------===//
345 namespace test_func {
347 constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {
348 return __f;
350 constexpr const char *get_function() {
351 return __func__;
353 constexpr bool test_function() {
354 return is_equal(__func__, test_func_simple()) &&
355 !is_equal(get_function(), test_func_simple());
357 static_assert(test_function());
359 template <class T, class U = SL>
360 constexpr Pair<U, U> test_func_template(T, U u = U::current()) {
361 static_assert(is_equal(__PRETTY_FUNCTION__, U::current().function()));
362 return {u, U::current()};
364 template <class T>
365 void func_template_tests() {
366 constexpr auto P = test_func_template(42);
367 //static_assert(is_equal(P.first.function(), __func__), "");
368 //static_assert(!is_equal(P.second.function(), __func__), "");
370 template void func_template_tests<int>();
372 template <class = int, class T = SL>
373 struct TestCtor {
374 T info = T::current();
375 T ctor_info;
376 TestCtor() = default;
377 template <class U = SL>
378 constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {}
380 void ctor_tests() {
381 constexpr TestCtor<> Default;
382 constexpr TestCtor<> Template{42};
383 static const char *XYZZY = Template.info.function();
384 static_assert(is_equal(Default.info.function(), "test_func::TestCtor<>::TestCtor() [T = std::source_location]"));
385 static_assert(is_equal(Default.ctor_info.function(), ""));
386 static_assert(is_equal(Template.info.function(), "test_func::TestCtor<>::TestCtor(int, U) [T = std::source_location, U = std::source_location]"));
387 static_assert(is_equal(Template.ctor_info.function(), __PRETTY_FUNCTION__));
390 constexpr SL global_sl = SL::current();
391 static_assert(is_equal(global_sl.function(), ""));
393 } // namespace test_func
395 //===----------------------------------------------------------------------===//
396 // __builtin_COLUMN()
397 //===----------------------------------------------------------------------===//
399 namespace test_column {
401 // clang-format off
402 constexpr bool test_column_fn() {
403 constexpr SL S = SL::current();
404 static_assert(S.line() == (__LINE__ - 1), "");
405 constexpr int Indent = 4;
407 // The start of the call expression to `current()` begins at the token `SL`
408 constexpr int ExpectCol = Indent + 3;
409 constexpr SL S2
411 SL // Call expression starts here
413 current
418 static_assert(S2.column() == ExpectCol, "");
421 constexpr int ExpectCol = 2;
422 constexpr int C =
423 __builtin_COLUMN // Expect call expression to start here
425 static_assert(C == ExpectCol);
427 return true;
429 #line 420
430 static_assert(test_column_fn());
432 // Test that the column matches the start of the call expression 'SL::current()'
433 static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));
434 struct TestClass {
435 int x = __builtin_COLUMN();
436 TestClass() = default; /* indented to 3 spaces for testing */
437 constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}
439 struct TestAggClass {
440 int x = __builtin_COLUMN();
442 constexpr bool test_class() {
444 auto check = [](int V, const char* S, int indent = 4) {
445 assert(V == (__builtin_strlen(S) + indent));
448 TestClass t{};
449 check(t.x, " T", 0); // Start of default constructor decl.
452 TestClass t1
453 {42};
454 check(t1.x, "TestClass t"); // Start of variable being constructed.
457 TestAggClass t { };
458 check(t.x, "TestAggClass t { }");
461 TestAggClass t = { };
462 check(t.x, "TestAggClass t = { }");
464 return true;
466 static_assert(test_class());
467 // clang-format on
468 } // namespace test_column
470 // Test [reflection.src_loc.creation]p2
471 // > The value should be affected by #line (C++14 16.4) in the same manner as
472 // > for __LINE__ and __FILE__.
473 namespace test_pragma_line {
474 constexpr int StartLine = 42;
475 #line 42
476 static_assert(__builtin_LINE() == StartLine);
477 static_assert(__builtin_LINE() == StartLine + 1);
478 static_assert(SL::current().line() == StartLine + 2);
479 #line 44 "test_file.c"
480 static_assert(is_equal("test_file.c", __FILE__));
481 static_assert(is_equal("test_file.c", __builtin_FILE()));
482 static_assert(is_equal("test_file.c", SL::current().file()));
483 static_assert(is_equal("test_file.c", SLF::test_function().file()));
484 static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
485 } // end namespace test_pragma_line
487 namespace test_out_of_line_init {
488 #line 4000 "test_out_of_line_init.cpp"
489 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
490 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
491 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
492 #line 4100 "A.cpp"
493 struct A {
494 int n = __builtin_LINE();
495 int n2 = get_line();
496 const char *f = __builtin_FILE();
497 const char *f2 = get_file();
498 const char *func = __builtin_FUNCTION();
499 const char *func2 = get_func();
500 SL info = SL::current();
502 #line 4200 "B.cpp"
503 struct B {
504 A a = {};
506 #line 4300 "test_passed.cpp"
507 constexpr B b = {};
508 static_assert(b.a.n == 4300, "");
509 static_assert(b.a.n2 == 4300, "");
510 static_assert(b.a.info.line() == 4300, "");
511 static_assert(is_equal(b.a.f, "test_passed.cpp"));
512 static_assert(is_equal(b.a.f2, "test_passed.cpp"));
513 static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));
514 static_assert(is_equal(b.a.func, ""));
515 static_assert(is_equal(b.a.func2, ""));
516 static_assert(is_equal(b.a.info.function(), ""));
518 constexpr bool test_in_func() {
519 #line 4400 "test_func_passed.cpp"
520 constexpr B b = {};
521 static_assert(b.a.n == 4400, "");
522 static_assert(b.a.n2 == 4400, "");
523 static_assert(b.a.info.line() == 4400, "");
524 static_assert(is_equal(b.a.f, "test_func_passed.cpp"));
525 static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));
526 static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));
527 static_assert(is_equal(b.a.func, "test_in_func"));
528 static_assert(is_equal(b.a.func2, "test_in_func"));
529 static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()"));
530 return true;
532 static_assert(test_in_func());
534 } // end namespace test_out_of_line_init
536 namespace test_global_scope {
537 #line 5000 "test_global_scope.cpp"
538 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
539 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
540 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
541 #line 5100
542 struct InInit {
543 unsigned l = get_line();
544 const char *f = get_file();
545 const char *func = get_func();
547 #line 5200 "in_init.cpp"
548 constexpr InInit() {}
550 #line 5300
551 constexpr InInit II;
553 static_assert(II.l == 5200, "");
554 static_assert(is_equal(II.f, "in_init.cpp"));
555 static_assert(is_equal(II.func, "InInit"));
557 #line 5400
558 struct AggInit {
559 unsigned l = get_line();
560 const char *f = get_file();
561 const char *func = get_func();
563 #line 5500 "brace_init.cpp"
564 constexpr AggInit AI = {};
565 static_assert(AI.l == 5500);
566 static_assert(is_equal(AI.f, "brace_init.cpp"));
567 static_assert(is_equal(AI.func, ""));
569 } // namespace test_global_scope
571 namespace TestFuncInInit {
572 #line 6000 "InitClass.cpp"
573 struct Init {
574 SL info;
575 #line 6100 "InitCtor.cpp"
576 constexpr Init(SL info = SL::current()) : info(info) {}
578 #line 6200 "InitGlobal.cpp"
579 constexpr Init I;
580 static_assert(I.info.line() == 6200);
581 static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));
583 } // namespace TestFuncInInit
585 namespace TestConstexprContext {
586 #line 7000 "TestConstexprContext.cpp"
587 constexpr const char* foo() { return __builtin_FILE(); }
588 #line 7100 "Bar.cpp"
589 constexpr const char* bar(const char* x = foo()) { return x; }
590 constexpr bool test() {
591 static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
592 return true;
594 static_assert(test());