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: 20 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; 34 constexpr unsigned int line() const noexcept { return __m_line; } 35 constexpr unsigned int column() const noexcept { return __m_col; } 36 constexpr const char *file() const noexcept { return __m_file; } 37 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 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> 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 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 138 constexpr int baz() { return 101; } 139 140 constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) { 141 return x; 142 } 143 void bar() { 144 static_assert(test_line_fn_simple() == __LINE__, ""); 145 static_assert(test_line_fn_simple() == __LINE__, ""); 146 } 147 148 struct CallExpr { 149 constexpr int operator()(int x = __builtin_LINE()) const { return x; } 150 }; 151 constexpr CallExpr get_call() { return CallExpr{}; } 152 static_assert(get_call()() == __LINE__, ""); 153 154 template <class T> 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 { 161 constexpr bool check(int expect) const { 162 return info.line() == expect; 163 } 164 SL info = SL::current(); 165 InMemInit() = default; 166 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 { 173 constexpr bool check(int expect) const { 174 return info.line() == expect; 175 } 176 U info = U::current(); 177 InMemInitTemplate() = default; 178 constexpr InMemInitTemplate(T) {} 179 constexpr InMemInitTemplate(T, T) : info(U::current()) {} 180 template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current()) 181 : info(info) {} 182 }; 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(); 194 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 { 203 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> 211 constexpr U test_fn_template(T, U u = U::current()) { 212 return u; 213 } 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> 220 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 }; 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> 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; 269 constexpr ClassBase(int yy, int zz = __builtin_LINE()) 270 : y(yy), z(zz) {} 271 }; 272 struct ClassDer : ClassBase { 273 #line 600 274 ClassDer() = default; 275 constexpr ClassDer(int yy) : ClassBase(yy) {} 276 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; 287 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 { 298 constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) { 299 return __f; 300 } 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 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 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 343 constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) { 344 return __f; 345 } 346 constexpr const char *get_function() { 347 return __func__; 348 } 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> 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> 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> 374 constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {} 375 }; 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 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 */ 432 constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {} 433 }; 434 struct TestAggClass { 435 int x = __builtin_COLUMN(); 436 }; 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" 484 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; } 485 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; } 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 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" 533 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; } 534 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; } 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" 543 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" 571 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" 582 constexpr const char* foo() { return __builtin_FILE(); } 583 #line 7100 "Bar.cpp" 584 constexpr const char* bar(const char* x = foo()) { return x; } 585 constexpr bool test() { 586 static_assert(is_equal(bar(), "TestConstexprContext.cpp")); 587 return true; 588 } 589 static_assert(test()); 590 } 591