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/Arg.cpp34
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ArgList.cpp41
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp14
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Compilation.cpp100
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Driver.cpp248
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/DriverOptions.cpp14
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/OptTable.cpp158
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Option.cpp333
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h106
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp61
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp481
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.h43
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp974
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.h5
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Types.cpp14
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp14
16 files changed, 1549 insertions, 1091 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Arg.cpp b/contrib/llvm/tools/clang/lib/Driver/Arg.cpp
index c0a2a50..93d70a9 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Arg.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Arg.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Arg.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Option.h"
#include "llvm/ADT/SmallString.h"
@@ -15,22 +16,23 @@
#include "llvm/Support/raw_ostream.h"
using namespace clang::driver;
+using clang::StringRef;
-Arg::Arg(const Option *_Opt, unsigned _Index, const Arg *_BaseArg)
- : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+Arg::Arg(const Option _Opt, StringRef S, unsigned _Index, const Arg *_BaseArg)
+ : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
Claimed(false), OwnsValues(false) {
}
-Arg::Arg(const Option *_Opt, unsigned _Index,
+Arg::Arg(const Option _Opt, StringRef S, unsigned _Index,
const char *Value0, const Arg *_BaseArg)
- : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+ : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
Claimed(false), OwnsValues(false) {
Values.push_back(Value0);
}
-Arg::Arg(const Option *_Opt, unsigned _Index,
+Arg::Arg(const Option _Opt, StringRef S, unsigned _Index,
const char *Value0, const char *Value1, const Arg *_BaseArg)
- : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+ : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
Claimed(false), OwnsValues(false) {
Values.push_back(Value0);
Values.push_back(Value1);
@@ -47,7 +49,7 @@ void Arg::dump() const {
llvm::errs() << "<";
llvm::errs() << " Opt:";
- Opt->dump();
+ Opt.dump();
llvm::errs() << " Index:" << Index;
@@ -83,39 +85,39 @@ void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
}
for (unsigned i = 0, e = getNumValues(); i != e; ++i)
- Output.push_back(getValue(Args, i));
+ Output.push_back(getValue(i));
}
void Arg::render(const ArgList &Args, ArgStringList &Output) const {
switch (getOption().getRenderStyle()) {
case Option::RenderValuesStyle:
for (unsigned i = 0, e = getNumValues(); i != e; ++i)
- Output.push_back(getValue(Args, i));
+ Output.push_back(getValue(i));
break;
case Option::RenderCommaJoinedStyle: {
SmallString<256> Res;
llvm::raw_svector_ostream OS(Res);
- OS << getOption().getName();
+ OS << getSpelling();
for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
if (i) OS << ',';
- OS << getValue(Args, i);
+ OS << getValue(i);
}
Output.push_back(Args.MakeArgString(OS.str()));
break;
}
-
+
case Option::RenderJoinedStyle:
Output.push_back(Args.GetOrMakeJoinedArgString(
- getIndex(), getOption().getName(), getValue(Args, 0)));
+ getIndex(), getSpelling(), getValue(0)));
for (unsigned i = 1, e = getNumValues(); i != e; ++i)
- Output.push_back(getValue(Args, i));
+ Output.push_back(getValue(i));
break;
case Option::RenderSeparateStyle:
- Output.push_back(getOption().getName().data());
+ Output.push_back(Args.MakeArgString(getSpelling()));
for (unsigned i = 0, e = getNumValues(); i != e; ++i)
- Output.push_back(getValue(Args, i));
+ Output.push_back(getValue(i));
break;
}
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
index 7fd439e..b3a43df 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
@@ -211,7 +211,7 @@ bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
StringRef ArgList::getLastArgValue(OptSpecifier Id,
StringRef Default) const {
if (Arg *A = getLastArg(Id))
- return A->getValue(*this);
+ return A->getValue();
return Default;
}
@@ -220,10 +220,10 @@ int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
int Res = Default;
if (Arg *A = getLastArg(Id)) {
- if (StringRef(A->getValue(*this)).getAsInteger(10, Res)) {
+ if (StringRef(A->getValue()).getAsInteger(10, Res)) {
if (Diags)
Diags->Report(diag::err_drv_invalid_int_value)
- << A->getAsString(*this) << A->getValue(*this);
+ << A->getAsString(*this) << A->getValue();
}
}
@@ -258,7 +258,7 @@ void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
ie = filtered_end(); it != ie; ++it) {
(*it)->claim();
for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
- Output.push_back((*it)->getValue(*this, i));
+ Output.push_back((*it)->getValue(i));
}
}
@@ -271,10 +271,10 @@ void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
if (Joined) {
Output.push_back(MakeArgString(StringRef(Translation) +
- (*it)->getValue(*this, 0)));
+ (*it)->getValue(0)));
} else {
Output.push_back(Translation);
- Output.push_back((*it)->getValue(*this, 0));
+ Output.push_back((*it)->getValue(0));
}
}
}
@@ -362,33 +362,40 @@ const char *DerivedArgList::MakeArgString(StringRef Str) const {
return BaseArgs.MakeArgString(Str);
}
-Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
- Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
+Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
+ Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
+ Twine(Opt.getName())),
+ BaseArgs.MakeIndex(Opt.getName()), BaseArg);
SynthesizedArgs.push_back(A);
return A;
}
-Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
+Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
StringRef Value) const {
unsigned Index = BaseArgs.MakeIndex(Value);
- Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg);
+ Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
+ Twine(Opt.getName())),
+ Index, BaseArgs.getArgString(Index), BaseArg);
SynthesizedArgs.push_back(A);
return A;
}
-Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
+Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
StringRef Value) const {
- unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
- Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg);
+ unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
+ Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
+ Twine(Opt.getName())),
+ Index, BaseArgs.getArgString(Index + 1), BaseArg);
SynthesizedArgs.push_back(A);
return A;
}
-Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
+Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
StringRef Value) const {
- unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str());
- Arg *A = new Arg(Opt, Index,
- BaseArgs.getArgString(Index) + Opt->getName().size(),
+ unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str());
+ Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
+ Twine(Opt.getName())), Index,
+ BaseArgs.getArgString(Index) + Opt.getName().size(),
BaseArg);
SynthesizedArgs.push_back(A);
return A;
diff --git a/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp b/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
index ea80f5a..4f89b73 100644
--- a/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
@@ -15,11 +15,19 @@ using namespace clang::driver;
using namespace clang::driver::options;
using namespace clang::driver::cc1asoptions;
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR)
+#include "clang/Driver/CC1AsOptions.inc"
+#undef OPTION
+#undef PREFIX
+
static const OptTable::Info CC1AsInfoTable[] = {
-#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+#define PREFIX(NAME, VALUE)
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) \
- { NAME, HELPTEXT, METAVAR, Option::KIND##Class, PARAM, FLAGS, \
- OPT_##GROUP, OPT_##ALIAS },
+ { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
+ FLAGS, OPT_##GROUP, OPT_##ALIAS },
#include "clang/Driver/CC1AsOptions.inc"
};
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
index c962fca..124e50c 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
@@ -17,6 +17,7 @@
#include "clang/Driver/ToolChain.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
#include <sys/stat.h>
@@ -101,6 +102,105 @@ void Compilation::PrintJob(raw_ostream &OS, const Job &J,
}
}
+static bool skipArg(const char *Flag, bool &SkipNextArg) {
+ StringRef FlagRef(Flag);
+
+ // Assume we're going to see -Flag <Arg>.
+ SkipNextArg = true;
+
+ // These flags are all of the form -Flag <Arg> and are treated as two
+ // arguments. Therefore, we need to skip the flag and the next argument.
+ bool Res = llvm::StringSwitch<bool>(Flag)
+ .Cases("-I", "-MF", "-MT", "-MQ", true)
+ .Cases("-o", "-coverage-file", "-dependency-file", true)
+ .Cases("-fdebug-compilation-dir", "-fmodule-cache-path", "-idirafter", true)
+ .Cases("-include", "-include-pch", "-internal-isystem", true)
+ .Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
+ .Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
+ .Cases("-resource-dir", "-serialize-diagnostic-file", true)
+ .Case("-dwarf-debug-flags", true)
+ .Default(false);
+
+ // Match found.
+ if (Res)
+ return Res;
+
+ // The remaining flags are treated as a single argument.
+ SkipNextArg = false;
+
+ // These flags are all of the form -Flag and have no second argument.
+ Res = llvm::StringSwitch<bool>(Flag)
+ .Cases("-M", "-MM", "-MG", "-MP", "-MD", true)
+ .Case("-MMD", true)
+ .Default(false);
+
+ // Match found.
+ if (Res)
+ return Res;
+
+ // These flags are treated as a single argument (e.g., -F<Dir>).
+ if (FlagRef.startswith("-F") || FlagRef.startswith("-I"))
+ return true;
+
+ return false;
+}
+
+static bool quoteNextArg(const char *flag) {
+ return llvm::StringSwitch<bool>(flag)
+ .Case("-D", true)
+ .Default(false);
+}
+
+void Compilation::PrintDiagnosticJob(raw_ostream &OS, const Job &J) const {
+ if (const Command *C = dyn_cast<Command>(&J)) {
+ OS << C->getExecutable();
+ unsigned QuoteNextArg = 0;
+ for (ArgStringList::const_iterator it = C->getArguments().begin(),
+ ie = C->getArguments().end(); it != ie; ++it) {
+
+ bool SkipNext;
+ if (skipArg(*it, SkipNext)) {
+ if (SkipNext) ++it;
+ continue;
+ }
+
+ if (!QuoteNextArg)
+ QuoteNextArg = quoteNextArg(*it) ? 2 : 0;
+
+ OS << ' ';
+
+ if (QuoteNextArg == 1)
+ OS << '"';
+
+ if (!std::strpbrk(*it, " \"\\$")) {
+ OS << *it;
+ } else {
+ // Quote the argument and escape shell special characters; this isn't
+ // really complete but is good enough.
+ OS << '"';
+ for (const char *s = *it; *s; ++s) {
+ if (*s == '"' || *s == '\\' || *s == '$')
+ OS << '\\';
+ OS << *s;
+ }
+ OS << '"';
+ }
+
+ if (QuoteNextArg) {
+ if (QuoteNextArg == 1)
+ OS << '"';
+ --QuoteNextArg;
+ }
+ }
+ OS << '\n';
+ } else {
+ const JobList *Jobs = cast<JobList>(&J);
+ for (JobList::const_iterator
+ it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
+ PrintDiagnosticJob(OS, **it);
+ }
+}
+
bool Compilation::CleanupFileList(const ArgStringList &Files,
bool IssueErrors) const {
bool Success = true;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
index 57b3417..3c410bb 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
@@ -52,25 +52,13 @@ Driver::Driver(StringRef ClangExecutable,
ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple),
DefaultImageName(DefaultImageName),
- DriverTitle("clang \"gcc-compatible\" driver"),
+ DriverTitle("clang LLVM compiler"),
CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
CCLogDiagnosticsFilename(0), CCCIsCXX(false),
CCCIsCPP(false),CCCEcho(false), CCCPrintBindings(false),
CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
- CCCUseClang(true), CCCUseClangCXX(true), CCCUseClangCPP(true),
- ForcedClangUse(false), CCCUsePCH(true), SuppressMissingInputWarning(false) {
- if (IsProduction) {
- // In a "production" build, only use clang on architectures we expect to
- // work.
- //
- // During development its more convenient to always have the driver use
- // clang, but we don't want users to be confused when things don't work, or
- // to file bugs for things we don't support.
- CCCClangArchs.insert(llvm::Triple::x86);
- CCCClangArchs.insert(llvm::Triple::x86_64);
- CCCClangArchs.insert(llvm::Triple::arm);
- }
+ CCCUsePCH(true), SuppressMissingInputWarning(false) {
Name = llvm::sys::path::stem(ClangExecutable);
Dir = llvm::sys::path::parent_path(ClangExecutable);
@@ -109,7 +97,7 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgList) {
for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
it != ie; ++it) {
Arg *A = *it;
- if (A->getOption().isUnsupported()) {
+ if (A->getOption().hasFlag(options::Unsupported)) {
Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args);
continue;
}
@@ -186,9 +174,9 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
// Add the remaining values as Xlinker arguments.
for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
- if (StringRef(A->getValue(Args, i)) != "--no-demangle")
+ if (StringRef(A->getValue(i)) != "--no-demangle")
DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker),
- A->getValue(Args, i));
+ A->getValue(i));
continue;
}
@@ -197,22 +185,22 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
// some build systems. We don't try to be complete here because we don't
// care to encourage this usage model.
if (A->getOption().matches(options::OPT_Wp_COMMA) &&
- A->getNumValues() == 2 &&
- (A->getValue(Args, 0) == StringRef("-MD") ||
- A->getValue(Args, 0) == StringRef("-MMD"))) {
+ (A->getValue(0) == StringRef("-MD") ||
+ A->getValue(0) == StringRef("-MMD"))) {
// Rewrite to -MD/-MMD along with -MF.
- if (A->getValue(Args, 0) == StringRef("-MD"))
+ if (A->getValue(0) == StringRef("-MD"))
DAL->AddFlagArg(A, Opts->getOption(options::OPT_MD));
else
DAL->AddFlagArg(A, Opts->getOption(options::OPT_MMD));
- DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF),
- A->getValue(Args, 1));
+ if (A->getNumValues() == 2)
+ DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF),
+ A->getValue(1));
continue;
}
// Rewrite reserved library names.
if (A->getOption().matches(options::OPT_l)) {
- StringRef Value = A->getValue(Args);
+ StringRef Value = A->getValue();
// Rewrite unless -nostdlib is present.
if (!HasNostdlib && Value == "stdc++") {
@@ -285,48 +273,23 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
CCCEcho = Args->hasArg(options::OPT_ccc_echo);
if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
- CCCGenericGCCName = A->getValue(*Args);
- CCCUseClangCXX = Args->hasFlag(options::OPT_ccc_clang_cxx,
- options::OPT_ccc_no_clang_cxx,
- CCCUseClangCXX);
+ CCCGenericGCCName = A->getValue();
CCCUsePCH = Args->hasFlag(options::OPT_ccc_pch_is_pch,
options::OPT_ccc_pch_is_pth);
- CCCUseClang = !Args->hasArg(options::OPT_ccc_no_clang);
- CCCUseClangCPP = !Args->hasArg(options::OPT_ccc_no_clang_cpp);
- if (const Arg *A = Args->getLastArg(options::OPT_ccc_clang_archs)) {
- StringRef Cur = A->getValue(*Args);
-
- CCCClangArchs.clear();
- while (!Cur.empty()) {
- std::pair<StringRef, StringRef> Split = Cur.split(',');
-
- if (!Split.first.empty()) {
- llvm::Triple::ArchType Arch =
- llvm::Triple(Split.first, "", "").getArch();
-
- if (Arch == llvm::Triple::UnknownArch)
- Diag(clang::diag::err_drv_invalid_arch_name) << Split.first;
-
- CCCClangArchs.insert(Arch);
- }
-
- Cur = Split.second;
- }
- }
// FIXME: DefaultTargetTriple is used by the target-prefixed calls to as/ld
// and getToolChain is const.
if (const Arg *A = Args->getLastArg(options::OPT_target))
- DefaultTargetTriple = A->getValue(*Args);
+ DefaultTargetTriple = A->getValue();
if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir))
- Dir = InstalledDir = A->getValue(*Args);
+ Dir = InstalledDir = A->getValue();
for (arg_iterator it = Args->filtered_begin(options::OPT_B),
ie = Args->filtered_end(); it != ie; ++it) {
const Arg *A = *it;
A->claim();
- PrefixDirs.push_back(A->getValue(*Args, 0));
+ PrefixDirs.push_back(A->getValue(0));
}
if (const Arg *A = Args->getLastArg(options::OPT__sysroot_EQ))
- SysRoot = A->getValue(*Args);
+ SysRoot = A->getValue();
if (Args->hasArg(options::OPT_nostdlib))
UseStdLib = false;
@@ -399,11 +362,11 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
std::string Cmd;
llvm::raw_string_ostream OS(Cmd);
if (FailingCommand)
- C.PrintJob(OS, *FailingCommand, "\n", false);
+ C.PrintDiagnosticJob(OS, *FailingCommand);
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);
+ C.PrintDiagnosticJob(OS, C.getJobs());
OS.flush();
// Clear stale state and suppress tool output.
@@ -418,7 +381,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
bool IgnoreInput = false;
// Ignore input from stdin or any inputs that cannot be preprocessed.
- if (!strcmp(it->second->getValue(C.getArgs()), "-")) {
+ if (!strcmp(it->second->getValue(), "-")) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating preprocessed source(s) - ignoring input from stdin"
".";
@@ -442,7 +405,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
it != ie; ++it) {
Arg *A = *it;
if (A->getOption().matches(options::OPT_arch)) {
- StringRef ArchName = A->getValue(C.getArgs());
+ StringRef ArchName = A->getValue();
ArchNames.insert(ArchName);
}
}
@@ -501,57 +464,6 @@ 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 ");
@@ -639,12 +551,12 @@ void Driver::PrintOptions(const ArgList &Args) const {
it != ie; ++it, ++i) {
Arg *A = *it;
llvm::errs() << "Option " << i << " - "
- << "Name: \"" << A->getOption().getName() << "\", "
+ << "Name: \"" << A->getOption().getPrefixedName() << "\", "
<< "Values: {";
for (unsigned j = 0; j < A->getNumValues(); ++j) {
if (j)
llvm::errs() << ", ";
- llvm::errs() << '"' << A->getValue(Args, j) << '"';
+ llvm::errs() << '"' << A->getValue(j) << '"';
}
llvm::errs() << "}\n";
}
@@ -652,7 +564,9 @@ void Driver::PrintOptions(const ArgList &Args) const {
void Driver::PrintHelp(bool ShowHidden) const {
getOpts().PrintHelp(llvm::outs(), Name.c_str(), DriverTitle.c_str(),
- ShowHidden);
+ /*Include*/0,
+ /*Exclude*/options::NoDriverOption |
+ (ShowHidden ? 0 : options::HelpHidden));
}
void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
@@ -750,12 +664,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
// FIXME: The following handlers should use a callback mechanism, we don't
// know what the client would like to do.
if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
- llvm::outs() << GetFilePath(A->getValue(C.getArgs()), TC) << "\n";
+ llvm::outs() << GetFilePath(A->getValue(), TC) << "\n";
return false;
}
if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
- llvm::outs() << GetProgramPath(A->getValue(C.getArgs()), TC) << "\n";
+ llvm::outs() << GetProgramPath(A->getValue(), TC) << "\n";
return false;
}
@@ -818,7 +732,7 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
os << Action::getClassName(A->getKind()) << ", ";
if (InputAction *IA = dyn_cast<InputAction>(A)) {
- os << "\"" << IA->getInputArg().getValue(C.getArgs()) << "\"";
+ os << "\"" << IA->getInputArg().getValue() << "\"";
} else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
os << '"' << BIA->getArchName() << '"'
<< ", {" << PrintActions1(C, *BIA->begin(), Ids) << "}";
@@ -878,7 +792,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
// Validate the option here; we don't save the type here because its
// particular spelling may participate in other driver choices.
llvm::Triple::ArchType Arch =
- llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
+ tools::darwin::getArchTypeForDarwinArchName(A->getValue());
if (Arch == llvm::Triple::UnknownArch) {
Diag(clang::diag::err_drv_invalid_arch_name)
<< A->getAsString(Args);
@@ -886,15 +800,15 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
}
A->claim();
- if (ArchNames.insert(A->getValue(Args)))
- Archs.push_back(A->getValue(Args));
+ if (ArchNames.insert(A->getValue()))
+ Archs.push_back(A->getValue());
}
}
// 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(Args.MakeArgString(TC.getArchName()));
+ Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName()));
// 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"
@@ -981,8 +895,8 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
it != ie; ++it) {
Arg *A = *it;
- if (isa<InputOption>(A->getOption())) {
- const char *Value = A->getValue(Args);
+ if (A->getOption().getKind() == Option::InputClass) {
+ const char *Value = A->getValue();
types::ID Ty = types::TY_INVALID;
// Infer the input type if necessary.
@@ -1049,8 +963,8 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
if (CheckInputsExist && memcmp(Value, "-", 2) != 0) {
SmallString<64> Path(Value);
if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) {
- SmallString<64> Directory(WorkDir->getValue(Args));
- if (llvm::sys::path::is_absolute(Directory.str())) {
+ if (!llvm::sys::path::is_absolute(Path.str())) {
+ SmallString<64> Directory(WorkDir->getValue());
llvm::sys::path::append(Directory, Value);
Path.assign(Directory);
}
@@ -1064,21 +978,21 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
} else
Inputs.push_back(std::make_pair(Ty, A));
- } else if (A->getOption().isLinkerInput()) {
+ } else if (A->getOption().hasFlag(options::LinkerInput)) {
// Just treat as object type, we could make a special type for this if
// necessary.
Inputs.push_back(std::make_pair(types::TY_Object, A));
} else if (A->getOption().matches(options::OPT_x)) {
InputTypeArg = A;
- InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
+ InputType = types::lookupTypeForTypeSpecifier(A->getValue());
A->claim();
// Follow gcc behavior and treat as linker input for invalid -x
// options. Its not clear why we shouldn't just revert to unknown; but
// this isn't very important, we might as well be bug compatible.
if (!InputType) {
- Diag(clang::diag::err_drv_unknown_language) << A->getValue(Args);
+ Diag(clang::diag::err_drv_unknown_language) << A->getValue();
InputType = types::TY_Object;
}
}
@@ -1301,7 +1215,7 @@ void Driver::BuildJobs(Compilation &C) const {
const char *LinkingOutput = 0;
if (isa<LipoJobAction>(A)) {
if (FinalOutput)
- LinkingOutput = FinalOutput->getValue(C.getArgs());
+ LinkingOutput = FinalOutput->getValue();
else
LinkingOutput = DefaultImageName.c_str();
}
@@ -1331,13 +1245,13 @@ void Driver::BuildJobs(Compilation &C) const {
// DiagnosticsEngine, so that extra values, position, and so on could be
// printed.
if (!A->isClaimed()) {
- if (A->getOption().hasNoArgumentUnused())
+ if (A->getOption().hasFlag(options::NoArgumentUnused))
continue;
// Suppress the warning automatically if this is just a flag, and it is an
// instance of an argument we already claimed.
const Option &Opt = A->getOption();
- if (isa<FlagOption>(Opt)) {
+ if (Opt.getKind() == Option::FlagClass) {
bool DuplicateClaimed = false;
for (arg_iterator it = C.getArgs().filtered_begin(&Opt),
@@ -1392,6 +1306,7 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
!C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
!C.getArgs().hasArg(options::OPT_traditional_cpp) &&
!C.getArgs().hasArg(options::OPT_save_temps) &&
+ !C.getArgs().hasArg(options::OPT_rewrite_objc) &&
ToolForJob->hasIntegratedCPP())
Inputs = &(*Inputs)[0]->getInputs();
@@ -1413,7 +1328,7 @@ void Driver::BuildJobsForAction(Compilation &C,
const Arg &Input = IA->getInputArg();
Input.claim();
if (Input.getOption().matches(options::OPT_INPUT)) {
- const char *Name = Input.getValue(C.getArgs());
+ const char *Name = Input.getValue();
Result = InputInfo(Name, A->getType(), Name);
} else
Result = InputInfo(&Input, A->getType(), "");
@@ -1502,7 +1417,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
if (AtTopLevel && !isa<DsymutilJobAction>(JA) &&
!isa<VerifyJobAction>(JA)) {
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
- return C.addResultFile(FinalOutput->getValue(C.getArgs()));
+ return C.addResultFile(FinalOutput->getValue());
}
// Default to writing to stdout?
@@ -1580,7 +1495,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
// Respect a limited subset of the '-Bprefix' functionality in GCC by
- // attempting to use this prefix when lokup up program paths.
+ // attempting to use this prefix when looking for file paths.
for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(),
ie = PrefixDirs.end(); it != ie; ++it) {
std::string Dir(*it);
@@ -1619,26 +1534,26 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
return Name;
}
-static bool isPathExecutable(llvm::sys::Path &P, bool WantFile) {
- bool Exists;
- return (WantFile ? !llvm::sys::fs::exists(P.str(), Exists) && Exists
- : P.canExecute());
-}
-
-std::string Driver::GetProgramPath(const char *Name, const ToolChain &TC,
- bool WantFile) const {
+std::string Driver::GetProgramPath(const char *Name,
+ const ToolChain &TC) const {
// FIXME: Needs a better variable than DefaultTargetTriple
std::string TargetSpecificExecutable(DefaultTargetTriple + "-" + Name);
// Respect a limited subset of the '-Bprefix' functionality in GCC by
- // attempting to use this prefix when lokup up program paths.
+ // attempting to use this prefix when looking for program paths.
for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(),
ie = PrefixDirs.end(); it != ie; ++it) {
- llvm::sys::Path P(*it);
- P.appendComponent(TargetSpecificExecutable);
- if (isPathExecutable(P, WantFile)) return P.str();
- P.eraseComponent();
- P.appendComponent(Name);
- if (isPathExecutable(P, WantFile)) return P.str();
+ bool IsDirectory;
+ if (!llvm::sys::fs::is_directory(*it, IsDirectory) && IsDirectory) {
+ llvm::sys::Path P(*it);
+ P.appendComponent(TargetSpecificExecutable);
+ if (P.canExecute()) return P.str();
+ P.eraseComponent();
+ P.appendComponent(Name);
+ if (P.canExecute()) return P.str();
+ } else {
+ llvm::sys::Path P(*it + Name);
+ if (P.canExecute()) return P.str();
+ }
}
const ToolChain::path_list &List = TC.getProgramPaths();
@@ -1646,10 +1561,10 @@ std::string Driver::GetProgramPath(const char *Name, const ToolChain &TC,
it = List.begin(), ie = List.end(); it != ie; ++it) {
llvm::sys::Path P(*it);
P.appendComponent(TargetSpecificExecutable);
- if (isPathExecutable(P, WantFile)) return P.str();
+ if (P.canExecute()) return P.str();
P.eraseComponent();
P.appendComponent(Name);
- if (isPathExecutable(P, WantFile)) return P.str();
+ if (P.canExecute()) return P.str();
}
// If all else failed, search the path.
@@ -1701,7 +1616,7 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple,
StringRef DarwinArchName) {
// FIXME: Already done in Compilation *Driver::BuildCompilation
if (const Arg *A = Args.getLastArg(options::OPT_target))
- DefaultTargetTriple = A->getValue(Args);
+ DefaultTargetTriple = A->getValue();
llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple));
@@ -1710,14 +1625,14 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple,
// If an explict Darwin arch name is given, that trumps all.
if (!DarwinArchName.empty()) {
Target.setArch(
- llvm::Triple::getArchTypeForDarwinArchName(DarwinArchName));
+ tools::darwin::getArchTypeForDarwinArchName(DarwinArchName));
return Target;
}
// Handle the Darwin '-arch' flag.
if (Arg *A = Args.getLastArg(options::OPT_arch)) {
llvm::Triple::ArchType DarwinArch
- = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
+ = tools::darwin::getArchTypeForDarwinArchName(A->getValue());
if (DarwinArch != llvm::Triple::UnknownArch)
Target.setArch(DarwinArch);
}
@@ -1820,37 +1735,14 @@ bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
const llvm::Triple &Triple) const {
// Check if user requested no clang, or clang doesn't understand this type (we
// only handle single inputs for now).
- if (!CCCUseClang || JA.size() != 1 ||
+ if (JA.size() != 1 ||
!types::isAcceptedByClang((*JA.begin())->getType()))
return false;
// Otherwise make sure this is an action clang understands.
- if (isa<PreprocessJobAction>(JA)) {
- if (!CCCUseClangCPP) {
- Diag(clang::diag::warn_drv_not_using_clang_cpp);
- return false;
- }
- } else if (!isa<PrecompileJobAction>(JA) && !isa<CompileJobAction>(JA))
- return false;
-
- // Use clang for C++?
- if (!CCCUseClangCXX && types::isCXX((*JA.begin())->getType())) {
- Diag(clang::diag::warn_drv_not_using_clang_cxx);
+ if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
+ !isa<CompileJobAction>(JA))
return false;
- }
-
- // Always use clang for precompiling, AST generation, and rewriting,
- // regardless of archs.
- if (isa<PrecompileJobAction>(JA) ||
- types::isOnlyAcceptedByClang(JA.getType()))
- return true;
-
- // Finally, don't use clang if this isn't one of the user specified archs to
- // build.
- if (!CCCClangArchs.empty() && !CCCClangArchs.count(Triple.getArch())) {
- Diag(clang::diag::warn_drv_not_using_clang_arch) << Triple.getArchName();
- return false;
- }
return true;
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/DriverOptions.cpp b/contrib/llvm/tools/clang/lib/Driver/DriverOptions.cpp
index 715819d..3925b8a 100644
--- a/contrib/llvm/tools/clang/lib/Driver/DriverOptions.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/DriverOptions.cpp
@@ -14,11 +14,19 @@
using namespace clang::driver;
using namespace clang::driver::options;
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR)
+#include "clang/Driver/Options.inc"
+#undef OPTION
+#undef PREFIX
+
static const OptTable::Info InfoTable[] = {
-#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+#define PREFIX(NAME, VALUE)
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) \
- { NAME, HELPTEXT, METAVAR, Option::KIND##Class, PARAM, FLAGS, \
- OPT_##GROUP, OPT_##ALIAS },
+ { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
+ FLAGS, OPT_##GROUP, OPT_##ALIAS },
#include "clang/Driver/Options.inc"
};
diff --git a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
index a3e38b2..6e7b695 100644
--- a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
@@ -11,6 +11,7 @@
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -54,6 +55,13 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
if (int N = StrCmpOptionName(A.Name, B.Name))
return N == -1;
+ for (const char * const *APre = A.Prefixes,
+ * const *BPre = B.Prefixes;
+ *APre != 0 && *BPre != 0; ++APre, ++BPre) {
+ if (int N = StrCmpOptionName(*APre, *BPre))
+ return N == -1;
+ }
+
// Names are the same, check that classes are in order; exactly one
// should be joined, and it should succeed the other.
assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) &&
@@ -78,23 +86,24 @@ OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
//
OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
- : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
- Options(new Option*[NumOptionInfos]),
- TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
+ : OptionInfos(_OptionInfos),
+ NumOptionInfos(_NumOptionInfos),
+ TheInputOptionID(0),
+ TheUnknownOptionID(0),
+ FirstSearchableIndex(0)
{
// Explicitly zero initialize the error to work around a bug in array
// value-initialization on MinGW with gcc 4.3.5.
- memset(Options, 0, sizeof(*Options) * NumOptionInfos);
// Find start of normal options.
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
unsigned Kind = getInfo(i + 1).Kind;
if (Kind == Option::InputClass) {
- assert(!TheInputOption && "Cannot have multiple input options!");
- TheInputOption = getOption(i + 1);
+ assert(!TheInputOptionID && "Cannot have multiple input options!");
+ TheInputOptionID = getInfo(i + 1).ID;
} else if (Kind == Option::UnknownClass) {
- assert(!TheUnknownOption && "Cannot have multiple input options!");
- TheUnknownOption = getOption(i + 1);
+ assert(!TheUnknownOptionID && "Cannot have multiple unknown options!");
+ TheUnknownOptionID = getInfo(i + 1).ID;
} else if (Kind != Option::GroupClass) {
FirstSearchableIndex = i;
break;
@@ -115,91 +124,80 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
// Check that options are in order.
for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
if (!(getInfo(i) < getInfo(i + 1))) {
- getOption(i)->dump();
- getOption(i + 1)->dump();
+ getOption(i).dump();
+ getOption(i + 1).dump();
llvm_unreachable("Options are not in order!");
}
}
#endif
+
+ // Build prefixes.
+ for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
+ if (const char *const *P = getInfo(i).Prefixes) {
+ for (; *P != 0; ++P) {
+ PrefixesUnion.insert(*P);
+ }
+ }
+ }
+
+ // Build prefix chars.
+ for (llvm::StringSet<>::const_iterator I = PrefixesUnion.begin(),
+ E = PrefixesUnion.end(); I != E; ++I) {
+ StringRef Prefix = I->getKey();
+ for (StringRef::const_iterator C = Prefix.begin(), CE = Prefix.end();
+ C != CE; ++C)
+ if (std::find(PrefixChars.begin(), PrefixChars.end(), *C)
+ == PrefixChars.end())
+ PrefixChars.push_back(*C);
+ }
}
OptTable::~OptTable() {
- for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- delete Options[i];
- delete[] Options;
}
-Option *OptTable::CreateOption(unsigned id) const {
- const Info &info = getInfo(id);
- const OptionGroup *Group =
- cast_or_null<OptionGroup>(getOption(info.GroupID));
- const Option *Alias = getOption(info.AliasID);
-
- Option *Opt = 0;
- switch (info.Kind) {
- case Option::InputClass:
- Opt = new InputOption(id); break;
- case Option::UnknownClass:
- Opt = new UnknownOption(id); break;
- case Option::GroupClass:
- Opt = new OptionGroup(id, info.Name, Group); break;
- case Option::FlagClass:
- Opt = new FlagOption(id, info.Name, Group, Alias); break;
- case Option::JoinedClass:
- Opt = new JoinedOption(id, info.Name, Group, Alias); break;
- case Option::SeparateClass:
- Opt = new SeparateOption(id, info.Name, Group, Alias); break;
- case Option::CommaJoinedClass:
- Opt = new CommaJoinedOption(id, info.Name, Group, Alias); break;
- case Option::MultiArgClass:
- Opt = new MultiArgOption(id, info.Name, Group, Alias, info.Param); break;
- case Option::JoinedOrSeparateClass:
- Opt = new JoinedOrSeparateOption(id, info.Name, Group, Alias); break;
- case Option::JoinedAndSeparateClass:
- Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
- }
+const Option OptTable::getOption(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ if (id == 0)
+ return Option(0, 0);
+ assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
+ return Option(&getInfo(id), this);
+}
- if (info.Flags & DriverOption)
- Opt->setDriverOption(true);
- if (info.Flags & LinkerInput)
- Opt->setLinkerInput(true);
- if (info.Flags & NoArgumentUnused)
- Opt->setNoArgumentUnused(true);
- if (info.Flags & NoForward)
- Opt->setNoForward(true);
- if (info.Flags & RenderAsInput)
- Opt->setNoOptAsInput(true);
- if (info.Flags & RenderJoined) {
- assert((info.Kind == Option::JoinedOrSeparateClass ||
- info.Kind == Option::SeparateClass) && "Invalid option.");
- Opt->setRenderStyle(Option::RenderJoinedStyle);
- }
- if (info.Flags & RenderSeparate) {
- assert((info.Kind == Option::JoinedOrSeparateClass ||
- info.Kind == Option::JoinedClass) && "Invalid option.");
- Opt->setRenderStyle(Option::RenderSeparateStyle);
- }
- if (info.Flags & Unsupported)
- Opt->setUnsupported(true);
- if (info.Flags & CC1Option)
- Opt->setIsCC1Option(true);
+static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) {
+ if (Arg == "-")
+ return true;
+ for (llvm::StringSet<>::const_iterator I = Prefixes.begin(),
+ E = Prefixes.end(); I != E; ++I)
+ if (Arg.startswith(I->getKey()))
+ return false;
+ return true;
+}
- return Opt;
+/// \returns Matched size. 0 means no match.
+static unsigned matchOption(const OptTable::Info *I, StringRef Str) {
+ for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) {
+ StringRef Prefix(*Pre);
+ if (Str.startswith(Prefix) && Str.substr(Prefix.size()).startswith(I->Name))
+ return Prefix.size() + StringRef(I->Name).size();
+ }
+ return 0;
}
Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
unsigned Prev = Index;
const char *Str = Args.getArgString(Index);
- // Anything that doesn't start with '-' is an input, as is '-' itself.
- if (Str[0] != '-' || Str[1] == '\0')
- return new Arg(TheInputOption, Index++, Str);
+ // Anything that doesn't start with PrefixesUnion is an input, as is '-'
+ // itself.
+ if (isInput(PrefixesUnion, Str))
+ return new Arg(getOption(TheInputOptionID), Str, Index++, Str);
const Info *Start = OptionInfos + FirstSearchableIndex;
const Info *End = OptionInfos + getNumOptions();
+ StringRef Name = StringRef(Str).ltrim(PrefixChars);
// Search for the first next option which could be a prefix.
- Start = std::lower_bound(Start, End, Str);
+ Start = std::lower_bound(Start, End, Name.data());
// Options are stored in sorted order, with '\0' at the end of the
// alphabet. Since the only options which can accept a string must
@@ -210,15 +208,16 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
// blanking on the simplest way to make it fast. We can solve this
// problem when we move to TableGen.
for (; Start != End; ++Start) {
+ unsigned ArgSize = 0;
// Scan for first option which is a proper prefix.
for (; Start != End; ++Start)
- if (memcmp(Str, Start->Name, strlen(Start->Name)) == 0)
+ if ((ArgSize = matchOption(Start, Str)))
break;
if (Start == End)
break;
// See if this option matches.
- if (Arg *A = getOption(Start - OptionInfos + 1)->accept(Args, Index))
+ if (Arg *A = Option(Start, this).accept(Args, Index, ArgSize))
return A;
// Otherwise, see if this argument was missing values.
@@ -226,7 +225,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
return 0;
}
- return new Arg(TheUnknownOption, Index++, Str);
+ return new Arg(getOption(TheUnknownOptionID), Str, Index++, Str);
}
InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
@@ -266,10 +265,11 @@ InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
}
static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
- std::string Name = Opts.getOptionName(Id);
+ const Option O = Opts.getOption(Id);
+ std::string Name = O.getPrefixedName();
// Add metavar, if used.
- switch (Opts.getOptionKind(Id)) {
+ switch (O.getKind()) {
case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
llvm_unreachable("Invalid option with help text.");
@@ -346,7 +346,8 @@ static const char *getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id) {
}
void OptTable::PrintHelp(raw_ostream &OS, const char *Name,
- const char *Title, bool ShowHidden) const {
+ const char *Title, unsigned short FlagsToInclude,
+ unsigned short FlagsToExclude) const {
OS << "OVERVIEW: " << Title << "\n";
OS << '\n';
OS << "USAGE: " << Name << " [options] <inputs>\n";
@@ -365,7 +366,8 @@ void OptTable::PrintHelp(raw_ostream &OS, const char *Name,
if (getOptionKind(Id) == Option::GroupClass)
continue;
- if (!ShowHidden && isOptionHelpHidden(Id))
+ if ((FlagsToInclude && !(getInfo(Id).Flags & FlagsToInclude)) ||
+ getInfo(Id).Flags & FlagsToExclude)
continue;
if (const char *Text = getOptionHelpText(Id)) {
diff --git a/contrib/llvm/tools/clang/lib/Driver/Option.cpp b/contrib/llvm/tools/clang/lib/Driver/Option.cpp
index 03360ea..9a34df5 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Option.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Option.cpp
@@ -13,46 +13,20 @@
#include "clang/Driver/ArgList.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/Twine.h"
#include <cassert>
#include <algorithm>
using namespace clang::driver;
-Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
- const OptionGroup *_Group, const Option *_Alias)
- : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
- Unsupported(false), LinkerInput(false), NoOptAsInput(false),
- DriverOption(false), NoArgumentUnused(false), NoForward(false) {
+Option::Option(const OptTable::Info *info, const OptTable *owner)
+ : Info(info), Owner(owner) {
// Multi-level aliases are not supported, and alias options cannot
// have groups. This just simplifies option tracking, it is not an
// inherent limitation.
- assert((!Alias || (!Alias->Alias && !Group)) &&
+ assert((!Info || !getAlias().isValid() || (!getAlias().getAlias().isValid() &&
+ !getGroup().isValid())) &&
"Multi-level aliases and aliases with groups are unsupported.");
-
- // Initialize rendering options based on the class.
- switch (Kind) {
- case GroupClass:
- case InputClass:
- case UnknownClass:
- RenderStyle = RenderValuesStyle;
- break;
-
- case JoinedClass:
- case JoinedAndSeparateClass:
- RenderStyle = RenderJoinedStyle;
- break;
-
- case CommaJoinedClass:
- RenderStyle = RenderCommaJoinedStyle;
- break;
-
- case FlagClass:
- case SeparateClass:
- case MultiArgClass:
- case JoinedOrSeparateClass:
- RenderStyle = RenderSeparateStyle;
- break;
- }
}
Option::~Option() {
@@ -60,7 +34,7 @@ Option::~Option() {
void Option::dump() const {
llvm::errs() << "<";
- switch (Kind) {
+ switch (getKind()) {
#define P(N) case N: llvm::errs() << #N; break
P(GroupClass);
P(InputClass);
@@ -75,206 +49,153 @@ void Option::dump() const {
#undef P
}
- llvm::errs() << " Name:\"" << Name << '"';
+ llvm::errs() << " Prefixes:[";
+ for (const char * const *Pre = Info->Prefixes; *Pre != 0; ++Pre) {
+ llvm::errs() << '"' << *Pre << (*(Pre + 1) == 0 ? "\"" : "\", ");
+ }
+ llvm::errs() << ']';
- if (Group) {
+ llvm::errs() << " Name:\"" << getName() << '"';
+
+ const Option Group = getGroup();
+ if (Group.isValid()) {
llvm::errs() << " Group:";
- Group->dump();
+ Group.dump();
}
- if (Alias) {
+ const Option Alias = getAlias();
+ if (Alias.isValid()) {
llvm::errs() << " Alias:";
- Alias->dump();
+ Alias.dump();
}
- if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
- llvm::errs() << " NumArgs:" << MOA->getNumArgs();
+ if (getKind() == MultiArgClass)
+ llvm::errs() << " NumArgs:" << getNumArgs();
llvm::errs() << ">\n";
}
bool Option::matches(OptSpecifier Opt) const {
// Aliases are never considered in matching, look through them.
- if (Alias)
- return Alias->matches(Opt);
+ const Option Alias = getAlias();
+ if (Alias.isValid())
+ return Alias.matches(Opt);
// Check exact match.
- if (ID == Opt)
+ if (getID() == Opt.getID())
return true;
- if (Group)
- return Group->matches(Opt);
+ const Option Group = getGroup();
+ if (Group.isValid())
+ return Group.matches(Opt);
return false;
}
-OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
- const OptionGroup *Group)
- : Option(Option::GroupClass, ID, Name, Group, 0) {
-}
-
-Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
- llvm_unreachable("accept() should never be called on an OptionGroup");
-}
-
-InputOption::InputOption(OptSpecifier ID)
- : Option(Option::InputClass, ID, "<input>", 0, 0) {
-}
-
-Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
- llvm_unreachable("accept() should never be called on an InputOption");
-}
-
-UnknownOption::UnknownOption(OptSpecifier ID)
- : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
-}
-
-Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
- llvm_unreachable("accept() should never be called on an UnknownOption");
-}
-
-FlagOption::FlagOption(OptSpecifier ID, const char *Name,
- const OptionGroup *Group, const Option *Alias)
- : Option(Option::FlagClass, ID, Name, Group, Alias) {
-}
-
-Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
- // Matches iff this is an exact match.
- // FIXME: Avoid strlen.
- if (getName().size() != strlen(Args.getArgString(Index)))
- return 0;
-
- return new Arg(getUnaliasedOption(), Index++);
-}
-
-JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
- const OptionGroup *Group, const Option *Alias)
- : Option(Option::JoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
- // Always matches.
- const char *Value = Args.getArgString(Index) + getName().size();
- return new Arg(getUnaliasedOption(), Index++, Value);
-}
-
-CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
- const OptionGroup *Group,
- const Option *Alias)
- : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *CommaJoinedOption::accept(const ArgList &Args,
- unsigned &Index) const {
- // Always matches.
- const char *Str = Args.getArgString(Index) + getName().size();
- Arg *A = new Arg(getUnaliasedOption(), Index++);
+Arg *Option::accept(const ArgList &Args,
+ unsigned &Index,
+ unsigned ArgSize) const {
+ const Option &UnaliasedOption = getUnaliasedOption();
+ StringRef Spelling;
+ // If the option was an alias, get the spelling from the unaliased one.
+ if (getID() == UnaliasedOption.getID()) {
+ Spelling = StringRef(Args.getArgString(Index), ArgSize);
+ } else {
+ Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
+ Twine(UnaliasedOption.getName()));
+ }
- // Parse out the comma separated values.
- const char *Prev = Str;
- for (;; ++Str) {
- char c = *Str;
+ switch (getKind()) {
+ case FlagClass:
+ if (ArgSize != strlen(Args.getArgString(Index)))
+ return 0;
- if (!c || c == ',') {
- if (Prev != Str) {
- char *Value = new char[Str - Prev + 1];
- memcpy(Value, Prev, Str - Prev);
- Value[Str - Prev] = '\0';
- A->getValues().push_back(Value);
+ return new Arg(UnaliasedOption, Spelling, Index++);
+ case JoinedClass: {
+ const char *Value = Args.getArgString(Index) + ArgSize;
+ return new Arg(UnaliasedOption, Spelling, Index++, Value);
+ }
+ case CommaJoinedClass: {
+ // Always matches.
+ const char *Str = Args.getArgString(Index) + ArgSize;
+ Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
+
+ // Parse out the comma separated values.
+ const char *Prev = Str;
+ for (;; ++Str) {
+ char c = *Str;
+
+ if (!c || c == ',') {
+ if (Prev != Str) {
+ char *Value = new char[Str - Prev + 1];
+ memcpy(Value, Prev, Str - Prev);
+ Value[Str - Prev] = '\0';
+ A->getValues().push_back(Value);
+ }
+
+ if (!c)
+ break;
+
+ Prev = Str + 1;
}
-
- if (!c)
- break;
-
- Prev = Str + 1;
}
- }
- A->setOwnsValues(true);
-
- return A;
-}
-
-SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
- const OptionGroup *Group, const Option *Alias)
- : Option(Option::SeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
- // Matches iff this is an exact match.
- // FIXME: Avoid strlen.
- if (getName().size() != strlen(Args.getArgString(Index)))
- return 0;
-
- Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
-
- return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
-
-MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
- const OptionGroup *Group, const Option *Alias,
- unsigned _NumArgs)
- : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
- assert(NumArgs > 1 && "Invalid MultiArgOption!");
-}
-
-Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
- // Matches iff this is an exact match.
- // FIXME: Avoid strlen.
- if (getName().size() != strlen(Args.getArgString(Index)))
- return 0;
-
- Index += 1 + NumArgs;
- if (Index > Args.getNumInputArgStrings())
- return 0;
+ A->setOwnsValues(true);
- Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
- Args.getArgString(Index - NumArgs));
- for (unsigned i = 1; i != NumArgs; ++i)
- A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
- return A;
-}
-
-JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID,
- const char *Name,
- const OptionGroup *Group,
- const Option *Alias)
- : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedOrSeparateOption::accept(const ArgList &Args,
- unsigned &Index) const {
- // If this is not an exact match, it is a joined arg.
- // FIXME: Avoid strlen.
- if (getName().size() != strlen(Args.getArgString(Index))) {
- const char *Value = Args.getArgString(Index) + getName().size();
- return new Arg(this, Index++, Value);
+ return A;
}
+ case SeparateClass:
+ // Matches iff this is an exact match.
+ // FIXME: Avoid strlen.
+ if (ArgSize != strlen(Args.getArgString(Index)))
+ return 0;
+
+ Index += 2;
+ if (Index > Args.getNumInputArgStrings())
+ return 0;
+
+ return new Arg(UnaliasedOption, Spelling,
+ Index - 2, Args.getArgString(Index - 1));
+ case MultiArgClass: {
+ // Matches iff this is an exact match.
+ // FIXME: Avoid strlen.
+ if (ArgSize != strlen(Args.getArgString(Index)))
+ return 0;
+
+ Index += 1 + getNumArgs();
+ if (Index > Args.getNumInputArgStrings())
+ return 0;
+
+ Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
+ Args.getArgString(Index - getNumArgs()));
+ for (unsigned i = 1; i != getNumArgs(); ++i)
+ A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
+ return A;
+ }
+ case JoinedOrSeparateClass: {
+ // If this is not an exact match, it is a joined arg.
+ // FIXME: Avoid strlen.
+ if (ArgSize != strlen(Args.getArgString(Index))) {
+ const char *Value = Args.getArgString(Index) + ArgSize;
+ return new Arg(*this, Spelling, Index++, Value);
+ }
- // Otherwise it must be separate.
- Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
-
- return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
-
-JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
- const char *Name,
- const OptionGroup *Group,
- const Option *Alias)
- : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
- unsigned &Index) const {
- // Always matches.
-
- Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
+ // Otherwise it must be separate.
+ Index += 2;
+ if (Index > Args.getNumInputArgStrings())
+ return 0;
- return new Arg(getUnaliasedOption(), Index - 2,
- Args.getArgString(Index-2)+getName().size(),
- Args.getArgString(Index-1));
+ return new Arg(UnaliasedOption, Spelling,
+ Index - 2, Args.getArgString(Index - 1));
+ }
+ case JoinedAndSeparateClass:
+ // Always matches.
+ Index += 2;
+ if (Index > Args.getNumInputArgStrings())
+ return 0;
+
+ return new Arg(UnaliasedOption, Spelling, Index - 2,
+ Args.getArgString(Index - 2) + ArgSize,
+ Args.getArgString(Index - 1));
+ default:
+ llvm_unreachable("Invalid option kind!");
+ }
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
new file mode 100644
index 0000000..ecb396e
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
@@ -0,0 +1,106 @@
+//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
+
+#include "clang/Driver/ArgList.h"
+
+namespace clang {
+namespace driver {
+
+class SanitizerArgs {
+ /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
+ /// bit positions within \c Kind.
+ enum SanitizeOrdinal {
+#define SANITIZER(NAME, ID) SO_##ID,
+#include "clang/Basic/Sanitizers.def"
+ SO_Count
+ };
+
+ /// Bugs to catch at runtime.
+ enum SanitizeKind {
+#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
+#include "clang/Basic/Sanitizers.def"
+ NeedsAsanRt = Address,
+ NeedsTsanRt = Thread,
+ NeedsUbsanRt = Undefined
+ };
+ unsigned Kind;
+
+ public:
+ SanitizerArgs() : Kind(0) {}
+ /// Parses the sanitizer arguments from an argument list.
+ SanitizerArgs(const Driver &D, const ArgList &Args);
+
+ bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+ bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
+
+ bool sanitizesVptr() const { return Kind & Vptr; }
+
+ void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+ if (!Kind)
+ return;
+ llvm::SmallString<256> SanitizeOpt("-fsanitize=");
+#define SANITIZER(NAME, ID) \
+ if (Kind & ID) \
+ SanitizeOpt += NAME ",";
+#include "clang/Basic/Sanitizers.def"
+ SanitizeOpt.pop_back();
+ CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
+ }
+
+ private:
+ /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
+ /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
+ /// is not known.
+ static unsigned parse(const char *Value) {
+ return llvm::StringSwitch<SanitizeKind>(Value)
+#define SANITIZER(NAME, ID) .Case(NAME, ID)
+#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
+#include "clang/Basic/Sanitizers.def"
+ .Default(SanitizeKind());
+ }
+
+ /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
+ /// invalid components.
+ static unsigned parse(const Driver &D, const Arg *A) {
+ unsigned Kind = 0;
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
+ if (unsigned K = parse(A->getValue(I)))
+ Kind |= K;
+ else
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << A->getValue(I);
+ }
+ return Kind;
+ }
+
+ /// Produce an argument string from argument \p A, which shows how it provides
+ /// a value in \p Mask. For instance, the argument
+ /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
+ /// "-fsanitize=alignment".
+ static std::string describeSanitizeArg(const ArgList &Args, const Arg *A,
+ unsigned Mask) {
+ if (!A->getOption().matches(options::OPT_fsanitize_EQ))
+ return A->getAsString(Args);
+
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
+ if (parse(A->getValue(I)) & Mask)
+ return std::string("-fsanitize=") + A->getValue(I);
+
+ llvm_unreachable("arg didn't provide expected value");
+ }
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
index 48ed044..de8ed1d 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
@@ -14,6 +14,7 @@
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
@@ -32,13 +33,32 @@ const Driver &ToolChain::getDriver() const {
return D;
}
+std::string ToolChain::getDefaultUniversalArchName() const {
+ // In universal driver terms, the arch name accepted by -arch isn't exactly
+ // the same as the ones that appear in the triple. Roughly speaking, this is
+ // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
+ // only interesting special case is powerpc.
+ switch (Triple.getArch()) {
+ case llvm::Triple::ppc:
+ return "ppc";
+ case llvm::Triple::ppc64:
+ return "ppc64";
+ default:
+ return Triple.getArchName();
+ }
+}
+
+bool ToolChain::IsUnwindTablesDefault() const {
+ return false;
+}
+
std::string ToolChain::GetFilePath(const char *Name) const {
return D.GetFilePath(Name, *this);
}
-std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const {
- return D.GetProgramPath(Name, *this, WantFile);
+std::string ToolChain::GetProgramPath(const char *Name) const {
+ return D.GetProgramPath(Name, *this);
}
types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
@@ -66,13 +86,13 @@ static const char *getARMTargetCPU(const ArgList &Args,
// 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);
+ return A->getValue();
}
StringRef MArch;
if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
// Otherwise, if we have -march= choose the base CPU for that arch.
- MArch = A->getValue(Args);
+ MArch = A->getValue();
} else {
// Otherwise, use the Arch from the triple.
MArch = Triple.getArchName();
@@ -91,6 +111,8 @@ static const char *getARMTargetCPU(const ArgList &Args,
.Cases("armv6z", "armv6zk", "arm1176jzf-s")
.Case("armv6t2", "arm1156t2-s")
.Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
+ .Cases("armv7f", "armv7-f", "cortex-a9-mp")
+ .Cases("armv7s", "armv7-s", "swift")
.Cases("armv7r", "armv7-r", "cortex-r4")
.Cases("armv7m", "armv7-m", "cortex-m3")
.Case("ep9312", "ep9312")
@@ -119,10 +141,12 @@ static const char *getLLVMArchSuffixForARM(StringRef CPU) {
.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")
+ .Cases("cortex-a8", "cortex-a9", "cortex-a15", "v7")
.Case("cortex-m3", "v7m")
.Case("cortex-m4", "v7m")
.Case("cortex-m0", "v6m")
+ .Case("cortex-a9-mp", "v7f")
+ .Case("swift", "v7s")
.Default("");
}
@@ -142,7 +166,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
// FIXME: Thumb should just be another -target-feaure, not in the triple.
StringRef Suffix =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
- bool ThumbDefault = (Suffix == "v7" && getTriple().isOSDarwin());
+ bool ThumbDefault = (Suffix.startswith("v7") && getTriple().isOSDarwin());
std::string ArchName = "arm";
// Assembly files should start in ARM mode.
@@ -180,7 +204,7 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
const ArgList &Args) const
{
if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
- StringRef Value = A->getValue(Args);
+ StringRef Value = A->getValue();
if (Value == "compiler-rt")
return ToolChain::RLT_CompilerRT;
if (Value == "libgcc")
@@ -194,7 +218,7 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
- StringRef Value = A->getValue(Args);
+ StringRef Value = A->getValue();
if (Value == "libc++")
return ToolChain::CST_Libcxx;
if (Value == "libstdc++")
@@ -273,3 +297,24 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CmdArgs.push_back("-lcc_kext");
}
+
+bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // Check if -ffast-math or -funsafe-math is enabled.
+ Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations);
+
+ if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
+ A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
+ return false;
+
+ // If crtfastmath.o exists add it to the arguments.
+ std::string Path = GetFilePath("crtfastmath.o");
+ if (Path == "crtfastmath.o") // Not found.
+ return false;
+
+ CmdArgs.push_back(Args.MakeArgString(Path));
+ return true;
+}
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index 01c6623..a2ccb35 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -31,6 +31,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/system_error.h"
+#include "SanitizerArgs.h"
+
#include <cstdlib> // ::getenv
#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
@@ -80,17 +82,11 @@ bool Darwin::HasNativeLLVMSupport() const {
/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
- if (isTargetIPhoneOS()) {
+ 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);
- }
- }
+ if (isNonFragile)
+ return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
+ return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
}
/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
@@ -111,6 +107,9 @@ static const char *GetArmArchForMArch(StringRef Value) {
.Cases("armv7a", "armv7-a", "armv7")
.Cases("armv7r", "armv7-r", "armv7")
.Cases("armv7m", "armv7-m", "armv7")
+ .Cases("armv7f", "armv7-f", "armv7f")
+ .Cases("armv7k", "armv7-k", "armv7k")
+ .Cases("armv7s", "armv7-s", "armv7s")
.Default(0);
}
@@ -122,7 +121,10 @@ static const char *GetArmArchForMCpu(StringRef Value) {
.Case("xscale", "xscale")
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s",
"arm1176jzf-s", "cortex-m0", "armv6")
- .Cases("cortex-a8", "cortex-r4", "cortex-m3", "cortex-a9", "armv7")
+ .Cases("cortex-a8", "cortex-r4", "cortex-m3", "cortex-a9", "cortex-a15",
+ "armv7")
+ .Case("cortex-a9-mp", "armv7f")
+ .Case("swift", "armv7s")
.Default(0);
}
@@ -134,11 +136,11 @@ StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
case llvm::Triple::thumb:
case llvm::Triple::arm: {
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
- if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
+ if (const char *Arch = GetArmArchForMArch(A->getValue()))
return Arch;
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
- if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
+ if (const char *Arch = GetArmArchForMCpu(A->getValue()))
return Arch;
return "arm";
@@ -175,24 +177,11 @@ void Generic_ELF::anchor() {}
Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
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 (!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)))
- useClang = false;
- }
-
- // FIXME: This seems like a hacky way to choose clang frontend.
- if (useClang)
+ // FIXME: This seems like a hacky way to choose clang frontend.
Key = Action::AnalyzeJobClass;
+ }
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
@@ -245,30 +234,6 @@ DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple)
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
-
- // For fallback, we need to know how to find the GCC cc1 executables, so we
- // also add the GCC libexec paths. This is legacy code that can be removed
- // once fallback is no longer useful.
- AddGCCLibexecPath(DarwinVersion[0]);
- AddGCCLibexecPath(DarwinVersion[0] - 2);
- AddGCCLibexecPath(DarwinVersion[0] - 1);
- AddGCCLibexecPath(DarwinVersion[0] + 1);
- AddGCCLibexecPath(DarwinVersion[0] + 2);
-}
-
-void DarwinClang::AddGCCLibexecPath(unsigned darwinVersion) {
- std::string ToolChainDir = "i686-apple-darwin";
- ToolChainDir += llvm::utostr(darwinVersion);
- ToolChainDir += "/4.2.1";
-
- std::string Path = getDriver().Dir;
- Path += "/../llvm-gcc-4.2/libexec/gcc/";
- Path += ToolChainDir;
- getProgramPaths().push_back(Path);
-
- Path = "/usr/llvm-gcc-4.2/libexec/gcc/";
- Path += ToolChainDir;
- getProgramPaths().push_back(Path);
}
void DarwinClang::AddLinkARCArgs(const ArgList &Args,
@@ -287,9 +252,6 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
s += "iphonesimulator";
else if (isTargetIPhoneOS())
s += "iphoneos";
- // FIXME: Remove this once we depend fully on -mios-simulator-version-min.
- else if (TargetSimulatorVersionFromDefines != VersionTuple())
- s += "iphonesimulator";
else
s += "macosx";
s += ".a";
@@ -320,13 +282,15 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
break;
default:
getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
- << Args.getLastArg(options::OPT_rtlib_EQ)->getValue(Args) << "darwin";
+ << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
return;
}
// Darwin doesn't support real static executables, don't link any runtime
// libraries with -static.
- if (Args.hasArg(options::OPT_static))
+ if (Args.hasArg(options::OPT_static) ||
+ Args.hasArg(options::OPT_fapple_kext) ||
+ Args.hasArg(options::OPT_mkernel))
return;
// Reject -static-libgcc for now, we can deal with this when and if someone
@@ -351,15 +315,16 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
}
}
+ SanitizerArgs Sanitize(getDriver(), Args);
+
// Add ASAN runtime library, if required. Dynamic libraries and bundles
// should not be linked with the runtime library.
- if (Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false)) {
+ if (Sanitize.needsAsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) return;
if (isTargetIPhoneOS()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
- << "-faddress-sanitizer";
+ << "-fsanitize=address";
} else {
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.asan_osx.a");
@@ -410,67 +375,28 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
}
}
-static inline StringRef SimulatorVersionDefineName() {
- return "__IPHONE_OS_VERSION_MIN_REQUIRED";
-}
-
-/// \brief Parse the simulator version define:
-/// __IPHONE_OS_VERSION_MIN_REQUIRED=([0-9])([0-9][0-9])([0-9][0-9])
-// and return the grouped values as integers, e.g:
-// __IPHONE_OS_VERSION_MIN_REQUIRED=40201
-// will return Major=4, Minor=2, Micro=1.
-static bool GetVersionFromSimulatorDefine(StringRef define,
- unsigned &Major, unsigned &Minor,
- unsigned &Micro) {
- assert(define.startswith(SimulatorVersionDefineName()));
- StringRef name, version;
- llvm::tie(name, version) = define.split('=');
- if (version.empty())
- return false;
- std::string verstr = version.str();
- char *end;
- unsigned num = (unsigned) strtol(verstr.c_str(), &end, 10);
- if (*end != '\0')
- return false;
- Major = num / 10000;
- num = num % 10000;
- Minor = num / 100;
- Micro = num % 100;
- return true;
-}
-
void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
const OptTable &Opts = getDriver().getOpts();
+ // Support allowing the SDKROOT environment variable used by xcrun and other
+ // Xcode tools to define the default sysroot, by making it the default for
+ // isysroot.
+ if (!Args.hasArg(options::OPT_isysroot)) {
+ if (char *env = ::getenv("SDKROOT")) {
+ // We only use this value as the default if it is an absolute path and
+ // exists.
+ if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env)) {
+ Args.append(Args.MakeSeparateArg(
+ 0, Opts.getOption(options::OPT_isysroot), env));
+ }
+ }
+ }
+
Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Arg *iOSSimVersion = Args.getLastArg(
options::OPT_mios_simulator_version_min_EQ);
- // FIXME: HACK! When compiling for the simulator we don't get a
- // '-miphoneos-version-min' to help us know whether there is an ARC runtime
- // or not; try to parse a __IPHONE_OS_VERSION_MIN_REQUIRED
- // define passed in command-line.
- if (!iOSVersion && !iOSSimVersion) {
- for (arg_iterator it = Args.filtered_begin(options::OPT_D),
- ie = Args.filtered_end(); it != ie; ++it) {
- StringRef define = (*it)->getValue(Args);
- if (define.startswith(SimulatorVersionDefineName())) {
- unsigned Major = 0, Minor = 0, Micro = 0;
- if (GetVersionFromSimulatorDefine(define, Major, Minor, Micro) &&
- Major < 10 && Minor < 100 && Micro < 100) {
- 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;
- }
- }
- }
-
if (OSXVersion && (iOSVersion || iOSSimVersion)) {
getDriver().Diag(diag::err_drv_argument_not_allowed_with)
<< OSXVersion->getAsString(Args)
@@ -500,7 +426,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
if (iOSTarget.empty()) {
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
StringRef first, second;
- StringRef isysroot = A->getValue(Args);
+ StringRef isysroot = A->getValue();
llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
if (second != "")
iOSTarget = second.substr(0,3);
@@ -510,7 +436,8 @@ 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() &&
- getDarwinArchName(Args) == "armv7")
+ (getDarwinArchName(Args) == "armv7" ||
+ getDarwinArchName(Args) == "armv7s"))
iOSTarget = iOSVersionMin;
// Handle conflicting deployment targets
@@ -536,21 +463,21 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
if (!OSXTarget.empty()) {
- const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+ const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
Args.append(OSXVersion);
} else if (!iOSTarget.empty()) {
- const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
+ const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget);
Args.append(iOSVersion);
} else if (!iOSSimTarget.empty()) {
- const Option *O = Opts.getOption(
+ const Option O = Opts.getOption(
options::OPT_mios_simulator_version_min_EQ);
iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
Args.append(iOSSimVersion);
} else {
// Otherwise, assume we are targeting OS X.
- const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+ const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
Args.append(OSXVersion);
}
@@ -568,7 +495,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
bool HadExtra;
if (OSXVersion) {
assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!");
- if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
+ if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor,
Micro, HadExtra) || HadExtra ||
Major != 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
@@ -576,7 +503,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
} else {
const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
assert(Version && "Unknown target platform!");
- if (!Driver::GetReleaseVersion(Version->getValue(Args), Major, Minor,
+ if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor,
Micro, HadExtra) || HadExtra ||
Major >= 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
@@ -614,7 +541,7 @@ void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
// Check in the sysroot first.
bool Exists;
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
- llvm::sys::Path P(A->getValue(Args));
+ llvm::sys::Path P(A->getValue());
P.appendComponent("usr");
P.appendComponent("lib");
P.appendComponent("libstdc++.dylib");
@@ -655,7 +582,14 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
llvm::sys::Path P(getDriver().ResourceDir);
P.appendComponent("lib");
P.appendComponent("darwin");
- P.appendComponent("libclang_rt.cc_kext.a");
+
+ // Use the newer cc_kext for iOS ARM after 6.0.
+ if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
+ !isIPhoneOSVersionLT(6, 0)) {
+ P.appendComponent("libclang_rt.cc_kext.a");
+ } else {
+ P.appendComponent("libclang_rt.cc_kext_ios5.a");
+ }
// For now, allow missing resource libraries to support developers who may
// not have compiler-rt checked out or integrated into their build.
@@ -683,15 +617,15 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
if (A->getOption().matches(options::OPT_Xarch__)) {
// Skip this argument unless the architecture matches either the toolchain
// triple arch, or the arch being bound.
- //
- // FIXME: Canonicalize name.
- StringRef XarchArch = A->getValue(Args, 0);
- if (!(XarchArch == getArchName() ||
- (BoundArch && XarchArch == BoundArch)))
+ llvm::Triple::ArchType XarchArch =
+ tools::darwin::getArchTypeForDarwinArchName(A->getValue(0));
+ if (!(XarchArch == getArch() ||
+ (BoundArch && XarchArch ==
+ tools::darwin::getArchTypeForDarwinArchName(BoundArch))))
continue;
Arg *OriginalArg = A;
- unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(Args, 1));
+ unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
unsigned Prev = Index;
Arg *XarchArg = Opts.ParseOneArg(Args, Index);
@@ -707,7 +641,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
<< A->getAsString(Args);
continue;
- } else if (XarchArg->getOption().isDriverOption()) {
+ } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
<< A->getAsString(Args);
continue;
@@ -721,12 +655,12 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
// Linker input arguments require custom handling. The problem is that we
// have already constructed the phase actions, so we can not treat them as
// "input arguments".
- if (A->getOption().isLinkerInput()) {
+ if (A->getOption().hasFlag(options::LinkerInput)) {
// Convert the argument into individual Zlinker_input_args.
for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
DAL->AddSeparateArg(OriginalArg,
Opts.getOption(options::OPT_Zlinker_input),
- A->getValue(Args, i));
+ A->getValue(i));
}
continue;
@@ -749,7 +683,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
case options::OPT_dependency_file:
DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
- A->getValue(Args));
+ A->getValue());
break;
case options::OPT_gfull:
@@ -805,8 +739,8 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
// how the driver driver works.
if (BoundArch) {
StringRef Name = BoundArch;
- const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
- const Option *MArch = Opts.getOption(options::OPT_march_EQ);
+ const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
+ const Option MArch = Opts.getOption(options::OPT_march_EQ);
// This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
// which defines the list of which architectures we accept.
@@ -864,6 +798,12 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
DAL->AddJoinedArg(0, MArch, "armv6k");
else if (Name == "armv7")
DAL->AddJoinedArg(0, MArch, "armv7a");
+ else if (Name == "armv7f")
+ DAL->AddJoinedArg(0, MArch, "armv7f");
+ else if (Name == "armv7k")
+ DAL->AddJoinedArg(0, MArch, "armv7k");
+ else if (Name == "armv7s")
+ DAL->AddJoinedArg(0, MArch, "armv7s");
else
llvm_unreachable("invalid Darwin arch");
@@ -875,6 +815,25 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
if (BoundArch)
AddDeploymentTarget(*DAL);
+ // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
+ // FIXME: It would be far better to avoid inserting those -static arguments,
+ // but we can't check the deployment target in the translation code until
+ // it is set here.
+ if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) {
+ for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
+ Arg *A = *it;
+ ++it;
+ if (A->getOption().getID() != options::OPT_mkernel &&
+ A->getOption().getID() != options::OPT_fapple_kext)
+ continue;
+ assert(it != ie && "unexpected argument translation");
+ A = *it;
+ assert(A->getOption().getID() == options::OPT_static &&
+ "missing expected -static argument");
+ it = DAL->getArgs().erase(it);
+ }
+ }
+
// Validate the C++ standard library choice.
CXXStdlibType Type = GetCXXStdlibType(*DAL);
if (Type == ToolChain::CST_Libcxx) {
@@ -882,13 +841,8 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
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 (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))
+ where = "iOS 5.0";
if (where != StringRef()) {
getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
@@ -900,9 +854,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
}
bool Darwin::IsUnwindTablesDefault() const {
- // FIXME: Gross; we should probably have some separate target
- // definition, possibly even reusing the one in clang.
- return getArchName() == "x86_64";
+ return getArch() == llvm::Triple::x86_64;
}
bool Darwin::UseDwarfDebugFlags() const {
@@ -917,19 +869,17 @@ bool Darwin::UseSjLjExceptions() const {
getTriple().getArch() == llvm::Triple::thumb);
}
-const char *Darwin::GetDefaultRelocationModel() const {
- return "pic";
+bool Darwin::isPICDefault() const {
+ return true;
}
-const char *Darwin::GetForcedPicModel() const {
- if (getArchName() == "x86_64")
- return "pic";
- return 0;
+bool Darwin::isPICDefaultForced() const {
+ return getArch() == llvm::Triple::x86_64;
}
bool Darwin::SupportsProfiling() const {
// Profiling instrumentation is only supported on x86.
- return getArchName() == "i386" || getArchName() == "x86_64";
+ return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
}
bool Darwin::SupportsObjCGC() const {
@@ -937,8 +887,10 @@ bool Darwin::SupportsObjCGC() const {
return !isTargetIPhoneOS();
}
-bool Darwin::SupportsObjCARC() const {
- return isTargetIPhoneOS() || !isMacosxVersionLT(10, 6);
+void Darwin::CheckObjCARC() const {
+ if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
+ return;
+ getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
}
std::string
@@ -1013,7 +965,7 @@ bool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const {
static StringRef getGCCToolchainDir(const ArgList &Args) {
const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
if (A)
- return A->getValue(Args);
+ return A->getValue();
return GCC_INSTALL_PREFIX;
}
@@ -1072,7 +1024,8 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
if (!llvm::sys::fs::exists(LibDir))
continue;
for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
- ScanLibDirForGCCTriple(TargetArch, LibDir, CandidateTripleAliases[k]);
+ ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
+ CandidateTripleAliases[k]);
}
for (unsigned j = 0, je = CandidateMultiarchLibDirs.size(); j < je; ++j) {
const std::string LibDir
@@ -1081,7 +1034,7 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
continue;
for (unsigned k = 0, ke = CandidateMultiarchTripleAliases.size(); k < ke;
++k)
- ScanLibDirForGCCTriple(TargetArch, LibDir,
+ ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
CandidateMultiarchTripleAliases[k],
/*NeedsMultiarchSuffix=*/true);
}
@@ -1136,7 +1089,10 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
static const char *const MIPSLibDirs[] = { "/lib" };
static const char *const MIPSTriples[] = { "mips-linux-gnu" };
static const char *const MIPSELLibDirs[] = { "/lib" };
- static const char *const MIPSELTriples[] = { "mipsel-linux-gnu" };
+ static const char *const MIPSELTriples[] = {
+ "mipsel-linux-gnu",
+ "mipsel-linux-android"
+ };
static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
static const char *const MIPS64Triples[] = { "mips64-linux-gnu" };
@@ -1264,8 +1220,32 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
MultiarchTripleAliases.push_back(MultiarchTriple.str());
}
+// FIXME: There is the same routine in the Tools.cpp.
+static bool hasMipsN32ABIArg(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
+ return A && (A->getValue() == StringRef("n32"));
+}
+
+static StringRef getTargetMultiarchSuffix(llvm::Triple::ArchType TargetArch,
+ const ArgList &Args) {
+ if (TargetArch == llvm::Triple::x86_64 ||
+ TargetArch == llvm::Triple::ppc64)
+ return "/64";
+
+ if (TargetArch == llvm::Triple::mips64 ||
+ TargetArch == llvm::Triple::mips64el) {
+ if (hasMipsN32ABIArg(Args))
+ return "/n32";
+ else
+ return "/64";
+ }
+
+ return "/32";
+}
+
void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
- llvm::Triple::ArchType TargetArch, const std::string &LibDir,
+ llvm::Triple::ArchType TargetArch, const ArgList &Args,
+ const std::string &LibDir,
StringRef CandidateTriple, bool NeedsMultiarchSuffix) {
// There are various different suffixes involving the triple we
// check for. We also record what is necessary to walk from each back
@@ -1274,6 +1254,10 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
"/gcc/" + CandidateTriple.str(),
"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
+ // The Freescale PPC SDK has the gcc libraries in
+ // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
+ "/" + CandidateTriple.str(),
+
// Ubuntu has a strange mis-matched pair of triples that this happens to
// match.
// FIXME: It may be worthwhile to generalize this and look for a second
@@ -1283,6 +1267,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
const std::string InstallSuffixes[] = {
"/../../..",
"/../../../..",
+ "/../..",
"/../../../.."
};
// Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
@@ -1307,11 +1292,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
// *if* there is a subdirectory of the right name with crtbegin.o in it,
// we use that. If not, and if not a multiarch triple, we look for
// crtbegin.o without the subdirectory.
- StringRef MultiarchSuffix
- = (TargetArch == llvm::Triple::x86_64 ||
- TargetArch == llvm::Triple::ppc64 ||
- TargetArch == llvm::Triple::mips64 ||
- TargetArch == llvm::Triple::mips64el) ? "/64" : "/32";
+ StringRef MultiarchSuffix = getTargetMultiarchSuffix(TargetArch, Args);
if (llvm::sys::fs::exists(LI->path() + MultiarchSuffix + "/crtbegin.o")) {
GCCMultiarchSuffix = MultiarchSuffix.str();
} else {
@@ -1392,18 +1373,17 @@ Tool &Generic_GCC::SelectTool(const Compilation &C,
}
bool Generic_GCC::IsUnwindTablesDefault() const {
- // FIXME: Gross; we should probably have some separate target
- // definition, possibly even reusing the one in clang.
- return getArchName() == "x86_64";
+ return getArch() == llvm::Triple::x86_64;
}
-const char *Generic_GCC::GetDefaultRelocationModel() const {
- return "static";
+bool Generic_GCC::isPICDefault() const {
+ return false;
}
-const char *Generic_GCC::GetForcedPicModel() const {
- return 0;
+bool Generic_GCC::isPICDefaultForced() const {
+ return false;
}
+
/// Hexagon Toolchain
Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple)
@@ -1457,21 +1437,14 @@ Tool &Hexagon_TC::SelectTool(const Compilation &C,
return *T;
}
-bool Hexagon_TC::IsUnwindTablesDefault() const {
- // FIXME: Gross; we should probably have some separate target
- // definition, possibly even reusing the one in clang.
- return getArchName() == "x86_64";
+bool Hexagon_TC::isPICDefault() const {
+ return false;
}
-const char *Hexagon_TC::GetDefaultRelocationModel() const {
- return "static";
+bool Hexagon_TC::isPICDefaultForced() const {
+ return false;
}
-const char *Hexagon_TC::GetForcedPicModel() const {
- return 0;
-} // End Hexagon
-
-
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
/// Currently does not support anything else but compilation.
@@ -1495,16 +1468,12 @@ bool TCEToolChain::IsMathErrnoDefault() const {
return true;
}
-bool TCEToolChain::IsUnwindTablesDefault() const {
+bool TCEToolChain::isPICDefault() const {
return false;
}
-const char *TCEToolChain::GetDefaultRelocationModel() const {
- return "static";
-}
-
-const char *TCEToolChain::GetForcedPicModel() const {
- return 0;
+bool TCEToolChain::isPICDefaultForced() const {
+ return false;
}
Tool &TCEToolChain::SelectTool(const Compilation &C,
@@ -1613,19 +1582,43 @@ void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
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);
+ switch (GetCXXStdlibType(DriverArgs)) {
+ case ToolChain::CST_Libcxx:
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/");
+ break;
+ case ToolChain::CST_Libstdcxx:
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/stdc++");
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
+ StringRef Triple = getTriple().str();
+ if (Triple.startswith("amd64"))
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
+ Triple.substr(5));
+ else
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/stdc++/" +
+ Triple);
+ break;
+ }
}
void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
- CmdArgs.push_back("-lstdc++");
+ switch (GetCXXStdlibType(Args)) {
+ case ToolChain::CST_Libcxx:
+ CmdArgs.push_back("-lc++");
+ CmdArgs.push_back("-lcxxrt");
+ // Include supc++ to provide Unwind until provided by libcxx.
+ CmdArgs.push_back("-lgcc");
+ break;
+ case ToolChain::CST_Libstdcxx:
+ CmdArgs.push_back("-lstdc++");
+ break;
+ }
}
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
@@ -2020,6 +2013,46 @@ static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
}
+static bool isMipsArch(llvm::Triple::ArchType Arch) {
+ return Arch == llvm::Triple::mips ||
+ Arch == llvm::Triple::mipsel ||
+ Arch == llvm::Triple::mips64 ||
+ Arch == llvm::Triple::mips64el;
+}
+
+static bool isMipsR2Arch(llvm::Triple::ArchType Arch,
+ const ArgList &Args) {
+ if (Arch != llvm::Triple::mips &&
+ Arch != llvm::Triple::mipsel)
+ return false;
+
+ Arg *A = Args.getLastArg(options::OPT_march_EQ,
+ options::OPT_mcpu_EQ,
+ options::OPT_mips_CPUs_Group);
+
+ if (!A)
+ return false;
+
+ if (A->getOption().matches(options::OPT_mips_CPUs_Group))
+ return A->getOption().matches(options::OPT_mips32r2);
+
+ return A->getValue() == StringRef("mips32r2");
+}
+
+static StringRef getMultilibDir(const llvm::Triple &Triple,
+ const ArgList &Args) {
+ if (!isMipsArch(Triple.getArch()))
+ return Triple.isArch32Bit() ? "lib32" : "lib64";
+
+ // lib32 directory has a special meaning on MIPS targets.
+ // It contains N32 ABI binaries. Use this folder if produce
+ // code for N32 ABI only.
+ if (hasMipsN32ABIArg(Args))
+ return "lib32";
+
+ return Triple.isArch32Bit() ? "lib" : "lib64";
+}
+
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
llvm::Triple::ArchType Arch = Triple.getArch();
@@ -2043,19 +2076,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
ExtraOpts.push_back("-X");
- const bool IsMips = Arch == llvm::Triple::mips ||
- Arch == llvm::Triple::mipsel ||
- Arch == llvm::Triple::mips64 ||
- Arch == llvm::Triple::mips64el;
-
- const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::ANDROIDEABI;
+ const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android;
// Do not use 'gnu' hash style for Mips targets because .gnu.hash
// and the MIPS ABI require .dynsym to be sorted in different ways.
// .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
// ABI requires a mapping between the GOT and the symbol table.
// Android loader does not support .gnu.hash.
- if (!IsMips && !IsAndroid) {
+ if (!isMipsArch(Arch) && !IsAndroid) {
if (IsRedhat(Distro) || IsOpenSuse(Distro) ||
(IsUbuntu(Distro) && Distro >= UbuntuMaverick))
ExtraOpts.push_back("--hash-style=gnu");
@@ -2084,16 +2112,23 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// to the link paths.
path_list &Paths = getFilePaths();
- const std::string Multilib = Triple.isArch32Bit() ? "lib32" : "lib64";
+ const std::string Multilib = getMultilibDir(Triple, Args);
const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
// Add the multilib suffixed paths where they are available.
if (GCCInstallation.isValid()) {
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
const std::string &LibPath = GCCInstallation.getParentLibPath();
- addPathIfExists((GCCInstallation.getInstallPath() +
- GCCInstallation.getMultiarchSuffix()),
- Paths);
+
+ if (IsAndroid && isMipsR2Arch(Triple.getArch(), Args))
+ addPathIfExists(GCCInstallation.getInstallPath() +
+ GCCInstallation.getMultiarchSuffix() +
+ "/mips-r2",
+ Paths);
+ else
+ addPathIfExists((GCCInstallation.getInstallPath() +
+ GCCInstallation.getMultiarchSuffix()),
+ Paths);
// If the GCC installation we found is inside of the sysroot, we want to
// prefer libraries installed in the parent prefix of the GCC installation.
@@ -2108,6 +2143,11 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
addPathIfExists(LibPath + "/../" + Multilib, Paths);
}
+ // On Android, libraries in the parent prefix of the GCC installation are
+ // preferred to the ones under sysroot.
+ if (IsAndroid) {
+ addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
+ }
}
addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
@@ -2326,16 +2366,25 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
StringRef LibDir = GCCInstallation.getParentLibPath();
StringRef InstallDir = GCCInstallation.getInstallPath();
StringRef Version = GCCInstallation.getVersion().Text;
- if (!addLibStdCXXIncludePaths(LibDir + "/../include/c++/" + Version,
- (GCCInstallation.getTriple().str() +
- GCCInstallation.getMultiarchSuffix()),
- DriverArgs, CC1Args)) {
+ StringRef TripleStr = GCCInstallation.getTriple().str();
+
+ const std::string IncludePathCandidates[] = {
+ LibDir.str() + "/../include/c++/" + Version.str(),
// Gentoo is weird and places its headers inside the GCC install, so if the
// first attempt to find the headers fails, try this pattern.
- addLibStdCXXIncludePaths(InstallDir + "/include/g++-v4",
- (GCCInstallation.getTriple().str() +
- GCCInstallation.getMultiarchSuffix()),
- DriverArgs, CC1Args);
+ InstallDir.str() + "/include/g++-v4",
+ // Android standalone toolchain has C++ headers in yet another place.
+ LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.str(),
+ // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
+ // without a subdirectory corresponding to the gcc version.
+ LibDir.str() + "/../include/c++",
+ };
+
+ for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
+ if (addLibStdCXXIncludePaths(IncludePathCandidates[i], (TripleStr +
+ GCCInstallation.getMultiarchSuffix()),
+ DriverArgs, CC1Args))
+ break;
}
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
index 95a11be..4c267e8 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
@@ -111,6 +111,7 @@ protected:
SmallVectorImpl<StringRef> &MultiarchTripleAliases);
void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch,
+ const ArgList &Args,
const std::string &LibDir,
StringRef CandidateTriple,
bool NeedsMultiarchSuffix = false);
@@ -128,8 +129,8 @@ public:
const ActionList &Inputs) const;
virtual bool IsUnwindTablesDefault() const;
- virtual const char *GetDefaultRelocationModel() const;
- virtual const char *GetForcedPicModel() const;
+ virtual bool isPICDefault() const;
+ virtual bool isPICDefaultForced() const;
protected:
/// \name ToolChain Implementation Helper Functions
@@ -155,9 +156,8 @@ public:
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
- virtual bool IsUnwindTablesDefault() const;
- virtual const char *GetDefaultRelocationModel() const;
- virtual const char *GetForcedPicModel() const;
+ virtual bool isPICDefault() const;
+ virtual bool isPICDefaultForced() const;
};
/// Darwin - The base Darwin tool chain.
@@ -185,11 +185,6 @@ 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.
@@ -243,9 +238,7 @@ public:
}
bool isTargetMacOS() const {
- return !isTargetIOSSimulator() &&
- !isTargetIPhoneOS() &&
- TargetSimulatorVersionFromDefines == VersionTuple();
+ return !isTargetIOSSimulator() && !isTargetIPhoneOS();
}
bool isTargetInitialized() const { return TargetInitialized; }
@@ -325,6 +318,10 @@ public:
return true;
}
+ virtual bool IsEncodeExtendedBlockSignatureDefault() const {
+ return true;
+ }
+
virtual bool IsObjCNonFragileABIDefault() const {
// Non-fragile ABI is default for everything but i386.
return getTriple().getArch() != llvm::Triple::x86;
@@ -347,14 +344,14 @@ public:
virtual RuntimeLibType GetDefaultRuntimeLibType() const {
return ToolChain::RLT_CompilerRT;
}
- virtual const char *GetDefaultRelocationModel() const;
- virtual const char *GetForcedPicModel() const;
+ virtual bool isPICDefault() const;
+ virtual bool isPICDefaultForced() const;
virtual bool SupportsProfiling() const;
virtual bool SupportsObjCGC() const;
- virtual bool SupportsObjCARC() const;
+ virtual void CheckObjCARC() const;
virtual bool UseDwarfDebugFlags() const;
@@ -365,9 +362,6 @@ public:
/// DarwinClang - The Darwin toolchain used by Clang.
class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
-private:
- void AddGCCLibexecPath(unsigned darwinVersion);
-
public:
DarwinClang(const Driver &D, const llvm::Triple& Triple);
@@ -399,7 +393,7 @@ public:
std::string ComputeEffectiveClangTriple(const ArgList &Args,
types::ID InputType) const;
- virtual const char *GetDefaultRelocationModel() const { return "pic"; }
+ virtual bool isPICDefault() const { return false; };
};
class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
@@ -540,9 +534,8 @@ public:
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
bool IsMathErrnoDefault() const;
- bool IsUnwindTablesDefault() const;
- const char* GetDefaultRelocationModel() const;
- const char* GetForcedPicModel() const;
+ bool isPICDefault() const;
+ bool isPICDefaultForced() const;
private:
mutable llvm::DenseMap<unsigned, Tool*> Tools;
@@ -564,8 +557,8 @@ public:
virtual bool IsIntegratedAssemblerDefault() const;
virtual bool IsUnwindTablesDefault() const;
- virtual const char *GetDefaultRelocationModel() const;
- virtual const char *GetForcedPicModel() const;
+ virtual bool isPICDefault() const;
+ virtual bool isPICDefaultForced() const;
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index 936bde9..927ffe0 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "InputInfo.h"
+#include "SanitizerArgs.h"
#include "ToolChains.h"
using namespace clang::driver;
@@ -93,9 +94,15 @@ static void addDirectoryList(const ArgList &Args,
const char *ArgName,
const char *EnvVar) {
const char *DirList = ::getenv(EnvVar);
+ bool CombinedArg = false;
+
if (!DirList)
return; // Nothing to do.
+ StringRef Name(ArgName);
+ if (Name.equals("-I") || Name.equals("-L"))
+ CombinedArg = true;
+
StringRef Dirs(DirList);
if (Dirs.empty()) // Empty string should not add '.'.
return;
@@ -103,21 +110,37 @@ static void addDirectoryList(const ArgList &Args,
StringRef::size_type Delim;
while ((Delim = Dirs.find(llvm::sys::PathSeparator)) != StringRef::npos) {
if (Delim == 0) { // Leading colon.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
+ if (CombinedArg) {
+ CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
+ } else {
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(".");
+ }
} else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
+ if (CombinedArg) {
+ CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
+ } else {
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
+ }
}
Dirs = Dirs.substr(Delim + 1);
}
if (Dirs.empty()) { // Trailing colon.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
+ if (CombinedArg) {
+ CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
+ } else {
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(".");
+ }
} else { // Add the last path.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs));
+ if (CombinedArg) {
+ CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
+ } else {
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(Args.MakeArgString(Dirs));
+ }
}
}
@@ -200,6 +223,12 @@ static void addProfileRT(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back(Args.MakeArgString(ProfileRT));
}
+static bool forwardToGCC(const Option &O) {
+ return !O.hasFlag(options::NoForward) &&
+ !O.hasFlag(options::DriverOption) &&
+ !O.hasFlag(options::LinkerInput);
+}
+
void Clang::AddPreprocessingOptions(Compilation &C,
const Driver &D,
const ArgList &Args,
@@ -220,7 +249,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
// Determine the output location.
const char *DepFile;
if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
- DepFile = MF->getValue(Args);
+ DepFile = MF->getValue();
C.addFailureResultFile(DepFile);
} else if (Output.getType() == types::TY_Dependencies) {
DepFile = Output.getFilename();
@@ -242,7 +271,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
// when we are only generating a dependency file.
Arg *OutputOpt = Args.getLastArg(options::OPT_o);
if (OutputOpt && Output.getType() != types::TY_Dependencies) {
- DepTarget = OutputOpt->getValue(Args);
+ DepTarget = OutputOpt->getValue();
} else {
// Otherwise derive from the base input.
//
@@ -282,7 +311,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
if (A->getOption().matches(options::OPT_MQ)) {
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
- QuoteTarget(A->getValue(Args), Quoted);
+ QuoteTarget(A->getValue(), Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
// -MT flag - no change
@@ -310,7 +339,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
bool FoundPTH = false;
bool FoundPCH = false;
- llvm::sys::Path P(A->getValue(Args));
+ llvm::sys::Path P(A->getValue());
bool Exists;
if (UsePCH) {
P.appendSuffix("pch");
@@ -442,10 +471,12 @@ static const char *getLLVMArchSuffixForARM(StringRef CPU) {
.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")
+ .Cases("cortex-a8", "cortex-a9", "cortex-a15", "v7")
.Case("cortex-m3", "v7m")
.Case("cortex-m4", "v7m")
.Case("cortex-m0", "v6m")
+ .Case("cortex-a9-mp", "v7f")
+ .Case("swift", "v7s")
.Default("");
}
@@ -458,7 +489,7 @@ static std::string getARMTargetCPU(const ArgList &Args,
// If we have -mcpu=, use that.
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- StringRef MCPU = A->getValue(Args);
+ StringRef MCPU = A->getValue();
// Handle -mcpu=native.
if (MCPU == "native")
return llvm::sys::getHostCPUName();
@@ -469,7 +500,7 @@ static std::string getARMTargetCPU(const ArgList &Args,
StringRef MArch;
if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
// Otherwise, if we have -march= choose the base CPU for that arch.
- MArch = A->getValue(Args);
+ MArch = A->getValue();
} else {
// Otherwise, use the Arch from the triple.
MArch = Triple.getArchName();
@@ -500,6 +531,8 @@ static std::string getARMTargetCPU(const ArgList &Args,
.Cases("armv6z", "armv6zk", "arm1176jzf-s")
.Case("armv6t2", "arm1156t2-s")
.Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
+ .Cases("armv7f", "armv7-f", "cortex-a9-mp")
+ .Cases("armv7s", "armv7-s", "swift")
.Cases("armv7r", "armv7-r", "cortex-r4")
.Cases("armv7m", "armv7-m", "cortex-m3")
.Case("ep9312", "ep9312")
@@ -531,7 +564,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
// frontend target.
static void addFPUArgs(const Driver &D, const Arg *A, const ArgList &Args,
ArgStringList &CmdArgs) {
- StringRef FPU = A->getValue(Args);
+ StringRef FPU = A->getValue();
// Set the target features based on the FPU.
if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
@@ -569,14 +602,15 @@ static void addFPUArgs(const Driver &D, const Arg *A, const ArgList &Args,
// Handle -mfpmath=.
static void addFPMathArgs(const Driver &D, const Arg *A, const ArgList &Args,
ArgStringList &CmdArgs, StringRef CPU) {
- StringRef FPMath = A->getValue(Args);
+ StringRef FPMath = A->getValue();
// Set the target features based on the FPMath.
if (FPMath == "neon") {
CmdArgs.push_back("-target-feature");
CmdArgs.push_back("+neonfp");
- if (CPU != "cortex-a8" && CPU != "cortex-a9" && CPU != "cortex-a9-mp")
+ if (CPU != "cortex-a8" && CPU != "cortex-a9" && CPU != "cortex-a9-mp" &&
+ CPU != "cortex-a15")
D.Diag(diag::err_drv_invalid_feature) << "-mfpmath=neon" << CPU;
} else if (FPMath == "vfp" || FPMath == "vfp2" || FPMath == "vfp3" ||
@@ -603,7 +637,7 @@ static StringRef getARMFloatABI(const Driver &D,
else if (A->getOption().matches(options::OPT_mhard_float))
FloatABI = "hard";
else {
- FloatABI = A->getValue(Args);
+ FloatABI = A->getValue();
if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
D.Diag(diag::err_drv_invalid_mfloat_abi)
<< A->getAsString(Args);
@@ -643,7 +677,7 @@ static StringRef getARMFloatABI(const Driver &D,
// EABI is always AAPCS, and if it was not marked 'hard', it's softfp
FloatABI = "softfp";
break;
- case llvm::Triple::ANDROIDEABI: {
+ case llvm::Triple::Android: {
std::string ArchName =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
if (StringRef(ArchName).startswith("v7"))
@@ -669,18 +703,29 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs,
bool KernelOrKext) const {
const Driver &D = getToolChain().getDriver();
- llvm::Triple Triple = getToolChain().getTriple();
+ // Get the effective triple, which takes into account the deployment target.
+ std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
+ llvm::Triple Triple(TripleStr);
+ std::string CPUName = getARMTargetCPU(Args, Triple);
// Select the ABI to use.
//
// FIXME: Support -meabi.
const char *ABIName = 0;
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
- ABIName = A->getValue(Args);
+ ABIName = A->getValue();
+ } else if (Triple.isOSDarwin()) {
+ // The backend is hardwired to assume AAPCS for M-class processors, ensure
+ // the frontend matches that.
+ if (StringRef(CPUName).startswith("cortex-m")) {
+ ABIName = "aapcs";
+ } else {
+ ABIName = "apcs-gnu";
+ }
} else {
// Select the default based on the platform.
switch(Triple.getEnvironment()) {
- case llvm::Triple::ANDROIDEABI:
+ case llvm::Triple::Android:
case llvm::Triple::GNUEABI:
case llvm::Triple::GNUEABIHF:
ABIName = "aapcs-linux";
@@ -697,7 +742,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
// Set the CPU based on -march= and -mcpu=.
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(getARMTargetCPU(Args, Triple)));
+ CmdArgs.push_back(Args.MakeArgString(CPUName));
// Determine floating point ABI from the options & target defaults.
StringRef FloatABI = getARMFloatABI(D, Args, Triple);
@@ -754,8 +799,10 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
// Kernel code has more strict alignment requirements.
if (KernelOrKext) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-long-calls");
+ if (Triple.getOS() != llvm::Triple::IOS || Triple.isOSVersionLT(6)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-long-calls");
+ }
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-arm-strict-align");
@@ -777,44 +824,18 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
CmdArgs.push_back("-no-implicit-float");
}
-// Get default architecture.
-static const char* getMipsArchFromCPU(StringRef CPUName) {
- if (CPUName == "mips32" || CPUName == "mips32r2")
- return "mips";
-
- assert((CPUName == "mips64" || CPUName == "mips64r2") &&
- "Unexpected cpu name.");
-
- return "mips64";
-}
-
-// Check that ArchName is a known Mips architecture name.
-static bool checkMipsArchName(StringRef ArchName) {
- return ArchName == "mips" ||
- ArchName == "mipsel" ||
- ArchName == "mips64" ||
- ArchName == "mips64el";
-}
-
-// Get default target cpu.
-static const char* getMipsCPUFromArch(StringRef ArchName) {
- if (ArchName == "mips" || ArchName == "mipsel")
+// Translate MIPS CPU name alias option to CPU name.
+static StringRef getMipsCPUFromAlias(const Arg &A) {
+ if (A.getOption().matches(options::OPT_mips32))
return "mips32";
-
- assert((ArchName == "mips64" || ArchName == "mips64el") &&
- "Unexpected arch name.");
-
- return "mips64";
-}
-
-// Get default ABI.
-static const char* getMipsABIFromArch(StringRef ArchName) {
- if (ArchName == "mips" || ArchName == "mipsel")
- return "o32";
-
- assert((ArchName == "mips64" || ArchName == "mips64el") &&
- "Unexpected arch name.");
- return "n64";
+ if (A.getOption().matches(options::OPT_mips32r2))
+ return "mips32r2";
+ if (A.getOption().matches(options::OPT_mips64))
+ return "mips64";
+ if (A.getOption().matches(options::OPT_mips64r2))
+ return "mips64r2";
+ llvm_unreachable("Unexpected option");
+ return "";
}
// Get CPU and ABI names. They are not independent
@@ -823,26 +844,53 @@ static void getMipsCPUAndABI(const ArgList &Args,
const ToolChain &TC,
StringRef &CPUName,
StringRef &ABIName) {
- StringRef ArchName;
-
- // Select target cpu and architecture.
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- CPUName = A->getValue(Args);
- ArchName = getMipsArchFromCPU(CPUName);
- }
- else {
- ArchName = Args.MakeArgString(TC.getArchName());
- if (!checkMipsArchName(ArchName))
- TC.getDriver().Diag(diag::err_drv_invalid_arch_name) << ArchName;
+ const char *DefMips32CPU = "mips32";
+ const char *DefMips64CPU = "mips64";
+
+ if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
+ options::OPT_mcpu_EQ,
+ options::OPT_mips_CPUs_Group)) {
+ if (A->getOption().matches(options::OPT_mips_CPUs_Group))
+ CPUName = getMipsCPUFromAlias(*A);
else
- CPUName = getMipsCPUFromArch(ArchName);
+ CPUName = A->getValue();
}
-
- // Select the ABI to use.
+
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
- ABIName = A->getValue(Args);
- else
- ABIName = getMipsABIFromArch(ArchName);
+ ABIName = A->getValue();
+
+ // Setup default CPU and ABI names.
+ if (CPUName.empty() && ABIName.empty()) {
+ switch (TC.getTriple().getArch()) {
+ default:
+ llvm_unreachable("Unexpected triple arch name");
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ CPUName = DefMips32CPU;
+ break;
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ CPUName = DefMips64CPU;
+ break;
+ }
+ }
+
+ if (!ABIName.empty()) {
+ // Deduce CPU name from ABI name.
+ CPUName = llvm::StringSwitch<const char *>(ABIName)
+ .Cases("o32", "eabi", DefMips32CPU)
+ .Cases("n32", "n64", DefMips64CPU)
+ .Default("");
+ }
+ else if (!CPUName.empty()) {
+ // Deduce ABI name from CPU name.
+ ABIName = llvm::StringSwitch<const char *>(CPUName)
+ .Cases("mips32", "mips32r2", "o32")
+ .Cases("mips64", "mips64r2", "n64")
+ .Default("");
+ }
+
+ // FIXME: Warn on inconsistent cpu and abi usage.
}
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
@@ -859,7 +907,7 @@ static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
else if (A->getOption().matches(options::OPT_mhard_float))
FloatABI = "hard";
else {
- FloatABI = A->getValue(Args);
+ FloatABI = A->getValue();
if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") {
D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
FloatABI = "hard";
@@ -941,12 +989,19 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
AddTargetFeature(Args, CmdArgs,
options::OPT_mdspr2, options::OPT_mno_dspr2,
"dspr2");
+
+ if (Arg *A = Args.getLastArg(options::OPT_G)) {
+ StringRef v = A->getValue();
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
+ A->claim();
+ }
}
/// 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);
+ StringRef CPUName = A->getValue();
if (CPUName == "native") {
std::string CPU = llvm::sys::getHostCPUName();
@@ -978,6 +1033,8 @@ static std::string getPPCTargetCPU(const ArgList &Args) {
.Case("970", "970")
.Case("G5", "g5")
.Case("a2", "a2")
+ .Case("e500mc", "e500mc")
+ .Case("e5500", "e5500")
.Case("power6", "pwr6")
.Case("power7", "pwr7")
.Case("powerpc", "ppc")
@@ -1015,7 +1072,7 @@ void Clang::AddSparcTargetArgs(const ArgList &Args,
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
// Select the float ABI as determined by -msoft-float, -mhard-float, and
@@ -1054,6 +1111,8 @@ void Clang::AddSparcTargetArgs(const ArgList &Args,
void Clang::AddX86TargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
+ const bool isAndroid =
+ getToolChain().getTriple().getEnvironment() == llvm::Triple::Android;
if (!Args.hasFlag(options::OPT_mred_zone,
options::OPT_mno_red_zone,
true) ||
@@ -1068,7 +1127,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
const char *CPUName = 0;
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- if (StringRef(A->getValue(Args)) == "native") {
+ if (StringRef(A->getValue()) == "native") {
// FIXME: Reject attempts to use -march=native unless the target matches
// the host.
//
@@ -1078,7 +1137,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
if (!CPU.empty() && CPU != "generic")
CPUName = Args.MakeArgString(CPU);
} else
- CPUName = A->getValue(Args);
+ CPUName = A->getValue();
}
// Select the default CPU if none was given (or detection failed).
@@ -1118,7 +1177,9 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
if (getToolChain().getArch() == llvm::Triple::x86_64)
CPUName = "x86-64";
else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "pentium4";
+ // All x86 devices running Android have core2 as their common
+ // denominator. This makes a better choice than pentium4.
+ CPUName = isAndroid ? "core2" : "pentium4";
}
}
@@ -1141,8 +1202,8 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
(*it)->claim();
// Skip over "-m".
- assert(Name.startswith("-m") && "Invalid feature name.");
- Name = Name.substr(2);
+ assert(Name.startswith("m") && "Invalid feature name.");
+ Name = Name.substr(1);
bool IsNegative = Name.startswith("no-");
if (IsNegative)
@@ -1174,7 +1235,7 @@ static Arg* getLastHexagonArchArg (const ArgList &Args)
A->claim();
}
else if ((*it)->getOption().matches(options::OPT_m_Joined)){
- StringRef Value = (*it)->getValue(Args,0);
+ StringRef Value = (*it)->getValue(0);
if (Value.startswith("v")) {
A = *it;
A->claim();
@@ -1191,7 +1252,7 @@ static StringRef getHexagonTargetCPU(const ArgList &Args)
// Select the default CPU (v4) if none was given or detection failed.
if ((A = getLastHexagonArchArg (Args))) {
- WhichHexagon = A->getValue(Args);
+ WhichHexagon = A->getValue();
if (WhichHexagon == "")
return "v4";
else
@@ -1216,7 +1277,7 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
if (Arg *A = Args.getLastArg(options::OPT_G,
options::OPT_msmall_data_threshold_EQ)) {
std::string SmallDataThreshold="-small-data-threshold=";
- SmallDataThreshold += A->getValue(Args);
+ SmallDataThreshold += A->getValue();
CmdArgs.push_back ("-mllvm");
CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold));
A->claim();
@@ -1392,25 +1453,80 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault);
}
+SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) {
+ Kind = 0;
+
+ const Arg *AsanArg, *TsanArg, *UbsanArg;
+ for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
+ unsigned Add = 0, Remove = 0;
+ const char *DeprecatedReplacement = 0;
+ if ((*I)->getOption().matches(options::OPT_faddress_sanitizer)) {
+ Add = Address;
+ DeprecatedReplacement = "-fsanitize=address";
+ } else if ((*I)->getOption().matches(options::OPT_fno_address_sanitizer)) {
+ Remove = Address;
+ DeprecatedReplacement = "-fno-sanitize=address";
+ } else if ((*I)->getOption().matches(options::OPT_fthread_sanitizer)) {
+ Add = Thread;
+ DeprecatedReplacement = "-fsanitize=thread";
+ } else if ((*I)->getOption().matches(options::OPT_fno_thread_sanitizer)) {
+ Remove = Thread;
+ DeprecatedReplacement = "-fno-sanitize=thread";
+ } else if ((*I)->getOption().matches(options::OPT_fcatch_undefined_behavior)) {
+ Add = Undefined;
+ DeprecatedReplacement = "-fsanitize=undefined";
+ } else if ((*I)->getOption().matches(options::OPT_fsanitize_EQ)) {
+ Add = parse(D, *I);
+ } else if ((*I)->getOption().matches(options::OPT_fno_sanitize_EQ)) {
+ Remove = parse(D, *I);
+ } else {
+ continue;
+ }
+
+ (*I)->claim();
+
+ Kind |= Add;
+ Kind &= ~Remove;
+
+ if (Add & NeedsAsanRt) AsanArg = *I;
+ if (Add & NeedsTsanRt) TsanArg = *I;
+ if (Add & NeedsUbsanRt) UbsanArg = *I;
+
+ // If this is a deprecated synonym, produce a warning directing users
+ // towards the new spelling.
+ if (DeprecatedReplacement)
+ D.Diag(diag::warn_drv_deprecated_arg)
+ << (*I)->getAsString(Args) << DeprecatedReplacement;
+ }
+
+ // Only one runtime library can be used at once.
+ // FIXME: Allow Ubsan to be combined with the other two.
+ bool NeedsAsan = needsAsanRt();
+ bool NeedsTsan = needsTsanRt();
+ bool NeedsUbsan = needsUbsanRt();
+ if (NeedsAsan + NeedsTsan + NeedsUbsan > 1)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << describeSanitizeArg(Args, NeedsAsan ? AsanArg : TsanArg,
+ NeedsAsan ? NeedsAsanRt : NeedsTsanRt)
+ << describeSanitizeArg(Args, NeedsUbsan ? UbsanArg : TsanArg,
+ NeedsUbsan ? NeedsUbsanRt : NeedsTsanRt);
+}
+
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
/// 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) {
- if (!Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false))
- return;
- if(TC.getTriple().getEnvironment() == llvm::Triple::ANDROIDEABI) {
+ if(TC.getTriple().getEnvironment() == llvm::Triple::Android) {
if (!Args.hasArg(options::OPT_shared)) {
if (!Args.hasArg(options::OPT_pie))
TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie);
- // For an executable, we add a .preinit_array stub.
- CmdArgs.push_back("-u");
- CmdArgs.push_back("__asan_preinit");
- CmdArgs.push_back("-lasan");
}
- CmdArgs.push_back("-lasan_preload");
- CmdArgs.push_back("-ldl");
+ SmallString<128> LibAsan(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(LibAsan, "lib", "linux",
+ (Twine("libclang_rt.asan-") +
+ TC.getArchName() + "-android.so"));
+ CmdArgs.push_back(Args.MakeArgString(LibAsan));
} else {
if (!Args.hasArg(options::OPT_shared)) {
// LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
@@ -1431,9 +1547,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
/// 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.
@@ -1448,6 +1561,22 @@ static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
}
}
+/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
+/// (Linux).
+static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ // LibUbsan is "libclang_rt.ubsan-<ArchName>.a" in the Linux library
+ // resource directory.
+ SmallString<128> LibUbsan(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(LibUbsan, "lib", "linux",
+ (Twine("libclang_rt.ubsan-") +
+ TC.getArchName() + ".a"));
+ CmdArgs.push_back(Args.MakeArgString(LibUbsan));
+ CmdArgs.push_back("-lpthread");
+ }
+}
+
static bool shouldUseFramePointer(const ArgList &Args,
const llvm::Triple &Triple) {
if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
@@ -1516,7 +1645,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->claim();
for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
- StringRef Value = A->getValue(Args, i);
+ StringRef Value = A->getValue(i);
if (Value == "-force_cpusubtype_ALL") {
// Do nothing, this is the default and we don't support anything else.
@@ -1600,8 +1729,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-analyzer-eagerly-assume");
- CmdArgs.push_back("-analyzer-ipa=inlining");
-
// Add default argument set.
if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
CmdArgs.push_back("-analyzer-checker=core");
@@ -1627,7 +1754,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// reasons.
CmdArgs.push_back("-analyzer-output");
if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
else
CmdArgs.push_back("plist");
@@ -1642,67 +1769,90 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CheckCodeGenerationOptions(D, Args);
- // Perform argument translation for LLVM backend. This
- // takes some care in reconciling with llvm-gcc. The
- // issue is that llvm-gcc translates these options based on
- // the values in cc1, whereas we are processing based on
- // the driver arguments.
-
- // This comes from the default translation the driver + cc1
- // would do to enable flag_pic.
-
- 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;
- if (LastPICArg) {
- PICForPIE = (LastPICArg->getOption().matches(options::OPT_fPIE) ||
- LastPICArg->getOption().matches(options::OPT_fpie));
- PICEnabled = (PICForPIE ||
- LastPICArg->getOption().matches(options::OPT_fPIC) ||
- LastPICArg->getOption().matches(options::OPT_fpic));
- PICDisabled = !PICEnabled;
+ // For the PIC and PIE flag options, this logic is different from the legacy
+ // logic in very old versions of GCC, as that logic was just a bug no one had
+ // ever fixed. This logic is both more rational and consistent with GCC's new
+ // logic now that the bugs are fixed. The last argument relating to either
+ // PIC or PIE wins, and no other argument is used. If the last argument is
+ // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any
+ // PIE option implicitly enables PIC at the same level.
+ bool PIE = false;
+ bool PIC = getToolChain().isPICDefault();
+ bool IsPICLevelTwo = PIC;
+ if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+ options::OPT_fpic, options::OPT_fno_pic,
+ options::OPT_fPIE, options::OPT_fno_PIE,
+ options::OPT_fpie, options::OPT_fno_pie)) {
+ Option O = A->getOption();
+ if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
+ O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
+ PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
+ PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
+ IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
+ O.matches(options::OPT_fPIC);
+ } else {
+ PIE = PIC = false;
+ }
+ }
+ // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
+ // is forced, then neither PIC nor PIE flags will have no effect.
+ if (getToolChain().isPICDefaultForced()) {
+ PIE = false;
+ PIC = getToolChain().isPICDefault();
+ IsPICLevelTwo = PIC;
}
+
+ // Inroduce a Darwin-specific hack. If the default is PIC but the flags
+ // specified while enabling PIC enabled level 1 PIC, just force it back to
+ // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
+ // informal testing).
+ if (PIC && getToolChain().getTriple().isOSDarwin())
+ IsPICLevelTwo |= getToolChain().isPICDefault();
+
// Note that these flags are trump-cards. Regardless of the order w.r.t. the
// PIC or PIE options above, if these show up, PIC is disabled.
- if (Args.hasArg(options::OPT_mkernel))
- PICDisabled = true;
+ llvm::Triple Triple(TripleStr);
+ if ((Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_fapple_kext)) &&
+ (Triple.getOS() != llvm::Triple::IOS ||
+ Triple.isOSVersionLT(6)))
+ PIC = PIE = false;
if (Args.hasArg(options::OPT_static))
- PICDisabled = true;
- bool DynamicNoPIC = Args.hasArg(options::OPT_mdynamic_no_pic);
-
- // Select the relocation model.
- const char *Model = getToolChain().GetForcedPicModel();
- if (!Model) {
- if (DynamicNoPIC)
- Model = "dynamic-no-pic";
- else if (PICDisabled)
- Model = "static";
- else if (PICEnabled)
- Model = "pic";
- else
- Model = getToolChain().GetDefaultRelocationModel();
- }
- StringRef ModelStr = Model ? Model : "";
- if (Model && ModelStr != "pic") {
- CmdArgs.push_back("-mrelocation-model");
- CmdArgs.push_back(Model);
- }
+ PIC = PIE = false;
+
+ if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
+ // This is a very special mode. It trumps the other modes, almost no one
+ // uses it, and it isn't even valid on any OS but Darwin.
+ if (!getToolChain().getTriple().isOSDarwin())
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getSpelling() << getToolChain().getTriple().str();
- // Infer the __PIC__ and __PIE__ values.
- if (ModelStr == "pic" && PICForPIE) {
- CmdArgs.push_back("-pie-level");
- CmdArgs.push_back((LastPICArg &&
- LastPICArg->getOption().matches(options::OPT_fPIE)) ?
- "2" : "1");
- } else if (ModelStr == "pic" || ModelStr == "dynamic-no-pic") {
- CmdArgs.push_back("-pic-level");
- CmdArgs.push_back(((ModelStr != "dynamic-no-pic" && LastPICArg &&
- LastPICArg->getOption().matches(options::OPT_fPIC)) ||
- getToolChain().getTriple().isOSDarwin()) ? "2" : "1");
+ // FIXME: Warn when this flag trumps some other PIC or PIE flag.
+
+ CmdArgs.push_back("-mrelocation-model");
+ CmdArgs.push_back("dynamic-no-pic");
+
+ // Only a forced PIC mode can cause the actual compile to have PIC defines
+ // etc., no flags are sufficient. This behavior was selected to closely
+ // match that of llvm-gcc and Apple GCC before that.
+ if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
+ CmdArgs.push_back("-pic-level");
+ CmdArgs.push_back("2");
+ }
+ } else {
+ // Currently, LLVM only knows about PIC vs. static; the PIE differences are
+ // handled in Clang's IRGen by the -pie-level flag.
+ CmdArgs.push_back("-mrelocation-model");
+ CmdArgs.push_back(PIC ? "pic" : "static");
+
+ if (PIC) {
+ CmdArgs.push_back("-pic-level");
+ CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
+ if (PIE) {
+ CmdArgs.push_back("-pie-level");
+ CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
+ }
+ }
}
if (!Args.hasFlag(options::OPT_fmerge_all_constants,
@@ -1713,7 +1863,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
CmdArgs.push_back("-mregparm");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
@@ -1741,25 +1891,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// flag disables them after the flag enabling them, enable the codegen
// optimization. This is complicated by several "umbrella" flags.
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_ffinite_math_only,
options::OPT_fno_finite_math_only,
options::OPT_fhonor_infinities,
options::OPT_fno_honor_infinities))
- if (A->getOption().getID() != options::OPT_fno_finite_math_only &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_finite_math_only &&
A->getOption().getID() != options::OPT_fhonor_infinities)
CmdArgs.push_back("-menable-no-infs");
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_ffinite_math_only,
options::OPT_fno_finite_math_only,
options::OPT_fhonor_nans,
options::OPT_fno_honor_nans))
- if (A->getOption().getID() != options::OPT_fno_finite_math_only &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_finite_math_only &&
A->getOption().getID() != options::OPT_fhonor_nans)
CmdArgs.push_back("-menable-no-nans");
// -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_fno_fast_math,
options::OPT_fmath_errno,
options::OPT_fno_math_errno))
MathErrno = A->getOption().getID() == options::OPT_fmath_errno;
@@ -1772,38 +1927,46 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// madness.
bool AssociativeMath = false;
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
options::OPT_fassociative_math,
options::OPT_fno_associative_math))
- if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
A->getOption().getID() != options::OPT_fno_associative_math)
AssociativeMath = true;
bool ReciprocalMath = false;
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
options::OPT_freciprocal_math,
options::OPT_fno_reciprocal_math))
- if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
A->getOption().getID() != options::OPT_fno_reciprocal_math)
ReciprocalMath = true;
bool SignedZeros = true;
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
options::OPT_fsigned_zeros,
options::OPT_fno_signed_zeros))
- if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
A->getOption().getID() != options::OPT_fsigned_zeros)
SignedZeros = false;
bool TrappingMath = true;
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_funsafe_math_optimizations,
options::OPT_fno_unsafe_math_optimizations,
options::OPT_ftrapping_math,
options::OPT_fno_trapping_math))
- if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ if (A->getOption().getID() != options::OPT_fno_fast_math &&
+ A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
A->getOption().getID() != options::OPT_ftrapping_math)
TrappingMath = false;
if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
@@ -1813,16 +1976,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Validate and pass through -fp-contract option.
if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
options::OPT_ffp_contract)) {
if (A->getOption().getID() == options::OPT_ffp_contract) {
- StringRef Val = A->getValue(Args);
+ StringRef Val = A->getValue();
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
+ } else if (A->getOption().getID() == options::OPT_ffast_math) {
// If fast-math is set then set the fp-contract mode to fast.
CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
}
@@ -1833,10 +1997,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// preprocessor macros. This is distinct from enabling any optimizations as
// these options induce language changes which must survive serialization
// and deserialization, etc.
- if (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");
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math))
+ if (A->getOption().matches(options::OPT_ffast_math))
+ CmdArgs.push_back("-ffast-math");
+ if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math))
+ if (A->getOption().matches(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.
@@ -1885,7 +2051,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("-mlimit-float-precision");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
// FIXME: Handle -mtune=.
@@ -1893,7 +2059,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
CmdArgs.push_back("-mcode-model");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
// Add target specific cpu and features flags.
@@ -1937,7 +2103,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Pass the linker version in use.
if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
CmdArgs.push_back("-target-linker-version");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
// -mno-omit-leaf-frame-pointer is the default on Darwin.
@@ -1991,6 +2157,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
Args.ClaimAllArgs(options::OPT_g_flags_Group);
+ if (Args.hasArg(options::OPT_gcolumn_info))
+ CmdArgs.push_back("-dwarf-column-info");
Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
@@ -2008,7 +2176,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
C.getArgs().hasArg(options::OPT_S)) {
if (Output.isFilename()) {
CmdArgs.push_back("-coverage-file");
- CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
+ SmallString<128> absFilename(Output.getFilename());
+ llvm::sys::fs::make_absolute(absFilename);
+ CmdArgs.push_back(Args.MakeArgString(absFilename));
}
}
@@ -2047,7 +2217,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case options::OPT_ccc_arcmt_migrate:
CmdArgs.push_back("-arcmt-migrate");
CmdArgs.push_back("-mt-migrate-directory");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
@@ -2062,7 +2232,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
<< A->getAsString(Args) << "-ccc-arcmt-migrate";
}
CmdArgs.push_back("-mt-migrate-directory");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
options::OPT_objcmt_migrate_subscripting)) {
@@ -2094,7 +2264,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (A->getOption().matches(options::OPT_O4))
CmdArgs.push_back("-O3");
else if (A->getOption().matches(options::OPT_O) &&
- A->getValue(Args)[0] == '\0')
+ A->getValue()[0] == '\0')
CmdArgs.push_back("-O2");
else
A->render(Args, CmdArgs);
@@ -2132,8 +2302,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// eventually we want to do all the standard defaulting here instead of
// splitting it between the driver and clang -cc1.
if (!types::isCXX(InputType))
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
- "-std=", /*Joined=*/true);
+ Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+ "-std=", /*Joined=*/true);
+ else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32)
+ CmdArgs.push_back("-std=c++11");
+
Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
}
@@ -2182,18 +2355,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
options::OPT_ftemplate_depth_EQ)) {
CmdArgs.push_back("-ftemplate-depth");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
CmdArgs.push_back("-fconstexpr-depth");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
options::OPT_Wlarge_by_value_copy_def)) {
if (A->getNumValues()) {
- StringRef bytes = A->getValue(Args);
+ StringRef bytes = A->getValue();
CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
} else
CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
@@ -2202,50 +2375,50 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_fbounds_checking,
options::OPT_fbounds_checking_EQ)) {
if (A->getNumValues()) {
- StringRef val = A->getValue(Args);
+ StringRef val = A->getValue();
CmdArgs.push_back(Args.MakeArgString("-fbounds-checking=" + val));
} else
CmdArgs.push_back("-fbounds-checking=1");
}
- if (Args.hasArg(options::OPT__relocatable_pch))
+ if (Args.hasArg(options::OPT_relocatable_pch))
CmdArgs.push_back("-relocatable-pch");
if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
CmdArgs.push_back("-fconstant-string-class");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
CmdArgs.push_back("-ftabstop");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
CmdArgs.push_back("-ferror-limit");
if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
else
CmdArgs.push_back("19");
if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
CmdArgs.push_back("-fmacro-backtrace-limit");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
CmdArgs.push_back("-ftemplate-backtrace-limit");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
CmdArgs.push_back("-fconstexpr-backtrace-limit");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
// Pass -fmessage-length=.
CmdArgs.push_back("-fmessage-length");
if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
} else {
// If -fmessage-length=N was not specified, determine whether this is a
// terminal and, if so, implicitly define -fmessage-length appropriately.
@@ -2255,7 +2428,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
CmdArgs.push_back("-fvisibility");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
@@ -2268,7 +2441,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-ffreestanding");
// Forward -f (flag) options which we can pass directly.
- Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
@@ -2279,6 +2451,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
+ SanitizerArgs Sanitize(D, Args);
+ Sanitize.addArgs(Args, CmdArgs);
+
// Report and error for -faltivec on anything other then PowerPC.
if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
if (!(getToolChain().getTriple().getArch() == llvm::Triple::ppc ||
@@ -2289,14 +2464,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (getToolChain().SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_pg);
- if (Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false))
- CmdArgs.push_back("-faddress-sanitizer");
-
- if (Args.hasFlag(options::OPT_fthread_sanitizer,
- options::OPT_fno_thread_sanitizer, false))
- CmdArgs.push_back("-fthread-sanitizer");
-
// -flax-vector-conversions is default.
if (!Args.hasFlag(options::OPT_flax_vector_conversions,
options::OPT_fno_lax_vector_conversions))
@@ -2317,7 +2484,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
CmdArgs.push_back("-ftrapv-handler");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
@@ -2338,6 +2505,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_pthread);
+
// -stack-protector=0 is default.
unsigned StackProtectorLevel = 0;
if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
@@ -2356,6 +2524,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
}
+ // --param ssp-buffer-size=
+ for (arg_iterator it = Args.filtered_begin(options::OPT__param),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ StringRef Str((*it)->getValue());
+ if (Str.startswith("ssp-buffer-size=")) {
+ if (StackProtectorLevel) {
+ CmdArgs.push_back("-stack-protector-buffer-size");
+ // FIXME: Verify the argument is a valid integer.
+ CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
+ }
+ (*it)->claim();
+ }
+ }
+
// Translate -mstackrealign
if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
false)) {
@@ -2371,6 +2553,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
}
+ if (Args.hasArg(options::OPT_mstrict_align)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-strict-align");
+ }
// Forward -f options with positive and negative forms; we translate
// these by hand.
@@ -2428,9 +2614,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -frtti is default.
if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
- KernelOrKext)
+ KernelOrKext) {
CmdArgs.push_back("-fno-rtti");
+ // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
+ if (Sanitize.sanitizesVptr()) {
+ std::string NoRttiArg =
+ Args.getLastArg(options::OPT_mkernel,
+ options::OPT_fapple_kext,
+ options::OPT_fno_rtti)->getAsString(Args);
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fsanitize=vptr" << NoRttiArg;
+ }
+ }
+
// -fshort-enums=0 is default for all architectures except Hexagon.
if (Args.hasFlag(options::OPT_fshort_enums,
options::OPT_fno_short_enums,
@@ -2538,12 +2735,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fobjc-default-synthesize-properties");
}
+ // -fencode-extended-block-signature=1 is default.
+ if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
+ CmdArgs.push_back("-fencode-extended-block-signature");
+ }
+
// Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
// NOTE: This logic is duplicated in ToolChains.cpp.
bool ARC = isObjCAutoRefCount(Args);
if (ARC) {
- if (!getToolChain().SupportsObjCARC())
- D.Diag(diag::err_arc_unsupported);
+ getToolChain().CheckObjCARC();
CmdArgs.push_back("-fobjc-arc");
@@ -2630,7 +2831,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fno-pack-struct doesn't apply to -fpack-struct=.
if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
std::string PackStructStr = "-fpack-struct=";
- PackStructStr += A->getValue(Args);
+ PackStructStr += A->getValue();
CmdArgs.push_back(Args.MakeArgString(PackStructStr));
} else if (Args.hasFlag(options::OPT_fpack_struct,
options::OPT_fno_pack_struct, false)) {
@@ -2679,13 +2880,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (const Arg *A =
Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
CmdArgs.push_back("-fdiagnostics-show-category");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (const Arg *A =
Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(
@@ -2777,9 +2978,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Handle serialized diagnostics.
if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
CmdArgs.push_back("-serialize-diagnostic-file");
- CmdArgs.push_back(Args.MakeArgString(A->getValue(Args)));
+ CmdArgs.push_back(Args.MakeArgString(A->getValue()));
}
+ if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
+ CmdArgs.push_back("-fretain-comments-from-system-headers");
+
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
// parser.
Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
@@ -2789,7 +2993,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// We translate this by hand to the -cc1 argument, since nightly test uses
// it and developers have been trained to spell it with -mllvm.
- if (StringRef((*it)->getValue(Args, 0)) == "-disable-llvm-optzns")
+ if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns")
CmdArgs.push_back("-disable-llvm-optzns");
else
(*it)->render(Args, CmdArgs);
@@ -2808,7 +3012,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
CmdArgs.push_back("-x");
- CmdArgs.push_back(types::getTypeName(II.getType()));
+ if (Args.hasArg(options::OPT_rewrite_objc))
+ CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
+ else
+ CmdArgs.push_back(types::getTypeName(II.getType()));
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
@@ -2895,7 +3102,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
if (runtimeArg &&
runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
ObjCRuntime runtime;
- StringRef value = runtimeArg->getValue(args);
+ StringRef value = runtimeArg->getValue();
if (runtime.tryParse(value)) {
getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
<< value;
@@ -2913,7 +3120,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
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);
+ StringRef value = abiArg->getValue();
if (value == "1")
objcABIVersion = 1;
else if (value == "2")
@@ -2941,7 +3148,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
if (Arg *abiArg = args.getLastArg(
options::OPT_fobjc_nonfragile_abi_version_EQ)) {
- StringRef value = abiArg->getValue(args);
+ StringRef value = abiArg->getValue();
if (value == "1")
nonFragileABIVersion = 1;
else if (value == "2")
@@ -2994,7 +3201,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
// 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());
+ runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
else
runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
}
@@ -3117,7 +3324,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
for (ArgList::const_iterator
it = Args.begin(), ie = Args.end(); it != ie; ++it) {
Arg *A = *it;
- if (A->getOption().hasForwardToGCC()) {
+ if (forwardToGCC(A->getOption())) {
// Don't forward any -g arguments to assembly steps.
if (isa<AssembleJobAction>(JA) &&
A->getOption().matches(options::OPT_g_Group))
@@ -3135,17 +3342,17 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
RenderExtraToolArgs(JA, CmdArgs);
// If using a driver driver, force the arch.
- const std::string &Arch = getToolChain().getArchName();
+ llvm::Triple::ArchType Arch = getToolChain().getArch();
if (getToolChain().getTriple().isOSDarwin()) {
CmdArgs.push_back("-arch");
// FIXME: Remove these special cases.
- if (Arch == "powerpc")
+ if (Arch == llvm::Triple::ppc)
CmdArgs.push_back("ppc");
- else if (Arch == "powerpc64")
+ else if (Arch == llvm::Triple::ppc64)
CmdArgs.push_back("ppc64");
else
- CmdArgs.push_back(Args.MakeArgString(Arch));
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
}
// Try to force gcc to match the tool chain we want, if we recognize
@@ -3153,9 +3360,9 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
//
// FIXME: The triple class should directly provide the information we want
// here.
- if (Arch == "i386" || Arch == "powerpc")
+ if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
CmdArgs.push_back("-m32");
- else if (Arch == "x86_64" || Arch == "powerpc64")
+ else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86_64)
CmdArgs.push_back("-m64");
if (Output.isFilename()) {
@@ -3342,7 +3549,7 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
for (ArgList::const_iterator
it = Args.begin(), ie = Args.end(); it != ie; ++it) {
Arg *A = *it;
- if (A->getOption().hasForwardToGCC()) {
+ if (forwardToGCC(A->getOption())) {
// Don't forward any -g arguments to assembly steps.
if (isa<AssembleJobAction>(JA) &&
A->getOption().matches(options::OPT_g_Group))
@@ -3410,6 +3617,37 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
// Hexagon tools end.
+llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
+ // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
+ // archs which Darwin doesn't use.
+
+ // The matching this routine does is fairly pointless, since it is neither the
+ // complete architecture list, nor a reasonable subset. The problem is that
+ // historically the driver driver accepts this and also ties its -march=
+ // handling to the architecture name, so we need to be careful before removing
+ // support for it.
+
+ // This code must be kept in sync with Clang's Darwin specific argument
+ // translation.
+
+ return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
+ .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
+ .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
+ .Case("ppc64", llvm::Triple::ppc64)
+ .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
+ .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
+ llvm::Triple::x86)
+ .Case("x86_64", llvm::Triple::x86_64)
+ // This is derived from the driver driver.
+ .Cases("arm", "armv4t", "armv5", "armv6", llvm::Triple::arm)
+ .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", llvm::Triple::arm)
+ .Case("r600", llvm::Triple::r600)
+ .Case("nvptx", llvm::Triple::nvptx)
+ .Case("nvptx64", llvm::Triple::nvptx64)
+ .Case("amdil", llvm::Triple::amdil)
+ .Case("spir", llvm::Triple::spir)
+ .Default(llvm::Triple::UnknownArch);
+}
const char *darwin::CC1::getCC1Name(types::ID Type) const {
switch (Type) {
@@ -3458,7 +3696,7 @@ darwin::CC1::getDependencyFileName(const ArgList &Args,
std::string Res;
if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
- std::string Str(OutputOpt->getValue(Args));
+ std::string Str(OutputOpt->getValue());
Res = Str.substr(0, Str.rfind('.'));
} else {
Res = darwin::CC1::getBaseInputStem(Args, Inputs);
@@ -3547,6 +3785,7 @@ void darwin::CC1::RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const {
.Case("duplicate-method-arg", true)
.Case("dynamic-class-memaccess", true)
.Case("enum-compare", true)
+ .Case("enum-conversion", true)
.Case("exit-time-destructors", true)
.Case("gnu", true)
.Case("gnu-designator", true)
@@ -3556,6 +3795,7 @@ void darwin::CC1::RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const {
.Case("implicit-atomic-properties", true)
.Case("incompatible-pointer-types", true)
.Case("incomplete-implementation", true)
+ .Case("int-conversion", true)
.Case("initializer-overrides", true)
.Case("invalid-noreturn", true)
.Case("invalid-token-paste", true)
@@ -3620,7 +3860,10 @@ void darwin::CC1::AddCC1Args(const ArgList &Args,
CheckCodeGenerationOptions(D, Args);
// Derived from cc1 spec.
- if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
+ if ((!Args.hasArg(options::OPT_mkernel) ||
+ (getDarwinToolChain().isTargetIPhoneOS() &&
+ !getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) &&
+ !Args.hasArg(options::OPT_static) &&
!Args.hasArg(options::OPT_mdynamic_no_pic))
CmdArgs.push_back("-fPIC");
@@ -3673,7 +3916,7 @@ void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
Args.hasArg(options::OPT_o)) {
Arg *OutputOpt = Args.getLastArg(options::OPT_o);
CmdArgs.push_back("-auxbase-strip");
- CmdArgs.push_back(OutputOpt->getValue(Args));
+ CmdArgs.push_back(OutputOpt->getValue());
} else {
CmdArgs.push_back("-auxbase");
CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
@@ -3812,7 +4055,7 @@ void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
Args.AddLastArg(CmdArgs, options::OPT_P);
// FIXME: Handle %I properly.
- if (getToolChain().getArchName() == "x86_64") {
+ if (getToolChain().getArch() == llvm::Triple::x86_64) {
CmdArgs.push_back("-imultilib");
CmdArgs.push_back("x86_64");
}
@@ -3838,7 +4081,7 @@ void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
(Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
CmdArgs.push_back("-MQ");
- CmdArgs.push_back(OutputOpt->getValue(Args));
+ CmdArgs.push_back(OutputOpt->getValue());
}
}
@@ -4074,9 +4317,11 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-force_cpusubtype_ALL");
if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
- (Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_fapple_kext)))
+ (((Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_fapple_kext)) &&
+ (!getDarwinToolChain().isTargetIPhoneOS() ||
+ getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
+ Args.hasArg(options::OPT_static)))
CmdArgs.push_back("-static");
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -4111,16 +4356,29 @@ void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
CmdArgs.push_back("-force_cpusubtype_ALL");
}
+bool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const {
+ // We only need to generate a temp path for LTO if we aren't compiling object
+ // files. When compiling source files, we run 'dsymutil' after linking. We
+ // don't run 'dsymutil' when compiling object files.
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
+ if (it->getType() != types::TY_Object)
+ return true;
+
+ return false;
+}
+
void darwin::Link::AddLinkArgs(Compilation &C,
const ArgList &Args,
- ArgStringList &CmdArgs) const {
+ ArgStringList &CmdArgs,
+ const InputInfoList &Inputs) const {
const Driver &D = getToolChain().getDriver();
const toolchains::Darwin &DarwinTC = getDarwinToolChain();
unsigned Version[3] = { 0, 0, 0 };
if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
bool HadExtra;
- if (!Driver::GetReleaseVersion(A->getValue(Args), Version[0],
+ if (!Driver::GetReleaseVersion(A->getValue(), Version[0],
Version[1], Version[2], HadExtra) ||
HadExtra)
D.Diag(diag::err_drv_invalid_version_number)
@@ -4141,7 +4399,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
ie = Args.filtered_end(); it != ie; ++it) {
const Arg *A = *it;
for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
- if (StringRef(A->getValue(Args, i)) == "-kext")
+ if (StringRef(A->getValue(i)) == "-kext")
UsesLdClassic = true;
}
}
@@ -4152,7 +4410,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
// If we are using LTO, then automatically create a temporary file path for
// the linker to use, so that it's lifetime will extend past a possible
// dsymutil step.
- if (Version[0] >= 116 && D.IsUsingLTO(Args)) {
+ if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
const char *TmpPath = C.getArgs().MakeArgString(
D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
C.addTempFile(TmpPath);
@@ -4287,7 +4545,7 @@ void darwin::Link::AddLinkArgs(Compilation &C,
CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
} else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
CmdArgs.push_back("-syslibroot");
- CmdArgs.push_back(A->getValue(Args));
+ CmdArgs.push_back(A->getValue());
}
Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
@@ -4339,7 +4597,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
// I'm not sure why this particular decomposition exists in gcc, but
// we follow suite for ease of comparison.
- AddLinkArgs(C, Args, CmdArgs);
+ AddLinkArgs(C, Args, CmdArgs, Inputs);
Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_s);
@@ -4424,7 +4682,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
} else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-lcrt1.o");
- else
+ else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
CmdArgs.push_back("-lcrt1.3.1.o");
} else {
if (getDarwinToolChain().isMacosxVersionLT(10, 5))
@@ -4452,11 +4710,12 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
- // If we're building a dynamic lib with -faddress-sanitizer, unresolved
- // symbols may appear. Mark all of them as dynamic_lookup.
- // Linking executables is handled in lib/Driver/ToolChains.cpp.
- if (Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false)) {
+ SanitizerArgs Sanitize(getToolChain().getDriver(), Args);
+ // If we're building a dynamic lib with -fsanitize=address, or
+ // -fsanitize=undefined, unresolved symbols may appear. Mark all
+ // of them as dynamic_lookup. Linking executables is handled in
+ // lib/Driver/ToolChains.cpp.
+ if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) {
CmdArgs.push_back("-undefined");
@@ -4475,14 +4734,14 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
!Args.hasArg(options::OPT_nodefaultlibs)) {
// Avoid linking compatibility stubs on i386 mac.
if (!getDarwinToolChain().isTargetMacOS() ||
- getDarwinToolChain().getArchName() != "i386") {
+ getDarwinToolChain().getArch() != llvm::Triple::x86) {
// 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().getDefaultObjCRuntime(/*nonfragile*/ true);
// We use arclite library for both ARC and subscripting support.
- if ((!runtime.hasARC() && isObjCAutoRefCount(Args)) ||
+ if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
!runtime.hasSubscripting())
getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
}
@@ -4938,14 +5197,21 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
// the default system libraries. Just mimic this for now.
CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
+ if (Args.hasArg(options::OPT_pthread)) {
+ if (!Args.hasArg(options::OPT_shared) &&
+ Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back("-lpthread_p");
+ else
+ CmdArgs.push_back("-lpthread");
+ }
+
if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
+ if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lc_p");
else
CmdArgs.push_back("-lc");
}
+
CmdArgs.push_back("-lgcc");
}
@@ -5057,8 +5323,14 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lm");
}
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
+ if (Args.hasArg(options::OPT_pthread)) {
+ if (!Args.hasArg(options::OPT_shared) &&
+ Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back("-lpthread_p");
+ else
+ CmdArgs.push_back("-lpthread");
+ }
+
if (!Args.hasArg(options::OPT_shared)) {
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lc_p");
@@ -5109,17 +5381,48 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
// When building 32-bit code on FreeBSD/amd64, we have to explicitly
// instruct as in the base system to assemble 32-bit code.
- if (getToolChain().getArchName() == "i386")
+ if (getToolChain().getArch() == llvm::Triple::x86)
CmdArgs.push_back("--32");
-
- if (getToolChain().getArchName() == "powerpc")
+ else if (getToolChain().getArch() == llvm::Triple::ppc)
CmdArgs.push_back("-a32");
+ else if (getToolChain().getArch() == llvm::Triple::mips ||
+ getToolChain().getArch() == llvm::Triple::mipsel ||
+ getToolChain().getArch() == llvm::Triple::mips64 ||
+ getToolChain().getArch() == llvm::Triple::mips64el) {
+ StringRef CPUName;
+ StringRef ABIName;
+ getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
- // Set byte order explicitly
- if (getToolChain().getArchName() == "mips")
- CmdArgs.push_back("-EB");
- else if (getToolChain().getArchName() == "mipsel")
- CmdArgs.push_back("-EL");
+ CmdArgs.push_back("-march");
+ CmdArgs.push_back(CPUName.data());
+
+ // Convert ABI name to the GNU tools acceptable variant.
+ if (ABIName == "o32")
+ ABIName = "32";
+ else if (ABIName == "n64")
+ ABIName = "64";
+
+ CmdArgs.push_back("-mabi");
+ CmdArgs.push_back(ABIName.data());
+
+ if (getToolChain().getArch() == llvm::Triple::mips ||
+ getToolChain().getArch() == llvm::Triple::mips64)
+ CmdArgs.push_back("-EB");
+ else
+ CmdArgs.push_back("-EL");
+
+ 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);
@@ -5143,7 +5446,9 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
+ const toolchains::FreeBSD& ToolChain =
+ static_cast<const toolchains::FreeBSD&>(getToolChain());
+ const Driver &D = ToolChain.getDriver();
ArgStringList CmdArgs;
// Silence warning for "clang -g foo.o -o foo"
@@ -5157,6 +5462,9 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+ if (Args.hasArg(options::OPT_pie))
+ CmdArgs.push_back("-pie");
+
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
@@ -5169,8 +5477,8 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/libexec/ld-elf.so.1");
}
- if (getToolChain().getTriple().getOSMajorVersion() >= 9) {
- llvm::Triple::ArchType Arch = getToolChain().getArch();
+ if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
+ llvm::Triple::ArchType Arch = ToolChain.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");
@@ -5181,12 +5489,12 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
// When building 32-bit code on FreeBSD/amd64, we have to explicitly
// instruct ld in the base system to link 32-bit code.
- if (getToolChain().getArchName() == "i386") {
+ if (ToolChain.getArch() == llvm::Triple::x86) {
CmdArgs.push_back("-m");
CmdArgs.push_back("elf_i386_fbsd");
}
- if (getToolChain().getArchName() == "powerpc") {
+ if (ToolChain.getArch() == llvm::Triple::ppc) {
CmdArgs.push_back("-m");
CmdArgs.push_back("elf32ppc_fbsd");
}
@@ -5200,29 +5508,33 @@ void freebsd::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_pg))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("gcrt1.o")));
- else {
- const char *crt = Args.hasArg(options::OPT_pie) ? "Scrt1.o" : "crt1.o";
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath(crt)));
- }
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbeginS.o")));
+ crt1 = "gcrt1.o";
+ else 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")));
+
+ const char *crtbegin = NULL;
+ if (Args.hasArg(options::OPT_static))
+ crtbegin = "crtbeginT.o";
+ else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+ crtbegin = "crtbeginS.o";
+ else
+ crtbegin = "crtbegin.o";
+
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
- const ToolChain::path_list Paths = getToolChain().getFilePaths();
+ const ToolChain::path_list Paths = ToolChain.getFilePaths();
for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
i != e; ++i)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
@@ -5233,12 +5545,12 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_r);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+ ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lm_p");
else
@@ -5291,20 +5603,17 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtend.o")));
+ if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
else
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtendS.o")));
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtn.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+ addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(ToolChain.GetProgramPath("ld"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5321,9 +5630,9 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("--32");
// Set byte order explicitly
- if (getToolChain().getArchName() == "mips")
+ if (getToolChain().getArch() == llvm::Triple::mips)
CmdArgs.push_back("-EB");
- else if (getToolChain().getArchName() == "mipsel")
+ else if (getToolChain().getArch() == llvm::Triple::mipsel)
CmdArgs.push_back("-EL");
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -5548,7 +5857,7 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
static void AddLibgcc(llvm::Triple Triple, const Driver &D,
ArgStringList &CmdArgs, const ArgList &Args) {
- bool isAndroid = Triple.getEnvironment() == llvm::Triple::ANDROIDEABI;
+ bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
bool StaticLibgcc = isAndroid || Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_static_libgcc);
if (!D.CCCIsCXX)
@@ -5571,6 +5880,11 @@ static void AddLibgcc(llvm::Triple Triple, const Driver &D,
CmdArgs.push_back("-lgcc");
}
+static bool hasMipsN32ABIArg(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
+ return A && (A->getValue() == StringRef("n32"));
+}
+
void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -5579,8 +5893,8 @@ 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;
+ const bool isAndroid =
+ ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
ArgStringList CmdArgs;
@@ -5627,10 +5941,18 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("elf32btsmip");
else if (ToolChain.getArch() == llvm::Triple::mipsel)
CmdArgs.push_back("elf32ltsmip");
- else if (ToolChain.getArch() == llvm::Triple::mips64)
- CmdArgs.push_back("elf64btsmip");
- else if (ToolChain.getArch() == llvm::Triple::mips64el)
- CmdArgs.push_back("elf64ltsmip");
+ else if (ToolChain.getArch() == llvm::Triple::mips64) {
+ if (hasMipsN32ABIArg(Args))
+ CmdArgs.push_back("elf32btsmipn32");
+ else
+ CmdArgs.push_back("elf64btsmip");
+ }
+ else if (ToolChain.getArch() == llvm::Triple::mips64el) {
+ if (hasMipsN32ABIArg(Args))
+ CmdArgs.push_back("elf32ltsmipn32");
+ else
+ CmdArgs.push_back("elf64ltsmip");
+ }
else
CmdArgs.push_back("elf_x86_64");
@@ -5642,8 +5964,7 @@ 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) {
+ if (isAndroid) {
CmdArgs.push_back("-Bsymbolic");
}
}
@@ -5668,8 +5989,12 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
ToolChain.getArch() == llvm::Triple::mipsel)
CmdArgs.push_back("/lib/ld.so.1");
else if (ToolChain.getArch() == llvm::Triple::mips64 ||
- ToolChain.getArch() == llvm::Triple::mips64el)
- CmdArgs.push_back("/lib64/ld.so.1");
+ ToolChain.getArch() == llvm::Triple::mips64el) {
+ if (hasMipsN32ABIArg(Args))
+ CmdArgs.push_back("/lib32/ld.so.1");
+ else
+ CmdArgs.push_back("/lib64/ld.so.1");
+ }
else if (ToolChain.getArch() == llvm::Triple::ppc)
CmdArgs.push_back("/lib/ld.so.1");
else if (ToolChain.getArch() == llvm::Triple::ppc64)
@@ -5700,11 +6025,16 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *crtbegin;
if (Args.hasArg(options::OPT_static))
crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
- else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+ else if (Args.hasArg(options::OPT_shared))
crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
+ else if (Args.hasArg(options::OPT_pie))
+ crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
else
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+
+ // Add crtfastmath.o if available and fast math is enabled.
+ ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
@@ -5729,6 +6059,12 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ SanitizerArgs Sanitize(D, Args);
+
+ // Call this before we add the C++ ABI library.
+ if (Sanitize.needsUbsanRt())
+ addUbsanRTLinux(getToolChain(), Args, CmdArgs);
+
if (D.CCCIsCXX &&
!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -5743,8 +6079,10 @@ 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 (Sanitize.needsAsanRt())
+ addAsanRTLinux(getToolChain(), Args, CmdArgs);
+ if (Sanitize.needsTsanRt())
+ addTsanRTLinux(getToolChain(), Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib)) {
if (!Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -5767,8 +6105,10 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostartfiles)) {
const char *crtend;
- if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+ if (Args.hasArg(options::OPT_shared))
crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
+ else if (Args.hasArg(options::OPT_pie))
+ crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
else
crtend = isAndroid ? "crtend_android.o" : "crtend.o";
@@ -5874,7 +6214,7 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
// When building 32-bit code on DragonFly/pc64, we have to explicitly
// instruct as in the base system to assemble 32-bit code.
- if (getToolChain().getArchName() == "i386")
+ if (getToolChain().getArch() == llvm::Triple::x86)
CmdArgs.push_back("--32");
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -5918,7 +6258,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
// When building 32-bit code on DragonFly/pc64, we have to explicitly
// instruct ld in the base system to link 32-bit code.
- if (getToolChain().getArchName() == "i386") {
+ if (getToolChain().getArch() == llvm::Triple::x86) {
CmdArgs.push_back("-m");
CmdArgs.push_back("elf_i386");
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h
index 999c57a..5898c66 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.h
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h
@@ -202,6 +202,8 @@ namespace hexagon {
namespace darwin {
+ llvm::Triple::ArchType getArchTypeForDarwinArchName(StringRef Str);
+
class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool {
virtual void anchor();
protected:
@@ -288,8 +290,9 @@ namespace darwin {
};
class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool {
+ bool NeedsTempPath(const InputInfoList &Inputs) const;
void AddLinkArgs(Compilation &C, const ArgList &Args,
- ArgStringList &CmdArgs) const;
+ ArgStringList &CmdArgs, const InputInfoList &Inputs) const;
public:
Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {}
diff --git a/contrib/llvm/tools/clang/lib/Driver/Types.cpp b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
index 9d8fcfd..862025e 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Types.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
@@ -94,20 +94,6 @@ bool types::isAcceptedByClang(ID Id) {
}
}
-bool types::isOnlyAcceptedByClang(ID Id) {
- switch (Id) {
- default:
- return false;
-
- case TY_AST:
- case TY_LLVM_IR:
- case TY_LLVM_BC:
- case TY_RewrittenObjC:
- case TY_RewrittenLegacyObjC:
- return true;
- }
-}
-
bool types::isObjC(ID Id) {
switch (Id) {
default:
diff --git a/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
index 6827034..de2d535 100644
--- a/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
@@ -81,19 +81,15 @@ bool Windows::IsIntegratedAssemblerDefault() const {
}
bool Windows::IsUnwindTablesDefault() const {
- // FIXME: Gross; we should probably have some separate target
- // definition, possibly even reusing the one in clang.
- return getArchName() == "x86_64";
+ return getArch() == llvm::Triple::x86_64;
}
-const char *Windows::GetDefaultRelocationModel() const {
- return "static";
+bool Windows::isPICDefault() const {
+ return getArch() == llvm::Triple::x86_64;
}
-const char *Windows::GetForcedPicModel() const {
- if (getArchName() == "x86_64")
- return "pic";
- return 0;
+bool Windows::isPICDefaultForced() const {
+ return getArch() == llvm::Triple::x86_64;
}
// FIXME: This probably should goto to some platform utils place.
OpenPOWER on IntegriCloud