forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			591 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			591 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
 | 
						|
// expected-no-diagnostics
 | 
						|
 | 
						|
#define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
 | 
						|
#define CURRENT_FROM_MACRO() SL::current()
 | 
						|
#define FORWARD(...) __VA_ARGS__
 | 
						|
 | 
						|
template <unsigned>
 | 
						|
struct Printer;
 | 
						|
 | 
						|
namespace std {
 | 
						|
namespace experimental {
 | 
						|
struct source_location {
 | 
						|
private:
 | 
						|
  unsigned int __m_line = 0;
 | 
						|
  unsigned int __m_col = 0;
 | 
						|
  const char *__m_file = nullptr;
 | 
						|
  const char *__m_func = nullptr;
 | 
						|
public:
 | 
						|
  static constexpr source_location current(
 | 
						|
      const char *__file = __builtin_FILE(),
 | 
						|
      const char *__func = __builtin_FUNCTION(),
 | 
						|
      unsigned int __line = __builtin_LINE(),
 | 
						|
      unsigned int __col = __builtin_COLUMN()) noexcept {
 | 
						|
    source_location __loc;
 | 
						|
    __loc.__m_line = __line;
 | 
						|
    __loc.__m_col = __col;
 | 
						|
    __loc.__m_file = __file;
 | 
						|
    __loc.__m_func = __func;
 | 
						|
    return __loc;
 | 
						|
  }
 | 
						|
  constexpr source_location() = default;
 | 
						|
  constexpr source_location(source_location const &) = default;
 | 
						|
  constexpr unsigned int line() const noexcept { return __m_line; }
 | 
						|
  constexpr unsigned int column() const noexcept { return __m_col; }
 | 
						|
  constexpr const char *file() const noexcept { return __m_file; }
 | 
						|
  constexpr const char *function() const noexcept { return __m_func; }
 | 
						|
};
 | 
						|
} // namespace experimental
 | 
						|
} // namespace std
 | 
						|
 | 
						|
using SL = std::experimental::source_location;
 | 
						|
 | 
						|
#include "Inputs/source-location-file.h"
 | 
						|
namespace SLF = source_location_file;
 | 
						|
 | 
						|
constexpr bool is_equal(const char *LHS, const char *RHS) {
 | 
						|
  while (*LHS != 0 && *RHS != 0) {
 | 
						|
    if (*LHS != *RHS)
 | 
						|
      return false;
 | 
						|
    ++LHS;
 | 
						|
    ++RHS;
 | 
						|
  }
 | 
						|
  return *LHS == 0 && *RHS == 0;
 | 
						|
}
 | 
						|
 | 
						|
template <class T>
 | 
						|
constexpr T identity(T t) {
 | 
						|
  return t;
 | 
						|
}
 | 
						|
 | 
						|
template <class T, class U>
 | 
						|
struct Pair {
 | 
						|
  T first;
 | 
						|
  U second;
 | 
						|
};
 | 
						|
 | 
						|
template <class T, class U>
 | 
						|
constexpr bool is_same = false;
 | 
						|
template <class T>
 | 
						|
constexpr bool is_same<T, T> = true;
 | 
						|
 | 
						|
// test types
 | 
						|
static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
 | 
						|
static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);
 | 
						|
static_assert(is_same<decltype(__builtin_FILE()), const char *>);
 | 
						|
static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
 | 
						|
 | 
						|
// test noexcept
 | 
						|
static_assert(noexcept(__builtin_LINE()));
 | 
						|
static_assert(noexcept(__builtin_COLUMN()));
 | 
						|
static_assert(noexcept(__builtin_FILE()));
 | 
						|
static_assert(noexcept(__builtin_FUNCTION()));
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//                            __builtin_LINE()
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
namespace test_line {
 | 
						|
static_assert(SL::current().line() == __LINE__);
 | 
						|
static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());
 | 
						|
 | 
						|
static constexpr SL GlobalS = SL::current();
 | 
						|
 | 
						|
static_assert(GlobalS.line() == __LINE__ - 2);
 | 
						|
 | 
						|
// clang-format off
 | 
						|
