summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver')
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Compilation.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Driver.cpp117
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp7
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/OptTable.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp471
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.h82
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp492
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.h3
9 files changed, 731 insertions, 467 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
index 5619212..2657faa 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
@@ -101,6 +101,12 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
llvm::sys::Path P(*it);
std::string Error;
+ // Don't try to remove files which we don't have write access to (but may be
+ // able to remove). Underlying tools may have intentionally not overwritten
+ // them.
+ if (!P.canWrite())
+ continue;
+
if (P.eraseFromDisk(false, &Error)) {
// Failure is only failure if the file exists and is "regular". There is
// a race condition here due to the limited interface of
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
index 4b6aef6..302779b 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
@@ -30,6 +30,7 @@
#include "clang/Basic/Version.h"
#include "llvm/Config/config.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -42,13 +43,6 @@
#include <map>
-#ifdef __CYGWIN__
-#include <cygwin/version.h>
-#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
-#define IS_CYGWIN15 1
-#endif
-#endif
-
using namespace clang::driver;
using namespace clang;
@@ -58,15 +52,17 @@ Driver::Driver(llvm::StringRef _ClangExecutable,
bool IsProduction, bool CXXIsProduction,
Diagnostic &_Diags)
: Opts(createDriverOptTable()), Diags(_Diags),
- ClangExecutable(_ClangExecutable), DefaultHostTriple(_DefaultHostTriple),
- DefaultImageName(_DefaultImageName),
+ ClangExecutable(_ClangExecutable), UseStdLib(true),
+ DefaultHostTriple(_DefaultHostTriple), DefaultImageName(_DefaultImageName),
DriverTitle("clang \"gcc-compatible\" driver"),
Host(0),
- CCPrintOptionsFilename(0), CCPrintHeadersFilename(0), CCCIsCXX(false),
- CCCEcho(false), CCCPrintBindings(false), CCPrintOptions(false),
- CCPrintHeaders(false), CCCGenericGCCName("gcc"),
- CheckInputsExist(true), CCCUseClang(true), CCCUseClangCXX(true),
- CCCUseClangCPP(true), CCCUsePCH(true), SuppressMissingInputWarning(false) {
+ CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
+ CCLogDiagnosticsFilename(0), CCCIsCXX(false),
+ CCCIsCPP(false),CCCEcho(false), CCCPrintBindings(false),
+ CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
+ CCCGenericGCCName(""), CheckInputsExist(true), CCCUseClang(true),
+ CCCUseClangCXX(true), CCCUseClangCPP(true), CCCUsePCH(true),
+ SuppressMissingInputWarning(false) {
if (IsProduction) {
// In a "production" build, only use clang on architectures we expect to
// work, and don't use clang C++.
@@ -100,11 +96,10 @@ Driver::~Driver() {
delete Host;
}
-InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
- const char **ArgEnd) {
+InputArgList *Driver::ParseArgStrings(llvm::ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
unsigned MissingArgIndex, MissingArgCount;
- InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
+ InputArgList *Args = getOpts().ParseArgs(ArgList.begin(), ArgList.end(),
MissingArgIndex, MissingArgCount);
// Check for missing argument error.
@@ -206,7 +201,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
return DAL;
}
-Compilation *Driver::BuildCompilation(int argc, const char **argv) {
+Compilation *Driver::BuildCompilation(llvm::ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Compilation construction");
// FIXME: Handle environment options which effect driver behavior, somewhere
@@ -218,9 +213,7 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
// FIXME: This stuff needs to go into the Compilation, not the driver.
bool CCCPrintOptions = false, CCCPrintActions = false;
- const char **Start = argv + 1, **End = argv + argc;
-
- InputArgList *Args = ParseArgStrings(Start, End);
+ InputArgList *Args = ParseArgStrings(ArgList.slice(1));
// -no-canonical-prefixes is used very early in main.
Args->ClaimAllArgs(options::OPT_no_canonical_prefixes);
@@ -238,13 +231,6 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
- if (CCCIsCXX) {
-#ifdef IS_CYGWIN15
- CCCGenericGCCName = "g++-4";
-#else
- CCCGenericGCCName = "g++";
-#endif
- }
CCCEcho = Args->hasArg(options::OPT_ccc_echo);
if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
CCCGenericGCCName = A->getValue(*Args);
@@ -287,6 +273,10 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
A->claim();
PrefixDirs.push_back(A->getValue(*Args, 0));
}
+ if (const Arg *A = Args->getLastArg(options::OPT__sysroot_EQ))
+ SysRoot = A->getValue(*Args);
+ if (Args->hasArg(options::OPT_nostdlib))
+ UseStdLib = false;
Host = GetHostInfo(DefaultHostTriple.c_str());
@@ -593,7 +583,7 @@ static bool ContainsCompileAction(const Action *A) {
}
void Driver::BuildUniversalActions(const ToolChain &TC,
- const ArgList &Args,
+ const DerivedArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
// Collect the list of architectures. Duplicates are allowed, but should only
@@ -688,7 +678,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
}
}
-void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
+void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
// Start by constructing the list of inputs and their types.
@@ -721,18 +711,23 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArgNoClaim(options::OPT_E))
+ if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP)
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
- // Otherwise lookup by extension, and fallback to ObjectType if not
- // found. We use a host hook here because Darwin at least has its own
+ // Otherwise lookup by extension.
+ // Fallback is C if invoked as C preprocessor or Object otherwise.
+ // We use a host hook here because Darwin at least has its own
// idea of what .s is.
if (const char *Ext = strrchr(Value, '.'))
Ty = TC.LookupTypeForExtension(Ext + 1);
- if (Ty == types::TY_INVALID)
- Ty = types::TY_Object;
+ if (Ty == types::TY_INVALID) {
+ if (CCCIsCPP)
+ Ty = types::TY_C;
+ else
+ Ty = types::TY_Object;
+ }
// If the driver is invoked as C++ compiler (like clang++ or c++) it
// should autodetect some input files as C++ for g++ compatibility.
@@ -799,6 +794,15 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
}
}
+ if (CCCIsCPP && Inputs.empty()) {
+ // If called as standalone preprocessor, stdin is processed
+ // if no other input is present.
+ unsigned Index = Args.getBaseArgs().MakeIndex("-");
+ Arg *A = Opts->ParseOneArg(Args, Index);
+ A->claim();
+ Inputs.push_back(std::make_pair(types::TY_C, A));
+ }
+
if (!SuppressMissingInputWarning && Inputs.empty()) {
Diag(clang::diag::err_drv_no_input_files);
return;
@@ -811,7 +815,8 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
phases::ID FinalPhase;
// -{E,M,MM} only run the preprocessor.
- if ((FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
+ if (CCCIsCPP ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
(FinalPhaseArg = Args.getLastArg(options::OPT_M, options::OPT_MM))) {
FinalPhase = phases::Preprocess;
@@ -853,6 +858,10 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
// Claim here to avoid the more general unused warning.
InputArg->claim();
+ // Suppress all unused style warnings with -Qunused-arguments
+ if (Args.hasArg(options::OPT_Qunused_arguments))
+ continue;
+
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess &&
@@ -945,7 +954,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
} else if (Args.hasArg(options::OPT_emit_ast)) {
return new CompileJobAction(Input, types::TY_AST);
} else if (Args.hasArg(options::OPT_emit_llvm) ||
- Args.hasArg(options::OPT_flto) || HasO4) {
+ Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false) ||
+ HasO4) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return new CompileJobAction(Input, Output);
@@ -1064,14 +1074,17 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
C.getArgs().hasArg(options::OPT_static) ||
C.getArgs().hasArg(options::OPT_fapple_kext));
- bool IsIADefault = (TC->IsIntegratedAssemblerDefault() && !HasStatic);
+ bool IsDarwin = TC->getTriple().getOS() == llvm::Triple::Darwin;
+ bool IsIADefault = TC->IsIntegratedAssemblerDefault() &&
+ !(HasStatic && IsDarwin);
if (C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIADefault) &&
!C.getArgs().hasArg(options::OPT_save_temps) &&
isa<AssembleJobAction>(JA) &&
Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
- const Tool &Compiler = TC->SelectTool(C,cast<JobAction>(**Inputs->begin()));
+ const Tool &Compiler = TC->SelectTool(
+ C, cast<JobAction>(**Inputs->begin()), (*Inputs)[0]->getInputs());
if (Compiler.hasIntegratedAssembler()) {
Inputs = &(*Inputs)[0]->getInputs();
ToolForJob = &Compiler;
@@ -1080,7 +1093,7 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
// Otherwise use the tool for the current job.
if (!ToolForJob)
- ToolForJob = &TC->SelectTool(C, *JA);
+ ToolForJob = &TC->SelectTool(C, *JA, *Inputs);
// See if we should use an integrated preprocessor. We do so when we have
// exactly one input, since this is the only use case we care about
@@ -1206,7 +1219,13 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
}
llvm::SmallString<128> BasePath(BaseInput);
- llvm::StringRef BaseName = llvm::sys::path::filename(BasePath);
+ llvm::StringRef BaseName;
+
+ // Dsymutil actions should use the full path.
+ if (isa<DsymutilJobAction>(JA))
+ BaseName = BasePath;
+ else
+ BaseName = llvm::sys::path::filename(BasePath);
// Determine what the derived output name should be.
const char *NamedOutput;
@@ -1243,7 +1262,12 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
// attempting to use this prefix when lokup up program paths.
for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(),
ie = PrefixDirs.end(); it != ie; ++it) {
- llvm::sys::Path P(*it);
+ std::string Dir(*it);
+ if (Dir.empty())
+ continue;
+ if (Dir[0] == '=')
+ Dir = SysRoot + Dir.substr(1);
+ llvm::sys::Path P(Dir);
P.appendComponent(Name);
bool Exists;
if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
@@ -1253,7 +1277,12 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
const ToolChain::path_list &List = TC.getFilePaths();
for (ToolChain::path_list::const_iterator
it = List.begin(), ie = List.end(); it != ie; ++it) {
- llvm::sys::Path P(*it);
+ std::string Dir(*it);
+ if (Dir.empty())
+ continue;
+ if (Dir[0] == '=')
+ Dir = SysRoot + Dir.substr(1);
+ llvm::sys::Path P(Dir);
P.appendComponent(Name);
bool Exists;
if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
@@ -1323,7 +1352,7 @@ std::string Driver::GetTemporaryPath(const char *Suffix) const {
const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
llvm::PrettyStackTraceString CrashInfo("Constructing host");
- llvm::Triple Triple(TripleStr);
+ llvm::Triple Triple(llvm::Triple::normalize(TripleStr).c_str());
// TCE is an osless target
if (Triple.getArchName() == "tce")
diff --git a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp
index cd413180..198af54 100644
--- a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp
@@ -113,14 +113,9 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
TCTriple.setArch(Arch);
// If we recognized the arch, match it to the toolchains we support.
- const char *UseNewToolChain = ::getenv("CCC_ENABLE_NEW_DARWIN_TOOLCHAIN");
- if (UseNewToolChain ||
- Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 ||
+ if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 ||
Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
TC = new toolchains::DarwinClang(*this, TCTriple);
- } else if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
- // We still use the legacy DarwinGCC toolchain on X86.
- TC = new toolchains::DarwinGCC(*this, TCTriple);
} else
TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple);
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
index c3d3048..0252b3e 100644
--- a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
@@ -20,9 +20,9 @@ using namespace clang::driver::options;
// Ordering on Info. The ordering is *almost* lexicographic, with two
// exceptions. First, '\0' comes at the end of the alphabet instead of
-// the beginning (thus options preceed any other options which prefix
+// the beginning (thus options precede any other options which prefix
// them). Second, for options with the same name, the less permissive
-// version should come first; a Flag option should preceed a Joined
+// version should come first; a Flag option should precede a Joined
// option, for example.
static int StrCmpOptionName(const char *A, const char *B) {
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
index e305683..d919915 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
@@ -47,7 +47,7 @@ bool ToolChain::HasNativeLLVMSupport() const {
return false;
}
-/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
//
// FIXME: tblgen this.
static const char *getARMTargetCPU(const ArgList &Args,
@@ -101,6 +101,8 @@ static const char *getARMTargetCPU(const ArgList &Args,
return "iwmmxt";
if (MArch == "xscale")
return "xscale";
+ if (MArch == "armv6m" || MArch == "armv6-m")
+ return "cortex-m0";
// If all else failed, return the most base CPU LLVM supports.
return "arm7tdmi";
@@ -137,6 +139,12 @@ static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
if (CPU == "cortex-a8" || CPU == "cortex-a9")
return "v7";
+ if (CPU == "cortex-m3")
+ return "v7m";
+
+ if (CPU == "cortex-m0")
+ return "v6m";
+
return "";
}
@@ -168,10 +176,10 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args) const {
}
std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args) const {
- // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on
- // non-Darwin.
+ // Diagnose use of Darwin OS deployment target arguments on non-Darwin.
if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
- options::OPT_miphoneos_version_min_EQ))
+ options::OPT_miphoneos_version_min_EQ,
+ options::OPT_mios_simulator_version_min_EQ))
getDriver().Diag(clang::diag::err_drv_clang_unsupported)
<< A->getAsString(Args);
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index 422c572..499587a 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -105,7 +105,8 @@ static const char *GetArmArchForMCpu(llvm::StringRef Value) {
return "xscale";
if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
- Value == "arm1176jz-s" || Value == "arm1176jzf-s")
+ Value == "arm1176jz-s" || Value == "arm1176jzf-s" ||
+ Value == "cortex-m0" )
return "armv6";
if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
@@ -118,7 +119,8 @@ llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
switch (getTriple().getArch()) {
default:
return getArchName();
-
+
+ case llvm::Triple::thumb:
case llvm::Triple::arm: {
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
@@ -133,82 +135,6 @@ llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
}
}
-DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple)
- : Darwin(Host, Triple)
-{
- // We can only work with 4.2.1 currently.
- GCCVersion[0] = 4;
- GCCVersion[1] = 2;
- GCCVersion[2] = 1;
-
- // Set up the tool chain paths to match gcc.
- ToolChainDir = "i686-apple-darwin";
- ToolChainDir += llvm::utostr(DarwinVersion[0]);
- ToolChainDir += "/";
- ToolChainDir += llvm::utostr(GCCVersion[0]);
- ToolChainDir += '.';
- ToolChainDir += llvm::utostr(GCCVersion[1]);
- ToolChainDir += '.';
- ToolChainDir += llvm::utostr(GCCVersion[2]);
-
- // Try the next major version if that tool chain dir is invalid.
- std::string Tmp = "/usr/lib/gcc/" + ToolChainDir;
- bool Exists;
- if (llvm::sys::fs::exists(Tmp, Exists) || Exists) {
- std::string Next = "i686-apple-darwin";
- Next += llvm::utostr(DarwinVersion[0] + 1);
- Next += "/";
- Next += llvm::utostr(GCCVersion[0]);
- Next += '.';
- Next += llvm::utostr(GCCVersion[1]);
- Next += '.';
- Next += llvm::utostr(GCCVersion[2]);
-
- // Use that if it exists, otherwise hope the user isn't linking.
- //
- // FIXME: Drop dependency on gcc's tool chain.
- Tmp = "/usr/lib/gcc/" + Next;
- if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
- ToolChainDir = Next;
- }
-
- std::string Path;
- if (getArchName() == "x86_64") {
- Path = getDriver().Dir;
- Path += "/../lib/gcc/";
- Path += ToolChainDir;
- Path += "/x86_64";
- getFilePaths().push_back(Path);
-
- Path = "/usr/lib/gcc/";
- Path += ToolChainDir;
- Path += "/x86_64";
- getFilePaths().push_back(Path);
- }
-
- Path = getDriver().Dir;
- Path += "/../lib/gcc/";
- Path += ToolChainDir;
- getFilePaths().push_back(Path);
-
- Path = "/usr/lib/gcc/";
- Path += ToolChainDir;
- getFilePaths().push_back(Path);
-
- Path = getDriver().Dir;
- Path += "/../libexec/gcc/";
- Path += ToolChainDir;
- getProgramPaths().push_back(Path);
-
- Path = "/usr/libexec/gcc/";
- Path += ToolChainDir;
- getProgramPaths().push_back(Path);
-
- getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir)
- getProgramPaths().push_back(getDriver().Dir);
-}
-
Darwin::~Darwin() {
// Free tool implementations.
for (llvm::DenseMap<unsigned, Tool*>::iterator
@@ -226,33 +152,31 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const {
unsigned Version[3];
getTargetVersion(Version);
-
- // Mangle the target version into the OS triple component. For historical
- // reasons that make little sense, the version passed here is the "darwin"
- // version, which drops the 10 and offsets by 4. See inverse code when
- // setting the OS version preprocessor define.
- if (!isTargetIPhoneOS()) {
- Version[0] = Version[1] + 4;
- Version[1] = Version[2];
- Version[2] = 0;
- } else {
- // Use the environment to communicate that we are targetting iPhoneOS.
- Triple.setEnvironmentName("iphoneos");
- }
-
+
llvm::SmallString<16> Str;
- llvm::raw_svector_ostream(Str) << "darwin" << Version[0]
- << "." << Version[1] << "." << Version[2];
+ llvm::raw_svector_ostream(Str)
+ << (isTargetIPhoneOS() ? "ios" : "macosx")
+ << Version[0] << "." << Version[1] << "." << Version[2];
Triple.setOSName(Str.str());
return Triple.getTriple();
}
-Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
+
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {
+ // Fallback to llvm-gcc for i386 kext compiles, we don't support that ABI.
+ if (Inputs.size() == 1 &&
+ types::isCXX(Inputs[0]->getType()) &&
+ getTriple().getOS() == llvm::Triple::Darwin &&
+ getTriple().getArch() == llvm::Triple::x86 &&
+ C.getArgs().getLastArg(options::OPT_fapple_kext))
+ Key = JA.getKind();
+ else
+ Key = Action::AnalyzeJobClass;
+ } else
Key = JA.getKind();
// FIXME: This doesn't belong here, but ideally we will support static soon
@@ -297,91 +221,12 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
return *T;
}
-void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- std::string Tmp;
-
- // FIXME: Derive these correctly.
- if (getArchName() == "x86_64") {
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
- "/x86_64"));
- // Intentionally duplicated for (temporary) gcc bug compatibility.
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
- "/x86_64"));
- }
-
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
-
- Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir;
- bool Exists;
- if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
- Tmp = getDriver().Dir + "/../lib/gcc";
- if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
- // Intentionally duplicated for (temporary) gcc bug compatibility.
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
- Tmp = getDriver().Dir + "/../lib/" + ToolChainDir;
- if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
- Tmp = getDriver().Dir + "/../lib";
- if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
- "/../../../" + ToolChainDir));
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
- "/../../.."));
-}
-
-void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- // Note that this routine is only used for targetting OS X.
-
- // Derived from libgcc and lib specs but refactored.
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-lgcc_static");
- } else {
- if (Args.hasArg(options::OPT_static_libgcc)) {
- CmdArgs.push_back("-lgcc_eh");
- } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
- // Derived from darwin_iphoneos_libgcc spec.
- if (isTargetIPhoneOS()) {
- CmdArgs.push_back("-lgcc_s.1");
- } else {
- CmdArgs.push_back("-lgcc_s.10.5");
- }
- } else if (Args.hasArg(options::OPT_shared_libgcc) ||
- Args.hasFlag(options::OPT_fexceptions,
- options::OPT_fno_exceptions) ||
- Args.hasArg(options::OPT_fgnu_runtime)) {
- // FIXME: This is probably broken on 10.3?
- if (isMacosxVersionLT(10, 5))
- CmdArgs.push_back("-lgcc_s.10.4");
- else if (isMacosxVersionLT(10, 6))
- CmdArgs.push_back("-lgcc_s.10.5");
- } else {
- if (isMacosxVersionLT(10, 3, 9))
- ; // Do nothing.
- else if (isMacosxVersionLT(10, 5))
- CmdArgs.push_back("-lgcc_s.10.4");
- else if (isMacosxVersionLT(10, 6))
- CmdArgs.push_back("-lgcc_s.10.5");
- }
-
- if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) {
- CmdArgs.push_back("-lgcc");
- CmdArgs.push_back("-lSystem");
- } else {
- CmdArgs.push_back("-lSystem");
- CmdArgs.push_back("-lgcc");
- }
- }
-}
DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple)
: Darwin(Host, Triple)
{
+ std::string UsrPrefix = "llvm-gcc-4.2/";
+
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
@@ -392,18 +237,18 @@ DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple)
getProgramPaths().push_back(getDriver().Dir);
// For fallback, we need to know how to find the GCC cc1 executables, so we
- // also add the GCC libexec paths. This is legiy code that can be removed once
- // fallback is no longer useful.
+ // also add the GCC libexec paths. This is legacy code that can be removed
+ // once fallback is no longer useful.
std::string ToolChainDir = "i686-apple-darwin";
ToolChainDir += llvm::utostr(DarwinVersion[0]);
ToolChainDir += "/4.2.1";
std::string Path = getDriver().Dir;
- Path += "/../libexec/gcc/";
+ Path += "/../" + UsrPrefix + "libexec/gcc/";
Path += ToolChainDir;
getProgramPaths().push_back(Path);
- Path = "/usr/libexec/gcc/";
+ Path = "/usr/" + UsrPrefix + "libexec/gcc/";
Path += ToolChainDir;
getProgramPaths().push_back(Path);
}
@@ -498,12 +343,13 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
// Select the dynamic runtime library and the target specific static library.
const char *DarwinStaticLib = 0;
if (isTargetIPhoneOS()) {
- CmdArgs.push_back("-lgcc_s.1");
+ // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
+ // it never went into the SDK.
+ if (!isTargetIOSSimulator())
+ CmdArgs.push_back("-lgcc_s.1");
- // We may need some static functions for armv6/thumb which are required to
- // be in the same linkage unit as their caller.
- if (getDarwinArchName(Args) == "armv6")
- DarwinStaticLib = "libclang_rt.armv6.a";
+ // We currently always need a static runtime library for iOS.
+ DarwinStaticLib = "libclang_rt.ios.a";
} else {
// The dynamic runtime library was merged with libSystem for 10.6 and
// beyond; only 10.4 and 10.5 need an additional runtime library.
@@ -513,7 +359,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
CmdArgs.push_back("-lgcc_s.10.5");
// For OS X, we thought we would only need a static runtime library when
- // targetting 10.4, to provide versions of the static functions which were
+ // targeting 10.4, to provide versions of the static functions which were
// omitted from 10.4.dylib.
//
// Unfortunately, that turned out to not be true, because Darwin system
@@ -547,46 +393,69 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
const OptTable &Opts = getDriver().getOpts();
Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
- Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
- if (OSXVersion && iPhoneVersion) {
+ Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
+ Arg *iOSSimVersion = Args.getLastArg(
+ options::OPT_mios_simulator_version_min_EQ);
+ if (OSXVersion && (iOSVersion || iOSSimVersion)) {
getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
<< OSXVersion->getAsString(Args)
- << iPhoneVersion->getAsString(Args);
- iPhoneVersion = 0;
- } else if (!OSXVersion && !iPhoneVersion) {
- // If neither OS X nor iPhoneOS targets were specified, check for
+ << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args);
+ iOSVersion = iOSSimVersion = 0;
+ } else if (iOSVersion && iOSSimVersion) {
+ getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
+ << iOSVersion->getAsString(Args)
+ << iOSSimVersion->getAsString(Args);
+ iOSSimVersion = 0;
+ } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) {
+ // If not deployment target was specified on the command line, check for
// environment defines.
const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET");
- const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
+ const char *iOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
+ const char *iOSSimTarget = ::getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET");
// Ignore empty strings.
if (OSXTarget && OSXTarget[0] == '\0')
OSXTarget = 0;
- if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0')
- iPhoneOSTarget = 0;
+ if (iOSTarget && iOSTarget[0] == '\0')
+ iOSTarget = 0;
+ if (iOSSimTarget && iOSSimTarget[0] == '\0')
+ iOSSimTarget = 0;
- // Diagnose conflicting deployment targets, and choose default platform
- // based on the tool chain.
+ // Handle conflicting deployment targets
//
// FIXME: Don't hardcode default here.
- if (OSXTarget && iPhoneOSTarget) {
- // FIXME: We should see if we can get away with warning or erroring on
- // this. Perhaps put under -pedantic?
+
+ // Do not allow conflicts with the iOS simulator target.
+ if (iOSSimTarget && (OSXTarget || iOSTarget)) {
+ getDriver().Diag(clang::diag::err_drv_conflicting_deployment_targets)
+ << "IOS_SIMULATOR_DEPLOYMENT_TARGET"
+ << (OSXTarget ? "MACOSX_DEPLOYMENT_TARGET" :
+ "IPHONEOS_DEPLOYMENT_TARGET");
+ }
+
+ // Allow conflicts among OSX and iOS for historical reasons, but choose the
+ // default platform.
+ if (OSXTarget && iOSTarget) {
if (getTriple().getArch() == llvm::Triple::arm ||
getTriple().getArch() == llvm::Triple::thumb)
OSXTarget = 0;
else
- iPhoneOSTarget = 0;
+ iOSTarget = 0;
}
if (OSXTarget) {
const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
Args.append(OSXVersion);
- } else if (iPhoneOSTarget) {
+ } else if (iOSTarget) {
const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
- iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget);
- Args.append(iPhoneVersion);
+ iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget);
+ Args.append(iOSVersion);
+ } else if (iOSSimTarget) {
+ const Option *O = Opts.getOption(
+ options::OPT_mios_simulator_version_min_EQ);
+ iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
+ Args.append(iOSSimVersion);
} else {
// Otherwise, assume we are targeting OS X.
const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
@@ -595,25 +464,44 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
+ // Reject invalid architecture combinations.
+ if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 &&
+ getTriple().getArch() != llvm::Triple::x86_64)) {
+ getDriver().Diag(clang::diag::err_drv_invalid_arch_for_deployment_target)
+ << getTriple().getArchName() << iOSSimVersion->getAsString(Args);
+ }
+
// Set the tool chain target information.
unsigned Major, Minor, Micro;
bool HadExtra;
if (OSXVersion) {
- assert(!iPhoneVersion && "Unknown target platform!");
+ assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!");
if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
Micro, HadExtra) || HadExtra ||
- Major != 10 || Minor >= 10 || Micro >= 10)
+ Major != 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(clang::diag::err_drv_invalid_version_number)
<< OSXVersion->getAsString(Args);
} else {
- assert(iPhoneVersion && "Unknown target platform!");
- if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
+ const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
+ assert(Version && "Unknown target platform!");
+ if (!Driver::GetReleaseVersion(Version->getValue(Args), Major, Minor,
Micro, HadExtra) || HadExtra ||
Major >= 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(clang::diag::err_drv_invalid_version_number)
- << iPhoneVersion->getAsString(Args);
+ << Version->getAsString(Args);
}
- setTarget(iPhoneVersion, Major, Minor, Micro);
+
+ bool IsIOSSim = bool(iOSSimVersion);
+
+ // In GCC, the simulator historically was treated as being OS X in some
+ // contexts, like determining the link logic, despite generally being called
+ // with an iOS deployment target. For compatibility, we detect the
+ // simulator as iOS + x86, and treat it differently in a few contexts.
+ if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
+ getTriple().getArch() == llvm::Triple::x86_64))
+ IsIOSSim = true;
+
+ setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim);
}
void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
@@ -716,9 +604,12 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
// driver behavior; that isn't going to work in our model. We
// use isDriverOption() as an approximation, although things
// like -O4 are going to slip through.
- if (!XarchArg || Index > Prev + 1 ||
- XarchArg->getOption().isDriverOption()) {
- getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
+ if (!XarchArg || Index > Prev + 1) {
+ getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument_with_args)
+ << A->getAsString(Args);
+ continue;
+ } else if (XarchArg->getOption().isDriverOption()) {
+ getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument_isdriver)
<< A->getAsString(Args);
continue;
}
@@ -922,6 +813,11 @@ const char *Darwin::GetForcedPicModel() const {
return 0;
}
+bool Darwin::SupportsProfiling() const {
+ // Profiling instrumentation is only supported on x86.
+ return getArchName() == "i386" || getArchName() == "x86_64";
+}
+
bool Darwin::SupportsObjCGC() const {
// Garbage collection is supported everywhere except on iPhone OS.
return !isTargetIPhoneOS();
@@ -939,7 +835,7 @@ Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const {
Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
: ToolChain(Host, Triple) {
getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+ if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
}
@@ -951,7 +847,8 @@ Generic_GCC::~Generic_GCC() {
}
Tool &Generic_GCC::SelectTool(const Compilation &C,
- const JobAction &JA) const {
+ const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1039,7 +936,8 @@ const char *TCEToolChain::GetForcedPicModel() const {
}
Tool &TCEToolChain::SelectTool(const Compilation &C,
- const JobAction &JA) const {
+ const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
Key = Action::AnalyzeJobClass;
@@ -1065,7 +963,8 @@ OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
getFilePaths().push_back("/usr/lib");
}
-Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1089,7 +988,7 @@ Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::openbsd::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1115,7 +1014,8 @@ FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple)
}
}
-Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1138,7 +1038,7 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::freebsd::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1157,16 +1057,16 @@ NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple)
llvm::Triple::x86_64)
Lib32 = true;
- getProgramPaths().push_back(getDriver().Dir + "/../libexec");
- getProgramPaths().push_back("/usr/libexec");
- if (Lib32) {
- getFilePaths().push_back("/usr/lib/i386");
- } else {
- getFilePaths().push_back("/usr/lib");
+ if (getDriver().UseStdLib) {
+ if (Lib32)
+ getFilePaths().push_back("=/usr/lib/i386");
+ else
+ getFilePaths().push_back("=/usr/lib");
}
}
-Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1189,7 +1089,7 @@ Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::netbsd::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1206,7 +1106,8 @@ Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple)
getFilePaths().push_back("/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
}
-Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1221,7 +1122,7 @@ Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::minix::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1234,7 +1135,7 @@ AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_GCC(Host, Triple) {
getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+ if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
getFilePaths().push_back(getDriver().Dir + "/../lib");
@@ -1245,7 +1146,8 @@ AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
}
-Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1260,7 +1162,7 @@ Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::auroraux::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1277,16 +1179,22 @@ enum LinuxDistro {
Exherbo,
Fedora13,
Fedora14,
+ Fedora15,
+ FedoraRawhide,
OpenSuse11_3,
+ UbuntuHardy,
+ UbuntuIntrepid,
UbuntuJaunty,
UbuntuKarmic,
UbuntuLucid,
UbuntuMaverick,
+ UbuntuNatty,
UnknownDistro
};
static bool IsFedora(enum LinuxDistro Distro) {
- return Distro == Fedora13 || Distro == Fedora14;
+ return Distro == Fedora13 || Distro == Fedora14 ||
+ Distro == Fedora15 || Distro == FedoraRawhide;
}
static bool IsOpenSuse(enum LinuxDistro Distro) {
@@ -1298,8 +1206,10 @@ static bool IsDebian(enum LinuxDistro Distro) {
}
static bool IsUbuntu(enum LinuxDistro Distro) {
- return Distro == UbuntuLucid || Distro == UbuntuMaverick ||
- Distro == UbuntuJaunty || Distro == UbuntuKarmic;
+ return Distro == UbuntuHardy || Distro == UbuntuIntrepid ||
+ Distro == UbuntuLucid || Distro == UbuntuMaverick ||
+ Distro == UbuntuJaunty || Distro == UbuntuKarmic ||
+ Distro == UbuntuNatty;
}
static bool IsDebianBased(enum LinuxDistro Distro) {
@@ -1315,7 +1225,9 @@ static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) {
return true;
}
- if (Arch == llvm::Triple::x86 && IsDebianBased(Distro))
+ if (Arch == llvm::Triple::ppc64)
+ return true;
+ if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) && IsDebianBased(Distro))
return true;
return false;
}
@@ -1327,24 +1239,35 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
llvm::SmallVector<llvm::StringRef, 8> Lines;
Data.split(Lines, "\n");
for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) {
- if (Lines[i] == "DISTRIB_CODENAME=maverick")
- return UbuntuMaverick;
- else if (Lines[i] == "DISTRIB_CODENAME=lucid")
- return UbuntuLucid;
+ if (Lines[i] == "DISTRIB_CODENAME=hardy")
+ return UbuntuHardy;
+ else if (Lines[i] == "DISTRIB_CODENAME=intrepid")
+ return UbuntuIntrepid;
else if (Lines[i] == "DISTRIB_CODENAME=jaunty")
return UbuntuJaunty;
else if (Lines[i] == "DISTRIB_CODENAME=karmic")
return UbuntuKarmic;
+ else if (Lines[i] == "DISTRIB_CODENAME=lucid")
+ return UbuntuLucid;
+ else if (Lines[i] == "DISTRIB_CODENAME=maverick")
+ return UbuntuMaverick;
+ else if (Lines[i] == "DISTRIB_CODENAME=natty")
+ return UbuntuNatty;
}
return UnknownDistro;
}
if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
llvm::StringRef Data = File.get()->getBuffer();
- if (Data.startswith("Fedora release 14 (Laughlin)"))
+ if (Data.startswith("Fedora release 15"))
+ return Fedora15;
+ else if (Data.startswith("Fedora release 14"))
return Fedora14;
- else if (Data.startswith("Fedora release 13 (Goddard)"))
+ else if (Data.startswith("Fedora release 13"))
return Fedora13;
+ else if (Data.startswith("Fedora release") &&
+ Data.find("Rawhide") != llvm::StringRef::npos)
+ return FedoraRawhide;
return UnknownDistro;
}
@@ -1384,7 +1307,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
Suffix32 = "/32";
std::string Suffix64 = "";
- if (Arch == llvm::Triple::x86)
+ if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
Suffix64 = "/64";
std::string Lib32 = "lib";
@@ -1400,7 +1323,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
Lib64 = "lib64";
std::string GccTriple = "";
- if (Arch == llvm::Triple::arm) {
+ if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
if (!llvm::sys::fs::exists("/usr/lib/gcc/arm-linux-gnueabi", Exists) &&
Exists)
GccTriple = "arm-linux-gnueabi";
@@ -1423,6 +1346,9 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-manbo-linux-gnu",
Exists) && Exists)
GccTriple = "x86_64-manbo-linux-gnu";
+ else if (!llvm::sys::fs::exists("/usr/lib/x86_64-linux-gnu/gcc",
+ Exists) && Exists)
+ GccTriple = "x86_64-linux-gnu";
} else if (Arch == llvm::Triple::x86) {
if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-linux-gnu", Exists) && Exists)
GccTriple = "i686-linux-gnu";
@@ -1438,11 +1364,26 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
else if (!llvm::sys::fs::exists("/usr/lib/gcc/i586-suse-linux", Exists) &&
Exists)
GccTriple = "i586-suse-linux";
+ else if (!llvm::sys::fs::exists("/usr/lib/gcc/i486-slackware-linux", Exists)
+ && Exists)
+ GccTriple = "i486-slackware-linux";
+ } else if (Arch == llvm::Triple::ppc) {
+ if (!llvm::sys::fs::exists("/usr/lib/powerpc-linux-gnu", Exists) && Exists)
+ GccTriple = "powerpc-linux-gnu";
+ else if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc-unknown-linux-gnu", Exists) && Exists)
+ GccTriple = "powerpc-unknown-linux-gnu";
+ } else if (Arch == llvm::Triple::ppc64) {
+ if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists)
+ GccTriple = "powerpc64-unknown-linux-gnu";
+ else if (!llvm::sys::fs::exists("/usr/lib64/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists)
+ GccTriple = "powerpc64-unknown-linux-gnu";
}
- const char* GccVersions[] = {"4.5.2", "4.5.1", "4.5", "4.4.5", "4.4.4",
- "4.4.3", "4.4", "4.3.4", "4.3.3", "4.3.2",
- "4.3"};
+ const char* GccVersions[] = {"4.6.0",
+ "4.5.2", "4.5.1", "4.5",
+ "4.4.5", "4.4.4", "4.4.3", "4.4",
+ "4.3.4", "4.3.3", "4.3.2", "4.3",
+ "4.2.4", "4.2.3", "4.2.2", "4.2.1", "4.2"};
std::string Base = "";
for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) {
std::string Suffix = GccTriple + "/" + GccVersions[i];
@@ -1456,10 +1397,15 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
Base = t2;
break;
}
+ std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix;
+ if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) {
+ Base = t3;
+ break;
+ }
}
path_list &Paths = getFilePaths();
- bool Is32Bits = getArch() == llvm::Triple::x86;
+ bool Is32Bits = (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::ppc);
std::string Suffix;
std::string Lib;
@@ -1485,10 +1431,10 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
ExtraOpts.push_back("relro");
}
- if (Arch == llvm::Triple::arm)
+ if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
ExtraOpts.push_back("-X");
- if (IsFedora(Distro) || Distro == UbuntuMaverick)
+ if (IsFedora(Distro) || Distro == UbuntuMaverick || Distro == UbuntuNatty)
ExtraOpts.push_back("--hash-style=gnu");
if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty ||
@@ -1500,7 +1446,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
if (Distro == DebianSqueeze || IsOpenSuse(Distro) ||
IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick ||
- Distro == UbuntuKarmic)
+ Distro == UbuntuKarmic || Distro == UbuntuNatty)
ExtraOpts.push_back("--build-id");
if (Distro == ArchLinux)
@@ -1527,7 +1473,8 @@ bool Linux::HasNativeLLVMSupport() const {
return true;
}
-Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1550,7 +1497,7 @@ Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::linuxtools::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1564,7 +1511,7 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
// Path mangling to find libexec
getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+ if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
getFilePaths().push_back(getDriver().Dir + "/../lib");
@@ -1572,7 +1519,8 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
getFilePaths().push_back("/usr/lib/gcc41");
}
-Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
@@ -1587,7 +1535,7 @@ Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
case Action::LinkJobClass:
T = new tools::dragonfly::Link(*this); break;
default:
- T = &Generic_GCC::SelectTool(C, JA);
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
@@ -1598,7 +1546,8 @@ Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple)
: ToolChain(Host, Triple) {
}
-Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const {
+Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
index 0e3645c..7a1a050 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
@@ -33,7 +33,8 @@ public:
Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
~Generic_GCC();
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
virtual bool IsUnwindTablesDefault() const;
virtual const char *GetDefaultRelocationModel() const;
@@ -56,10 +57,13 @@ private:
// the argument translation business.
mutable bool TargetInitialized;
- /// Whether we are targetting iPhoneOS target.
+ /// Whether we are targeting iPhoneOS target.
mutable bool TargetIsIPhoneOS;
- /// The OS version we are targetting.
+ /// Whether we are targeting the iPhoneOS simulator target.
+ mutable bool TargetIsIPhoneOSSimulator;
+
+ /// The OS version we are targeting.
mutable unsigned TargetVersion[3];
/// The default macosx-version-min of this tool chain; empty until
@@ -80,18 +84,22 @@ public:
// FIXME: Eliminate these ...Target functions and derive separate tool chains
// for these targets and put version in constructor.
- void setTarget(bool isIPhoneOS, unsigned Major, unsigned Minor,
- unsigned Micro) const {
+ void setTarget(bool IsIPhoneOS, unsigned Major, unsigned Minor,
+ unsigned Micro, bool IsIOSSim) const {
+ assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!");
+
// FIXME: For now, allow reinitialization as long as values don't
// change. This will go away when we move away from argument translation.
- if (TargetInitialized && TargetIsIPhoneOS == isIPhoneOS &&
+ if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS &&
+ TargetIsIPhoneOSSimulator == IsIOSSim &&
TargetVersion[0] == Major && TargetVersion[1] == Minor &&
TargetVersion[2] == Micro)
return;
assert(!TargetInitialized && "Target already initialized!");
TargetInitialized = true;
- TargetIsIPhoneOS = isIPhoneOS;
+ TargetIsIPhoneOS = IsIPhoneOS;
+ TargetIsIPhoneOSSimulator = IsIOSSim;
TargetVersion[0] = Major;
TargetVersion[1] = Minor;
TargetVersion[2] = Micro;
@@ -102,6 +110,11 @@ public:
return TargetIsIPhoneOS;
}
+ bool isTargetIOSSimulator() const {
+ assert(TargetInitialized && "Target not initialized!");
+ return TargetIsIPhoneOSSimulator;
+ }
+
bool isTargetInitialized() const { return TargetInitialized; }
void getTargetVersion(unsigned (&Res)[3]) const {
@@ -160,7 +173,8 @@ public:
virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
const char *BoundArch) const;
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
virtual bool IsBlocksDefault() const {
// Always allow blocks on Darwin; users interested in versioning are
@@ -212,6 +226,8 @@ public:
virtual const char *GetDefaultRelocationModel() const;
virtual const char *GetForcedPicModel() const;
+ virtual bool SupportsProfiling() const;
+
virtual bool SupportsObjCGC() const;
virtual bool UseDwarfDebugFlags() const;
@@ -244,29 +260,6 @@ public:
/// }
};
-/// DarwinGCC - The Darwin toolchain used by GCC.
-class LLVM_LIBRARY_VISIBILITY DarwinGCC : public Darwin {
- /// GCC version to use.
- unsigned GCCVersion[3];
-
- /// The directory suffix for this tool chain.
- std::string ToolChainDir;
-
-public:
- DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple);
-
- /// @name Darwin ToolChain Implementation
- /// {
-
- virtual void AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const;
-
- virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const;
-
- /// }
-};
-
/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
public:
@@ -294,42 +287,48 @@ class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
public:
AuroraUX(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
public:
OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
public:
FreeBSD(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
public:
NetBSD(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC {
public:
Minix(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
public:
DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
};
class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
@@ -338,7 +337,8 @@ public:
virtual bool HasNativeLLVMSupport() const;
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
std::string Linker;
std::vector<std::string> ExtraOpts;
@@ -352,7 +352,8 @@ public:
TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
~TCEToolChain();
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
bool IsMathErrnoDefault() const;
bool IsUnwindTablesDefault() const;
const char* GetDefaultRelocationModel() const;
@@ -369,7 +370,8 @@ class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
public:
Windows(const HostInfo &Host, const llvm::Triple& Triple);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
virtual bool IsIntegratedAssemblerDefault() const;
virtual bool IsUnwindTablesDefault() const;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index a2c95fc..7b78cd5 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -34,14 +34,32 @@
#include "InputInfo.h"
#include "ToolChains.h"
+#ifdef __CYGWIN__
+#include <cygwin/version.h>
+#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
+#define IS_CYGWIN15 1
+#endif
+#endif
+
using namespace clang::driver;
using namespace clang::driver::tools;
+/// FindTargetProgramPath - Return path of the target specific version of
+/// ProgName. If it doesn't exist, return path of ProgName itself.
+static std::string FindTargetProgramPath(const ToolChain &TheToolChain,
+ const char *ProgName) {
+ std::string Executable(TheToolChain.getTripleString() + "-" + ProgName);
+ std::string Path(TheToolChain.GetProgramPath(Executable.c_str()));
+ if (Path != Executable)
+ return Path;
+ return TheToolChain.GetProgramPath(ProgName);
+}
+
/// CheckPreprocessingOptions - Perform some validation of preprocessing
/// arguments that is shared with gcc.
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
- if (!Args.hasArg(options::OPT_E))
+ if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-E";
}
@@ -309,7 +327,7 @@ void Clang::AddPreprocessingOptions(const Driver &D,
}
}
-/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
//
// FIXME: tblgen this.
static const char *getARMTargetCPU(const ArgList &Args,
@@ -363,6 +381,8 @@ static const char *getARMTargetCPU(const ArgList &Args,
return "iwmmxt";
if (MArch == "xscale")
return "xscale";
+ if (MArch == "armv6m" || MArch == "armv6-m")
+ return "cortex-m0";
// If all else failed, return the most base CPU LLVM supports.
return "arm7tdmi";
@@ -420,10 +440,17 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
}
void Clang::AddARMTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
+ ArgStringList &CmdArgs,
+ bool KernelOrKext) const {
const Driver &D = getToolChain().getDriver();
llvm::Triple Triple = getToolChain().getTriple();
+ // Disable movt generation, if requested.
+#ifdef DISABLE_ARM_DARWIN_USE_MOVT
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-darwin-use-movt=0");
+#endif
+
// Select the ABI to use.
//
// FIXME: Support -meabi.
@@ -577,6 +604,28 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
} else
D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
+
+ // Setting -msoft-float effectively disables NEON because of the GCC
+ // implementation, although the same isn't true of VFP or VFP3.
+ if (FloatABI == "soft") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-neon");
+ }
+
+ // Kernel code has more strict alignment requirements.
+ if (KernelOrKext) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-long-calls");
+
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-strict-align");
+
+ // The kext linker doesn't know how to deal with movw/movt.
+#ifndef DISABLE_ARM_DARWIN_USE_MOVT
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-darwin-use-movt=0");
+#endif
+ }
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
@@ -726,12 +775,12 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
CPUName = "x86-64";
else if (getToolChain().getArchName() == "i386")
CPUName = "i486";
- } else if (getToolChain().getOS().startswith("netbsd")) {
+ } else if (getToolChain().getOS().startswith("freebsd")) {
if (getToolChain().getArchName() == "x86_64")
CPUName = "x86-64";
else if (getToolChain().getArchName() == "i386")
CPUName = "i486";
- } else if (getToolChain().getOS().startswith("freebsd")) {
+ } else if (getToolChain().getOS().startswith("netbsd")) {
if (getToolChain().getArchName() == "x86_64")
CPUName = "x86-64";
else if (getToolChain().getArchName() == "i386")
@@ -767,34 +816,112 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
}
}
-static bool needsExceptions(const ArgList &Args, types::ID InputType,
- const llvm::Triple &Triple) {
- // Handle -fno-exceptions.
+static bool
+shouldUseExceptionTablesForObjCExceptions(const ArgList &Args,
+ const llvm::Triple &Triple) {
+ // We use the zero-cost exception tables for Objective-C if the non-fragile
+ // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
+ // later.
+
+ if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
+ return true;
+
+ if (Triple.getOS() != llvm::Triple::Darwin)
+ return false;
+
+ return (Triple.getDarwinMajorNumber() >= 9 &&
+ (Triple.getArch() == llvm::Triple::x86_64 ||
+ Triple.getArch() == llvm::Triple::arm));
+}
+
+/// addExceptionArgs - Adds exception related arguments to the driver command
+/// arguments. There's a master flag, -fexceptions and also language specific
+/// flags to enable/disable C++ and Objective-C exceptions.
+/// This makes it possible to for example disable C++ exceptions but enable
+/// Objective-C exceptions.
+static void addExceptionArgs(const ArgList &Args, types::ID InputType,
+ const llvm::Triple &Triple,
+ bool KernelOrKext, bool IsRewriter,
+ ArgStringList &CmdArgs) {
+ if (KernelOrKext)
+ return;
+
+ // Exceptions are enabled by default.
+ bool ExceptionsEnabled = true;
+
+ // This keeps track of whether exceptions were explicitly turned on or off.
+ bool DidHaveExplicitExceptionFlag = false;
+
if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
options::OPT_fno_exceptions)) {
if (A->getOption().matches(options::OPT_fexceptions))
- return true;
- else
- return false;
+ ExceptionsEnabled = true;
+ else
+ ExceptionsEnabled = false;
+
+ DidHaveExplicitExceptionFlag = true;
}
- // Otherwise, C++ inputs use exceptions.
- if (types::isCXX(InputType))
- return true;
+ bool ShouldUseExceptionTables = false;
- // As do Objective-C non-fragile ABI inputs and all Objective-C inputs on
- // x86_64 and ARM after SnowLeopard.
- if (types::isObjC(InputType)) {
- if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
- return true;
- if (Triple.getOS() != llvm::Triple::Darwin)
- return false;
- return (Triple.getDarwinMajorNumber() >= 9 &&
- (Triple.getArch() == llvm::Triple::x86_64 ||
- Triple.getArch() == llvm::Triple::arm));
+ // Exception tables and cleanups can be enabled with -fexceptions even if the
+ // language itself doesn't support exceptions.
+ if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
+ ShouldUseExceptionTables = true;
+
+ // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
+ // is not necessarily sensible, but follows GCC.
+ if (types::isObjC(InputType) &&
+ Args.hasFlag(options::OPT_fobjc_exceptions,
+ options::OPT_fno_objc_exceptions,
+ true)) {
+ CmdArgs.push_back("-fobjc-exceptions");
+
+ ShouldUseExceptionTables |=
+ shouldUseExceptionTablesForObjCExceptions(Args, Triple);
}
- return false;
+ if (types::isCXX(InputType)) {
+ bool CXXExceptionsEnabled = ExceptionsEnabled;
+
+ if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
+ options::OPT_fno_cxx_exceptions,
+ options::OPT_fexceptions,
+ options::OPT_fno_exceptions)) {
+ if (A->getOption().matches(options::OPT_fcxx_exceptions))
+ CXXExceptionsEnabled = true;
+ else if (A->getOption().matches(options::OPT_fno_cxx_exceptions))
+ CXXExceptionsEnabled = false;
+ }
+
+ if (CXXExceptionsEnabled) {
+ CmdArgs.push_back("-fcxx-exceptions");
+
+ ShouldUseExceptionTables = true;
+ }
+ }
+
+ if (ShouldUseExceptionTables)
+ CmdArgs.push_back("-fexceptions");
+}
+
+static bool ShouldDisableCFI(const ArgList &Args,
+ const ToolChain &TC) {
+
+ // FIXME: Duplicated code with ToolChains.cpp
+ // FIXME: This doesn't belong here, but ideally we will support static soon
+ // anyway.
+ bool HasStatic = (Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_static) ||
+ Args.hasArg(options::OPT_fapple_kext));
+ bool IsIADefault = TC.IsIntegratedAssemblerDefault() && !HasStatic;
+ bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as,
+ options::OPT_no_integrated_as,
+ IsIADefault);
+ bool UseCFI = Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
+ options::OPT_fno_dwarf2_cfi_asm,
+ UseIntegratedAs);
+ return !UseCFI;
}
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
@@ -837,8 +964,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_O_Group))
IsOpt = !A->getOption().matches(options::OPT_O0);
if (Args.hasFlag(options::OPT_mrelax_all,
- options::OPT_mno_relax_all,
- !IsOpt))
+ options::OPT_mno_relax_all,
+ !IsOpt))
CmdArgs.push_back("-mrelax-all");
// When using an integrated assembler, translate -Wa, and -Xassembler
@@ -855,10 +982,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Value == "-force_cpusubtype_ALL") {
// Do nothing, this is the default and we don't support anything else.
} else if (Value == "-L") {
- // We don't support -L yet, but it isn't important enough to error
- // on. No one should really be using it for a semantic change.
- D.Diag(clang::diag::warn_drv_unsupported_option_argument)
- << A->getOption().getName() << Value;
+ CmdArgs.push_back("-msave-temp-labels");
} else {
D.Diag(clang::diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Value;
@@ -925,29 +1049,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// 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)) {
- types::ID InputType = Inputs[0].getType();
-
- // Checks to perform for all language types.
-
CmdArgs.push_back("-analyzer-checker=core");
+ CmdArgs.push_back("-analyzer-checker=deadcode");
+ CmdArgs.push_back("-analyzer-checker=security");
+
if (getToolChain().getTriple().getOS() != llvm::Triple::Win32)
CmdArgs.push_back("-analyzer-checker=unix");
- if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
- CmdArgs.push_back("-analyzer-checker=macosx");
-
- // Checks to perform for Objective-C/Objective-C++.
- if (types::isObjC(InputType)) {
- // Enable all checkers in 'cocoa' package.
- CmdArgs.push_back("-analyzer-checker=cocoa");
- }
- // NOTE: Leaving -analyzer-check-objc-mem here is intentional.
- // It also checks C code.
- CmdArgs.push_back("-analyzer-check-objc-mem");
-
- CmdArgs.push_back("-analyzer-eagerly-assume");
+ if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
+ CmdArgs.push_back("-analyzer-checker=osx");
}
// Set the output format. The default is plist, for (lame) historical
@@ -1011,7 +1125,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
if (!Args.hasFlag(options::OPT_fmerge_all_constants,
options::OPT_fno_merge_all_constants))
- CmdArgs.push_back("-no-merge-all-constants");
+ CmdArgs.push_back("-fno-merge-all-constants");
// LLVM Code Generator Options.
@@ -1020,6 +1134,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
+ if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
+ CmdArgs.push_back("-mrtd");
+
// FIXME: Set --enable-unsafe-fp-math.
if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
options::OPT_fomit_frame_pointer))
@@ -1054,6 +1171,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin)
CmdArgs.push_back("-mconstructor-aliases");
+ // Darwin's kernel doesn't support guard variables; just die if we
+ // try to use them.
+ if (KernelOrKext &&
+ getToolChain().getTriple().getOS() == llvm::Triple::Darwin)
+ CmdArgs.push_back("-fforbid-guard-variables");
+
if (Args.hasArg(options::OPT_mms_bitfields)) {
CmdArgs.push_back("-mms-bitfields");
}
@@ -1090,7 +1213,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::arm:
case llvm::Triple::thumb:
- AddARMTargetArgs(Args, CmdArgs);
+ AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
break;
case llvm::Triple::mips:
@@ -1155,6 +1278,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_P);
Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
+ if (D.CCLogDiagnostics) {
+ CmdArgs.push_back("-diagnostic-log-file");
+ CmdArgs.push_back(D.CCLogDiagnosticsFilename ?
+ D.CCLogDiagnosticsFilename : "-");
+ }
+
// Special case debug options to only pass -g to clang. This is
// wrong.
Args.ClaimAllArgs(options::OPT_g_Group);
@@ -1167,6 +1296,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
+ if (Args.hasArg(options::OPT_ftest_coverage) ||
+ Args.hasArg(options::OPT_coverage))
+ CmdArgs.push_back("-femit-coverage-notes");
+ if (Args.hasArg(options::OPT_fprofile_arcs) ||
+ Args.hasArg(options::OPT_coverage))
+ CmdArgs.push_back("-femit-coverage-data");
+
Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
@@ -1192,10 +1328,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else if (A->getOption().matches(options::OPT_O) &&
A->getValue(Args)[0] == '\0')
CmdArgs.push_back("-O2");
- else if (A->getOption().matches(options::OPT_O) &&
- A->getValue(Args)[0] == 'z' &&
- A->getValue(Args)[1] == '\0')
- CmdArgs.push_back("-Os");
else
A->render(Args, CmdArgs);
}
@@ -1236,6 +1368,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
}
+ // Map the bizarre '-Wwrite-strings' flag to a more sensible
+ // '-fconst-strings'; this better indicates its actual behavior.
+ if (Args.hasFlag(options::OPT_Wwrite_strings, options::OPT_Wno_write_strings,
+ false)) {
+ // For perfect compatibility with GCC, we do this even in the presence of
+ // '-w'. This flag names something other than a warning for GCC.
+ CmdArgs.push_back("-fconst-strings");
+ }
+
+ // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
+ // during C++ compilation, which it is by default. GCC keeps this define even
+ // in the presence of '-w', match this behavior bug-for-bug.
+ if (types::isCXX(InputType) &&
+ Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
+ true)) {
+ CmdArgs.push_back("-fdeprecated-macro");
+ }
+
// Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
if (Asm->getOption().matches(options::OPT_fasm))
@@ -1244,6 +1394,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fno-gnu-keywords");
}
+ if (ShouldDisableCFI(Args, getToolChain()))
+ CmdArgs.push_back("-fno-dwarf2-cfi-asm");
+
if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
CmdArgs.push_back("-ftemplate-depth");
CmdArgs.push_back(A->getValue(Args));
@@ -1317,7 +1470,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
- Args.AddLastArg(CmdArgs, options::OPT_pg);
+ if (getToolChain().SupportsProfiling())
+ Args.AddLastArg(CmdArgs, options::OPT_pg);
// -flax-vector-conversions is default.
if (!Args.hasFlag(options::OPT_flax_vector_conversions,
@@ -1354,7 +1508,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
- Args.AddLastArg(CmdArgs, options::OPT_fwrapv);
+ // Forward -ftrap_function= options to the backend.
+ if (Arg *A = Args.getLastArg(options::OPT_ftrap_function_EQ)) {
+ llvm::StringRef FuncName = A->getValue(Args);
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back(Args.MakeArgString("-trap-func=" + FuncName));
+ }
+
+ // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
+ // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+ if (Arg *A = Args.getLastArg(options::OPT_fwrapv,
+ options::OPT_fno_wrapv)) {
+ if (A->getOption().matches(options::OPT_fwrapv))
+ CmdArgs.push_back("-fwrapv");
+ } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
+ options::OPT_fno_strict_overflow)) {
+ if (A->getOption().matches(options::OPT_fno_strict_overflow))
+ CmdArgs.push_back("-fwrapv");
+ }
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
Args.AddLastArg(CmdArgs, options::OPT_funroll_loops);
@@ -1395,7 +1566,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fblocks=0 is default.
if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
- getToolChain().IsBlocksDefault())) {
+ getToolChain().IsBlocksDefault()) ||
+ (Args.hasArg(options::OPT_fgnu_runtime) &&
+ Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
+ !Args.hasArg(options::OPT_fno_blocks))) {
CmdArgs.push_back("-fblocks");
}
@@ -1411,10 +1585,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
false))
CmdArgs.push_back("-fno-elide-constructors");
- // -fexceptions=0 is default.
- if (!KernelOrKext &&
- needsExceptions(Args, InputType, getToolChain().getTriple()))
- CmdArgs.push_back("-fexceptions");
+ // Add exception args.
+ addExceptionArgs(Args, InputType, getToolChain().getTriple(),
+ KernelOrKext, IsRewriter, CmdArgs);
if (getToolChain().UseSjLjExceptions())
CmdArgs.push_back("-fsjlj-exceptions");
@@ -1469,6 +1642,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_borland_extensions, false))
CmdArgs.push_back("-fborland-extensions");
+ // -fno-delayed-template-parsing is default.
+ if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
+ options::OPT_fno_delayed_template_parsing,
+ false))
+ CmdArgs.push_back("-fdelayed-template-parsing");
+
// -fgnu-keywords default varies depending on language; only pass if
// specified.
if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
@@ -1545,17 +1724,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ // FIXME: Don't expose -fobjc-default-synthesize-properties as a top-level
+ // driver flag yet. This feature is still under active development
+ // and shouldn't be exposed as a user visible feature (which may change).
+ // Clang still supports this as a -cc1 option for development and testing.
+#if 0
// -fobjc-default-synthesize-properties=0 is default.
if (Args.hasFlag(options::OPT_fobjc_default_synthesize_properties,
options::OPT_fno_objc_default_synthesize_properties,
getToolChain().IsObjCDefaultSynthPropertiesDefault())) {
CmdArgs.push_back("-fobjc-default-synthesize-properties");
}
-
- // -fno-objc-exceptions is default.
- if (IsRewriter || Args.hasFlag(options::OPT_fobjc_exceptions,
- options::OPT_fno_objc_exceptions))
- CmdArgs.push_back("-fobjc-exceptions");
+#endif
}
if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
@@ -1619,6 +1799,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
options::OPT_fno_diagnostics_fixit_info))
CmdArgs.push_back("-fno-diagnostics-fixit-info");
+
+ // Enable -fdiagnostics-show-name by default.
+ if (Args.hasFlag(options::OPT_fdiagnostics_show_name,
+ options::OPT_fno_diagnostics_show_name, false))
+ CmdArgs.push_back("-fdiagnostics-show-name");
// Enable -fdiagnostics-show-option by default.
if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
@@ -1631,6 +1816,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
+ if (Arg *A = Args.getLastArg(
+ options::OPT_fdiagnostics_show_note_include_stack,
+ options::OPT_fno_diagnostics_show_note_include_stack)) {
+ if (A->getOption().matches(
+ options::OPT_fdiagnostics_show_note_include_stack))
+ CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
+ else
+ CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
+ }
+
// Color diagnostics are the default, unless the terminal doesn't support
// them.
if (Args.hasFlag(options::OPT_fcolor_diagnostics,
@@ -1686,9 +1881,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
#endif
+ // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
if (Arg *A = Args.getLastArg(options::OPT_traditional,
- options::OPT_traditional_cpp))
- D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ options::OPT_traditional_cpp)) {
+ if (isa<PreprocessJobAction>(JA))
+ CmdArgs.push_back("-traditional-cpp");
+ else
+ D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ }
Args.AddLastArg(CmdArgs, options::OPT_dM);
Args.AddLastArg(CmdArgs, options::OPT_dD);
@@ -1768,6 +1968,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// care to warn the user about.
Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
+
+ // Disable warnings for clang -E -use-gold-plugin -emit-llvm foo.c
+ Args.ClaimAllArgs(options::OPT_use_gold_plugin);
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
}
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1782,6 +1986,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
// Don't warn about "clang -w -c foo.s"
Args.ClaimAllArgs(options::OPT_w);
+ // and "clang -emit-llvm -c foo.s"
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ // and "clang -use-gold-plugin -c foo.s"
+ Args.ClaimAllArgs(options::OPT_use_gold_plugin);
// Invoke ourselves in -cc1as mode.
//
@@ -1807,7 +2015,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
!IsOpt))
CmdArgs.push_back("-relax-all");
- // FIXME: Add -force_cpusubtype_ALL support, once we have it.
+ // Ignore explicit -force_cpusubtype_ALL option.
+ (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
// FIXME: Add -g support, once we have it.
@@ -1815,6 +2024,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
+ Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
assert(Output.isFilename() && "Unexpected lipo output.");
CmdArgs.push_back("-o");
@@ -1930,7 +2140,20 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- const char *GCCName = getToolChain().getDriver().getCCCGenericGCCName().c_str();
+ const std::string customGCCName = D.getCCCGenericGCCName();
+ const char *GCCName;
+ if (!customGCCName.empty())
+ GCCName = customGCCName.c_str();
+ else if (D.CCCIsCXX) {
+#ifdef IS_CYGWIN15
+ // FIXME: Detect the version of Cygwin at runtime?
+ GCCName = "g++-4";
+#else
+ GCCName = "g++";
+#endif
+ } else
+ GCCName = "gcc";
+
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
@@ -2044,10 +2267,6 @@ void darwin::CC1::AddCC1Args(const ArgList &Args,
CmdArgs.push_back("-fno-builtin-strcpy");
}
- // gcc has some code here to deal with when no -mmacosx-version-min
- // and no -miphoneos-version-min is present, but this never happens
- // due to tool chain specific argument translation.
-
if (Args.hasArg(options::OPT_g_Flag) &&
!Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
CmdArgs.push_back("-feliminate-unused-debug-symbols");
@@ -2111,7 +2330,8 @@ void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
if (Args.hasArg(options::OPT_v))
CmdArgs.push_back("-version");
- if (Args.hasArg(options::OPT_pg))
+ if (Args.hasArg(options::OPT_pg) &&
+ getToolChain().SupportsProfiling())
CmdArgs.push_back("-p");
Args.AddLastArg(CmdArgs, options::OPT_p);
@@ -2134,6 +2354,9 @@ void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
} else
Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
+ // Claim Clang only -f options, they aren't worth warning about.
+ Args.ClaimAllArgs(options::OPT_f_clang_Group);
+
Args.AddAllArgs(CmdArgs, options::OPT_undef);
if (Args.hasArg(options::OPT_Qn))
CmdArgs.push_back("-fno-ident");
@@ -2191,6 +2414,9 @@ void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
// The driver treats -fsyntax-only specially.
Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
+ // Claim Clang only -f options, they aren't worth warning about.
+ Args.ClaimAllArgs(options::OPT_f_clang_Group);
+
if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
!Args.hasArg(options::OPT_fno_working_directory))
CmdArgs.push_back("-fworking-directory");
@@ -2322,7 +2548,7 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
OutputArgs.push_back("-o");
OutputArgs.push_back(Output.getFilename());
- if (Args.hasArg(options::OPT_E)) {
+ if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) {
AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
} else {
AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
@@ -2442,11 +2668,16 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
assert(Inputs.size() == 1 && "Unexpected number of inputs.");
const InputInfo &Input = Inputs[0];
- // Bit of a hack, this is only used for original inputs.
- //
- // FIXME: This is broken for preprocessed .s inputs.
- if (Input.isFilename() &&
- strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
+ // Determine the original source input.
+ const Action *SourceAction = &JA;
+ while (SourceAction->getKind() != Action::InputClass) {
+ assert(!SourceAction->getInputs().empty() && "unexpected root action!");
+ SourceAction = SourceAction->getInputs()[0];
+ }
+
+ // Forward -g, assuming we are dealing with an actual assembly file.
+ if (SourceAction->getType() == types::TY_Asm ||
+ SourceAction->getType() == types::TY_PP_Asm) {
if (Args.hasArg(options::OPT_gstabs))
CmdArgs.push_back("--gstabs");
else if (Args.hasArg(options::OPT_g_Group))
@@ -2502,6 +2733,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
const ArgList &Args,
ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
+ const toolchains::Darwin &DarwinTC = getDarwinToolChain();
unsigned Version[3] = { 0, 0, 0 };
if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
@@ -2521,7 +2753,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
// will match the linker version detected at configure time. We need the
// universal driver.
if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle) &&
- !getDarwinToolChain().isTargetIPhoneOS()) {
+ !DarwinTC.isTargetIPhoneOS()) {
// Don't pass -demangle to ld_classic.
//
// FIXME: This is a temporary workaround, ld should be handling this.
@@ -2596,7 +2828,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
Args.AddLastArg(CmdArgs, options::OPT_all__load);
Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
- if (getDarwinToolChain().isTargetIPhoneOS())
+ if (DarwinTC.isTargetIPhoneOS())
Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
@@ -2608,15 +2840,27 @@ void darwin::Link::AddLinkArgs(Compilation &C,
Args.AddAllArgs(CmdArgs, options::OPT_image__base);
Args.AddAllArgs(CmdArgs, options::OPT_init);
- // Adding all arguments doesn't make sense here but this is what gcc does. One
- // of this should always be present thanks to argument translation.
- assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) ||
- Args.hasArg(options::OPT_miphoneos_version_min_EQ)) &&
- "Missing version argument (lost in translation)?");
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
- "-macosx_version_min");
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
- "-iphoneos_version_min");
+ // Add the deployment target.
+ unsigned TargetVersion[3];
+ DarwinTC.getTargetVersion(TargetVersion);
+
+ // If we had an explicit -mios-simulator-version-min argument, honor that,
+ // otherwise use the traditional deployment targets. We can't just check the
+ // is-sim attribute because existing code follows this path, and the linker
+ // may not handle the argument.
+ //
+ // FIXME: We may be able to remove this, once we can verify no one depends on
+ // it.
+ if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
+ CmdArgs.push_back("-ios_simulator_version_min");
+ else if (DarwinTC.isTargetIPhoneOS())
+ CmdArgs.push_back("-iphoneos_version_min");
+ else
+ CmdArgs.push_back("-macosx_version_min");
+ CmdArgs.push_back(Args.MakeArgString(llvm::Twine(TargetVersion[0]) + "." +
+ llvm::Twine(TargetVersion[1]) + "." +
+ llvm::Twine(TargetVersion[2])));
+
Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
Args.AddLastArg(CmdArgs, options::OPT_multi__module);
Args.AddLastArg(CmdArgs, options::OPT_single__module);
@@ -2722,7 +2966,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Derived from startfile spec.
if (Args.hasArg(options::OPT_dynamiclib)) {
// Derived from darwin_dylib1 spec.
- if (getDarwinToolChain().isTargetIPhoneOS()) {
+ if (getDarwinToolChain().isTargetIOSSimulator()) {
+ // The simulator doesn't have a versioned crt1 file.
+ CmdArgs.push_back("-ldylib1.o");
+ } else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-ldylib1.o");
} else {
@@ -2735,7 +2982,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_bundle)) {
if (!Args.hasArg(options::OPT_static)) {
// Derived from darwin_bundle1 spec.
- if (getDarwinToolChain().isTargetIPhoneOS()) {
+ if (getDarwinToolChain().isTargetIOSSimulator()) {
+ // The simulator doesn't have a versioned crt1 file.
+ CmdArgs.push_back("-lbundle1.o");
+ } else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-lbundle1.o");
} else {
@@ -2744,7 +2994,8 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
}
} else {
- if (Args.hasArg(options::OPT_pg)) {
+ if (Args.hasArg(options::OPT_pg) &&
+ getToolChain().SupportsProfiling()) {
if (Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_object) ||
Args.hasArg(options::OPT_preload)) {
@@ -2761,7 +3012,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lcrt0.o");
} else {
// Derived from darwin_crt1 spec.
- if (getDarwinToolChain().isTargetIPhoneOS()) {
+ if (getDarwinToolChain().isTargetIOSSimulator()) {
+ // The simulator doesn't have a versioned crt1 file.
+ CmdArgs.push_back("-lcrt1.o");
+ } else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-lcrt1.o");
else
@@ -3156,6 +3410,9 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
@@ -3206,12 +3463,10 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
-
const ToolChain::path_list Paths = getToolChain().getFilePaths();
for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
i != e; ++i)
CmdArgs.push_back(Args.MakeArgString(llvm::StringRef("-L") + *i));
-
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
Args.AddAllArgs(CmdArgs, options::OPT_s);
@@ -3323,8 +3578,8 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(II.getFilename());
}
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(),
+ "as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -3336,6 +3591,9 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
@@ -3434,8 +3692,8 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
"crtn.o")));
}
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(),
+ "ld"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -3487,14 +3745,14 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Silence warning for "clang -g foo.o -o foo"
Args.ClaimAllArgs(options::OPT_g_Group);
+ // and "clang -emit-llvm foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
// and for "clang -g foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);
- if (Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) {
- CmdArgs.push_back("--sysroot");
- CmdArgs.push_back(A->getValue(Args));
- }
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
if (Args.hasArg(options::OPT_pie))
CmdArgs.push_back("-pie");
@@ -3517,13 +3775,19 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-m");
if (ToolChain.getArch() == llvm::Triple::x86)
CmdArgs.push_back("elf_i386");
- else if (ToolChain.getArch() == llvm::Triple::arm)
+ else if (ToolChain.getArch() == llvm::Triple::arm
+ || ToolChain.getArch() == llvm::Triple::thumb)
CmdArgs.push_back("armelf_linux_eabi");
+ else if (ToolChain.getArch() == llvm::Triple::ppc)
+ CmdArgs.push_back("elf32ppclinux");
+ else if (ToolChain.getArch() == llvm::Triple::ppc64)
+ CmdArgs.push_back("elf64ppc");
else
CmdArgs.push_back("elf_x86_64");
if (Args.hasArg(options::OPT_static)) {
- if (ToolChain.getArch() == llvm::Triple::arm)
+ if (ToolChain.getArch() == llvm::Triple::arm
+ || ToolChain.getArch() == llvm::Triple::thumb)
CmdArgs.push_back("-Bstatic");
else
CmdArgs.push_back("-static");
@@ -3532,13 +3796,19 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
if (ToolChain.getArch() == llvm::Triple::arm ||
+ ToolChain.getArch() == llvm::Triple::thumb ||
(!Args.hasArg(options::OPT_static) &&
!Args.hasArg(options::OPT_shared))) {
CmdArgs.push_back("-dynamic-linker");
if (ToolChain.getArch() == llvm::Triple::x86)
CmdArgs.push_back("/lib/ld-linux.so.2");
- else if (ToolChain.getArch() == llvm::Triple::arm)
+ else if (ToolChain.getArch() == llvm::Triple::arm ||
+ ToolChain.getArch() == llvm::Triple::thumb)
CmdArgs.push_back("/lib/ld-linux.so.3");
+ else if (ToolChain.getArch() == llvm::Triple::ppc)
+ CmdArgs.push_back("/lib/ld.so.1");
+ else if (ToolChain.getArch() == llvm::Triple::ppc64)
+ CmdArgs.push_back("/lib64/ld64.so.1");
else
CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
}
@@ -3573,6 +3843,7 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
const ToolChain::path_list Paths = ToolChain.getFilePaths();
+
for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
i != e; ++i)
CmdArgs.push_back(Args.MakeArgString(llvm::StringRef("-L") + *i));
@@ -3770,6 +4041,9 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h
index 10c8839..93abf75 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.h
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h
@@ -34,7 +34,8 @@ namespace tools {
const InputInfo &Output,
const InputInfoList &Inputs) const;
- void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+ void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ bool KernelOrKext) const;
void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
OpenPOWER on IntegriCloud