EricWF updated this revision to Diff 167664.
EricWF added a comment.

Build, cache and substitute the `SourceLocExpr` for a `StringLiteral` during 
constant evaluation. This is instead of the changes to `LValueBase`which stored 
the string value and type in addition to the original `SourceLocExpr`.

Currently only `SourceLocExpr` uses the `StringLiteral` cache in `ASTContext`. 
`PredefinedExpr` could be made to use it at the expense of losing the 
`SourceLocation` information the `StringLiteral` caches.

@rsmith How does this look now?

I'll follow up with a separate `__builtin_SOURCE_LOCATION()` patch which 
returns a single relocatable object containing the file, func, line and column. 
@rsmith Any pointers on how to implement that?


https://reviews.llvm.org/D37035

Files:
  docs/LanguageExtensions.rst
  include/clang/AST/ASTContext.h
  include/clang/AST/CurrentSourceLocExprScope.h
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Stmt.h
  include/clang/Basic/StmtNodes.td
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseExpr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CodeGenCXX/builtin-source-location.cpp
  test/CodeGenCXX/builtin_FUNCTION.cpp
  test/CodeGenCXX/builtin_LINE.cpp
  test/CodeGenCXX/debug-info-line.cpp
  test/Parser/builtin_source_location.c
  test/Sema/source_location.c
  test/SemaCXX/Inputs/source-location-file.h
  test/SemaCXX/source_location.cpp

Index: test/SemaCXX/source_location.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/source_location.cpp
@@ -0,0 +1,590 @@
+// 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());
+}
Index: test/SemaCXX/Inputs/source-location-file.h
===================================================================
--- /dev/null
+++ test/SemaCXX/Inputs/source-location-file.h
@@ -0,0 +1,44 @@
+
+// NOTE: source_location.cpp must include this file after defining
+// std::source_location.
+namespace source_location_file {
+
+constexpr const char *FILE = __FILE__;
+
+constexpr SL global_info = SL::current();
+
+constexpr SL test_function(SL v = SL::current()) {
+  return v;
+}
+
+constexpr SL test_function_indirect() {
+  return test_function();
+}
+
+template <class T, class U = SL>
+constexpr U test_function_template(T, U u = U::current()) {
+  return u;
+}
+
+template <class T, class U = SL>
+constexpr U test_function_template_indirect(T t) {
+  return test_function_template(t);
+}
+
+struct TestClass {
+  SL info = SL::current();
+  SL ctor_info;
+  TestClass() = default;
+  constexpr TestClass(int, SL cinfo = SL::current()) : ctor_info(cinfo) {}
+  template <class T, class U = SL>
+  constexpr TestClass(int, T, U u = U::current()) : ctor_info(u) {}
+};
+
+template <class T = SL>
+struct AggrClass {
+  int x;
+  T info;
+  T init_info = T::current();
+};
+
+} // namespace source_location_file
Index: test/Sema/source_location.c
===================================================================
--- /dev/null
+++ test/Sema/source_location.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c90 -fconst-strings -DCONST_STRINGS -verify %s
+// RUN: %clang_cc1 -std=c90 -verify %s
+
+// expected-no-diagnostics
+
+#define IsEqual(L, R) (__builtin_strcmp(L, R) == 0)
+
+const char *const FILE = __builtin_FILE();
+const char *const FUNC = __builtin_FUNCTION();
+const unsigned LINE = __builtin_LINE();
+const unsigned COL = __builtin_COLUMN();
+
+#ifndef CONST_STRINGS
+char *const NCFILE = __builtin_FILE();
+char *const NCFUNC = __builtin_FUNCTION();
+#endif
+
+#ifdef CONST_STRINGS
+_Static_assert(IsEqual(__builtin_FILE(), __FILE__), "");
+_Static_assert(__builtin_LINE() == __LINE__, "");
+_Static_assert(IsEqual("", __builtin_FUNCTION()), "");
+
+#line 42 "my_file.c"
+_Static_assert(__builtin_LINE() == 42, "");
+_Static_assert(IsEqual(__builtin_FILE(), "my_file.c"), "");
+
+_Static_assert(__builtin_COLUMN() == __builtin_strlen("_Static_assert(_"), "");
+
+void foo() {
+  _Static_assert(IsEqual(__builtin_FUNCTION(), "foo"), "");
+}
+#endif // CONST_STRINGS
Index: test/Parser/builtin_source_location.c
===================================================================
--- /dev/null
+++ test/Parser/builtin_source_location.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() {
+  int line = __builtin_LINE();
+  __builtin_LINE(42); // expected-error {{expected ')'}}
+  __builtin_LINE(double); // expected-error {{expected ')'}}
+
+  int column = __builtin_COLUMN();
+  __builtin_COLUMN(42); // expected-error {{expected ')'}}
+  __builtin_COLUMN(double); // expected-error {{expected ')'}}
+
+  const char *func = __builtin_FUNCTION();
+  __builtin_FUNCTION(42); // expected-error {{expected ')'}}
+  __builtin_FUNCTION(double); // expected-error {{expected ')'}}
+
+  const char *file = __builtin_FILE();
+  __builtin_FILE(42); // expected-error {{expected ')'}}
+  __builtin_FILE(double); // expected-error {{expected ')'}}
+}
Index: test/CodeGenCXX/debug-info-line.cpp
===================================================================
--- test/CodeGenCXX/debug-info-line.cpp
+++ test/CodeGenCXX/debug-info-line.cpp
@@ -293,6 +293,13 @@
   f24_a();
 }
 
+// CHECK-LABEL: define
+void f25_a(int x = __builtin_LINE()) {}
+void f25() {
+  // CHECK: call void @_Z5f25_ai(i32 2700)
+#line 2700
+  f25_a();
+}
 // CHECK: [[DBG_F1]] = !DILocation(line: 100,
 // CHECK: [[DBG_FOO_VALUE]] = !DILocation(line: 200,
 // CHECK: [[DBG_FOO_REF]] = !DILocation(line: 202,