constexpr bool test_line_fn() {
 | 
						|
  constexpr SL S = SL::current();
 | 
						|
  static_assert(S.line() == (__LINE__ - 1), "");
 | 
						|
  // The start of the call expression to `current()` begins at the token `SL`
 | 
						|
  constexpr int ExpectLine = __LINE__ + 3;
 | 
						|
  constexpr SL S2
 | 
						|
  =
 | 
						|
  SL // Call expression starts here
 | 
						|
  ::
 | 
						|
  current
 | 
						|
  (
 | 
						|
 | 
						|
  )
 | 
						|
  ;
 | 
						|
  static_assert(S2.line() == ExpectLine, "");
 | 
						|
 | 
						|
  static_assert(
 | 
						|
          FORWARD(
 | 
						|
             __builtin_LINE
 | 
						|
            (
 | 
						|
            )
 | 
						|
          )
 | 
						|
    == __LINE__ - 1, "");
 | 
						|
  static_assert(\
 | 
						|
\
 | 
						|
  __builtin_LINE()\
 | 
						|
\
 | 
						|
  == __LINE__ - 2, "");
 | 
						|
  static_assert(\
 | 
						|
          _\
 | 
						|
_builtin_LINE()
 | 
						|
          == __LINE__ - 2, "");
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
// clang-format on
 | 
						|
static_assert(test_line_fn());
 | 
						|
 | 
						|
static_assert(__builtin_LINE() == __LINE__, "");
 | 
						|
 | 
						|
constexpr int baz() { return 101; }
 | 
						|
 | 
						|
constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {
 | 
						|
  return x;
 | 
						|
}
 | 
						|
void bar() {
 | 
						|
  static_assert(test_line_fn_simple() == __LINE__, "");
 | 
						|
  static_assert(test_line_fn_simple() == __LINE__, "");
 | 
						|
}
 | 
						|
 | 
						|
struct CallExpr {
 | 
						|
  constexpr int operator()(int x = __builtin_LINE()) const { return x; }
 | 
						|
};
 | 
						|
constexpr CallExpr get_call() { return CallExpr{}; }
 | 
						|
static_assert(get_call()() == __LINE__, "");
 | 
						|
 | 
						|
template <class T>
 | 
						|
constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {
 | 
						|
  return Expect == L;
 | 
						|
}
 | 
						|
static_assert(test_line_fn_template(__LINE__));
 | 
						|
 | 
						|
struct InMemInit {
 | 
						|
  constexpr bool check(int expect) const {
 | 
						|
    return info.line() == expect;
 | 
						|
  }
 | 
						|
  SL info = SL::current();
 | 
						|
  InMemInit() = default;
 | 
						|
  constexpr InMemInit(int) {}
 | 
						|
};
 | 
						|
static_assert(InMemInit{}.check(__LINE__ - 3), "");
 | 
						|
static_assert(InMemInit{42}.check(__LINE__ - 3), "");
 | 
						|
 | 
						|
template <class T, class U = SL>
 | 
						|
struct InMemInitTemplate {
 | 
						|
  constexpr bool check(int expect) const {
 | 
						|
    return info.line() == expect;
 | 
						|
  }
 | 
						|
  U info = U::current();
 | 
						|
  InMemInitTemplate() = default;
 | 
						|
  constexpr InMemInitTemplate(T) {}
 | 
						|
  constexpr InMemInitTemplate(T, T) : info(U::current()) {}
 | 
						|
  template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current())
 | 
						|
      : info(info) {}
 | 
						|
};
 | 
						|
void test_mem_init_template() {
 | 
						|
  constexpr int line_offset = 8;
 | 
						|
  static_assert(InMemInitTemplate<int>{}.check(__LINE__ - line_offset), "");
 | 
						|
  static_assert(InMemInitTemplate<unsigned>{42}.check(__LINE__ - line_offset), "");
 | 
						|
  static_assert(InMemInitTemplate<unsigned>{42, 42}.check(__LINE__ - line_offset), "");
 | 
						|
  static_assert(InMemInitTemplate<unsigned>{42, 42, 42}.check(__LINE__), "");
 | 
						|
}
 | 
						|
 | 
						|
struct AggInit {
 | 
						|
  int x;
 | 
						|
  int y = __builtin_LINE();
 | 
						|
  constexpr bool check(int expect) const {
 | 
						|
    return y == expect;
 | 
						|
  }
 | 
						|
};
 | 
						|
constexpr AggInit AI{42};
 | 
						|
static_assert(AI.check(__LINE__ - 1), "");
 | 
						|
 | 
						|
template <class T, class U = SL>
 | 
						|
