aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r--lib/Driver/Driver.cpp524
1 files changed, 319 insertions, 205 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 396ddf4dd816..f6016b43b692 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -120,20 +120,20 @@ std::string Driver::GetResourcesPath(StringRef BinaryPath,
Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
- : Opts(createDriverOptTable()), Diags(Diags), VFS(std::move(VFS)),
- Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
- LTOMode(LTOK_None), ClangExecutable(ClangExecutable),
- SysRoot(DEFAULT_SYSROOT), DriverTitle("clang LLVM compiler"),
- CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr),
- CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false),
- CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
- CCGenDiagnostics(false), TargetTriple(TargetTriple),
- CCCGenericGCCName(""), Saver(Alloc), CheckInputsExist(true),
- GenReproducer(false), SuppressMissingInputWarning(false) {
+ : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode),
+ SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None),
+ ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
+ DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr),
+ CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
+ CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false),
+ CCLogDiagnostics(false), CCGenDiagnostics(false),
+ TargetTriple(TargetTriple), CCCGenericGCCName(""), Saver(Alloc),
+ CheckInputsExist(true), GenReproducer(false),
+ SuppressMissingInputWarning(false) {
// Provide a sane fallback if no VFS is specified.
if (!this->VFS)
- this->VFS = llvm::vfs::createPhysicalFileSystem().release();
+ this->VFS = llvm::vfs::getRealFileSystem();
Name = llvm::sys::path::filename(ClangExecutable);
Dir = llvm::sys::path::parent_path(ClangExecutable);
@@ -274,11 +274,11 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
FinalPhase = phases::Preprocess;
- // --precompile only runs up to precompilation.
+ // --precompile only runs up to precompilation.
} else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
FinalPhase = phases::Precompile;
- // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
+ // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
@@ -286,21 +286,23 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
- (PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs)) ||
- (PhaseArg = DAL.getLastArg(options::OPT__analyze,
- options::OPT__analyze_auto)) ||
+ (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
(PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
FinalPhase = phases::Compile;
- // -S only runs up to the backend.
+ // 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;
- // -c compilation only runs up to the assembler.
+ // -c compilation only runs up to the assembler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
FinalPhase = phases::Assemble;
- // Otherwise do everything.
+ // Otherwise do everything.
} else
FinalPhase = phases::Link;
@@ -310,7 +312,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
return FinalPhase;
}
-static Arg *MakeInputArg(DerivedArgList &Args, OptTable &Opts,
+static Arg *MakeInputArg(DerivedArgList &Args, const OptTable &Opts,
StringRef Value, bool Claim = true) {
Arg *A = new Arg(Opts.getOption(options::OPT_INPUT), Value,
Args.getBaseArgs().MakeIndex(Value), Value.data());
@@ -321,6 +323,7 @@ static Arg *MakeInputArg(DerivedArgList &Args, OptTable &Opts,
}
DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
+ const llvm::opt::OptTable &Opts = getOpts();
DerivedArgList *DAL = new DerivedArgList(Args);
bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
@@ -337,12 +340,12 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
A->getOption().matches(options::OPT_Xlinker)) &&
A->containsValue("--no-demangle")) {
// Add the rewritten no-demangle argument.
- DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle));
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
// Add the remaining values as Xlinker arguments.
for (StringRef Val : A->getValues())
if (Val != "--no-demangle")
- DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), Val);
+ DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
continue;
}
@@ -355,12 +358,11 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
A->getValue(0) == StringRef("-MMD"))) {
// Rewrite to -MD/-MMD along with -MF.
if (A->getValue(0) == StringRef("-MD"))
- DAL->AddFlagArg(A, Opts->getOption(options::OPT_MD));
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
else
- DAL->AddFlagArg(A, Opts->getOption(options::OPT_MMD));
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
if (A->getNumValues() == 2)
- DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF),
- A->getValue(1));
+ DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
continue;
}
@@ -371,13 +373,13 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
// Rewrite unless -nostdlib is present.
if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
Value == "stdc++") {
- DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx));
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
continue;
}
// Rewrite unconditionally.
if (Value == "cc_kext") {
- DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_cckext));
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
continue;
}
}
@@ -386,7 +388,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
if (A->getOption().matches(options::OPT__DASH_DASH)) {
A->claim();
for (StringRef Val : A->getValues())
- DAL->append(MakeInputArg(*DAL, *Opts, Val, false));
+ DAL->append(MakeInputArg(*DAL, Opts, Val, false));
continue;
}
@@ -395,14 +397,14 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
// Enforce -static if -miamcu is present.
if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false))
- DAL->AddFlagArg(0, Opts->getOption(options::OPT_static));
+ DAL->AddFlagArg(0, Opts.getOption(options::OPT_static));
// Add a default value of -mlinker-version=, if one was given and the user
// didn't specify one.
#if defined(HOST_LINK_VERSION)
if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
strlen(HOST_LINK_VERSION) > 0) {
- DAL->AddJoinedArg(0, Opts->getOption(options::OPT_mlinker_version_EQ),
+ DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
HOST_LINK_VERSION);
DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
}
@@ -626,7 +628,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// because the device toolchain we create depends on both.
auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
if (!CudaTC) {
- CudaTC = llvm::make_unique<toolchains::CudaToolChain>(
+ CudaTC = std::make_unique<toolchains::CudaToolChain>(
*this, CudaTriple, *HostTC, C.getInputArgs(), OFK);
}
C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
@@ -641,7 +643,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// because the device toolchain we create depends on both.
auto &HIPTC = ToolChains[HIPTriple.str() + "/" + HostTriple.str()];
if (!HIPTC) {
- HIPTC = llvm::make_unique<toolchains::HIPToolChain>(
+ HIPTC = std::make_unique<toolchains::HIPToolChain>(
*this, HIPTriple, *HostTC, C.getInputArgs());
}
C.addOffloadDeviceToolChain(HIPTC.get(), OFK);
@@ -699,7 +701,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
auto &CudaTC =
ToolChains[TT.str() + "/" + HostTC->getTriple().normalize()];
if (!CudaTC)
- CudaTC = llvm::make_unique<toolchains::CudaToolChain>(
+ CudaTC = std::make_unique<toolchains::CudaToolChain>(
*this, TT, *HostTC, C.getInputArgs(), Action::OFK_OpenMP);
TC = CudaTC.get();
} else
@@ -760,7 +762,7 @@ bool Driver::readConfigFile(StringRef FileName) {
llvm::sys::path::native(CfgFileName);
ConfigFile = CfgFileName.str();
bool ContainErrors;
- CfgOptions = llvm::make_unique<InputArgList>(
+ CfgOptions = std::make_unique<InputArgList>(
ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
if (ContainErrors) {
CfgOptions.reset();
@@ -954,7 +956,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// Arguments specified in command line.
bool ContainsError;
- CLOptions = llvm::make_unique<InputArgList>(
+ CLOptions = std::make_unique<InputArgList>(
ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
// Try parsing configuration file.
@@ -1000,7 +1002,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
if (!CLModePassThroughArgList.empty()) {
// Parse any pass through args using default clang processing rather
// than clang-cl processing.
- auto CLModePassThroughOptions = llvm::make_unique<InputArgList>(
+ auto CLModePassThroughOptions = std::make_unique<InputArgList>(
ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
if (!ContainsError)
@@ -1093,7 +1095,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
}
std::unique_ptr<llvm::opt::InputArgList> UArgs =
- llvm::make_unique<InputArgList>(std::move(Args));
+ std::make_unique<InputArgList>(std::move(Args));
// Perform the default argument translations.
DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
@@ -1592,16 +1594,17 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1"))
DisableFlags &= ~options::NoDriverOption;
+ const llvm::opt::OptTable &Opts = getOpts();
StringRef Cur;
Cur = Flags.at(Flags.size() - 1);
StringRef Prev;
if (Flags.size() >= 2) {
Prev = Flags.at(Flags.size() - 2);
- SuggestedCompletions = Opts->suggestValueCompletions(Prev, Cur);
+ SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
}
if (SuggestedCompletions.empty())
- SuggestedCompletions = Opts->suggestValueCompletions(Cur, "");
+ SuggestedCompletions = Opts.suggestValueCompletions(Cur, "");
// If Flags were empty, it means the user typed `clang [tab]` where we should
// list all possible flags. If there was no value completion and the user
@@ -1619,7 +1622,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
// If the flag is in the form of "--autocomplete=-foo",
// we were requested to print out all option names that start with "-foo".
// For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
- SuggestedCompletions = Opts->findByPrefix(Cur, DisableFlags);
+ SuggestedCompletions = Opts.findByPrefix(Cur, DisableFlags);
// We have to query the -W flags manually as they're not in the OptTable.
// TODO: Find a good way to add them to OptTable instead and them remove
@@ -1799,23 +1802,36 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
return true;
}
+enum {
+ TopLevelAction = 0,
+ HeadSibAction = 1,
+ OtherSibAction = 2,
+};
+
// Display an action graph human-readably. Action A is the "sink" node
// and latest-occuring action. Traversal is in pre-order, visiting the
// inputs to each action before printing the action itself.
static unsigned PrintActions1(const Compilation &C, Action *A,
- std::map<Action *, unsigned> &Ids) {
+ std::map<Action *, unsigned> &Ids,
+ Twine Indent = {}, int Kind = TopLevelAction) {
if (Ids.count(A)) // A was already visited.
return Ids[A];
std::string str;
llvm::raw_string_ostream os(str);
+ auto getSibIndent = [](int K) -> Twine {
+ return (K == HeadSibAction) ? " " : (K == OtherSibAction) ? "| " : "";
+ };
+
+ Twine SibIndent = Indent + getSibIndent(Kind);
+ int SibKind = HeadSibAction;
os << Action::getClassName(A->getKind()) << ", ";
if (InputAction *IA = dyn_cast<InputAction>(A)) {
os << "\"" << IA->getInputArg().getValue() << "\"";
} else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
os << '"' << BIA->getArchName() << '"' << ", {"
- << PrintActions1(C, *BIA->input_begin(), Ids) << "}";
+ << PrintActions1(C, *BIA->input_begin(), Ids, SibIndent, SibKind) << "}";
} else if (OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
bool IsFirst = true;
OA->doOnEachDependence(
@@ -1838,8 +1854,9 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
os << ":" << BoundArch;
os << ")";
os << '"';
- os << " {" << PrintActions1(C, A, Ids) << "}";
+ os << " {" << PrintActions1(C, A, Ids, SibIndent, SibKind) << "}";
IsFirst = false;
+ SibKind = OtherSibAction;
});
} else {
const ActionList *AL = &A->getInputs();
@@ -1847,8 +1864,9 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
if (AL->size()) {
const char *Prefix = "{";
for (Action *PreRequisite : *AL) {
- os << Prefix << PrintActions1(C, PreRequisite, Ids);
+ os << Prefix << PrintActions1(C, PreRequisite, Ids, SibIndent, SibKind);
Prefix = ", ";
+ SibKind = OtherSibAction;
}
os << "}";
} else
@@ -1869,9 +1887,13 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
}
}
+ auto getSelfIndent = [](int K) -> Twine {
+ return (K == HeadSibAction) ? "+- " : (K == OtherSibAction) ? "|- " : "";
+ };
+
unsigned Id = Ids.size();
Ids[A] = Id;
- llvm::errs() << Id << ": " << os.str() << ", "
+ llvm::errs() << Indent + getSelfIndent(Kind) << Id << ": " << os.str() << ", "
<< types::getTypeName(A->getType()) << offload_os.str() << "\n";
return Id;
@@ -2037,6 +2059,7 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
// Construct a the list of inputs and their types.
void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
InputList &Inputs) const {
+ const llvm::opt::OptTable &Opts = getOpts();
// Track the current user specified (-x) input. We also explicitly track the
// argument used to set the type; we only want to claim the type when we
// actually use it, so we warn about unused -x arguments.
@@ -2160,7 +2183,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
StringRef Value = A->getValue();
if (DiagnoseInputExistence(Args, Value, types::TY_C,
/*TypoCorrect=*/false)) {
- Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue());
+ Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
Inputs.push_back(std::make_pair(types::TY_C, InputArg));
}
A->claim();
@@ -2168,7 +2191,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
StringRef Value = A->getValue();
if (DiagnoseInputExistence(Args, Value, types::TY_CXX,
/*TypoCorrect=*/false)) {
- Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue());
+ Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
}
A->claim();
@@ -2202,7 +2225,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
if (CCCIsCPP() && Inputs.empty()) {
// If called as standalone preprocessor, stdin is processed
// if no other input is present.
- Arg *A = MakeInputArg(Args, *Opts, "-");
+ Arg *A = MakeInputArg(Args, Opts, "-");
Inputs.push_back(std::make_pair(types::TY_C, A));
}
}
@@ -2223,7 +2246,7 @@ class OffloadingActionBuilder final {
/// Builder interface. It doesn't build anything or keep any state.
class DeviceActionBuilder {
public:
- typedef llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhasesTy;
+ typedef const llvm::SmallVectorImpl<phases::ID> PhasesTy;
enum ActionBuilderReturnCode {
// The builder acted successfully on the current action.
@@ -2276,12 +2299,13 @@ class OffloadingActionBuilder final {
return ABRT_Inactive;
}
- /// Append top level actions generated by the builder. Return true if errors
- /// were found.
+ /// Append top level actions generated by the builder.
virtual void appendTopLevelActions(ActionList &AL) {}
- /// Append linker actions generated by the builder. Return true if errors
- /// were found.
+ /// Append linker actions generated by the builder.
+ virtual void appendLinkActions(ActionList &AL) {}
+
+ /// Append linker actions generated by the builder.
virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
/// Initialize the builder. Return true if any initialization errors are
@@ -2309,6 +2333,8 @@ class OffloadingActionBuilder final {
/// compilation.
bool CompileHostOnly = false;
bool CompileDeviceOnly = false;
+ bool EmitLLVM = false;
+ bool EmitAsm = false;
/// List of GPU architectures to use in this compilation.
SmallVector<CudaArch, 4> GpuArchList;
@@ -2324,6 +2350,10 @@ class OffloadingActionBuilder final {
/// Flag for -fgpu-rdc.
bool Relocatable = false;
+
+ /// Default GPU architecture if there's no one specified.
+ CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
+
public:
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs,
@@ -2475,6 +2505,8 @@ class OffloadingActionBuilder final {
CompileDeviceOnly = PartialCompilationArg &&
PartialCompilationArg->getOption().matches(
options::OPT_cuda_device_only);
+ EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
+ EmitAsm = Args.getLastArg(options::OPT_S);
// Collect all cuda_gpu_arch parameters, removing duplicates.
std::set<CudaArch> GpuArchs;
@@ -2511,7 +2543,7 @@ class OffloadingActionBuilder final {
// supported GPUs. sm_20 code should work correctly, if
// suboptimally, on all newer GPUs.
if (GpuArchList.empty())
- GpuArchList.push_back(CudaArch::SM_20);
+ GpuArchList.push_back(DefaultCudaArch);
return Error;
}
@@ -2523,7 +2555,9 @@ class OffloadingActionBuilder final {
public:
CudaActionBuilder(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs)
- : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda) {}
+ : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda) {
+ DefaultCudaArch = CudaArch::SM_20;
+ }
ActionBuilderReturnCode
getDeviceDependences(OffloadAction::DeviceDependences &DA,
@@ -2638,7 +2672,9 @@ class OffloadingActionBuilder final {
public:
HIPActionBuilder(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs)
- : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {}
+ : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {
+ DefaultCudaArch = CudaArch::GFX803;
+ }
bool canUseBundlerUnbundler() const override { return true; }
@@ -2661,7 +2697,8 @@ class OffloadingActionBuilder final {
assert(!CompileHostOnly &&
"Not expecting CUDA actions in host-only compilation.");
- if (!Relocatable && CurPhase == phases::Backend) {
+ if (!Relocatable && CurPhase == phases::Backend && !EmitLLVM &&
+ !EmitAsm) {
// If we are in backend phase, we attempt to generate the fat binary.
// We compile each arch to IR and use a link action to generate code
// object containing ISA. Then we use a special "link" action to create
@@ -2729,7 +2766,8 @@ class OffloadingActionBuilder final {
A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
AssociatedOffloadKind);
- return ABRT_Success;
+ return (CompileDeviceOnly && CurPhase == FinalPhase) ? ABRT_Ignore_Host
+ : ABRT_Success;
}
void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
@@ -2870,7 +2908,7 @@ class OffloadingActionBuilder final {
OpenMPDeviceActions.clear();
}
- void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
+ void appendLinkActions(ActionList &AL) override {
assert(ToolChains.size() == DeviceLinkerInputs.size() &&
"Toolchains and linker inputs sizes do not match.");
@@ -2879,12 +2917,18 @@ class OffloadingActionBuilder final {
for (auto &LI : DeviceLinkerInputs) {
auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, types::TY_Image);
- DA.add(*DeviceLinkAction, **TC, /*BoundArch=*/nullptr,
- Action::OFK_OpenMP);
+ OffloadAction::DeviceDependences DeviceLinkDeps;
+ DeviceLinkDeps.add(*DeviceLinkAction, **TC, /*BoundArch=*/nullptr,
+ Action::OFK_OpenMP);
+ AL.push_back(C.MakeAction<OffloadAction>(DeviceLinkDeps,
+ DeviceLinkAction->getType()));
++TC;
}
+ DeviceLinkerInputs.clear();
}
+ void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {}
+
bool initialize() override {
// Get the OpenMP toolchains. If we don't get any, the action builder will
// know there is nothing to do related to OpenMP offloading.
@@ -3088,7 +3132,8 @@ public:
// the resulting list. Otherwise, just append the device actions. For
// device only compilation, HostAction is a null pointer, therefore only do
// this when HostAction is not a null pointer.
- if (CanUseBundler && HostAction && !OffloadAL.empty()) {
+ if (CanUseBundler && HostAction &&
+ HostAction->getType() != types::TY_Nothing && !OffloadAL.empty()) {
// Add the host action to the list in order to create the bundling action.
OffloadAL.push_back(HostAction);
@@ -3108,6 +3153,25 @@ public:
return false;
}
+ Action* makeHostLinkAction() {
+ // Build a list of device linking actions.
+ ActionList DeviceAL;
+ for (DeviceActionBuilder *SB : SpecializedBuilders) {
+ if (!SB->isValid())
+ continue;
+ SB->appendLinkActions(DeviceAL);
+ }
+
+ if (DeviceAL.empty())
+ return nullptr;
+
+ // Create wrapper bitcode from the result of device link actions and compile
+ // it to an object which will be added to the host link command.
+ auto *BC = C.MakeAction<OffloadWrapperJobAction>(DeviceAL, types::TY_LLVM_BC);
+ auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm);
+ return C.MakeAction<AssembleJobAction>(ASM, types::TY_Object);
+ }
+
/// Processes the host linker action. This currently consists of replacing it
/// with an offload action if there are device link objects and propagate to
/// the host action all the offload kinds used in the current compilation. The
@@ -3148,63 +3212,9 @@ public:
};
} // anonymous namespace.
-void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
- const InputList &Inputs, ActionList &Actions) const {
- llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
-
- if (!SuppressMissingInputWarning && Inputs.empty()) {
- Diag(clang::diag::err_drv_no_input_files);
- return;
- }
-
- Arg *FinalPhaseArg;
- phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
-
- if (FinalPhase == phases::Link) {
- if (Args.hasArg(options::OPT_emit_llvm))
- Diag(clang::diag::err_drv_emit_llvm_link);
- if (IsCLMode() && LTOMode != LTOK_None &&
- !Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
- Diag(clang::diag::err_drv_lto_without_lld);
- }
-
- // Reject -Z* at the top level, these options should never have been exposed
- // by gcc.
- if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
- Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args);
-
- // Diagnose misuse of /Fo.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
- StringRef V = A->getValue();
- if (Inputs.size() > 1 && !V.empty() &&
- !llvm::sys::path::is_separator(V.back())) {
- // Check whether /Fo tries to name an output file for multiple inputs.
- Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
- << A->getSpelling() << V;
- Args.eraseArg(options::OPT__SLASH_Fo);
- }
- }
-
- // Diagnose misuse of /Fa.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
- StringRef V = A->getValue();
- if (Inputs.size() > 1 && !V.empty() &&
- !llvm::sys::path::is_separator(V.back())) {
- // Check whether /Fa tries to name an asm file for multiple inputs.
- Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
- << A->getSpelling() << V;
- Args.eraseArg(options::OPT__SLASH_Fa);
- }
- }
-
- // Diagnose misuse of /o.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
- if (A->getValue()[0] == '\0') {
- // It has to have a value.
- Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
- Args.eraseArg(options::OPT__SLASH_o);
- }
- }
+void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
+ const InputList &Inputs,
+ ActionList &Actions) const {
// Ignore /Yc/Yu if both /Yc and /Yu passed but with different filenames.
Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
@@ -3220,6 +3230,18 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Args.eraseArg(options::OPT__SLASH_Yc);
YcArg = nullptr;
}
+
+ Arg *FinalPhaseArg;
+ phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
+
+ if (FinalPhase == phases::Link) {
+ if (Args.hasArg(options::OPT_emit_llvm))
+ Diag(clang::diag::err_drv_emit_llvm_link);
+ if (IsCLMode() && LTOMode != LTOK_None &&
+ !Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
+ Diag(clang::diag::err_drv_lto_without_lld);
+ }
+
if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) {
// If only preprocessing or /Y- is used, all pch handling is disabled.
// Rather than check for it everywhere, just remove clang-cl pch-related
@@ -3230,20 +3252,14 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
YcArg = YuArg = nullptr;
}
- // Builder to be used to build offloading actions.
- OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
-
- // Construct the actions to perform.
- HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
- ActionList LinkerInputs;
-
- llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
+ unsigned LastPLSize = 0;
for (auto &I : Inputs) {
types::ID InputType = I.first;
const Arg *InputArg = I.second;
- PL.clear();
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
types::getCompilationPhases(InputType, PL);
+ LastPLSize = PL.size();
// If the first step comes after the final phase we are doing as part of
// this compilation, warn the user about it.
@@ -3267,7 +3283,10 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
else if (InitialPhase == phases::Compile &&
- FinalPhase == phases::Preprocess &&
+ (Args.getLastArg(options::OPT__SLASH_EP,
+ options::OPT__SLASH_P) ||
+ Args.getLastArg(options::OPT_E) ||
+ Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
getPreprocessedType(InputType) == types::TY_INVALID)
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
<< InputArg->getAsString(Args) << !!FinalPhaseArg
@@ -3287,8 +3306,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
types::getCompilationPhases(HeaderType, PCHPL);
// Build the pipeline for the pch file.
- Action *ClangClPch =
- C.MakeAction<InputAction>(*InputArg, HeaderType);
+ Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType);
for (phases::ID Phase : PCHPL)
ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
assert(ClangClPch);
@@ -3300,6 +3318,85 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// probably not be considered successful either.
}
}
+ }
+
+ // If we are linking, claim any options which are obviously only used for
+ // compilation.
+ // FIXME: Understand why the last Phase List length is used here.
+ if (FinalPhase == phases::Link && LastPLSize == 1) {
+ Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
+ Args.ClaimAllArgs(options::OPT_cl_compile_Group);
+ }
+}
+
+void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
+ const InputList &Inputs, ActionList &Actions) const {
+ llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
+
+ if (!SuppressMissingInputWarning && Inputs.empty()) {
+ Diag(clang::diag::err_drv_no_input_files);
+ return;
+ }
+
+ // Reject -Z* at the top level, these options should never have been exposed
+ // by gcc.
+ if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
+ Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args);
+
+ // Diagnose misuse of /Fo.
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
+ StringRef V = A->getValue();
+ if (Inputs.size() > 1 && !V.empty() &&
+ !llvm::sys::path::is_separator(V.back())) {
+ // Check whether /Fo tries to name an output file for multiple inputs.
+ Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
+ << A->getSpelling() << V;
+ Args.eraseArg(options::OPT__SLASH_Fo);
+ }
+ }
+
+ // Diagnose misuse of /Fa.
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
+ StringRef V = A->getValue();
+ if (Inputs.size() > 1 && !V.empty() &&
+ !llvm::sys::path::is_separator(V.back())) {
+ // Check whether /Fa tries to name an asm file for multiple inputs.
+ Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
+ << A->getSpelling() << V;
+ Args.eraseArg(options::OPT__SLASH_Fa);
+ }
+ }
+
+ // Diagnose misuse of /o.
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
+ if (A->getValue()[0] == '\0') {
+ // It has to have a value.
+ Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
+ Args.eraseArg(options::OPT__SLASH_o);
+ }
+ }
+
+ handleArguments(C, Args, Inputs, Actions);
+
+ // Builder to be used to build offloading actions.
+ OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
+
+ // Construct the actions to perform.
+ HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
+ ActionList LinkerInputs;
+ ActionList MergerInputs;
+
+ for (auto &I : Inputs) {
+ types::ID InputType = I.first;
+ const Arg *InputArg = I.second;
+
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
+ types::getCompilationPhases(*this, Args, InputType, PL);
+ if (PL.empty())
+ continue;
+
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> FullPL;
+ types::getCompilationPhases(InputType, FullPL);
// Build the pipeline for this file.
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
@@ -3309,28 +3406,33 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
break;
- for (SmallVectorImpl<phases::ID>::iterator i = PL.begin(), e = PL.end();
- i != e; ++i) {
- phases::ID Phase = *i;
-
- // We are done if this step is past what the user requested.
- if (Phase > FinalPhase)
- break;
+ for (phases::ID Phase : PL) {
// Add any offload action the host action depends on.
Current = OffloadBuilder.addDeviceDependencesToHostAction(
- Current, InputArg, Phase, FinalPhase, PL);
+ Current, InputArg, Phase, PL.back(), FullPL);
if (!Current)
break;
// Queue linker inputs.
if (Phase == phases::Link) {
- assert((i + 1) == e && "linking must be final compilation step.");
+ assert(Phase == PL.back() && "linking must be final compilation step.");
LinkerInputs.push_back(Current);
Current = nullptr;
break;
}
+ // TODO: Consider removing this because the merged may not end up being
+ // the final Phase in the pipeline. Perhaps the merged could just merge
+ // and then pass an artifact of some sort to the Link Phase.
+ // Queue merger inputs.
+ if (Phase == phases::IfsMerge) {
+ assert(Phase == PL.back() && "merging must be final compilation step.");
+ MergerInputs.push_back(Current);
+ Current = nullptr;
+ break;
+ }
+
// Each precompiled header file after a module file action is a module
// header of that same module file, rather than being compiled to a
// separate PCH.
@@ -3375,17 +3477,17 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Add a link action if necessary.
if (!LinkerInputs.empty()) {
+ if (Action *Wrapper = OffloadBuilder.makeHostLinkAction())
+ LinkerInputs.push_back(Wrapper);
Action *LA = C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
LA = OffloadBuilder.processHostLinkAction(LA);
Actions.push_back(LA);
}
- // If we are linking, claim any options which are obviously only used for
- // compilation.
- if (FinalPhase == phases::Link && PL.size() == 1) {
- Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
- Args.ClaimAllArgs(options::OPT_cl_compile_Group);
- }
+ // 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.
@@ -3423,10 +3525,14 @@ Action *Driver::ConstructPhaseAction(
switch (Phase) {
case phases::Link:
llvm_unreachable("link action invalid here.");
+ case phases::IfsMerge:
+ llvm_unreachable("ifsmerge action invalid here.");
case phases::Preprocess: {
types::ID OutputTy;
- // -{M, MM} alter the output type.
- if (Args.hasArg(options::OPT_M, options::OPT_MM)) {
+ // -M and -MM specify the dependency file name by altering the output type,
+ // -if -MD and -MMD are not specified.
+ if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
+ !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
OutputTy = types::TY_Dependencies;
} else {
OutputTy = Input->getType();
@@ -3474,7 +3580,7 @@ Action *Driver::ConstructPhaseAction(
if (Args.hasArg(options::OPT_rewrite_legacy_objc))
return C.MakeAction<CompileJobAction>(Input,
types::TY_RewrittenLegacyObjC);
- if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto))
+ if (Args.hasArg(options::OPT__analyze))
return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist);
if (Args.hasArg(options::OPT__migrate))
return C.MakeAction<MigrateJobAction>(Input, types::TY_Remap);
@@ -3484,8 +3590,8 @@ 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_iterface_stubs))
- return C.MakeAction<CompileJobAction>(Input, types::TY_IFS);
+ 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: {
@@ -3759,18 +3865,8 @@ class ToolSelector final {
if (!AJ || !BJ)
return nullptr;
- // Retrieve the compile job, backend action must always be preceded by one.
- ActionList CompileJobOffloadActions;
- auto *CJ = getPrevDependentAction(BJ->getInputs(), CompileJobOffloadActions,
- /*CanBeCollapsed=*/false);
- if (!AJ || !BJ || !CJ)
- return nullptr;
-
- assert(isa<CompileJobAction>(CJ) &&
- "Expecting compile job preceding backend job.");
-
- // Get compiler tool.
- const Tool *T = TC.SelectTool(*CJ);
+ // Get backend tool.
+ const Tool *T = TC.SelectTool(*BJ);
if (!T)
return nullptr;
@@ -4175,6 +4271,13 @@ InputInfo Driver::BuildJobsForActionNoCache(
A->getOffloadingDeviceKind(), TC->getTriple().normalize(),
/*CreatePrefixForHost=*/!!A->getOffloadingHostActiveKinds() &&
!AtTopLevel);
+ if (isa<OffloadWrapperJobAction>(JA)) {
+ OffloadingPrefix += "-wrapper";
+ if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
+ BaseInput = FinalOutput->getValue();
+ else
+ BaseInput = getDefaultImageName();
+ }
Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch,
AtTopLevel, MultipleArchs,
OffloadingPrefix),
@@ -4358,11 +4461,22 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image);
} else {
SmallString<128> Output(getDefaultImageName());
+ // HIP image for device compilation with -fno-gpu-rdc is per compilation
+ // unit.
+ bool IsHIPNoRDC = JA.getOffloadingDeviceKind() == Action::OFK_HIP &&
+ !C.getArgs().hasFlag(options::OPT_fgpu_rdc,
+ options::OPT_fno_gpu_rdc, false);
+ if (IsHIPNoRDC) {
+ Output = BaseName;
+ llvm::sys::path::replace_extension(Output, "");
+ }
Output += OffloadingPrefix;
if (MultipleArchs && !BoundArch.empty()) {
Output += "-";
Output.append(BoundArch);
}
+ if (IsHIPNoRDC)
+ Output += ".out";
NamedOutput = C.getArgs().MakeArgString(Output.c_str());
}
} else if (JA.getType() == types::TY_PCH && IsCLMode()) {
@@ -4586,152 +4700,152 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
if (!TC) {
switch (Target.getOS()) {
case llvm::Triple::Haiku:
- TC = llvm::make_unique<toolchains::Haiku>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Haiku>(*this, Target, Args);
break;
case llvm::Triple::Ananas:
- TC = llvm::make_unique<toolchains::Ananas>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Ananas>(*this, Target, Args);
break;
case llvm::Triple::CloudABI:
- TC = llvm::make_unique<toolchains::CloudABI>(*this, Target, Args);
+ TC = std::make_unique<toolchains::CloudABI>(*this, Target, Args);
break;
case llvm::Triple::Darwin:
case llvm::Triple::MacOSX:
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
- TC = llvm::make_unique<toolchains::DarwinClang>(*this, Target, Args);
+ TC = std::make_unique<toolchains::DarwinClang>(*this, Target, Args);
break;
case llvm::Triple::DragonFly:
- TC = llvm::make_unique<toolchains::DragonFly>(*this, Target, Args);
+ TC = std::make_unique<toolchains::DragonFly>(*this, Target, Args);
break;
case llvm::Triple::OpenBSD:
- TC = llvm::make_unique<toolchains::OpenBSD>(*this, Target, Args);
+ TC = std::make_unique<toolchains::OpenBSD>(*this, Target, Args);
break;
case llvm::Triple::NetBSD:
- TC = llvm::make_unique<toolchains::NetBSD>(*this, Target, Args);
+ TC = std::make_unique<toolchains::NetBSD>(*this, Target, Args);
break;
case llvm::Triple::FreeBSD:
- TC = llvm::make_unique<toolchains::FreeBSD>(*this, Target, Args);
+ TC = std::make_unique<toolchains::FreeBSD>(*this, Target, Args);
break;
case llvm::Triple::Minix:
- TC = llvm::make_unique<toolchains::Minix>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Minix>(*this, Target, Args);
break;
case llvm::Triple::Linux:
case llvm::Triple::ELFIAMCU:
if (Target.getArch() == llvm::Triple::hexagon)
- TC = llvm::make_unique<toolchains::HexagonToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target,
Args);
else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
!Target.hasEnvironment())
- TC = llvm::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
Args);
else if (Target.getArch() == llvm::Triple::ppc ||
Target.getArch() == llvm::Triple::ppc64 ||
Target.getArch() == llvm::Triple::ppc64le)
- TC = llvm::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
Args);
else
- TC = llvm::make_unique<toolchains::Linux>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
break;
case llvm::Triple::NaCl:
- TC = llvm::make_unique<toolchains::NaClToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::NaClToolChain>(*this, Target, Args);
break;
case llvm::Triple::Fuchsia:
- TC = llvm::make_unique<toolchains::Fuchsia>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args);
break;
case llvm::Triple::Solaris:
- TC = llvm::make_unique<toolchains::Solaris>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Solaris>(*this, Target, Args);
break;
case llvm::Triple::AMDHSA:
case llvm::Triple::AMDPAL:
case llvm::Triple::Mesa3D:
- TC = llvm::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
break;
case llvm::Triple::Win32:
switch (Target.getEnvironment()) {
default:
if (Target.isOSBinFormatELF())
- TC = llvm::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
else if (Target.isOSBinFormatMachO())
- TC = llvm::make_unique<toolchains::MachO>(*this, Target, Args);
+ TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
else
- TC = llvm::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
break;
case llvm::Triple::GNU:
- TC = llvm::make_unique<toolchains::MinGW>(*this, Target, Args);
+ TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);
break;
case llvm::Triple::Itanium:
- TC = llvm::make_unique<toolchains::CrossWindowsToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::CrossWindowsToolChain>(*this, Target,
Args);
break;
case llvm::Triple::MSVC:
case llvm::Triple::UnknownEnvironment:
if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
.startswith_lower("bfd"))
- TC = llvm::make_unique<toolchains::CrossWindowsToolChain>(
+ TC = std::make_unique<toolchains::CrossWindowsToolChain>(
*this, Target, Args);
else
TC =
- llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args);
+ std::make_unique<toolchains::MSVCToolChain>(*this, Target, Args);
break;
}
break;
case llvm::Triple::PS4:
- TC = llvm::make_unique<toolchains::PS4CPU>(*this, Target, Args);
+ TC = std::make_unique<toolchains::PS4CPU>(*this, Target, Args);
break;
case llvm::Triple::Contiki:
- TC = llvm::make_unique<toolchains::Contiki>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Contiki>(*this, Target, Args);
break;
case llvm::Triple::Hurd:
- TC = llvm::make_unique<toolchains::Hurd>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Hurd>(*this, Target, Args);
break;
default:
// Of these targets, Hexagon is the only one that might have
// an OS of Linux, in which case it got handled above already.
switch (Target.getArch()) {
case llvm::Triple::tce:
- TC = llvm::make_unique<toolchains::TCEToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::TCEToolChain>(*this, Target, Args);
break;
case llvm::Triple::tcele:
- TC = llvm::make_unique<toolchains::TCELEToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::TCELEToolChain>(*this, Target, Args);
break;
case llvm::Triple::hexagon:
- TC = llvm::make_unique<toolchains::HexagonToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target,
Args);
break;
case llvm::Triple::lanai:
- TC = llvm::make_unique<toolchains::LanaiToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::LanaiToolChain>(*this, Target, Args);
break;
case llvm::Triple::xcore:
- TC = llvm::make_unique<toolchains::XCoreToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::XCoreToolChain>(*this, Target, Args);
break;
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
- TC = llvm::make_unique<toolchains::WebAssembly>(*this, Target, Args);
+ TC = std::make_unique<toolchains::WebAssembly>(*this, Target, Args);
break;
case llvm::Triple::avr:
- TC = llvm::make_unique<toolchains::AVRToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::AVRToolChain>(*this, Target, Args);
break;
case llvm::Triple::msp430:
TC =
- llvm::make_unique<toolchains::MSP430ToolChain>(*this, Target, Args);
+ std::make_unique<toolchains::MSP430ToolChain>(*this, Target, Args);
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
- TC = llvm::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
+ TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
break;
default:
if (Target.getVendor() == llvm::Triple::Myriad)
- TC = llvm::make_unique<toolchains::MyriadToolChain>(*this, Target,
+ TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
Args);
else if (toolchains::BareMetal::handlesTarget(Target))
- TC = llvm::make_unique<toolchains::BareMetal>(*this, Target, Args);
+ TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
else if (Target.isOSBinFormatELF())
- TC = llvm::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
else if (Target.isOSBinFormatMachO())
- TC = llvm::make_unique<toolchains::MachO>(*this, Target, Args);
+ TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
else
- TC = llvm::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
+ TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
}
}
}