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__
12 class source_location
{
16 static constexpr source_location
current(const __impl
*__p
= __builtin_source_location()) noexcept
{
17 source_location __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
: ""; }
29 // Note: The type name "std::source_location::__impl", and its constituent
30 // field-names are required by __builtin_source_location().
32 const char *_M_file_name
;
33 const char *_M_function_name
;
37 const __impl
*__m_impl
= nullptr;
40 using public_impl_alias
= __impl
;
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) {
56 return *LHS
== 0 && *RHS
== 0;
60 constexpr T
identity(T t
) {
64 template <class T
, class U
>
70 template <class T
, class U
>
71 constexpr bool is_same
= false;
73 constexpr bool is_same
<T
, T
> = true;
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
*>);
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 //===----------------------------------------------------------------------===//
91 //===----------------------------------------------------------------------===//
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);
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;
109 SL
// Call expression starts here
116 static_assert(S2
.line() == ExpectLine
, "");
124 == __LINE__
- 1, "");
129 == __LINE__
- 2, "");
133 == __LINE__
- 2, "");
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()) {
148 static_assert(test_line_fn_simple() == __LINE__
, "");
149 static_assert(test_line_fn_simple() == __LINE__
, "");
153 constexpr int operator()(int x
= __builtin_LINE()) const { return x
; }
155 constexpr CallExpr
get_call() { return CallExpr
{}; }
156 static_assert(get_call()() == __LINE__
, "");
159 constexpr bool test_line_fn_template(T Expect
, int L
= __builtin_LINE()) {
162 static_assert(test_line_fn_template(__LINE__
));
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())
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__
), "");
197 int y
= __builtin_LINE();
198 constexpr bool check(int expect
) const {
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();
211 U info
= U::current();
214 template <class T
, class U
= SL
>
215 constexpr U
test_fn_template(T
, U u
= U::current()) {
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());
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());
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);
256 int x
= __builtin_LINE();
257 int y
= __builtin_LINE();
258 int z
= __builtin_LINE();
261 struct AggDer
: AggBase
{
264 static_assert(AggDer
{}.x
== 400, "");
268 int x
= __builtin_LINE();
272 ClassBase() = default;
273 constexpr ClassBase(int yy
, int zz
= __builtin_LINE())
276 struct ClassDer
: ClassBase
{
278 ClassDer() = default;
279 constexpr ClassDer(int yy
) : ClassBase(yy
) {}
280 constexpr ClassDer(int yy
, int zz
) : ClassBase(yy
, zz
) {}
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
{
290 ClassAggDer() = default;
291 constexpr ClassAggDer(int, int x
= __builtin_LINE()) : AggBase
{x
} {}
293 static_assert(ClassAggDer
{}.x
== 100, "");
295 } // namespace test_line
297 //===----------------------------------------------------------------------===//
299 //===----------------------------------------------------------------------===//
301 namespace test_file
{
302 constexpr const char *test_file_simple(const char *__f
= __builtin_FILE()) {
305 void test_function() {
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"));
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()) {
350 constexpr const char *get_function() {
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()};
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
>
374 T info
= T::current();
376 TestCtor() = default;
377 template <class U
= SL
>
378 constexpr TestCtor(int, U u
= U::current()) : ctor_info(u
) {}
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
{
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;
411 SL
// Call expression starts here
418 static_assert(S2
.column() == ExpectCol
, "");
421 constexpr int ExpectCol
= 2;
423 __builtin_COLUMN
// Expect call expression to start here
425 static_assert(C
== ExpectCol
);
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"));
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
));
449 check(t
.x
, " T", 0); // Start of default constructor decl.
454 check(t1
.x
, "TestClass t"); // Start of variable being constructed.
458 check(t
.x
, "TestAggClass t { }");
461 TestAggClass t
= { };
462 check(t
.x
, "TestAggClass t = { }");
466 static_assert(test_class());
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;
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
; }
494 int n
= __builtin_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();
506 #line 4300 "test_passed.cpp"
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"
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()"));
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
; }
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() {}
553 static_assert(II
.l
== 5200, "");
554 static_assert(is_equal(II
.f
, "in_init.cpp"));
555 static_assert(is_equal(II
.func
, "InInit"));
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"
575 #line 6100 "InitCtor.cpp"
576 constexpr Init(SL info
= SL::current()) : info(info
) {}
578 #line 6200 "InitGlobal.cpp"
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(); }
589 constexpr const char* bar(const char* x
= foo()) { return x
; }
590 constexpr bool test() {
591 static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
594 static_assert(test());