1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
2 // expected-no-diagnostics
3 
4 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
5 #define CURRENT_FROM_MACRO() SL::current()
6 #define FORWARD(...) __VA_ARGS__
7 
8 template <unsigned>
9 struct Printer;
10 
11 namespace std {
12 namespace experimental {
13 struct source_location {
14 private:
15   unsigned int __m_line = 0;
16   unsigned int __m_col = 0;
17   const char *__m_file = nullptr;
18   const char *__m_func = nullptr;
19 public:
currentstd::experimental::source_location20   static constexpr source_location current(
21       const char *__file = __builtin_FILE(),
22       const char *__func = __builtin_FUNCTION(),
23       unsigned int __line = __builtin_LINE(),
24       unsigned int __col = __builtin_COLUMN()) noexcept {
25     source_location __loc;
26     __loc.__m_line = __line;
27     __loc.__m_col = __col;
28     __loc.__m_file = __file;
29     __loc.__m_func = __func;
30     return __loc;
31   }
32   constexpr source_location() = default;
33   constexpr source_location(source_location const &) = default;
linestd::experimental::source_location34   constexpr unsigned int line() const noexcept { return __m_line; }
columnstd::experimental::source_location35   constexpr unsigned int column() const noexcept { return __m_col; }
filestd::experimental::source_location36   constexpr const char *file() const noexcept { return __m_file; }
functionstd::experimental::source_location37   constexpr const char *function() const noexcept { return __m_func; }
38 };
39 } // namespace experimental
40 } // namespace std
41 
42 using SL = std::experimental::source_location;
43 
44 #include "Inputs/source-location-file.h"
45 namespace SLF = source_location_file;
46 
is_equal(const char * LHS,const char * RHS)47 constexpr bool is_equal(const char *LHS, const char *RHS) {
48   while (*LHS != 0 && *RHS != 0) {
49     if (*LHS != *RHS)
50       return false;
51     ++LHS;
52     ++RHS;
53   }
54   return *LHS == 0 && *RHS == 0;
55 }
56 
57 template <class T>
identity(T t)58 constexpr T identity(T t) {
59   return t;
60 }
61 
62 template <class T, class U>
63 struct Pair {
64   T first;
65   U second;
66 };
67 
68 template <class T, class U>
69 constexpr bool is_same = false;
70 template <class T>
71 constexpr bool is_same<T, T> = true;
72 
73 // test types
74 static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
75 static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);
76 static_assert(is_same<decltype(__builtin_FILE()), const char *>);
77 static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
78 
79 // test noexcept
80 static_assert(noexcept(__builtin_LINE()));
81 static_assert(noexcept(__builtin_COLUMN()));
82 static_assert(noexcept(__builtin_FILE()));
83 static_assert(noexcept(__builtin_FUNCTION()));
84 
85 //===----------------------------------------------------------------------===//
86 //                            __builtin_LINE()
87 //===----------------------------------------------------------------------===//
88 
89 namespace test_line {
90 static_assert(SL::current().line() == __LINE__);
91 static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());
92 
93 static constexpr SL GlobalS = SL::current();
94 
95 static_assert(GlobalS.line() == __LINE__ - 2);
96 
97 // clang-format off
test_line_fn()98 constexpr bool test_line_fn() {
99   constexpr SL S = SL::current();
100   static_assert(S.line() == (__LINE__ - 1), "");
101   // The start of the call expression to `current()` begins at the token `SL`
102   constexpr int ExpectLine = __LINE__ + 3;
103   constexpr SL S2
104   =
105   SL // Call expression starts here
106   ::
107   current
108   (
109 
110   )
111   ;
112   static_assert(S2.line() == ExpectLine, "");
113 
114   static_assert(
115           FORWARD(
116              __builtin_LINE
117             (
118             )
119           )
120     == __LINE__ - 1, "");
121   static_assert(\
122 \
123   __builtin_LINE()\
124 \
125   == __LINE__ - 2, "");
126   static_assert(\
127           _\
128 _builtin_LINE()
129           == __LINE__ - 2, "");
130 
131   return true;
132 }
133 // clang-format on
134 static_assert(test_line_fn());
135 
136 static_assert(__builtin_LINE() == __LINE__, "");
137 
baz()138 constexpr int baz() { return 101; }
139 
test_line_fn_simple(int z=baz (),int x=__builtin_LINE ())140 constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {
141   return x;
142 }
bar()143 void bar() {
144   static_assert(test_line_fn_simple() == __LINE__, "");
145   static_assert(test_line_fn_simple() == __LINE__, "");
146 }
147 
148 struct CallExpr {
operator ()test_line::CallExpr149   constexpr int operator()(int x = __builtin_LINE()) const { return x; }
150 };
get_call()151 constexpr CallExpr get_call() { return CallExpr{}; }
152 static_assert(get_call()() == __LINE__, "");
153 
154 template <class T>
test_line_fn_template(T Expect,int L=__builtin_LINE ())155 constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {
156   return Expect == L;
157 }
158 static_assert(test_line_fn_template(__LINE__));
159 
160 struct InMemInit {
checktest_line::InMemInit161   constexpr bool check(int expect) const {
162     return info.line() == expect;
163   }
164   SL info = SL::current();
165   InMemInit() = default;
InMemInittest_line::InMemInit166   constexpr InMemInit(int) {}
167 };
168 static_assert(InMemInit{}.check(__LINE__ - 3), "");
169 static_assert(InMemInit{42}.check(__LINE__ - 3), "");
170 
171 template <class T, class U = SL>
172 struct InMemInitTemplate {
checktest_line::InMemInitTemplate173   constexpr bool check(int expect) const {
174     return info.line() == expect;
175   }
176   U info = U::current();
177   InMemInitTemplate() = default;
InMemInitTemplatetest_line::InMemInitTemplate178   constexpr InMemInitTemplate(T) {}
InMemInitTemplatetest_line::InMemInitTemplate179   constexpr InMemInitTemplate(T, T) : info(U::current()) {}
InMemInitTemplatetest_line::InMemInitTemplate180   template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current())
181       : info(info) {}
182 };
test_mem_init_template()183 void test_mem_init_template() {
184   constexpr int line_offset = 8;
185   static_assert(InMemInitTemplate<int>{}.check(__LINE__ - line_offset), "");
186   static_assert(InMemInitTemplate<unsigned>{42}.check(__LINE__ - line_offset), "");
187   static_assert(InMemInitTemplate<unsigned>{42, 42}.check(__LINE__ - line_offset), "");
188   static_assert(InMemInitTemplate<unsigned>{42, 42, 42}.check(__LINE__), "");
189 }
190 
191 struct AggInit {
192   int x;
193   int y = __builtin_LINE();
checktest_line::AggInit194   constexpr bool check(int expect) const {
195     return y == expect;
196   }
197 };
198 constexpr AggInit AI{42};
199 static_assert(AI.check(__LINE__ - 1), "");
200 
201 template <class T, class U = SL>
202 struct AggInitTemplate {
checktest_line::AggInitTemplate203   constexpr bool check(int expect) const {
204     return expect == info.line();
205   }
206   T x;
207   U info = U::current();
208 };
209 
210 template <class T, class U = SL>
test_fn_template(T,U u=U::current ())211 constexpr U test_fn_template(T, U u = U::current()) {
212   return u;
213 }
fn_template_tests()214 void fn_template_tests() {
215   static_assert(test_fn_template(42).line() == __LINE__, "");
216 }
217 
218 struct TestMethodTemplate {
219   template <class T, class U = SL, class U2 = SL>
gettest_line::TestMethodTemplate220   constexpr U get(T, U u = U::current(), U2 u2 = identity(U2::current())) const {
221     assert(u.line() == u2.line());
222     return u;
223   }
224 };
method_template_tests()225 void method_template_tests() {
226   static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");
227 }
228 
229 struct InStaticInit {
230   static constexpr int LINE = __LINE__;
231   static constexpr const int x1 = __builtin_LINE();
232   static constexpr const int x2 = identity(__builtin_LINE());
233   static const int x3;
234   const int x4 = __builtin_LINE();
235   int x5 = __builtin_LINE();
236 };
237 const int InStaticInit::x3 = __builtin_LINE();
238 static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");
239 static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");
240 
241 template <class T, int N = __builtin_LINE(), int Expect = -1>
check_fn_template_param(T)242 constexpr void check_fn_template_param(T) {
243   constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;
244   static_assert(N == RealExpect);
245 }
246 template void check_fn_template_param(int);
247 template void check_fn_template_param<long, 42, 42>(long);
248 
249 #line 100
250 struct AggBase {
251 #line 200
252   int x = __builtin_LINE();
253   int y = __builtin_LINE();
254   int z = __builtin_LINE();
255 };
256 #line 300
257 struct AggDer : AggBase {
258 };
259 #line 400
260 static_assert(AggDer{}.x == 400, "");
261 
262 struct ClassBase {
263 #line 400
264   int x = __builtin_LINE();
265   int y = 0;
266   int z = 0;
267 #line 500
268   ClassBase() = default;
ClassBasetest_line::ClassBase269   constexpr ClassBase(int yy, int zz = __builtin_LINE())
270       : y(yy), z(zz) {}
271 };
272 struct ClassDer : ClassBase {
273 #line 600
274   ClassDer() = default;
ClassDertest_line::ClassDer275   constexpr ClassDer(int yy) : ClassBase(yy) {}
ClassDertest_line::ClassDer276   constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}
277 };
278 #line 700
279 static_assert(ClassDer{}.x == 500, "");
280 static_assert(ClassDer{42}.x == 501, "");
281 static_assert(ClassDer{42}.z == 601, "");
282 static_assert(ClassDer{42, 42}.x == 501, "");
283 
284 struct ClassAggDer : AggBase {
285 #line 800
286   ClassAggDer() = default;
ClassAggDertest_line::ClassAggDer287   constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}
288 };
289 static_assert(ClassAggDer{}.x == 100, "");
290 
291 } // namespace test_line
292 
293 //===----------------------------------------------------------------------===//
294 //                            __builtin_FILE()
295 //===----------------------------------------------------------------------===//
296 
297 namespace test_file {
test_file_simple(const char * __f=__builtin_FILE ())298 constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {
299   return __f;
300 }
test_function()301 void test_function() {
302 #line 900
303   static_assert(is_equal(test_file_simple(), __FILE__));
304   static_assert(is_equal(SLF::test_function().file(), __FILE__), "");
305   static_assert(is_equal(SLF::test_function_template(42).file(), __FILE__), "");
306 
307   static_assert(is_equal(SLF::test_function_indirect().file(), SLF::global_info.file()), "");
308   static_assert(is_equal(SLF::test_function_template_indirect(42).file(), SLF::global_info.file()), "");
309 
310   static_assert(test_file_simple() != nullptr);
311   static_assert(!is_equal(test_file_simple(), "source_location.cpp"));
312 }
313 
test_class()314 void test_class() {
315 #line 315
316   using SLF::TestClass;
317   constexpr TestClass Default;
318   constexpr TestClass InParam{42};
319   constexpr TestClass Template{42, 42};
320   constexpr auto *F = Default.info.file();
321   constexpr auto Char = F[0];
322   static_assert(is_equal(Default.info.file(), SLF::FILE), "");
323   static_assert(is_equal(InParam.info.file(), SLF::FILE), "");
324   static_assert(is_equal(InParam.ctor_info.file(), __FILE__), "");
325 }
326 
test_aggr_class()327 void test_aggr_class() {
328   using Agg = SLF::AggrClass<>;
329   constexpr Agg Default{};
330   constexpr Agg InitOne{42};
331   static_assert(is_equal(Default.init_info.file(), __FILE__), "");
332   static_assert(is_equal(InitOne.init_info.file(), __FILE__), "");
333 }
334 
335 } // namespace test_file
336 
337 //===----------------------------------------------------------------------===//
338 //                            __builtin_FUNCTION()
339 //===----------------------------------------------------------------------===//
340 
341 namespace test_func {
342 
test_func_simple(const char * __f=__builtin_FUNCTION ())343 constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {
344   return __f;
345 }
get_function()346 constexpr const char *get_function() {
347   return __func__;
348 }
test_function()349 constexpr bool test_function() {
350   return is_equal(__func__, test_func_simple()) &&
351          !is_equal(get_function(), test_func_simple());
352 }
353 static_assert(test_function());
354 
355 template <class T, class U = SL>
test_func_template(T,U u=U::current ())356 constexpr Pair<U, U> test_func_template(T, U u = U::current()) {
357   static_assert(is_equal(__func__, U::current().function()));
358   return {u, U::current()};
359 }
360 template <class T>
func_template_tests()361 void func_template_tests() {
362   constexpr auto P = test_func_template(42);
363   //static_assert(is_equal(P.first.function(), __func__), "");
364   //static_assert(!is_equal(P.second.function(), __func__), "");
365 }
366 template void func_template_tests<int>();
367 
368 template <class = int, class T = SL>
369 struct TestCtor {
370   T info = T::current();
371   T ctor_info;
372   TestCtor() = default;
373   template <class U = SL>
TestCtortest_func::TestCtor374   constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {}
375 };
ctor_tests()376 void ctor_tests() {
377   constexpr TestCtor<> Default;
378   constexpr TestCtor<> Template{42};
379   static_assert(!is_equal(Default.info.function(), __func__));
380   static_assert(is_equal(Default.info.function(), "TestCtor"));
381   static_assert(is_equal(Template.info.function(), "TestCtor"));
382   static_assert(is_equal(Template.ctor_info.function(), __func__));
383 }
384 
385 constexpr SL global_sl = SL::current();
386 static_assert(is_equal(global_sl.function(), ""));
387 
388 } // namespace test_func
389 
390 //===----------------------------------------------------------------------===//
391 //                            __builtin_COLUMN()
392 //===----------------------------------------------------------------------===//
393 
394 namespace test_column {
395 
396 // clang-format off
test_column_fn()397 constexpr bool test_column_fn() {
398   constexpr SL S = SL::current();
399   static_assert(S.line() == (__LINE__ - 1), "");
400   constexpr int Indent = 4;
401   {
402     // The start of the call expression to `current()` begins at the token `SL`
403     constexpr int ExpectCol = Indent + 3;
404     constexpr SL S2
405      =
406       SL // Call expression starts here
407         ::
408           current
409                  (
410 
411                   )
412                    ;
413     static_assert(S2.column() == ExpectCol, "");
414   }
415   {
416     constexpr int ExpectCol = 2;
417     constexpr int C =
418  __builtin_COLUMN // Expect call expression to start here
419       ();
420     static_assert(C == ExpectCol);
421   }
422   return true;
423 }
424 #line 420
425 static_assert(test_column_fn());
426 
427 // Test that the column matches the start of the call expression 'SL::current()'
428 static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));
429 struct TestClass {
430   int x = __builtin_COLUMN();
431    TestClass() = default; /* indented to 3 spaces for testing */
TestClasstest_column::TestClass432   constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}
433 };
434 struct TestAggClass {
435   int x = __builtin_COLUMN();
436 };
test_class()437 constexpr bool test_class() {
438 
439   auto check = [](int V, const char* S, int indent = 4) {
440     assert(V == (__builtin_strlen(S) + indent));
441   };
442   {
443     TestClass t{};
444     check(t.x, "   T", 0); // Start of default constructor decl.
445   }
446   {
447     TestClass t1
448             {42};
449     check(t1.x, "TestClass t"); // Start of variable being constructed.
450   }
451   {
452     TestAggClass t  { };
453     check(t.x, "TestAggClass t  { }");
454   }
455   {
456     TestAggClass t = { };
457     check(t.x, "TestAggClass t = { }");
458   }
459   return true;
460 }
461 static_assert(test_class());
462 // clang-format on
463 } // namespace test_column
464 
465 // Test [reflection.src_loc.creation]p2
466 //  >  The value should be affected by #line (C++14 16.4) in the same manner as
467 //  >  for __LINE__ and __FILE__.
468 namespace test_pragma_line {
469 constexpr int StartLine = 42;
470 #line 42
471 static_assert(__builtin_LINE() == StartLine);
472 static_assert(__builtin_LINE() == StartLine + 1);
473 static_assert(SL::current().line() == StartLine + 2);
474 #line 44 "test_file.c"
475 static_assert(is_equal("test_file.c", __FILE__));
476 static_assert(is_equal("test_file.c", __builtin_FILE()));
477 static_assert(is_equal("test_file.c", SL::current().file()));
478 static_assert(is_equal("test_file.c", SLF::test_function().file()));
479 static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
480 } // end namespace test_pragma_line
481 
482 namespace test_out_of_line_init {
483 #line 4000 "test_out_of_line_init.cpp"
get_line(unsigned n=__builtin_LINE ())484 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
get_file(const char * f=__builtin_FILE ())485 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
get_func(const char * f=__builtin_FUNCTION ())486 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
487 #line 4100 "A.cpp"
488 struct A {
489   int n = __builtin_LINE();
490   int n2 = get_line();
491   const char *f = __builtin_FILE();
492   const char *f2 = get_file();
493   const char *func = __builtin_FUNCTION();
494   const char *func2 = get_func();
495   SL info = SL::current();
496 };
497 #line 4200 "B.cpp"
498 struct B {
499   A a = {};
500 };
501 #line 4300 "test_passed.cpp"
502 constexpr B b = {};
503 static_assert(b.a.n == 4300, "");
504 static_assert(b.a.n2 == 4300, "");
505 static_assert(b.a.info.line() == 4300, "");
506 static_assert(is_equal(b.a.f, "test_passed.cpp"));
507 static_assert(is_equal(b.a.f2, "test_passed.cpp"));
508 static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));
509 static_assert(is_equal(b.a.func, ""));
510 static_assert(is_equal(b.a.func2, ""));
511 static_assert(is_equal(b.a.info.function(), ""));
512 
test_in_func()513 constexpr bool test_in_func() {
514 #line 4400 "test_func_passed.cpp"
515   constexpr B b = {};
516   static_assert(b.a.n == 4400, "");
517   static_assert(b.a.n2 == 4400, "");
518   static_assert(b.a.info.line() == 4400, "");
519   static_assert(is_equal(b.a.f, "test_func_passed.cpp"));
520   static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));
521   static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));
522   static_assert(is_equal(b.a.func, "test_in_func"));
523   static_assert(is_equal(b.a.func2, "test_in_func"));
524   static_assert(is_equal(b.a.info.function(), "test_in_func"));
525   return true;
526 }
527 static_assert(test_in_func());
528 
529 } // end namespace test_out_of_line_init
530 
531 namespace test_global_scope {
532 #line 5000 "test_global_scope.cpp"
get_line(unsigned n=__builtin_LINE ())533 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
get_file(const char * f=__builtin_FILE ())534 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
get_func(const char * f=__builtin_FUNCTION ())535 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
536 #line 5100
537 struct InInit {
538   unsigned l = get_line();
539   const char *f = get_file();
540   const char *func = get_func();
541 
542 #line 5200 "in_init.cpp"
InInittest_global_scope::InInit543   constexpr InInit() {}
544 };
545 #line 5300
546 constexpr InInit II;
547 
548 static_assert(II.l == 5200, "");
549 static_assert(is_equal(II.f, "in_init.cpp"));
550 static_assert(is_equal(II.func, "InInit"));
551 
552 #line 5400
553 struct AggInit {
554   unsigned l = get_line();
555   const char *f = get_file();
556   const char *func = get_func();
557 };
558 #line 5500 "brace_init.cpp"
559 constexpr AggInit AI = {};
560 static_assert(AI.l == 5500);
561 static_assert(is_equal(AI.f, "brace_init.cpp"));
562 static_assert(is_equal(AI.func, ""));
563 
564 } // namespace test_global_scope
565 
566 namespace TestFuncInInit {
567 #line 6000 "InitClass.cpp"
568 struct Init {
569   SL info;
570 #line 6100 "InitCtor.cpp"
InitTestFuncInInit::Init571   constexpr Init(SL info = SL::current()) : info(info) {}
572 };
573 #line 6200 "InitGlobal.cpp"
574 constexpr Init I;
575 static_assert(I.info.line() == 6200);
576 static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));
577 
578 } // namespace TestFuncInInit
579 
580 namespace TestConstexprContext {
581 #line 7000 "TestConstexprContext.cpp"
foo()582   constexpr const char* foo() { return __builtin_FILE(); }
583 #line 7100 "Bar.cpp"
bar(const char * x=foo ())584   constexpr const char* bar(const char* x = foo()) { return x; }
test()585   constexpr bool test() {
586     static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
587     return true;
588   }
589   static_assert(test());
590 }
591