summaryrefslogtreecommitdiffstats
path: root/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
committerdim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
commitea266cad53e3d49771fa38103913d3ec7a166694 (patch)
tree8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/Driver/Tools.cpp
parentc72c57c9e9b69944e3e009cd5e209634839581d3 (diff)
downloadFreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip
FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release): http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r--lib/Driver/Tools.cpp440
1 files changed, 291 insertions, 149 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 77a72ba..aba1fe4 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include <sys/stat.h>
#include "Tools.h"
#include "InputInfo.h"
#include "SanitizerArgs.h"
@@ -544,6 +545,9 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
if (Triple.isOSDarwin())
return true;
return false;
+
+ case llvm::Triple::systemz:
+ return false;
}
}
@@ -815,7 +819,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
CmdArgs.push_back("-mno-global-merge");
}
- if (Args.hasArg(options::OPT_mno_implicit_float))
+ if (!Args.hasFlag(options::OPT_mimplicit_float,
+ options::OPT_mno_implicit_float,
+ true))
CmdArgs.push_back("-no-implicit-float");
}
@@ -851,8 +857,15 @@ static void getMipsCPUAndABI(const ArgList &Args,
CPUName = A->getValue();
}
- if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
+ if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
ABIName = A->getValue();
+ // Convert a GNU style Mips ABI name to the name
+ // accepted by LLVM Mips backend.
+ ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
+ .Case("32", "o32")
+ .Case("64", "n64")
+ .Default(ABIName);
+ }
// Setup default CPU and ABI names.
if (CPUName.empty() && ABIName.empty()) {
@@ -899,8 +912,6 @@ static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
// and -mfloat-abi=.
static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
- // Select the float ABI as determined by -msoft-float, -mhard-float,
- // and -mfloat-abi=.
StringRef FloatABI;
if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
options::OPT_mhard_float,
@@ -911,7 +922,7 @@ static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
FloatABI = "hard";
else {
FloatABI = A->getValue();
- if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") {
+ if (FloatABI != "soft" && FloatABI != "hard") {
D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
FloatABI = "hard";
}
@@ -944,7 +955,7 @@ static void AddTargetFeature(const ArgList &Args,
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
+ ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
StringRef CPUName;
StringRef ABIName;
@@ -977,12 +988,6 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
CmdArgs.push_back("-mips16-hard-float");
}
}
- else if (FloatABI == "single") {
- // Restrict the use of hardware floating-point
- // instructions to 32-bit operations.
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+single-float");
- }
else {
// Floating point operations and argument passing are hard.
assert(FloatABI == "hard" && "Invalid float abi!");
@@ -991,9 +996,15 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
}
AddTargetFeature(Args, CmdArgs,
+ options::OPT_msingle_float, options::OPT_mdouble_float,
+ "single-float");
+ AddTargetFeature(Args, CmdArgs,
options::OPT_mips16, options::OPT_mno_mips16,
"mips16");
AddTargetFeature(Args, CmdArgs,
+ options::OPT_mmicromips, options::OPT_mno_micromips,
+ "micromips");
+ AddTargetFeature(Args, CmdArgs,
options::OPT_mdsp, options::OPT_mno_dsp,
"dsp");
AddTargetFeature(Args, CmdArgs,
@@ -1127,11 +1138,11 @@ static std::string getR600TargetGPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
std::string GPUName = A->getValue();
return llvm::StringSwitch<const char *>(GPUName)
- .Cases("rv610", "rv620", "rv630", "r600")
- .Cases("rv635", "rs780", "rs880", "r600")
+ .Cases("rv630", "rv635", "r600")
+ .Cases("rv610", "rv620", "rs780", "rs880")
.Case("rv740", "rv770")
.Case("palm", "cedar")
- .Cases("sumo", "sumo2", "redwood")
+ .Cases("sumo", "sumo2", "sumo")
.Case("hemlock", "cypress")
.Case("aruba", "cayman")
.Default(GPUName.c_str());
@@ -1255,6 +1266,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
Args.hasArg(options::OPT_fapple_kext));
if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
options::OPT_mno_soft_float,
+ options::OPT_mimplicit_float,
options::OPT_mno_implicit_float)) {
const Option &O = A->getOption();
NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
@@ -1452,6 +1464,18 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("-fexceptions");
}
+static bool ShouldDisableAutolink(const ArgList &Args,
+ const ToolChain &TC) {
+ bool Default = true;
+ if (TC.getTriple().isOSDarwin()) {
+ // The native darwin assembler doesn't support the linker_option directives,
+ // so we disable them if we think the .s file will be passed to it.
+ Default = TC.useIntegratedAs();
+ }
+ return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
+ Default);
+}
+
static bool ShouldDisableCFI(const ArgList &Args,
const ToolChain &TC) {
bool Default = true;
@@ -1508,11 +1532,12 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault);
}
-SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args)
+SanitizerArgs::SanitizerArgs(const ToolChain &TC, const ArgList &Args)
: Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
AsanZeroBaseShadow(false) {
unsigned AllKinds = 0; // All kinds of sanitizers that were turned on
// at least once (possibly, disabled further).
+ const Driver &D = TC.getDriver();
for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
unsigned Add, Remove;
if (!parse(D, Args, *I, Add, Remove, true))
@@ -1604,11 +1629,20 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args)
/* Default */false);
// Parse -f(no-)sanitize-address-zero-base-shadow options.
- if (NeedsAsan)
+ if (NeedsAsan) {
+ bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android);
+ bool ZeroBaseShadowDefault = IsAndroid;
AsanZeroBaseShadow =
- Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
- options::OPT_fno_sanitize_address_zero_base_shadow,
- /* Default */false);
+ Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
+ options::OPT_fno_sanitize_address_zero_base_shadow,
+ ZeroBaseShadowDefault);
+ // Zero-base shadow is a requirement on Android.
+ if (IsAndroid && !AsanZeroBaseShadow) {
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fno-sanitize-address-zero-base-shadow"
+ << lastArgumentForKind(D, Args, Address);
+ }
+ }
}
static void addSanitizerRTLinkFlagsLinux(
@@ -1637,6 +1671,7 @@ static void addSanitizerRTLinkFlagsLinux(
LibSanitizerArgs.begin(), LibSanitizerArgs.end());
CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-lrt");
CmdArgs.push_back("-ldl");
// If possible, use a dynamic symbols file to export the symbols from the
@@ -1656,11 +1691,6 @@ static void addSanitizerRTLinkFlagsLinux(
static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if(TC.getTriple().getEnvironment() == llvm::Triple::Android) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie);
- }
-
SmallString<128> LibAsan(TC.getDriver().ResourceDir);
llvm::sys::path::append(LibAsan, "lib", "linux",
(Twine("libclang_rt.asan-") +
@@ -1668,13 +1698,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
} else {
if (!Args.hasArg(options::OPT_shared)) {
- bool ZeroBaseShadow = Args.hasFlag(
- options::OPT_fsanitize_address_zero_base_shadow,
- options::OPT_fno_sanitize_address_zero_base_shadow, false);
- if (ZeroBaseShadow && !Args.hasArg(options::OPT_pie)) {
- TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
- "-fsanitize-address-zero-base-shadow" << "-pie";
- }
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
}
}
@@ -1685,9 +1708,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
- "-fsanitize=thread" << "-pie";
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
}
}
@@ -1697,9 +1717,6 @@ static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
- "-fsanitize=memory" << "-pie";
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
}
}
@@ -1764,14 +1781,27 @@ static bool shouldUseLeafFramePointer(const ArgList &Args,
/// If the PWD environment variable is set, add a CC1 option to specify the
/// debug compilation directory.
static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
- if (const char *pwd = ::getenv("PWD")) {
- // GCC also verifies that stat(pwd) and stat(".") have the same inode
- // number. Not doing those because stats are slow, but we could.
- if (llvm::sys::path::is_absolute(pwd)) {
- std::string CompDir = pwd;
- CmdArgs.push_back("-fdebug-compilation-dir");
- CmdArgs.push_back(Args.MakeArgString(CompDir));
- }
+ struct stat StatPWDBuf, StatDotBuf;
+
+ const char *pwd = ::getenv("PWD");
+ if (!pwd)
+ return;
+
+ if (llvm::sys::path::is_absolute(pwd) &&
+ stat(pwd, &StatPWDBuf) == 0 &&
+ stat(".", &StatDotBuf) == 0 &&
+ StatPWDBuf.st_ino == StatDotBuf.st_ino &&
+ StatPWDBuf.st_dev == StatDotBuf.st_dev) {
+ CmdArgs.push_back("-fdebug-compilation-dir");
+ CmdArgs.push_back(Args.MakeArgString(pwd));
+ return;
+ }
+
+ // Fall back to using getcwd.
+ SmallString<128> cwd;
+ if (!llvm::sys::fs::current_path(cwd)) {
+ CmdArgs.push_back("-fdebug-compilation-dir");
+ CmdArgs.push_back(Args.MakeArgString(cwd));
}
}
@@ -1817,6 +1847,13 @@ static void SplitDebugInfo(const ToolChain &TC, Compilation &C,
C.addCommand(new Command(JA, T, Exec, StripArgs));
}
+static bool isOptimizationLevelFast(const ArgList &Args) {
+ if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+ if (A->getOption().matches(options::OPT_Ofast))
+ return true;
+ return false;
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -1969,6 +2006,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-analyzer-checker=deadcode");
+ if (types::isCXX(Inputs[0].getType()))
+ CmdArgs.push_back("-analyzer-checker=cplusplus");
+
// Enable the following experimental checkers for testing.
CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
@@ -1997,37 +2037,38 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CheckCodeGenerationOptions(D, Args);
- // For the PIC and PIE flag options, this logic is different from the legacy
- // logic in very old versions of GCC, as that logic was just a bug no one had
- // ever fixed. This logic is both more rational and consistent with GCC's new
- // logic now that the bugs are fixed. The last argument relating to either
- // PIC or PIE wins, and no other argument is used. If the last argument is
- // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any
- // PIE option implicitly enables PIC at the same level.
- bool PIE = false;
- bool PIC = getToolChain().isPICDefault();
+ bool PIE = getToolChain().isPIEDefault();
+ bool PIC = PIE || getToolChain().isPICDefault();
bool IsPICLevelTwo = PIC;
- if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
- options::OPT_fpic, options::OPT_fno_pic,
- options::OPT_fPIE, options::OPT_fno_PIE,
- options::OPT_fpie, options::OPT_fno_pie)) {
- Option O = A->getOption();
- if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
- O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
- PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
- PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
- IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
- O.matches(options::OPT_fPIC);
- } else {
- PIE = PIC = false;
- }
- }
+
+ // For the PIC and PIE flag options, this logic is different from the
+ // legacy logic in very old versions of GCC, as that logic was just
+ // a bug no one had ever fixed. This logic is both more rational and
+ // consistent with GCC's new logic now that the bugs are fixed. The last
+ // argument relating to either PIC or PIE wins, and no other argument is
+ // used. If the last argument is any flavor of the '-fno-...' arguments,
+ // both PIC and PIE are disabled. Any PIE option implicitly enables PIC
+ // at the same level.
+ Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+ options::OPT_fpic, options::OPT_fno_pic,
+ options::OPT_fPIE, options::OPT_fno_PIE,
+ options::OPT_fpie, options::OPT_fno_pie);
// Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
// is forced, then neither PIC nor PIE flags will have no effect.
- if (getToolChain().isPICDefaultForced()) {
- PIE = false;
- PIC = getToolChain().isPICDefault();
- IsPICLevelTwo = PIC;
+ if (!getToolChain().isPICDefaultForced()) {
+ if (LastPICArg) {
+ Option O = LastPICArg->getOption();
+ if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
+ O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
+ PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
+ PIC = PIE || O.matches(options::OPT_fPIC) ||
+ O.matches(options::OPT_fpic);
+ IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
+ O.matches(options::OPT_fPIC);
+ } else {
+ PIE = PIC = false;
+ }
+ }
}
// Inroduce a Darwin-specific hack. If the default is PIC but the flags
@@ -2101,7 +2142,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
options::OPT_fno_zero_initialized_in_bss))
CmdArgs.push_back("-mno-zero-initialized-in-bss");
- if (!Args.hasFlag(options::OPT_fstrict_aliasing,
+
+ bool OFastEnabled = isOptimizationLevelFast(Args);
+ // If -Ofast is the optimization level, then -fstrict-aliasing should be
+ // enabled. This alias option is being used to simplify the hasFlag logic.
+ OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast :
+ options::OPT_fstrict_aliasing;
+ if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
options::OPT_fno_strict_aliasing,
getToolChain().IsStrictAliasingDefault()))
CmdArgs.push_back("-relaxed-aliasing");
@@ -2117,13 +2164,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Handle segmented stacks.
if (Args.hasArg(options::OPT_fsplit_stack))
CmdArgs.push_back("-split-stacks");
+
+ // If -Ofast is the optimization level, then -ffast-math should be enabled.
+ // This alias option is being used to simplify the getLastArg logic.
+ OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast :
+ options::OPT_ffast_math;
// Handle various floating point optimization flags, mapping them to the
// appropriate LLVM code generation flags. The pattern for all of these is to
// default off the codegen optimizations, and if any flag enables them and no
// flag disables them after the flag enabling them, enable the codegen
// optimization. This is complicated by several "umbrella" flags.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_ffinite_math_only,
options::OPT_fno_finite_math_only,
@@ -2133,7 +2185,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->getOption().getID() != options::OPT_fno_finite_math_only &&
A->getOption().getID() != options::OPT_fhonor_infinities)
CmdArgs.push_back("-menable-no-infs");
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_ffinite_math_only,
options::OPT_fno_finite_math_only,
@@ -2146,7 +2198,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
bool MathErrno = getToolChain().IsMathErrnoDefault();
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_fmath_errno,
options::OPT_fno_math_errno))
@@ -2159,7 +2211,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// entire set of LLVM optimizations, so collect them through all the flag
// madness.
bool AssociativeMath = false;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
@@ -2170,7 +2222,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->getOption().getID() != options::OPT_fno_associative_math)
AssociativeMath = true;
bool ReciprocalMath = false;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
@@ -2181,7 +2233,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->getOption().getID() != options::OPT_fno_reciprocal_math)
ReciprocalMath = true;
bool SignedZeros = true;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
@@ -2192,7 +2244,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->getOption().getID() != options::OPT_fsigned_zeros)
SignedZeros = false;
bool TrappingMath = true;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
@@ -2208,7 +2260,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Validate and pass through -fp-contract option.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
options::OPT_fno_fast_math,
options::OPT_ffp_contract)) {
if (A->getOption().getID() == options::OPT_ffp_contract) {
@@ -2219,7 +2271,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Val;
}
- } else if (A->getOption().getID() == options::OPT_ffast_math) {
+ } else if (A->getOption().matches(options::OPT_ffast_math) ||
+ (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
// If fast-math is set then set the fp-contract mode to fast.
CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
}
@@ -2230,9 +2283,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// preprocessor macros. This is distinct from enabling any optimizations as
// these options induce language changes which must survive serialization
// and deserialization, etc.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math))
- if (A->getOption().matches(options::OPT_ffast_math))
- CmdArgs.push_back("-ffast-math");
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
+ options::OPT_fno_fast_math))
+ if (!A->getOption().matches(options::OPT_fno_fast_math))
+ CmdArgs.push_back("-ffast-math");
if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math))
if (A->getOption().matches(options::OPT_ffinite_math_only))
CmdArgs.push_back("-ffinite-math-only");
@@ -2597,6 +2651,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (ShouldDisableDwarfDirectory(Args, getToolChain()))
CmdArgs.push_back("-fno-dwarf-directory-asm");
+ if (ShouldDisableAutolink(Args, getToolChain()))
+ CmdArgs.push_back("-fno-autolink");
+
// Add in -fdebug-compilation-dir if necessary.
addDebugCompDirArg(Args, CmdArgs);
@@ -2705,7 +2762,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
- SanitizerArgs Sanitize(D, Args);
+ SanitizerArgs Sanitize(getToolChain(), Args);
Sanitize.addArgs(Args, CmdArgs);
if (!Args.hasFlag(options::OPT_fsanitize_recover,
@@ -2892,16 +2949,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
- // -fmodules-autolink (on by default when modules is enabled) automatically
- // links against libraries for imported modules. This requires the
- // integrated assembler.
- if (HaveModules && getToolChain().useIntegratedAs() &&
- Args.hasFlag(options::OPT_fmodules_autolink,
- options::OPT_fno_modules_autolink,
- true)) {
- CmdArgs.push_back("-fmodules-autolink");
- }
-
// -faccess-control is default.
if (Args.hasFlag(options::OPT_fno_access_control,
options::OPT_faccess_control,
@@ -3198,9 +3245,42 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Color diagnostics are the default, unless the terminal doesn't support
// them.
- if (Args.hasFlag(options::OPT_fcolor_diagnostics,
- options::OPT_fno_color_diagnostics,
- llvm::sys::Process::StandardErrHasColors()))
+ // Support both clang's -f[no-]color-diagnostics and gcc's
+ // -f[no-]diagnostics-colors[=never|always|auto].
+ enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
+ for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+ it != ie; ++it) {
+ const Option &O = (*it)->getOption();
+ if (!O.matches(options::OPT_fcolor_diagnostics) &&
+ !O.matches(options::OPT_fdiagnostics_color) &&
+ !O.matches(options::OPT_fno_color_diagnostics) &&
+ !O.matches(options::OPT_fno_diagnostics_color) &&
+ !O.matches(options::OPT_fdiagnostics_color_EQ))
+ continue;
+
+ (*it)->claim();
+ if (O.matches(options::OPT_fcolor_diagnostics) ||
+ O.matches(options::OPT_fdiagnostics_color)) {
+ ShowColors = Colors_On;
+ } else if (O.matches(options::OPT_fno_color_diagnostics) ||
+ O.matches(options::OPT_fno_diagnostics_color)) {
+ ShowColors = Colors_Off;
+ } else {
+ assert(O.matches(options::OPT_fdiagnostics_color_EQ));
+ StringRef value((*it)->getValue());
+ if (value == "always")
+ ShowColors = Colors_On;
+ else if (value == "never")
+ ShowColors = Colors_Off;
+ else if (value == "auto")
+ ShowColors = Colors_Auto;
+ else
+ getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
+ << ("-fdiagnostics-color=" + value).str();
+ }
+ }
+ if (ShowColors == Colors_On ||
+ (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
CmdArgs.push_back("-fcolor-diagnostics");
if (!Args.hasFlag(options::OPT_fshow_source_location,
@@ -3222,8 +3302,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
false))
CmdArgs.push_back("-fasm-blocks");
+ // If -Ofast is the optimization level, then -fvectorize should be enabled.
+ // This alias option is being used to simplify the hasFlag logic.
+ OptSpecifier VectorizeAliasOption = OFastEnabled ? options::OPT_Ofast :
+ options::OPT_fvectorize;
+
// -fvectorize is default.
- if (Args.hasFlag(options::OPT_fvectorize,
+ if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
options::OPT_fno_vectorize, true)) {
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-vectorize-loops");
@@ -3233,7 +3318,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_fslp_vectorize,
options::OPT_fno_slp_vectorize, false)) {
CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-vectorize");
+ CmdArgs.push_back("-vectorize-slp");
+ }
+
+ // -fno-slp-vectorize-aggressive is default.
+ if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
+ options::OPT_fno_slp_vectorize_aggressive, false)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-vectorize-slp-aggressive");
}
if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
@@ -3298,6 +3390,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -fcomment-block-commands to -cc1.
Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
+ // Forward -fparse-all-comments to -cc1.
+ Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
// parser.
@@ -3673,6 +3767,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec = getToolChain().getDriver().getClangProgramPath();
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+
+ // Handle the debug info splitting at object creation time if we're
+ // creating an object.
+ // TODO: Currently only works on linux with newer objcopy.
+ if (Args.hasArg(options::OPT_gsplit_dwarf) &&
+ (getToolChain().getTriple().getOS() == llvm::Triple::Linux))
+ SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
+ SplitDebugName(Args, Inputs));
}
void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
@@ -3867,7 +3969,6 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(
Args.MakeArgString(std::string("-G") + SmallDataThreshold));
- Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
@@ -4579,7 +4680,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
- SanitizerArgs Sanitize(getToolChain().getDriver(), Args);
+ SanitizerArgs Sanitize(getToolChain(), Args);
// If we're building a dynamic lib with -fsanitize=address,
// unresolved symbols may appear. Mark all
// of them as dynamic_lookup. Linking executables is handled in
@@ -5706,6 +5807,12 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back("-EL");
+ Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
+ Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
+ options::OPT_mno_micromips);
+ Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
+ Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
+
Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
options::OPT_fpic, options::OPT_fno_pic,
options::OPT_fPIE, options::OPT_fno_PIE,
@@ -5717,6 +5824,9 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
LastPICArg->getOption().matches(options::OPT_fpie))) {
CmdArgs.push_back("-KPIC");
}
+ } else if (getToolChain().getArch() == llvm::Triple::systemz) {
+ // At the moment we always produce z10 code.
+ CmdArgs.push_back("-march=z10");
}
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -5784,6 +5894,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = ToolChain.getDriver();
const bool isAndroid =
ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
+ SanitizerArgs Sanitize(getToolChain(), Args);
+ const bool IsPIE =
+ !Args.hasArg(options::OPT_shared) &&
+ (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
ArgStringList CmdArgs;
@@ -5798,7 +5912,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_pie) && !Args.hasArg(options::OPT_shared))
+ if (IsPIE)
CmdArgs.push_back("-pie");
if (Args.hasArg(options::OPT_rdynamic))
@@ -5844,6 +5958,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back("elf64ltsmip");
}
+ else if (ToolChain.getArch() == llvm::Triple::systemz)
+ CmdArgs.push_back("elf64_s390");
else
CmdArgs.push_back("elf_x86_64");
@@ -5890,7 +6006,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
else if (ToolChain.getArch() == llvm::Triple::ppc)
CmdArgs.push_back("/lib/ld.so.1");
- else if (ToolChain.getArch() == llvm::Triple::ppc64)
+ else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
+ ToolChain.getArch() == llvm::Triple::systemz)
CmdArgs.push_back("/lib64/ld64.so.1");
else
CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
@@ -5904,7 +6021,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!isAndroid) {
const char *crt1 = NULL;
if (!Args.hasArg(options::OPT_shared)){
- if (Args.hasArg(options::OPT_pie))
+ if (IsPIE)
crt1 = "Scrt1.o";
else
crt1 = "crt1.o";
@@ -5920,7 +6037,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
else if (Args.hasArg(options::OPT_shared))
crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
- else if (Args.hasArg(options::OPT_pie))
+ else if (IsPIE)
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
else
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
@@ -5971,8 +6088,6 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- SanitizerArgs Sanitize(D, Args);
-
// Call these before we add the C++ ABI library.
if (Sanitize.needsUbsanRt())
addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX,
@@ -6030,7 +6145,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *crtend;
if (Args.hasArg(options::OPT_shared))
crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
- else if (Args.hasArg(options::OPT_pie))
+ else if (IsPIE)
crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
else
crtend = isAndroid ? "crtend_android.o" : "crtend.o";
@@ -6162,21 +6277,29 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ bool UseGCC47 = false;
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
+ if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47))
+ UseGCC47 = false;
+
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+ CmdArgs.push_back("--eh-frame-hdr");
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
+ if (Args.hasArg(options::OPT_rdynamic))
+ CmdArgs.push_back("-export-dynamic");
if (Args.hasArg(options::OPT_shared))
CmdArgs.push_back("-Bshareable");
else {
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
}
+ CmdArgs.push_back("--hash-style=both");
}
// When building 32-bit code on DragonFly/pc64, we have to explicitly
@@ -6196,18 +6319,26 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+ if (Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("gcrt1.o")));
+ else {
+ if (Args.hasArg(options::OPT_pie))
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("Scrt1.o")));
+ else
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crt1.o")));
+ }
}
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crti.o")));
+ if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtbeginS.o")));
+ else
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtbegin.o")));
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
@@ -6220,20 +6351,19 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
!Args.hasArg(options::OPT_nodefaultlibs)) {
// FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
// rpaths
- CmdArgs.push_back("-L/usr/lib/gcc41");
+ if (UseGCC47)
+ CmdArgs.push_back("-L/usr/lib/gcc47");
+ else
+ CmdArgs.push_back("-L/usr/lib/gcc44");
if (!Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-rpath");
- CmdArgs.push_back("/usr/lib/gcc41");
-
- CmdArgs.push_back("-rpath-link");
- CmdArgs.push_back("/usr/lib/gcc41");
-
- CmdArgs.push_back("-rpath");
- CmdArgs.push_back("/usr/lib");
-
- CmdArgs.push_back("-rpath-link");
- CmdArgs.push_back("/usr/lib");
+ if (UseGCC47) {
+ CmdArgs.push_back("-rpath");
+ CmdArgs.push_back("/usr/lib/gcc47");
+ } else {
+ CmdArgs.push_back("-rpath");
+ CmdArgs.push_back("/usr/lib/gcc44");
+ }
}
if (D.CCCIsCXX) {
@@ -6241,13 +6371,6 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lm");
}
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc_pic");
- } else {
- CmdArgs.push_back("-lgcc");
- }
-
-
if (Args.hasArg(options::OPT_pthread))
CmdArgs.push_back("-lpthread");
@@ -6255,23 +6378,42 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lc");
}
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc_pic");
+ if (UseGCC47) {
+ if (Args.hasArg(options::OPT_static) ||
+ Args.hasArg(options::OPT_static_libgcc)) {
+ CmdArgs.push_back("-lgcc");
+ CmdArgs.push_back("-lgcc_eh");
+ } else {
+ if (Args.hasArg(options::OPT_shared_libgcc)) {
+ CmdArgs.push_back("-lgcc_pic");
+ if (!Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back("-lgcc");
+ } else {
+ CmdArgs.push_back("-lgcc");
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lgcc_pic");
+ CmdArgs.push_back("--no-as-needed");
+ }
+ }
} else {
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back("-lgcc_pic");
+ } else {
+ CmdArgs.push_back("-lgcc");
+ }
}
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
+ if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
+ getToolChain().GetFilePath("crtendS.o")));
else
CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtendS.o")));
+ getToolChain().GetFilePath("crtend.o")));
CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtn.o")));
+ getToolChain().GetFilePath("crtn.o")));
}
addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
OpenPOWER on IntegriCloud