Forward ported from attachment to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47047 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -574,6 +574,10 @@ c_common_handle_option (size_t scode, co add_path (xstrdup (arg), SYSTEM, 0, true); break; + case OPT_iremap: + add_cpp_remap_path (arg); + break; + case OPT_iwithprefix: add_prefixed_path (arg, SYSTEM); break; --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1632,6 +1632,10 @@ iquote C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) -iquote Add to the end of the quote include path. +iremap +C ObjC C++ ObjC++ Joined Separate +-iremap Convert to if it occurs as prefix in __FILE__. + iwithprefix C ObjC C++ ObjC++ Joined Separate -iwithprefix Add to the end of the system include path. --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -4444,6 +4444,7 @@ without notice. @c man begin SYNOPSIS cpp [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}] [@option{-I}@var{dir}@dots{}] [@option{-iquote}@var{dir}@dots{}] + [@option{-iremap}@var{src}:@var{dst}] [@option{-W}@var{warn}@dots{}] [@option{-M}|@option{-MM}] [@option{-MG}] [@option{-MF} @var{filename}] [@option{-MP}] [@option{-MQ} @var{target}@dots{}] --- a/gcc/doc/cppopts.texi +++ b/gcc/doc/cppopts.texi @@ -532,6 +532,12 @@ Search @var{dir} only for header files r If @var{dir} begins with @code{=}, then the @code{=} will be replaced by the sysroot prefix; see @option{--sysroot} and @option{-isysroot}. +@item -iremap @var{src}:@var{dst} +@opindex iremap +Replace the prefix @var{src} in __FILE__ with @var{dst} at expansion time. +This option can be specified more than once. Processing stops at the first +match. + @item -fdirectives-only @opindex fdirectives-only When preprocessing, handle directives, but do not expand macros. --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -476,8 +476,8 @@ Objective-C and Objective-C++ Dialects}. @item Directory Options @xref{Directory Options,,Options for Directory Search}. @gccoptlist{-B@var{prefix} -I@var{dir} -iplugindir=@var{dir} @gol --iquote@var{dir} -L@var{dir} -no-canonical-prefixes -I- @gol ---sysroot=@var{dir} --no-sysroot-suffix} +-iquote@var{dir} -iremap@var{src}:@var{dst} -L@var{dir} -no-canonical-prefixes @gol +-I- --sysroot=@var{dir} --no-sysroot-suffix} @item Code Generation Options @xref{Code Gen Options,,Options for Code Generation Conventions}. @@ -10861,6 +10861,12 @@ be searched for header files only for th "@var{file}"}; they are not searched for @code{#include <@var{file}>}, otherwise just like @option{-I}. +@item -iremap @var{src}:@var{dst} +@opindex iremap +Replace the prefix @var{src} in __FILE__ with @var{dst} at expansion time. +This option can be specified more than once. Processing stops at the first +match. + @item -L@var{dir} @opindex L Add directory @var{dir} to the list of directories to be searched --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -760,6 +760,9 @@ extern void cpp_set_lang (cpp_reader *, /* Set the include paths. */ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); +/* Provide src:dst pair for __FILE__ remapping. */ +extern void add_cpp_remap_path (const char *); + /* Call these to get pointers to the options, callback, and deps structures for a given reader. These pointers are good until you call cpp_finish on that reader. You can either edit the callbacks --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -227,6 +227,64 @@ static const char * const monthnames[] = "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static size_t remap_pairs; +static char **remap_src; +static char **remap_dst; + +void +add_cpp_remap_path (const char *arg) +{ + const char *arg_dst; + size_t len; + + arg_dst = strchr(arg, ':'); + if (arg_dst == NULL) + { + fprintf(stderr, "Invalid argument for -iremap\n"); + exit(1); + } + + len = arg_dst - arg; + ++arg_dst; + + remap_src = (char **) xrealloc(remap_src, sizeof(char *) * (remap_pairs + 1)); + remap_dst = (char **) xrealloc(remap_dst, sizeof(char *) * (remap_pairs + 1)); + + remap_src[remap_pairs] = (char *) xmalloc(len + 1); + memcpy(remap_src[remap_pairs], arg, len); + remap_src[remap_pairs][len] = '\0'; + remap_dst[remap_pairs] = xstrdup(arg_dst); + ++remap_pairs; +} + +static const char * +cpp_remap_file (const char *arg, char **tmp_name) +{ + char *result; + size_t i, len; + + for (i = 0; i < remap_pairs; ++i) + { + len = strlen (remap_src[i]); + if (strncmp (remap_src[i], arg, len)) + continue; + if (arg[len] == '\0') + return xstrdup (remap_dst[i]); + if (arg[len] != '/') + continue; + arg += len; + len = strlen (remap_dst[i]); + result = (char *) xmalloc (len + strlen (arg) + 1); + memcpy(result, remap_dst[i], len); + strcpy(result + len, arg); + *tmp_name = result; + + return result; + } + + return arg; +} + /* Helper function for builtin_macro. Returns the text generated by a builtin macro. */ const uchar * @@ -290,6 +348,7 @@ _cpp_builtin_macro_text (cpp_reader *pfi { unsigned int len; const char *name; + char *tmp_name = NULL; uchar *buf; if (node->value.builtin == BT_FILE) @@ -301,6 +360,7 @@ _cpp_builtin_macro_text (cpp_reader *pfi if (!name) abort (); } + name = cpp_remap_file (name, &tmp_name); len = strlen (name); buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); result = buf; @@ -308,6 +368,7 @@ _cpp_builtin_macro_text (cpp_reader *pfi buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); *buf++ = '"'; *buf = '\0'; + free (tmp_name); } break;