Index: test/CodeGenCXX/builtin_LINE.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/builtin_LINE.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -std=c++1z -fblocks %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+extern "C" int sink;
+extern "C" const volatile void* volatile ptr_sink = nullptr;
+
+struct Tag1 {};
+struct Tag2 {};
+struct Tag3 {};
+struct Tag4 {};
+
+constexpr int get_line_constexpr(int l = __builtin_LINE()) {
+  return l;
+}
+
+int get_line_nonconstexpr(int l = __builtin_LINE()) {
+  return l;
+}
+
+
+int get_line(int l = __builtin_LINE()) {
+  return l;
+}
+
+int get_line2(int l = get_line()) { return l; }
+
+
+// CHECK: @global_one = global i32 [[@LINE+1]], align 4
+int global_one = __builtin_LINE();
+// CHECK-NEXT: @global_two = global i32 [[@LINE+1]], align 4
+int global_two = get_line_constexpr();
+// CHECK: @_ZL12global_three = internal constant i32 [[@LINE+1]], align 4
+const int global_three(get_line_constexpr());
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: %call = call i32 @_Z21get_line_nonconstexpri(i32 [[@LINE+2]])
+// CHECK-NEXT: store i32 %call, i32* @global_four, align 4
+int global_four = get_line_nonconstexpr();
+
+struct InClassInit {
+  int Init = __builtin_LINE();
+  int Init2 = get_line2();
+  InClassInit();
+  constexpr InClassInit(Tag1, int l = __builtin_LINE()) : Init(l), Init2(l) {}
+  constexpr InClassInit(Tag2) : Init(__builtin_LINE()), Init2(__builtin_LINE()) {}
+  InClassInit(Tag3, int l = __builtin_LINE());
+  InClassInit(Tag4, int l = get_line2());
+
+  static void test_class();
+};
+// CHECK-LABEL: define void @_ZN11InClassInit10test_classEv()
+void InClassInit::test_class() {
+  // CHECK: call void @_ZN11InClassInitC1Ev(%struct.InClassInit* %test_one)
+  InClassInit test_one;
+  // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag1i(%struct.InClassInit* %test_two, i32 [[@LINE+1]])
+  InClassInit test_two{Tag1{}};
+  // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag2(%struct.InClassInit* %test_three)
+  InClassInit test_three{Tag2{}};
+  // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag3i(%struct.InClassInit* %test_four, i32 [[@LINE+1]])
+  InClassInit test_four(Tag3{});
+  // CHECK-NEXT: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+3]])
+  // CHECK-NEXT: %[[CALL2:.+]] = call i32 @_Z9get_line2i(i32 %[[CALL]])
+  // CHECK-NEXT: call void @_ZN11InClassInitC1E4Tag4i(%struct.InClassInit* %test_five, i32 %[[CALL2]])
+  InClassInit test_five(Tag4{});
+
+}
+// CHECK-LABEL: define void @_ZN11InClassInitC2Ev
+// CHECK: store i32 [[@LINE+4]], i32* %Init, align 4
+// CHECK: %call = call i32 @_Z8get_linei(i32 [[@LINE+3]])
+// CHECK-NEXT: %call2 = call i32 @_Z9get_line2i(i32 %call)
+// CHECK-NEXT: store i32 %call2, i32* %Init2, align 4
+InClassInit::InClassInit() = default;
+
+InClassInit::InClassInit(Tag3, int l) : Init(l) {}
+
+// CHECK-LABEL: define void @_ZN11InClassInitC2E4Tag4i(%struct.InClassInit* %this, i32 %arg)
+// CHECK:  %[[TEMP:.+]] = load i32, i32* %arg.addr, align 4
+// CHECK-NEXT: store i32 %[[TEMP]], i32* %Init, align 4
+// CHECK: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+3]])
+// CHECK-NEXT: %[[CALL2:.+]] = call i32 @_Z9get_line2i(i32 %[[CALL]])
+// CHECK-NEXT: store i32 %[[CALL2]], i32* %Init2, align 4
+InClassInit::InClassInit(Tag4, int arg) : Init(arg) {}
+
+// CHECK-LABEL: define void @_Z13get_line_testv()
+void get_line_test() {
+  // CHECK: %[[CALL:.+]] = call i32 @_Z8get_linei(i32 [[@LINE+2]])
+  // CHECK-NEXT: store i32 %[[CALL]], i32* @sink, align 4
+  sink = get_line();
+  // CHECK-NEXT:  store i32 [[@LINE+1]], i32* @sink, align 4
+  sink = __builtin_LINE();
+  ptr_sink = &global_three;
+}
+
+void foo() {
+  const int N[] = {__builtin_LINE(), get_line_constexpr()};
+}
Index: test/CodeGenCXX/builtin_FUNCTION.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/builtin_FUNCTION.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++2a -fblocks %s -triple %itanium_abi_triple -emit-llvm -o %t.ll
+// RUN: FileCheck --input-file %t.ll %s
+
+namespace test_func {
+
+constexpr const char *test_default_arg(const char *f = __builtin_FUNCTION()) {
+  return f;
+}
+// CHECK: @[[EMPTY_STR:.+]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+
+// CHECK: @_ZN9test_func6globalE = global i8* getelementptr inbounds ([1 x i8], [1 x i8]* @[[EMPTY_STR]], i32 0, i32 0), align 8
+const char *global = test_default_arg();
+
+// CHECK: @_ZN9test_func10global_twoE = global i8* getelementptr inbounds ([1 x i8], [1 x i8]* @[[EMPTY_STR]], i32 0, i32 0), align 8
+const char *global_two = __builtin_FUNCTION();
+
+const char * const global_three = test_default_arg();
+
+// CHECK: @[[STR_ONE:.+]] = private unnamed_addr constant [14 x i8] c"test_func_one\00", align 1
+// CHECK: @[[STR_TWO:.+]] = private unnamed_addr constant [14 x i8] c"test_func_two\00", align 1
+// CHECK: @[[STR_THREE:.+]] = private unnamed_addr constant [20 x i8] c"do_default_arg_test\00", align 1
+
+// CHECK: define i8* @_ZN9test_func13test_func_oneEv()
+// CHECK: ret i8* getelementptr inbounds ([14 x i8], [14 x i8]* @[[STR_ONE]], i32 0, i32 0)
+const char *test_func_one() {
+  return __builtin_FUNCTION();
+}
+
+// CHECK: define i8* @_ZN9test_func13test_func_twoEv()
+// CHECK: ret i8* getelementptr inbounds ([14 x i8], [14 x i8]* @[[STR_TWO]], i32 0, i32 0)
+const char *test_func_two() {
+  return __builtin_FUNCTION();
+}
+
+// CHECK: define void @_ZN9test_func19do_default_arg_testEv()
+// CHECK: %call = call i8* @_ZN9test_func16test_default_argEPKc(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @[[STR_THREE]], i32 0, i32 0))
+void do_default_arg_test() {
+  test_default_arg();
+}
+
+} // namespace test_func
Index: test/CodeGenCXX/builtin-source-location.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/builtin-source-location.cpp
@@ -0,0 +1,268 @@
+// RUN: %clang_cc1 -std=c++2a -fblocks %s -triple %itanium_abi_triple -emit-llvm -o %t.ll
+
+#line 8 "builtin-source-location.cpp"
+
+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:
+  constexpr void set(unsigned l, unsigned c, const char *f, const char *func) {
+    __m_line = l;
+    __m_col = c;
+    __m_file = f;
+    __m_func = func;
+  }
+  static constexpr source_location current(
+      unsigned int __line = __builtin_LINE(),
+      unsigned int __col = __builtin_COLUMN(),
+      const char *__file = __builtin_FILE(),
+      const char *__func = __builtin_FUNCTION()) noexcept {
+    source_location __loc;
+    __loc.set(__line, __col, __file, __func);
+    return __loc;
+  }
+  static source_location bad_current(
+      unsigned int __line = __builtin_LINE(),
+      unsigned int __col = __builtin_COLUMN(),
+      const char *__file = __builtin_FILE(),
+      const char *__func = __builtin_FUNCTION()) noexcept {
+    source_location __loc;
+    __loc.set(__line, __col, __file, __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; }
+};
+
+using SL = source_location;
+
+extern "C" int sink(...);
+
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-ONE
+//
+// CHECK-GLOBAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_const_init.cpp\00"
+// CHECK-GLOBAL-ONE-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+//
+// CHECK-GLOBAL-ONE: @const_init_global = global %struct.source_location { i32 1000, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+#line 1000 "test_const_init.cpp"
+SL const_init_global = SL::current();
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-TWO
+//
+// CHECK-GLOBAL-TWO-DAG: @runtime_init_global = global %struct.source_location zeroinitializer, align 8
+//
+// CHECK-GLOBAL-TWO-DAG: @[[FILE:.*]] = {{.*}}c"test_runtime_init.cpp\00"
+// CHECK-GLOBAL-TWO-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+//
+// CHECK-GLOBAL-TWO: define internal void @__cxx_global_var_init()
+// CHECK-GLOBAL-TWO-NOT: ret
+// CHECK-GLOBAL-TWO: call void @_ZN15source_location11bad_currentEjjPKcS1_(%struct.source_location* sret @runtime_init_global,
+// CHECK-GLOBAL-TWO-SAME: i32 1100, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]],
+#line 1100 "test_runtime_init.cpp"
+SL runtime_init_global = SL::bad_current();
+
+#line 2000 "test_function.cpp"
+extern "C" void test_function() {
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-LOCAL-ONE
+//
+// CHECK-LOCAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_current.cpp\00"
+// CHECK-LOCAL-ONE-DAG: @[[FUNC:.*]] = {{.*}}c"test_function\00"
+//
+// CHECK-LOCAL-ONE:  call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %local,
+// CHECK-LOCAL-ONE-SAME: i32 2100, i32 {{[0-9]+}},
+// CHECK-LOCAL-ONE-SAME: {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]],
+#line 2100 "test_current.cpp"
+  SL local = SL::current();
+}
+
+#line 3000 "TestInitClass.cpp"
+struct TestInit {
+  SL info = SL::current();
+  SL arg_info;
+
+#line 3100 "TestInitCtor.cpp"
+  TestInit(SL arg_info = SL::current()) : arg_info(arg_info) {}
+};
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-GLOBAL
+//
+// CHECK-CTOR-GLOBAL-DAG: @GlobalInitVal = global %struct.TestInit zeroinitializer, align 8
+// CHECK-CTOR-GLOBAL-DAG: @[[FILE:.*]] = {{.*}}c"GlobalInitVal.cpp\00"
+// CHECK-CTOR-GLOBAL-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+//
+// CHECK-CTOR-GLOBAL: define internal void @__cxx_global_var_init.{{[0-9]+}}()
+// CHECK-CTOR-GLOBAL-NOT: ret
+//
+// CHECK-CTOR-GLOBAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP_ONE:[^,]*]],
+// CHECK-CTOR-GLOBAL-SAME: i32 3400, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]],
+// CHECK-CTOR-GLOBAL-NEXT: call void @_ZN8TestInitC1E15source_location(%struct.TestInit* @GlobalInitVal, %struct.source_location* {{[^%]*}}%[[TMP_ONE]])
+#line 3400 "GlobalInitVal.cpp"
+TestInit GlobalInitVal;
+
+extern "C" void test_init_function() {
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-LOCAL
+//
+// CHECK-CTOR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"LocalInitVal.cpp\00"
+// CHECK-CTOR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_init_function\00"
+//
+// CHECK-CTOR-LOCAL: define void @test_init_function()
+// CHECK-CTOR-LOCAL-NOT: ret
+//
+// CHECK-CTOR-LOCAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]],
+// CHECK-CTOR-LOCAL-SAME: i32 3500, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]],
+// CHECK-CTOR-LOCAL-NEXT: call void @_ZN8TestInitC1E15source_location(%struct.TestInit* %init_local, %struct.source_location* {{[^%]*}}%[[TMP]])
+#line 3500 "LocalInitVal.cpp"
+  TestInit init_local;
+  sink(init_local);
+}
+
+#line 4000 "ConstexprClass.cpp"
+struct TestInitConstexpr {
+  SL info = SL::current();
+  SL arg_info;
+#line 4200 "ConstexprCtor.cpp"
+  constexpr TestInitConstexpr(SL arg_info = SL::current()) : arg_info(arg_info) {}
+};
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-T2
+//
+// CHECK-CONSTEXPR-T2-DAG: @[[FILE_INIT:.*]] = {{.*}}c"ConstexprCtor.cpp\00"
+// CHECK-CONSTEXPR-T2-DAG: @[[FUNC_INIT:.*]] = {{.*}}c"TestInitConstexpr\00"
+// CHECK-CONSTEXPR-T2-DAG: @[[FILE_ARG:.*]] = {{.*}}c"ConstexprGlobal.cpp\00"
+// CHECK-CONSTEXPR-T2-DAG: @[[EMPTY:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+//
+// CHECK-CONSTEXPR-T2: @ConstexprGlobal = global %struct.TestInitConstexpr {
+// CHECK-CONSTEXPR-T2-SAME: %struct.source_location { i32 4200, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_INIT]], {{[^@]*}}@[[FUNC_INIT]],
+// CHECK-CONSTEXPR-T2-SAME: {{[^%]*}}%struct.source_location { i32 4400, i32 {{[0-9]+}},  {{[^@]*}}@[[FILE_ARG]], {{[^@]*}}@[[EMPTY]]
+#line 4400 "ConstexprGlobal.cpp"
+TestInitConstexpr ConstexprGlobal;
+
+extern "C" void test_init_function_constexpr() {
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-LOCAL
+//
+// CHECK-CONSTEXPR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_init_function_constexpr\00"
+// CHECK-CONSTEXPR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"ConstexprLocal.cpp\00"
+//
+// CHECK-CONSTEXPR-LOCAL: define void @test_init_function_constexpr()
+// CHECK-CONSTEXPR-LOCAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]],
+// CHECK-CONSTEXPR-LOCAL-SAME: i32 4600, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+// CHECK-CONSTEXPR-LOCAL: call void @_ZN17TestInitConstexprC1E15source_location(%struct.TestInitConstexpr* %local_val, {{.*}}%[[TMP]])
+#line 4600 "ConstexprLocal.cpp"
+  TestInitConstexpr local_val;
+}
+
+#line 5000 "TestInitAgg.cpp"
+struct TestInitAgg {
+#line 5100 "i1.cpp"
+  SL i1;
+#line 5200 "i2.cpp"
+  SL i2 = SL::current();
+#line 5300 "TestInitAggEnd.cpp"
+};
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-DEFAULT
+//
+// CHECK-AGG-DEFAULT-DAG: @[[FILE:.*]] = {{.*}}c"TestInitAgg.cpp\00"
+// CHECK-AGG-DEFAULT-DAG: @[[FUNC:.*]] = {{.*}}c"TestInitAgg\00"
+//
+// CHECK-AGG-DEFAULT: @GlobalAggDefault = global %struct.TestInitAgg {
+// CHECK-AGG-DEFAULT-SAME: %struct.source_location zeroinitializer,
+// CHECK-AGG-DEFAULT-SAME: %struct.source_location { i32 5000, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+#line 5400 "GlobalAggDefault.cpp"
+TestInitAgg GlobalAggDefault;
+
+#line 5500 "test_agg_init_test.cpp"
+extern "C" void test_agg_init() {
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-BRACE
+//
+// CHECK-AGG-BRACE-DAG: @[[FILE:.*]] = {{.*}}c"BraceInitEnd.cpp\00"
+// CHECK-AGG-BRACE-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00"
+//
+// CHECK-AGG-BRACE: define void @test_agg_init()
+// CHECK-AGG-BRACE: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_brace_init, i32 0, i32 1
+// CHECK-AGG-BRACE-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]],
+// CHECK-AGG-BRACE-SAME: i32 5700, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+#line 5600 "BraceInitStart.cpp"
+  TestInitAgg local_brace_init{
+#line 5700 "BraceInitEnd.cpp"
+  };
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-EQUAL
+//
+// CHECK-AGG-EQUAL-DAG: @[[FILE:.*]] = {{.*}}c"EqualInitEnd.cpp\00"
+// CHECK-AGG-EQUAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00"
+//
+// CHECK-AGG-EQUAL: define void @test_agg_init()
+// CHECK-AGG-EQUAL: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_equal_init, i32 0, i32 1
+// CHECK-AGG-EQUAL-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]],
+// CHECK-AGG-EQUAL-SAME: i32 5900, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+#line 5800 "EqualInitStart.cpp"
+  TestInitAgg local_equal_init =
+      {
+#line 5900 "EqualInitEnd.cpp"
+      };
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-LIST
+//
+// CHECK-AGG-LIST-DAG: @[[FILE_DEFAULT:.*]] = {{.*}}c"InitListEnd.cpp\00"
+// CHECK-AGG-LIST-DAG: @[[FILE_ELEM:.*]] = {{.*}}c"ListElem.cpp\00"
+// CHECK-AGG-LIST-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00"
+//
+// CHECK-AGG-LIST: define void @test_agg_init()
+//
+// CHECK-AGG-LIST: %[[I1:.*]] =  getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_list_init, i32 0, i32 0
+// CHECK-AGG-LIST-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I1]],
+// CHECK-AGG-LIST-SAME: i32 6100, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_ELEM]], {{[^@]*}}@[[FUNC]]
+//
+// CHECK-AGG-LIST: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_list_init, i32 0, i32 1
+// CHECK-AGG-LIST-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]],
+// CHECK-AGG-LIST-SAME: i32 6200, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_DEFAULT]], {{[^@]*}}@[[FUNC]]
+#line 6000 "InitListStart.cpp"
+  TestInitAgg local_list_init =
+      {
+#line 6100 "ListElem.cpp"
+          {SL::current()}
+#line 6200 "InitListEnd.cpp"
+      };
+}
+
+#line 7000 "TestTemplate.cpp"
+template <class Tp, int>
+struct TestTemplate {
+  Tp info = Tp::current();
+  Tp arg_info;
+#line 7100 "TestTemplateCtor.cpp"
+  constexpr TestTemplate(Tp arg_info = Tp::current()) : arg_info(arg_info) {}
+};
+
+#line 7200 "test_template.cpp"
+template <class T, int V>
+void test_template() {
+
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=0
+// RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=1
+//
+// CHECK-TEMPL-DAG: @[[FILE:.*]] = {{.*}}c"local_templ.cpp\00"
+// CHECK-TEMPL-DAG: @[[FUNC:.*]] = {{.*}}c"test_template\00"
+//
+// CHECK-TEMPL: define weak_odr void @_Z13test_templateI15source_locationLi[[INT_ID]]EEvv()
+// CHECK-TEMPL-NEXT: entry:
+// CHECK-TEMPL-NOT: ret
+//
+// CHECK-TEMPL:  call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]],
+// CHECK-TEMPL-SAME: i32 7300, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]]
+#line 7300 "local_templ.cpp"
+  TestTemplate<T, V> local_templ;
+}
+#line 7400 "EndTestTemplate.cpp"
+template void test_template<SL, 0>();
+template void test_template<SL, 1>();
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1336,6 +1336,7 @@
     case Stmt::NoInitExprClass:
     case Stmt::SizeOfPackExprClass:
     case Stmt::StringLiteralClass:
