karapsinie updated this revision to Diff 505462.
karapsinie added a comment.
Execute "git-clang-format HEAD~1"
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144878/new/
https://reviews.llvm.org/D144878
Files:
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/AST/Expr.h
clang/include/clang/Basic/TokenKinds.def
clang/include/clang/Lex/Preprocessor.h
clang/lib/AST/Expr.cpp
clang/lib/Lex/PPMacroExpansion.cpp
clang/lib/Parse/ParseExpr.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/Preprocessor/feature_tests.c
clang/test/Preprocessor/feature_tests.cpp
clang/test/Sema/source_location.c
clang/test/SemaCXX/Inputs/source-location-file.h
clang/test/SemaCXX/source_location.cpp
clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -259,6 +259,10 @@
Lang_CXX03, Verifier,
functionDecl(hasDescendant(
sourceLocExpr(hasBuiltinStr("__builtin_FILE")))));
+ testImport("void declToImport() { (void)__builtin_FILE_NAME(); }", Lang_CXX03,
+ "", Lang_CXX03, Verifier,
+ functionDecl(hasDescendant(
+ sourceLocExpr(hasBuiltinStr("__builtin_FILE_NAME")))));
testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03,
"", Lang_CXX03, Verifier,
functionDecl(hasDescendant(
Index: clang/test/SemaCXX/source_location.cpp
===================================================================
--- clang/test/SemaCXX/source_location.cpp
+++ clang/test/SemaCXX/source_location.cpp
@@ -84,6 +84,7 @@
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_FILE_NAME()), const char *>);
static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
@@ -91,6 +92,7 @@
static_assert(noexcept(__builtin_LINE()));
static_assert(noexcept(__builtin_COLUMN()));
static_assert(noexcept(__builtin_FILE()));
+static_assert(noexcept(__builtin_FILE_NAME()));
static_assert(noexcept(__builtin_FUNCTION()));
static_assert(noexcept(__builtin_source_location()));
@@ -346,6 +348,54 @@
} // namespace test_file
+//===----------------------------------------------------------------------===//
+// __builtin_FILE_NAME()
+//===----------------------------------------------------------------------===//
+
+namespace test_file_name {
+constexpr const char *test_file_name_simple(
+ const char *__f = __builtin_FILE_NAME()) {
+ return __f;
+}
+void test_function() {
+#line 900
+ static_assert(is_equal(test_file_name_simple(), __FILE_NAME__));
+ static_assert(is_equal(SLF::test_function_filename(), __FILE_NAME__), "");
+ static_assert(is_equal(SLF::test_function_filename_template(42),
+ __FILE_NAME__), "");
+
+ static_assert(is_equal(SLF::test_function_filename_indirect(),
+ SLF::global_info_filename), "");
+ static_assert(is_equal(SLF::test_function_filename_template_indirect(42),
+ SLF::global_info_filename), "");
+
+ static_assert(test_file_name_simple() != nullptr);
+ static_assert(is_equal(test_file_name_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_name;
+ constexpr auto Char = F[0];
+ static_assert(is_equal(Default.info_file_name, SLF::FILE_NAME), "");
+ static_assert(is_equal(InParam.info_file_name, SLF::FILE_NAME), "");
+ static_assert(is_equal(InParam.ctor_info_file_name, __FILE_NAME__), "");
+}
+
+void test_aggr_class() {
+ using Agg = SLF::AggrClass<>;
+ constexpr Agg Default{};
+ constexpr Agg InitOne{42};
+ static_assert(is_equal(Default.init_info_file_name, __FILE_NAME__), "");
+ static_assert(is_equal(InitOne.init_info_file_name, __FILE_NAME__), "");
+}
+
+} // namespace test_file_name
+
//===----------------------------------------------------------------------===//
// __builtin_FUNCTION()
//===----------------------------------------------------------------------===//
@@ -487,6 +537,7 @@
#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", __builtin_FILE_NAME()));
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()));
Index: clang/test/SemaCXX/Inputs/source-location-file.h
===================================================================
--- clang/test/SemaCXX/Inputs/source-location-file.h
+++ clang/test/SemaCXX/Inputs/source-location-file.h
@@ -4,8 +4,10 @@
namespace source_location_file {
constexpr const char *FILE = __FILE__;
+constexpr const char *FILE_NAME = __FILE_NAME__;
constexpr SL global_info = SL::current();
+constexpr const char *global_info_filename = __builtin_FILE_NAME();
constexpr SL test_function(SL v = SL::current()) {
return v;
@@ -15,6 +17,15 @@
return test_function();
}
+constexpr const char *test_function_filename(
+ const char *file_name = __builtin_FILE_NAME()) {
+ return file_name;
+}
+
+constexpr const char *test_function_filename_indirect() {
+ return test_function_filename();
+}
+
template <class T, class U = SL>
constexpr U test_function_template(T, U u = U::current()) {
return u;
@@ -25,13 +36,29 @@
return test_function_template(t);
}
+template <class T, class U = const char *>
+constexpr U test_function_filename_template(T, U u = __builtin_FILE_NAME()) {
+ return u;
+}
+
+template <class T, class U = const char *>
+constexpr U test_function_filename_template_indirect(T t) {
+ return test_function_filename_template(t);
+}
+
struct TestClass {
SL info = SL::current();
+ const char *info_file_name = __builtin_FILE_NAME();
SL ctor_info;
+ const char *ctor_info_file_name = nullptr;
TestClass() = default;
- constexpr TestClass(int, SL cinfo = SL::current()) : ctor_info(cinfo) {}
+ constexpr TestClass(int, SL cinfo = SL::current(),
+ const char *cfile_name = __builtin_FILE_NAME()) :
+ ctor_info(cinfo), ctor_info_file_name(cfile_name) {}
template <class T, class U = SL>
- constexpr TestClass(int, T, U u = U::current()) : ctor_info(u) {}
+ constexpr TestClass(int, T, U u = U::current(),
+ const char *cfile_name = __builtin_FILE_NAME()) :
+ ctor_info(u), ctor_info_file_name(cfile_name) {}
};
template <class T = SL>
@@ -39,6 +66,7 @@
int x;
T info;
T init_info = T::current();
+ const char *init_info_file_name = __builtin_FILE_NAME();
};
} // namespace source_location_file
Index: clang/test/Sema/source_location.c
===================================================================
--- clang/test/Sema/source_location.c
+++ clang/test/Sema/source_location.c
@@ -17,12 +17,14 @@
#ifdef CONST_STRINGS
_Static_assert(IsEqual(__builtin_FILE(), __FILE__), "");
+_Static_assert(IsEqual(__builtin_FILE_NAME(), __FILE_NAME__), "");
_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(IsEqual(__builtin_FILE_NAME(), "my_file.c"), "");
_Static_assert(__builtin_COLUMN() == __builtin_strlen("_Static_assert(_"), "");
Index: clang/test/Preprocessor/feature_tests.cpp
===================================================================
--- clang/test/Preprocessor/feature_tests.cpp
+++ clang/test/Preprocessor/feature_tests.cpp
@@ -23,6 +23,7 @@
// still return true.
#if !__has_builtin(__builtin_LINE) || \
!__has_builtin(__builtin_FILE) || \
+ !__has_builtin(__builtin_FILE_NAME) || \
!__has_builtin(__builtin_FUNCTION) || \
!__has_builtin(__builtin_COLUMN) || \
!__has_builtin(__array_rank) || \
Index: clang/test/Preprocessor/feature_tests.c
===================================================================
--- clang/test/Preprocessor/feature_tests.c
+++ clang/test/Preprocessor/feature_tests.c
@@ -24,6 +24,7 @@
// still return true.
#if !__has_builtin(__builtin_LINE) || \
!__has_builtin(__builtin_FILE) || \
+ !__has_builtin(__builtin_FILE_NAME) || \
!__has_builtin(__builtin_FUNCTION) || \
!__has_builtin(__builtin_COLUMN) || \
!__has_builtin(__builtin_types_compatible_p)
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -17045,6 +17045,7 @@
QualType ResultTy;
switch (Kind) {
case SourceLocExpr::File:
+ case SourceLocExpr::FileName:
case SourceLocExpr::Function: {
QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0);
ResultTy =
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -789,6 +789,7 @@
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
/// assign-expr ')'
/// [GNU] '__builtin_FILE' '(' ')'
+/// [CLANG] '__builtin_FILE_NAME' '(' ')'
/// [GNU] '__builtin_FUNCTION' '(' ')'
/// [GNU] '__builtin_LINE' '(' ')'
/// [CLANG] '__builtin_COLUMN' '(' ')'
@@ -801,9 +802,9 @@
/// [OBJC] '\@encode' '(' type-name ')'
/// [OBJC] objc-string-literal
/// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
-/// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3]
+/// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3]
/// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
-/// [C++11] typename-specifier braced-init-list [C++11 5.2.3]
+/// [C++11] typename-specifier braced-init-list [C++11 5.2.3]
/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
@@ -1317,6 +1318,7 @@
case tok::kw___builtin_convertvector:
case tok::kw___builtin_COLUMN:
case tok::kw___builtin_FILE:
+ case tok::kw___builtin_FILE_NAME:
case tok::kw___builtin_FUNCTION:
case tok::kw___builtin_LINE:
case tok::kw___builtin_source_location:
@@ -2542,6 +2544,7 @@
/// assign-expr ')'
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
/// [GNU] '__builtin_FILE' '(' ')'
+/// [CLANG] '__builtin_FILE_NAME' '(' ')'
/// [GNU] '__builtin_FUNCTION' '(' ')'
/// [GNU] '__builtin_LINE' '(' ')'
/// [CLANG] '__builtin_COLUMN' '(' ')'
@@ -2777,6 +2780,7 @@
}
case tok::kw___builtin_COLUMN:
case tok::kw___builtin_FILE:
+ case tok::kw___builtin_FILE_NAME:
case tok::kw___builtin_FUNCTION:
case tok::kw___builtin_LINE:
case tok::kw___builtin_source_location: {
@@ -2790,6 +2794,8 @@
switch (T) {
case tok::kw___builtin_FILE:
return SourceLocExpr::File;
+ case tok::kw___builtin_FILE_NAME:
+ return SourceLocExpr::FileName;
case tok::kw___builtin_FUNCTION:
return SourceLocExpr::Function;
case tok::kw___builtin_LINE:
Index: clang/lib/Lex/PPMacroExpansion.cpp
===================================================================
--- clang/lib/Lex/PPMacroExpansion.cpp
+++ clang/lib/Lex/PPMacroExpansion.cpp
@@ -1559,17 +1559,11 @@
// __FILE_NAME__ is a Clang-specific extension that expands to the
// the last part of __FILE__.
if (II == Ident__FILE_NAME__) {
- // Try to get the last path component, failing that return the original
- // presumed location.
- StringRef PLFileName = llvm::sys::path::filename(PLoc.getFilename());
- if (PLFileName != "")
- FN += PLFileName;
- else
- FN += PLoc.getFilename();
+ processPathToFileName(FN, PLoc, getLangOpts(), getTargetInfo());
} else {
FN += PLoc.getFilename();
+ processPathForFileMacro(FN, getLangOpts(), getTargetInfo());
}
- processPathForFileMacro(FN, getLangOpts(), getTargetInfo());
Lexer::Stringify(FN);
OS << '"' << FN << '"';
}
@@ -1995,3 +1989,16 @@
llvm::sys::path::remove_dots(Path, false, llvm::sys::path::Style::posix);
}
}
+
+void Preprocessor::processPathToFileName(SmallVectorImpl<char> &FileName,
+ const PresumedLoc &PLoc,
+ const LangOptions &LangOpts,
+ const TargetInfo &TI) {
+ // Try to get the last path component, failing that return the original
+ // presumed location.
+ StringRef PLFileName = llvm::sys::path::filename(PLoc.getFilename());
+ if (PLFileName.empty())
+ PLFileName = PLoc.getFilename();
+ FileName.append(PLFileName.begin(), PLFileName.end());
+ processPathForFileMacro(FileName, LangOpts, TI);
+}
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -2239,6 +2239,8 @@
switch (getIdentKind()) {
case File:
return "__builtin_FILE";
+ case FileName:
+ return "__builtin_FILE_NAME";
case Function:
return "__builtin_FUNCTION";
case Line:
@@ -2277,6 +2279,14 @@
};
switch (getIdentKind()) {
+ case SourceLocExpr::FileName: {
+ // builtin_FILE_NAME() is a Clang-specific extension that expands to the
+ // the last part of builtin_FILE().
+ SmallString<256> FileName;
+ clang::Preprocessor::processPathToFileName(
+ FileName, PLoc, Ctx.getLangOpts(), Ctx.getTargetInfo());
+ return MakeStringLiteral(FileName);
+ }
case SourceLocExpr::File: {
SmallString<256> Path(PLoc.getFilename());
clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(),
Index: clang/include/clang/Lex/Preprocessor.h
===================================================================
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -2855,6 +2855,11 @@
const LangOptions &LangOpts,
const TargetInfo &TI);
+ static void processPathToFileName(SmallVectorImpl<char> &FileName,
+ const PresumedLoc &PLoc,
+ const LangOptions &LangOpts,
+ const TargetInfo &TI);
+
private:
void emitMacroDeprecationWarning(const Token &Identifier) const;
void emitRestrictExpansionWarning(const Token &Identifier) const;
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -436,6 +436,7 @@
KEYWORD(__builtin_choose_expr , KEYALL)
KEYWORD(__builtin_offsetof , KEYALL)
KEYWORD(__builtin_FILE , KEYALL)
+KEYWORD(__builtin_FILE_NAME , KEYALL)
KEYWORD(__builtin_FUNCTION , KEYALL)
KEYWORD(__builtin_LINE , KEYALL)
KEYWORD(__builtin_COLUMN , KEYALL)
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4686,13 +4686,14 @@
};
/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
-/// __builtin_FUNCTION(), __builtin_FILE(), or __builtin_source_location().
+/// __builtin_FUNCTION(), __builtin_FILE(), __builtin_FILE_NAME(),
+/// or __builtin_source_location().
class SourceLocExpr final : public Expr {
SourceLocation BuiltinLoc, RParenLoc;
DeclContext *ParentContext;
public:
- enum IdentKind { Function, File, Line, Column, SourceLocStruct };
+ enum IdentKind { Function, File, FileName, Line, Column, SourceLocStruct };
SourceLocExpr(const ASTContext &Ctx, IdentKind Type, QualType ResultTy,
SourceLocation BLoc, SourceLocation RParenLoc,
@@ -4716,6 +4717,7 @@
bool isIntType() const {
switch (getIdentKind()) {
case File:
+ case FileName:
case Function:
case SourceLocStruct:
return false;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -110,6 +110,9 @@
optimizations.
- Clang now supports ``__builtin_nondeterministic_value`` that returns a
nondeterministic value of the same type as the provided argument.
+- Clang now supports ``__builtin_FILE_NAME()`` which returns the same
+ information as the ``__FILE_NAME__`` macro (the presumed file name
+ from the invocation point, with no path components included).
New Compiler Flags
------------------
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -3609,13 +3609,15 @@
Clang provides builtins to support C++ standard library implementation
of ``std::source_location`` as specified in C++20. With the exception
-of ``__builtin_COLUMN``, these builtins are also implemented by GCC.
+of ``__builtin_COLUMN`` and ``__builtin_FILE_NAME``,
+these builtins are also implemented by GCC.
**Syntax**:
.. code-block:: c
const char *__builtin_FILE();
+ const char *__builtin_FILE_NAME(); // Clang only
const char *__builtin_FUNCTION();
unsigned __builtin_LINE();
unsigned __builtin_COLUMN(); // Clang only
@@ -3646,11 +3648,11 @@
**Description**:
-The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, and ``__builtin_FILE``
-return the values, at the "invocation point", for ``__LINE__``,
-``__FUNCTION__``, and ``__FILE__`` respectively. ``__builtin_COLUMN`` similarly
-returns the column, though there is no corresponding macro. These builtins are
-constant expressions.
+The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, ``__builtin_FILE`` and
+``__builtin_FILE_NAME`` return the values, at the "invocation point", for
+``__LINE__``, ``__FUNCTION__``, ``__FILE__`` and ``__FILE_NAME__`` respectively.
+``__builtin_COLUMN`` similarly returns the column,
+though there is no corresponding macro. These builtins are constant expressions.
When the builtins appear as part of a default function argument the invocation
point is the location of the caller. When the builtins appear as part of a
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits