summaryrefslogtreecommitdiff
path: root/lib/Driver/ToolChains/Clang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/ToolChains/Clang.cpp')
-rw-r--r--lib/Driver/ToolChains/Clang.cpp889
1 files changed, 699 insertions, 190 deletions
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 8e9c4c6aecb87..75f16898dfaf6 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -19,12 +19,14 @@
#include "AMDGPU.h"
#include "CommonArgs.h"
#include "Hexagon.h"
+#include "MSP430.h"
#include "InputInfo.h"
#include "PS4CPU.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
+#include "clang/Driver/Distro.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
@@ -341,7 +343,7 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- aarch64::getAArch64TargetFeatures(D, Args, Features);
+ aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
@@ -363,6 +365,8 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
case llvm::Triple::amdgcn:
amdgpu::getAMDGPUTargetFeatures(D, Args, Features);
break;
+ case llvm::Triple::msp430:
+ msp430::getMSP430TargetFeatures(D, Args, Features);
}
// Find the last of each feature.
@@ -493,6 +497,8 @@ static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
if (A.getOption().matches(options::OPT_gline_tables_only) ||
A.getOption().matches(options::OPT_ggdb1))
return codegenoptions::DebugLineTablesOnly;
+ if (A.getOption().matches(options::OPT_gline_directives_only))
+ return codegenoptions::DebugDirectivesOnly;
return codegenoptions::LimitedDebugInfo;
}
@@ -524,11 +530,12 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
break;
}
- if (Triple.getOS() == llvm::Triple::NetBSD) {
+ if (Triple.isOSNetBSD()) {
return !areOptimizationsEnabled(Args);
}
- if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) {
+ if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
+ Triple.isOSHurd()) {
switch (Triple.getArch()) {
// Don't use a frame pointer on linux if optimizing for certain targets.
case llvm::Triple::mips64:
@@ -800,6 +807,29 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
CmdArgs.push_back("-fcoverage-mapping");
}
+ if (Args.hasArg(options::OPT_fprofile_exclude_files_EQ)) {
+ auto *Arg = Args.getLastArg(options::OPT_fprofile_exclude_files_EQ);
+ if (!Args.hasArg(options::OPT_coverage))
+ D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ << "-fprofile-exclude-files="
+ << "--coverage";
+
+ StringRef v = Arg->getValue();
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-fprofile-exclude-files=" + v)));
+ }
+
+ if (Args.hasArg(options::OPT_fprofile_filter_files_EQ)) {
+ auto *Arg = Args.getLastArg(options::OPT_fprofile_filter_files_EQ);
+ if (!Args.hasArg(options::OPT_coverage))
+ D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ << "-fprofile-filter-files="
+ << "--coverage";
+
+ StringRef v = Arg->getValue();
+ CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-filter-files=" + v)));
+ }
+
if (C.getArgs().hasArg(options::OPT_c) ||
C.getArgs().hasArg(options::OPT_S)) {
if (Output.isFilename()) {
@@ -889,6 +919,9 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
unsigned DwarfVersion,
llvm::DebuggerKind DebuggerTuning) {
switch (DebugInfoKind) {
+ case codegenoptions::DebugDirectivesOnly:
+ CmdArgs.push_back("-debug-info-kind=line-directives-only");
+ break;
case codegenoptions::DebugLineTablesOnly:
CmdArgs.push_back("-debug-info-kind=line-tables-only");
break;
@@ -1100,10 +1133,19 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue();
if (!isa<PrecompileJobAction>(JA)) {
CmdArgs.push_back("-include-pch");
- CmdArgs.push_back(Args.MakeArgString(D.GetClPchPath(C, ThroughHeader)));
+ CmdArgs.push_back(Args.MakeArgString(D.GetClPchPath(
+ C, !ThroughHeader.empty()
+ ? ThroughHeader
+ : llvm::sys::path::filename(Inputs[0].getBaseInput()))));
+ }
+
+ if (ThroughHeader.empty()) {
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-pch-through-hdrstop-") + (YcArg ? "create" : "use")));
+ } else {
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-pch-through-header=") + ThroughHeader));
}
- CmdArgs.push_back(
- Args.MakeArgString(Twine("-pch-through-header=") + ThroughHeader));
}
}
@@ -1114,42 +1156,26 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
bool IsFirstImplicitInclude = !RenderedImplicitInclude;
RenderedImplicitInclude = true;
- // Use PCH if the user requested it.
- bool UsePCH = D.CCCUsePCH;
-
- bool FoundPTH = false;
bool FoundPCH = false;
SmallString<128> P(A->getValue());
// We want the files to have a name like foo.h.pch. Add a dummy extension
// so that replace_extension does the right thing.
P += ".dummy";
- if (UsePCH) {
- llvm::sys::path::replace_extension(P, "pch");
- if (llvm::sys::fs::exists(P))
- FoundPCH = true;
- }
+ llvm::sys::path::replace_extension(P, "pch");
+ if (llvm::sys::fs::exists(P))
+ FoundPCH = true;
if (!FoundPCH) {
- llvm::sys::path::replace_extension(P, "pth");
- if (llvm::sys::fs::exists(P))
- FoundPTH = true;
- }
-
- if (!FoundPCH && !FoundPTH) {
llvm::sys::path::replace_extension(P, "gch");
if (llvm::sys::fs::exists(P)) {
- FoundPCH = UsePCH;
- FoundPTH = !UsePCH;
+ FoundPCH = true;
}
}
- if (FoundPCH || FoundPTH) {
+ if (FoundPCH) {
if (IsFirstImplicitInclude) {
A->claim();
- if (UsePCH)
- CmdArgs.push_back("-include-pch");
- else
- CmdArgs.push_back("-include-pth");
+ CmdArgs.push_back("-include-pch");
CmdArgs.push_back(Args.MakeArgString(P));
continue;
} else {
@@ -1283,21 +1309,28 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) {
}
}
-void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
- ArgStringList &CmdArgs, bool KernelOrKext) const {
+namespace {
+void RenderARMABI(const llvm::Triple &Triple, const ArgList &Args,
+ ArgStringList &CmdArgs) {
// Select the ABI to use.
// FIXME: Support -meabi.
// FIXME: Parts of this are duplicated in the backend, unify this somehow.
const char *ABIName = nullptr;
- if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
+ if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
ABIName = A->getValue();
- else {
+ } else {
std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
ABIName = llvm::ARM::computeDefaultTargetABI(Triple, CPU).data();
}
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName);
+}
+}
+
+void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
+ ArgStringList &CmdArgs, bool KernelOrKext) const {
+ RenderARMABI(Triple, Args, CmdArgs);
// Determine floating point ABI from the options & target defaults.
arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
@@ -1409,19 +1442,59 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
}
}
-void Clang::AddAArch64TargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+// Parse -mbranch-protection=<protection>[+<protection>]* where
+// <protection> ::= standard | none | [bti,pac-ret[+b-key,+leaf]*]
+// Returns a triple of (return address signing Scope, signing key, require
+// landing pads)
+static std::tuple<StringRef, StringRef, bool>
+ParseAArch64BranchProtection(const Driver &D, const ArgList &Args,
+ const Arg *A) {
+ StringRef Scope = "none";
+ StringRef Key = "a_key";
+ bool IndirectBranches = false;
- if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
- Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext))
- CmdArgs.push_back("-disable-red-zone");
+ StringRef Value = A->getValue();
+ // This maps onto -mbranch-protection=<scope>+<key>
+
+ if (Value.equals("standard")) {
+ Scope = "non-leaf";
+ Key = "a_key";
+ IndirectBranches = true;
+
+ } else if (!Value.equals("none")) {
+ SmallVector<StringRef, 4> BranchProtection;
+ StringRef(A->getValue()).split(BranchProtection, '+');
+
+ auto Protection = BranchProtection.begin();
+ while (Protection != BranchProtection.end()) {
+ if (Protection->equals("bti"))
+ IndirectBranches = true;
+ else if (Protection->equals("pac-ret")) {
+ Scope = "non-leaf";
+ while (++Protection != BranchProtection.end()) {
+ // Inner loop as "leaf" and "b-key" options must only appear attached
+ // to pac-ret.
+ if (Protection->equals("leaf"))
+ Scope = "all";
+ else if (Protection->equals("b-key"))
+ Key = "b_key";
+ else
+ break;
+ }
+ Protection--;
+ } else
+ D.Diag(diag::err_invalid_branch_protection)
+ << *Protection << A->getAsString(Args);
+ Protection++;
+ }
+ }
- if (!Args.hasFlag(options::OPT_mimplicit_float,
- options::OPT_mno_implicit_float, true))
- CmdArgs.push_back("-no-implicit-float");
+ return std::make_tuple(Scope, Key, IndirectBranches);
+}
+namespace {
+void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
+ ArgStringList &CmdArgs) {
const char *ABIName = nullptr;
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
ABIName = A->getValue();
@@ -1432,6 +1505,23 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName);
+}
+}
+
+void Clang::AddAArch64TargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+
+ if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
+ Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_fapple_kext))
+ CmdArgs.push_back("-disable-red-zone");
+
+ if (!Args.hasFlag(options::OPT_mimplicit_float,
+ options::OPT_mno_implicit_float, true))
+ CmdArgs.push_back("-no-implicit-float");
+
+ RenderAArch64ABI(Triple, Args, CmdArgs);
if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
options::OPT_mno_fix_cortex_a53_835769)) {
@@ -1455,6 +1545,35 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
else
CmdArgs.push_back("-aarch64-enable-global-merge=true");
}
+
+ // Enable/disable return address signing and indirect branch targets.
+ if (Arg *A = Args.getLastArg(options::OPT_msign_return_address_EQ,
+ options::OPT_mbranch_protection_EQ)) {
+
+ const Driver &D = getToolChain().getDriver();
+
+ StringRef Scope, Key;
+ bool IndirectBranches;
+
+ if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
+ Scope = A->getValue();
+ if (!Scope.equals("none") && !Scope.equals("non-leaf") &&
+ !Scope.equals("all"))
+ D.Diag(diag::err_invalid_branch_protection)
+ << Scope << A->getAsString(Args);
+ Key = "a_key";
+ IndirectBranches = false;
+ } else
+ std::tie(Scope, Key, IndirectBranches) =
+ ParseAArch64BranchProtection(D, Args, A);
+
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-msign-return-address=") + Scope));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
+ if (IndirectBranches)
+ CmdArgs.push_back("-mbranch-target-enforce");
+ }
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
@@ -1706,6 +1825,10 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
Args.hasArg(options::OPT_fapple_kext))
CmdArgs.push_back("-disable-red-zone");
+ if (!Args.hasFlag(options::OPT_mtls_direct_seg_refs,
+ options::OPT_mno_tls_direct_seg_refs, true))
+ CmdArgs.push_back("-mno-tls-direct-seg-refs");
+
// Default to avoid implicit floating-point for kernel/kext code, but allow
// that to be overridden with -mno-soft-float.
bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
@@ -2033,6 +2156,9 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
}
CmdArgs.push_back(Value.data());
TakeNextArg = true;
+ } else if (Value == "-fdebug-compilation-dir") {
+ CmdArgs.push_back("-fdebug-compilation-dir");
+ TakeNextArg = true;
} else {
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Value;
@@ -2045,6 +2171,11 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-target-feature");
CmdArgs.push_back(MipsTargetFeature);
}
+
+ // forward -fembed-bitcode to assmebler
+ if (C.getDriver().embedBitcodeEnabled() ||
+ C.getDriver().embedBitcodeMarkerOnly())
+ Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
}
static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
@@ -2066,6 +2197,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
StringRef DenormalFPMath = "";
StringRef FPContract = "";
+ if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
+ CmdArgs.push_back("-mlimit-float-precision");
+ CmdArgs.push_back(A->getValue());
+ }
+
for (const Arg *A : Args) {
switch (A->getOption().getID()) {
// If this isn't an FP option skip the claim below
@@ -2228,8 +2364,6 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
// Treat blocks as analysis entry points.
CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
- CmdArgs.push_back("-analyzer-eagerly-assume");
-
// Add default argument set.
if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
CmdArgs.push_back("-analyzer-checker=core");
@@ -2339,6 +2473,50 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args,
}
}
+static void RenderTrivialAutoVarInitOptions(const Driver &D,
+ const ToolChain &TC,
+ const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
+ StringRef TrivialAutoVarInit = "";
+
+ for (const Arg *A : Args) {
+ switch (A->getOption().getID()) {
+ default:
+ continue;
+ case options::OPT_ftrivial_auto_var_init: {
+ A->claim();
+ StringRef Val = A->getValue();
+ if (Val == "uninitialized" || Val == "zero" || Val == "pattern")
+ TrivialAutoVarInit = Val;
+ else
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << Val;
+ break;
+ }
+ }
+ }
+
+ if (TrivialAutoVarInit.empty())
+ switch (DefaultTrivialAutoVarInit) {
+ case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+ break;
+ case LangOptions::TrivialAutoVarInitKind::Pattern:
+ TrivialAutoVarInit = "pattern";
+ break;
+ case LangOptions::TrivialAutoVarInitKind::Zero:
+ TrivialAutoVarInit = "zero";
+ break;
+ }
+
+ if (!TrivialAutoVarInit.empty()) {
+ if (TrivialAutoVarInit == "zero" && !Args.hasArg(options::OPT_enable_trivial_var_init_zero))
+ D.Diag(diag::err_drv_trivial_auto_var_init_zero_disabled);
+ CmdArgs.push_back(
+ Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit));
+ }
+}
+
static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) {
const unsigned ForwardedArguments[] = {
options::OPT_cl_opt_disable,
@@ -2658,8 +2836,10 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
CmdArgs.push_back("-fno-signed-char");
}
- if (Args.hasFlag(options::OPT_fchar8__t, options::OPT_fno_char8__t, false))
- CmdArgs.push_back("-fchar8_t");
+ // The default depends on the language standard.
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_fchar8__t, options::OPT_fno_char8__t))
+ A->render(Args, CmdArgs);
if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
options::OPT_fno_short_wchar)) {
@@ -2669,8 +2849,8 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
} else {
bool IsARM = T.isARM() || T.isThumb() || T.isAArch64();
CmdArgs.push_back("-fwchar-type=int");
- if (IsARM && !(T.isOSWindows() || T.getOS() == llvm::Triple::NetBSD ||
- T.getOS() == llvm::Triple::OpenBSD))
+ if (IsARM && !(T.isOSWindows() || T.isOSNetBSD() ||
+ T.isOSOpenBSD()))
CmdArgs.push_back("-fno-signed-wchar");
else
CmdArgs.push_back("-fsigned-wchar");
@@ -2701,7 +2881,6 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
// When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
// to do Array/Dictionary subscripting by default.
if (Arch == llvm::Triple::x86 && T.isMacOSX() &&
- !T.isMacOSXVersionLT(10, 7) &&
Runtime.getKind() == ObjCRuntime::FragileMacOSX && Runtime.isNeXTFamily())
CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
@@ -2737,6 +2916,18 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
Args.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions);
}
+ // Allow the user to control whether messages can be converted to runtime
+ // functions.
+ if (types::isObjC(Input.getType())) {
+ auto *Arg = Args.getLastArg(
+ options::OPT_fobjc_convert_messages_to_runtime_calls,
+ options::OPT_fno_objc_convert_messages_to_runtime_calls);
+ if (Arg &&
+ Arg->getOption().matches(
+ options::OPT_fno_objc_convert_messages_to_runtime_calls))
+ CmdArgs.push_back("-fno-objc-convert-messages-to-runtime-calls");
+ }
+
// -fobjc-infer-related-result-type is the default, except in the Objective-C
// rewriter.
if (InferCovariantReturns)
@@ -2872,12 +3063,35 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
CmdArgs.push_back("-fno-spell-checking");
}
+enum class DwarfFissionKind { None, Split, Single };
+
+static DwarfFissionKind getDebugFissionKind(const Driver &D,
+ const ArgList &Args, Arg *&Arg) {
+ Arg =
+ Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ);
+ if (!Arg)
+ return DwarfFissionKind::None;
+
+ if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
+ return DwarfFissionKind::Split;
+
+ StringRef Value = Arg->getValue();
+ if (Value == "split")
+ return DwarfFissionKind::Split;
+ if (Value == "single")
+ return DwarfFissionKind::Single;
+
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << Arg->getOption().getName() << Arg->getValue();
+ return DwarfFissionKind::None;
+}
+
static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
const llvm::Triple &T, const ArgList &Args,
bool EmitCodeView, bool IsWindowsMSVC,
ArgStringList &CmdArgs,
codegenoptions::DebugInfoKind &DebugInfoKind,
- const Arg *&SplitDWARFArg) {
+ DwarfFissionKind &DwarfFission) {
if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
options::OPT_fno_debug_info_for_profiling, false) &&
checkDebugInfoOption(
@@ -2902,10 +3116,12 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
Args.ClaimAllArgs(options::OPT_g_Group);
- SplitDWARFArg = Args.getLastArg(options::OPT_gsplit_dwarf);
+ Arg* SplitDWARFArg;
+ DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg);
- if (SplitDWARFArg && !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) {
- SplitDWARFArg = nullptr;
+ if (DwarfFission != DwarfFissionKind::None &&
+ !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) {
+ DwarfFission = DwarfFissionKind::None;
SplitDWARFInlining = false;
}
@@ -2922,12 +3138,13 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
// composing split-dwarf and line-tables-only, so let those compose
// naturally in that case. And if you just turned off debug info,
// (-gsplit-dwarf -g0) - do that.
- if (SplitDWARFArg) {
+ if (DwarfFission != DwarfFissionKind::None) {
if (A->getIndex() > SplitDWARFArg->getIndex()) {
if (DebugInfoKind == codegenoptions::NoDebugInfo ||
+ DebugInfoKind == codegenoptions::DebugDirectivesOnly ||
(DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
SplitDWARFInlining))
- SplitDWARFArg = nullptr;
+ DwarfFission = DwarfFissionKind::None;
} else if (SplitDWARFInlining)
DebugInfoKind = codegenoptions::NoDebugInfo;
}
@@ -2960,21 +3177,28 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
if (checkDebugInfoOption(A, Args, D, TC))
DWARFVersion = DwarfVersionNum(A->getSpelling());
- // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility
- // argument parsing.
- if (EmitCodeView) {
- if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) {
- EmitCodeView = checkDebugInfoOption(A, Args, D, TC);
- if (EmitCodeView) {
- // DWARFVersion remains at 0 if no explicit choice was made.
- CmdArgs.push_back("-gcodeview");
- }
- }
+ if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) {
+ if (checkDebugInfoOption(A, Args, D, TC))
+ EmitCodeView = true;
}
+ // If the user asked for debug info but did not explicitly specify -gcodeview
+ // or -gdwarf, ask the toolchain for the default format.
if (!EmitCodeView && DWARFVersion == 0 &&
- DebugInfoKind != codegenoptions::NoDebugInfo)
- DWARFVersion = TC.GetDefaultDwarfVersion();
+ DebugInfoKind != codegenoptions::NoDebugInfo) {
+ switch (TC.getDefaultDebugFormat()) {
+ case codegenoptions::DIF_CodeView:
+ EmitCodeView = true;
+ break;
+ case codegenoptions::DIF_DWARF:
+ DWARFVersion = TC.GetDefaultDwarfVersion();
+ break;
+ }
+ }
+
+ // -gline-directives-only supported only for the DWARF debug info.
+ if (DWARFVersion == 0 && DebugInfoKind == codegenoptions::DebugDirectivesOnly)
+ DebugInfoKind = codegenoptions::NoDebugInfo;
// We ignore flag -gstrict-dwarf for now.
// And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
@@ -2993,10 +3217,11 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-dwarf-column-info");
// FIXME: Move backend command line options to the module.
- // If -gline-tables-only is the last option it wins.
+ // If -gline-tables-only or -gline-directives-only is the last option it wins.
if (const Arg *A = Args.getLastArg(options::OPT_gmodules))
if (checkDebugInfoOption(A, Args, D, TC)) {
- if (DebugInfoKind != codegenoptions::DebugLineTablesOnly) {
+ if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
+ DebugInfoKind != codegenoptions::DebugDirectivesOnly) {
DebugInfoKind = codegenoptions::LimitedDebugInfo;
CmdArgs.push_back("-dwarf-ext-refs");
CmdArgs.push_back("-fmodule-format=obj");
@@ -3005,15 +3230,19 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
// -gsplit-dwarf should turn on -g and enable the backend dwarf
// splitting and extraction.
- // FIXME: Currently only works on Linux.
- if (T.isOSLinux()) {
+ // FIXME: Currently only works on Linux and Fuchsia.
+ if (T.isOSLinux() || T.isOSFuchsia()) {
if (!SplitDWARFInlining)
CmdArgs.push_back("-fno-split-dwarf-inlining");
- if (SplitDWARFArg) {
+ if (DwarfFission != DwarfFissionKind::None) {
if (DebugInfoKind == codegenoptions::NoDebugInfo)
DebugInfoKind = codegenoptions::LimitedDebugInfo;
- CmdArgs.push_back("-enable-split-dwarf");
+
+ if (DwarfFission == DwarfFissionKind::Single)
+ CmdArgs.push_back("-enable-split-dwarf=single");
+ else
+ CmdArgs.push_back("-enable-split-dwarf");
}
}
@@ -3044,6 +3273,19 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-gembed-source");
}
+ if (EmitCodeView) {
+ CmdArgs.push_back("-gcodeview");
+
+ // Emit codeview type hashes if requested.
+ if (Args.hasFlag(options::OPT_gcodeview_ghash,
+ options::OPT_gno_codeview_ghash, false)) {
+ CmdArgs.push_back("-gcodeview-ghash");
+ }
+ }
+
+ // Adjust the debug info kind for the given toolchain.
+ TC.adjustDebugInfoKind(DebugInfoKind, Args);
+
RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion,
DebuggerTuning);
@@ -3055,11 +3297,24 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-debug-info-macro");
// -ggnu-pubnames turns on gnu style pubnames in the backend.
- if (Args.hasFlag(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
- false))
- if (checkDebugInfoOption(Args.getLastArg(options::OPT_ggnu_pubnames), Args,
- D, TC))
- CmdArgs.push_back("-ggnu-pubnames");
+ const auto *PubnamesArg =
+ Args.getLastArg(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
+ options::OPT_gpubnames, options::OPT_gno_pubnames);
+ if (DwarfFission != DwarfFissionKind::None ||
+ DebuggerTuning == llvm::DebuggerKind::LLDB ||
+ (PubnamesArg && checkDebugInfoOption(PubnamesArg, Args, D, TC)))
+ if (!PubnamesArg ||
+ (!PubnamesArg->getOption().matches(options::OPT_gno_gnu_pubnames) &&
+ !PubnamesArg->getOption().matches(options::OPT_gno_pubnames)))
+ CmdArgs.push_back(PubnamesArg && PubnamesArg->getOption().matches(
+ options::OPT_gpubnames)
+ ? "-gpubnames"
+ : "-ggnu-pubnames");
+
+ if (Args.hasFlag(options::OPT_fdebug_ranges_base_address,
+ options::OPT_fno_debug_ranges_base_address, false)) {
+ CmdArgs.push_back("-fdebug-ranges-base-address");
+ }
// -gdwarf-aranges turns on the emission of the aranges section in the
// backend.
@@ -3103,32 +3358,64 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args, const char *LinkingOutput) const {
- const llvm::Triple &RawTriple = getToolChain().getTriple();
- const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+ const auto &TC = getToolChain();
+ const llvm::Triple &RawTriple = TC.getTriple();
+ const llvm::Triple &Triple = TC.getEffectiveTriple();
const std::string &TripleStr = Triple.getTriple();
bool KernelOrKext =
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
- const Driver &D = getToolChain().getDriver();
+ const Driver &D = TC.getDriver();
ArgStringList CmdArgs;
// Check number of inputs for sanity. We need at least one input.
assert(Inputs.size() >= 1 && "Must have at least one input.");
- const InputInfo &Input = Inputs[0];
// CUDA/HIP compilation may have multiple inputs (source file + results of
// device-side compilations). OpenMP device jobs also take the host IR as a
- // second input. All other jobs are expected to have exactly one
- // input.
+ // second input. Module precompilation accepts a list of header files to
+ // include as part of the module. All other jobs are expected to have exactly
+ // one input.
bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
- assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) ||
- Inputs.size() == 1) &&
- "Unable to handle multiple inputs.");
-
- const llvm::Triple *AuxTriple =
- IsCuda ? getToolChain().getAuxTriple() : nullptr;
+ bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
+
+ // A header module compilation doesn't have a main input file, so invent a
+ // fake one as a placeholder.
+ const char *ModuleName = [&]{
+ auto *ModuleNameArg = Args.getLastArg(options::OPT_fmodule_name_EQ);
+ return ModuleNameArg ? ModuleNameArg->getValue() : "";
+ }();
+ InputInfo HeaderModuleInput(Inputs[0].getType(), ModuleName, ModuleName);
+
+ const InputInfo &Input =
+ IsHeaderModulePrecompile ? HeaderModuleInput : Inputs[0];
+
+ InputInfoList ModuleHeaderInputs;
+ const InputInfo *CudaDeviceInput = nullptr;
+ const InputInfo *OpenMPDeviceInput = nullptr;
+ for (const InputInfo &I : Inputs) {
+ if (&I == &Input) {
+ // This is the primary input.
+ } else if (IsHeaderModulePrecompile &&
+ types::getPrecompiledType(I.getType()) == types::TY_PCH) {
+ types::ID Expected = HeaderModuleInput.getType();
+ if (I.getType() != Expected) {
+ D.Diag(diag::err_drv_module_header_wrong_kind)
+ << I.getFilename() << types::getTypeName(I.getType())
+ << types::getTypeName(Expected);
+ }
+ ModuleHeaderInputs.push_back(I);
+ } else if ((IsCuda || IsHIP) && !CudaDeviceInput) {
+ CudaDeviceInput = &I;
+ } else if (IsOpenMPDevice && !OpenMPDeviceInput) {
+ OpenMPDeviceInput = &I;
+ } else {
+ llvm_unreachable("unexpectedly given multiple inputs");
+ }
+ }
+ const llvm::Triple *AuxTriple = IsCuda ? TC.getAuxTriple() : nullptr;
bool IsWindowsGNU = RawTriple.isWindowsGNUEnvironment();
bool IsWindowsCygnus = RawTriple.isWindowsCygwinEnvironment();
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
@@ -3204,7 +3491,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Push all default warning arguments that are specific to
// the given target. These come before user provided warning options
// are provided.
- getToolChain().addClangWarningOptions(CmdArgs);
+ TC.addClangWarningOptions(CmdArgs);
// Select the appropriate action.
RewriteKind rewriteKind = RK_None;
@@ -3231,17 +3518,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Also ignore explicit -force_cpusubtype_ALL option.
(void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
} else if (isa<PrecompileJobAction>(JA)) {
- // Use PCH if the user requested it.
- bool UsePCH = D.CCCUsePCH;
-
if (JA.getType() == types::TY_Nothing)
CmdArgs.push_back("-fsyntax-only");
else if (JA.getType() == types::TY_ModuleFile)
- CmdArgs.push_back("-emit-module-interface");
- else if (UsePCH)
- CmdArgs.push_back("-emit-pch");
+ CmdArgs.push_back(IsHeaderModulePrecompile
+ ? "-emit-header-module"
+ : "-emit-module-interface");
else
- CmdArgs.push_back("-emit-pth");
+ CmdArgs.push_back("-emit-pch");
} else if (isa<VerifyPCHJobAction>(JA)) {
CmdArgs.push_back("-verify-pch");
} else {
@@ -3305,13 +3589,116 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
// Embed-bitcode option.
+ // Only white-listed flags below are allowed to be embedded.
if (C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
(isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
// Add flags implied by -fembed-bitcode.
Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
// Disable all llvm IR level optimizations.
CmdArgs.push_back("-disable-llvm-passes");
+
+ // reject options that shouldn't be supported in bitcode
+ // also reject kernel/kext
+ static const constexpr unsigned kBitcodeOptionBlacklist[] = {
+ options::OPT_mkernel,
+ options::OPT_fapple_kext,
+ options::OPT_ffunction_sections,
+ options::OPT_fno_function_sections,
+ options::OPT_fdata_sections,
+ options::OPT_fno_data_sections,
+ options::OPT_funique_section_names,
+ options::OPT_fno_unique_section_names,
+ options::OPT_mrestrict_it,
+ options::OPT_mno_restrict_it,
+ options::OPT_mstackrealign,
+ options::OPT_mno_stackrealign,
+ options::OPT_mstack_alignment,
+ options::OPT_mcmodel_EQ,
+ options::OPT_mlong_calls,
+ options::OPT_mno_long_calls,
+ options::OPT_ggnu_pubnames,
+ options::OPT_gdwarf_aranges,
+ options::OPT_fdebug_types_section,
+ options::OPT_fno_debug_types_section,
+ options::OPT_fdwarf_directory_asm,
+ options::OPT_fno_dwarf_directory_asm,
+ options::OPT_mrelax_all,
+ options::OPT_mno_relax_all,
+ options::OPT_ftrap_function_EQ,
+ options::OPT_ffixed_r9,
+ options::OPT_mfix_cortex_a53_835769,
+ options::OPT_mno_fix_cortex_a53_835769,
+ options::OPT_ffixed_x18,
+ options::OPT_mglobal_merge,
+ options::OPT_mno_global_merge,
+ options::OPT_mred_zone,
+ options::OPT_mno_red_zone,
+ options::OPT_Wa_COMMA,
+ options::OPT_Xassembler,
+ options::OPT_mllvm,
+ };
+ for (const auto &A : Args)
+ if (std::find(std::begin(kBitcodeOptionBlacklist),
+ std::end(kBitcodeOptionBlacklist),
+ A->getOption().getID()) !=
+ std::end(kBitcodeOptionBlacklist))
+ D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling();
+
+ // Render the CodeGen options that need to be passed.
+ if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
+ options::OPT_fno_optimize_sibling_calls))
+ CmdArgs.push_back("-mdisable-tail-calls");
+
+ RenderFloatingPointOptions(TC, D, isOptimizationLevelFast(Args), Args,
+ CmdArgs);
+
+ // Render ABI arguments
+ switch (TC.getArch()) {
+ default: break;
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumbeb:
+ RenderARMABI(Triple, Args, CmdArgs);
+ break;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ RenderAArch64ABI(Triple, Args, CmdArgs);
+ break;
+ }
+
+ // Optimization level for CodeGen.
+ if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+ if (A->getOption().matches(options::OPT_O4)) {
+ CmdArgs.push_back("-O3");
+ D.Diag(diag::warn_O4_is_O3);
+ } else {
+ A->render(Args, CmdArgs);
+ }
+ }
+
+ // Input/Output file.
+ if (Output.getType() == types::TY_Dependencies) {
+ // Handled with other dependency code.
+ } else if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ } else {
+ assert(Output.isNothing() && "Input output.");
+ }
+
+ for (const auto &II : Inputs) {
+ addDashXForInput(Args, II, CmdArgs);
+ if (II.isFilename())
+ CmdArgs.push_back(II.getFilename());
+ else
+ II.getInputArg().renderAsInput(Args, CmdArgs);
+ }
+
+ C.addCommand(llvm::make_unique<Command>(JA, *this, D.getClangProgramPath(),
+ CmdArgs, Inputs));
+ return;
}
+
if (C.getDriver().embedBitcodeMarkerOnly() && !C.getDriver().isUsingLTO())
CmdArgs.push_back("-fembed-bitcode=marker");
@@ -3346,12 +3733,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_static))
CmdArgs.push_back("-static-define");
+ if (Args.hasArg(options::OPT_municode))
+ CmdArgs.push_back("-DUNICODE");
+
if (isa<AnalyzeJobAction>(JA))
RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
+ // Enable compatilibily mode to avoid analyzer-config related errors.
+ // Since we can't access frontend flags through hasArg, let's manually iterate
+ // through them.
+ bool FoundAnalyzerConfig = false;
+ for (auto Arg : Args.filtered(options::OPT_Xclang))
+ if (StringRef(Arg->getValue()) == "-analyzer-config") {
+ FoundAnalyzerConfig = true;
+ break;
+ }
+ if (!FoundAnalyzerConfig)
+ for (auto Arg : Args.filtered(options::OPT_Xanalyzer))
+ if (StringRef(Arg->getValue()) == "-analyzer-config") {
+ FoundAnalyzerConfig = true;
+ break;
+ }
+ if (FoundAnalyzerConfig)
+ CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+
CheckCodeGenerationOptions(D, Args);
- unsigned FunctionAlignment = ParseFunctionAlignment(getToolChain(), Args);
+ unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
assert(FunctionAlignment <= 31 && "function alignment will be truncated!");
if (FunctionAlignment) {
CmdArgs.push_back("-function-alignment");
@@ -3361,8 +3769,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
llvm::Reloc::Model RelocationModel;
unsigned PICLevel;
bool IsPIE;
- std::tie(RelocationModel, PICLevel, IsPIE) =
- ParsePICArgs(getToolChain(), Args);
+ std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(TC, Args);
const char *RMName = RelocationModelName(RelocationModel);
@@ -3390,13 +3797,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-mthread-model");
if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) {
- if (!getToolChain().isThreadModelSupported(A->getValue()))
+ if (!TC.isThreadModelSupported(A->getValue()))
D.Diag(diag::err_drv_invalid_thread_model_for_target)
<< A->getValue() << A->getAsString(Args);
CmdArgs.push_back(A->getValue());
}
else
- CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
+ CmdArgs.push_back(Args.MakeArgString(TC.getThreadModel()));
Args.AddLastArg(CmdArgs, options::OPT_fveclib);
@@ -3451,7 +3858,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
options::OPT_freg_struct_return)) {
- if (getToolChain().getArch() != llvm::Triple::x86) {
+ if (TC.getArch() != llvm::Triple::x86) {
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getSpelling() << RawTriple.str();
} else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
@@ -3516,18 +3923,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fsplit_stack))
CmdArgs.push_back("-split-stacks");
- RenderFloatingPointOptions(getToolChain(), D, OFastEnabled, Args, CmdArgs);
+ RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs);
// Decide whether to use verbose asm. Verbose assembly is the default on
// toolchains which have the integrated assembler on by default.
- bool IsIntegratedAssemblerDefault =
- getToolChain().IsIntegratedAssemblerDefault();
+ bool IsIntegratedAssemblerDefault = TC.IsIntegratedAssemblerDefault();
if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
IsIntegratedAssemblerDefault) ||
Args.hasArg(options::OPT_dA))
CmdArgs.push_back("-masm-verbose");
- if (!getToolChain().useIntegratedAs())
+ if (!TC.useIntegratedAs())
CmdArgs.push_back("-no-integrated-as");
if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
@@ -3580,20 +3986,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool AsynchronousUnwindTables =
Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
options::OPT_fno_asynchronous_unwind_tables,
- (getToolChain().IsUnwindTablesDefault(Args) ||
- getToolChain().getSanitizerArgs().needsUnwindTables()) &&
+ (TC.IsUnwindTablesDefault(Args) ||
+ TC.getSanitizerArgs().needsUnwindTables()) &&
!Freestanding);
if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
AsynchronousUnwindTables))
CmdArgs.push_back("-munwind-tables");
- getToolChain().addClangTargetOptions(Args, CmdArgs,
- JA.getOffloadingDeviceKind());
-
- if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
- CmdArgs.push_back("-mlimit-float-precision");
- CmdArgs.push_back(A->getValue());
- }
+ TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind());
// FIXME: Handle -mtune=.
(void)Args.hasArg(options::OPT_mtune_EQ);
@@ -3620,22 +4020,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
types::ID InputType = Input.getType();
if (D.IsCLMode())
AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
- else
- EmitCodeView = Args.hasArg(options::OPT_gcodeview);
- const Arg *SplitDWARFArg = nullptr;
- RenderDebugOptions(getToolChain(), D, RawTriple, Args, EmitCodeView,
- IsWindowsMSVC, CmdArgs, DebugInfoKind, SplitDWARFArg);
+ DwarfFissionKind DwarfFission;
+ RenderDebugOptions(TC, D, RawTriple, Args, EmitCodeView, IsWindowsMSVC,
+ CmdArgs, DebugInfoKind, DwarfFission);
// Add the split debug info name to the command lines here so we
// can propagate it to the backend.
- bool SplitDWARF = SplitDWARFArg && RawTriple.isOSLinux() &&
+ bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) &&
+ (RawTriple.isOSLinux() || RawTriple.isOSFuchsia()) &&
(isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
isa<BackendJobAction>(JA));
const char *SplitDWARFOut;
if (SplitDWARF) {
CmdArgs.push_back("-split-dwarf-file");
- SplitDWARFOut = SplitDebugName(Args, Input);
+ SplitDWARFOut = SplitDebugName(Args, Output);
CmdArgs.push_back(SplitDWARFOut);
}
@@ -3653,7 +4052,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_fallow_unsupported)) {
Arg *Unsupported;
if (types::isCXX(InputType) && RawTriple.isOSDarwin() &&
- getToolChain().getArch() == llvm::Triple::x86) {
+ TC.getArch() == llvm::Triple::x86) {
if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
(Unsupported = Args.getLastArg(options::OPT_mkernel)))
D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
@@ -3717,9 +4116,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
ABICompatArg->render(Args, CmdArgs);
// Add runtime flag for PS4 when PGO, coverage, or sanitizers are enabled.
- if (RawTriple.isPS4CPU()) {
- PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);
- PS4cpu::addSanitizerArgs(getToolChain(), CmdArgs);
+ if (RawTriple.isPS4CPU() &&
+ !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+ PS4cpu::addProfileRTArgs(TC, Args, CmdArgs);
+ PS4cpu::addSanitizerArgs(TC, CmdArgs);
}
// Pass options for controlling the default header search paths.
@@ -3867,10 +4267,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fno-gnu-keywords");
}
- if (ShouldDisableDwarfDirectory(Args, getToolChain()))
+ if (ShouldDisableDwarfDirectory(Args, TC))
CmdArgs.push_back("-fno-dwarf-directory-asm");
- if (ShouldDisableAutolink(Args, getToolChain()))
+ if (ShouldDisableAutolink(Args, TC))
CmdArgs.push_back("-fno-autolink");
// Add in -fdebug-compilation-dir if necessary.
@@ -3916,6 +4316,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_relocatable_pch))
CmdArgs.push_back("-relocatable-pch");
+ if (const Arg *A = Args.getLastArg(options::OPT_fcf_runtime_abi_EQ)) {
+ static const char *kCFABIs[] = {
+ "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
+ };
+
+ if (find(kCFABIs, StringRef(A->getValue())) == std::end(kCFABIs))
+ D.Diag(diag::err_drv_invalid_cf_runtime_abi) << A->getValue();
+ else
+ A->render(Args, CmdArgs);
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
CmdArgs.push_back("-fconstant-string-class");
CmdArgs.push_back(A->getValue());
@@ -3983,6 +4394,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
+ Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden);
Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
@@ -3993,6 +4405,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
Args.AddLastArg(CmdArgs, options::OPT_femulated_tls,
options::OPT_fno_emulated_tls);
+ Args.AddLastArg(CmdArgs, options::OPT_fkeep_static_consts);
// AltiVec-like language extensions aren't relevant for assembling.
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
@@ -4022,11 +4435,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
options::OPT_fno_openmp_simd);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
+ Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
+ Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
+ if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
+ options::OPT_fno_openmp_optimistic_collapse,
+ /*Default=*/false))
+ CmdArgs.push_back("-fopenmp-optimistic-collapse");
// When in OpenMP offloading mode with NVPTX target, forward
// cuda-mode flag
- Args.AddLastArg(CmdArgs, options::OPT_fopenmp_cuda_mode,
- options::OPT_fno_openmp_cuda_mode);
+ if (Args.hasFlag(options::OPT_fopenmp_cuda_mode,
+ options::OPT_fno_openmp_cuda_mode, /*Default=*/false))
+ CmdArgs.push_back("-fopenmp-cuda-mode");
+
+ // When in OpenMP offloading mode with NVPTX target, check if full runtime
+ // is required.
+ if (Args.hasFlag(options::OPT_fopenmp_cuda_force_full_runtime,
+ options::OPT_fno_openmp_cuda_force_full_runtime,
+ /*Default=*/false))
+ CmdArgs.push_back("-fopenmp-cuda-force-full-runtime");
break;
default:
// By default, if Clang doesn't know how to generate useful OpenMP code
@@ -4043,16 +4470,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
}
- const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
- Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
+ const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
+ Sanitize.addArgs(TC, Args, CmdArgs, InputType);
- const XRayArgs &XRay = getToolChain().getXRayArgs();
- XRay.addArgs(getToolChain(), Args, CmdArgs, InputType);
+ const XRayArgs &XRay = TC.getXRayArgs();
+ XRay.addArgs(TC, Args, CmdArgs, InputType);
- if (getToolChain().SupportsProfiling())
+ if (TC.SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_pg);
- if (getToolChain().SupportsProfiling())
+ if (TC.SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_mfentry);
// -flax-vector-conversions is default.
@@ -4099,7 +4526,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_pthread);
- RenderSSPOptions(getToolChain(), Args, CmdArgs, KernelOrKext);
+ if (Args.hasFlag(options::OPT_mspeculative_load_hardening, options::OPT_mno_speculative_load_hardening,
+ false))
+ CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening"));
+
+ RenderSSPOptions(TC, Args, CmdArgs, KernelOrKext);
+ RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
// Translate -mstackrealign
if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
@@ -4158,8 +4590,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else
A->render(Args, CmdArgs);
}
+ Args.AddLastArg(CmdArgs, options::OPT_fprofile_remapping_file_EQ);
- RenderBuiltinOptions(getToolChain(), RawTriple, Args, CmdArgs);
+ RenderBuiltinOptions(TC, RawTriple, Args, CmdArgs);
if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
options::OPT_fno_assume_sane_operator_new))
@@ -4167,19 +4600,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fblocks=0 is default.
if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
- getToolChain().IsBlocksDefault()) ||
+ TC.IsBlocksDefault()) ||
(Args.hasArg(options::OPT_fgnu_runtime) &&
Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
!Args.hasArg(options::OPT_fno_blocks))) {
CmdArgs.push_back("-fblocks");
- if (!Args.hasArg(options::OPT_fgnu_runtime) &&
- !getToolChain().hasBlocksRuntime())
+ if (!Args.hasArg(options::OPT_fgnu_runtime) && !TC.hasBlocksRuntime())
CmdArgs.push_back("-fblocks-runtime-optional");
}
// -fencode-extended-block-signature=1 is default.
- if (getToolChain().IsEncodeExtendedBlockSignatureDefault())
+ if (TC.IsEncodeExtendedBlockSignatureDefault())
CmdArgs.push_back("-fencode-extended-block-signature");
if (Args.hasFlag(options::OPT_fcoroutines_ts, options::OPT_fno_coroutines_ts,
@@ -4204,7 +4636,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_felide_constructors, false))
CmdArgs.push_back("-fno-elide-constructors");
- ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode();
+ ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
if (KernelOrKext || (types::isCXX(InputType) &&
(RTTIMode == ToolChain::RM_Disabled)))
@@ -4212,7 +4644,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fshort-enums=0 is default for all architectures except Hexagon.
if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
- getToolChain().getArch() == llvm::Triple::hexagon))
+ TC.getArch() == llvm::Triple::hexagon))
CmdArgs.push_back("-fshort-enums");
RenderCharacterOptions(Args, AuxTriple ? *AuxTriple : RawTriple, CmdArgs);
@@ -4222,8 +4654,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
!RawTriple.isOSWindows() &&
RawTriple.getOS() != llvm::Triple::Solaris &&
- getToolChain().getArch() != llvm::Triple::hexagon &&
- getToolChain().getArch() != llvm::Triple::xcore &&
+ TC.getArch() != llvm::Triple::xcore &&
((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) ||
RawTriple.hasEnvironment())) ||
KernelOrKext)
@@ -4252,7 +4683,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_ms_extensions, true))))
CmdArgs.push_back("-fms-compatibility");
- VersionTuple MSVT = getToolChain().computeMSVCVersion(&D, Args);
+ VersionTuple MSVT = TC.computeMSVCVersion(&D, Args);
if (!MSVT.empty())
CmdArgs.push_back(
Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString()));
@@ -4330,8 +4761,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_experimental_new_pass_manager);
ObjCRuntime Runtime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
- RenderObjCOptions(getToolChain(), D, RawTriple, Args, Runtime,
- rewriteKind != RK_None, Input, CmdArgs);
+ RenderObjCOptions(TC, D, RawTriple, Args, Runtime, rewriteKind != RK_None,
+ Input, CmdArgs);
if (Args.hasFlag(options::OPT_fapplication_extension,
options::OPT_fno_application_extension, false))
@@ -4339,8 +4770,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Handle GCC-style exception args.
if (!C.getDriver().IsCLMode())
- addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, Runtime,
- CmdArgs);
+ addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs);
// Handle exception personalities
Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
@@ -4355,7 +4785,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Opt.matches(options::OPT_fdwarf_exceptions))
CmdArgs.push_back("-fdwarf-exceptions");
} else {
- switch (getToolChain().GetExceptionModel(Args)) {
+ switch (TC.GetExceptionModel(Args)) {
default:
break;
case llvm::ExceptionHandling::DwarfCFI:
@@ -4592,7 +5022,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// nice to enable this when doing a crashdump for modules as well.
if (Args.hasFlag(options::OPT_frewrite_includes,
options::OPT_fno_rewrite_includes, false) ||
- (C.isForDiagnostics() && (RewriteImports || !HaveModules)))
+ (C.isForDiagnostics() && !HaveModules))
CmdArgs.push_back("-frewrite-includes");
// Only allow -traditional or -traditional-cpp outside in preprocessing modes.
@@ -4685,23 +5115,39 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
addDashXForInput(Args, Input, CmdArgs);
- if (Input.isFilename())
- CmdArgs.push_back(Input.getFilename());
- else
- Input.getInputArg().renderAsInput(Args, CmdArgs);
+ ArrayRef<InputInfo> FrontendInputs = Input;
+ if (IsHeaderModulePrecompile)
+ FrontendInputs = ModuleHeaderInputs;
+ else if (Input.isNothing())
+ FrontendInputs = {};
+
+ for (const InputInfo &Input : FrontendInputs) {
+ if (Input.isFilename())
+ CmdArgs.push_back(Input.getFilename());
+ else
+ Input.getInputArg().renderAsInput(Args, CmdArgs);
+ }
Args.AddAllArgs(CmdArgs, options::OPT_undef);
const char *Exec = D.getClangProgramPath();
- // Optionally embed the -cc1 level arguments into the debug info, for build
- // analysis.
+ // Optionally embed the -cc1 level arguments into the debug info or a
+ // section, for build analysis.
// Also record command line arguments into the debug info if
// -grecord-gcc-switches options is set on.
// By default, -gno-record-gcc-switches is set on and no recording.
- if (getToolChain().UseDwarfDebugFlags() ||
- Args.hasFlag(options::OPT_grecord_gcc_switches,
- options::OPT_gno_record_gcc_switches, false)) {
+ auto GRecordSwitches =
+ Args.hasFlag(options::OPT_grecord_command_line,
+ options::OPT_gno_record_command_line, false);
+ auto FRecordSwitches =
+ Args.hasFlag(options::OPT_frecord_command_line,
+ options::OPT_fno_record_command_line, false);
+ if (FRecordSwitches && !Triple.isOSBinFormatELF())
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args)
+ << TripleStr;
+ if (TC.UseDwarfDebugFlags() || GRecordSwitches || FRecordSwitches) {
ArgStringList OriginalArgs;
for (const auto &Arg : Args)
Arg->render(Args, OriginalArgs);
@@ -4714,21 +5160,27 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Flags += " ";
Flags += EscapedArg;
}
- CmdArgs.push_back("-dwarf-debug-flags");
- CmdArgs.push_back(Args.MakeArgString(Flags));
+ auto FlagsArgString = Args.MakeArgString(Flags);
+ if (TC.UseDwarfDebugFlags() || GRecordSwitches) {
+ CmdArgs.push_back("-dwarf-debug-flags");
+ CmdArgs.push_back(FlagsArgString);
+ }
+ if (FRecordSwitches) {
+ CmdArgs.push_back("-record-command-line");
+ CmdArgs.push_back(FlagsArgString);
+ }
}
- if (IsCuda) {
- // Host-side cuda compilation receives all device-side outputs in a single
- // fatbin as Inputs[1]. Include the binary with -fcuda-include-gpubinary.
- if (Inputs.size() > 1) {
- assert(Inputs.size() == 2 && "More than one GPU binary!");
+ // Host-side cuda compilation receives all device-side outputs in a single
+ // fatbin as Inputs[1]. Include the binary with -fcuda-include-gpubinary.
+ if ((IsCuda || IsHIP) && CudaDeviceInput) {
CmdArgs.push_back("-fcuda-include-gpubinary");
- CmdArgs.push_back(Inputs[1].getFilename());
- }
+ CmdArgs.push_back(CudaDeviceInput->getFilename());
+ if (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
+ CmdArgs.push_back("-fgpu-rdc");
+ }
- if (Args.hasFlag(options::OPT_fcuda_rdc, options::OPT_fno_cuda_rdc, false))
- CmdArgs.push_back("-fcuda-rdc");
+ if (IsCuda) {
if (Args.hasFlag(options::OPT_fcuda_short_ptr,
options::OPT_fno_cuda_short_ptr, false))
CmdArgs.push_back("-fcuda-short-ptr");
@@ -4741,9 +5193,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// only the relevant declarations are emitted.
if (IsOpenMPDevice) {
CmdArgs.push_back("-fopenmp-is-device");
- if (Inputs.size() == 2) {
+ if (OpenMPDeviceInput) {
CmdArgs.push_back("-fopenmp-host-ir-file-path");
- CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
+ CmdArgs.push_back(Args.MakeArgString(OpenMPDeviceInput->getFilename()));
}
}
@@ -4777,6 +5229,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fwhole-program-vtables");
}
+ bool RequiresSplitLTOUnit = WholeProgramVTables || Sanitize.needsLTO();
+ bool SplitLTOUnit =
+ Args.hasFlag(options::OPT_fsplit_lto_unit,
+ options::OPT_fno_split_lto_unit, RequiresSplitLTOUnit);
+ if (RequiresSplitLTOUnit && !SplitLTOUnit)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fno-split-lto-unit"
+ << (WholeProgramVTables ? "-fwhole-program-vtables" : "-fsanitize=cfi");
+ if (SplitLTOUnit)
+ CmdArgs.push_back("-fsplit-lto-unit");
+
if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel,
options::OPT_fno_experimental_isel)) {
CmdArgs.push_back("-mllvm");
@@ -4818,6 +5281,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_complete_member_pointers, false))
CmdArgs.push_back("-fcomplete-member-pointers");
+ if (!Args.hasFlag(options::OPT_fcxx_static_destructors,
+ options::OPT_fno_cxx_static_destructors, true))
+ CmdArgs.push_back("-fno-c++-static-destructors");
+
if (Arg *A = Args.getLastArg(options::OPT_moutline,
options::OPT_mno_outline)) {
if (A->getOption().matches(options::OPT_moutline)) {
@@ -4838,8 +5305,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
- getToolChain().getTriple().isOSBinFormatELF() &&
- getToolChain().useIntegratedAs()))
+ (TC.getTriple().isOSBinFormatELF() ||
+ TC.getTriple().isOSBinFormatCOFF()) &&
+ !TC.getTriple().isPS4() &&
+ !TC.getTriple().isOSNetBSD() &&
+ !Distro(D.getVFS()).IsGentoo() &&
+ !TC.getTriple().isAndroid() &&
+ TC.useIntegratedAs()))
CmdArgs.push_back("-faddrsig");
// Finally add the compile command to the compilation.
@@ -4860,16 +5332,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
+ // Make the compile command echo its inputs for /showFilenames.
+ if (Output.getType() == types::TY_Object &&
+ Args.hasFlag(options::OPT__SLASH_showFilenames,
+ options::OPT__SLASH_showFilenames_, false)) {
+ C.getJobs().getJobs().back()->setPrintInputFilenames(true);
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_pg))
- if (Args.hasArg(options::OPT_fomit_frame_pointer))
+ if (!shouldUseFramePointer(Args, Triple))
D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
<< A->getAsString(Args);
// Claim some arguments which clang supports automatically.
// -fpch-preprocess is used with gcc to add a special marker in the output to
- // include the PCH file. Clang's PTH solution is completely transparent, so we
- // do not need to deal with it at all.
+ // include the PCH file.
Args.ClaimAllArgs(options::OPT_fpch_preprocess);
// Claim some arguments which clang doesn't support, but we don't
@@ -4912,7 +5390,8 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
}
if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
(runtime.getVersion() >= VersionTuple(2, 0)))
- if (!getToolChain().getTriple().isOSBinFormatELF()) {
+ if (!getToolChain().getTriple().isOSBinFormatELF() &&
+ !getToolChain().getTriple().isOSBinFormatCOFF()) {
getToolChain().getDriver().Diag(
diag::err_drv_gnustep_objc_runtime_incompatible_binary)
<< runtime.getVersion().getMajor();
@@ -5163,7 +5642,6 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
*DebugInfoKind = codegenoptions::LimitedDebugInfo;
else
*DebugInfoKind = codegenoptions::DebugLineTablesOnly;
- CmdArgs.push_back("-gcodeview");
} else {
*EmitCodeView = false;
}
@@ -5197,6 +5675,16 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
CmdArgs.push_back("-fms-volatile");
+ if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
+ options::OPT__SLASH_Zc_dllexportInlines,
+ false)) {
+ if (Args.hasArg(options::OPT__SLASH_fallback)) {
+ D.Diag(clang::diag::err_drv_dllexport_inlines_and_fallback);
+ } else {
+ CmdArgs.push_back("-fno-dllexport-inlines");
+ }
+ }
+
Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
if (MostGeneralArg && BestCaseArg)
@@ -5270,9 +5758,28 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("msvc");
}
- if (Args.hasArg(options::OPT__SLASH_Guard) &&
- Args.getLastArgValue(options::OPT__SLASH_Guard).equals_lower("cf"))
- CmdArgs.push_back("-cfguard");
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
+ SmallVector<StringRef, 1> SplitArgs;
+ StringRef(A->getValue()).split(SplitArgs, ",");
+ bool Instrument = false;
+ bool NoChecks = false;
+ for (StringRef Arg : SplitArgs) {
+ if (Arg.equals_lower("cf"))
+ Instrument = true;
+ else if (Arg.equals_lower("cf-"))
+ Instrument = false;
+ else if (Arg.equals_lower("nochecks"))
+ NoChecks = true;
+ else if (Arg.equals_lower("nochecks-"))
+ NoChecks = false;
+ else
+ D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << Arg;
+ }
+ // Currently there's no support emitting CFG instrumentation; the flag only
+ // emits the table of address-taken functions.
+ if (Instrument || NoChecks)
+ CmdArgs.push_back("-cfguard");
+ }
}
visualstudio::Compiler *Clang::getCLFallback() const {
@@ -5525,10 +6032,12 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- if (Args.hasArg(options::OPT_gsplit_dwarf) &&
- getToolChain().getTriple().isOSLinux()) {
+ const llvm::Triple &T = getToolChain().getTriple();
+ Arg *A;
+ if ((getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split) &&
+ (T.isOSLinux() || T.isOSFuchsia())) {
CmdArgs.push_back("-split-dwarf-file");
- CmdArgs.push_back(SplitDebugName(Args, Input));
+ CmdArgs.push_back(SplitDebugName(Args, Output));
}
assert(Input.isFilename() && "Invalid input.");