Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1246,6 +1246,9 @@ Flag <["-"], "fno-implicit-modules">, Group, Flags<[DriverOption, CC1Option]>; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group, Flags<[CC1Option]>; +def ffile_macro_prefix_to_remove : Joined<["-"], "ffile-macro-prefix-to-remove=">, + Group, Flags<[DriverOption, CC1Option]>, + HelpText<"prefix to be removed from expanded string of __FILE__ macro">; def fmudflapth : Flag<["-"], "fmudflapth">, Group; def fmudflap : Flag<["-"], "fmudflap">, Group; Index: include/clang/Lex/PreprocessorOptions.h =================================================================== --- include/clang/Lex/PreprocessorOptions.h +++ include/clang/Lex/PreprocessorOptions.h @@ -127,12 +127,16 @@ /// manipulation of the compiler invocation object, in cases where the /// compiler invocation and its buffers will be reused. bool RetainRemappedFileBuffers = false; - + /// \brief The Objective-C++ ARC standard library that we should support, /// by providing appropriate definitions to retrofit the standard library /// with support for lifetime-qualified pointers. ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib; - + + /// \brief This string will be used in expanding __FILE__ macro. If it + /// matches the prefix of __FILE__, the matched part won't be expanded. + std::string FileMacroPrefixToRemove; + /// \brief Records the set of modules class FailedModulesSet { llvm::StringSet<> Failed; Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1264,6 +1264,15 @@ // For IAMCU add special include arguments. getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs); } + + // Add FILE macro prefix removing arguments or basename only flags. + if (const Arg *A = + Args.getLastArg(options::OPT_ffile_macro_prefix_to_remove)) { + StringRef PrefixToRemove(A->getValue()); + if (!PrefixToRemove.empty()) + CmdArgs.push_back(Args.MakeArgString("-ffile-macro-prefix-to-remove=" + + PrefixToRemove)); + } } // FIXME: Move to target hook. Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2826,6 +2826,10 @@ Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library; } + if (Arg *A = Args.getLastArg(OPT_ffile_macro_prefix_to_remove)) { + Opts.FileMacroPrefixToRemove = A->getValue(); + } + // Always avoid lexing editor placeholders when we're just running the // preprocessor as we never want to emit the // "editor placeholder in source file" error in PP only mode. Index: lib/Lex/PPMacroExpansion.cpp =================================================================== --- lib/Lex/PPMacroExpansion.cpp +++ lib/Lex/PPMacroExpansion.cpp @@ -26,9 +26,10 @@ #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/MacroArgs.h" #include "clang/Lex/MacroInfo.h" +#include "clang/Lex/PTHLexer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorLexer.h" -#include "clang/Lex/PTHLexer.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -36,15 +37,16 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1717,7 +1719,16 @@ // Escape this filename. Turn '\' -> '\\' '"' -> '\"' SmallString<128> FN; if (PLoc.isValid()) { - FN += PLoc.getFilename(); + StringRef Filename = PLoc.getFilename(); + if (II == Ident__FILE__) { + const std::string &PrefixToRemove = + getPreprocessorOpts().FileMacroPrefixToRemove; + if (Filename.startswith(PrefixToRemove)) + FN += Filename.substr(PrefixToRemove.size()); + else + FN += Filename; + } else + FN += Filename; Lexer::Stringify(FN); OS << '"' << FN << '"'; }