diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/Driver.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Driver.cpp | 155 |
1 files changed, 84 insertions, 71 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp index 1664d0d..8cca1de 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp @@ -17,6 +17,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Job.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/ADT/ArrayRef.h" @@ -44,21 +45,19 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; -Driver::Driver(StringRef ClangExecutable, - StringRef DefaultTargetTriple, +Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, DiagnosticsEngine &Diags) - : Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode), - ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), - UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple), - DriverTitle("clang LLVM compiler"), - CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr), - CCLogDiagnosticsFilename(nullptr), - CCCPrintBindings(false), - CCPrintHeaders(false), CCLogDiagnostics(false), - CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true), - CCCUsePCH(true), SuppressMissingInputWarning(false) { - - Name = llvm::sys::path::stem(ClangExecutable); + : Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode), + SaveTemps(SaveTempsNone), ClangExecutable(ClangExecutable), + SysRoot(DEFAULT_SYSROOT), UseStdLib(true), + DefaultTargetTriple(DefaultTargetTriple), + DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr), + CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr), + CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false), + CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true), + CCCUsePCH(true), SuppressMissingInputWarning(false) { + + Name = llvm::sys::path::filename(ClangExecutable); Dir = llvm::sys::path::parent_path(ClangExecutable); // Compute the path to the resource directory. @@ -141,10 +140,8 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { } } - for (arg_iterator it = Args->filtered_begin(options::OPT_UNKNOWN), - ie = Args->filtered_end(); it != ie; ++it) { - Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args); - } + for (const Arg *A : Args->filtered(options::OPT_UNKNOWN)) + Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args); return Args; } @@ -348,9 +345,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { DefaultTargetTriple = A->getValue(); if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir)) Dir = InstalledDir = A->getValue(); - for (arg_iterator it = Args->filtered_begin(options::OPT_B), - ie = Args->filtered_end(); it != ie; ++it) { - const Arg *A = *it; + for (const Arg *A : Args->filtered(options::OPT_B)) { A->claim(); PrefixDirs.push_back(A->getValue(0)); } @@ -364,6 +359,13 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { if (const Arg *A = Args->getLastArg(options::OPT_resource_dir)) ResourceDir = A->getValue(); + if (const Arg *A = Args->getLastArg(options::OPT_save_temps_EQ)) { + SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue()) + .Case("cwd", SaveTempsCwd) + .Case("obj", SaveTempsObj) + .Default(SaveTempsCwd); + } + // Perform the default argument translations. DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args); @@ -504,7 +506,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C, // If any of the preprocessing commands failed, clean up and exit. if (!FailingCommands.empty()) { - if (!C.getArgs().hasArg(options::OPT_save_temps)) + if (!isSaveTempsEnabled()) C.CleanupFileList(C.getTempFiles(), true); Diag(clang::diag::note_drv_command_failed_diag_msg) @@ -545,6 +547,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C, Diag(clang::diag::note_drv_command_failed_diag_msg) << "Error generating run script: " + Script + " " + EC.message(); } else { + ScriptOS << "# Crash reproducer for " << getClangFullVersion() << "\n" + << "# Original command: "; + Cmd.Print(ScriptOS, "\n", /*Quote=*/true); Cmd.Print(ScriptOS, "\n", /*Quote=*/true, &CrashInfo); Diag(clang::diag::note_drv_command_failed_diag_msg) << Script; } @@ -612,7 +617,7 @@ int Driver::ExecuteCompilation(Compilation &C, const Command *FailingCommand = it->second; // Remove result files if we're not saving temps. - if (!C.getArgs().hasArg(options::OPT_save_temps)) { + if (!isSaveTempsEnabled()) { const JobAction *JA = cast<JobAction>(&FailingCommand->getSource()); C.CleanupFileMap(C.getResultFiles(), JA, true); @@ -970,7 +975,7 @@ static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, SmallString<64> Path(Value); if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) { - if (!llvm::sys::path::is_absolute(Path.str())) { + if (!llvm::sys::path::is_absolute(Path)) { SmallString<64> Directory(WorkDir->getValue()); llvm::sys::path::append(Directory, Value); Path.assign(Directory); @@ -980,10 +985,11 @@ static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, if (llvm::sys::fs::exists(Twine(Path))) return true; - if (D.IsCLMode() && llvm::sys::Process::FindInEnvPath("LIB", Value)) + if (D.IsCLMode() && !llvm::sys::path::is_absolute(Twine(Path)) && + llvm::sys::Process::FindInEnvPath("LIB", Value)) return true; - D.Diag(clang::diag::err_drv_no_such_file) << Path.str(); + D.Diag(clang::diag::err_drv_no_such_file) << Path; return false; } @@ -1264,7 +1270,7 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, continue; // Otherwise construct the appropriate action. - Current = ConstructPhaseAction(Args, Phase, std::move(Current)); + Current = ConstructPhaseAction(TC, Args, Phase, std::move(Current)); if (Current->getType() == types::TY_Nothing) break; } @@ -1290,7 +1296,8 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, } std::unique_ptr<Action> -Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, +Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, + phases::ID Phase, std::unique_ptr<Action> Input) const { llvm::PrettyStackTraceString CrashInfo("Constructing phase actions"); // Build the appropriate action. @@ -1349,7 +1356,7 @@ Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, types::TY_LLVM_BC); } case phases::Backend: { - if (IsUsingLTO(Args)) { + if (IsUsingLTO(TC, Args)) { types::ID Output = Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; return llvm::make_unique<BackendJobAction>(std::move(Input), Output); @@ -1370,7 +1377,10 @@ Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, llvm_unreachable("invalid phase in ConstructPhaseAction"); } -bool Driver::IsUsingLTO(const ArgList &Args) const { +bool Driver::IsUsingLTO(const ToolChain &TC, const ArgList &Args) const { + if (TC.getSanitizerArgs().needsLTO()) + return true; + if (Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false)) return true; @@ -1453,9 +1463,8 @@ void Driver::BuildJobs(Compilation &C) const { if (Opt.getKind() == Option::FlagClass) { bool DuplicateClaimed = false; - for (arg_iterator it = C.getArgs().filtered_begin(&Opt), - ie = C.getArgs().filtered_end(); it != ie; ++it) { - if ((*it)->isClaimed()) { + for (const Arg *AA : C.getArgs().filtered(&Opt)) { + if (AA->isClaimed()) { DuplicateClaimed = true; break; } @@ -1471,8 +1480,8 @@ void Driver::BuildJobs(Compilation &C) const { } } -static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC, - const JobAction *JA, +static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, + const ToolChain *TC, const JobAction *JA, const ActionList *&Inputs) { const Tool *ToolForJob = nullptr; @@ -1481,7 +1490,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC, // compiler input. if (TC->useIntegratedAs() && - !C.getArgs().hasArg(options::OPT_save_temps) && + !SaveTemps && !C.getArgs().hasArg(options::OPT_via_file_asm) && !C.getArgs().hasArg(options::OPT__SLASH_FA) && !C.getArgs().hasArg(options::OPT__SLASH_Fa) && @@ -1512,8 +1521,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC, const Tool *Compiler = TC->SelectTool(*CompileJA); if (!Compiler) return nullptr; - if (!Compiler->canEmitIR() || - !C.getArgs().hasArg(options::OPT_save_temps)) { + if (!Compiler->canEmitIR() || !SaveTemps) { Inputs = &(*Inputs)[0]->getInputs(); ToolForJob = Compiler; } @@ -1529,7 +1537,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC, if (Inputs->size() == 1 && isa<PreprocessJobAction>(*Inputs->begin()) && !C.getArgs().hasArg(options::OPT_no_integrated_cpp) && !C.getArgs().hasArg(options::OPT_traditional_cpp) && - !C.getArgs().hasArg(options::OPT_save_temps) && + !SaveTemps && !C.getArgs().hasArg(options::OPT_rewrite_objc) && ToolForJob->hasIntegratedCPP()) Inputs = &(*Inputs)[0]->getInputs(); @@ -1577,7 +1585,7 @@ void Driver::BuildJobsForAction(Compilation &C, const ActionList *Inputs = &A->getInputs(); const JobAction *JA = cast<JobAction>(A); - const Tool *T = SelectToolForJob(C, TC, JA, Inputs); + const Tool *T = SelectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs); if (!T) return; @@ -1684,8 +1692,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, assert(AtTopLevel && isa<PreprocessJobAction>(JA)); StringRef BaseName = llvm::sys::path::filename(BaseInput); StringRef NameArg; - if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi, - options::OPT__SLASH_o)) + if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi)) NameArg = A->getValue(); return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName, types::TY_PP_C), &JA); @@ -1708,7 +1715,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, } // Output to a temporary file? - if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) && + if ((!AtTopLevel && !isSaveTempsEnabled() && !C.getArgs().hasArg(options::OPT__SLASH_Fo)) || CCGenDiagnostics) { StringRef Name = llvm::sys::path::filename(BaseInput); @@ -1731,7 +1738,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, // Determine what the derived output name should be. const char *NamedOutput; - if (JA.getType() == types::TY_Object && + if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC) && C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) { // The /Fo or /o flag decides the object filename. StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fo, @@ -1780,11 +1787,20 @@ const char *Driver::GetNamedOutputPath(Compilation &C, NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); } + // Prepend object file path if -save-temps=obj + if (!AtTopLevel && isSaveTempsObj() && C.getArgs().hasArg(options::OPT_o) && + JA.getType() != types::TY_PCH) { + Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); + SmallString<128> TempPath(FinalOutput->getValue()); + llvm::sys::path::remove_filename(TempPath); + StringRef OutputFileName = llvm::sys::path::filename(NamedOutput); + llvm::sys::path::append(TempPath, OutputFileName); + NamedOutput = C.getArgs().MakeArgString(TempPath.c_str()); + } + // If we're saving temps and the temp file conflicts with the input file, // then avoid overwriting input file. - if (!AtTopLevel && C.getArgs().hasArg(options::OPT_save_temps) && - NamedOutput == BaseName) { - + if (!AtTopLevel && isSaveTempsEnabled() && NamedOutput == BaseName) { bool SameFile = false; SmallString<256> Result; llvm::sys::fs::current_path(Result); @@ -1856,8 +1872,8 @@ void Driver::generatePrefixedToolNames(const char *Tool, const ToolChain &TC, SmallVectorImpl<std::string> &Names) const { // FIXME: Needs a better variable than DefaultTargetTriple - Names.push_back(DefaultTargetTriple + "-" + Tool); - Names.push_back(Tool); + Names.emplace_back(DefaultTargetTriple + "-" + Tool); + Names.emplace_back(Tool); } static bool ScanDirForExecutable(SmallString<128> &Dir, @@ -2003,12 +2019,15 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, const ToolChain &Driver::getToolChain(const ArgList &Args, StringRef DarwinArchName) const { - llvm::Triple Target = computeTargetTriple(DefaultTargetTriple, Args, - DarwinArchName); + llvm::Triple Target = + computeTargetTriple(DefaultTargetTriple, Args, DarwinArchName); ToolChain *&TC = ToolChains[Target.str()]; if (!TC) { switch (Target.getOS()) { + case llvm::Triple::CloudABI: + TC = new toolchains::CloudABI(*this, Target, Args); + break; case llvm::Triple::Darwin: case llvm::Triple::MacOSX: case llvm::Triple::IOS: @@ -2038,6 +2057,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, else TC = new toolchains::Linux(*this, Target, Args); break; + case llvm::Triple::NaCl: + TC = new toolchains::NaCl_TC(*this, Target, Args); + break; case llvm::Triple::Solaris: TC = new toolchains::Solaris(*this, Target, Args); break; @@ -2069,29 +2091,20 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, } break; default: - // TCE is an OSless target - if (Target.getArchName() == "tce") { + // Of these targets, Hexagon is the only one that might have + // an OS of Linux, in which case it got handled above already. + if (Target.getArchName() == "tce") TC = new toolchains::TCEToolChain(*this, Target, Args); - break; - } - // If Hexagon is configured as an OSless target - if (Target.getArch() == llvm::Triple::hexagon) { + else if (Target.getArch() == llvm::Triple::hexagon) TC = new toolchains::Hexagon_TC(*this, Target, Args); - break; - } - if (Target.getArch() == llvm::Triple::xcore) { + else if (Target.getArch() == llvm::Triple::xcore) TC = new toolchains::XCore(*this, Target, Args); - break; - } - if (Target.isOSBinFormatELF()) { + else if (Target.isOSBinFormatELF()) TC = new toolchains::Generic_ELF(*this, Target, Args); - break; - } - if (Target.isOSBinFormatMachO()) { + else if (Target.isOSBinFormatMachO()) TC = new toolchains::MachO(*this, Target, Args); - break; - } - TC = new toolchains::Generic_GCC(*this, Target, Args); + else + TC = new toolchains::Generic_GCC(*this, Target, Args); break; } } @@ -2125,7 +2138,7 @@ bool Driver::GetReleaseVersion(const char *Str, unsigned &Major, Major = Minor = Micro = 0; if (*Str == '\0') - return true; + return false; char *End; Major = (unsigned) strtol(Str, &End, 10); @@ -2166,6 +2179,6 @@ std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks() const { return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask); } -bool clang::driver::isOptimizationLevelFast(const llvm::opt::ArgList &Args) { +bool clang::driver::isOptimizationLevelFast(const ArgList &Args) { return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false); } |