This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH v3] Ability to remap file names in __FILE__, etc (PR other/70268)
Thanks for the review. Third revision of the patch attached.
Martin Sebor <msebor@gmail.com> writes:
> >>>+/* { dg-options "-ffile-prefix-map==FILE-PREFIX" } */
> >>
> >>What's up with this "=="? (as opposed to "=").
> >
> >Since I cannot predict the actual path, I am remapping empty prefix
> >to FILE-PREFIX which effectively adds FILE-PREFIX to any path.
>
> IIUC, it's the same as "-ffile-prefix-map=/=/FILE-PREFIX", correct?
It is (probably) correct in this particular case. More generally,
this won't hold if you are on a non-POSIX platform (C:\...) or
using relative paths.
> That seems useful to me, but I'm not sure it's as useful as it
> could or might need to be in some cases. E.g., if sources for
> nightly builds are downloaded into a temporary directory with some
> random name, this prepends a known prefix to the directory but it
> doesn't make the whole path-name determinate. Do you think it
> would it be useful to add support for globbing, as a separate
> enhancement?)
I believe the expected use for these options is that you know where
you are building and you want to strip the varying prefix and leave
the invariant. For example, if I unpacked gcc as /tmp/gcc/... then
for a path like /tmp/gcc/libcpp/macro.c I would want to strip
/tmp/gcc/ and not /tmp/gcc/libcpp/.
Which means that for the globbing idea to work you would need to
specify some kind of a 'stop anchor', e.g., '*/libcpp=libcpp' since
just '*/=/' will strip everything all the way to the file name.
So I would suggest that we wait for a clear need and a concrete
use case.
> >+ffile-prefix-map=
> >+Common Joined RejectNegative Var(common_deferred_options) Defer
>
> AFAIK, RejectNegative applies to options that take integer arguments.
> This one takes a string so it probably doesn't belong here.
Fixed.
> >+@item -fmacro-prefix-map=@var{old}=@var{new}
> >+@opindex fmacro-prefix-map
> >+When preprocessing files in directory @file{@var{old}}, expand the
> >+@code{__FILE__} and @code{__BASE_FILE__} macros as in @file{@var{new}}
> >+instead.
>
> This could be just me, but to my eyes this sentence can be read
> one of two ways: (1) files residing in directory old, or (2)
> the current working directory is old while preprocessing some
> files. To make it 100% clear which is meant, I would find it
> more accurate if it were phrased like this instead:
>
> When preprocessing files residing in directory @file{@var{old}},
> expand the @code{__FILE__} and @code{__BASE_FILE__} macros as if
> the files resided in directory @file{@var{new}} instead.
>
> Ditto for the other options.
Fixed.
libcpp/ChangeLog:
2017-12-09 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* include/cpplib.h (cpp_callbacks::remap_filename): New callback.
* libcpp/macro.c (_cpp_builtin_macro_text): Call remap_filename for
__FILE__ and __BASE_FILE__.
gcc/ChangeLog:
2017-12-09 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* common.opt: (-ffile-prefix-map): New option.
* opts.c (common_handle_option): Defer it.
* opts-global.c (handle_common_deferred_options): Handle it.
* debug.h (remap_debug_filename, add_debug_prefix_map): Move to...
* file-prefix-map.h: New file.
(remap_debug_filename, add_debug_prefix_map): ...here.
(add_macro_prefix_map, add_file_prefix_map, remap_macro_filename): New.
* final.c (debug_prefix_map, add_debug_prefix_map
remap_debug_filename): Move to...
* file-prefix-map.c: New file.
(file_prefix_map, add_prefix_map, remap_filename) ...here and rename,
generalize, get rid of alloca() call.
(add_macro_prefix_map, add_debug_prefix_map, add_file_prefix_map):
Implement in terms of add_prefix_map().
(remap_macro_filename, remap_debug_filename): Implement in term of
remap_filename().
* Makefile.in (OBJS, PLUGIN_HEADERS): Add new files.
* builtins.c (fold_builtin_FILE): Call remap_macro_filename().
* dbxout.c: Include file-prefix-map.h.
* varasm.c: Likewise.
* vmsdbgout.c: Likewise.
* xcoffout.c: Likewise.
* dwarf2out.c: Likewise plus omit new options from DW_AT_producer.
* doc/cppopts.texi (-fmacro-prefix-map): Document.
* doc/invoke.texi (-ffile-prefix-map): Document.
(-fdebug-prefix-map): Update description.
gcc/c-family/ChangeLog:
2017-12-09 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* c-family/c.opt (-fmacro-prefix-map): New option.
* c-family/c-opts.c (c_common_handle_option): Handle it.
* c-family/c-lex.c (init_c_lex): Set remap_filename cpp callback.
* c-family/c-ppoutput.c (init_pp_output): Likewise.
gcc/testsuite/ChangeLog:
2017-12-09 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* c-c++-common/ffile-prefix-map.c: New test.
* c-c++-common/fmacro-prefix-map.c: New test.
* c-c++-common/cpp/ffile-prefix-map.c: New test.
* c-c++-common/cpp/fmacro-prefix-map.c: New test.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6874f94e7f6..3237bf289df 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1284,6 +1284,7 @@ OBJS = \
expmed.o \
expr.o \
fibonacci_heap.o \
+ file-prefix-map.o \
final.o \
fixed-value.o \
fold-const.o \
@@ -3498,8 +3499,8 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
tree-ssa-loop-niter.h tree-ssa-ter.h tree-ssa-threadedge.h \
tree-ssa-threadupdate.h inchash.h wide-int.h signop.h hash-map.h \
hash-set.h dominance.h cfg.h cfgrtl.h cfganal.h cfgbuild.h cfgcleanup.h \
- lcm.h cfgloopmanip.h builtins.def chkp-builtins.def pass-instances.def \
- params.list
+ lcm.h cfgloopmanip.h file-prefix-map.h builtins.def chkp-builtins.def \
+ pass-instances.def params.list
# generate the 'build fragment' b-header-vars
s-header-vars: Makefile
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6b25253950c..65f5c43d770 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3. If not see
#include "case-cfn-macros.h"
#include "gimple-fold.h"
#include "intl.h"
+#include "file-prefix-map.h" /* remap_macro_filename() */
struct target_builtins default_target_builtins;
#if SWITCHABLE_TARGET
@@ -8776,7 +8777,13 @@ static inline tree
fold_builtin_FILE (location_t loc)
{
if (const char *fname = LOCATION_FILE (loc))
+ {
+ /* The documentation says this builtin is equivalent to the preprocessor
+ __FILE__ macro so it appears appropriate to use the same file prefix
+ mappings. */
+ fname = remap_macro_filename (fname);
return build_string_literal (strlen (fname) + 1, fname);
+ }
return build_string_literal (1, "");
}
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index 8342800303a..9d61abe545d 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h"
#include "c-pragma.h"
#include "debug.h"
+#include "file-prefix-map.h" /* remap_macro_filename() */
#include "attribs.h"
@@ -82,6 +83,7 @@ init_c_lex (void)
cb->has_attribute = c_common_has_attribute;
cb->get_source_date_epoch = cb_get_source_date_epoch;
cb->get_suggestion = cb_get_suggestion;
+ cb->remap_filename = remap_macro_filename;
/* Set the debug callbacks if we can use them. */
if ((debug_info_level == DINFO_LEVEL_VERBOSE
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index cead15e7a63..04b8c6cd40a 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "plugin.h" /* For PLUGIN_INCLUDE_FILE event. */
#include "mkdeps.h"
#include "dumpfile.h"
+#include "file-prefix-map.h" /* add_*_prefix_map() */
#ifndef DOLLARS_IN_IDENTIFIERS
# define DOLLARS_IN_IDENTIFIERS true
@@ -448,6 +449,10 @@ c_common_handle_option (size_t scode, const char *arg, int value,
cpp_opts->dollars_in_ident = value;
break;
+ case OPT_fmacro_prefix_map_:
+ add_macro_prefix_map (arg);
+ break;
+
case OPT_ffreestanding:
value = !value;
/* Fall through. */
diff --git a/gcc/c-family/c-ppoutput.c b/gcc/c-family/c-ppoutput.c
index d1c92379f62..949a4955923 100644
--- a/gcc/c-family/c-ppoutput.c
+++ b/gcc/c-family/c-ppoutput.c
@@ -22,6 +22,7 @@
#include "c-common.h" /* For flags. */
#include "../libcpp/internal.h"
#include "c-pragma.h" /* For parse_in. */
+#include "file-prefix-map.h" /* remap_macro_filename() */
/* Encapsulates state used to convert a stream of tokens into a text
file. */
@@ -151,6 +152,7 @@ init_pp_output (FILE *out_stream)
cb->has_attribute = c_common_has_attribute;
cb->get_source_date_epoch = cb_get_source_date_epoch;
+ cb->remap_filename = remap_macro_filename;
/* Initialize the print structure. */
print.src_line = 1;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b2548105736..36ec7fd79a3 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1386,6 +1386,10 @@ fdollars-in-identifiers
C ObjC C++ ObjC++
Permit '$' as an identifier character.
+fmacro-prefix-map=
+C ObjC C++ ObjC++ Joined
+-fmacro-prefix-map=<old>=<new> Map one directory name to another in __FILE__, __BASE_FILE__, and __builtin_FILE().
+
fdump-ada-spec
C ObjC C++ ObjC++ RejectNegative Var(flag_dump_ada_spec)
Write all declarations as Ada code transitively.
diff --git a/gcc/common.opt b/gcc/common.opt
index ffcbf850216..53dcc402e58 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1174,8 +1174,12 @@ Common RejectNegative Joined Var(common_deferred_options) Defer
-fdbg-cnt=<counter>:<limit>[,<counter>:<limit>,...] Set the debug counter limit.
fdebug-prefix-map=
-Common Joined RejectNegative Var(common_deferred_options) Defer
-Map one directory name to another in debug information.
+Common Joined Var(common_deferred_options) Defer
+-fdebug-prefix-map=<old>=<new> Map one directory name to another in debug information.
+
+ffile-prefix-map=
+Common Joined Var(common_deferred_options) Defer
+-ffile-prefix-map=<old>=<new> Map one directory name to another in compilation result.
fdebug-types-section
Common Report Var(flag_debug_types_section) Init(0)
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 290f11b3c46..fbb6a5df6c2 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -91,6 +91,7 @@ along with GCC; see the file COPYING3. If not see
#include "common/common-target.h"
#include "langhooks.h"
#include "expr.h"
+#include "file-prefix-map.h" /* remap_debug_filename() */
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
diff --git a/gcc/debug.h b/gcc/debug.h
index 277d990c20f..22fc7e7ab20 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -246,9 +246,6 @@ extern bool dwarf2out_do_frame (void);
extern bool dwarf2out_do_cfi_asm (void);
extern void dwarf2out_switch_text_section (void);
-const char *remap_debug_filename (const char *);
-void add_debug_prefix_map (const char *);
-
/* For -fdump-go-spec. */
extern const struct gcc_debug_hooks *
diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi
index 16bf22a6f38..7c162463050 100644
--- a/gcc/doc/cppopts.texi
+++ b/gcc/doc/cppopts.texi
@@ -287,6 +287,17 @@ When this option is given no argument, the default parameter value is
Note that @code{-ftrack-macro-expansion=2} is activated by default.
+@item -fmacro-prefix-map=@var{old}=@var{new}
+@opindex fmacro-prefix-map
+When preprocessing files residing in directory @file{@var{old}},
+expand the @code{__FILE__} and @code{__BASE_FILE__} macros as if the
+files resided in directory @file{@var{new}} instead. This can be used
+to change an absolute path to a relative path by using @file{.} for
+@var{new} which can result in more reproducible builds that are
+location independent. This option also affects
+@code{__builtin_FILE()} during compilation. See also
+@option{-ffile-prefix-map}.
+
@item -fexec-charset=@var{charset}
@opindex fexec-charset
@cindex character set, execution
@@ -534,4 +545,3 @@ token in the output is preceded by the dump of the map its location
belongs to.
When used from GCC without @option{-E}, this option has no effect.
-
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3487a62ab28..e84b03ac1f3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -172,7 +172,8 @@ in the following sections.
@gccoptlist{-c -S -E -o @var{file} -x @var{language} @gol
-v -### --help@r{[}=@var{class}@r{[},@dots{}@r{]]} --target-help --version @gol
-pass-exit-codes -pipe -specs=@var{file} -wrapper @gol
-@@@var{file} -fplugin=@var{file} -fplugin-arg-@var{name}=@var{arg} @gol
+@@@var{file} -ffile-prefix-map=@var{old}=@var{new} @gol
+-fplugin=@var{file} -fplugin-arg-@var{name}=@var{arg} @gol
-fdump-ada-spec@r{[}-slim@r{]} -fada-spec-parent=@var{unit} -fdump-go-spec=@var{file}}
@item C Language Options
@@ -480,9 +481,9 @@ Objective-C and Objective-C++ Dialects}.
-dD -dI -dM -dN -dU @gol
-fdebug-cpp -fdirectives-only -fdollars-in-identifiers @gol
-fexec-charset=@var{charset} -fextended-identifiers @gol
--finput-charset=@var{charset} -fno-canonical-system-headers @gol
--fpch-deps -fpch-preprocess -fpreprocessed @gol
--ftabstop=@var{width} -ftrack-macro-expansion @gol
+-finput-charset=@var{charset} -fmacro-prefix-map=@var{old}=@var{new} @gol
+-fno-canonical-system-headers @gol -fpch-deps -fpch-preprocess @gol
+-fpreprocessed -ftabstop=@var{width} -ftrack-macro-expansion @gol
-fwide-exec-charset=@var{charset} -fworking-directory @gol
-H -imacros @var{file} -include @var{file} @gol
-M -MD -MF -MG -MM -MMD -MP -MQ -MT @gol
@@ -1651,6 +1652,16 @@ This invokes all subprograms of @command{gcc} under
@samp{gdb --args}, thus the invocation of @command{cc1} is
@samp{gdb --args cc1 @dots{}}.
+@item -ffile-prefix-map=@var{old}=@var{new}
+@opindex ffile-prefix-map
+When compiling files residing in directory @file{@var{old}}, record
+any references to them in the result of the compilation as if the
+files resided in directory @file{@var{new}} instead. Specifying this
+option is equivalent to specifying all the individual
+@option{-f*-prefix-map} options. This can be used to make reproducible
+builds that are location independent. See also
+@option{-fmacro-prefix-map} and @option{-fdebug-prefix-map}.
+
@item -fplugin=@var{name}.so
@opindex fplugin
Load the plugin code in file @var{name}.so, assumed to be a
@@ -7054,13 +7065,14 @@ link processing time. Merging is enabled by default.
@item -fdebug-prefix-map=@var{old}=@var{new}
@opindex fdebug-prefix-map
-When compiling files in directory @file{@var{old}}, record debugging
-information describing them as in @file{@var{new}} instead. This can be
-used to replace a build-time path with an install-time path in the debug info.
-It can also be used to change an absolute path to a relative path by using
-@file{.} for @var{new}. This can give more reproducible builds, which are
-location independent, but may require an extra command to tell GDB where to
-find the source files.
+When compiling files residing in directory @file{@var{old}}, record
+debugging information describing them as if the files resided in
+directory @file{@var{new}} instead. This can be used to replace a
+build-time path with an install-time path in the debug info. It can
+also be used to change an absolute path to a relative path by using
+@file{.} for @var{new}. This can give more reproducible builds, which
+are location independent, but may require an extra command to tell GDB
+where to find the source files. See also @option{-ffile-prefix-map}.
@item -fvar-tracking
@opindex fvar-tracking
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index ae3d962526c..9d1297a087f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -94,6 +94,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtl-iter.h"
#include "stringpool.h"
#include "attribs.h"
+#include "file-prefix-map.h" /* remap_debug_filename() */
static void dwarf2out_source_line (unsigned int, unsigned int, const char *,
int, bool);
@@ -23417,6 +23418,8 @@ gen_producer_string (void)
case OPT_fltrans_output_list_:
case OPT_fresolution_:
case OPT_fdebug_prefix_map_:
+ case OPT_fmacro_prefix_map_:
+ case OPT_ffile_prefix_map_:
case OPT_fcompare_debug:
/* Ignore these. */
continue;
diff --git a/gcc/file-prefix-map.c b/gcc/file-prefix-map.c
new file mode 100644
index 00000000000..563546b8632
--- /dev/null
+++ b/gcc/file-prefix-map.c
@@ -0,0 +1,130 @@
+/* Implementation of file prefix remapping support (-f*-prefix-map options).
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic.h"
+#include "file-prefix-map.h"
+
+/* Structure recording the mapping from source file and directory names at
+ compile time to those to be embedded in the compilation result (debug
+ information, the __FILE__ macro expansion, etc). */
+struct file_prefix_map
+{
+ const char *old_prefix;
+ const char *new_prefix;
+ size_t old_len;
+ size_t new_len;
+ struct file_prefix_map *next;
+};
+
+/* Record a file prefix mapping in the specified map. ARG is the argument to
+ -f*-prefix-map and must be of the form OLD=NEW. OPT is the option name
+ for diagnostics. */
+static void
+add_prefix_map (file_prefix_map *&maps, const char *arg, const char *opt)
+{
+ file_prefix_map *map;
+ const char *p;
+
+ p = strchr (arg, '=');
+ if (!p)
+ {
+ error ("invalid argument %qs to %qs", arg, opt);
+ return;
+ }
+ map = XNEW (file_prefix_map);
+ map->old_prefix = xstrndup (arg, p - arg);
+ map->old_len = p - arg;
+ p++;
+ map->new_prefix = xstrdup (p);
+ map->new_len = strlen (p);
+ map->next = maps;
+ maps = map;
+}
+
+/* Perform user-specified mapping of filename prefixes. Return the
+ GC-allocated new name corresponding to FILENAME or FILENAME if no
+ remapping was performed. */
+
+static const char *
+remap_filename (file_prefix_map *maps, const char *filename)
+{
+ file_prefix_map *map;
+ char *s;
+ const char *name;
+ size_t name_len;
+
+ for (map = maps; map; map = map->next)
+ if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0)
+ break;
+ if (!map)
+ return filename;
+ name = filename + map->old_len;
+ name_len = strlen (name) + 1;
+
+ s = (char *) ggc_alloc_atomic (name_len + map->new_len);
+ memcpy (s, map->new_prefix, map->new_len);
+ memcpy (s + map->new_len, name, name_len);
+ return s;
+}
+
+/* NOTE: if adding another -f*-prefix-map option then don't forget to
+ ignore it in DW_AT_producer (dwarf2out.c). */
+
+/* Linked lists of file_prefix_map structures. */
+static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map */
+static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map */
+
+/* Record a file prefix mapping for -fmacro-prefix-map. */
+void
+add_macro_prefix_map (const char *arg)
+{
+ add_prefix_map (macro_prefix_maps, arg, "-fmacro-prefix-map");
+}
+
+/* Record a file prefix mapping for -fdebug-prefix-map. */
+void
+add_debug_prefix_map (const char *arg)
+{
+ add_prefix_map (debug_prefix_maps, arg, "-fdebug-prefix-map");
+}
+
+/* Record a file prefix mapping for all -f*-prefix-map. */
+void
+add_file_prefix_map (const char *arg)
+{
+ add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map");
+ add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map");
+}
+
+/* Remap using -fmacro-prefix-map. Return the GC-allocated new name
+ corresponding to FILENAME or FILENAME if no remapping was performed. */
+const char *
+remap_macro_filename (const char *filename)
+{
+ return remap_filename (macro_prefix_maps, filename);
+}
+
+/* Remap using -fdebug-prefix-map. Return the GC-allocated new name
+ corresponding to FILENAME or FILENAME if no remapping was performed. */
+const char *
+remap_debug_filename (const char *filename)
+{
+ return remap_filename (debug_prefix_maps, filename);
+}
diff --git a/gcc/file-prefix-map.h b/gcc/file-prefix-map.h
new file mode 100644
index 00000000000..3309eeed646
--- /dev/null
+++ b/gcc/file-prefix-map.h
@@ -0,0 +1,28 @@
+/* Declarations for file prefix remapping support (-f*-prefix-map options).
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_FILE_PREFIX_MAP_H
+#define GCC_FILE_PREFIX_MAP_H
+
+void add_macro_prefix_map (const char *);
+void add_debug_prefix_map (const char *);
+void add_file_prefix_map (const char *);
+
+const char *remap_macro_filename (const char *);
+const char *remap_debug_filename (const char *);
+
+#endif /* !GCC_FILE_PREFIX_MAP_H */
diff --git a/gcc/final.c b/gcc/final.c
index afb6906997d..c9bd26059f2 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1507,71 +1507,6 @@ asm_str_count (const char *templ)
return count;
}
-/* ??? This is probably the wrong place for these. */
-/* Structure recording the mapping from source file and directory
- names at compile time to those to be embedded in debug
- information. */
-struct debug_prefix_map
-{
- const char *old_prefix;
- const char *new_prefix;
- size_t old_len;
- size_t new_len;
- struct debug_prefix_map *next;
-};
-
-/* Linked list of such structures. */
-static debug_prefix_map *debug_prefix_maps;
-
-
-/* Record a debug file prefix mapping. ARG is the argument to
- -fdebug-prefix-map and must be of the form OLD=NEW. */
-
-void
-add_debug_prefix_map (const char *arg)
-{
- debug_prefix_map *map;
- const char *p;
-
- p = strchr (arg, '=');
- if (!p)
- {
- error ("invalid argument %qs to -fdebug-prefix-map", arg);
- return;
- }
- map = XNEW (debug_prefix_map);
- map->old_prefix = xstrndup (arg, p - arg);
- map->old_len = p - arg;
- p++;
- map->new_prefix = xstrdup (p);
- map->new_len = strlen (p);
- map->next = debug_prefix_maps;
- debug_prefix_maps = map;
-}
-
-/* Perform user-specified mapping of debug filename prefixes. Return
- the new name corresponding to FILENAME. */
-
-const char *
-remap_debug_filename (const char *filename)
-{
- debug_prefix_map *map;
- char *s;
- const char *name;
- size_t name_len;
-
- for (map = debug_prefix_maps; map; map = map->next)
- if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0)
- break;
- if (!map)
- return filename;
- name = filename + map->old_len;
- name_len = strlen (name) + 1;
- s = (char *) alloca (name_len + map->new_len);
- memcpy (s, map->new_prefix, map->new_len);
- memcpy (s + map->new_len, name, name_len);
- return ggc_strdup (s);
-}
/* Return true if DWARF2 debug info can be emitted for DECL. */
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 343dbd3ac2c..aadc2ef880b 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
+#include "file-prefix-map.h" /* add_*_prefix_map() */
typedef const char *const_char_p; /* For DEF_VEC_P. */
@@ -365,6 +366,10 @@ handle_common_deferred_options (void)
add_debug_prefix_map (opt->arg);
break;
+ case OPT_ffile_prefix_map_:
+ add_file_prefix_map (opt->arg);
+ break;
+
case OPT_fdump_:
if (!g->get_dumps ()->dump_switch_p (opt->arg))
error ("unrecognized command line option %<-fdump-%s%>", opt->arg);
diff --git a/gcc/opts.c b/gcc/opts.c
index 17579e72373..8c8ad3e06a5 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2091,6 +2091,7 @@ common_handle_option (struct gcc_options *opts,
break;
case OPT_fdebug_prefix_map_:
+ case OPT_ffile_prefix_map_:
/* Deferred. */
break;
diff --git a/gcc/testsuite/c-c++-common/cpp/ffile-prefix-map.c b/gcc/testsuite/c-c++-common/cpp/ffile-prefix-map.c
new file mode 100644
index 00000000000..294875b717d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/ffile-prefix-map.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-ffile-prefix-map==FILE-PREFIX" } */
+
+#pragma message "FILE starts with " __FILE__ /* { dg-message "FILE starts with FILE-PREFIX" } */
+#pragma message "BASE_FILE starts with " __BASE_FILE__ /* { dg-message "BASE_FILE starts with FILE-PREFIX" } */
diff --git a/gcc/testsuite/c-c++-common/cpp/fmacro-prefix-map.c b/gcc/testsuite/c-c++-common/cpp/fmacro-prefix-map.c
new file mode 100644
index 00000000000..43dc4bb287e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/fmacro-prefix-map.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fmacro-prefix-map==MACRO-PREFIX" } */
+
+#pragma message "FILE starts with " __FILE__ /* { dg-message "FILE starts with MACRO-PREFIX" } */
+#pragma message "BASE_FILE starts with " __BASE_FILE__ /* { dg-message "BASE_FILE starts with MACRO-PREFIX" } */
diff --git a/gcc/testsuite/c-c++-common/ffile-prefix-map.c b/gcc/testsuite/c-c++-common/ffile-prefix-map.c
new file mode 100644
index 00000000000..88c29ca829b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ffile-prefix-map.c
@@ -0,0 +1,12 @@
+/* Test __builtin_FILE(). */
+/* { dg-do run } */
+/* { dg-options "-ffile-prefix-map==FILE-PREFIX" } */
+
+#include <stdio.h>
+
+int main ()
+{
+ printf ("__builtin_FILE starts with %s\n", __builtin_FILE ());
+}
+
+/* { dg-output "__builtin_FILE starts with FILE-PREFIX" } */
diff --git a/gcc/testsuite/c-c++-common/fmacro-prefix-map.c b/gcc/testsuite/c-c++-common/fmacro-prefix-map.c
new file mode 100644
index 00000000000..db51587cb4f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fmacro-prefix-map.c
@@ -0,0 +1,12 @@
+/* Test __builtin_FILE(). */
+/* { dg-do run } */
+/* { dg-options "-fmacro-prefix-map==MACRO-PREFIX" } */
+
+#include <stdio.h>
+
+int main ()
+{
+ printf ("__builtin_FILE starts with %s\n", __builtin_FILE ());
+}
+
+/* { dg-output "__builtin_FILE starts with MACRO-PREFIX" } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 392ac443f14..34d225a96cb 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "asan.h"
#include "rtl-iter.h"
+#include "file-prefix-map.h" /* remap_debug_filename() */
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data declarations. */
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 91dcd2e3910..908ab9aa849 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "function.h"
#include "target.h"
+#include "file-prefix-map.h" /* remap_debug_filename() */
/* Difference in seconds between the VMS Epoch and the Unix Epoch */
static const long long vms_epoch_offset = 3506716800ll;
diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c
index cf2064d5ba5..afda2f83e82 100644
--- a/gcc/xcoffout.c
+++ b/gcc/xcoffout.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "output.h"
#include "debug.h"
+#include "file-prefix-map.h" /* remap_debug_filename() */
#ifdef XCOFF_DEBUGGING_INFO
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 4d04a48a0e4..a4e8ac6f8d3 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -622,6 +622,10 @@ struct cpp_callbacks
C++-style comments it does not include the terminating newline. */
void (*comment) (cpp_reader *, source_location, const unsigned char *,
size_t);
+
+ /* Callback for filename remapping in __FILE__ and __BASE_FILE__ macro
+ expansions. */
+ const char *(*remap_filename) (const char*);
};
#ifdef VMS
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 791817af8db..46407b6425e 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -450,6 +450,8 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
if (!name)
abort ();
}
+ if (pfile->cb.remap_filename)
+ name = pfile->cb.remap_filename (name);
len = strlen (name);
buf = _cpp_unaligned_alloc (pfile, len * 2 + 3);
result = buf;