struct AggInitTemplate {
 | 
						|
  constexpr bool check(int expect) const {
 | 
						|
    return expect == info.line();
 | 
						|
  }
 | 
						|
  T x;
 | 
						|
  U info = U::current();
 | 
						|
};
 | 
						|
 | 
						|
template <class T, class U = SL>
 | 
						|
constexpr U test_fn_template(T, U u = U::current()) {
 | 
						|
  return u;
 | 
						|
}
 | 
						|
void fn_template_tests() {
 | 
						|
  static_assert(test_fn_template(42).line() == __LINE__, "");
 | 
						|
}
 | 
						|
 | 
						|
struct TestMethodTemplate {
 | 
						|
  template <class T, class U = SL, class U2 = SL>
 | 
						|
  constexpr U get(T, U u = U::current(), U2 u2 = identity(U2::current())) const {
 | 
						|
    assert(u.line() == u2.line());
 | 
						|
    return u;
 | 
						|
  }
 | 
						|
};
 | 
						|
void method_template_tests() {
 | 
						|
  static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");
 | 
						|
}
 | 
						|
 | 
						|
struct InStaticInit {
 | 
						|
  static constexpr int LINE = __LINE__;
 | 
						|
  static constexpr const int x1 = __builtin_LINE();
 | 
						|
  static constexpr const int x2 = identity(__builtin_LINE());
 | 
						|
  static const int x3;
 | 
						|
  const int x4 = __builtin_LINE();
 | 
						|
  int x5 = __builtin_LINE();
 | 
						|
};
 | 
						|
const int InStaticInit::x3 = __builtin_LINE();
 | 
						|
static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");
 | 
						|
static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");
 | 
						|
 | 
						|
template <class T, int N = __builtin_LINE(), int Expect = -1>
 | 
						|
constexpr void check_fn_template_param(T) {
 | 
						|
  constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;
 | 
						|
  static_assert(N == RealExpect);
 | 
						|
}
 | 
						|
template void check_fn_template_param(int);
 | 
						|
template void check_fn_template_param<long, 42, 42>(long);
 | 
						|
 | 
						|
#line 100
 | 
						|
struct AggBase {
 | 
						|
#line 200
 | 
						|
  int x = __builtin_LINE();
 | 
						|
  int y = __builtin_LINE();
 | 
						|
  int z = __builtin_LINE();
 | 
						|
};
 | 
						|
#line 300
 | 
						|
struct AggDer : AggBase {
 | 
						|
};
 | 
						|
#line 400
 | 
						|
static_assert(AggDer{}.x == 400, "");
 | 
						|
 | 
						|
struct ClassBase {
 | 
						|
#line 400
 | 
						|
  int x = __builtin_LINE();
 | 
						|
  int y = 0;
 | 
						|
  int z = 0;
 | 
						|
#line 500
 | 
						|
  ClassBase() = default;
 | 
						|
  constexpr ClassBase(int yy, int zz = __builtin_LINE())
 | 
						|
      : y(yy), z(zz) {}
 | 
						|
};
 | 
						|
struct ClassDer : ClassBase {
 | 
						|
#line 600
 | 
						|
  ClassDer() = default;
 | 
						|
  constexpr ClassDer(int yy) : ClassBase(yy) {}
 | 
						|
  constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}
 | 
						|
};
 | 
						|
#line 700
 | 
						|
static_assert(ClassDer{}.x == 500, "");
 | 
						|
static_assert(ClassDer{42}.x == 501, "");
 | 
						|
static_assert(ClassDer{42}.z == 601, "");
 | 
						|
static_assert(ClassDer{42, 42}.x == 501, "");
 | 
						|
 | 
						|
struct ClassAggDer : AggBase {
 | 
						|
#line 800
 | 
						|
  ClassAggDer() = default;
 | 
						|
  constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}
 | 
						|
};
 | 
						|
static_assert(ClassAggDer{}.x == 100, "");
 | 
						|
 | 
						|
} // namespace test_line
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//                            __builtin_FILE()
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
namespace test_file {
 | 
						|
constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {
 | 
						|
  return __f;
 | 
						|
}
 | 
						|
void test_function() {
 | 
						|
#line 900
 | 
						|
  static_assert(is_equal(test_file_simple(), __FILE__));
 | 
						|
  static_assert(is_equal(SLF::test_function().file(), __FILE__), "");
 | 
						|
  static_assert(is_equal(SLF::test_function_template(42).file(), __FILE__), "");
 | 
						|
 | 
						|
  static_assert(is_equal(SLF::test_function_indirect().file(), SLF::global_info.file()), "");
 | 
						|
  static_assert(is_equal(SLF::test_function_template_indirect(42).file(), SLF::global_info.file()), "");
 | 
						|
 | 
						|
  static_assert(test_file_simple() != nullptr);
 | 
						|
  static_assert(!is_equal(test_file_simple(), "source_location.cpp"));
 | 
						|
}
 | 
						|
 | 
						|
void test_class() {
 | 
						|
#line 315
 | 
						|
  using SLF::TestClass;
 | 
						|
  constexpr TestClass Default;
 | 
						|
  constexpr TestClass InParam{42};
 | 
						|
  constexpr TestClass Template{42, 42};
 | 
						|
  constexpr auto *F = Default.info.file();
 | 
						|
  constexpr auto Char = F[0];
 | 
						|
  static_assert(is_equal(Default.info.file(), SLF::FILE), "");
 | 
						|
  static_assert(is_equal(InParam.info.file(), SLF::FILE), "");
 | 
						|
  static_assert(is_equal(InParam.ctor_info.file(), __FILE__), "");
 | 
						|
}
 | 
						|
 | 
						|
void test_aggr_class() {
 | 
						|
  using Agg = SLF::AggrClass<>;
 | 
						|
  constexpr Agg Default{};
 | 
						|
  constexpr Agg InitOne{42};
 | 
						|
  static_assert(is_equal(Default.init_info.file(), __FILE__), "");
 | 
						|
  static_assert(is_equal(InitOne.init_info.file(), __FILE__), "");
 | 
						|
}
 | 
						|
 | 
						|
} // namespace test_file
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//                            __builtin_FUNCTION()
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
namespace test_func {
 | 
						|
 | 
						|
constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {
 | 
						|
  return __f;
 | 
						|
}
 | 
						|
constexpr const char *get_function() {
 | 
						|
  return __func__;
 | 
						|
}
 | 
						|
constexpr bool test_function() {
 | 
						|
  return is_equal(__func__, test_func_simple()) &&
 | 
						|
         !is_equal(get_function(), test_func_simple());
 | 
						|
}
 | 
						|
static_assert(test_function());
 | 
						|
 | 
						|
template <class T, class U = SL>
 | 
						|
constexpr Pair<U, U> test_func_template(T, U u = U::current()) {
 | 
						|
  static_assert(is_equal(__func__, U::current().function()));
 | 
						|
  return {u, U::current()};
 | 
						|
}
 | 
						|
template <class T>
 | 
						|
void func_template_tests() {
 | 
						|
  constexpr auto P = test_func_template(42);
 | 
						|
  //static_assert(is_equal(P.first.function(), __func__), "");
 | 
						|
  //static_assert(!is_equal(P.second.function(), __func__), "");
 | 
						|
}
 | 
						|
template void func_template_tests<int>();
 | 
						|
 | 
						|
template <class = int, class T = SL>
 | 
						|
struct TestCtor {
 | 
						|
  T info = T::current();
 | 
						|
  T ctor_info;
 | 
						|
  TestCtor() = default;
 | 
						|
  template <class U = SL>
 | 
						|
  constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {}
 | 
						|
};
 | 
						|
void ctor_tests() {
 | 
						|
  constexpr TestCtor<> Default;
 | 
						|
  constexpr TestCtor<> Template{42};
 | 
						|
  static_assert(!is_equal(Default.info.function(), __func__));
 | 
						|
  static_assert(is_equal(Default.info.function(), "TestCtor"));
 | 
						|
  static_assert(is_equal(Template.info.function(), "TestCtor"));
 | 
						|
  static_assert(is_equal(Template.ctor_info.function(), __func__));
 | 
						|
}
 | 
						|
 | 
						|
constexpr SL global_sl = SL::current();
 | 
						|
static_assert(is_equal(global_sl.function(), ""));
 | 
						|
 | 
						|
} // namespace test_func
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//                            __builtin_COLUMN()
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
namespace test_column {
 | 
						|
 | 
						|
// clang-format off
 | 
						|
constexpr bool test_column_fn() {
 | 
						|
  constexpr SL S = SL::current();
 | 
						|
  static_assert(S.line() == (__LINE__ - 1), "");
 | 
						|
  constexpr int Indent = 4;
 | 
						|
  {
 | 
						|
    // The start of the call expression to `current()` begins at the token `SL`
 | 
						|
    constexpr int ExpectCol = Indent + 3;
 | 
						|
    constexpr SL S2
 | 
						|
     =
 | 
						|
      SL // Call expression starts here
 | 
						|
        ::
 | 
						|
          current
 | 
						|
                 (
 | 
						|
 | 
						|
                  )
 | 
						|
                   ;
 | 
						|
    static_assert(S2.column() == ExpectCol, "");
 | 
						|
  }
 | 
						|
  {
 | 
						|
    constexpr int ExpectCol = 2;
 | 
						|
    constexpr int C =
 | 
						|
 __builtin_COLUMN // Expect call expression to start here
 | 
						|
      ();
 | 
						|
    static_assert(C == ExpectCol);
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
#line 420
 | 
						|
static_assert(test_column_fn());
 | 
						|
 | 
						|
// Test that the column matches the start of the call expression 'SL::current()'
 | 
						|
static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));
 | 
						|
struct TestClass {
 | 
						|
  int x = __builtin_COLUMN();
 | 
						|
   TestClass() = default; /* indented to 3 spaces for testing */
 | 
						|
  constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}
 | 
						|
};
 | 
						|
struct TestAggClass {
 | 
						|
  int x = __builtin_COLUMN();
 | 
						|
};
 | 
						|
constexpr bool test_class() {
 | 
						|
 | 
						|
  auto check = [](int V, const char* S, int indent = 4) {
 | 
						|
    assert(V == (__builtin_strlen(S) + indent));
 | 
						|
  };
 | 
						|
  {
 | 
						|
    TestClass t{};
 | 
						|
    check(t.x, "   T", 0); // Start of default constructor decl.
 | 
						|
  }
 | 
						|
  {
 | 
						|
    TestClass t1
 | 
						|
            {42};
 | 
						|
    check(t1.x, "TestClass t"); // Start of variable being constructed.
 | 
						|
  }
 | 
						|
  {
 | 
						|
    TestAggClass t  { };
 | 
						|
    check(t.x, "TestAggClass t  { }");
 | 
						|
  }
 | 
						|
  {
 | 
						|
    TestAggClass t = { };
 | 
						|
    check(t.x, "TestAggClass t = { }");
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
static_assert(test_class());
 | 
						|
// clang-format on
 | 
						|
} // namespace test_column
 | 
						|
 | 
						|
// Test [reflection.src_loc.creation]p2
 | 
						|
//  >  The value should be affected by #line (C++14 16.4) in the same manner as
 | 
						|
//  >  for __LINE__ and __FILE__.
 | 
						|
namespace test_pragma_line {
 | 
						|
constexpr int StartLine = 42;
 | 
						|
#line 42
 | 
						|
static_assert(__builtin_LINE() == StartLine);
 | 
						|
static_assert(__builtin_LINE() == StartLine + 1);
 | 
						|
static_assert(SL::current().line() == StartLine + 2);
 | 
						|
#line 44 "test_file.c"
 | 
						|
static_assert(is_equal("test_file.c", __FILE__));
 | 
						|
static_assert(is_equal("test_file.c", __builtin_FILE()));
 | 
						|
static_assert(is_equal("test_file.c", SL::current().file()));
 | 
						|
static_assert(is_equal("test_file.c", SLF::test_function().file()));
 | 
						|
static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
 | 
						|
} // end namespace test_pragma_line
 | 
						|
 | 
						|
namespace test_out_of_line_init {
 | 
						|
#line 4000 "test_out_of_line_init.cpp"
 | 
						|
constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
 | 
						|
constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
 | 
						|
constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
 | 
						|
#line 4100 "A.cpp"
 | 
						|
struct A {
 | 
						|
  int n = __builtin_LINE();
 | 
						|
  int n2 = get_line();
 | 
						|
  const char *f = __builtin_FILE();
 | 
						|
  const char *f2 = get_file();
 | 
						|
  const char *func = __builtin_FUNCTION();
 | 
						|
  const char *func2 = get_func();
 | 
						|
  SL info = SL::current();
 | 
						|
};
 | 
						|
#line 4200 "B.cpp"
 | 
						|
struct B {
 | 
						|
  A a = {};
 | 
						|
};
 | 
						|
#line 4300 "test_passed.cpp"
 | 
						|
constexpr B b = {};
 | 
						|
static_assert(b.a.n == 4300, "");
 | 
						|
static_assert(b.a.n2 == 4300, "");
 | 
						|
static_assert(b.a.info.line() == 4300, "");
 | 
						|
static_assert(is_equal(b.a.f, "test_passed.cpp"));
 | 
						|
static_assert(is_equal(b.a.f2, "test_passed.cpp"));
 | 
						|
static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));
 | 
						|
static_assert(is_equal(b.a.func, ""));
 | 
						|
static_assert(is_equal(b.a.func2, ""));
 | 
						|
static_assert(is_equal(b.a.info.function(), ""));
 | 
						|
 | 
						|
constexpr bool test_in_func() {
 | 
						|
#line 4400 "test_func_passed.cpp"
 | 
						|
  constexpr B b = {};
 | 
						|
  static_assert(b.a.n == 4400, "");
 | 
						|
  static_assert(b.a.n2 == 4400, "");
 | 
						|
  static_assert(b.a.info.line() == 4400, "");
 | 
						|
  static_assert(is_equal(b.a.f, "test_func_passed.cpp"));
 | 
						|
  static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));
 | 
						|
  static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));
 | 
						|
  static_assert(is_equal(b.a.func, "test_in_func"));
 | 
						|
  static_assert(is_equal(b.a.func2, "test_in_func"));
 | 
						|
  static_assert(is_equal(b.a.info.function(), "test_in_func"));
 | 
						|
  return true;
 | 
						|
}
 | 
						|
static_assert(test_in_func());
 | 
						|
 | 
						|
} // end namespace test_out_of_line_init
 | 
						|
 | 
						|
namespace test_global_scope {
 | 
						|
#line 5000 "test_global_scope.cpp"
 | 
						|
constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
 | 
						|
constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
 | 
						|
constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
 | 
						|
#line 5100
 | 
						|
struct InInit {
 | 
						|
  unsigned l = get_line();
 | 
						|
  const char *f = get_file();
 | 
						|
  const char *func = get_func();
 | 
						|
 | 
						|
#line 5200 "in_init.cpp"
 | 
						|
  constexpr InInit() {}
 | 
						|
};
 | 
						|
#line 5300
 | 
						|
constexpr InInit II;
 | 
						|
 | 
						|
static_assert(II.l == 5200, "");
 | 
						|
static_assert(is_equal(II.f, "in_init.cpp"));
 | 
						|
static_assert(is_equal(II.func, "InInit"));
 | 
						|
 | 
						|
#line 5400
 | 
						|
struct AggInit {
 | 
						|
  unsigned l = get_line();
 | 
						|
  const char *f = get_file();
 | 
						|
  const char *func = get_func();
 | 
						|
};
 | 
						|
#line 5500 "brace_init.cpp"
 | 
						|
constexpr AggInit AI = {};
 | 
						|
static_assert(AI.l == 5500);
 | 
						|
static_assert(is_equal(AI.f, "brace_init.cpp"));
 | 
						|
static_assert(is_equal(AI.func, ""));
 | 
						|
 | 
						|
} // namespace test_global_scope
 | 
						|
 | 
						|
namespace TestFuncInInit {
 | 
						|
#line 6000 "InitClass.cpp"
 | 
						|
struct Init {
 | 
						|
  SL info;
 | 
						|
#line 6100 "InitCtor.cpp"
 | 
						|
  constexpr Init(SL info = SL::current()) : info(info) {}
 | 
						|
};
 | 
						|
#line 6200 "InitGlobal.cpp"
 | 
						|
constexpr Init I;
 | 
						|
static_assert(I.info.line() == 6200);
 | 
						|
static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));
 | 
						|
 | 
						|
} // namespace TestFuncInInit
 | 
						|
 | 
						|
namespace TestConstexprContext {
 | 
						|
#line 7000 "TestConstexprContext.cpp"
 | 
						|
  constexpr const char* foo() { return __builtin_FILE(); }
 | 
						|
#line 7100 "Bar.cpp"
 | 
						|
  constexpr const char* bar(const char* x = foo()) { return x; }
 | 
						|
  constexpr bool test() {
 | 
						|
    static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  static_assert(test());
 | 
						|
}
 |