+    case Stmt::SourceLocExprClass:
     case Stmt::ObjCStringLiteralClass:
     case Stmt::CXXPseudoDestructorExprClass:
     case Stmt::SubstNonTypeTemplateParmExprClass:
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -852,6 +852,15 @@
   Code = serialization::EXPR_VA_ARG;
 }
 
+void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
+  VisitExpr(E);
+  Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
+  Record.AddSourceLocation(E->getBeginLoc());
+  Record.AddSourceLocation(E->getEndLoc());
+  Record.push_back(E->getIdentType());
+  Code = serialization::EXPR_SOURCE_LOC;
+}
+
 void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
   VisitExpr(E);
   Record.AddSourceLocation(E->getAmpAmpLoc());
@@ -1396,13 +1405,15 @@
 void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   VisitExpr(E);
   Record.AddDeclRef(E->getParam());
+  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
   Record.AddSourceLocation(E->getUsedLocation());
   Code = serialization::EXPR_CXX_DEFAULT_ARG;
 }
 
 void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   VisitExpr(E);
   Record.AddDeclRef(E->getField());
+  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
   Record.AddSourceLocation(E->getExprLoc());
   Code = serialization::EXPR_CXX_DEFAULT_INIT;
 }
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -913,6 +913,14 @@
   E->setIsMicrosoftABI(Record.readInt());
 }
 
+void ASTStmtReader::VisitSourceLocExpr(SourceLocExpr *E) {
+  VisitExpr(E);
+  E->setParentContext(ReadDeclAs<DeclContext>());
+  E->setLocStart(ReadSourceLocation());
+  E->setLocEnd(ReadSourceLocation());
+  E->setIdentType(static_cast<SourceLocExpr::IdentType>(Record.readInt()));
+}
+
 void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
   VisitExpr(E);
   E->setAmpAmpLoc(ReadSourceLocation());
@@ -1427,12 +1435,14 @@
 void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   VisitExpr(E);
   E->Param = ReadDeclAs<ParmVarDecl>();
+  E->UsedContext = ReadDeclAs<DeclContext>();
   E->Loc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   VisitExpr(E);
   E->Field = ReadDeclAs<FieldDecl>();
+  E->UsedContext = ReadDeclAs<DeclContext>();
   E->Loc = ReadSourceLocation();
 }
 
@@ -2522,6 +2532,10 @@
       S = new (Context) VAArgExpr(Empty);
       break;
 
