Add __builtin_FILE_NAME()
Add '__builtin_FILE_NAME()', which expands to the filename because the full path is not always needed. It corresponds to the '__FILE_NAME__' predefined macro and is consistent with the other '__builin' functions added for predefined macros. Differential Revision: https://reviews.llvm.org/D144878
This commit is contained in:
parent
5ecba15434
commit
2147e940e8
|
@ -3611,13 +3611,15 @@ Source location builtins
|
||||||
|
|
||||||
Clang provides builtins to support C++ standard library implementation
|
Clang provides builtins to support C++ standard library implementation
|
||||||
of ``std::source_location`` as specified in C++20. With the exception
|
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**:
|
**Syntax**:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
const char *__builtin_FILE();
|
const char *__builtin_FILE();
|
||||||
|
const char *__builtin_FILE_NAME(); // Clang only
|
||||||
const char *__builtin_FUNCTION();
|
const char *__builtin_FUNCTION();
|
||||||
unsigned __builtin_LINE();
|
unsigned __builtin_LINE();
|
||||||
unsigned __builtin_COLUMN(); // Clang only
|
unsigned __builtin_COLUMN(); // Clang only
|
||||||
|
@ -3648,11 +3650,11 @@ of ``__builtin_COLUMN``, these builtins are also implemented by GCC.
|
||||||
|
|
||||||
**Description**:
|
**Description**:
|
||||||
|
|
||||||
The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, and ``__builtin_FILE``
|
The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, ``__builtin_FILE`` and
|
||||||
return the values, at the "invocation point", for ``__LINE__``,
|
``__builtin_FILE_NAME`` return the values, at the "invocation point", for
|
||||||
``__FUNCTION__``, and ``__FILE__`` respectively. ``__builtin_COLUMN`` similarly
|
``__LINE__``, ``__FUNCTION__``, ``__FILE__`` and ``__FILE_NAME__`` respectively.
|
||||||
returns the column, though there is no corresponding macro. These builtins are
|
``__builtin_COLUMN`` similarly returns the column,
|
||||||
constant expressions.
|
though there is no corresponding macro. These builtins are constant expressions.
|
||||||
|
|
||||||
When the builtins appear as part of a default function argument the invocation
|
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
|
point is the location of the caller. When the builtins appear as part of a
|
||||||
|
|
|
@ -116,6 +116,9 @@ Non-comprehensive list of changes in this release
|
||||||
optimizations.
|
optimizations.
|
||||||
- Clang now supports ``__builtin_nondeterministic_value`` that returns a
|
- Clang now supports ``__builtin_nondeterministic_value`` that returns a
|
||||||
nondeterministic value of the same type as the provided argument.
|
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
|
New Compiler Flags
|
||||||
------------------
|
------------------
|
||||||
|
|
|
@ -4685,13 +4685,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
|
/// 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 {
|
class SourceLocExpr final : public Expr {
|
||||||
SourceLocation BuiltinLoc, RParenLoc;
|
SourceLocation BuiltinLoc, RParenLoc;
|
||||||
DeclContext *ParentContext;
|
DeclContext *ParentContext;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum IdentKind { Function, File, Line, Column, SourceLocStruct };
|
enum IdentKind { Function, File, FileName, Line, Column, SourceLocStruct };
|
||||||
|
|
||||||
SourceLocExpr(const ASTContext &Ctx, IdentKind Type, QualType ResultTy,
|
SourceLocExpr(const ASTContext &Ctx, IdentKind Type, QualType ResultTy,
|
||||||
SourceLocation BLoc, SourceLocation RParenLoc,
|
SourceLocation BLoc, SourceLocation RParenLoc,
|
||||||
|
@ -4715,6 +4716,7 @@ public:
|
||||||
bool isIntType() const {
|
bool isIntType() const {
|
||||||
switch (getIdentKind()) {
|
switch (getIdentKind()) {
|
||||||
case File:
|
case File:
|
||||||
|
case FileName:
|
||||||
case Function:
|
case Function:
|
||||||
case SourceLocStruct:
|
case SourceLocStruct:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -436,6 +436,7 @@ KEYWORD(__attribute , KEYALL)
|
||||||
KEYWORD(__builtin_choose_expr , KEYALL)
|
KEYWORD(__builtin_choose_expr , KEYALL)
|
||||||
KEYWORD(__builtin_offsetof , KEYALL)
|
KEYWORD(__builtin_offsetof , KEYALL)
|
||||||
KEYWORD(__builtin_FILE , KEYALL)
|
KEYWORD(__builtin_FILE , KEYALL)
|
||||||
|
KEYWORD(__builtin_FILE_NAME , KEYALL)
|
||||||
KEYWORD(__builtin_FUNCTION , KEYALL)
|
KEYWORD(__builtin_FUNCTION , KEYALL)
|
||||||
KEYWORD(__builtin_LINE , KEYALL)
|
KEYWORD(__builtin_LINE , KEYALL)
|
||||||
KEYWORD(__builtin_COLUMN , KEYALL)
|
KEYWORD(__builtin_COLUMN , KEYALL)
|
||||||
|
|
|
@ -2842,6 +2842,11 @@ public:
|
||||||
const LangOptions &LangOpts,
|
const LangOptions &LangOpts,
|
||||||
const TargetInfo &TI);
|
const TargetInfo &TI);
|
||||||
|
|
||||||
|
static void processPathToFileName(SmallVectorImpl<char> &FileName,
|
||||||
|
const PresumedLoc &PLoc,
|
||||||
|
const LangOptions &LangOpts,
|
||||||
|
const TargetInfo &TI);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitMacroDeprecationWarning(const Token &Identifier) const;
|
void emitMacroDeprecationWarning(const Token &Identifier) const;
|
||||||
void emitRestrictExpansionWarning(const Token &Identifier) const;
|
void emitRestrictExpansionWarning(const Token &Identifier) const;
|
||||||
|
|
|
@ -2239,6 +2239,8 @@ StringRef SourceLocExpr::getBuiltinStr() const {
|
||||||
switch (getIdentKind()) {
|
switch (getIdentKind()) {
|
||||||
case File:
|
case File:
|
||||||
return "__builtin_FILE";
|
return "__builtin_FILE";
|
||||||
|
case FileName:
|
||||||
|
return "__builtin_FILE_NAME";
|
||||||
case Function:
|
case Function:
|
||||||
return "__builtin_FUNCTION";
|
return "__builtin_FUNCTION";
|
||||||
case Line:
|
case Line:
|
||||||
|
@ -2277,6 +2279,14 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (getIdentKind()) {
|
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: {
|
case SourceLocExpr::File: {
|
||||||
SmallString<256> Path(PLoc.getFilename());
|
SmallString<256> Path(PLoc.getFilename());
|
||||||
clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(),
|
clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(),
|
||||||
|
|
|
@ -1559,17 +1559,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
|
||||||
// __FILE_NAME__ is a Clang-specific extension that expands to the
|
// __FILE_NAME__ is a Clang-specific extension that expands to the
|
||||||
// the last part of __FILE__.
|
// the last part of __FILE__.
|
||||||
if (II == Ident__FILE_NAME__) {
|
if (II == Ident__FILE_NAME__) {
|
||||||
// Try to get the last path component, failing that return the original
|
processPathToFileName(FN, PLoc, getLangOpts(), getTargetInfo());
|
||||||
// presumed location.
|
|
||||||
StringRef PLFileName = llvm::sys::path::filename(PLoc.getFilename());
|
|
||||||
if (PLFileName != "")
|
|
||||||
FN += PLFileName;
|
|
||||||
else
|
|
||||||
FN += PLoc.getFilename();
|
|
||||||
} else {
|
} else {
|
||||||
FN += PLoc.getFilename();
|
FN += PLoc.getFilename();
|
||||||
|
processPathForFileMacro(FN, getLangOpts(), getTargetInfo());
|
||||||
}
|
}
|
||||||
processPathForFileMacro(FN, getLangOpts(), getTargetInfo());
|
|
||||||
Lexer::Stringify(FN);
|
Lexer::Stringify(FN);
|
||||||
OS << '"' << FN << '"';
|
OS << '"' << FN << '"';
|
||||||
}
|
}
|
||||||
|
@ -1974,3 +1968,16 @@ void Preprocessor::processPathForFileMacro(SmallVectorImpl<char> &Path,
|
||||||
llvm::sys::path::remove_dots(Path, false, llvm::sys::path::Style::posix);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -789,6 +789,7 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback {
|
||||||
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
|
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
|
||||||
/// assign-expr ')'
|
/// assign-expr ')'
|
||||||
/// [GNU] '__builtin_FILE' '(' ')'
|
/// [GNU] '__builtin_FILE' '(' ')'
|
||||||
|
/// [CLANG] '__builtin_FILE_NAME' '(' ')'
|
||||||
/// [GNU] '__builtin_FUNCTION' '(' ')'
|
/// [GNU] '__builtin_FUNCTION' '(' ')'
|
||||||
/// [GNU] '__builtin_LINE' '(' ')'
|
/// [GNU] '__builtin_LINE' '(' ')'
|
||||||
/// [CLANG] '__builtin_COLUMN' '(' ')'
|
/// [CLANG] '__builtin_COLUMN' '(' ')'
|
||||||
|
@ -1317,6 +1318,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
||||||
case tok::kw___builtin_convertvector:
|
case tok::kw___builtin_convertvector:
|
||||||
case tok::kw___builtin_COLUMN:
|
case tok::kw___builtin_COLUMN:
|
||||||
case tok::kw___builtin_FILE:
|
case tok::kw___builtin_FILE:
|
||||||
|
case tok::kw___builtin_FILE_NAME:
|
||||||
case tok::kw___builtin_FUNCTION:
|
case tok::kw___builtin_FUNCTION:
|
||||||
case tok::kw___builtin_LINE:
|
case tok::kw___builtin_LINE:
|
||||||
case tok::kw___builtin_source_location:
|
case tok::kw___builtin_source_location:
|
||||||
|
@ -2542,6 +2544,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
|
||||||
/// assign-expr ')'
|
/// assign-expr ')'
|
||||||
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
|
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
|
||||||
/// [GNU] '__builtin_FILE' '(' ')'
|
/// [GNU] '__builtin_FILE' '(' ')'
|
||||||
|
/// [CLANG] '__builtin_FILE_NAME' '(' ')'
|
||||||
/// [GNU] '__builtin_FUNCTION' '(' ')'
|
/// [GNU] '__builtin_FUNCTION' '(' ')'
|
||||||
/// [GNU] '__builtin_LINE' '(' ')'
|
/// [GNU] '__builtin_LINE' '(' ')'
|
||||||
/// [CLANG] '__builtin_COLUMN' '(' ')'
|
/// [CLANG] '__builtin_COLUMN' '(' ')'
|
||||||
|
@ -2777,6 +2780,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
}
|
}
|
||||||
case tok::kw___builtin_COLUMN:
|
case tok::kw___builtin_COLUMN:
|
||||||
case tok::kw___builtin_FILE:
|
case tok::kw___builtin_FILE:
|
||||||
|
case tok::kw___builtin_FILE_NAME:
|
||||||
case tok::kw___builtin_FUNCTION:
|
case tok::kw___builtin_FUNCTION:
|
||||||
case tok::kw___builtin_LINE:
|
case tok::kw___builtin_LINE:
|
||||||
case tok::kw___builtin_source_location: {
|
case tok::kw___builtin_source_location: {
|
||||||
|
@ -2790,6 +2794,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
switch (T) {
|
switch (T) {
|
||||||
case tok::kw___builtin_FILE:
|
case tok::kw___builtin_FILE:
|
||||||
return SourceLocExpr::File;
|
return SourceLocExpr::File;
|
||||||
|
case tok::kw___builtin_FILE_NAME:
|
||||||
|
return SourceLocExpr::FileName;
|
||||||
case tok::kw___builtin_FUNCTION:
|
case tok::kw___builtin_FUNCTION:
|
||||||
return SourceLocExpr::Function;
|
return SourceLocExpr::Function;
|
||||||
case tok::kw___builtin_LINE:
|
case tok::kw___builtin_LINE:
|
||||||
|
|
|
@ -17060,6 +17060,7 @@ ExprResult Sema::ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind,
|
||||||
QualType ResultTy;
|
QualType ResultTy;
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case SourceLocExpr::File:
|
case SourceLocExpr::File:
|
||||||
|
case SourceLocExpr::FileName:
|
||||||
case SourceLocExpr::Function: {
|
case SourceLocExpr::Function: {
|
||||||
QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0);
|
QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0);
|
||||||
ResultTy =
|
ResultTy =
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
// still return true.
|
// still return true.
|
||||||
#if !__has_builtin(__builtin_LINE) || \
|
#if !__has_builtin(__builtin_LINE) || \
|
||||||
!__has_builtin(__builtin_FILE) || \
|
!__has_builtin(__builtin_FILE) || \
|
||||||
|
!__has_builtin(__builtin_FILE_NAME) || \
|
||||||
!__has_builtin(__builtin_FUNCTION) || \
|
!__has_builtin(__builtin_FUNCTION) || \
|
||||||
!__has_builtin(__builtin_COLUMN) || \
|
!__has_builtin(__builtin_COLUMN) || \
|
||||||
!__has_builtin(__builtin_types_compatible_p)
|
!__has_builtin(__builtin_types_compatible_p)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
// still return true.
|
// still return true.
|
||||||
#if !__has_builtin(__builtin_LINE) || \
|
#if !__has_builtin(__builtin_LINE) || \
|
||||||
!__has_builtin(__builtin_FILE) || \
|
!__has_builtin(__builtin_FILE) || \
|
||||||
|
!__has_builtin(__builtin_FILE_NAME) || \
|
||||||
!__has_builtin(__builtin_FUNCTION) || \
|
!__has_builtin(__builtin_FUNCTION) || \
|
||||||
!__has_builtin(__builtin_COLUMN) || \
|
!__has_builtin(__builtin_COLUMN) || \
|
||||||
!__has_builtin(__array_rank) || \
|
!__has_builtin(__array_rank) || \
|
||||||
|
|
|
@ -17,12 +17,14 @@ char *const NCFUNC = __builtin_FUNCTION();
|
||||||
|
|
||||||
#ifdef CONST_STRINGS
|
#ifdef CONST_STRINGS
|
||||||
_Static_assert(IsEqual(__builtin_FILE(), __FILE__), "");
|
_Static_assert(IsEqual(__builtin_FILE(), __FILE__), "");
|
||||||
|
_Static_assert(IsEqual(__builtin_FILE_NAME(), __FILE_NAME__), "");
|
||||||
_Static_assert(__builtin_LINE() == __LINE__, "");
|
_Static_assert(__builtin_LINE() == __LINE__, "");
|
||||||
_Static_assert(IsEqual("", __builtin_FUNCTION()), "");
|
_Static_assert(IsEqual("", __builtin_FUNCTION()), "");
|
||||||
|
|
||||||
#line 42 "my_file.c"
|
#line 42 "my_file.c"
|
||||||
_Static_assert(__builtin_LINE() == 42, "");
|
_Static_assert(__builtin_LINE() == 42, "");
|
||||||
_Static_assert(IsEqual(__builtin_FILE(), "my_file.c"), "");
|
_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(_"), "");
|
_Static_assert(__builtin_COLUMN() == __builtin_strlen("_Static_assert(_"), "");
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
namespace source_location_file {
|
namespace source_location_file {
|
||||||
|
|
||||||
constexpr const char *FILE = __FILE__;
|
constexpr const char *FILE = __FILE__;
|
||||||
|
constexpr const char *FILE_NAME = __FILE_NAME__;
|
||||||
|
|
||||||
constexpr SL global_info = SL::current();
|
constexpr SL global_info = SL::current();
|
||||||
|
constexpr const char *global_info_filename = __builtin_FILE_NAME();
|
||||||
|
|
||||||
constexpr SL test_function(SL v = SL::current()) {
|
constexpr SL test_function(SL v = SL::current()) {
|
||||||
return v;
|
return v;
|
||||||
|
@ -15,6 +17,15 @@ constexpr SL test_function_indirect() {
|
||||||
return test_function();
|
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>
|
template <class T, class U = SL>
|
||||||
constexpr U test_function_template(T, U u = U::current()) {
|
constexpr U test_function_template(T, U u = U::current()) {
|
||||||
return u;
|
return u;
|
||||||
|
@ -25,13 +36,29 @@ constexpr U test_function_template_indirect(T t) {
|
||||||
return test_function_template(t);
|
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 {
|
struct TestClass {
|
||||||
SL info = SL::current();
|
SL info = SL::current();
|
||||||
|
const char *info_file_name = __builtin_FILE_NAME();
|
||||||
SL ctor_info;
|
SL ctor_info;
|
||||||
|
const char *ctor_info_file_name = nullptr;
|
||||||
TestClass() = default;
|
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>
|
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>
|
template <class T = SL>
|
||||||
|
@ -39,6 +66,7 @@ struct AggrClass {
|
||||||
int x;
|
int x;
|
||||||
T info;
|
T info;
|
||||||
T init_info = T::current();
|
T init_info = T::current();
|
||||||
|
const char *init_info_file_name = __builtin_FILE_NAME();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace source_location_file
|
} // namespace source_location_file
|
||||||
|
|
|
@ -84,6 +84,7 @@ constexpr bool is_same<T, T> = true;
|
||||||
static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
|
static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
|
||||||
static_assert(is_same<decltype(__builtin_COLUMN()), 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()), 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_FUNCTION()), const char *>);
|
||||||
static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
|
static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ static_assert(is_same<decltype(__builtin_source_location()), const std::source_l
|
||||||
static_assert(noexcept(__builtin_LINE()));
|
static_assert(noexcept(__builtin_LINE()));
|
||||||
static_assert(noexcept(__builtin_COLUMN()));
|
static_assert(noexcept(__builtin_COLUMN()));
|
||||||
static_assert(noexcept(__builtin_FILE()));
|
static_assert(noexcept(__builtin_FILE()));
|
||||||
|
static_assert(noexcept(__builtin_FILE_NAME()));
|
||||||
static_assert(noexcept(__builtin_FUNCTION()));
|
static_assert(noexcept(__builtin_FUNCTION()));
|
||||||
static_assert(noexcept(__builtin_source_location()));
|
static_assert(noexcept(__builtin_source_location()));
|
||||||
|
|
||||||
|
@ -346,6 +348,54 @@ void test_aggr_class() {
|
||||||
|
|
||||||
} // namespace test_file
|
} // 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()
|
// __builtin_FUNCTION()
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -487,6 +537,7 @@ static_assert(SL::current().line() == StartLine + 2);
|
||||||
#line 44 "test_file.c"
|
#line 44 "test_file.c"
|
||||||
static_assert(is_equal("test_file.c", __FILE__));
|
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()));
|
||||||
|
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", SL::current().file()));
|
||||||
static_assert(is_equal("test_file.c", SLF::test_function().file()));
|
static_assert(is_equal("test_file.c", SLF::test_function().file()));
|
||||||
static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
|
static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
|
||||||
|
|
|
@ -259,6 +259,10 @@ TEST_P(ImportExpr, ImportSourceLocExpr) {
|
||||||
Lang_CXX03, Verifier,
|
Lang_CXX03, Verifier,
|
||||||
functionDecl(hasDescendant(
|
functionDecl(hasDescendant(
|
||||||
sourceLocExpr(hasBuiltinStr("__builtin_FILE")))));
|
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,
|
testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03,
|
||||||
"", Lang_CXX03, Verifier,
|
"", Lang_CXX03, Verifier,
|
||||||
functionDecl(hasDescendant(
|
functionDecl(hasDescendant(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user