c: Add support for __FILE_NAME__ macro (PR c/42579)

The toolchain provided by ST for stm32 has had support for
__FILENAME__ for a while, but clang/llvm has recently implemented
support for __FILE_NAME__, so it seems better to use the same macro
name in GCC.

It happens that the ST patch is similar to the one proposed in PR
c/42579.

Given these input files:
::::::::::::::
mydir/myinc.h
::::::::::::::
char* mystringh_file = __FILE__;
char* mystringh_filename = __FILE_NAME__;
char* mystringh_base_file = __BASE_FILE__;
::::::::::::::
mydir/mysrc.c
::::::::::::::

char* mystring_file = __FILE__;
char* mystring_filename = __FILE_NAME__;
char* mystring_base_file = __BASE_FILE__;

we produce:
$ gcc mydir/mysrc.c -I . -E
char* mystringh_file = "./mydir/myinc.h";
char* mystringh_filename = "myinc.h";
char* mystringh_base_file = "mydir/mysrc.c";

char* mystring_file = "mydir/mysrc.c";
char* mystring_filename = "mysrc.c";
char* mystring_base_file = "mydir/mysrc.c";

2021-05-20  Christophe Lyon  <christophe.lyon@linaro.org>
	    Torbjörn Svensson  <torbjorn.svensson@st.com>

	PR c/42579
	libcpp/
	* include/cpplib.h (cpp_builtin_type): Add BT_FILE_NAME entry.
	* init.c (builtin_array): Likewise.
	* macro.c (_cpp_builtin_macro_text): Add support for BT_FILE_NAME.

	gcc/
	* doc/cpp.texi (Common Predefined Macros): Document __FILE_NAME__.

	gcc/testsuite/
	* c-c++-common/spellcheck-reserved.c: Add tests for __FILE_NAME__.
	* c-c++-common/cpp/file-name-1.c: New test.
This commit is contained in:
Christophe Lyon 2021-05-20 08:10:50 +00:00
parent 9e0a5e3ea3
commit 1a9b3f04c1
6 changed files with 59 additions and 4 deletions

View File

@ -2005,6 +2005,13 @@ This macro expands to the name of the main input file, in the form
of a C string constant. This is the source file that was specified of a C string constant. This is the source file that was specified
on the command line of the preprocessor or C compiler. on the command line of the preprocessor or C compiler.
@item __FILE_NAME__
This macro expands to the basename of the current input file, in the
form of a C string constant. This is the last path component by which
the preprocessor opened the file. For example, processing
@code{"/usr/local/include/myheader.h"} would set this
macro to @code{"myheader.h"}.
@item __INCLUDE_LEVEL__ @item __INCLUDE_LEVEL__
This macro expands to a decimal integer constant that represents the This macro expands to a decimal integer constant that represents the
depth of nesting in include files. The value of this macro is depth of nesting in include files. The value of this macro is

View File

@ -0,0 +1,22 @@
/* { dg-do preprocess } */
/* { dg-additional-options -Wno-pedantic } */
main-1 __FILE_NAME__
# 7 "inner.h" 1
inner-1 __FILE_NAME__
# 9 "subdir/inside.h" 1
inside-1 __FILE_NAME__
inside-2 __FILE__
# 11 "" 2
inner-2 __FILE_NAME__
#13 "" 2
main-2 __FILE_NAME__
/* { dg-final { scan-file file-name-1.i "main-1 \"\[^\n]*file-name-1.c\"\n" } } */
/* { dg-final { scan-file file-name-1.i "main-2 \"\[^\n]*file-name-1.c\"\n" } } */
/* { dg-final { scan-file file-name-1.i "inner-1 \"inner.h\"\n" } } */
/* { dg-final { scan-file file-name-1.i "inner-2 \"inner.h\"\n" } } */
/* { dg-final { scan-file file-name-1.i "inside-1 \"inside.h\"\n" } } */
/* { dg-final { scan-file file-name-1.i "inside-2 \"subdir/inside.h\"\n" } } */

View File

@ -50,3 +50,21 @@ const char * test_3 (void)
/* { dg-error "did you mean '__FILE__'" "" { target c } misspelled__FILE_ } */ /* { dg-error "did you mean '__FILE__'" "" { target c } misspelled__FILE_ } */
/* { dg-error "'__FILE_' was not declared in this scope; did you mean '__FILE__'\\?" "" { target c++ } misspelled__FILE_ } */ /* { dg-error "'__FILE_' was not declared in this scope; did you mean '__FILE__'\\?" "" { target c++ } misspelled__FILE_ } */
} }
/* Verify that we can correct "__FILE_NAME_" to "__FILE_NAME__". */
const char * test_4 (void)
{
return __FILE_NAME_; /* { dg-line misspelled__FILE_NAME_ } */
/* { dg-error "did you mean '__FILE_NAME__'" "" { target c } misspelled__FILE_NAME_ } */
/* { dg-error "'__FILE_NAME_' was not declared in this scope; did you mean '__FILE_NAME__'\\?" "" { target c++ } misspelled__FILE_NAME_ } */
}
/* Verify that we can correct "__FILENAME__" to "__FILE_NAME__". */
const char * test_5 (void)
{
return __FILENAME__; /* { dg-line misspelled__FILENAME__ } */
/* { dg-error "did you mean '__FILE_NAME__'" "" { target c } misspelled__FILENAME__ } */
/* { dg-error "'__FILENAME__' was not declared in this scope; did you mean '__FILE_NAME__'\\?" "" { target c++ } misspelled__FILENAME__ } */
}

View File

@ -886,6 +886,7 @@ enum cpp_builtin_type
BT_SPECLINE = 0, /* `__LINE__' */ BT_SPECLINE = 0, /* `__LINE__' */
BT_DATE, /* `__DATE__' */ BT_DATE, /* `__DATE__' */
BT_FILE, /* `__FILE__' */ BT_FILE, /* `__FILE__' */
BT_FILE_NAME, /* `__FILE_NAME__' */
BT_BASE_FILE, /* `__BASE_FILE__' */ BT_BASE_FILE, /* `__BASE_FILE__' */
BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
BT_TIME, /* `__TIME__' */ BT_TIME, /* `__TIME__' */

View File

@ -405,6 +405,7 @@ static const struct builtin_macro builtin_array[] =
B("__TIME__", BT_TIME, false), B("__TIME__", BT_TIME, false),
B("__DATE__", BT_DATE, false), B("__DATE__", BT_DATE, false),
B("__FILE__", BT_FILE, false), B("__FILE__", BT_FILE, false),
B("__FILE_NAME__", BT_FILE_NAME, false),
B("__BASE_FILE__", BT_BASE_FILE, false), B("__BASE_FILE__", BT_BASE_FILE, false),
B("__LINE__", BT_SPECLINE, true), B("__LINE__", BT_SPECLINE, true),
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true), B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true),

View File

@ -531,15 +531,21 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
} }
break; break;
case BT_FILE: case BT_FILE:
case BT_FILE_NAME:
case BT_BASE_FILE: case BT_BASE_FILE:
{ {
unsigned int len; unsigned int len;
const char *name; const char *name;
uchar *buf; uchar *buf;
if (node->value.builtin == BT_FILE) if (node->value.builtin == BT_FILE
name = linemap_get_expansion_filename (pfile->line_table, || node->value.builtin == BT_FILE_NAME)
pfile->line_table->highest_line); {
name = linemap_get_expansion_filename (pfile->line_table,
pfile->line_table->highest_line);
if ((node->value.builtin == BT_FILE_NAME) && name)
name = lbasename (name);
}
else else
{ {
name = _cpp_get_file_name (pfile->main_file); name = _cpp_get_file_name (pfile->main_file);