+    case EXPR_SOURCE_LOC:
+      S = new (Context) SourceLocExpr(Empty);
+      break;
+
     case EXPR_ADDR_LABEL:
       S = new (Context) AddrLabelExpr(Empty);
       break;
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -2678,9 +2678,9 @@
   /// By default, builds a new default-argument expression, which does not
   /// require any semantic analysis. Subclasses may override this routine to
   /// provide different behavior.
-  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
-                                            ParmVarDecl *Param) {
-    return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param);
+  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param) {
+    return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
+                                     getSema().CurContext);
   }
 
   /// Build a new C++11 default-initialization expression.
@@ -2690,7 +2690,8 @@
   /// routine to provide different behavior.
   ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
                                        FieldDecl *Field) {
-    return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field);
+    return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field,
+                                      getSema().CurContext);
   }
 
   /// Build a new C++ zero-initialization expression.
@@ -2944,6 +2945,18 @@
                                   RParenLoc, Length, PartialArgs);
   }
 
+  /// Build a new expression representing a call to a source location
+  ///  builtin.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildSourceLocExpr(SourceLocExpr::IdentType Type,
+                                  SourceLocation BuiltinLoc,
+                                  SourceLocation RPLoc,
+                                  DeclContext *ParentContext) {
+    return getSema().BuildSourceLocExpr(Type, BuiltinLoc, RPLoc, ParentContext);
+  }
+
   /// Build a new Objective-C boxed expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -9912,6 +9925,20 @@
   return getDerived().TransformCallExpr(E);
 }
 
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
+  bool NeedRebuildFunc = E->getIdentType() == SourceLocExpr::Function &&
+                         isa<FunctionDecl>(getSema().CurContext) &&
+                         getSema().CurContext != E->getParentContext();
+
+  if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
+    return E;
+
+  return getDerived().RebuildSourceLocExpr(E->getIdentType(), E->getBeginLoc(),
+                                           E->getEndLoc(),
+                                           getSema().CurContext);
+}
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
@@ -10138,8 +10165,8 @@
   if (!Param)
     return ExprError();
 
-  if (!getDerived().AlwaysRebuild() &&
-      Param == E->getParam())
+  if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
+      E->getUsedContext() == SemaRef.CurContext)
     return E;
 
   return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
@@ -10153,7 +10180,8 @@
   if (!Field)
     return ExprError();
 
-  if (!getDerived().AlwaysRebuild() && Field == E->getField())
+  if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
+      E->getUsedContext() == SemaRef.CurContext)
     return E;
 
   return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -4684,7 +4684,7 @@
                                         FunctionDecl *FD, ParmVarDecl *Param) {
   if (CheckCXXDefaultArgExpr(CallLoc, FD, Param))
     return ExprError();
-  return CXXDefaultArgExpr::Create(Context, CallLoc, Param);
+  return CXXDefaultArgExpr::Create(Context, CallLoc, Param, CurContext);
 }
 
 Sema::VariadicCallType
@@ -4943,8 +4943,7 @@
     } else {
       assert(Param && "can't use default arguments without a known callee");
 
-      ExprResult ArgExpr =
-        BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
+      ExprResult ArgExpr = BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
       if (ArgExpr.isInvalid())
         return true;
 
@@ -13667,6 +13666,20 @@
   return new (Context) GNUNullExpr(Ty, TokenLoc);
 }
 
+ExprResult Sema::ActOnSourceLocExpr(SourceLocExpr::IdentType Type,
+                                    SourceLocation BuiltinLoc,
+                                    SourceLocation RPLoc) {
+  return BuildSourceLocExpr(Type, BuiltinLoc, RPLoc, CurContext);
+}
+
+ExprResult Sema::BuildSourceLocExpr(SourceLocExpr::IdentType Type,
+                                    SourceLocation BuiltinLoc,
+                                    SourceLocation RPLoc,
+                                    DeclContext *ParentContext) {
+  return new (Context)
+      SourceLocExpr(Context, Type, BuiltinLoc, RPLoc, ParentContext);
+}
+
 bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
                                               bool Diagnose) {
   if (!getLangOpts().ObjC1)
Index: lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- lib/Sema/SemaExceptionSpec.cpp
+++ lib/Sema/SemaExceptionSpec.cpp
@@ -1287,6 +1287,7 @@
   case Expr::PredefinedExprClass:
   case Expr::SizeOfPackExprClass:
   case Expr::StringLiteralClass:
+  case Expr::SourceLocExprClass:
     // These expressions can never throw.
     return CT_Cannot;
 
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -12902,7 +12902,7 @@
 
   // If we already have the in-class initializer nothing needs to be done.
   if (Field->getInClassInitializer())
-    return CXXDefaultInitExpr::Create(Context, Loc, Field);
+    return CXXDefaultInitExpr::Create(Context, Loc, Field, CurContext);
 
   // If we might have already tried and failed to instantiate, don't try again.
   if (Field->isInvalidDecl())
@@ -12943,7 +12943,7 @@
       Field->setInvalidDecl();
       return ExprError();
     }
-    return CXXDefaultInitExpr::Create(Context, Loc, Field);
+    return CXXDefaultInitExpr::Create(Context, Loc, Field, CurContext);
   }
 
   // DR1351:
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -638,6 +638,10 @@
 /// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
 /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
 ///                                     assign-expr ')'
+/// [GNU]   '__builtin_FILE' '(' ')'
+/// [GNU]   '__builtin_FUNCTION' '(' ')'
+/// [GNU]   '__builtin_LINE' '(' ')'
+/// [CLANG] '__builtin_COLUMN' '(' ')'
 /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
 /// [GNU]   '__null'
 /// [OBJC]  '[' objc-message-expr ']'
@@ -1102,6 +1106,10 @@
   case tok::kw___builtin_choose_expr:
   case tok::kw___builtin_astype: // primary-expression: [OCL] as_type()
   case tok::kw___builtin_convertvector:
+  case tok::kw___builtin_COLUMN:
+  case tok::kw___builtin_FILE:
+  case tok::kw___builtin_FUNCTION:
+  case tok::kw___builtin_LINE:
     return ParseBuiltinPrimaryExpression();
   case tok::kw___null:
     return Actions.ActOnGNUNullExpr(ConsumeToken());
@@ -2058,6 +2066,10 @@
 /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
 ///                                     assign-expr ')'
 /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+/// [GNU]   '__builtin_FILE' '(' ')'
+/// [GNU]   '__builtin_FUNCTION' '(' ')'
+/// [GNU]   '__builtin_LINE' '(' ')'
+/// [CLANG] '__builtin_COLUMN' '(' ')'
 /// [OCL]   '__builtin_astype' '(' assignment-expression ',' type-name ')'
 ///
 /// [GNU] offsetof-member-designator:
@@ -2277,6 +2289,33 @@
                                          ConsumeParen());
     break;
   }
+  case tok::kw___builtin_COLUMN:
+  case tok::kw___builtin_FILE:
+  case tok::kw___builtin_FUNCTION:
+  case tok::kw___builtin_LINE: {
+    // Attempt to consume the r-paren.
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected) << tok::r_paren;
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return ExprError();
+    }
+    SourceLocExpr::IdentType Type = [&] {
+      switch (T) {
+      case tok::kw___builtin_FILE:
+        return SourceLocExpr::File;
+      case tok::kw___builtin_FUNCTION:
+        return SourceLocExpr::Function;
+      case tok::kw___builtin_LINE:
+        return SourceLocExpr::Line;
+      case tok::kw___builtin_COLUMN:
+        return SourceLocExpr::Column;
+      default:
+        llvm_unreachable("invalid keyword");
+      }
+    }();
+    Res = Actions.ActOnSourceLocExpr(Type, StartLoc, ConsumeParen());
+    break;
+  }
   }
 
   if (Res.isInvalid())
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -23,6 +23,7 @@
 #include "EHScopeStack.h"
 #include "VarBypassDetector.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/CurrentSourceLocExprScope.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
@@ -1392,6 +1393,12 @@
   SourceLocation LastStopPoint;
 
 public:
+  /// Source location information about the default argument or member
+  /// initializer expression we're evaluating, if any.
+  CurrentSourceLocExprScope CurSourceLocExprScope;
+  using SourceLocExprScopeGuard =
+      CurrentSourceLocExprScope::SourceLocExprScopeGuard;
+
   /// A scope within which we are constructing the fields of an object which
   /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use
   /// if we need to evaluate a CXXDefaultInitExpr within the evaluation.
@@ -1414,9 +1421,10 @@
   /// is overridden to be the object under construction.
   class CXXDefaultInitExprScope  {
   public:
-    CXXDefaultInitExprScope(CodeGenFunction &CGF)
+    CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E)
         : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue),
-        OldCXXThisAlignment(CGF.CXXThisAlignment) {
+          OldCXXThisAlignment(CGF.CXXThisAlignment),
+          SourceLocScope(E, CGF.CurSourceLocExprScope) {
       CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer();
       CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment();
     }
@@ -1429,6 +1437,12 @@
     CodeGenFunction &CGF;
     llvm::Value *OldCXXThisValue;
     CharUnits OldCXXThisAlignment;
+    SourceLocExprScopeGuard SourceLocScope;
+  };
+
+  struct CXXDefaultArgExprScope : SourceLocExprScopeGuard {
+    CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E)
+        : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {}
   };
 
   /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the
