diff options
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 149 |
1 files changed, 138 insertions, 11 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f6016b43b692..e718b8366df0 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -8,6 +8,7 @@ #include "clang/Driver/Driver.h" #include "InputInfo.h" +#include "ToolChains/AIX.h" #include "ToolChains/AMDGPU.h" #include "ToolChains/AVR.h" #include "ToolChains/Ananas.h" @@ -177,6 +178,7 @@ void Driver::setDriverModeFromOption(StringRef Opt) { .Case("g++", GXXMode) .Case("cpp", CPPMode) .Case("cl", CLMode) + .Case("flang", FlangMode) .Default(None)) Mode = *M; else @@ -290,10 +292,6 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { FinalPhase = phases::Compile; - // clang interface stubs - } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) { - FinalPhase = phases::IfsMerge; - // -S only runs up to the backend. } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) { FinalPhase = phases::Backend; @@ -539,6 +537,17 @@ static llvm::Triple computeTargetTriple(const Driver &D, } } + // If target is RISC-V adjust the target triple according to + // provided architecture name + A = Args.getLastArg(options::OPT_march_EQ); + if (A && Target.isRISCV()) { + StringRef ArchName = A->getValue(); + if (ArchName.startswith_lower("rv32")) + Target.setArch(llvm::Triple::riscv32); + else if (ArchName.startswith_lower("rv64")) + Target.setArch(llvm::Triple::riscv64); + } + return Target; } @@ -735,7 +744,7 @@ static bool searchForFile(SmallVectorImpl<char> &FilePath, ArrayRef<std::string> Dirs, StringRef FileName) { SmallString<128> WPath; - for (const StringRef &Dir : Dirs) { + for (const std::string &Dir : Dirs) { if (Dir.empty()) continue; WPath.clear(); @@ -1981,8 +1990,9 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, // Handle debug info queries. Arg *A = Args.getLastArg(options::OPT_g_Group); - if (A && !A->getOption().matches(options::OPT_g0) && - !A->getOption().matches(options::OPT_gstabs) && + bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) && + !A->getOption().matches(options::OPT_gstabs); + if ((enablesDebugInfo || willEmitRemarks(Args)) && ContainsCompileOrAssembleAction(Actions.back())) { // Add a 'dsymutil' step if necessary, when debug info is enabled and we @@ -3489,6 +3499,68 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, Actions.push_back( C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image)); + if (Args.hasArg(options::OPT_emit_interface_stubs)) { + llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList; + if (Args.hasArg(options::OPT_c)) { + llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> CompilePhaseList; + types::getCompilationPhases(types::TY_IFS_CPP, CompilePhaseList); + llvm::copy_if(CompilePhaseList, std::back_inserter(PhaseList), + [&](phases::ID Phase) { return Phase <= phases::Compile; }); + } else { + types::getCompilationPhases(types::TY_IFS_CPP, PhaseList); + } + + ActionList MergerInputs; + + for (auto &I : Inputs) { + types::ID InputType = I.first; + const Arg *InputArg = I.second; + + // Currently clang and the llvm assembler do not support generating symbol + // stubs from assembly, so we skip the input on asm files. For ifs files + // we rely on the normal pipeline setup in the pipeline setup code above. + if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm || + InputType == types::TY_Asm) + continue; + + Action *Current = C.MakeAction<InputAction>(*InputArg, InputType); + + for (auto Phase : PhaseList) { + switch (Phase) { + default: + llvm_unreachable( + "IFS Pipeline can only consist of Compile followed by IfsMerge."); + case phases::Compile: { + // Only IfsMerge (llvm-ifs) can handle .o files by looking for ifs + // files where the .o file is located. The compile action can not + // handle this. + if (InputType == types::TY_Object) + break; + + Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP); + break; + } + case phases::IfsMerge: { + assert(Phase == PhaseList.back() && + "merging must be final compilation step."); + MergerInputs.push_back(Current); + Current = nullptr; + break; + } + } + } + + // If we ended with something, add to the output list. + if (Current) + Actions.push_back(Current); + } + + // Add an interface stubs merge action if necessary. + if (!MergerInputs.empty()) + Actions.push_back( + C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image)); + } + // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom // Compile phase that prints out supported cpu models and quits. if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) { @@ -3590,8 +3662,6 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); - if (Args.hasArg(options::OPT_emit_interface_stubs)) - return C.MakeAction<CompileJobAction>(Input, types::TY_IFS_CPP); return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); } case phases::Backend: { @@ -3620,11 +3690,29 @@ void Driver::BuildJobs(Compilation &C) const { Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); // It is an error to provide a -o option if we are making multiple output - // files. + // files. There are exceptions: + // + // IfsMergeJob: when generating interface stubs enabled we want to be able to + // generate the stub file at the same time that we generate the real + // library/a.out. So when a .o, .so, etc are the output, with clang interface + // stubs there will also be a .ifs and .ifso at the same location. + // + // CompileJob of type TY_IFS_CPP: when generating interface stubs is enabled + // and -c is passed, we still want to be able to generate a .ifs file while + // we are also generating .o files. So we allow more than one output file in + // this case as well. + // if (FinalOutput) { unsigned NumOutputs = 0; + unsigned NumIfsOutputs = 0; for (const Action *A : C.getActions()) - if (A->getType() != types::TY_Nothing) + if (A->getType() != types::TY_Nothing && + !(A->getKind() == Action::IfsMergeJobClass || + (A->getType() == clang::driver::types::TY_IFS_CPP && + A->getKind() == clang::driver::Action::CompileJobClass && + 0 == NumIfsOutputs++) || + (A->getKind() == Action::BindArchClass && A->getInputs().size() && + A->getInputs().front()->getKind() == Action::IfsMergeJobClass))) ++NumOutputs; if (NumOutputs > 1) { @@ -4699,6 +4787,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, auto &TC = ToolChains[Target.str()]; if (!TC) { switch (Target.getOS()) { + case llvm::Triple::AIX: + TC = std::make_unique<toolchains::AIX>(*this, Target, Args); + break; case llvm::Triple::Haiku: TC = std::make_unique<toolchains::Haiku>(*this, Target, Args); break; @@ -4872,6 +4963,19 @@ bool Driver::ShouldUseClangCompiler(const JobAction &JA) const { return true; } +bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const { + // Say "no" if there is not exactly one input of a type flang understands. + if (JA.size() != 1 || + !types::isFortran((*JA.input_begin())->getType())) + return false; + + // And say "no" if this is not a kind of action flang understands. + if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA)) + return false; + + return true; +} + /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the /// grouped values as integers. Numbers which are not provided are set to 0. /// @@ -4957,3 +5061,26 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const { bool clang::driver::isOptimizationLevelFast(const ArgList &Args) { return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false); } + +bool clang::driver::willEmitRemarks(const ArgList &Args) { + // -fsave-optimization-record enables it. + if (Args.hasFlag(options::OPT_fsave_optimization_record, + options::OPT_fno_save_optimization_record, false)) + return true; + + // -fsave-optimization-record=<format> enables it as well. + if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ, + options::OPT_fno_save_optimization_record, false)) + return true; + + // -foptimization-record-file alone enables it too. + if (Args.hasFlag(options::OPT_foptimization_record_file_EQ, + options::OPT_fno_save_optimization_record, false)) + return true; + + // -foptimization-record-passes alone enables it too. + if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ, + options::OPT_fno_save_optimization_record, false)) + return true; + return false; +} |