diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3c1dd2183165..48e29839afe7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -577,6 +577,13 @@ def frewrite_includes : Flag<["-"], "frewrite-includes">, Group, Flags<[CC1Option]>; def fno_rewrite_includes : Flag<["-"], "fno-rewrite-includes">, Group; +def frewrite_map_file : Separate<["-"], "frewrite-map-file">, + Group, + Flags<[ DriverOption, CC1Option ]>; +def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">, + Group, + Flags<[DriverOption]>; + def ffreestanding : Flag<["-"], "ffreestanding">, Group, Flags<[CC1Option]>, HelpText<"Assert that the compilation takes place in a freestanding environment">; def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group, Flags<[CC1Option]>, diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 4e6171fbfe9e..19cc6c11c5a0 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -176,6 +176,9 @@ public: /// flag. std::shared_ptr OptimizationRemarkAnalysisPattern; + /// Set of files definining the rules for the symbol rewriting. + std::vector RewriteMapFiles; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 54215743f8ac..e1267192a742 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -39,6 +39,7 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/SymbolRewriter.h" #include using namespace clang; using namespace llvm; @@ -234,6 +235,17 @@ static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple, return TLI; } +static void addSymbolRewriterPass(const CodeGenOptions &Opts, + PassManager *MPM) { + llvm::SymbolRewriter::RewriteDescriptorList DL; + + llvm::SymbolRewriter::RewriteMapParser MapParser; + for (const auto &MapFile : Opts.RewriteMapFiles) + MapParser.parse(MapFile, &DL); + + MPM->add(createRewriteSymbolsPass(DL)); +} + void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); @@ -346,6 +358,8 @@ void EmitAssemblyHelper::CreatePasses() { // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); + if (!CodeGenOpts.RewriteMapFiles.empty()) + addSymbolRewriterPass(CodeGenOpts, MPM); if (CodeGenOpts.VerifyModule) MPM->add(createDebugInfoVerifierPass()); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index ef744d03b1a6..d625c0e3e2f6 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2781,6 +2781,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // LLVM Code Generator Options. + if (Args.hasArg(options::OPT_frewrite_map_file) || + Args.hasArg(options::OPT_frewrite_map_file_EQ)) { + for (arg_iterator + MFI = Args.filtered_begin(options::OPT_frewrite_map_file, + options::OPT_frewrite_map_file_EQ), + MFE = Args.filtered_end(); + MFI != MFE; ++MFI) { + CmdArgs.push_back("-frewrite-map-file"); + CmdArgs.push_back((*MFI)->getValue()); + (*MFI)->claim(); + } + } + if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) { StringRef v = A->getValue(); CmdArgs.push_back("-mllvm"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5b3442841399..d630b5bf5c4a 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -594,6 +594,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo) Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly); + Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file); + return Success; } diff --git a/clang/test/Driver/symbol-rewriter.c b/clang/test/Driver/symbol-rewriter.c new file mode 100644 index 000000000000..3cfdb9d09cd9 --- /dev/null +++ b/clang/test/Driver/symbol-rewriter.c @@ -0,0 +1,21 @@ +// RUN: %clang -frewrite-map-file %S/Inputs/rewrite.map -### %s 2>&1 | FileCheck %s -check-prefix CHECK-SINGLE + +// CHECK-SINGLE: "-frewrite-map-file" "{{.*[\\/]}}rewrite.map" + +// RUN: %clang -frewrite-map-file %S/Inputs/rewrite-1.map -frewrite-map-file %S/Inputs/rewrite-2.map -### %s 2>&1 | FileCheck %s -check-prefix CHECK-MULTIPLE + +// CHECK-MULTIPLE: "-frewrite-map-file" "{{.*[\\/]}}rewrite-1.map" "-frewrite-map-file" "{{.*[\\/]}}rewrite-2.map" + +// RUN: %clang -frewrite-map-file=%S/Inputs/rewrite.map -### %s 2>&1 | FileCheck %s -check-prefix CHECK-SINGLE-EQ + +// CHECK-SINGLE-EQ: "-frewrite-map-file" "{{.*[\\/]}}rewrite.map" + +// RUN: %clang -frewrite-map-file=%S/Inputs/rewrite-1.map -frewrite-map-file=%S/Inputs/rewrite-2.map -### %s 2>&1 | FileCheck %s -check-prefix CHECK-MULTIPLE-EQ + +// CHECK-MULTIPLE-EQ: "-frewrite-map-file" "{{.*[\\/]}}rewrite-1.map" +// CHECK-MULTIPLE-EQ: "-frewrite-map-file" "{{.*[\\/]}}rewrite-2.map" + +// RUN: %clang -frewrite-map-file %S/Inputs/rewrite-1.map -frewrite-map-file=%S/Inputs/rewrite-2.map -### %s 2>&1 | FileCheck %s -check-prefix CHECK-MIXED + +// CHECK-MIXED: "-frewrite-map-file" "{{.*[\\/]}}rewrite-1.map" "-frewrite-map-file" "{{.*[\\/]}}rewrite-2.map" +