@@ -3490,6 +3504,9 @@
   Address EmitArrayToPointerDecay(const Expr *Array,
                                   LValueBaseInfo *BaseInfo = nullptr,
                                   TBAAAccessInfo *TBAAInfo = nullptr);
+  Address EmitArrayToPointerDecay(const Expr *E, QualType Ty, LValue LV,
+                                  LValueBaseInfo *BaseInfo = nullptr,
+                                  TBAAAccessInfo *TBAAInfo = nullptr);
 
   class ConstantEmission {
     llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -599,12 +599,30 @@
   Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
     return EmitLoadOfLValue(E);
   }
+  Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
+    auto &Ctx = CGF.getContext();
+    APValue Evaluated =
+        SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr());
+
+    if (SLE->isIntType())
+      return Builder.getInt(Evaluated.getInt());
+
+    // If we're not building an int, then we're building a string literal.
+    const APValue::LValueBase &Base = Evaluated.getLValueBase();
+    const StringLiteral *Str = cast<StringLiteral>(Base.get<const Expr *>());
+    QualType StrType = Str->getType();
+    LValue LV =
+        CGF.MakeAddrLValue(CGF.CGM.GetAddrOfConstantCString(Str->getBytes()),
+                           StrType, AlignmentSource::Decl);
+    return CGF.EmitArrayToPointerDecay(SLE, StrType, LV).getPointer();
+  }
 
   Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
     return Visit(DAE->getExpr());
   }
   Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
-    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
+    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
     return Visit(DIE->getExpr());
   }
   Value *VisitCXXThisExpr(CXXThisExpr *TE) {
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -876,13 +876,10 @@
     llvm_unreachable("Invalid CastKind");
   }
 
-  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE, QualType T) {
-    return Visit(DAE->getExpr(), T);
-  }
-
   llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE, QualType T) {
     // No need for a DefaultInitExprScope: we don't handle 'this' in a
     // constant expression.
+    // No need for a CurrentSourceLocExprScope either.
     return Visit(DIE->getExpr(), T);
   }
 
@@ -1021,7 +1018,6 @@
                                                         Types, true);
         return llvm::ConstantStruct::get(SType, Elts);
       }
-
       return llvm::ConstantArray::get(AType, Elts);
     }
 
@@ -1605,6 +1601,7 @@
   ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
   ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *E);
   ConstantLValue VisitPredefinedExpr(const PredefinedExpr *E);
+  ConstantLValue VisitSourceLocExpr(const SourceLocExpr *E);
   ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *E);
   ConstantLValue VisitCallExpr(const CallExpr *E);
   ConstantLValue VisitBlockExpr(const BlockExpr *E);
@@ -1754,6 +1751,18 @@
   return Visit(base.get<const Expr*>());
 }
 
+ConstantLValue
+ConstantLValueEmitter::VisitSourceLocExpr(const SourceLocExpr *E) {
+  const APValue::LValueBase &Base = Value.getLValueBase();
+  assert(isa<StringLiteral>(Base.get<const Expr *>()) &&
+         "Expected string literal result");
+  const StringLiteral *Str = cast<StringLiteral>(Base.get<const Expr *>());
+
+  // assert(Base.isGlobalString() &&
+  //       "source location expression does not evaluate to global string?");
+  return CGM.GetAddrOfConstantCString(Str->getBytes());
+}
+
 ConstantLValue
 ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -211,10 +211,11 @@
     return Visit(E->getSubExpr());
   }
   ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
     return Visit(DAE->getExpr());
   }
   ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
-    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
+    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
     return Visit(DIE->getExpr());
   }
   ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -162,10 +162,11 @@
   void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
   void VisitNoInitExpr(NoInitExpr *E) { } // Do nothing.
   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
+    CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
     Visit(DAE->getExpr());
   }
   void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
-    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
+    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
     Visit(DIE->getExpr());
   }
   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -1236,6 +1236,8 @@
 
   case Expr::ObjCPropertyRefExprClass:
     llvm_unreachable("cannot emit a property reference directly");
+  case Expr::SourceLocExprClass:
+    llvm_unreachable("SourceLocExpr isn't modeled as an l-value");
 
   case Expr::ObjCSelectorExprClass:
     return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
@@ -1302,11 +1304,15 @@
     return LV;
   }
 
-  case Expr::CXXDefaultArgExprClass:
-    return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
+  case Expr::CXXDefaultArgExprClass: {
+    auto *DAE = cast<CXXDefaultArgExpr>(E);
+    CXXDefaultArgExprScope Scope(*this, DAE);
+    return EmitLValue(DAE->getExpr());
+  }
   case Expr::CXXDefaultInitExprClass: {
-    CXXDefaultInitExprScope Scope(*this);
-    return EmitLValue(cast<CXXDefaultInitExpr>(E)->getExpr());
+    auto *DIE = cast<CXXDefaultInitExpr>(E);
+    CXXDefaultInitExprScope Scope(*this, DIE);
+    return EmitLValue(DIE->getExpr());
   }
   case Expr::CXXTypeidExprClass:
     return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
@@ -2655,6 +2661,7 @@
                         E->getType(), AlignmentSource::Decl);
 }
 
+
 LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   auto SL = E->getFunctionName();
   assert(SL != nullptr && "No StringLiteral name in PredefinedExpr");
@@ -3214,21 +3221,28 @@
 Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
                                                  LValueBaseInfo *BaseInfo,
                                                  TBAAAccessInfo *TBAAInfo) {
-  assert(E->getType()->isArrayType() &&
+  LValue LV = EmitLValue(E);
+  return EmitArrayToPointerDecay(E, E->getType(), LV, BaseInfo, TBAAInfo);
+}
+
+Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E, QualType Ty,
+                                                 LValue LV,
+                                                 LValueBaseInfo *BaseInfo,
+                                                 TBAAAccessInfo *TBAAInfo) {
+  assert(Ty->isArrayType() &&
          "Array to pointer decay must have array source type!");
 
   // Expressions of array type can't be bitfields or vector elements.
-  LValue LV = EmitLValue(E);
   Address Addr = LV.getAddress();
 
   // If the array type was an incomplete type, we need to make sure
   // the decay ends up being the right type.
-  llvm::Type *NewTy = ConvertType(E->getType());
+  llvm::Type *NewTy = ConvertType(Ty);
   Addr = Builder.CreateElementBitCast(Addr, NewTy);
 
   // Note that VLA pointers are always decayed, so we don't need to do
   // anything here.
-  if (!E->getType()->isVariableArrayType()) {
+  if (!Ty->isVariableArrayType()) {
     assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
            "Expected pointer to array");
     Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay");
@@ -3239,7 +3253,7 @@
   // accesses to elements of member arrays, we conservatively represent accesses
   // to the pointee object as if it had no any base lvalue specified.
   // TODO: Support TBAA for member arrays.
-  QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType();
+  QualType EltType = Ty->castAsArrayTypeUnsafe()->getElementType();
   if (BaseInfo) *BaseInfo = LV.getBaseInfo();
   if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType);
 
Index: lib/AST/StmtProfile.cpp
===================================================================
--- lib/AST/StmtProfile.cpp
+++ lib/AST/StmtProfile.cpp
@@ -1856,6 +1856,10 @@
   VisitExpr(E);
 }
 
+void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
+  VisitExpr(E);
+}
+
 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
   VisitExpr(S);
 }
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -1343,6 +1343,10 @@
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//
 
+void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
+  OS << Node->getBuiltinStr() << "()";
+}
+
 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
   if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
     OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -3557,6 +3557,7 @@
   case Expr::AsTypeExprClass:
   case Expr::PseudoObjectExprClass:
   case Expr::AtomicExprClass:
