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/ArgList.cpp62
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/CC1Options.cpp38
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Compilation.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Driver.cpp189
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/OptTable.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp27
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp338
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.h109
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp987
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.h38
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Types.cpp4
11 files changed, 1217 insertions, 579 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
index 55a0ddf..7fd439e 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
@@ -140,6 +140,68 @@ Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
return Res;
}
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2, OptSpecifier Id3,
+ OptSpecifier Id4, OptSpecifier Id5) const {
+ Arg *Res = 0;
+ for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
+ if ((*it)->getOption().matches(Id0) ||
+ (*it)->getOption().matches(Id1) ||
+ (*it)->getOption().matches(Id2) ||
+ (*it)->getOption().matches(Id3) ||
+ (*it)->getOption().matches(Id4) ||
+ (*it)->getOption().matches(Id5)) {
+ Res = *it;
+ Res->claim();
+ }
+ }
+
+ return Res;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2, OptSpecifier Id3,
+ OptSpecifier Id4, OptSpecifier Id5,
+ OptSpecifier Id6) const {
+ Arg *Res = 0;
+ for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
+ if ((*it)->getOption().matches(Id0) ||
+ (*it)->getOption().matches(Id1) ||
+ (*it)->getOption().matches(Id2) ||
+ (*it)->getOption().matches(Id3) ||
+ (*it)->getOption().matches(Id4) ||
+ (*it)->getOption().matches(Id5) ||
+ (*it)->getOption().matches(Id6)) {
+ Res = *it;
+ Res->claim();
+ }
+ }
+
+ return Res;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2, OptSpecifier Id3,
+ OptSpecifier Id4, OptSpecifier Id5,
+ OptSpecifier Id6, OptSpecifier Id7) const {
+ Arg *Res = 0;
+ for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
+ if ((*it)->getOption().matches(Id0) ||
+ (*it)->getOption().matches(Id1) ||
+ (*it)->getOption().matches(Id2) ||
+ (*it)->getOption().matches(Id3) ||
+ (*it)->getOption().matches(Id4) ||
+ (*it)->getOption().matches(Id5) ||
+ (*it)->getOption().matches(Id6) ||
+ (*it)->getOption().matches(Id7)) {
+ Res = *it;
+ Res->claim();
+ }
+ }
+
+ return Res;
+}
+
bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
diff --git a/contrib/llvm/tools/clang/lib/Driver/CC1Options.cpp b/contrib/llvm/tools/clang/lib/Driver/CC1Options.cpp
deleted file mode 100644
index 884b363..0000000
--- a/contrib/llvm/tools/clang/lib/Driver/CC1Options.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//===--- CC1Options.cpp - Clang CC1 Options Table -------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/CC1Options.h"
-#include "clang/Driver/Option.h"
-#include "clang/Driver/OptTable.h"
-using namespace clang;
-using namespace clang::driver;
-using namespace clang::driver::options;
-using namespace clang::driver::cc1options;
-
-static const OptTable::Info CC1InfoTable[] = {
-#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { NAME, HELPTEXT, METAVAR, Option::KIND##Class, PARAM, FLAGS, \
- OPT_##GROUP, OPT_##ALIAS },
-#include "clang/Driver/CC1Options.inc"
-};
-
-namespace {
-
-class CC1OptTable : public OptTable {
-public:
- CC1OptTable()
- : OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
-};
-
-}
-
-OptTable *clang::driver::createCC1OptTable() {
- return new CC1OptTable();
-}
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
index 5553fc9..c962fca 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
@@ -219,7 +219,7 @@ void Compilation::initCompilationForDiagnostics(void) {
// to avoid emitting warnings about unused args.
OptSpecifier OutputOpts[] = { options::OPT_o, options::OPT_MD,
options::OPT_MMD };
- for (unsigned i = 0; i != sizeof(OutputOpts)/sizeof(OutputOpts[0]); ++i) {
+ for (unsigned i = 0, e = llvm::array_lengthof(OutputOpts); i != e; ++i) {
if (TranslatedArgs->hasArg(OutputOpts[i]))
TranslatedArgs->eraseArg(OutputOpts[i]);
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
index bb78a41..57b3417 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
@@ -59,7 +59,7 @@ Driver::Driver(StringRef ClangExecutable,
CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
CCCUseClang(true), CCCUseClangCXX(true), CCCUseClangCPP(true),
- CCCUsePCH(true), SuppressMissingInputWarning(false) {
+ ForcedClangUse(false), CCCUsePCH(true), SuppressMissingInputWarning(false) {
if (IsProduction) {
// In a "production" build, only use clang on architectures we expect to
// work.
@@ -115,9 +115,10 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgList) {
}
// Warn about -mcpu= without an argument.
- if (A->getOption().matches(options::OPT_mcpu_EQ) &&
+ if (A->getOption().matches(options::OPT_mcpu_EQ) &&
A->containsValue("")) {
- Diag(clang::diag::warn_drv_empty_joined_argument) << A->getAsString(*Args);
+ Diag(clang::diag::warn_drv_empty_joined_argument) <<
+ A->getAsString(*Args);
}
}
@@ -253,7 +254,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
if (char *env = ::getenv("COMPILER_PATH")) {
StringRef CompilerPath = env;
while (!CompilerPath.empty()) {
- std::pair<StringRef, StringRef> Split = CompilerPath.split(':');
+ std::pair<StringRef, StringRef> Split = CompilerPath.split(':');
PrefixDirs.push_back(Split.first);
CompilerPath = Split.second;
}
@@ -376,24 +377,33 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
void Driver::generateCompilationDiagnostics(Compilation &C,
const Command *FailingCommand) {
if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
- return;
+ return;
// Don't try to generate diagnostics for link jobs.
- if (FailingCommand->getCreator().isLinkJob())
+ if (FailingCommand && FailingCommand->getCreator().isLinkJob())
return;
+ // Print the version of the compiler.
+ PrintVersion(C, llvm::errs());
+
Diag(clang::diag::note_drv_command_failed_diag_msg)
- << "Please submit a bug report to " BUG_REPORT_URL " and include command"
- " line arguments and all diagnostic information.";
+ << "PLEASE submit a bug report to " BUG_REPORT_URL " and include the "
+ "crash backtrace, preprocessed source, and associated run script.";
// Suppress driver output and emit preprocessor output to temp file.
CCCIsCPP = true;
CCGenDiagnostics = true;
+ C.getArgs().AddFlagArg(0, Opts->getOption(options::OPT_frewrite_includes));
// Save the original job command(s).
std::string Cmd;
llvm::raw_string_ostream OS(Cmd);
- C.PrintJob(OS, C.getJobs(), "\n", false);
+ if (FailingCommand)
+ C.PrintJob(OS, *FailingCommand, "\n", false);
+ else
+ // Crash triggered by FORCE_CLANG_DIAGNOSTICS_CRASH, which doesn't have an
+ // associated FailingCommand, so just pass all jobs.
+ C.PrintJob(OS, C.getJobs(), "\n", false);
OS.flush();
// Clear stale state and suppress tool output.
@@ -473,7 +483,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
// If the command succeeded, we are done.
if (Res == 0) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
- << "Preprocessed source(s) and associated run script(s) are located at:";
+ << "\n********************\n\n"
+ "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
+ "Preprocessed source(s) and associated run script(s) are located at:";
ArgStringList Files = C.getTempFiles();
for (ArgStringList::const_iterator it = Files.begin(), ie = Files.end();
it != ie; ++it) {
@@ -489,10 +501,76 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating run script: " + Script + " " + Err;
} else {
+ // Strip away options not necessary to reproduce the crash.
+ // FIXME: This doesn't work with quotes (e.g., -D "foo bar").
+ SmallVector<std::string, 16> Flag;
+ Flag.push_back("-D ");
+ Flag.push_back("-F");
+ Flag.push_back("-I ");
+ Flag.push_back("-M ");
+ Flag.push_back("-MD ");
+ Flag.push_back("-MF ");
+ Flag.push_back("-MG ");
+ Flag.push_back("-MM ");
+ Flag.push_back("-MMD ");
+ Flag.push_back("-MP ");
+ Flag.push_back("-MQ ");
+ Flag.push_back("-MT ");
+ Flag.push_back("-o ");
+ Flag.push_back("-coverage-file ");
+ Flag.push_back("-dependency-file ");
+ Flag.push_back("-fdebug-compilation-dir ");
+ Flag.push_back("-fmodule-cache-path ");
+ Flag.push_back("-idirafter ");
+ Flag.push_back("-include ");
+ Flag.push_back("-include-pch ");
+ Flag.push_back("-internal-isystem ");
+ Flag.push_back("-internal-externc-isystem ");
+ Flag.push_back("-iprefix ");
+ Flag.push_back("-iwithprefix ");
+ Flag.push_back("-iwithprefixbefore ");
+ Flag.push_back("-isysroot ");
+ Flag.push_back("-isystem ");
+ Flag.push_back("-iquote ");
+ Flag.push_back("-resource-dir ");
+ Flag.push_back("-serialize-diagnostic-file ");
+ for (unsigned i = 0, e = Flag.size(); i < e; ++i) {
+ size_t I = 0, E = 0;
+ do {
+ I = Cmd.find(Flag[i], I);
+ if (I == std::string::npos) break;
+
+ E = Cmd.find(" ", I + Flag[i].length());
+ if (E == std::string::npos) break;
+ // The -D option is not removed. Instead, the argument is quoted.
+ if (Flag[i] != "-D ") {
+ Cmd.erase(I, E - I + 1);
+ } else {
+ Cmd.insert(I+3, "\"");
+ Cmd.insert(++E, "\"");
+ I = E;
+ }
+ } while(1);
+ }
+ // Append the new filename with correct preprocessed suffix.
+ size_t I, E;
+ I = Cmd.find("-main-file-name ");
+ assert (I != std::string::npos && "Expected to find -main-file-name");
+ I += 16;
+ E = Cmd.find(" ", I);
+ assert (E != std::string::npos && "-main-file-name missing argument?");
+ StringRef OldFilename = StringRef(Cmd).slice(I, E);
+ StringRef NewFilename = llvm::sys::path::filename(*it);
+ I = StringRef(Cmd).rfind(OldFilename);
+ E = I + OldFilename.size();
+ I = Cmd.rfind(" ", I) + 1;
+ Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size());
ScriptOS << Cmd;
Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
}
}
+ Diag(clang::diag::note_drv_command_failed_diag_msg)
+ << "\n\n********************";
} else {
// Failure, remove preprocessed files.
if (!C.getArgs().hasArg(options::OPT_save_temps))
@@ -529,14 +607,8 @@ int Driver::ExecuteCompilation(const Compilation &C,
C.CleanupFileList(C.getResultFiles(), true);
// Failure result files are valid unless we crashed.
- if (Res < 0) {
+ if (Res < 0)
C.CleanupFileList(C.getFailureResultFiles(), true);
-#ifdef _WIN32
- // Exit status should not be negative on Win32,
- // unless abnormal termination.
- Res = 1;
-#endif
- }
}
// Print extra information about abnormal failures, if possible.
@@ -630,7 +702,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
return false;
}
- if (C.getArgs().hasArg(options::OPT__help) ||
+ if (C.getArgs().hasArg(options::OPT_help) ||
C.getArgs().hasArg(options::OPT__help_hidden)) {
PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden));
return false;
@@ -748,8 +820,7 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
if (InputAction *IA = dyn_cast<InputAction>(A)) {
os << "\"" << IA->getInputArg().getValue(C.getArgs()) << "\"";
} else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
- os << '"' << (BIA->getArchName() ? BIA->getArchName() :
- C.getDefaultToolChain().getArchName()) << '"'
+ os << '"' << BIA->getArchName() << '"'
<< ", {" << PrintActions1(C, *BIA->begin(), Ids) << "}";
} else {
os << "{";
@@ -823,7 +894,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
// When there is no explicit arch for this platform, make sure we still bind
// the architecture (to the default) so that -Xarch_ is handled correctly.
if (!Archs.size())
- Archs.push_back(0);
+ Archs.push_back(Args.MakeArgString(TC.getArchName()));
// FIXME: We killed off some others but these aren't yet detected in a
// functional manner. If we added information to jobs about which "auxiliary"
@@ -873,7 +944,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
if (A && !A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_gstabs) &&
ContainsCompileOrAssembleAction(Actions.back())) {
-
+
// Add a 'dsymutil' step if necessary, when debug info is enabled and we
// have a compile input. We need to run 'dsymutil' ourselves in such cases
// because the debug info will refer to a temporary object file which is
@@ -1060,18 +1131,27 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
if (Args.hasArg(options::OPT_Qunused_arguments))
continue;
+ // Special case when final phase determined by binary name, rather than
+ // by a command-line argument with a corresponding Arg.
+ if (CCCIsCPP)
+ Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
+ << InputArg->getAsString(Args)
+ << getPhaseName(InitialPhase);
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
- if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess &&
- getPreprocessedType(InputType) == types::TY_INVALID)
+ else if (InitialPhase == phases::Compile &&
+ FinalPhase == phases::Preprocess &&
+ getPreprocessedType(InputType) == types::TY_INVALID)
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
<< InputArg->getAsString(Args)
- << FinalPhaseArg->getOption().getName();
+ << !!FinalPhaseArg
+ << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
else
Diag(clang::diag::warn_drv_input_file_unused)
<< InputArg->getAsString(Args)
<< getPhaseName(InitialPhase)
- << FinalPhaseArg->getOption().getName();
+ << !!FinalPhaseArg
+ << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
continue;
}
@@ -1130,14 +1210,23 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
if (Args.hasArg(options::OPT_M, options::OPT_MM)) {
OutputTy = types::TY_Dependencies;
} else {
- OutputTy = types::getPreprocessedType(Input->getType());
+ OutputTy = Input->getType();
+ if (!Args.hasFlag(options::OPT_frewrite_includes,
+ options::OPT_fno_rewrite_includes, false))
+ OutputTy = types::getPreprocessedType(OutputTy);
assert(OutputTy != types::TY_INVALID &&
"Cannot preprocess this input type!");
}
return new PreprocessJobAction(Input, OutputTy);
}
- case phases::Precompile:
- return new PrecompileJobAction(Input, types::TY_PCH);
+ case phases::Precompile: {
+ types::ID OutputTy = types::TY_PCH;
+ if (Args.hasArg(options::OPT_fsyntax_only)) {
+ // Syntax checks should not emit a PCH file
+ OutputTy = types::TY_Nothing;
+ }
+ return new PrecompileJobAction(Input, OutputTy);
+ }
case phases::Compile: {
if (Args.hasArg(options::OPT_fsyntax_only)) {
return new CompileJobAction(Input, types::TY_Nothing);
@@ -1332,10 +1421,13 @@ void Driver::BuildJobsForAction(Compilation &C,
}
if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
- const ToolChain *TC = &C.getDefaultToolChain();
+ const ToolChain *TC;
+ const char *ArchName = BAA->getArchName();
- if (BAA->getArchName())
- TC = &getToolChain(C.getArgs(), BAA->getArchName());
+ if (ArchName)
+ TC = &getToolChain(C.getArgs(), ArchName);
+ else
+ TC = &C.getDefaultToolChain();
BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(),
AtTopLevel, LinkingOutput, Result);
@@ -1453,15 +1545,24 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
}
- // If we're saving temps and the temp filename conflicts with the input
- // filename, then avoid overwriting input file.
+ // If we're saving temps and the temp file conflicts with the input file,
+ // then avoid overwriting input file.
if (!AtTopLevel && C.getArgs().hasArg(options::OPT_save_temps) &&
NamedOutput == BaseName) {
- StringRef Name = llvm::sys::path::filename(BaseInput);
- std::pair<StringRef, StringRef> Split = Name.split('.');
- std::string TmpName =
- GetTemporaryPath(Split.first, types::getTypeTempSuffix(JA.getType()));
- return C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str()));
+
+ bool SameFile = false;
+ SmallString<256> Result;
+ llvm::sys::fs::current_path(Result);
+ llvm::sys::path::append(Result, BaseName);
+ llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile);
+ // Must share the same path to conflict.
+ if (SameFile) {
+ StringRef Name = llvm::sys::path::filename(BaseInput);
+ std::pair<StringRef, StringRef> Split = Name.split('.');
+ std::string TmpName =
+ GetTemporaryPath(Split.first, types::getTypeTempSuffix(JA.getType()));
+ return C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str()));
+ }
}
// As an annoying special case, PCH generation doesn't strip the pathname.
@@ -1564,7 +1665,7 @@ std::string Driver::GetProgramPath(const char *Name, const ToolChain &TC,
return Name;
}
-std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
+std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
const {
// FIXME: This is lame; sys::Path should provide this function (in particular,
// it should know how to find the temporary files dir).
@@ -1579,14 +1680,15 @@ std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
llvm::sys::Path P(TmpDir);
P.appendComponent(Prefix);
if (P.makeUnique(false, &Error)) {
- Diag(clang::diag::err_drv_unable_to_make_temp) << Error;
+ Diag(clang::diag::err_unable_to_make_temp) << Error;
return "";
}
// FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837.
P.eraseFromDisk(false, 0);
- P.appendSuffix(Suffix);
+ if (Suffix)
+ P.appendSuffix(Suffix);
return P.str();
}
@@ -1674,6 +1776,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::OpenBSD:
TC = new toolchains::OpenBSD(*this, Target, Args);
break;
+ case llvm::Triple::Bitrig:
+ TC = new toolchains::Bitrig(*this, Target, Args);
+ break;
case llvm::Triple::NetBSD:
TC = new toolchains::NetBSD(*this, Target, Args);
break;
diff --git a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
index 4f5390b..a3e38b2 100644
--- a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
@@ -181,6 +181,8 @@ Option *OptTable::CreateOption(unsigned id) const {
}
if (info.Flags & Unsupported)
Opt->setUnsupported(true);
+ if (info.Flags & CC1Option)
+ Opt->setIsCC1Option(true);
return Opt;
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
index db4d2a8..48ed044 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
@@ -14,10 +14,10 @@
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/ObjCRuntime.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
+#include "clang/Basic/ObjCRuntime.h"
using namespace clang::driver;
using namespace clang;
@@ -49,25 +49,9 @@ bool ToolChain::HasNativeLLVMSupport() const {
return false;
}
-void ToolChain::configureObjCRuntime(ObjCRuntime &runtime) const {
- switch (runtime.getKind()) {
- case ObjCRuntime::NeXT:
- // Assume a minimal NeXT runtime.
- runtime.HasARC = false;
- runtime.HasWeak = false;
- runtime.HasSubscripting = false;
- runtime.HasTerminate = false;
- return;
-
- case ObjCRuntime::GNU:
- // Assume a maximal GNU runtime.
- runtime.HasARC = true;
- runtime.HasWeak = true;
- runtime.HasSubscripting = false; // to be added
- runtime.HasTerminate = false; // to be added
- return;
- }
- llvm_unreachable("invalid runtime kind!");
+ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
+ return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
+ VersionTuple());
}
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
@@ -189,6 +173,9 @@ void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// Each toolchain should provide the appropriate include flags.
}
+void ToolChain::addClangTargetOptions(ArgStringList &CC1Args) const {
+}
+
ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
const ArgList &Args) const
{
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index 7f9ed9a..01c6623 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -14,10 +14,10 @@
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/ObjCRuntime.h"
#include "clang/Driver/OptTable.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
#include "llvm/ADT/SmallString.h"
@@ -42,9 +42,7 @@ using namespace clang;
/// Darwin - Darwin tool chain for i386 and x86_64.
Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple), TargetInitialized(false),
- ARCRuntimeForSimulator(ARCSimulator_None),
- LibCXXForSimulator(LibCXXSimulator_None)
+ : ToolChain(D, Triple), TargetInitialized(false)
{
// Compute the initial Darwin version from the triple
unsigned Major, Minor, Micro;
@@ -59,6 +57,11 @@ Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
DarwinVersion[0] = Minor + 4;
DarwinVersion[1] = Micro;
DarwinVersion[2] = 0;
+
+ // Compute the initial iOS version from the triple
+ Triple.getiOSVersion(Major, Minor, Micro);
+ llvm::raw_string_ostream(iOSVersionMin)
+ << Major << '.' << Minor << '.' << Micro;
}
types::ID Darwin::LookupTypeForExtension(const char *Ext) const {
@@ -75,42 +78,19 @@ bool Darwin::HasNativeLLVMSupport() const {
return true;
}
-bool Darwin::hasARCRuntime() const {
- // FIXME: Remove this once there is a proper way to detect an ARC runtime
- // for the simulator.
- switch (ARCRuntimeForSimulator) {
- case ARCSimulator_None:
- break;
- case ARCSimulator_HasARCRuntime:
- return true;
- case ARCSimulator_NoARCRuntime:
- return false;
- }
-
- if (isTargetIPhoneOS())
- return !isIPhoneOSVersionLT(5);
- else
- return !isMacosxVersionLT(10, 7);
-}
-
-bool Darwin::hasSubscriptingRuntime() const {
- return !isTargetIPhoneOS() && !isMacosxVersionLT(10, 8);
-}
-
/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
-void Darwin::configureObjCRuntime(ObjCRuntime &runtime) const {
- if (runtime.getKind() != ObjCRuntime::NeXT)
- return ToolChain::configureObjCRuntime(runtime);
-
- runtime.HasARC = runtime.HasWeak = hasARCRuntime();
- runtime.HasSubscripting = hasSubscriptingRuntime();
-
- // So far, objc_terminate is only available in iOS 5.
- // FIXME: do the simulator logic properly.
- if (!ARCRuntimeForSimulator && isTargetIPhoneOS())
- runtime.HasTerminate = !isIPhoneOSVersionLT(5);
- else
- runtime.HasTerminate = false;
+ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
+ if (isTargetIPhoneOS()) {
+ return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
+ } else if (TargetSimulatorVersionFromDefines != VersionTuple()) {
+ return ObjCRuntime(ObjCRuntime::iOS, TargetSimulatorVersionFromDefines);
+ } else {
+ if (isNonFragile) {
+ return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
+ } else {
+ return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
+ }
+ }
}
/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
@@ -194,21 +174,25 @@ void Generic_ELF::anchor() {}
Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key;
+ Action::ActionClass Key = JA.getKind();
+ bool useClang = false;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {
+ useClang = true;
// Fallback to llvm-gcc for i386 kext compiles, we don't support that ABI.
- if (Inputs.size() == 1 &&
+ if (!getDriver().shouldForceClangUse() &&
+ Inputs.size() == 1 &&
types::isCXX(Inputs[0]->getType()) &&
getTriple().isOSDarwin() &&
getTriple().getArch() == llvm::Triple::x86 &&
(C.getArgs().getLastArg(options::OPT_fapple_kext) ||
C.getArgs().getLastArg(options::OPT_mkernel)))
- Key = JA.getKind();
- else
- Key = Action::AnalyzeJobClass;
- } else
- Key = JA.getKind();
+ useClang = false;
+ }
+
+ // FIXME: This seems like a hacky way to choose clang frontend.
+ if (useClang)
+ Key = Action::AnalyzeJobClass;
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
@@ -287,76 +271,6 @@ void DarwinClang::AddGCCLibexecPath(unsigned darwinVersion) {
getProgramPaths().push_back(Path);
}
-void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- // The Clang toolchain uses explicit paths for internal libraries.
-
- // Unfortunately, we still might depend on a few of the libraries that are
- // only available in the gcc library directory (in particular
- // libstdc++.dylib). For now, hardcode the path to the known install location.
- // FIXME: This should get ripped out someday. However, when building on
- // 10.6 (darwin10), we're still relying on this to find libstdc++.dylib.
- llvm::sys::Path P(getDriver().Dir);
- P.eraseComponent(); // .../usr/bin -> ../usr
- P.appendComponent("llvm-gcc-4.2");
- P.appendComponent("lib");
- P.appendComponent("gcc");
- switch (getTriple().getArch()) {
- default:
- llvm_unreachable("Invalid Darwin arch!");
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- P.appendComponent("i686-apple-darwin10");
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- P.appendComponent("arm-apple-darwin10");
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- P.appendComponent("powerpc-apple-darwin10");
- break;
- }
- P.appendComponent("4.2.1");
-
- // Determine the arch specific GCC subdirectory.
- const char *ArchSpecificDir = 0;
- switch (getTriple().getArch()) {
- default:
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb: {
- std::string Triple = ComputeLLVMTriple(Args);
- StringRef TripleStr = Triple;
- if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5"))
- ArchSpecificDir = "v5";
- else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6"))
- ArchSpecificDir = "v6";
- else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7"))
- ArchSpecificDir = "v7";
- break;
- }
- case llvm::Triple::ppc64:
- ArchSpecificDir = "ppc64";
- break;
- case llvm::Triple::x86_64:
- ArchSpecificDir = "x86_64";
- break;
- }
-
- if (ArchSpecificDir) {
- P.appendComponent(ArchSpecificDir);
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
- P.eraseComponent();
- }
-
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
-}
-
void DarwinClang::AddLinkARCArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
@@ -374,7 +288,7 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
else if (isTargetIPhoneOS())
s += "iphoneos";
// FIXME: Remove this once we depend fully on -mios-simulator-version-min.
- else if (ARCRuntimeForSimulator != ARCSimulator_None)
+ else if (TargetSimulatorVersionFromDefines != VersionTuple())
s += "iphonesimulator";
else
s += "macosx";
@@ -545,11 +459,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
unsigned Major = 0, Minor = 0, Micro = 0;
if (GetVersionFromSimulatorDefine(define, Major, Minor, Micro) &&
Major < 10 && Minor < 100 && Micro < 100) {
- ARCRuntimeForSimulator = Major < 5 ? ARCSimulator_NoARCRuntime
- : ARCSimulator_HasARCRuntime;
- LibCXXForSimulator = Major < 5 ? LibCXXSimulator_NotAvailable
- : LibCXXSimulator_Available;
+ TargetSimulatorVersionFromDefines = VersionTuple(Major, Minor, Micro);
}
+ // When using the define to indicate the simulator, we force
+ // 10.6 macosx target.
+ const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+ OSXVersion = Args.MakeJoinedArg(0, O, "10.6");
+ Args.append(OSXVersion);
break;
}
}
@@ -593,9 +509,9 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// If no OSX or iOS target has been specified and we're compiling for armv7,
// go ahead as assume we're targeting iOS.
- if (OSXTarget.empty() && iOSTarget.empty())
- if (getDarwinArchName(Args) == "armv7")
- iOSTarget = "0.0";
+ if (OSXTarget.empty() && iOSTarget.empty() &&
+ getDarwinArchName(Args) == "armv7")
+ iOSTarget = iOSVersionMin;
// Handle conflicting deployment targets
//
@@ -956,27 +872,27 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
// Add an explicit version min argument for the deployment target. We do this
// after argument translation because -Xarch_ arguments may add a version min
// argument.
- AddDeploymentTarget(*DAL);
+ if (BoundArch)
+ AddDeploymentTarget(*DAL);
// Validate the C++ standard library choice.
CXXStdlibType Type = GetCXXStdlibType(*DAL);
if (Type == ToolChain::CST_Libcxx) {
- switch (LibCXXForSimulator) {
- case LibCXXSimulator_None:
- // Handle non-simulator cases.
- if (isTargetIPhoneOS()) {
- if (isIPhoneOSVersionLT(5, 0)) {
- getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
- << "iOS 5.0";
- }
- }
- break;
- case LibCXXSimulator_NotAvailable:
+ // Check whether the target provides libc++.
+ StringRef where;
+
+ // Complain about targetting iOS < 5.0 in any way.
+ if (TargetSimulatorVersionFromDefines != VersionTuple()) {
+ if (TargetSimulatorVersionFromDefines < VersionTuple(5, 0))
+ where = "iOS 5.0";
+ } else if (isTargetIPhoneOS()) {
+ if (isIPhoneOSVersionLT(5, 0))
+ where = "iOS 5.0";
+ }
+
+ if (where != StringRef()) {
getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
- << "iOS 5.0";
- break;
- case LibCXXSimulator_Available:
- break;
+ << where;
}
}
@@ -1187,6 +1103,9 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
"arm-linux-gnueabi",
"arm-linux-androideabi"
};
+ static const char *const ARMHFTriples[] = {
+ "arm-linux-gnueabihf",
+ };
static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
static const char *const X86_64Triples[] = {
@@ -1210,7 +1129,8 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
"i586-redhat-linux",
"i386-redhat-linux",
"i586-suse-linux",
- "i486-slackware-linux"
+ "i486-slackware-linux",
+ "i686-montavista-linux"
};
static const char *const MIPSLibDirs[] = { "/lib" };
@@ -1218,11 +1138,17 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
static const char *const MIPSELLibDirs[] = { "/lib" };
static const char *const MIPSELTriples[] = { "mipsel-linux-gnu" };
+ static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
+ static const char *const MIPS64Triples[] = { "mips64-linux-gnu" };
+ static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
+ static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu" };
+
static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
static const char *const PPCTriples[] = {
"powerpc-linux-gnu",
"powerpc-unknown-linux-gnu",
- "powerpc-suse-linux"
+ "powerpc-suse-linux",
+ "powerpc-montavista-linuxspe"
};
static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
static const char *const PPC64Triples[] = {
@@ -1236,8 +1162,13 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
case llvm::Triple::arm:
case llvm::Triple::thumb:
LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
- TripleAliases.append(
- ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+ TripleAliases.append(
+ ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
+ } else {
+ TripleAliases.append(
+ ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+ }
break;
case llvm::Triple::x86_64:
LibDirs.append(
@@ -1263,12 +1194,40 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
TripleAliases.append(
MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ MultiarchLibDirs.append(
+ MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ MultiarchTripleAliases.append(
+ MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
break;
case llvm::Triple::mipsel:
LibDirs.append(
MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
TripleAliases.append(
MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
+ MultiarchLibDirs.append(
+ MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ MultiarchTripleAliases.append(
+ MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
+ break;
+ case llvm::Triple::mips64:
+ LibDirs.append(
+ MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ TripleAliases.append(
+ MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
+ MultiarchLibDirs.append(
+ MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
+ MultiarchTripleAliases.append(
+ MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ break;
+ case llvm::Triple::mips64el:
+ LibDirs.append(
+ MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ TripleAliases.append(
+ MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
+ MultiarchLibDirs.append(
+ MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
+ MultiarchTripleAliases.append(
+ MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
break;
case llvm::Triple::ppc:
LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
@@ -1350,7 +1309,9 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
// crtbegin.o without the subdirectory.
StringRef MultiarchSuffix
= (TargetArch == llvm::Triple::x86_64 ||
- TargetArch == llvm::Triple::ppc64) ? "/64" : "/32";
+ TargetArch == llvm::Triple::ppc64 ||
+ TargetArch == llvm::Triple::mips64 ||
+ TargetArch == llvm::Triple::mips64el) ? "/64" : "/32";
if (llvm::sys::fs::exists(LI->path() + MultiarchSuffix + "/crtbegin.o")) {
GCCMultiarchSuffix = MultiarchSuffix.str();
} else {
@@ -1606,6 +1567,67 @@ Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,
return *T;
}
+/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
+
+Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+ : Generic_ELF(D, Triple, Args) {
+ getFilePaths().push_back(getDriver().Dir + "/../lib");
+ getFilePaths().push_back("/usr/lib");
+}
+
+Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
+ bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
+ options::OPT_no_integrated_as,
+ IsIntegratedAssemblerDefault());
+
+ Tool *&T = Tools[Key];
+ if (!T) {
+ switch (Key) {
+ case Action::AssembleJobClass: {
+ if (UseIntegratedAs)
+ T = new tools::ClangAs(*this);
+ else
+ T = new tools::bitrig::Assemble(*this);
+ break;
+ }
+ case Action::LinkJobClass:
+ T = new tools::bitrig::Link(*this); break;
+ default:
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
+ }
+ }
+
+ return *T;
+}
+
+void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+ DriverArgs.hasArg(options::OPT_nostdincxx))
+ return;
+
+ std::string Triple = getTriple().str();
+ if (Triple.substr(0, 5) == "amd64")
+ Triple.replace(0, 5, "x86_64");
+
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2");
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/backward");
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/" + Triple);
+
+}
+
+void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ CmdArgs.push_back("-lstdc++");
+}
+
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
@@ -1957,6 +1979,16 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
// common linux triples that don't quite match the Clang triple for both
// 32-bit and 64-bit targets. Multiarch fixes its install triples to these
// regardless of what the actual target triple is.
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+ if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+ return "arm-linux-gnueabihf";
+ } else {
+ if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
+ return "arm-linux-gnueabi";
+ }
+ return TargetTriple.str();
case llvm::Triple::x86:
if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
return "i386-linux-gnu";
@@ -2139,6 +2171,12 @@ Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,
return *T;
}
+void Linux::addClangTargetOptions(ArgStringList &CC1Args) const {
+ const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
+ if (V >= Generic_GCC::GCCVersion::Parse("4.7.0"))
+ CC1Args.push_back("-fuse-init-array");
+}
+
void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
const Driver &D = getDriver();
@@ -2197,6 +2235,9 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
const StringRef ARMMultiarchIncludeDirs[] = {
"/usr/include/arm-linux-gnueabi"
};
+ const StringRef ARMHFMultiarchIncludeDirs[] = {
+ "/usr/include/arm-linux-gnueabihf"
+ };
const StringRef MIPSMultiarchIncludeDirs[] = {
"/usr/include/mips-linux-gnu"
};
@@ -2215,7 +2256,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
} else if (getTriple().getArch() == llvm::Triple::x86) {
MultiarchIncludeDirs = X86MultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::arm) {
- MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+ if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::mips) {
MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::mipsel) {
@@ -2281,7 +2325,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
// equivalent to '/usr/include/c++/X.Y' in almost all cases.
StringRef LibDir = GCCInstallation.getParentLibPath();
StringRef InstallDir = GCCInstallation.getInstallPath();
- StringRef Version = GCCInstallation.getVersion();
+ StringRef Version = GCCInstallation.getVersion().Text;
if (!addLibStdCXXIncludePaths(LibDir + "/../include/c++/" + Version,
(GCCInstallation.getTriple().str() +
GCCInstallation.getMultiarchSuffix()),
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
index eaa6be1..95a11be 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
@@ -99,7 +99,7 @@ protected:
StringRef getParentLibPath() const { return GCCParentLibPath; }
/// \brief Get the detected GCC version string.
- StringRef getVersion() const { return Version.Text; }
+ const GCCVersion &getVersion() const { return Version; }
private:
static void CollectLibDirsAndTriples(
@@ -176,22 +176,6 @@ private:
// the argument translation business.
mutable bool TargetInitialized;
- // FIXME: Remove this once there is a proper way to detect an ARC runtime
- // for the simulator.
- public:
- mutable enum {
- ARCSimulator_None,
- ARCSimulator_HasARCRuntime,
- ARCSimulator_NoARCRuntime
- } ARCRuntimeForSimulator;
-
- mutable enum {
- LibCXXSimulator_None,
- LibCXXSimulator_NotAvailable,
- LibCXXSimulator_Available
- } LibCXXForSimulator;
-
-private:
/// Whether we are targeting iPhoneOS target.
mutable bool TargetIsIPhoneOS;
@@ -201,12 +185,19 @@ private:
/// The OS version we are targeting.
mutable VersionTuple TargetVersion;
+protected:
+ // FIXME: Remove this once there is a proper way to detect an ARC runtime
+ // for the simulator.
+ mutable VersionTuple TargetSimulatorVersionFromDefines;
+
+private:
/// The default macosx-version-min of this tool chain; empty until
/// initialized.
std::string MacosxVersionMin;
- bool hasARCRuntime() const;
- bool hasSubscriptingRuntime() const;
+ /// The default ios-version-min of this tool chain; empty until
+ /// initialized.
+ std::string iOSVersionMin;
private:
void AddDeploymentTarget(DerivedArgList &Args) const;
@@ -254,7 +245,7 @@ public:
bool isTargetMacOS() const {
return !isTargetIOSSimulator() &&
!isTargetIPhoneOS() &&
- ARCRuntimeForSimulator == ARCSimulator_None;
+ TargetSimulatorVersionFromDefines == VersionTuple();
}
bool isTargetInitialized() const { return TargetInitialized; }
@@ -279,14 +270,6 @@ public:
return TargetVersion < VersionTuple(V0, V1, V2);
}
- /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
- ///
- /// \param Args - The input argument list.
- /// \param CmdArgs [out] - The command argument list to append the paths
- /// (prefixed by -L) to.
- virtual void AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const = 0;
-
/// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library.
virtual void AddLinkARCArgs(const ArgList &Args,
ArgStringList &CmdArgs) const = 0;
@@ -304,7 +287,7 @@ public:
virtual bool HasNativeLLVMSupport() const;
- virtual void configureObjCRuntime(ObjCRuntime &runtime) const;
+ virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
virtual bool hasBlocksRuntime() const;
virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
@@ -333,7 +316,11 @@ public:
return ToolChain::IsStrictAliasingDefault();
#endif
}
-
+
+ virtual bool IsMathErrnoDefault() const {
+ return false;
+ }
+
virtual bool IsObjCDefaultSynthPropertiesDefault() const {
return true;
}
@@ -342,12 +329,7 @@ public:
// Non-fragile ABI is default for everything but i386.
return getTriple().getArch() != llvm::Triple::x86;
}
- virtual bool IsObjCLegacyDispatchDefault() const {
- // This is only used with the non-fragile ABI.
- // Legacy dispatch is used everywhere except on x86_64.
- return getTriple().getArch() != llvm::Triple::x86_64;
- }
virtual bool UseObjCMixedDispatch() const {
// This is only used with the non-fragile ABI and non-legacy dispatch.
@@ -392,9 +374,6 @@ public:
/// @name Darwin ToolChain Implementation
/// {
- virtual void AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const;
-
virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
@@ -459,33 +438,39 @@ class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
public:
OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+ virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual bool IsObjCLegacyDispatchDefault() const {
- llvm::Triple::ArchType Arch = getTriple().getArch();
- if (Arch == llvm::Triple::arm ||
- Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::x86_64)
- return false;
- return true;
- }
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
};
+class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
+public:
+ Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+
+ virtual bool IsMathErrnoDefault() const { return false; }
+ virtual bool IsObjCNonFragileABIDefault() const { return true; }
+ virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
+
+ virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
+ virtual void AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const;
+ virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
+ return 1;
+ }
+};
+
class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
public:
FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+ virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual bool IsObjCLegacyDispatchDefault() const {
- llvm::Triple::ArchType Arch = getTriple().getArch();
- if (Arch == llvm::Triple::arm ||
- Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::x86_64)
- return false;
- return true;
- }
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
@@ -495,15 +480,8 @@ class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
public:
NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+ virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual bool IsObjCLegacyDispatchDefault() const {
- llvm::Triple::ArchType Arch = getTriple().getArch();
- if (Arch == llvm::Triple::arm ||
- Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::x86_64)
- return false;
- return true;
- }
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
@@ -521,6 +499,8 @@ class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
public:
DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+ virtual bool IsMathErrnoDefault() const { return false; }
+
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
};
@@ -536,6 +516,7 @@ public:
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
+ virtual void addClangTargetOptions(ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
@@ -577,6 +558,10 @@ public:
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
+ virtual bool IsObjCDefaultSynthPropertiesDefault() const {
+ return true;
+ }
+
virtual bool IsIntegratedAssemblerDefault() const;
virtual bool IsUnwindTablesDefault() const;
virtual const char *GetDefaultRelocationModel() const;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index af7ac20..88c2eff 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -16,11 +16,11 @@
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Job.h"
-#include "clang/Driver/ObjCRuntime.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
+#include "clang/Basic/ObjCRuntime.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -174,8 +174,10 @@ static bool isObjCAutoRefCount(const ArgList &Args) {
/// \brief Determine whether we are linking the ObjC runtime.
static bool isObjCRuntimeLinked(const ArgList &Args) {
- if (isObjCAutoRefCount(Args))
+ if (isObjCAutoRefCount(Args)) {
+ Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
return true;
+ }
return Args.hasArg(options::OPT_fobjc_link_runtime);
}
@@ -422,16 +424,47 @@ void Clang::AddPreprocessingOptions(Compilation &C,
getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
}
+/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
+/// CPU.
+//
+// FIXME: This is redundant with -mcpu, why does LLVM use this.
+// FIXME: tblgen this, or kill it!
+static const char *getLLVMArchSuffixForARM(StringRef CPU) {
+ return llvm::StringSwitch<const char *>(CPU)
+ .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
+ .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
+ .Cases("arm920", "arm920t", "arm922t", "v4t")
+ .Cases("arm940t", "ep9312","v4t")
+ .Cases("arm10tdmi", "arm1020t", "v5")
+ .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e")
+ .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e")
+ .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e")
+ .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6")
+ .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6")
+ .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
+ .Cases("cortex-a8", "cortex-a9", "v7")
+ .Case("cortex-m3", "v7m")
+ .Case("cortex-m4", "v7m")
+ .Case("cortex-m0", "v6m")
+ .Default("");
+}
+
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
//
// FIXME: tblgen this.
-static const char *getARMTargetCPU(const ArgList &Args,
+static std::string getARMTargetCPU(const ArgList &Args,
const llvm::Triple &Triple) {
// FIXME: Warn on inconsistent use of -mcpu and -march.
// If we have -mcpu=, use that.
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
- return A->getValue(Args);
+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ StringRef MCPU = A->getValue(Args);
+ // Handle -mcpu=native.
+ if (MCPU == "native")
+ return llvm::sys::getHostCPUName();
+ else
+ return MCPU;
+ }
StringRef MArch;
if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
@@ -442,13 +475,25 @@ static const char *getARMTargetCPU(const ArgList &Args,
MArch = Triple.getArchName();
}
+ // Handle -march=native.
+ std::string NativeMArch;
+ if (MArch == "native") {
+ std::string CPU = llvm::sys::getHostCPUName();
+ if (CPU != "generic") {
+ // Translate the native cpu into the architecture. The switch below will
+ // then chose the minimum cpu for that arch.
+ NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU);
+ MArch = NativeMArch;
+ }
+ }
+
return llvm::StringSwitch<const char *>(MArch)
.Cases("armv2", "armv2a","arm2")
.Case("armv3", "arm6")
.Case("armv3m", "arm7m")
.Cases("armv4", "armv4t", "arm7tdmi")
.Cases("armv5", "armv5t", "arm10tdmi")
- .Cases("armv5e", "armv5te", "arm1026ejs")
+ .Cases("armv5e", "armv5te", "arm1022e")
.Case("armv5tej", "arm926ej-s")
.Cases("armv6", "armv6k", "arm1136jf-s")
.Case("armv6j", "arm1136j-s")
@@ -465,31 +510,6 @@ static const char *getARMTargetCPU(const ArgList &Args,
.Default("arm7tdmi");
}
-/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
-/// CPU.
-//
-// FIXME: This is redundant with -mcpu, why does LLVM use this.
-// FIXME: tblgen this, or kill it!
-static const char *getLLVMArchSuffixForARM(StringRef CPU) {
- return llvm::StringSwitch<const char *>(CPU)
- .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
- .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
- .Cases("arm920", "arm920t", "arm922t", "v4t")
- .Cases("arm940t", "ep9312","v4t")
- .Cases("arm10tdmi", "arm1020t", "v5")
- .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e")
- .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e")
- .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e")
- .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6")
- .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6")
- .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
- .Cases("cortex-a8", "cortex-a9", "v7")
- .Case("cortex-m3", "v7m")
- .Case("cortex-m4", "v7m")
- .Case("cortex-m0", "v6m")
- .Default("");
-}
-
// FIXME: Move to target hook.
static bool isSignedCharDefault(const llvm::Triple &Triple) {
switch (Triple.getArch()) {
@@ -601,25 +621,21 @@ static StringRef getARMFloatABI(const Driver &D,
// Darwin defaults to "softfp" for v6 and v7.
//
// FIXME: Factor out an ARM class so we can cache the arch somewhere.
- StringRef ArchName =
+ std::string ArchName =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
- if (ArchName.startswith("v6") || ArchName.startswith("v7"))
+ if (StringRef(ArchName).startswith("v6") ||
+ StringRef(ArchName).startswith("v7"))
FloatABI = "softfp";
else
FloatABI = "soft";
break;
}
- case llvm::Triple::Linux: {
- if (Triple.getEnvironment() == llvm::Triple::GNUEABI) {
- FloatABI = "softfp";
- break;
- }
- }
- // fall through
-
default:
switch(Triple.getEnvironment()) {
+ case llvm::Triple::GNUEABIHF:
+ FloatABI = "hard";
+ break;
case llvm::Triple::GNUEABI:
FloatABI = "softfp";
break;
@@ -628,9 +644,9 @@ static StringRef getARMFloatABI(const Driver &D,
FloatABI = "softfp";
break;
case llvm::Triple::ANDROIDEABI: {
- StringRef ArchName =
+ std::string ArchName =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
- if (ArchName.startswith("v7"))
+ if (StringRef(ArchName).startswith("v7"))
FloatABI = "softfp";
else
FloatABI = "soft";
@@ -666,6 +682,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
switch(Triple.getEnvironment()) {
case llvm::Triple::ANDROIDEABI:
case llvm::Triple::GNUEABI:
+ case llvm::Triple::GNUEABIHF:
ABIName = "aapcs-linux";
break;
case llvm::Triple::EABI:
@@ -680,7 +697,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
// Set the CPU based on -march= and -mcpu=.
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(getARMTargetCPU(Args, Triple));
+ CmdArgs.push_back(Args.MakeArgString(getARMTargetCPU(Args, Triple)));
// Determine floating point ABI from the options & target defaults.
StringRef FloatABI = getARMFloatABI(D, Args, Triple);
@@ -755,6 +772,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
if (A->getOption().matches(options::OPT_mno_global_merge))
CmdArgs.push_back("-mno-global-merge");
}
+
+ if (Args.hasArg(options::OPT_mno_implicit_float))
+ CmdArgs.push_back("-no-implicit-float");
}
// Get default architecture.
@@ -825,19 +845,9 @@ static void getMipsCPUAndABI(const ArgList &Args,
ABIName = getMipsABIFromArch(ArchName);
}
-void Clang::AddMIPSTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
- StringRef CPUName;
- StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
-
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(CPUName.data());
-
- CmdArgs.push_back("-target-abi");
- CmdArgs.push_back(ABIName.data());
-
+// 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;
@@ -851,8 +861,7 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
else {
FloatABI = A->getValue(Args);
if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") {
- D.Diag(diag::err_drv_invalid_mfloat_abi)
- << A->getAsString(Args);
+ D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
FloatABI = "hard";
}
}
@@ -866,6 +875,38 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
FloatABI = "hard";
}
+ return FloatABI;
+}
+
+static void AddTargetFeature(const ArgList &Args,
+ ArgStringList &CmdArgs,
+ OptSpecifier OnOpt,
+ OptSpecifier OffOpt,
+ StringRef FeatureName) {
+ if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
+ CmdArgs.push_back("-target-feature");
+ if (A->getOption().matches(OnOpt))
+ CmdArgs.push_back(Args.MakeArgString("+" + FeatureName));
+ else
+ CmdArgs.push_back(Args.MakeArgString("-" + FeatureName));
+ }
+}
+
+void Clang::AddMIPSTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const Driver &D = getToolChain().getDriver();
+ StringRef CPUName;
+ StringRef ABIName;
+ getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
+
+ CmdArgs.push_back("-target-cpu");
+ CmdArgs.push_back(CPUName.data());
+
+ CmdArgs.push_back("-target-abi");
+ CmdArgs.push_back(ABIName.data());
+
+ StringRef FloatABI = getMipsFloatABI(D, Args);
+
if (FloatABI == "soft") {
// Floating point operations and argument passing are soft.
CmdArgs.push_back("-msoft-float");
@@ -890,6 +931,82 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
CmdArgs.push_back("-mfloat-abi");
CmdArgs.push_back("hard");
}
+
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mips16, options::OPT_mno_mips16,
+ "mips16");
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mdsp, options::OPT_mno_dsp,
+ "dsp");
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mdspr2, options::OPT_mno_dspr2,
+ "dspr2");
+}
+
+/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
+static std::string getPPCTargetCPU(const ArgList &Args) {
+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ StringRef CPUName = A->getValue(Args);
+
+ if (CPUName == "native") {
+ std::string CPU = llvm::sys::getHostCPUName();
+ if (!CPU.empty() && CPU != "generic")
+ return CPU;
+ else
+ return "";
+ }
+
+ return llvm::StringSwitch<const char *>(CPUName)
+ .Case("common", "generic")
+ .Case("440", "440")
+ .Case("440fp", "440")
+ .Case("450", "450")
+ .Case("601", "601")
+ .Case("602", "602")
+ .Case("603", "603")
+ .Case("603e", "603e")
+ .Case("603ev", "603ev")
+ .Case("604", "604")
+ .Case("604e", "604e")
+ .Case("620", "620")
+ .Case("G3", "g3")
+ .Case("7400", "7400")
+ .Case("G4", "g4")
+ .Case("7450", "7450")
+ .Case("G4+", "g4+")
+ .Case("750", "750")
+ .Case("970", "970")
+ .Case("G5", "g5")
+ .Case("a2", "a2")
+ .Case("power6", "pwr6")
+ .Case("power7", "pwr7")
+ .Case("powerpc", "ppc")
+ .Case("powerpc64", "ppc64")
+ .Default("");
+ }
+
+ return "";
+}
+
+void Clang::AddPPCTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ std::string TargetCPUName = getPPCTargetCPU(Args);
+
+ // LLVM may default to generating code for the native CPU,
+ // but, like gcc, we default to a more generic option for
+ // each architecture. (except on Darwin)
+ llvm::Triple Triple = getToolChain().getTriple();
+ if (TargetCPUName.empty() && !Triple.isOSDarwin()) {
+ if (Triple.getArch() == llvm::Triple::ppc64)
+ TargetCPUName = "ppc64";
+ else
+ TargetCPUName = "ppc";
+ }
+
+ if (!TargetCPUName.empty()) {
+ CmdArgs.push_back("-target-cpu");
+ CmdArgs.push_back(Args.MakeArgString(TargetCPUName.c_str()));
+ }
}
void Clang::AddSparcTargetArgs(const ArgList &Args,
@@ -958,7 +1075,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
// FIXME: We should also incorporate the detected target features for use
// with -native.
std::string CPU = llvm::sys::getHostCPUName();
- if (!CPU.empty())
+ if (!CPU.empty() && CPU != "generic")
CPUName = Args.MakeArgString(CPU);
} else
CPUName = A->getValue(Args);
@@ -982,6 +1099,11 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
CPUName = "x86-64";
else if (getToolChain().getArch() == llvm::Triple::x86)
CPUName = "i486";
+ } else if (getToolChain().getOS().startswith("bitrig")) {
+ if (getToolChain().getArch() == llvm::Triple::x86_64)
+ CPUName = "x86-64";
+ else if (getToolChain().getArch() == llvm::Triple::x86)
+ CPUName = "i686";
} else if (getToolChain().getOS().startswith("freebsd")) {
if (getToolChain().getArch() == llvm::Triple::x86_64)
CPUName = "x86-64";
@@ -1088,7 +1210,7 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
CmdArgs.push_back("-fno-signed-char");
CmdArgs.push_back("-nobuiltininc");
- if (Args.hasArg(options::OPT_mqdsp6_compat))
+ if (Args.hasArg(options::OPT_mqdsp6_compat))
CmdArgs.push_back("-mqdsp6-compat");
if (Arg *A = Args.getLastArg(options::OPT_G,
@@ -1100,18 +1222,23 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
A->claim();
}
+ if (!Args.hasArg(options::OPT_fno_short_enums))
+ CmdArgs.push_back("-fshort-enums");
+ if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
+ CmdArgs.push_back ("-mllvm");
+ CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near");
+ }
CmdArgs.push_back ("-mllvm");
CmdArgs.push_back ("-machine-sink-split=0");
}
static bool
-shouldUseExceptionTablesForObjCExceptions(unsigned objcABIVersion,
+shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
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 (objcABIVersion >= 2)
+ if (runtime.isNonFragile())
return true;
if (!Triple.isOSDarwin())
@@ -1130,7 +1257,7 @@ shouldUseExceptionTablesForObjCExceptions(unsigned objcABIVersion,
static void addExceptionArgs(const ArgList &Args, types::ID InputType,
const llvm::Triple &Triple,
bool KernelOrKext,
- unsigned objcABIVersion,
+ const ObjCRuntime &objcRuntime,
ArgStringList &CmdArgs) {
if (KernelOrKext) {
// -mkernel and -fapple-kext imply no exceptions, so claim exception related
@@ -1176,7 +1303,7 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("-fobjc-exceptions");
ShouldUseExceptionTables |=
- shouldUseExceptionTablesForObjCExceptions(objcABIVersion, Triple);
+ shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
}
if (types::isCXX(InputType)) {
@@ -1269,22 +1396,56 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
/// This needs to be called before we add the C run-time (malloc, etc).
static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
- // Add asan linker flags when linking an executable, but not a shared object.
- if (Args.hasArg(options::OPT_shared) ||
- !Args.hasFlag(options::OPT_faddress_sanitizer,
+ if (!Args.hasFlag(options::OPT_faddress_sanitizer,
options::OPT_fno_address_sanitizer, false))
return;
+ if(TC.getTriple().getEnvironment() == llvm::Triple::ANDROIDEABI) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ if (!Args.hasArg(options::OPT_pie))
+ TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie);
+ // For an executable, we add a .preinit_array stub.
+ CmdArgs.push_back("-u");
+ CmdArgs.push_back("__asan_preinit");
+ CmdArgs.push_back("-lasan");
+ }
- // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library resource
- // directory.
- SmallString<128> LibAsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibAsan, "lib", "linux",
- (Twine("libclang_rt.asan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibAsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
+ CmdArgs.push_back("-lasan_preload");
+ CmdArgs.push_back("-ldl");
+ } else {
+ if (!Args.hasArg(options::OPT_shared)) {
+ // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
+ // resource directory.
+ SmallString<128> LibAsan(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(LibAsan, "lib", "linux",
+ (Twine("libclang_rt.asan-") +
+ TC.getArchName() + ".a"));
+ CmdArgs.push_back(Args.MakeArgString(LibAsan));
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-ldl");
+ CmdArgs.push_back("-export-dynamic");
+ }
+ }
+}
+
+/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
+/// This needs to be called before we add the C run-time (malloc, etc).
+static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (!Args.hasFlag(options::OPT_fthread_sanitizer,
+ options::OPT_fno_thread_sanitizer, false))
+ return;
+ if (!Args.hasArg(options::OPT_shared)) {
+ // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
+ // resource directory.
+ SmallString<128> LibTsan(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(LibTsan, "lib", "linux",
+ (Twine("libclang_rt.tsan-") +
+ TC.getArchName() + ".a"));
+ CmdArgs.push_back(Args.MakeArgString(LibTsan));
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-ldl");
+ CmdArgs.push_back("-export-dynamic");
+ }
}
static bool shouldUseFramePointer(const ArgList &Args,
@@ -1328,8 +1489,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(TripleStr));
// Select the appropriate action.
- bool IsRewriter = false;
- bool IsModernRewriter = false;
+ RewriteKind rewriteKind = RK_None;
if (isa<AnalyzeJobAction>(JA)) {
assert(JA.getType() == types::TY_Plist && "Invalid output type.");
@@ -1380,7 +1540,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Use PCH if the user requested it.
bool UsePCH = D.CCCUsePCH;
- if (UsePCH)
+ if (JA.getType() == types::TY_Nothing)
+ CmdArgs.push_back("-fsyntax-only");
+ else if (UsePCH)
CmdArgs.push_back("-emit-pch");
else
CmdArgs.push_back("-emit-pth");
@@ -1401,10 +1563,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-emit-pch");
} else if (JA.getType() == types::TY_RewrittenObjC) {
CmdArgs.push_back("-rewrite-objc");
- IsModernRewriter = true;
+ rewriteKind = RK_NonFragile;
} else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
CmdArgs.push_back("-rewrite-objc");
- IsRewriter = true;
+ rewriteKind = RK_Fragile;
} else {
assert(JA.getType() == types::TY_PP_Asm &&
"Unexpected output type!");
@@ -1488,22 +1650,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// This comes from the default translation the driver + cc1
// would do to enable flag_pic.
- //
- // FIXME: Centralize this code.
- Arg *LastPICArg = 0;
- for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
- if ((*I)->getOption().matches(options::OPT_fPIC) ||
- (*I)->getOption().matches(options::OPT_fno_PIC) ||
- (*I)->getOption().matches(options::OPT_fpic) ||
- (*I)->getOption().matches(options::OPT_fno_pic) ||
- (*I)->getOption().matches(options::OPT_fPIE) ||
- (*I)->getOption().matches(options::OPT_fno_PIE) ||
- (*I)->getOption().matches(options::OPT_fpie) ||
- (*I)->getOption().matches(options::OPT_fno_pie)) {
- LastPICArg = *I;
- (*I)->claim();
- }
- }
+
+ 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);
bool PICDisabled = false;
bool PICEnabled = false;
bool PICForPIE = false;
@@ -1606,16 +1757,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->getOption().getID() != options::OPT_fhonor_nans)
CmdArgs.push_back("-menable-no-nans");
- // -fno-math-errno is default.
- bool MathErrno = false;
+ // -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,
options::OPT_fmath_errno,
- options::OPT_fno_math_errno)) {
- if (A->getOption().getID() == options::OPT_fmath_errno) {
- CmdArgs.push_back("-fmath-errno");
- MathErrno = true;
- }
- }
+ options::OPT_fno_math_errno))
+ MathErrno = A->getOption().getID() == options::OPT_fmath_errno;
+ if (MathErrno)
+ CmdArgs.push_back("-fmath-errno");
// There are several flags which require disabling very specific
// optimizations. Any of these being disabled forces us to turn off the
@@ -1661,12 +1810,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
!TrappingMath)
CmdArgs.push_back("-menable-unsafe-fp-math");
- // We separately look for the '-ffast-math' flag, and if we find it, tell the
- // frontend to provide the appropriate preprocessor macros. This is distinct
- // from enabling any optimizations as it induces a language change which must
- // survive serialization and deserialization, etc.
+
+ // Validate and pass through -fp-contract option.
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_ffp_contract)) {
+ if (A->getOption().getID() == options::OPT_ffp_contract) {
+ StringRef Val = A->getValue(Args);
+ if (Val == "fast" || Val == "on" || Val == "off") {
+ CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
+ } else {
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << Val;
+ }
+ } else { // A is OPT_ffast_math
+ // If fast-math is set then set the fp-contract mode to fast.
+ CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
+ }
+ }
+
+ // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
+ // and if we find them, tell the frontend to provide the appropriate
+ // preprocessor macros. This is distinct from enabling any optimizations as
+ // these options induce language changes which must survive serialization
+ // and deserialization, etc.
if (Args.hasArg(options::OPT_ffast_math))
CmdArgs.push_back("-ffast-math");
+ if (Args.hasArg(options::OPT_ffinite_math_only))
+ CmdArgs.push_back("-ffinite-math-only");
// Decide whether to use verbose asm. Verbose assembly is the default on
// toolchains which have the integrated assembler on by default.
@@ -1711,6 +1881,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
AsynchronousUnwindTables))
CmdArgs.push_back("-munwind-tables");
+ getToolChain().addClangTargetOptions(CmdArgs);
+
if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("-mlimit-float-precision");
CmdArgs.push_back(A->getValue(Args));
@@ -1741,6 +1913,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
AddMIPSTargetArgs(Args, CmdArgs);
break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ AddPPCTargetArgs(Args, CmdArgs);
+ break;
+
case llvm::Triple::sparc:
AddSparcTargetArgs(Args, CmdArgs);
break;
@@ -1800,13 +1977,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
D.CCLogDiagnosticsFilename : "-");
}
- // Special case debug options to only pass -g to clang. This is
- // wrong.
+ // Use the last option from "-g" group. "-gline-tables-only" is
+ // preserved, all other debug options are substituted with "-g".
Args.ClaimAllArgs(options::OPT_g_Group);
- if (Arg *A = Args.getLastArg(options::OPT_g_Group))
- if (!A->getOption().matches(options::OPT_g0)) {
+ if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+ if (A->getOption().matches(options::OPT_gline_tables_only)) {
+ CmdArgs.push_back("-gline-tables-only");
+ } else if (!A->getOption().matches(options::OPT_g0) &&
+ !A->getOption().matches(options::OPT_ggdb0)) {
CmdArgs.push_back("-g");
}
+ }
+
+ // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
+ Args.ClaimAllArgs(options::OPT_g_flags_Group);
Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
@@ -1917,7 +2101,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
- Args.AddLastArg(CmdArgs, options::OPT_pedantic);
+ if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
+ CmdArgs.push_back("-pedantic");
Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
Args.AddLastArg(CmdArgs, options::OPT_w);
@@ -2007,11 +2192,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
options::OPT_Wlarge_by_value_copy_def)) {
- CmdArgs.push_back("-Wlarge-by-value-copy");
- if (A->getNumValues())
- CmdArgs.push_back(A->getValue(Args));
- else
- CmdArgs.push_back("64"); // default value for -Wlarge-by-value-copy.
+ if (A->getNumValues()) {
+ StringRef bytes = A->getValue(Args);
+ CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
+ } else
+ CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
+ }
+
+ if (Arg *A = Args.getLastArg(options::OPT_fbounds_checking,
+ options::OPT_fbounds_checking_EQ)) {
+ if (A->getNumValues()) {
+ StringRef val = A->getValue(Args);
+ CmdArgs.push_back(Args.MakeArgString("-fbounds-checking=" + val));
+ } else
+ CmdArgs.push_back("-fbounds-checking=1");
}
if (Args.hasArg(options::OPT__relocatable_pch))
@@ -2066,6 +2260,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
+ Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
+
// -fhosted is default.
if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
KernelOrKext)
@@ -2080,6 +2276,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
+ Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
+ Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
// Report and error for -faltivec on anything other then PowerPC.
if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
@@ -2107,6 +2305,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.getLastArg(options::OPT_fapple_kext))
CmdArgs.push_back("-fapple-kext");
+ if (Args.hasFlag(options::OPT_frewrite_includes,
+ options::OPT_fno_rewrite_includes, false))
+ CmdArgs.push_back("-frewrite-includes");
+
Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
@@ -2260,6 +2462,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().getTriple().getOS() == llvm::Triple::Win32))
CmdArgs.push_back("-fms-extensions");
+ // -fms-inline-asm.
+ if (Args.hasArg(options::OPT_fenable_experimental_ms_inline_asm))
+ CmdArgs.push_back("-fenable-experimental-ms-inline-asm");
+
// -fms-compatibility=0 is default.
if (Args.hasFlag(options::OPT_fms_compatibility,
options::OPT_fno_ms_compatibility,
@@ -2310,83 +2516,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fno_inline_functions))
CmdArgs.push_back("-fno-inline-functions");
- // -fobjc-nonfragile-abi=0 is default.
- ObjCRuntime objCRuntime;
- unsigned objcABIVersion = 0;
- bool NeXTRuntimeIsDefault
- = (IsRewriter || IsModernRewriter ||
- getToolChain().getTriple().isOSDarwin());
- if (Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
- NeXTRuntimeIsDefault)) {
- objCRuntime.setKind(ObjCRuntime::NeXT);
- } else {
- CmdArgs.push_back("-fgnu-runtime");
- objCRuntime.setKind(ObjCRuntime::GNU);
- }
- getToolChain().configureObjCRuntime(objCRuntime);
- if (objCRuntime.HasARC)
- CmdArgs.push_back("-fobjc-runtime-has-arc");
- if (objCRuntime.HasWeak)
- CmdArgs.push_back("-fobjc-runtime-has-weak");
- if (objCRuntime.HasTerminate)
- CmdArgs.push_back("-fobjc-runtime-has-terminate");
-
- // Compute the Objective-C ABI "version" to use. Version numbers are
- // slightly confusing for historical reasons:
- // 1 - Traditional "fragile" ABI
- // 2 - Non-fragile ABI, version 1
- // 3 - Non-fragile ABI, version 2
- objcABIVersion = 1;
- // If -fobjc-abi-version= is present, use that to set the version.
- if (Arg *A = Args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
- if (StringRef(A->getValue(Args)) == "1")
- objcABIVersion = 1;
- else if (StringRef(A->getValue(Args)) == "2")
- objcABIVersion = 2;
- else if (StringRef(A->getValue(Args)) == "3")
- objcABIVersion = 3;
- else
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
- } else {
- // Otherwise, determine if we are using the non-fragile ABI.
- bool NonFragileABIIsDefault =
- (IsModernRewriter ||
- (!IsRewriter && getToolChain().IsObjCNonFragileABIDefault()));
- if (Args.hasFlag(options::OPT_fobjc_nonfragile_abi,
- options::OPT_fno_objc_nonfragile_abi,
- NonFragileABIIsDefault)) {
- // Determine the non-fragile ABI version to use.
-#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
- unsigned NonFragileABIVersion = 1;
-#else
- unsigned NonFragileABIVersion = 2;
-#endif
-
- if (Arg *A = Args.getLastArg(
- options::OPT_fobjc_nonfragile_abi_version_EQ)) {
- if (StringRef(A->getValue(Args)) == "1")
- NonFragileABIVersion = 1;
- else if (StringRef(A->getValue(Args)) == "2")
- NonFragileABIVersion = 2;
- else
- D.Diag(diag::err_drv_clang_unsupported)
- << A->getAsString(Args);
- }
+ ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
- objcABIVersion = 1 + NonFragileABIVersion;
- } else {
- objcABIVersion = 1;
- }
- }
-
- if (objcABIVersion == 1) {
- CmdArgs.push_back("-fobjc-fragile-abi");
- } else {
- // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
- // legacy is the default.
+ // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
+ // legacy is the default.
+ if (objcRuntime.isNonFragile()) {
if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
options::OPT_fno_objc_legacy_dispatch,
- getToolChain().IsObjCLegacyDispatchDefault())) {
+ objcRuntime.isLegacyDispatchDefaultForArch(
+ getToolChain().getTriple().getArch()))) {
if (getToolChain().UseObjCMixedDispatch())
CmdArgs.push_back("-fobjc-dispatch-method=mixed");
else
@@ -2429,7 +2567,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fobjc-infer-related-result-type is the default, except in the Objective-C
// rewriter.
- if (IsRewriter || IsModernRewriter)
+ if (rewriteKind != RK_None)
CmdArgs.push_back("-fno-objc-infer-related-result-type");
// Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
@@ -2452,7 +2590,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Add exception args.
addExceptionArgs(Args, InputType, getToolChain().getTriple(),
- KernelOrKext, objcABIVersion, CmdArgs);
+ KernelOrKext, objcRuntime, CmdArgs);
if (getToolChain().UseSjLjExceptions())
CmdArgs.push_back("-fsjlj-exceptions");
@@ -2491,12 +2629,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Honor -fpack-struct= and -fpack-struct, if given. Note that
// -fno-pack-struct doesn't apply to -fpack-struct=.
if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
- CmdArgs.push_back("-fpack-struct");
- CmdArgs.push_back(A->getValue(Args));
+ std::string PackStructStr = "-fpack-struct=";
+ PackStructStr += A->getValue(Args);
+ CmdArgs.push_back(Args.MakeArgString(PackStructStr));
} else if (Args.hasFlag(options::OPT_fpack_struct,
options::OPT_fno_pack_struct, false)) {
- CmdArgs.push_back("-fpack-struct");
- CmdArgs.push_back("1");
+ CmdArgs.push_back("-fpack-struct=1");
}
if (Args.hasArg(options::OPT_mkernel) ||
@@ -2730,7 +2868,7 @@ void ClangAs::AddARMTargetArgs(const ArgList &Args,
// Set the CPU based on -march= and -mcpu=.
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(getARMTargetCPU(Args, Triple));
+ CmdArgs.push_back(Args.MakeArgString(getARMTargetCPU(Args, Triple)));
// Honor -mfpu=.
if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
@@ -2741,6 +2879,131 @@ void ClangAs::AddARMTargetArgs(const ArgList &Args,
addFPMathArgs(D, A, Args, CmdArgs, getARMTargetCPU(Args, Triple));
}
+/// Add options related to the Objective-C runtime/ABI.
+///
+/// Returns true if the runtime is non-fragile.
+ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
+ ArgStringList &cmdArgs,
+ RewriteKind rewriteKind) const {
+ // Look for the controlling runtime option.
+ Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime,
+ options::OPT_fgnu_runtime,
+ options::OPT_fobjc_runtime_EQ);
+
+ // Just forward -fobjc-runtime= to the frontend. This supercedes
+ // options about fragility.
+ if (runtimeArg &&
+ runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
+ ObjCRuntime runtime;
+ StringRef value = runtimeArg->getValue(args);
+ if (runtime.tryParse(value)) {
+ getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
+ << value;
+ }
+
+ runtimeArg->render(args, cmdArgs);
+ return runtime;
+ }
+
+ // Otherwise, we'll need the ABI "version". Version numbers are
+ // slightly confusing for historical reasons:
+ // 1 - Traditional "fragile" ABI
+ // 2 - Non-fragile ABI, version 1
+ // 3 - Non-fragile ABI, version 2
+ unsigned objcABIVersion = 1;
+ // If -fobjc-abi-version= is present, use that to set the version.
+ if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
+ StringRef value = abiArg->getValue(args);
+ if (value == "1")
+ objcABIVersion = 1;
+ else if (value == "2")
+ objcABIVersion = 2;
+ else if (value == "3")
+ objcABIVersion = 3;
+ else
+ getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
+ << value;
+ } else {
+ // Otherwise, determine if we are using the non-fragile ABI.
+ bool nonFragileABIIsDefault =
+ (rewriteKind == RK_NonFragile ||
+ (rewriteKind == RK_None &&
+ getToolChain().IsObjCNonFragileABIDefault()));
+ if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
+ options::OPT_fno_objc_nonfragile_abi,
+ nonFragileABIIsDefault)) {
+ // Determine the non-fragile ABI version to use.
+#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
+ unsigned nonFragileABIVersion = 1;
+#else
+ unsigned nonFragileABIVersion = 2;
+#endif
+
+ if (Arg *abiArg = args.getLastArg(
+ options::OPT_fobjc_nonfragile_abi_version_EQ)) {
+ StringRef value = abiArg->getValue(args);
+ if (value == "1")
+ nonFragileABIVersion = 1;
+ else if (value == "2")
+ nonFragileABIVersion = 2;
+ else
+ getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
+ << value;
+ }
+
+ objcABIVersion = 1 + nonFragileABIVersion;
+ } else {
+ objcABIVersion = 1;
+ }
+ }
+
+ // We don't actually care about the ABI version other than whether
+ // it's non-fragile.
+ bool isNonFragile = objcABIVersion != 1;
+
+ // If we have no runtime argument, ask the toolchain for its default runtime.
+ // However, the rewriter only really supports the Mac runtime, so assume that.
+ ObjCRuntime runtime;
+ if (!runtimeArg) {
+ switch (rewriteKind) {
+ case RK_None:
+ runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
+ break;
+ case RK_Fragile:
+ runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
+ break;
+ case RK_NonFragile:
+ runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
+ break;
+ }
+
+ // -fnext-runtime
+ } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
+ // On Darwin, make this use the default behavior for the toolchain.
+ if (getToolChain().getTriple().isOSDarwin()) {
+ runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
+
+ // Otherwise, build for a generic macosx port.
+ } else {
+ runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
+ }
+
+ // -fgnu-runtime
+ } else {
+ assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
+ // Legacy behaviour is to target the gnustep runtime if we are i
+ // non-fragile mode or the GCC runtime in fragile mode.
+ if (isNonFragile)
+ runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple());
+ else
+ runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
+ }
+
+ cmdArgs.push_back(args.MakeArgString(
+ "-fobjc-runtime=" + runtime.getAsString()));
+ return runtime;
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4025,9 +4288,6 @@ void darwin::Link::AddLinkArgs(Compilation &C,
} else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
CmdArgs.push_back("-syslibroot");
CmdArgs.push_back(A->getValue(Args));
- } else if (getDarwinToolChain().isTargetIPhoneOS()) {
- CmdArgs.push_back("-syslibroot");
- CmdArgs.push_back("/Developer/SDKs/Extra");
}
Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
@@ -4086,7 +4346,6 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_t);
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_A);
Args.AddLastArg(CmdArgs, options::OPT_e);
Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
Args.AddAllArgs(CmdArgs, options::OPT_r);
@@ -4100,8 +4359,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- if (!Args.hasArg(options::OPT_A) &&
- !Args.hasArg(options::OPT_nostdlib) &&
+ if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
// Derived from startfile spec.
if (Args.hasArg(options::OPT_dynamiclib)) {
@@ -4145,6 +4403,14 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
// darwin_crt2 spec is empty.
}
+ // By default on OS X 10.8 and later, we don't link with a crt1.o
+ // file and the linker knows to use _main as the entry point. But,
+ // when compiling with -pg, we need to link with the gcrt1.o file,
+ // so pass the -no_new_main option to tell the linker to use the
+ // "start" symbol as the entry point.
+ if (getDarwinToolChain().isTargetMacOS() &&
+ !getDarwinToolChain().isMacosxVersionLT(10, 8))
+ CmdArgs.push_back("-no_new_main");
} else {
if (Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_object) ||
@@ -4202,30 +4468,30 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
// This is more complicated in gcc...
CmdArgs.push_back("-lgomp");
- getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
-
- if (isObjCRuntimeLinked(Args)) {
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+ if (isObjCRuntimeLinked(Args) &&
+ !Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
// Avoid linking compatibility stubs on i386 mac.
if (!getDarwinToolChain().isTargetMacOS() ||
getDarwinToolChain().getArchName() != "i386") {
// If we don't have ARC or subscripting runtime support, link in the
// runtime stubs. We have to do this *before* adding any of the normal
// linker inputs so that its initializer gets run first.
- ObjCRuntime runtime;
- getDarwinToolChain().configureObjCRuntime(runtime);
+ ObjCRuntime runtime =
+ getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
// We use arclite library for both ARC and subscripting support.
- if ((!runtime.HasARC && isObjCAutoRefCount(Args)) ||
- !runtime.HasSubscripting)
+ if ((!runtime.hasARC() && isObjCAutoRefCount(Args)) ||
+ !runtime.hasSubscripting())
getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
- CmdArgs.push_back("-framework");
- CmdArgs.push_back("Foundation");
}
+ CmdArgs.push_back("-framework");
+ CmdArgs.push_back("Foundation");
// Link libobj.
CmdArgs.push_back("-lobjc");
}
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
-
if (LinkingOutput) {
CmdArgs.push_back("-arch_multiple");
CmdArgs.push_back("-final_output");
@@ -4246,8 +4512,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
}
- if (!Args.hasArg(options::OPT_A) &&
- !Args.hasArg(options::OPT_nostdlib) &&
+ if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
// endfile_spec is empty.
}
@@ -4699,6 +4964,142 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
+void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ ArgStringList CmdArgs;
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+ CmdArgs.push_back(II.getFilename());
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const Driver &D = getToolChain().getDriver();
+ ArgStringList CmdArgs;
+
+ if ((!Args.hasArg(options::OPT_nostdlib)) &&
+ (!Args.hasArg(options::OPT_shared))) {
+ CmdArgs.push_back("-e");
+ CmdArgs.push_back("__start");
+ }
+
+ if (Args.hasArg(options::OPT_static)) {
+ CmdArgs.push_back("-Bstatic");
+ } else {
+ if (Args.hasArg(options::OPT_rdynamic))
+ CmdArgs.push_back("-export-dynamic");
+ CmdArgs.push_back("--eh-frame-hdr");
+ CmdArgs.push_back("-Bdynamic");
+ if (Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back("-shared");
+ } else {
+ CmdArgs.push_back("-dynamic-linker");
+ CmdArgs.push_back("/usr/libexec/ld.so");
+ }
+ }
+
+ if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ } else {
+ assert(Output.isNothing() && "Invalid output.");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ if (Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("gcrt0.o")));
+ else
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crt0.o")));
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtbegin.o")));
+ } else {
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtbeginS.o")));
+ }
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+ if (D.CCCIsCXX) {
+ getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+ if (Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back("-lm_p");
+ else
+ CmdArgs.push_back("-lm");
+ }
+
+ if (Args.hasArg(options::OPT_pthread))
+ CmdArgs.push_back("-lpthread");
+ if (!Args.hasArg(options::OPT_shared)) {
+ if (Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back("-lc_p");
+ else
+ CmdArgs.push_back("-lc");
+ }
+
+ std::string myarch = "-lclang_rt.";
+ const llvm::Triple &T = getToolChain().getTriple();
+ llvm::Triple::ArchType Arch = T.getArch();
+ switch (Arch) {
+ case llvm::Triple::arm:
+ myarch += ("arm");
+ break;
+ case llvm::Triple::x86:
+ myarch += ("i386");
+ break;
+ case llvm::Triple::x86_64:
+ myarch += ("amd64");
+ break;
+ default:
+ assert(0 && "Unsupported architecture");
+ }
+ CmdArgs.push_back(Args.MakeArgString(myarch));
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ if (!Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtend.o")));
+ else
+ CmdArgs.push_back(Args.MakeArgString(
+ getToolChain().GetFilePath("crtendS.o")));
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4768,10 +5169,13 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/libexec/ld-elf.so.1");
}
- llvm::Triple::ArchType Arch = getToolChain().getArch();
- if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
- Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64)
- CmdArgs.push_back("--hash-style=both");
+ if (getToolChain().getTriple().getOSMajorVersion() >= 9) {
+ llvm::Triple::ArchType Arch = getToolChain().getArch();
+ if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
+ Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+ CmdArgs.push_back("--hash-style=both");
+ }
+ }
CmdArgs.push_back("--enable-new-dtags");
}
@@ -5078,6 +5482,14 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
StringRef MArch = getToolChain().getArchName();
if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
CmdArgs.push_back("-mfpu=neon");
+
+ StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
+ getToolChain().getTriple());
+ CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
+
+ Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
+ Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+ Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
} else if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mipsel ||
getToolChain().getArch() == llvm::Triple::mips64 ||
@@ -5103,11 +5515,19 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-EB");
else
CmdArgs.push_back("-EL");
- }
- Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
- Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
- Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
+ 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);
+ if (LastPICArg &&
+ (LastPICArg->getOption().matches(options::OPT_fPIC) ||
+ LastPICArg->getOption().matches(options::OPT_fpic) ||
+ LastPICArg->getOption().matches(options::OPT_fPIE) ||
+ LastPICArg->getOption().matches(options::OPT_fpie))) {
+ CmdArgs.push_back("-KPIC");
+ }
+ }
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
@@ -5126,9 +5546,10 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
-static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs,
- const ArgList &Args) {
- bool StaticLibgcc = Args.hasArg(options::OPT_static) ||
+static void AddLibgcc(llvm::Triple Triple, const Driver &D,
+ ArgStringList &CmdArgs, const ArgList &Args) {
+ bool isAndroid = Triple.getEnvironment() == llvm::Triple::ANDROIDEABI;
+ bool StaticLibgcc = isAndroid || Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_static_libgcc);
if (!D.CCCIsCXX)
CmdArgs.push_back("-lgcc");
@@ -5144,7 +5565,7 @@ static void AddLibgcc(const Driver &D, ArgStringList &CmdArgs,
CmdArgs.push_back("--no-as-needed");
}
- if (StaticLibgcc)
+ if (StaticLibgcc && !isAndroid)
CmdArgs.push_back("-lgcc_eh");
else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
CmdArgs.push_back("-lgcc");
@@ -5158,13 +5579,16 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const toolchains::Linux& ToolChain =
static_cast<const toolchains::Linux&>(getToolChain());
const Driver &D = ToolChain.getDriver();
+ const bool isAndroid = ToolChain.getTriple().getEnvironment() ==
+ llvm::Triple::ANDROIDEABI;
+
ArgStringList CmdArgs;
// 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
+ // and for "clang -w foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);
@@ -5218,6 +5642,10 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-static");
} else if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-shared");
+ if ((ToolChain.getArch() == llvm::Triple::arm
+ || ToolChain.getArch() == llvm::Triple::thumb) && isAndroid) {
+ CmdArgs.push_back("-Bsymbolic");
+ }
}
if (ToolChain.getArch() == llvm::Triple::arm ||
@@ -5225,11 +5653,17 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
(!Args.hasArg(options::OPT_static) &&
!Args.hasArg(options::OPT_shared))) {
CmdArgs.push_back("-dynamic-linker");
- if (ToolChain.getArch() == llvm::Triple::x86)
+ if (isAndroid)
+ CmdArgs.push_back("/system/bin/linker");
+ else if (ToolChain.getArch() == llvm::Triple::x86)
CmdArgs.push_back("/lib/ld-linux.so.2");
else if (ToolChain.getArch() == llvm::Triple::arm ||
- ToolChain.getArch() == llvm::Triple::thumb)
- CmdArgs.push_back("/lib/ld-linux.so.3");
+ ToolChain.getArch() == llvm::Triple::thumb) {
+ if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ CmdArgs.push_back("/lib/ld-linux-armhf.so.3");
+ else
+ CmdArgs.push_back("/lib/ld-linux.so.3");
+ }
else if (ToolChain.getArch() == llvm::Triple::mips ||
ToolChain.getArch() == llvm::Triple::mipsel)
CmdArgs.push_back("/lib/ld.so.1");
@@ -5249,25 +5683,27 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
- const char *crt1 = NULL;
- if (!Args.hasArg(options::OPT_shared)){
- if (Args.hasArg(options::OPT_pie))
- crt1 = "Scrt1.o";
- else
- crt1 = "crt1.o";
- }
- if (crt1)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
+ if (!isAndroid) {
+ const char *crt1 = NULL;
+ if (!Args.hasArg(options::OPT_shared)){
+ if (Args.hasArg(options::OPT_pie))
+ crt1 = "Scrt1.o";
+ else
+ crt1 = "crt1.o";
+ }
+ if (crt1)
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+ }
const char *crtbegin;
if (Args.hasArg(options::OPT_static))
- crtbegin = "crtbeginT.o";
+ crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
- crtbegin = "crtbeginS.o";
+ crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
else
- crtbegin = "crtbegin.o";
+ crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
}
@@ -5288,9 +5724,14 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Plugin));
}
+ if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+ CmdArgs.push_back("--no-demangle");
+
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- if (D.CCCIsCXX && !Args.hasArg(options::OPT_nostdlib)) {
+ if (D.CCCIsCXX &&
+ !Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
!Args.hasArg(options::OPT_static);
if (OnlyLibstdcxxStatic)
@@ -5303,34 +5744,37 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Call this before we add the C run-time.
addAsanRTLinux(getToolChain(), Args, CmdArgs);
+ addTsanRTLinux(getToolChain(), Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib)) {
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("--start-group");
+ if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+ if (Args.hasArg(options::OPT_static))
+ CmdArgs.push_back("--start-group");
- AddLibgcc(D, CmdArgs, Args);
+ AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
- if (Args.hasArg(options::OPT_pthread) ||
- Args.hasArg(options::OPT_pthreads))
- CmdArgs.push_back("-lpthread");
-
- CmdArgs.push_back("-lc");
+ if (Args.hasArg(options::OPT_pthread) ||
+ Args.hasArg(options::OPT_pthreads))
+ CmdArgs.push_back("-lpthread");
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("--end-group");
- else
- AddLibgcc(D, CmdArgs, Args);
+ CmdArgs.push_back("-lc");
+ if (Args.hasArg(options::OPT_static))
+ CmdArgs.push_back("--end-group");
+ else
+ AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
+ }
if (!Args.hasArg(options::OPT_nostartfiles)) {
const char *crtend;
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
- crtend = "crtendS.o";
+ crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
else
- crtend = "crtend.o";
+ crtend = isAndroid ? "crtend_android.o" : "crtend.o";
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+ if (!isAndroid)
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
}
@@ -5595,7 +6039,14 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-nologo");
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ Args.AddAllArgValues(CmdArgs, options::OPT_l);
+
+ // Add filenames immediately.
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ if (it->isFilename())
+ CmdArgs.push_back(it->getFilename());
+ }
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h
index 651a8f2..999c57a 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.h
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h
@@ -18,6 +18,8 @@
#include "llvm/Support/Compiler.h"
namespace clang {
+ class ObjCRuntime;
+
namespace driver {
class Driver;
@@ -39,10 +41,16 @@ namespace tools {
void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs,
bool KernelOrKext) const;
void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+ void AddPPCTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
+ enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
+
+ ObjCRuntime AddObjCRuntimeArgs(const ArgList &args, ArgStringList &cmdArgs,
+ RewriteKind rewrite) const;
+
public:
Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
@@ -369,6 +377,36 @@ namespace openbsd {
};
} // end namespace openbsd
+ /// bitrig -- Directly call GNU Binutils assembler and linker
+namespace bitrig {
+ class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
+ public:
+ Assemble(const ToolChain &TC) : Tool("bitrig::Assemble", "assembler",
+ TC) {}
+
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+ class LLVM_LIBRARY_VISIBILITY Link : public Tool {
+ public:
+ Link(const ToolChain &TC) : Tool("bitrig::Link", "linker", TC) {}
+
+ virtual bool hasIntegratedCPP() const { return false; }
+ virtual bool isLinkJob() const { return true; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+} // end namespace bitrig
+
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
diff --git a/contrib/llvm/tools/clang/lib/Driver/Types.cpp b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
index 50742fe..9d8fcfd 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Types.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
@@ -67,7 +67,8 @@ bool types::appendSuffixForType(ID Id) {
bool types::canLipoType(ID Id) {
return (Id == TY_Nothing ||
Id == TY_Image ||
- Id == TY_Object);
+ Id == TY_Object ||
+ Id == TY_LTO_BC);
}
bool types::isAcceptedByClang(ID Id) {
@@ -129,6 +130,7 @@ bool types::isCXX(ID Id) {
case TY_ObjCXX: case TY_PP_ObjCXX:
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+ case TY_CUDA:
return true;
}
}
OpenPOWER on IntegriCloud