From 56f433b3d9fb18a634c51366d0b18b5025e19260 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 16 Jan 2020 14:03:38 -0500 Subject: [PATCH] update clang drivers to llvm 10.x (ac446302c) --- src/zig_clang_cc1_main.cpp | 46 +++++++++++++----------------- src/zig_clang_cc1as_main.cpp | 28 +++++++++++------- src/zig_clang_driver.cpp | 55 ++++++++++++++++++++++++++++-------- 3 files changed, 82 insertions(+), 47 deletions(-) diff --git a/src/zig_clang_cc1_main.cpp b/src/zig_clang_cc1_main.cpp index d3515aa070..0b245be591 100644 --- a/src/zig_clang_cc1_main.cpp +++ b/src/zig_clang_cc1_main.cpp @@ -12,11 +12,6 @@ // //===----------------------------------------------------------------------===// -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winit-list-lifetime" -#endif - #include "clang/Basic/Stack.h" #include "clang/Basic/TargetOptions.h" #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" @@ -207,12 +202,13 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); - bool Success = CompilerInvocation::CreateFromArgs( - Clang->getInvocation(), Argv, Diags); - - if (Clang->getFrontendOpts().TimeTrace) - llvm::timeTraceProfilerInitialize(/* granularity (us) */ 500); + bool Success = + CompilerInvocation::CreateFromArgs(Clang->getInvocation(), Argv, Diags); + if (Clang->getFrontendOpts().TimeTrace) { + llvm::timeTraceProfilerInitialize( + Clang->getFrontendOpts().TimeTraceGranularity, Argv0); + } // --print-supported-cpus takes priority over the actual compilation. if (Clang->getFrontendOpts().PrintSupportedCPUs) return PrintSupportedCPUs(Clang->getTargetOpts().Triple); @@ -239,33 +235,30 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { // Execute the frontend actions. { - llvm::TimeTraceScope TimeScope("ExecuteCompiler", StringRef("")); + llvm::TimeTraceScope TimeScope("ExecuteCompiler"); Success = ExecuteCompilerInvocation(Clang.get()); } // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. llvm::TimerGroup::printAll(llvm::errs()); + llvm::TimerGroup::clearAll(); if (llvm::timeTraceProfilerEnabled()) { SmallString<128> Path(Clang->getFrontendOpts().OutputFile); llvm::sys::path::replace_extension(Path, "json"); - auto profilerOutput = - Clang->createOutputFile(Path.str(), - /*Binary=*/false, - /*RemoveFileOnSignal=*/false, "", - /*Extension=*/"json", - /*useTemporary=*/false); + if (auto profilerOutput = + Clang->createOutputFile(Path.str(), + /*Binary=*/false, + /*RemoveFileOnSignal=*/false, "", + /*Extension=*/"json", + /*useTemporary=*/false)) { - llvm::timeTraceProfilerWrite(*profilerOutput); - // FIXME(ibiryukov): make profilerOutput flush in destructor instead. - profilerOutput->flush(); - llvm::timeTraceProfilerCleanup(); - - llvm::errs() << "Time trace json-file dumped to " << Path.str() << "\n"; - llvm::errs() - << "Use chrome://tracing or Speedscope App " - "(https://www.speedscope.app) for flamegraph visualization\n"; + llvm::timeTraceProfilerWrite(*profilerOutput); + // FIXME(ibiryukov): make profilerOutput flush in destructor instead. + profilerOutput->flush(); + llvm::timeTraceProfilerCleanup(); + } } // Our error handler depends on the Diagnostics object, which we're @@ -281,3 +274,4 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { return !Success; } + diff --git a/src/zig_clang_cc1as_main.cpp b/src/zig_clang_cc1as_main.cpp index 08c094871d..f810c62a88 100644 --- a/src/zig_clang_cc1as_main.cpp +++ b/src/zig_clang_cc1as_main.cpp @@ -131,6 +131,7 @@ struct AssemblerInvocation { unsigned RelaxAll : 1; unsigned NoExecStack : 1; unsigned FatalWarnings : 1; + unsigned NoWarn : 1; unsigned IncrementalLinkerCompatible : 1; unsigned EmbedBitcode : 1; @@ -156,6 +157,7 @@ public: RelaxAll = 0; NoExecStack = 0; FatalWarnings = 0; + NoWarn = 0; IncrementalLinkerCompatible = 0; DwarfVersion = 0; EmbedBitcode = 0; @@ -179,7 +181,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, const unsigned IncludedFlagsBitmask = options::CC1AsOption; unsigned MissingArgIndex, MissingArgCount; InputArgList Args = OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount, - IncludedFlagsBitmask); + IncludedFlagsBitmask); // Check for missing argument error. if (MissingArgCount) { @@ -285,6 +287,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, Opts.RelaxAll = Args.hasArg(OPT_mrelax_all); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); + Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn); Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); Opts.TargetABI = Args.getLastArgValue(OPT_target_abi); Opts.IncrementalLinkerCompatible = @@ -313,7 +316,7 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) { std::error_code EC; auto Out = std::make_unique( - Path, EC, (Binary ? sys::fs::F_None : sys::fs::F_Text)); + Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_Text)); if (EC) { Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message(); return nullptr; @@ -350,7 +353,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, std::unique_ptr MRI(TheTarget->createMCRegInfo(Opts.Triple)); assert(MRI && "Unable to create target register info!"); - std::unique_ptr MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple)); + MCTargetOptions MCOptions; + std::unique_ptr MAI( + TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions)); assert(MAI && "Unable to create target asm info!"); // Ensure MCAsmInfo initialization occurs before any use, otherwise sections @@ -374,7 +379,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, // MCObjectFileInfo needs a MCContext reference in order to initialize itself. std::unique_ptr MOFI(new MCObjectFileInfo()); - MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); + MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr, &MCOptions); bool PIC = false; if (Opts.RelocationModel == "static") { @@ -431,7 +436,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, raw_pwrite_stream *Out = FDOS.get(); std::unique_ptr BOS; - MCTargetOptions MCOptions; + MCOptions.MCNoWarn = Opts.NoWarn; + MCOptions.MCFatalWarnings = Opts.FatalWarnings; MCOptions.ABIName = Opts.TargetABI; // FIXME: There is a bit of code duplication with addPassesToEmitFile. @@ -569,11 +575,11 @@ int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { return 1; if (Asm.ShowHelp) { - const OptTable &Opts = getDriverOptTable(); - Opts.PrintHelp(llvm::outs(), "clang -cc1as [options] file...", - "Clang Integrated Assembler", - /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, - /*ShowAllAliases=*/false); + getDriverOptTable().PrintHelp( + llvm::outs(), "clang -cc1as [options] file...", + "Clang Integrated Assembler", + /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, + /*ShowAllAliases=*/false); return 0; } @@ -604,6 +610,8 @@ int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { // If any timers were active but haven't been destroyed yet, print their // results now. TimerGroup::printAll(errs()); + TimerGroup::clearAll(); return !!Failed; } + diff --git a/src/zig_clang_driver.cpp b/src/zig_clang_driver.cpp index 79e3a34126..8b3afdb1d4 100644 --- a/src/zig_clang_driver.cpp +++ b/src/zig_clang_driver.cpp @@ -13,6 +13,8 @@ #include "clang/Driver/Driver.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/Stack.h" +#include "clang/Config/config.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" @@ -29,6 +31,7 @@ #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -236,6 +239,8 @@ static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver, *NumberSignPtr = '='; } +static int ExecuteCC1Tool(ArrayRef argv); + static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) { // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); @@ -266,16 +271,21 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient, // This lets us create the DiagnosticsEngine with a properly-filled-out // DiagnosticOptions instance. static DiagnosticOptions * -CreateAndPopulateDiagOpts(ArrayRef argv) { +CreateAndPopulateDiagOpts(ArrayRef argv, bool &UseNewCC1Process) { auto *DiagOpts = new DiagnosticOptions; - const OptTable &Opts = getDriverOptTable(); unsigned MissingArgIndex, MissingArgCount; - InputArgList Args = - Opts.ParseArgs(argv.slice(1), MissingArgIndex, MissingArgCount); + InputArgList Args = getDriverOptTable().ParseArgs( + argv.slice(1), MissingArgIndex, MissingArgCount); // We ignore MissingArgCount and the return value of ParseDiagnosticArgs. // Any errors that would be diagnosed here will also be diagnosed later, // when the DiagnosticsEngine actually exists. (void)ParseDiagnosticArgs(*DiagOpts, Args); + + UseNewCC1Process = + Args.hasFlag(clang::driver::options::OPT_fno_integrated_cc1, + clang::driver::options::OPT_fintegrated_cc1, + /*Default=*/CLANG_SPAWN_CC1); + return DiagOpts; } @@ -301,11 +311,17 @@ static void SetInstallDir(SmallVectorImpl &argv, TheDriver.setInstalledDir(InstalledPathParent); } -static int ExecuteCC1Tool(ArrayRef argv, StringRef Tool) { +static int ExecuteCC1Tool(ArrayRef argv) { + // If we call the cc1 tool from the clangDriver library (through + // Driver::CC1Main), we need to clean up the options usage count. The options + // are currently global, and they might have been used previously by the + // driver. + llvm::cl::ResetAllOptionOccurrences(); + StringRef Tool = argv[1]; void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath; - if (Tool == "") + if (Tool == "-cc1") return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP); - if (Tool == "as") + if (Tool == "-cc1as") return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP); // Reject unknown tools. @@ -316,6 +332,7 @@ static int ExecuteCC1Tool(ArrayRef argv, StringRef Tool) { extern "C" int ZigClang_main(int argc_, const char **argv_); int ZigClang_main(int argc_, const char **argv_) { + noteBottomOfStack(); llvm::InitLLVM X(argc_, argv_); size_t argv_offset = (strcmp(argv_[1], "-cc1") == 0 || strcmp(argv_[1], "-cc1as") == 0) ? 0 : 1; SmallVector argv(argv_ + argv_offset, argv_ + argc_); @@ -376,9 +393,11 @@ int ZigClang_main(int argc_, const char **argv_) { auto newEnd = std::remove(argv.begin(), argv.end(), nullptr); argv.resize(newEnd - argv.begin()); } - return ExecuteCC1Tool(argv, argv[1] + 4); + return ExecuteCC1Tool(argv); } + // Handle options that need handling before the real command line parsing in + // Driver::BuildCompilation() bool CanonicalPrefixes = true; for (int i = 1, size = argv.size(); i < size; ++i) { // Skip end-of-line response file markers @@ -421,10 +440,16 @@ int ZigClang_main(int argc_, const char **argv_) { ApplyQAOverride(argv, OverrideStr, SavedStrings); } - std::string Path = GetExecutablePath(argv_[0], CanonicalPrefixes); + std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes); + + // Whether the cc1 tool should be called inside the current process, or if we + // should spawn a new clang subprocess (old behavior). + // Not having an additional process saves some execution time of Windows, + // and makes debugging and profiling easier. + bool UseNewCC1Process; IntrusiveRefCntPtr DiagOpts = - CreateAndPopulateDiagOpts(argv); + CreateAndPopulateDiagOpts(argv, UseNewCC1Process); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); @@ -452,6 +477,12 @@ int ZigClang_main(int argc_, const char **argv_) { SetBackdoorDriverOutputsFromEnvVars(TheDriver); + if (!UseNewCC1Process) { + TheDriver.CC1Main = &ExecuteCC1Tool; + // Ensure the CC1Command actually catches cc1 crashes + llvm::CrashRecoveryContext::Enable(); + } + std::unique_ptr C(TheDriver.BuildCompilation(argv)); int Res = 1; if (C && !C->containsError()) { @@ -496,10 +527,11 @@ int ZigClang_main(int argc_, const char **argv_) { // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. llvm::TimerGroup::printAll(llvm::errs()); + llvm::TimerGroup::clearAll(); #ifdef _WIN32 // Exit status should not be negative on Win32, unless abnormal termination. - // Once abnormal termiation was caught, negative status should not be + // Once abnormal termination was caught, negative status should not be // propagated. if (Res < 0) Res = 1; @@ -509,3 +541,4 @@ int ZigClang_main(int argc_, const char **argv_) { // failing command. return Res; } +