+  case Expr::SourceLocExprClass:
   case Expr::FixedPointLiteralClass:
   {
     if (!NullOut) {
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -38,6 +38,7 @@
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/CurrentSourceLocExprScope.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
@@ -51,18 +52,22 @@
 #define DEBUG_TYPE "exprconstant"
 
 using namespace clang;
-using llvm::APSInt;
 using llvm::APFloat;
+using llvm::APSInt;
 
 static bool IsGlobalLValue(APValue::LValueBase B);
 
 namespace {
   struct LValue;
   struct CallStackFrame;
   struct EvalInfo;
 
+  using SourceLocExprScopeGuard =
+      CurrentSourceLocExprScope::SourceLocExprScopeGuard;
+
   static QualType getType(APValue::LValueBase B) {
     if (!B) return QualType();
+
     if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>()) {
       // FIXME: It's unclear where we're supposed to take the type from, and
       // this actually matters for arrays of unknown bound. Eg:
@@ -112,12 +117,12 @@
   /// Get an LValue path entry, which is known to not be an array index, as a
   /// field declaration.
   static const FieldDecl *getAsField(APValue::LValuePathEntry E) {
-    return dyn_cast<FieldDecl>(getAsBaseOrMember(E).getPointer());
+    return dyn_cast_or_null<FieldDecl>(getAsBaseOrMember(E).getPointer());
   }
   /// Get an LValue path entry, which is known to not be an array index, as a
   /// base class declaration.
   static const CXXRecordDecl *getAsBaseClass(APValue::LValuePathEntry E) {
-    return dyn_cast<CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
+    return dyn_cast_or_null<CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
   }
   /// Determine whether this LValue path entry for a base class names a virtual
   /// base class.
@@ -477,6 +482,10 @@
     /// parameters' function scope indices.
     APValue *Arguments;
 
+    /// Source location information about the default argument or default
+    /// initializer expression we're evaluating, if any.
+    CurrentSourceLocExprScope CurSourceLocExprScope;
+
     // Note that we intentionally use std::map here so that references to
     // values are stable.
     typedef std::pair<const void *, unsigned> MapKeyTy;
@@ -1401,9 +1410,7 @@
       IsNullPtr = true;
     }
 
-    void setInvalid(APValue::LValueBase B, unsigned I = 0) {
-      set(B, true);
-    }
+    void setInvalid(APValue::LValueBase B, unsigned I = 0) { set(B, true); }
 
     // Check that this LValue is not based on a null pointer. If it is, produce
     // a diagnostic and mark the designator as invalid.
@@ -1713,6 +1720,7 @@
   case Expr::CXXTypeidExprClass:
   case Expr::CXXUuidofExprClass:
     return true;
+
   case Expr::CallExprClass:
     return IsStringLiteralCall(cast<CallExpr>(E));
   // For GCC compatibility, &&label has static storage duration.
@@ -2627,8 +2635,14 @@
 }
 
 /// Extract the value of a character from a string literal.
-static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
+static APSInt extractStringLiteralCharacter(EvalInfo &Info,
+                                            APValue::LValueBase const &Base,
                                             uint64_t Index) {
+  const Expr *Lit = Base.get<const Expr *>();
+
+  assert(!isa<SourceLocExpr>(Lit) &&
+         "SourceLocExpr should have already been converted to a StringLiteral");
+
   // FIXME: Support MakeStringConstant
   if (const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
     std::string Str;
@@ -2819,6 +2833,7 @@
     }
 
     if (I == N) {
+      assert(!ObjType.isNull());
       // If we are reading an object of class type, there may still be more
       // things we need to check: if there are any mutable subobjects, we
       // cannot perform this read. (This only happens when performing a trivial
@@ -2983,8 +2998,8 @@
     return true;
   }
   bool foundString(APValue &Subobj, QualType SubobjType, uint64_t Character) {
-    Result = APValue(extractStringLiteralCharacter(
-        Info, Subobj.getLValueBase().get<const Expr *>(), Character));
+    Result = APValue(
+        extractStringLiteralCharacter(Info, Subobj.getLValueBase(), Character));
     return true;
   }
 };
@@ -3345,6 +3360,10 @@
 
   // Check for special cases where there is no existing APValue to look at.
   const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
+
+  assert((!Base || !isa<SourceLocExpr>(Base)) &&
+         "Base should have already been transformed into a StringLiteral");
+
   if (Base && !LVal.getLValueCallIndex() && !Type.isVolatileQualified()) {
     if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) {
       // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
@@ -4745,15 +4764,18 @@
     { return StmtVisitorTy::Visit(E->getReplacement()); }
   bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {
     TempVersionRAII RAII(*Info.CurrentCall);
+    SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
     return StmtVisitorTy::Visit(E->getExpr());
   }
   bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
     TempVersionRAII RAII(*Info.CurrentCall);
     // The initializer may not have been parsed yet, or might be erroneous.
     if (!E->getExpr())
       return Error(E);
+    SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
     return StmtVisitorTy::Visit(E->getExpr());
   }
+
   // We cannot create any objects for which cleanups are required, so there is
   // nothing to do here; all cleanups must come from unevaluated subexpressions.
   bool VisitExprWithCleanups(const ExprWithCleanups *E)
@@ -5391,8 +5413,8 @@
 
   if (!VD->getType()->isReferenceType()) {
     if (Frame) {
-      Result.set({VD, Frame->Index,
-                  Info.CurrentCall->getCurrentTemporaryVersion(VD)});
+      Result.set(
+          {VD, Frame->Index, Info.CurrentCall->getCurrentTemporaryVersion(VD)});
       return true;
     }
     return Success(VD);
@@ -5734,7 +5756,6 @@
 
   bool visitNonBuiltinCallExpr(const CallExpr *E);
 public:
-
   PointerExprEvaluator(EvalInfo &info, LValue &Result, bool InvalidBaseOK)
       : ExprEvaluatorBaseTy(info), Result(Result),
         InvalidBaseOK(InvalidBaseOK) {}
@@ -5804,6 +5825,19 @@
     return true;
   }
 
+  bool VisitSourceLocExpr(const SourceLocExpr *E) {
+    APValue LValResult = E->EvaluateInContext(
+        Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
+    assert(E->isStringType());
+    const StringLiteral *Str =
+        cast<StringLiteral>(LValResult.getLValueBase().get<const Expr *>());
+    Result.set(LValResult.getLValueBase());
+    Result.addArray(
+        Info, E,
+        cast<ConstantArrayType>(Str->getType()->getAsArrayTypeUnsafe()));
+    return true;
+  }
+
   // FIXME: Missing: @protocol, @selector
 };
 } // end anonymous namespace
@@ -7342,7 +7376,6 @@
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
-
   bool VisitIntegerLiteral(const IntegerLiteral *E) {
     return Success(E->getValue(), E);
   }
@@ -7415,7 +7448,7 @@
 
   bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
   bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
-
+  bool VisitSourceLocExpr(const SourceLocExpr *E);
   // FIXME: Missing: array subscript of vector, member of vector
 };
 
@@ -7515,6 +7548,12 @@
   return true;
 }
 
+bool IntExprEvaluator::VisitSourceLocExpr(const SourceLocExpr *E) {
+  APValue Evaluated = E->EvaluateInContext(
+      Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
+  return Success(Evaluated.getInt(), E);
+}
+
 /// Check whether the given declaration can be directly converted to an integral
 /// rvalue. If not, no diagnostic is produced; there are other things we can
 /// try.
@@ -11030,6 +11069,7 @@
 
   case Expr::SizeOfPackExprClass:
   case Expr::GNUNullExprClass:
+  case Expr::SourceLocExprClass:
     // GCC considers the GNU __null value to be an integral constant expression.
     return NoDiag();
 
Index: lib/AST/ExprClassification.cpp
===================================================================
--- lib/AST/ExprClassification.cpp
+++ lib/AST/ExprClassification.cpp
@@ -192,6 +192,7 @@
   case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::DesignatedInitUpdateExprClass:
+  case Expr::SourceLocExprClass:
     return Cl::CL_PRValue;
 
     // Next come the complicated cases.
Index: lib/AST/ExprCXX.cpp
===================================================================
--- lib/AST/ExprCXX.cpp
+++ lib/AST/ExprCXX.cpp
@@ -750,13 +750,14 @@
 }
 
 CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc,
-                                       FieldDecl *Field, QualType T)
+                                       FieldDecl *Field, QualType T,
+                                       DeclContext *UsedContext)
     : Expr(CXXDefaultInitExprClass, T.getNonLValueExprType(C),
-           T->isLValueReferenceType() ? VK_LValue : T->isRValueReferenceType()
-                                                        ? VK_XValue
-                                                        : VK_RValue,
+           T->isLValueReferenceType()
+               ? VK_LValue
+               : T->isRValueReferenceType() ? VK_XValue : VK_RValue,
            /*FIXME*/ OK_Ordinary, false, false, false, false),
-      Field(Field), Loc(Loc) {
+      Field(Field), UsedContext(UsedContext), Loc(Loc) {
   assert(Field->hasInClassInitializer());
 }
 
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1906,6 +1906,7 @@
   return OverOps[Opc];
 }
 
+
 bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
                                                       Opcode Opc,
                                                       Expr *LHS, Expr *RHS) {
@@ -1938,6 +1939,97 @@
 
   return true;
 }
