diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -89,6 +89,7 @@ enum class PrintingMode { AlwaysQuote, QuoteIfNeeded, + Verbatim, }; Command(const Action &Source, const Tool &Creator, const char *Executable, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -330,6 +330,10 @@ def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>, HelpText<"Print (but do not run) the commands to run for this compilation">; +def _HASH_HASH_HASH_VERBATIM : Flag<["-"], "###-verbatim">, + Flags<[DriverOption, CoreOption]>, + HelpText<"Print (but do not run) the commands to run for this compilation, " + "unquoted and unescaped">; def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>, Flags<[DriverOption, CoreOption]>; def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>, Group; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1451,6 +1451,12 @@ return 0; } + // Just print verbatim if -###-verbatim was present. + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM)) { + C.getJobs().Print(llvm::outs(), "\n", Command::PrintingMode::Verbatim); + return 0; + } + // If there were errors building the compilation, quit now. if (Diags.hasErrorOccurred()) return 1; @@ -1682,6 +1688,11 @@ SuppressMissingInputWarning = true; } + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM)) { + PrintVersion(C, llvm::outs()); + SuppressMissingInputWarning = true; + } + if (C.getArgs().hasArg(options::OPT_v)) { if (!SystemConfigDir.empty()) llvm::errs() << "System configuration file directory: " @@ -3565,8 +3576,9 @@ C.getArgs().hasArg(options::OPT_Qunused_arguments)) return; - // Claim -### here. + // Claim -### and -###-verbatim here. (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH); + (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM); // Claim --driver-mode, --rsp-quoting, it was handled earlier. (void)C.getArgs().hasArg(options::OPT_driver_mode); diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -101,7 +101,8 @@ void Command::printArg(raw_ostream &OS, StringRef Arg, PrintingMode Mode) { const bool Escape = Arg.find_first_of(" \"\\$") != StringRef::npos; - if (Mode == PrintingMode::QuoteIfNeeded && !Escape) { + if (Mode == PrintingMode::Verbatim || + (Mode == PrintingMode::QuoteIfNeeded && !Escape)) { OS << Arg; return; } @@ -213,9 +214,11 @@ void Command::Print(raw_ostream &OS, const char *Terminator, PrintingMode Mode, CrashReportInfo *CrashInfo) const { - // Always quote the exe. + // Always quote the exe unless printing verbatim. OS << ' '; - printArg(OS, Executable, PrintingMode::AlwaysQuote); + printArg(OS, Executable, + Mode == PrintingMode::Verbatim ? PrintingMode::Verbatim + : PrintingMode::AlwaysQuote); ArrayRef Args = Arguments; SmallVector ArgsRespFile; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1994,7 +1994,8 @@ StringRef Target, const InputInfo &Output, const InputInfo &Input, const ArgList &Args) const { // If this is a dry run, do not create the compilation database file. - if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || + C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM)) return; using llvm::yaml::escape; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1345,7 +1345,8 @@ llvm::errs() << LksBuffer; // If this is a dry run, do not create the linker script file. - if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || + C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM)) return; // Open script file and write the contents. @@ -1453,7 +1454,8 @@ llvm::errs() << LksBuffer; // If this is a dry run, do not create the linker script file. - if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || + C.getArgs().hasArg(options::OPT__HASH_HASH_HASH_VERBATIM)) return; // Open script file and write the contents. diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp --- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -61,6 +61,13 @@ return nullptr; } + // Just print the cc1 options verbatim if -###-verbatim was present. + if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH_VERBATIM)) { + C->getJobs().Print(llvm::errs(), "\n", + driver::Command::PrintingMode::Verbatim); + return nullptr; + } + // We expect to get back exactly one command job, if we didn't something // failed. Offload compilation is an exception as it creates multiple jobs. If // that's the case, we proceed with the first job. If caller needs a