+
+static QualType getDecayedSourceLocExprType(const ASTContext &Ctx,
+                                            SourceLocExpr::IdentType Type) {
+  switch (Type) {
+  case SourceLocExpr::File:
+  case SourceLocExpr::Function: {
+    QualType Ty = Ctx.CharTy;
+    // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+    if (Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().ConstStrings)
+      Ty = Ty.withConst();
+    return Ctx.getPointerType(Ty);
+  }
+  case SourceLocExpr::Line:
+  case SourceLocExpr::Column:
+    return Ctx.UnsignedIntTy;
+  }
+  llvm_unreachable("unhandled case");
+}
+
+SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, IdentType Type,
+                             SourceLocation BLoc, SourceLocation RParenLoc,
+                             DeclContext *ParentContext)
+    : Expr(SourceLocExprClass, getDecayedSourceLocExprType(Ctx, Type),
+           VK_RValue, OK_Ordinary, false, false, false, false),
+      BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) {
+  SourceLocExprBits.Type = Type;
+}
+
+StringRef SourceLocExpr::getBuiltinStr() const {
+  switch (getIdentType()) {
+  case File:
+    return "__builtin_FILE";
+  case Function:
+    return "__builtin_FUNCTION";
+  case Line:
+    return "__builtin_LINE";
+  case Column:
+    return "__builtin_COLUMN";
+  }
+}
+
+APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
+                                         const Expr *DefaultExpr) const {
+  SourceLocation Loc;
+  const DeclContext *Context;
+
+  std::tie(Loc,
+           Context) = [&]() -> std::pair<SourceLocation, const DeclContext *> {
+    if (auto *DIE = dyn_cast_or_null<CXXDefaultInitExpr>(DefaultExpr))
+      return {DIE->getUsedLocation(), DIE->getUsedContext()};
+    if (auto *DAE = dyn_cast_or_null<CXXDefaultArgExpr>(DefaultExpr))
+      return {DAE->getUsedLocation(), DAE->getUsedContext()};
+    return {this->getLocation(), this->getParentContext()};
+  }();
+
+  PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc(
+      Ctx.getSourceManager().getExpansionRange(Loc).getEnd());
+
+  switch (getIdentType()) {
+  case SourceLocExpr::Function:
+  case SourceLocExpr::File: {
+    return [&]() {
+      auto MkStr = [&](StringRef Tmp) {
+        StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp);
+        return APValue(Res, CharUnits::Zero(), APValue::NoLValuePath(), 0);
+      };
+      if (getIdentType() == SourceLocExpr::File)
+        return MkStr(PLoc.getFilename());
+      const auto *FD = dyn_cast_or_null<FunctionDecl>(Context);
+      if (!FD)
+        return MkStr("");
+      // If we have a simple identifier there is no need to cache the
+      // human readable name.
+      if (IdentifierInfo *II = FD->getDeclName().getAsIdentifierInfo())
+        return MkStr(II->getNameStart());
+      return MkStr(PredefinedExpr::ComputeName(PredefinedExpr::Function, FD));
+    }();
+  }
+  case SourceLocExpr::Line:
+  case SourceLocExpr::Column: {
+    int64_t LineOrCol = getIdentType() == SourceLocExpr::Line
+                            ? PLoc.getLine()
+                            : PLoc.getColumn();
+    llvm::APSInt IntVal(
+        llvm::APInt(Ctx.getTargetInfo().getIntWidth(), LineOrCol));
+    return APValue(IntVal);
+  }
+  }
+  llvm_unreachable("unhandled case");
+}
+
 InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
                            ArrayRef<Expr*> initExprs, SourceLocation rbraceloc)
   : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
@@ -3092,6 +3184,7 @@
   case ObjCAvailabilityCheckExprClass:
   case CXXUuidofExprClass:
   case OpaqueValueExprClass:
+  case SourceLocExprClass:
     // These never have a side-effect.
     return false;
 
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -6207,8 +6207,13 @@
   if (!Param)
     return nullptr;
 
-  return CXXDefaultArgExpr::Create(
-        Importer.getToContext(), Importer.Import(E->getUsedLocation()), Param);
+  DeclContext *DC = Importer.ImportContext(E->getUsedContext());
+  if (!DC)
+    return nullptr;
+
+  return CXXDefaultArgExpr::Create(Importer.getToContext(),
+                                   Importer.Import(E->getUsedLocation()), Param,
+                                   DC);
 }
 
 Expr *ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
@@ -6897,8 +6902,13 @@
   if (!ToField && DIE->getField())
     return nullptr;
 
-  return CXXDefaultInitExpr::Create(
-      Importer.getToContext(), Importer.Import(DIE->getBeginLoc()), ToField);
+  DeclContext *DC = Importer.ImportContext(DIE->getUsedContext());
+  if (!DC)
+    return nullptr;
+
+  return CXXDefaultInitExpr::Create(Importer.getToContext(),
+                                    Importer.Import(DIE->getBeginLoc()),
+                                    ToField, DC);
 }
 
 Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -10048,6 +10048,27 @@
   return MaterializedTemporaryValues.lookup(E);
 }
 
+QualType ASTContext::getStringLiteralArrayType(QualType EltTy,
+                                               unsigned Length) const {
+  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+  EltTy = EltTy.withConst();
+  EltTy = adjustStringLiteralBaseType(EltTy);
+  return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1),
+                              ArrayType::Normal, /*IndexTypeQuals*/ 0);
+}
+
+StringLiteral *
+ASTContext::getPredefinedStringLiteralFromCache(StringRef Key) const {
+  StringLiteral *&Result = StringLiteralCache[Key];
+  if (!Result)
+    Result = StringLiteral::Create(
+        *this, Key, StringLiteral::Ascii,
+        /*Pascal*/ false,
+        getStringLiteralArrayType(CharTy.withConst(), Key.size()),
+        SourceLocation());
+  return Result;
+}
+
 bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
   const llvm::Triple &T = getTargetInfo().getTriple();
   if (!T.isOSDarwin())
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h
+++ include/clang/Serialization/ASTBitCodes.h
@@ -1718,6 +1718,9 @@
       /// A GNUNullExpr record.
       EXPR_GNU_NULL,
 
+      /// A SourceLocExpr record.
+      EXPR_SOURCE_LOC,
+
       /// A ShuffleVectorExpr record.
       EXPR_SHUFFLE_VECTOR,
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4474,6 +4474,21 @@
   ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
                             TypeSourceInfo *TInfo, SourceLocation RPLoc);
 
+  // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(),
+  // __builtin_COLUMN()
+  ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentType Type,
+                                SourceLocation BuiltinLoc,
+                                SourceLocation RPLoc);
+
+  /// Build a potentially resolved SourceLocExpr.
+  ///
+  /// \param SubExpr - null when the SourceLocExpr is unresolved, otherwise
+  /// SubExpr will be a literal expression representing the value of the
+  /// builtin call.
+  ExprResult BuildSourceLocExpr(SourceLocExpr::IdentType Type,
+                                SourceLocation BuiltinLoc, SourceLocation RPLoc,
+                                DeclContext *ParentContext);
+
   // __null
   ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
 
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def
+++ include/clang/Basic/TokenKinds.def
@@ -403,6 +403,11 @@
 KEYWORD(__attribute                 , KEYALL)
 KEYWORD(__builtin_choose_expr       , KEYALL)
 KEYWORD(__builtin_offsetof          , KEYALL)
+KEYWORD(__builtin_FILE              , KEYALL)
+KEYWORD(__builtin_FUNCTION          , KEYALL)
+KEYWORD(__builtin_LINE              , KEYALL)
+KEYWORD(__builtin_COLUMN            , KEYALL)
+
 // __builtin_types_compatible_p is a GNU C extension that we handle like a C++
 // type trait.
 TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
Index: include/clang/Basic/StmtNodes.td
===================================================================
--- include/clang/Basic/StmtNodes.td
+++ include/clang/Basic/StmtNodes.td
@@ -92,6 +92,7 @@
 def VAArgExpr : DStmt<Expr>;
 def GenericSelectionExpr : DStmt<Expr>;
 def PseudoObjectExpr : DStmt<Expr>;
+def SourceLocExpr : DStmt<Expr>;
 
 // Atomic expressions
 def AtomicExpr : DStmt<Expr>;
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -293,6 +293,16 @@
     unsigned IsImplicit : 1;
   };
 
+  class SourceLocExprBitfields {
+    friend class SourceLocExpr;
+
+    unsigned : NumExprBits;
+
+    /// The type of source location builtin represented by the SourceLocExpr.
+    /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
+    unsigned Type : 2;
+  };
+
   union {
     StmtBitfields StmtBits;
     CompoundStmtBitfields CompoundStmtBits;
@@ -311,6 +321,7 @@
     InitListExprBitfields InitListExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
     CoawaitExprBitfields CoawaitBits;
+    SourceLocExprBitfields SourceLocExprBits;
   };
 
 public:
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -2525,6 +2525,8 @@
 DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
 DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
 DEF_TRAVERSE_STMT(StmtExpr, {})
+DEF_TRAVERSE_STMT(SourceLocExpr, {})
+
 DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
   if (S->hasExplicitTemplateArgs()) {
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -1064,18 +1064,22 @@
   /// The parameter whose default is being used.
   ParmVarDecl *Param;
 
+  /// The context where the default argument expression was used.
+  DeclContext *UsedContext;
+
   /// The location where the default argument expression was used.
   SourceLocation Loc;
 
-  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
+                    DeclContext *UsedContext)
       : Expr(SC,
              param->hasUnparsedDefaultArg()
                  ? param->getType().getNonReferenceType()
                  : param->getDefaultArg()->getType(),
              param->getDefaultArg()->getValueKind(),
              param->getDefaultArg()->getObjectKind(), false, false, false,
              false),
-        Param(param), Loc(Loc) {}
+        Param(param), UsedContext(UsedContext), Loc(Loc) {}
 
 public:
   friend class ASTStmtReader;
@@ -1086,8 +1090,10 @@
   // \p Param is the parameter whose default argument is used by this
   // expression.
   static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
-                                   ParmVarDecl *Param) {
-    return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
+                                   ParmVarDecl *Param,
+                                   DeclContext *UsedContext) {
+    return new (C)
+        CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
   }
 
   // Retrieve the parameter that the argument was created from.
@@ -1102,6 +1108,9 @@
     return getParam()->getDefaultArg();
   }
 
+  const DeclContext *getUsedContext() const { return UsedContext; }
+  DeclContext *getUsedContext() { return UsedContext; }
+
   /// Retrieve the location where this default argument was actually
   /// used.
   SourceLocation getUsedLocation() const { return Loc; }
@@ -1135,11 +1144,14 @@
   /// The field whose default is being used.
   FieldDecl *Field;
 
+  /// The context where the default initializer expression was used.
+  DeclContext *UsedContext;
+
   /// The location where the default initializer expression was used.
   SourceLocation Loc;
 
   CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
-                     QualType T);
+                     QualType T, DeclContext *UsedContext);
 
   CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
 
@@ -1150,8 +1162,10 @@
   /// \p Field is the non-static data member whose default initializer is used
   /// by this expression.
   static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
-                                    FieldDecl *Field) {
-    return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
+                                    FieldDecl *Field,
+                                    DeclContext *UsedContext) {
+    return new (C)
+        CXXDefaultInitExpr(C, Loc, Field, Field->getType(), UsedContext);
   }
 
   /// Get the field whose initializer will be used.
@@ -1168,6 +1182,13 @@
     return Field->getInClassInitializer();
   }
 
+  const DeclContext *getUsedContext() const { return UsedContext; }
+  DeclContext *getUsedContext() { return UsedContext; }
+
+  /// Retrieve the location where this default initializer expression was
+  /// actually used.
+  SourceLocation getUsedLocation() const { return Loc; }
+
   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
 
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -3947,6 +3947,75 @@
   }
 };
 
+/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
+/// __builtin_FUNCTION(), or __builtin_FILE()
+class SourceLocExpr final : public Expr {
+  SourceLocation BuiltinLoc, RParenLoc;
+  DeclContext *ParentContext;
+
+public:
+  enum IdentType { Function, File, Line, Column };
+
+  SourceLocExpr(const ASTContext &Ctx, IdentType Type, SourceLocation BLoc,
+                SourceLocation RParenLoc, DeclContext *Context);
+
+  /// Build an empty call expression.
+  explicit SourceLocExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}
+
+  /// Return the result of evaluating this SourceLocExpr in the specified
+  /// (and possibly null) default argument or initialization context.
+  APValue EvaluateInContext(const ASTContext &Ctx,
+                            const Expr *DefaultExpr) const;
+
+  /// Return a string representing the name of the specific builtin function.
+  StringRef getBuiltinStr() const LLVM_READONLY;
+
+  IdentType getIdentType() const LLVM_READONLY {
+    return static_cast<IdentType>(SourceLocExprBits.Type);
+  }
+
+  bool isStringType() const LLVM_READONLY {
+    switch (getIdentType()) {
+    case File:
+    case Function:
+      return true;
+    case Line:
+    case Column:
+      return false;
+    }
+  }
+  bool isIntType() const LLVM_READONLY { return !isStringType(); }
+
+  /// If the SourceLocExpr has been resolved return the subexpression
+  /// representing the resolved value. Otherwise return null.
+  const DeclContext *getParentContext() const { return ParentContext; }
+  DeclContext *getParentContext() { return ParentContext; }
+
+  SourceLocation getLocation() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(child_iterator(), child_iterator());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SourceLocExprClass;
+  }
+
+private:
+  friend class ASTStmtReader;
+
+  void setIdentType(IdentType T) { SourceLocExprBits.Type = T; }
+  void setParentContext(DeclContext *DC) { ParentContext = DC; }
+  void setLocStart(SourceLocation L) { BuiltinLoc = L; }
+  void setLocEnd(SourceLocation L) { RParenLoc = L; }
+};
+
 /// Describes an C or C++ initializer list.
 ///
 /// InitListExpr describes an initializer list, which can be used to
Index: include/clang/AST/CurrentSourceLocExprScope.h
===================================================================
--- /dev/null
+++ include/clang/AST/CurrentSourceLocExprScope.h
@@ -0,0 +1,75 @@
+//===--- CurrentSourceLocExprScope.h ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines types used to track the current context needed to evaluate
+//  a SourceLocExpr.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
+#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
+
+#include <cassert>
+
+namespace clang {
+class Expr;
+
+/// Represents the current source location and context used to determine the
+/// value of the source location builtins (ex. __builtin_LINE), including the
+/// context of default argument and default initializer expressions.
+class CurrentSourceLocExprScope {
+  /// The CXXDefaultArgExpr or CXXDefaultInitExpr we're currently evaluating.
+  const Expr *DefaultExpr = nullptr;
+
+public:
+  /// A RAII style scope gaurd used for tracking the current source
+  /// location and context as used by the source location builtins
+  /// (ex. __builtin_LINE).
+  class SourceLocExprScopeGuard;
+
+  const Expr *getDefaultExpr() const { return DefaultExpr; }
+
+  explicit CurrentSourceLocExprScope() = default;
+
+private:
+  explicit CurrentSourceLocExprScope(const Expr *DefaultExpr)
+      : DefaultExpr(DefaultExpr) {}
+
+  CurrentSourceLocExprScope(CurrentSourceLocExprScope const &) = default;
+  CurrentSourceLocExprScope &
+  operator=(CurrentSourceLocExprScope const &) = default;
+};
+
+class CurrentSourceLocExprScope::SourceLocExprScopeGuard {
+public:
+  SourceLocExprScopeGuard(const Expr *DefaultExpr,
+                          CurrentSourceLocExprScope &Current)
+      : Current(Current), OldVal(Current), Enable(false) {
+    assert(DefaultExpr && "the new scope should not be empty");
+    if ((Enable = (Current.getDefaultExpr() == nullptr)))
+      Current = CurrentSourceLocExprScope(DefaultExpr);
+  }
+
+  ~SourceLocExprScopeGuard() {
+    if (Enable)
+      Current = OldVal;
+  }
+
+private:
+  SourceLocExprScopeGuard(SourceLocExprScopeGuard const &) = delete;
+  SourceLocExprScopeGuard &operator=(SourceLocExprScopeGuard const &) = delete;
+
+  CurrentSourceLocExprScope &Current;
+  CurrentSourceLocExprScope OldVal;
+  bool Enable;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -276,6 +276,12 @@
   llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
     MaterializedTemporaryValues;
 
+  /// A cache mapping a function declaration to its human-readable function or
+  /// file name.
+  ///
+  /// This is lazily created.  This is intentionally not serialized.
+  mutable llvm::StringMap<StringLiteral *> StringLiteralCache;
+
   /// Representation of a "canonical" template template parameter that
   /// is used in canonical template names.
   class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
@@ -1340,6 +1346,10 @@
                                 ArrayType::ArraySizeModifier ASM,
                                 unsigned IndexTypeQuals) const;
 
+  /// Return a type for a constant array for a string literal of the
+  /// specified element type and length.
+  QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const;
+
   /// Returns a vla type where known sizes are replaced with [*].
   QualType getVariableArrayDecayedType(QualType Ty) const;
 
@@ -2786,6 +2796,11 @@
   APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
                                          bool MayCreate);
 
+  /// Return a string representing the human readable name for the specified
+  /// function declaration or file name. Used by SourceLocExpr and
+  /// PredefinedExpr to cache evaluated results.
+  StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const;
+
   //===--------------------------------------------------------------------===//
   //                    Statistics
   //===--------------------------------------------------------------------===//
Index: docs/LanguageExtensions.rst
===================================================================
--- docs/LanguageExtensions.rst
+++ docs/LanguageExtensions.rst
@@ -2281,6 +2281,61 @@
 token `none`. If a user calls `__builin_suspend`, clang will insert `token none`
 as the first argument to the intrinsic.
 
+Source location builtins
+------------------------
+
+Clang provides experimental builtins to support C++ standard library implementation
+of ``std::experimental::source_location`` as specified in  http://wg21.link/N4600.
+With the exception of ``__builtin_COLUMN``, these builtins are also implemented by
+GCC.
+
+**Syntax**:
+
+.. code-block:: c
+
+  const char *__builtin_FILE();
+  const char *__builtin_FUNCTION();
+  unsigned    __builtin_LINE();
+  unsigned    __builtin_COLUMN(); // Clang only
+
+**Example of use**:
+
+.. code-block:: c++
+
+  void my_assert(bool pred, int line = __builtin_LINE(), // Captures line of caller
+                 const char* file = __builtin_FILE(),
+                 const char* function = __builtin_FUNCTION()) {
+    if (pred) return;
+    printf("%s:%d assertion failed in function %s\n", file, line, function);
+    std::abort();
+  }
+
+  struct MyAggregateType {
+    int x;
+    int line = __builtin_LINE(); // captures line where aggregate initialization occurs
+  };
+  static_assert(MyAggregateType{42}.line == __LINE__);
+
+  struct MyClassType {
+    int line = __builtin_LINE(); // captures line of the constructor used during initialization
+    constexpr MyClassType(int) { assert(line == __LINE__); }
+  };
+
+**Description**:
+
+The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, and ``__builtin_FILE`` return
+the values, at the "invocation point", for ``__LINE__``, ``__FUNCTION__``, and
+``__FILE__`` respectively. These builtins are constant expressions.
+
+When the builtins appears as part of a default function argument the invocation
+point is the location of the caller. When the builtins appear as part of a
+default member initializer, the invocation point is the location of the
+constructor or aggregate initialization used to create the object. Otherwise
+the invocation point is the same as the location of the builtin.
+
+When the invocation point of ``__builtin_FUNCTION`` is not a function scope the
+empty string is returned.
+
 Non-standard C++11 Attributes
 =============================
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to