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/Action.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ArgList.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Compilation.cpp128
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Driver.cpp247
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/InputInfo.h2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Job.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/OptTable.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Option.cpp7
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Phases.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h130
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp100
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp918
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.h171
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp1757
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.h89
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Types.cpp76
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp60
18 files changed, 1888 insertions, 1815 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Action.cpp b/contrib/llvm/tools/clang/lib/Driver/Action.cpp
index d7b4bc7..2b5bbee 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Action.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Action.cpp
@@ -9,7 +9,6 @@
#include "clang/Driver/Action.h"
#include "llvm/Support/ErrorHandling.h"
-
#include <cassert>
using namespace clang::driver;
diff --git a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
index b3a43df..6c57b62 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ArgList.cpp
@@ -11,7 +11,6 @@
#include "clang/Driver/Arg.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Option.h"
-
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
@@ -84,7 +83,6 @@ Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
(*it)->getOption().matches(Id1)) {
Res = *it;
Res->claim();
-
}
}
@@ -308,6 +306,14 @@ const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
return MakeArgString(LHS + RHS);
}
+void ArgList::dump() {
+ llvm::errs() << "ArgList:";
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ llvm::errs() << " " << (*it)->getSpelling();
+ }
+ llvm::errs() << "\n";
+}
+
//
InputArgList::InputArgList(const char* const *ArgBegin,
diff --git a/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp b/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
index 4f89b73..9048043 100644
--- a/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/CC1AsOptions.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/CC1AsOptions.h"
-#include "clang/Driver/Option.h"
#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
using namespace clang;
using namespace clang::driver;
using namespace clang::driver::options;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
index 124e50c..1bff4a3 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp
@@ -8,20 +8,18 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Compilation.h"
-
#include "clang/Driver/Action.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#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>
+#include "llvm/Support/raw_ostream.h"
#include <errno.h>
+#include <sys/stat.h>
using namespace clang::driver;
using namespace clang;
@@ -113,7 +111,7 @@ static bool skipArg(const char *Flag, bool &SkipNextArg) {
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("-fdebug-compilation-dir", "-idirafter", true)
.Cases("-include", "-include-pch", "-internal-isystem", true)
.Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
.Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
@@ -201,39 +199,56 @@ void Compilation::PrintDiagnosticJob(raw_ostream &OS, const Job &J) const {
}
}
+bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
+ llvm::sys::Path P(File);
+ std::string Error;
+
+ // Don't try to remove files which we don't have write access to (but may be
+ // able to remove), or non-regular files. Underlying tools may have
+ // intentionally not overwritten them.
+ if (!P.canWrite() || !P.isRegularFile())
+ return true;
+
+ if (P.eraseFromDisk(false, &Error)) {
+ // Failure is only failure if the file exists and is "regular". There is
+ // a race condition here due to the limited interface of
+ // llvm::sys::Path, we want to know if the removal gave ENOENT.
+
+ // FIXME: Grumble, P.exists() is broken. PR3837.
+ struct stat buf;
+ if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
+ (errno != ENOENT)) {
+ if (IssueErrors)
+ getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
+ << Error;
+ return false;
+ }
+ }
+ return true;
+}
+
bool Compilation::CleanupFileList(const ArgStringList &Files,
bool IssueErrors) const {
bool Success = true;
-
for (ArgStringList::const_iterator
- it = Files.begin(), ie = Files.end(); it != ie; ++it) {
+ it = Files.begin(), ie = Files.end(); it != ie; ++it)
+ Success &= CleanupFile(*it, IssueErrors);
+ return Success;
+}
- llvm::sys::Path P(*it);
- std::string Error;
+bool Compilation::CleanupFileMap(const ArgStringMap &Files,
+ const JobAction *JA,
+ bool IssueErrors) const {
+ bool Success = true;
+ for (ArgStringMap::const_iterator
+ it = Files.begin(), ie = Files.end(); it != ie; ++it) {
- // Don't try to remove files which we don't have write access to (but may be
- // able to remove). Underlying tools may have intentionally not overwritten
- // them.
- if (!P.canWrite())
+ // If specified, only delete the files associated with the JobAction.
+ // Otherwise, delete all files in the map.
+ if (JA && it->first != JA)
continue;
-
- if (P.eraseFromDisk(false, &Error)) {
- // Failure is only failure if the file exists and is "regular". There is
- // a race condition here due to the limited interface of
- // llvm::sys::Path, we want to know if the removal gave ENOENT.
-
- // FIXME: Grumble, P.exists() is broken. PR3837.
- struct stat buf;
- if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
- (errno != ENOENT)) {
- if (IssueErrors)
- getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
- << Error;
- Success = false;
- }
- }
+ Success &= CleanupFile(it->second, IssueErrors);
}
-
return Success;
}
@@ -275,11 +290,12 @@ int Compilation::ExecuteCommand(const Command &C,
}
std::string Error;
+ bool ExecutionFailed;
int Res =
llvm::sys::Program::ExecuteAndWait(Prog, Argv,
/*env*/0, Redirects,
/*secondsToWait*/0, /*memoryLimit*/0,
- &Error);
+ &Error, &ExecutionFailed);
if (!Error.empty()) {
assert(Res && "Error string set with 0 result code!");
getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
@@ -289,24 +305,51 @@ int Compilation::ExecuteCommand(const Command &C,
FailingCommand = &C;
delete[] Argv;
- return Res;
+ return ExecutionFailed ? 1 : Res;
+}
+
+typedef SmallVectorImpl< std::pair<int, const Command *> > FailingCommandList;
+
+static bool ActionFailed(const Action *A,
+ const FailingCommandList &FailingCommands) {
+
+ if (FailingCommands.empty())
+ return false;
+
+ for (FailingCommandList::const_iterator CI = FailingCommands.begin(),
+ CE = FailingCommands.end(); CI != CE; ++CI)
+ if (A == &(CI->second->getSource()))
+ return true;
+
+ for (Action::const_iterator AI = A->begin(), AE = A->end(); AI != AE; ++AI)
+ if (ActionFailed(*AI, FailingCommands))
+ return true;
+
+ return false;
}
-int Compilation::ExecuteJob(const Job &J,
- const Command *&FailingCommand) const {
+static bool InputsOk(const Command &C,
+ const FailingCommandList &FailingCommands) {
+ return !ActionFailed(&C.getSource(), FailingCommands);
+}
+
+void Compilation::ExecuteJob(const Job &J,
+ FailingCommandList &FailingCommands) const {
if (const Command *C = dyn_cast<Command>(&J)) {
- return ExecuteCommand(*C, FailingCommand);
+ if (!InputsOk(*C, FailingCommands))
+ return;
+ const Command *FailingCommand = 0;
+ if (int Res = ExecuteCommand(*C, FailingCommand))
+ FailingCommands.push_back(std::make_pair(Res, FailingCommand));
} else {
const JobList *Jobs = cast<JobList>(&J);
- for (JobList::const_iterator
- it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
- if (int Res = ExecuteJob(**it, FailingCommand))
- return Res;
- return 0;
+ for (JobList::const_iterator it = Jobs->begin(), ie = Jobs->end();
+ it != ie; ++it)
+ ExecuteJob(**it, FailingCommands);
}
}
-void Compilation::initCompilationForDiagnostics(void) {
+void Compilation::initCompilationForDiagnostics() {
// Free actions and jobs.
DeleteContainerPointers(Actions);
Jobs.clear();
@@ -314,6 +357,7 @@ void Compilation::initCompilationForDiagnostics(void) {
// Clear temporary/results file lists.
TempFiles.clear();
ResultFiles.clear();
+ FailureResultFiles.clear();
// Remove any user specified output. Claim any unclaimed arguments, so as
// to avoid emitting warnings about unused args.
@@ -331,6 +375,6 @@ void Compilation::initCompilationForDiagnostics(void) {
Redirects[2] = new const llvm::sys::Path();
}
-StringRef Compilation::getSysRoot(void) const {
+StringRef Compilation::getSysRoot() const {
return getDriver().SysRoot;
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
index 3c410bb..6af03bd 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Driver.h"
-
+#include "InputInfo.h"
+#include "ToolChains.h"
+#include "clang/Basic/Version.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
@@ -20,24 +22,20 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
-
-#include "clang/Basic/Version.h"
-
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
-
-#include "InputInfo.h"
-#include "ToolChains.h"
-
+#include "llvm/Support/raw_ostream.h"
#include <map>
+// FIXME: It would prevent us from including llvm-config.h
+// if config.h were included before system_error.h.
#include "clang/Config/config.h"
using namespace clang::driver;
@@ -46,7 +44,6 @@ using namespace clang;
Driver::Driver(StringRef ClangExecutable,
StringRef DefaultTargetTriple,
StringRef DefaultImageName,
- bool IsProduction,
DiagnosticsEngine &Diags)
: Opts(createDriverOptTable()), Diags(Diags),
ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
@@ -129,6 +126,7 @@ const {
// -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
+ (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
@@ -242,7 +240,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
if (char *env = ::getenv("COMPILER_PATH")) {
StringRef CompilerPath = env;
while (!CompilerPath.empty()) {
- std::pair<StringRef, StringRef> Split = CompilerPath.split(':');
+ std::pair<StringRef, StringRef> Split
+ = CompilerPath.split(llvm::sys::PathSeparator);
PrefixDirs.push_back(Split.first);
CompilerPath = Split.second;
}
@@ -251,7 +250,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// FIXME: What are we going to do with -V and -b?
// FIXME: This stuff needs to go into the Compilation, not the driver.
- bool CCCPrintOptions = false, CCCPrintActions = false;
+ bool CCCPrintOptions, CCCPrintActions;
InputArgList *Args = ParseArgStrings(ArgList.slice(1));
@@ -293,6 +292,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
if (Args->hasArg(options::OPT_nostdlib))
UseStdLib = false;
+ if (const Arg *A = Args->getLastArg(options::OPT_resource_dir))
+ ResourceDir = A->getValue();
+
// Perform the default argument translations.
DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args);
@@ -342,8 +344,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
return;
- // Don't try to generate diagnostics for link jobs.
- if (FailingCommand && FailingCommand->getCreator().isLinkJob())
+ // Don't try to generate diagnostics for link or dsymutil jobs.
+ if (FailingCommand && (FailingCommand->getCreator().isLinkJob() ||
+ FailingCommand->getCreator().isDsymutilJob()))
return;
// Print the version of the compiler.
@@ -369,9 +372,12 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
C.PrintDiagnosticJob(OS, C.getJobs());
OS.flush();
- // Clear stale state and suppress tool output.
+ // Keep track of whether we produce any errors while trying to produce
+ // preprocessed sources.
+ DiagnosticErrorTrap Trap(Diags);
+
+ // Suppress tool output.
C.initCompilationForDiagnostics();
- Diags.Reset();
// Construct the list of inputs.
InputList Inputs;
@@ -398,6 +404,12 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
}
}
+ if (Inputs.empty()) {
+ Diag(clang::diag::note_drv_command_failed_diag_msg)
+ << "Error generating preprocessed source(s) - no preprocessable inputs.";
+ return;
+ }
+
// Don't attempt to generate preprocessed files if multiple -arch options are
// used, unless they're all duplicates.
llvm::StringSet<> ArchNames;
@@ -416,12 +428,6 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
return;
}
- if (Inputs.empty()) {
- Diag(clang::diag::note_drv_command_failed_diag_msg)
- << "Error generating preprocessed source(s) - no preprocessable inputs.";
- return;
- }
-
// Construct the list of abstract actions to perform for this compilation. On
// Darwin OSes this uses the driver-driver and builds universal actions.
const ToolChain &TC = C.getDefaultToolChain();
@@ -433,18 +439,18 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
BuildJobs(C);
// If there were errors building the compilation, quit now.
- if (Diags.hasErrorOccurred()) {
+ if (Trap.hasErrorOccurred()) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating preprocessed source(s).";
return;
}
// Generate preprocessed output.
- FailingCommand = 0;
- int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+ SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
+ C.ExecuteJob(C.getJobs(), FailingCommands);
// If the command succeeded, we are done.
- if (Res == 0) {
+ if (FailingCommands.empty()) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "\n********************\n\n"
"PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
@@ -485,8 +491,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
<< "\n\n********************";
} else {
// Failure, remove preprocessed files.
- if (!C.getArgs().hasArg(options::OPT_save_temps))
+ if (!C.getArgs().hasArg(options::OPT_save_temps)) {
C.CleanupFileList(C.getTempFiles(), true);
+ }
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating preprocessed source(s).";
@@ -494,7 +501,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
}
int Driver::ExecuteCompilation(const Compilation &C,
- const Command *&FailingCommand) const {
+ SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const {
// Just print if -### was present.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
@@ -505,44 +512,52 @@ int Driver::ExecuteCompilation(const Compilation &C,
if (Diags.hasErrorOccurred())
return 1;
- int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+ C.ExecuteJob(C.getJobs(), FailingCommands);
// Remove temp files.
C.CleanupFileList(C.getTempFiles());
// If the command succeeded, we are done.
- if (Res == 0)
- return Res;
-
- // Otherwise, remove result files as well.
- if (!C.getArgs().hasArg(options::OPT_save_temps)) {
- C.CleanupFileList(C.getResultFiles(), true);
+ if (FailingCommands.empty())
+ return 0;
- // Failure result files are valid unless we crashed.
- if (Res < 0)
- C.CleanupFileList(C.getFailureResultFiles(), true);
- }
+ // Otherwise, remove result files and print extra information about abnormal
+ // failures.
+ for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
+ FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
+ int Res = it->first;
+ const Command *FailingCommand = it->second;
+
+ // Remove result files if we're not saving temps.
+ if (!C.getArgs().hasArg(options::OPT_save_temps)) {
+ const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
+ C.CleanupFileMap(C.getResultFiles(), JA, true);
+
+ // Failure result files are valid unless we crashed.
+ if (Res < 0)
+ C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
+ }
- // Print extra information about abnormal failures, if possible.
- //
- // This is ad-hoc, but we don't want to be excessively noisy. If the result
- // status was 1, assume the command failed normally. In particular, if it was
- // the compiler then assume it gave a reasonable error code. Failures in other
- // tools are less common, and they generally have worse diagnostics, so always
- // print the diagnostic there.
- const Tool &FailingTool = FailingCommand->getCreator();
-
- if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
- // FIXME: See FIXME above regarding result code interpretation.
- if (Res < 0)
- Diag(clang::diag::err_drv_command_signalled)
- << FailingTool.getShortName();
- else
- Diag(clang::diag::err_drv_command_failed)
- << FailingTool.getShortName() << Res;
+ // Print extra information about abnormal failures, if possible.
+ //
+ // This is ad-hoc, but we don't want to be excessively noisy. If the result
+ // status was 1, assume the command failed normally. In particular, if it
+ // was the compiler then assume it gave a reasonable error code. Failures
+ // in other tools are less common, and they generally have worse
+ // diagnostics, so always print the diagnostic there.
+ const Tool &FailingTool = FailingCommand->getCreator();
+
+ if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
+ // FIXME: See FIXME above regarding result code interpretation.
+ if (Res < 0)
+ Diag(clang::diag::err_drv_command_signalled)
+ << FailingTool.getShortName();
+ else
+ Diag(clang::diag::err_drv_command_failed)
+ << FailingTool.getShortName() << Res;
+ }
}
-
- return Res;
+ return 0;
}
void Driver::PrintOptions(const ArgList &Args) const {
@@ -861,7 +876,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
// Add a 'dsymutil' step if necessary, when debug info is enabled and we
// have a compile input. We need to run 'dsymutil' ourselves in such cases
- // because the debug info will refer to a temporary object file which is
+ // because the debug info will refer to a temporary object file which
// will be removed at the end of the compilation process.
if (Act->getType() == types::TY_Image) {
ActionList Inputs;
@@ -1026,17 +1041,18 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
// Construct the actions to perform.
ActionList LinkerInputs;
- unsigned NumSteps = 0;
+ ActionList SplitInputs;
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
types::ID InputType = Inputs[i].first;
const Arg *InputArg = Inputs[i].second;
- NumSteps = types::getNumCompilationPhases(InputType);
- assert(NumSteps && "Invalid number of steps!");
+ PL.clear();
+ types::getCompilationPhases(InputType, PL);
// If the first step comes after the final phase we are doing as part of
// this compilation, warn the user about it.
- phases::ID InitialPhase = types::getCompilationPhase(InputType, 0);
+ phases::ID InitialPhase = PL[0];
if (InitialPhase > FinalPhase) {
// Claim here to avoid the more general unused warning.
InputArg->claim();
@@ -1071,8 +1087,9 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
// Build the pipeline for this file.
OwningPtr<Action> Current(new InputAction(*InputArg, InputType));
- for (unsigned i = 0; i != NumSteps; ++i) {
- phases::ID Phase = types::getCompilationPhase(InputType, i);
+ for (llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>::iterator
+ i = PL.begin(), e = PL.end(); i != e; ++i) {
+ phases::ID Phase = *i;
// We are done if this step is past what the user requested.
if (Phase > FinalPhase)
@@ -1080,7 +1097,7 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
// Queue linker inputs.
if (Phase == phases::Link) {
- assert(i + 1 == NumSteps && "linking must be final compilation step.");
+ assert((i + 1) == e && "linking must be final compilation step.");
LinkerInputs.push_back(Current.take());
break;
}
@@ -1108,7 +1125,7 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
// If we are linking, claim any options which are obviously only used for
// compilation.
- if (FinalPhase == phases::Link && (NumSteps == 1))
+ if (FinalPhase == phases::Link && PL.size() == 1)
Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
}
@@ -1154,6 +1171,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
return new MigrateJobAction(Input, types::TY_Remap);
} else if (Args.hasArg(options::OPT_emit_ast)) {
return new CompileJobAction(Input, types::TY_AST);
+ } else if (Args.hasArg(options::OPT_module_file_info)) {
+ return new CompileJobAction(Input, types::TY_ModuleFile);
} else if (IsUsingLTO(Args)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
@@ -1272,7 +1291,7 @@ void Driver::BuildJobs(Compilation &C) const {
}
}
-static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
+static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
const JobAction *JA,
const ActionList *&Inputs) {
const Tool *ToolForJob = 0;
@@ -1281,23 +1300,23 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
// bottom up, so what we are actually looking for is an assembler job with a
// compiler input.
- if (C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- TC->IsIntegratedAssemblerDefault()) &&
+ if (TC->useIntegratedAs() &&
!C.getArgs().hasArg(options::OPT_save_temps) &&
isa<AssembleJobAction>(JA) &&
Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
- const Tool &Compiler = TC->SelectTool(
- C, cast<JobAction>(**Inputs->begin()), (*Inputs)[0]->getInputs());
- if (Compiler.hasIntegratedAssembler()) {
+ const Tool *Compiler =
+ TC->SelectTool(cast<JobAction>(**Inputs->begin()));
+ if (!Compiler)
+ return NULL;
+ if (Compiler->hasIntegratedAssembler()) {
Inputs = &(*Inputs)[0]->getInputs();
- ToolForJob = &Compiler;
+ ToolForJob = Compiler;
}
}
// Otherwise use the tool for the current job.
if (!ToolForJob)
- ToolForJob = &TC->SelectTool(C, *JA, *Inputs);
+ ToolForJob = TC->SelectTool(*JA);
// See if we should use an integrated preprocessor. We do so when we have
// exactly one input, since this is the only use case we care about
@@ -1310,7 +1329,7 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
ToolForJob->hasIntegratedCPP())
Inputs = &(*Inputs)[0]->getInputs();
- return *ToolForJob;
+ return ToolForJob;
}
void Driver::BuildJobsForAction(Compilation &C,
@@ -1352,23 +1371,19 @@ void Driver::BuildJobsForAction(Compilation &C,
const ActionList *Inputs = &A->getInputs();
const JobAction *JA = cast<JobAction>(A);
- const Tool &T = SelectToolForJob(C, TC, JA, Inputs);
+ const Tool *T = SelectToolForJob(C, TC, JA, Inputs);
+ if (!T)
+ return;
// Only use pipes when there is exactly one input.
InputInfoList InputInfos;
for (ActionList::const_iterator it = Inputs->begin(), ie = Inputs->end();
it != ie; ++it) {
- // Treat dsymutil sub-jobs as being at the top-level too, they shouldn't get
- // temporary output names.
- //
+ // Treat dsymutil and verify sub-jobs as being at the top-level too, they
+ // shouldn't get temporary output names.
// FIXME: Clean this up.
bool SubJobAtTopLevel = false;
- if (AtTopLevel && isa<DsymutilJobAction>(A))
- SubJobAtTopLevel = true;
-
- // Also treat verify sub-jobs as being at the top-level. They don't
- // produce any output and so don't need temporary output names.
- if (AtTopLevel && isa<VerifyJobAction>(A))
+ if (AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A)))
SubJobAtTopLevel = true;
InputInfo II;
@@ -1386,16 +1401,15 @@ void Driver::BuildJobsForAction(Compilation &C,
BaseInput = InputInfos[0].getFilename();
// Determine the place to write output to, if any.
- if (JA->getType() == types::TY_Nothing) {
+ if (JA->getType() == types::TY_Nothing)
Result = InputInfo(A->getType(), BaseInput);
- } else {
+ else
Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel),
A->getType(), BaseInput);
- }
if (CCCPrintBindings && !CCGenDiagnostics) {
- llvm::errs() << "# \"" << T.getToolChain().getTripleString() << '"'
- << " - \"" << T.getName() << "\", inputs: [";
+ llvm::errs() << "# \"" << T->getToolChain().getTripleString() << '"'
+ << " - \"" << T->getName() << "\", inputs: [";
for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
llvm::errs() << InputInfos[i].getAsString();
if (i + 1 != e)
@@ -1403,8 +1417,8 @@ void Driver::BuildJobsForAction(Compilation &C,
}
llvm::errs() << "], output: " << Result.getAsString() << "\n";
} else {
- T.ConstructJob(C, *JA, Result, InputInfos,
- C.getArgsForToolChain(TC, BoundArch), LinkingOutput);
+ T->ConstructJob(C, *JA, Result, InputInfos,
+ C.getArgsForToolChain(TC, BoundArch), LinkingOutput);
}
}
@@ -1417,11 +1431,12 @@ 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());
+ return C.addResultFile(FinalOutput->getValue(), &JA);
}
// Default to writing to stdout?
- if (AtTopLevel && isa<PreprocessJobAction>(JA) && !CCGenDiagnostics)
+ if (AtTopLevel && !CCGenDiagnostics &&
+ (isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile))
return "-";
// Output to a temporary file?
@@ -1487,9 +1502,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
BasePath = NamedOutput;
else
llvm::sys::path::append(BasePath, NamedOutput);
- return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()));
+ return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
} else {
- return C.addResultFile(NamedOutput);
+ return C.addResultFile(NamedOutput, &JA);
}
}
@@ -1638,6 +1653,21 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple,
}
}
+ // Handle pseudo-target flags '-EL' and '-EB'.
+ if (Arg *A = Args.getLastArg(options::OPT_EL, options::OPT_EB)) {
+ if (A->getOption().matches(options::OPT_EL)) {
+ if (Target.getArch() == llvm::Triple::mips)
+ Target.setArch(llvm::Triple::mipsel);
+ else if (Target.getArch() == llvm::Triple::mips64)
+ Target.setArch(llvm::Triple::mips64el);
+ } else {
+ if (Target.getArch() == llvm::Triple::mipsel)
+ Target.setArch(llvm::Triple::mips);
+ else if (Target.getArch() == llvm::Triple::mips64el)
+ Target.setArch(llvm::Triple::mips64);
+ }
+ }
+
// Skip further flag support on OSes which don't support '-m32' or '-m64'.
if (Target.getArchName() == "tce" ||
Target.getOS() == llvm::Triple::AuroraUX ||
@@ -1681,7 +1711,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
Target.getArch() == llvm::Triple::x86_64 ||
Target.getArch() == llvm::Triple::arm ||
Target.getArch() == llvm::Triple::thumb)
- TC = new toolchains::DarwinClang(*this, Target);
+ TC = new toolchains::DarwinClang(*this, Target, Args);
else
TC = new toolchains::Darwin_Generic_GCC(*this, Target, Args);
break;
@@ -1705,7 +1735,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
break;
case llvm::Triple::Linux:
if (Target.getArch() == llvm::Triple::hexagon)
- TC = new toolchains::Hexagon_TC(*this, Target);
+ TC = new toolchains::Hexagon_TC(*this, Target, Args);
else
TC = new toolchains::Linux(*this, Target, Args);
break;
@@ -1713,17 +1743,21 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = new toolchains::Solaris(*this, Target, Args);
break;
case llvm::Triple::Win32:
- TC = new toolchains::Windows(*this, Target);
+ TC = new toolchains::Windows(*this, Target, Args);
break;
case llvm::Triple::MinGW32:
// FIXME: We need a MinGW toolchain. Fallthrough for now.
default:
// TCE is an OSless target
if (Target.getArchName() == "tce") {
- TC = new toolchains::TCEToolChain(*this, Target);
+ TC = new toolchains::TCEToolChain(*this, Target, Args);
+ break;
+ }
+ // If Hexagon is configured as an OSless target
+ if (Target.getArch() == llvm::Triple::hexagon) {
+ TC = new toolchains::Hexagon_TC(*this, Target, Args);
break;
}
-
TC = new toolchains::Generic_GCC(*this, Target, Args);
break;
}
@@ -1731,8 +1765,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
return *TC;
}
-bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
- const llvm::Triple &Triple) const {
+bool Driver::ShouldUseClangCompiler(const JobAction &JA) const {
// Check if user requested no clang, or clang doesn't understand this type (we
// only handle single inputs for now).
if (JA.size() != 1 ||
diff --git a/contrib/llvm/tools/clang/lib/Driver/InputInfo.h b/contrib/llvm/tools/clang/lib/Driver/InputInfo.h
index 2a2f4b9..a243d32 100644
--- a/contrib/llvm/tools/clang/lib/Driver/InputInfo.h
+++ b/contrib/llvm/tools/clang/lib/Driver/InputInfo.h
@@ -10,8 +10,8 @@
#ifndef CLANG_LIB_DRIVER_INPUTINFO_H_
#define CLANG_LIB_DRIVER_INPUTINFO_H_
+#include "clang/Driver/Arg.h"
#include "clang/Driver/Types.h"
-
#include <cassert>
#include <string>
diff --git a/contrib/llvm/tools/clang/lib/Driver/Job.cpp b/contrib/llvm/tools/clang/lib/Driver/Job.cpp
index 825c86a..8c46705 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Job.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Job.cpp
@@ -8,9 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Job.h"
-
#include "llvm/ADT/STLExtras.h"
-
#include <cassert>
using namespace clang::driver;
diff --git a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
index 6e7b695..20214a6 100644
--- a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp
@@ -12,8 +12,8 @@
#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 "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <map>
using namespace clang::driver;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Option.cpp b/contrib/llvm/tools/clang/lib/Driver/Option.cpp
index 9a34df5..dbc61ea 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Option.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Option.cpp
@@ -8,14 +8,13 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Option.h"
-
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/Twine.h"
-#include <cassert>
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
using namespace clang::driver;
Option::Option(const OptTable::Info *info, const OptTable *owner)
diff --git a/contrib/llvm/tools/clang/lib/Driver/Phases.cpp b/contrib/llvm/tools/clang/lib/Driver/Phases.cpp
index b885eee..155e53b 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Phases.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Phases.cpp
@@ -9,7 +9,6 @@
#include "clang/Driver/Phases.h"
#include "llvm/Support/ErrorHandling.h"
-
#include <cassert>
using namespace clang::driver;
diff --git a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
index ecb396e..e61f15a 100644
--- a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
+++ b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
@@ -9,7 +9,13 @@
#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Path.h"
namespace clang {
namespace driver {
@@ -30,59 +36,151 @@ class SanitizerArgs {
#include "clang/Basic/Sanitizers.def"
NeedsAsanRt = Address,
NeedsTsanRt = Thread,
- NeedsUbsanRt = Undefined
+ NeedsMsanRt = Memory,
+ NeedsUbsanRt = Undefined | Integer,
+ NotAllowedWithTrap = Vptr
};
unsigned Kind;
+ std::string BlacklistFile;
+ bool MsanTrackOrigins;
+ bool AsanZeroBaseShadow;
+ bool UbsanTrapOnError;
public:
- SanitizerArgs() : Kind(0) {}
+ SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+ AsanZeroBaseShadow(false), UbsanTrapOnError(false) {}
/// 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 needsMsanRt() const { return Kind & NeedsMsanRt; }
+ bool needsUbsanRt() const {
+ if (UbsanTrapOnError)
+ return false;
+ return Kind & NeedsUbsanRt;
+ }
bool sanitizesVptr() const { return Kind & Vptr; }
-
+ bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
+
void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
if (!Kind)
return;
- llvm::SmallString<256> SanitizeOpt("-fsanitize=");
+ 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));
+ if (!BlacklistFile.empty()) {
+ SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
+ BlacklistOpt += BlacklistFile;
+ CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
+ }
+
+ if (MsanTrackOrigins)
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
+
+ if (AsanZeroBaseShadow)
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fsanitize-address-zero-base-shadow"));
}
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.
+ /// Returns OR of members 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)
+ unsigned ParsedKind = 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());
+ // Assume -fsanitize=address implies -fsanitize=init-order.
+ // FIXME: This should be either specified in Sanitizers.def, or go away when
+ // we get rid of "-fsanitize=init-order" flag at all.
+ if (ParsedKind & Address)
+ ParsedKind |= InitOrder;
+ return ParsedKind;
}
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
/// invalid components.
- static unsigned parse(const Driver &D, const Arg *A) {
+ static unsigned parse(const Driver &D, const Arg *A, bool DiagnoseErrors) {
unsigned Kind = 0;
for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
if (unsigned K = parse(A->getValue(I)))
Kind |= K;
- else
+ else if (DiagnoseErrors)
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << A->getValue(I);
}
return Kind;
}
+ /// Parse a single flag of the form -f[no]sanitize=, or
+ /// -f*-sanitizer. Sets the masks defining required change of Kind value.
+ /// Returns true if the flag was parsed successfully.
+ static bool parse(const Driver &D, const ArgList &Args, const Arg *A,
+ unsigned &Add, unsigned &Remove, bool DiagnoseErrors) {
+ Add = 0;
+ Remove = 0;
+ const char *DeprecatedReplacement = 0;
+ if (A->getOption().matches(options::OPT_faddress_sanitizer)) {
+ Add = Address;
+ DeprecatedReplacement = "-fsanitize=address";
+ } else if (A->getOption().matches(options::OPT_fno_address_sanitizer)) {
+ Remove = Address;
+ DeprecatedReplacement = "-fno-sanitize=address";
+ } else if (A->getOption().matches(options::OPT_fthread_sanitizer)) {
+ Add = Thread;
+ DeprecatedReplacement = "-fsanitize=thread";
+ } else if (A->getOption().matches(options::OPT_fno_thread_sanitizer)) {
+ Remove = Thread;
+ DeprecatedReplacement = "-fno-sanitize=thread";
+ } else if (A->getOption().matches(options::OPT_fcatch_undefined_behavior)) {
+ Add = UndefinedTrap;
+ DeprecatedReplacement =
+ "-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error";
+ } else if (A->getOption().matches(options::OPT_fbounds_checking) ||
+ A->getOption().matches(options::OPT_fbounds_checking_EQ)) {
+ Add = Bounds;
+ DeprecatedReplacement = "-fsanitize=bounds";
+ } else if (A->getOption().matches(options::OPT_fsanitize_EQ)) {
+ Add = parse(D, A, DiagnoseErrors);
+ } else if (A->getOption().matches(options::OPT_fno_sanitize_EQ)) {
+ Remove = parse(D, A, DiagnoseErrors);
+ } else {
+ // Flag is not relevant to sanitizers.
+ return false;
+ }
+ // If this is a deprecated synonym, produce a warning directing users
+ // towards the new spelling.
+ if (DeprecatedReplacement && DiagnoseErrors)
+ D.Diag(diag::warn_drv_deprecated_arg)
+ << A->getAsString(Args) << DeprecatedReplacement;
+ return true;
+ }
+
+ /// Produce an argument string from ArgList \p Args, which shows how it
+ /// provides a sanitizer kind in \p Mask. For example, the argument list
+ /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt
+ /// would produce "-fsanitize=vptr".
+ static std::string lastArgumentForKind(const Driver &D, const ArgList &Args,
+ unsigned Kind) {
+ for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
+ I != E; ++I) {
+ unsigned Add, Remove;
+ if (parse(D, Args, *I, Add, Remove, false) &&
+ (Add & Kind))
+ return describeSanitizeArg(Args, *I, Kind);
+ Kind &= ~Remove;
+ }
+ llvm_unreachable("arg list didn't provide expected value");
+ }
+
/// 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
@@ -98,6 +196,18 @@ class SanitizerArgs {
llvm_unreachable("arg didn't provide expected value");
}
+
+ static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
+ std::string &BLPath) {
+ // For now, specify the default blacklist location for ASan only.
+ if (Kind & NeedsAsanRt) {
+ SmallString<64> Path(D.ResourceDir);
+ llvm::sys::path::append(Path, "asan_blacklist.txt");
+ BLPath = Path.str();
+ return true;
+ }
+ return false;
+ }
};
} // namespace driver
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
index de8ed1d..19270b2 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#include "Tools.h"
#include "clang/Driver/ToolChain.h"
-
+#include "clang/Basic/ObjCRuntime.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
@@ -18,12 +19,12 @@
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
-#include "clang/Basic/ObjCRuntime.h"
using namespace clang::driver;
using namespace clang;
-ToolChain::ToolChain(const Driver &D, const llvm::Triple &T)
- : D(D), Triple(T) {
+ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
+ const ArgList &A)
+ : D(D), Triple(T), Args(A) {
}
ToolChain::~ToolChain() {
@@ -33,6 +34,12 @@ const Driver &ToolChain::getDriver() const {
return D;
}
+bool ToolChain::useIntegratedAs() const {
+ return Args.hasFlag(options::OPT_integrated_as,
+ options::OPT_no_integrated_as,
+ IsIntegratedAssemblerDefault());
+}
+
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
@@ -52,6 +59,73 @@ bool ToolChain::IsUnwindTablesDefault() const {
return false;
}
+Tool *ToolChain::getClang() const {
+ if (!Clang)
+ Clang.reset(new tools::Clang(*this));
+ return Clang.get();
+}
+
+Tool *ToolChain::buildAssembler() const {
+ return new tools::ClangAs(*this);
+}
+
+Tool *ToolChain::buildLinker() const {
+ llvm_unreachable("Linking is not supported by this toolchain");
+}
+
+Tool *ToolChain::getAssemble() const {
+ if (!Assemble)
+ Assemble.reset(buildAssembler());
+ return Assemble.get();
+}
+
+Tool *ToolChain::getClangAs() const {
+ if (!Assemble)
+ Assemble.reset(new tools::ClangAs(*this));
+ return Assemble.get();
+}
+
+Tool *ToolChain::getLink() const {
+ if (!Link)
+ Link.reset(buildLinker());
+ return Link.get();
+}
+
+Tool *ToolChain::getTool(Action::ActionClass AC) const {
+ switch (AC) {
+ case Action::AssembleJobClass:
+ return getAssemble();
+
+ case Action::LinkJobClass:
+ return getLink();
+
+ case Action::InputClass:
+ case Action::BindArchClass:
+ case Action::LipoJobClass:
+ case Action::DsymutilJobClass:
+ case Action::VerifyJobClass:
+ llvm_unreachable("Invalid tool kind.");
+
+ case Action::CompileJobClass:
+ case Action::PrecompileJobClass:
+ case Action::PreprocessJobClass:
+ case Action::AnalyzeJobClass:
+ case Action::MigrateJobClass:
+ return getClang();
+ }
+
+ llvm_unreachable("Invalid tool kind.");
+}
+
+Tool *ToolChain::SelectTool(const JobAction &JA) const {
+ if (getDriver().ShouldUseClangCompiler(JA))
+ return getClang();
+ Action::ActionClass AC = JA.getKind();
+ if (AC == Action::AssembleJobClass && useIntegratedAs())
+ return getClangAs();
+ return getTool(AC);
+}
+
std::string ToolChain::GetFilePath(const char *Name) const {
return D.GetFilePath(Name, *this);
@@ -110,15 +184,17 @@ static const char *getARMTargetCPU(const ArgList &Args,
.Case("armv6j", "arm1136j-s")
.Cases("armv6z", "armv6zk", "arm1176jzf-s")
.Case("armv6t2", "arm1156t2-s")
+ .Cases("armv6m", "armv6-m", "cortex-m0")
.Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
+ .Cases("armv7l", "armv7-l", "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")
+ .Cases("armv7em", "armv7e-m", "cortex-m4")
.Case("ep9312", "ep9312")
.Case("iwmmxt", "iwmmxt")
.Case("xscale", "xscale")
- .Cases("armv6m", "armv6-m", "cortex-m0")
// If all else failed, return the most base CPU LLVM supports.
.Default("arm7tdmi");
}
@@ -141,10 +217,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", "cortex-a15", "v7")
- .Case("cortex-m3", "v7m")
- .Case("cortex-m4", "v7m")
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
+ .Cases("cortex-a9", "cortex-a15", "v7")
+ .Case("cortex-r5", "v7r")
.Case("cortex-m0", "v6m")
+ .Case("cortex-m3", "v7m")
+ .Case("cortex-m4", "v7em")
.Case("cortex-a9-mp", "v7f")
.Case("swift", "v7s")
.Default("");
@@ -166,7 +244,8 @@ 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.startswith("v7") && getTriple().isOSDarwin());
+ bool ThumbDefault = Suffix.startswith("v6m") ||
+ (Suffix.startswith("v7") && getTriple().isOSDarwin());
std::string ArchName = "arm";
// Assembly files should start in ARM mode.
@@ -197,7 +276,8 @@ void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// Each toolchain should provide the appropriate include flags.
}
-void ToolChain::addClangTargetOptions(ArgStringList &CC1Args) const {
+void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
}
ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index c5460b2..bcfe51e 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "ToolChains.h"
-
+#include "SanitizerArgs.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Version.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
@@ -17,34 +19,31 @@
#include "clang/Driver/OptTable.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/Version.h"
-
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "SanitizerArgs.h"
+// FIXME: This needs to be listed last until we fix the broken include guards
+// in these files and the LLVM config.h files.
+#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
#include <cstdlib> // ::getenv
-#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
-
using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
/// Darwin - Darwin tool chain for i386 and x86_64.
-Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple), TargetInitialized(false)
+Darwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+ : ToolChain(D, Triple, Args), TargetInitialized(false)
{
// Compute the initial Darwin version from the triple
unsigned Major, Minor, Micro;
@@ -100,15 +99,17 @@ bool Darwin::hasBlocksRuntime() const {
static const char *GetArmArchForMArch(StringRef Value) {
return llvm::StringSwitch<const char*>(Value)
.Case("armv6k", "armv6")
+ .Case("armv6m", "armv6m")
.Case("armv5tej", "armv5")
.Case("xscale", "xscale")
.Case("armv4t", "armv4t")
.Case("armv7", "armv7")
.Cases("armv7a", "armv7-a", "armv7")
.Cases("armv7r", "armv7-r", "armv7")
- .Cases("armv7m", "armv7-m", "armv7")
+ .Cases("armv7em", "armv7e-m", "armv7em")
.Cases("armv7f", "armv7-f", "armv7f")
.Cases("armv7k", "armv7-k", "armv7k")
+ .Cases("armv7m", "armv7-m", "armv7m")
.Cases("armv7s", "armv7-s", "armv7s")
.Default(0);
}
@@ -119,11 +120,12 @@ static const char *GetArmArchForMCpu(StringRef Value) {
.Cases("arm10e", "arm10tdmi", "armv5")
.Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
.Case("xscale", "xscale")
- .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s",
- "arm1176jzf-s", "cortex-m0", "armv6")
- .Cases("cortex-a8", "cortex-r4", "cortex-m3", "cortex-a9", "cortex-a15",
- "armv7")
+ .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
+ .Case("cortex-m0", "armv6m")
+ .Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
.Case("cortex-a9-mp", "armv7f")
+ .Case("cortex-m3", "armv7m")
+ .Case("cortex-m4", "armv7em")
.Case("swift", "armv7s")
.Default(0);
}
@@ -149,10 +151,6 @@ StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
}
Darwin::~Darwin() {
- // Free tool implementations.
- for (llvm::DenseMap<unsigned, Tool*>::iterator
- it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
- delete it->second;
}
std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
@@ -174,57 +172,36 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
void Generic_ELF::anchor() {}
-Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
-
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {
- // 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,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::InputClass:
- case Action::BindArchClass:
- llvm_unreachable("Invalid tool kind.");
- case Action::PreprocessJobClass:
- T = new tools::darwin::Preprocess(*this); break;
- case Action::AnalyzeJobClass:
- case Action::MigrateJobClass:
- T = new tools::Clang(*this); break;
- case Action::PrecompileJobClass:
- case Action::CompileJobClass:
- T = new tools::darwin::Compile(*this); break;
- case Action::AssembleJobClass: {
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::darwin::Assemble(*this);
- break;
- }
- case Action::LinkJobClass:
- T = new tools::darwin::Link(*this); break;
- case Action::LipoJobClass:
- T = new tools::darwin::Lipo(*this); break;
- case Action::DsymutilJobClass:
- T = new tools::darwin::Dsymutil(*this); break;
- case Action::VerifyJobClass:
- T = new tools::darwin::VerifyDebug(*this); break;
- }
+Tool *Darwin::getTool(Action::ActionClass AC) const {
+ switch (AC) {
+ case Action::LipoJobClass:
+ if (!Lipo)
+ Lipo.reset(new tools::darwin::Lipo(*this));
+ return Lipo.get();
+ case Action::DsymutilJobClass:
+ if (!Dsymutil)
+ Dsymutil.reset(new tools::darwin::Dsymutil(*this));
+ return Dsymutil.get();
+ case Action::VerifyJobClass:
+ if (!VerifyDebug)
+ VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
+ return VerifyDebug.get();
+ default:
+ return ToolChain::getTool(AC);
}
+}
- return *T;
+Tool *Darwin::buildLinker() const {
+ return new tools::darwin::Link(*this);
}
+Tool *Darwin::buildAssembler() const {
+ return new tools::darwin::Assemble(*this);
+}
-DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple)
- : Darwin(D, Triple)
+DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args)
+ : Darwin(D, Triple, Args)
{
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
@@ -261,16 +238,18 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
ArgStringList &CmdArgs,
- const char *DarwinStaticLib) const {
+ const char *DarwinStaticLib,
+ bool AlwaysLink) const {
llvm::sys::Path P(getDriver().ResourceDir);
P.appendComponent("lib");
P.appendComponent("darwin");
P.appendComponent(DarwinStaticLib);
// For now, allow missing resource libraries to support developers who may
- // not have compiler-rt checked out or integrated into their build.
+ // not have compiler-rt checked out or integrated into their build (unless
+ // we explicitly force linking with this library).
bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
+ if (AlwaysLink || (!llvm::sys::fs::exists(P.str(), Exists) && Exists))
CmdArgs.push_back(Args.MakeArgString(P.str()));
}
@@ -317,21 +296,35 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
SanitizerArgs Sanitize(getDriver(), Args);
+ // Add Ubsan runtime library, if required.
+ if (Sanitize.needsUbsanRt()) {
+ if (isTargetIPhoneOS()) {
+ getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
+ << "-fsanitize=undefined";
+ } else {
+ AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
+
+ // The Ubsan runtime library requires C++.
+ AddCXXStdlibLibArgs(Args, CmdArgs);
+ }
+ }
+
// Add ASAN runtime library, if required. Dynamic libraries and bundles
// should not be linked with the runtime library.
if (Sanitize.needsAsanRt()) {
- if (Args.hasArg(options::OPT_dynamiclib) ||
- Args.hasArg(options::OPT_bundle)) return;
- if (isTargetIPhoneOS()) {
+ if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
<< "-fsanitize=address";
} else {
- AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.asan_osx.a");
-
- // The ASAN runtime library requires C++ and CoreFoundation.
- AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-framework");
- CmdArgs.push_back("CoreFoundation");
+ if (Args.hasArg(options::OPT_dynamiclib) ||
+ Args.hasArg(options::OPT_bundle)) {
+ // Assume the binary will provide the ASan runtime.
+ } else {
+ AddLinkRuntimeLib(Args, CmdArgs,
+ "libclang_rt.asan_osx_dynamic.dylib", true);
+ // The ASAN runtime library requires C++.
+ AddCXXStdlibLibArgs(Args, CmdArgs);
+ }
}
}
@@ -381,11 +374,17 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// 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 (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+ // Warn if the path does not exist.
+ bool Exists;
+ if (llvm::sys::fs::exists(A->getValue(), Exists) || !Exists)
+ getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
+ } else {
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)) {
+ // We only use this value as the default if it is an absolute path,
+ // exists, and it is not the root path.
+ if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&
+ StringRef(env) != "/") {
Args.append(Args.MakeSeparateArg(
0, Opts.getOption(options::OPT_isysroot), env));
}
@@ -796,12 +795,18 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
DAL->AddJoinedArg(0, MArch, "xscale");
else if (Name == "armv6")
DAL->AddJoinedArg(0, MArch, "armv6k");
+ else if (Name == "armv6m")
+ DAL->AddJoinedArg(0, MArch, "armv6m");
else if (Name == "armv7")
DAL->AddJoinedArg(0, MArch, "armv7a");
+ else if (Name == "armv7em")
+ DAL->AddJoinedArg(0, MArch, "armv7em");
else if (Name == "armv7f")
DAL->AddJoinedArg(0, MArch, "armv7f");
else if (Name == "armv7k")
DAL->AddJoinedArg(0, MArch, "armv7k");
+ else if (Name == "armv7m")
+ DAL->AddJoinedArg(0, MArch, "armv7m");
else if (Name == "armv7s")
DAL->AddJoinedArg(0, MArch, "armv7s");
@@ -931,7 +936,7 @@ Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
// And retains any patch number it finds.
StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
if (!PatchText.empty()) {
- if (unsigned EndNumber = PatchText.find_first_not_of("0123456789")) {
+ if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
// Try to parse the number and any suffix.
if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
GoodVersion.Patch < 0)
@@ -945,20 +950,33 @@ Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
bool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const {
- if (Major < RHS.Major) return true; if (Major > RHS.Major) return false;
- if (Minor < RHS.Minor) return true; if (Minor > RHS.Minor) return false;
-
- // Note that we rank versions with *no* patch specified is better than ones
- // hard-coding a patch version. Thus if the RHS has no patch, it always
- // wins, and the LHS only wins if it has no patch and the RHS does have
- // a patch.
- if (RHS.Patch == -1) return true; if (Patch == -1) return false;
- if (Patch < RHS.Patch) return true; if (Patch > RHS.Patch) return false;
- if (PatchSuffix == RHS.PatchSuffix) return false;
-
- // Finally, between completely tied version numbers, the version with the
- // suffix loses as we prefer full releases.
- if (RHS.PatchSuffix.empty()) return true;
+ if (Major != RHS.Major)
+ return Major < RHS.Major;
+ if (Minor != RHS.Minor)
+ return Minor < RHS.Minor;
+ if (Patch != RHS.Patch) {
+ // Note that versions without a specified patch sort higher than those with
+ // a patch.
+ if (RHS.Patch == -1)
+ return true;
+ if (Patch == -1)
+ return false;
+
+ // Otherwise just sort on the patch itself.
+ return Patch < RHS.Patch;
+ }
+ if (PatchSuffix != RHS.PatchSuffix) {
+ // Sort empty suffixes higher.
+ if (RHS.PatchSuffix.empty())
+ return true;
+ if (PatchSuffix.empty())
+ return false;
+
+ // Provide a lexicographic sort to make this a total ordering.
+ return PatchSuffix < RHS.PatchSuffix;
+ }
+
+ // The versions are equal.
return false;
}
@@ -1051,6 +1069,12 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
// Declare a bunch of static data sets that we'll select between below. These
// are specifically designed to always refer to string literals to avoid any
// lifetime or initialization issues.
+ static const char *const AArch64LibDirs[] = { "/lib" };
+ static const char *const AArch64Triples[] = {
+ "aarch64-none-linux-gnu",
+ "aarch64-linux-gnu"
+ };
+
static const char *const ARMLibDirs[] = { "/lib" };
static const char *const ARMTriples[] = {
"arm-linux-gnueabi",
@@ -1078,6 +1102,7 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
"i686-pc-linux-gnu",
"i486-linux-gnu",
"i386-linux-gnu",
+ "i386-redhat-linux6E",
"i686-redhat-linux",
"i586-redhat-linux",
"i386-redhat-linux",
@@ -1103,6 +1128,7 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
static const char *const PPCTriples[] = {
"powerpc-linux-gnu",
"powerpc-unknown-linux-gnu",
+ "powerpc-linux-gnuspe",
"powerpc-suse-linux",
"powerpc-montavista-linuxspe"
};
@@ -1115,6 +1141,16 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
};
switch (TargetTriple.getArch()) {
+ case llvm::Triple::aarch64:
+ LibDirs.append(AArch64LibDirs, AArch64LibDirs
+ + llvm::array_lengthof(AArch64LibDirs));
+ TripleAliases.append(
+ AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
+ MultiarchLibDirs.append(
+ AArch64LibDirs, AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
+ MultiarchTripleAliases.append(
+ AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
+ break;
case llvm::Triple::arm:
case llvm::Triple::thumb:
LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
@@ -1316,60 +1352,40 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
const ArgList &Args)
- : ToolChain(D, Triple), GCCInstallation(getDriver(), Triple, Args) {
+ : ToolChain(D, Triple, Args), GCCInstallation(getDriver(), Triple, Args) {
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
}
Generic_GCC::~Generic_GCC() {
- // Free tool implementations.
- for (llvm::DenseMap<unsigned, Tool*>::iterator
- it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
- delete it->second;
-}
-
-Tool &Generic_GCC::SelectTool(const Compilation &C,
- const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::InputClass:
- case Action::BindArchClass:
- llvm_unreachable("Invalid tool kind.");
- case Action::PreprocessJobClass:
- T = new tools::gcc::Preprocess(*this); break;
- case Action::PrecompileJobClass:
- T = new tools::gcc::Precompile(*this); break;
- case Action::AnalyzeJobClass:
- case Action::MigrateJobClass:
- T = new tools::Clang(*this); break;
- case Action::CompileJobClass:
- T = new tools::gcc::Compile(*this); break;
- case Action::AssembleJobClass:
- T = new tools::gcc::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::gcc::Link(*this); break;
-
- // This is a bit ungeneric, but the only platform using a driver
- // driver is Darwin.
- case Action::LipoJobClass:
- T = new tools::darwin::Lipo(*this); break;
- case Action::DsymutilJobClass:
- T = new tools::darwin::Dsymutil(*this); break;
- case Action::VerifyJobClass:
- T = new tools::darwin::VerifyDebug(*this); break;
- }
+}
+
+Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
+ switch (AC) {
+ case Action::PreprocessJobClass:
+ if (!Preprocess)
+ Preprocess.reset(new tools::gcc::Preprocess(*this));
+ return Preprocess.get();
+ case Action::PrecompileJobClass:
+ if (!Precompile)
+ Precompile.reset(new tools::gcc::Precompile(*this));
+ return Precompile.get();
+ case Action::CompileJobClass:
+ if (!Compile)
+ Compile.reset(new tools::gcc::Compile(*this));
+ return Compile.get();
+ default:
+ return ToolChain::getTool(AC);
}
+}
+
+Tool *Generic_GCC::buildAssembler() const {
+ return new tools::gcc::Assemble(*this);
+}
- return *T;
+Tool *Generic_GCC::buildLinker() const {
+ return new tools::gcc::Link(*this);
}
bool Generic_GCC::IsUnwindTablesDefault() const {
@@ -1386,71 +1402,216 @@ bool Generic_GCC::isPICDefaultForced() const {
/// Hexagon Toolchain
-Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple) {
- getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
- getProgramPaths().push_back(getDriver().Dir);
+std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) {
+
+ // Locate the rest of the toolchain ...
+ if (strlen(GCC_INSTALL_PREFIX))
+ return std::string(GCC_INSTALL_PREFIX);
+
+ std::string InstallRelDir = InstalledDir + "/../../gnu";
+ if (llvm::sys::fs::exists(InstallRelDir))
+ return InstallRelDir;
+
+ std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
+ if (llvm::sys::fs::exists(PrefixRelDir))
+ return PrefixRelDir;
+
+ return InstallRelDir;
+}
+
+static void GetHexagonLibraryPaths(
+ const ArgList &Args,
+ const std::string Ver,
+ const std::string MarchString,
+ const std::string &InstalledDir,
+ ToolChain::path_list *LibPaths)
+{
+ bool buildingLib = Args.hasArg(options::OPT_shared);
+
+ //----------------------------------------------------------------------------
+ // -L Args
+ //----------------------------------------------------------------------------
+ for (arg_iterator
+ it = Args.filtered_begin(options::OPT_L),
+ ie = Args.filtered_end();
+ it != ie;
+ ++it) {
+ for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
+ LibPaths->push_back((*it)->getValue(i));
+ }
+
+ //----------------------------------------------------------------------------
+ // Other standard paths
+ //----------------------------------------------------------------------------
+ const std::string MarchSuffix = "/" + MarchString;
+ const std::string G0Suffix = "/G0";
+ const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
+ const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/";
+
+ // lib/gcc/hexagon/...
+ std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
+ if (buildingLib) {
+ LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
+ LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
+ }
+ LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
+ LibPaths->push_back(LibGCCHexagonDir + Ver);
+
+ // lib/gcc/...
+ LibPaths->push_back(RootDir + "lib/gcc");
+
+ // hexagon/lib/...
+ std::string HexagonLibDir = RootDir + "hexagon/lib";
+ if (buildingLib) {
+ LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
+ LibPaths->push_back(HexagonLibDir + G0Suffix);
+ }
+ LibPaths->push_back(HexagonLibDir + MarchSuffix);
+ LibPaths->push_back(HexagonLibDir);
+}
+
+Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : Linux(D, Triple, Args) {
+ const std::string InstalledDir(getDriver().getInstalledDir());
+ const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir);
+
+ // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
+ // program paths
+ const std::string BinDir(GnuDir + "/bin");
+ if (llvm::sys::fs::exists(BinDir))
+ getProgramPaths().push_back(BinDir);
+
+ // Determine version of GCC libraries and headers to use.
+ const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
+ llvm::error_code ec;
+ GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
+ for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
+ !ec && di != de; di = di.increment(ec)) {
+ GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
+ if (MaxVersion < cv)
+ MaxVersion = cv;
+ }
+ GCCLibAndIncVersion = MaxVersion;
+
+ ToolChain::path_list *LibPaths= &getFilePaths();
+
+ // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
+ // 'elf' OS type, so the Linux paths are not appropriate. When we actually
+ // support 'linux' we'll need to fix this up
+ LibPaths->clear();
+
+ GetHexagonLibraryPaths(
+ Args,
+ GetGCCLibAndIncVersion(),
+ GetTargetCPU(Args),
+ InstalledDir,
+ LibPaths);
}
Hexagon_TC::~Hexagon_TC() {
- // Free tool implementations.
- for (llvm::DenseMap<unsigned, Tool*>::iterator
- it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
- delete it->second;
-}
-
-Tool &Hexagon_TC::SelectTool(const Compilation &C,
- const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- // if (JA.getKind () == Action::CompileJobClass)
- // Key = JA.getKind ();
- // else
-
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
- // if ((JA.getKind () == Action::CompileJobClass)
- // && (JA.getType () != types::TY_LTO_BC)) {
- // Key = JA.getKind ();
- // }
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::InputClass:
- case Action::BindArchClass:
- assert(0 && "Invalid tool kind.");
- case Action::AnalyzeJobClass:
- T = new tools::Clang(*this); break;
- case Action::AssembleJobClass:
- T = new tools::hexagon::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::hexagon::Link(*this); break;
- default:
- assert(false && "Unsupported action for Hexagon target.");
- }
+}
+
+Tool *Hexagon_TC::buildAssembler() const {
+ return new tools::hexagon::Assemble(*this);
+}
+
+Tool *Hexagon_TC::buildLinker() const {
+ return new tools::hexagon::Link(*this);
+}
+
+void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+
+ if (DriverArgs.hasArg(options::OPT_nostdinc) ||
+ DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ llvm::sys::Path InstallDir(D.InstalledDir);
+ std::string Ver(GetGCCLibAndIncVersion());
+ std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
+ std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
+ addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
+ addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
+ addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
+}
+
+void Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+ DriverArgs.hasArg(options::OPT_nostdincxx))
+ return;
+
+ const Driver &D = getDriver();
+ std::string Ver(GetGCCLibAndIncVersion());
+ llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
+
+ IncludeDir.appendComponent("hexagon/include/c++/");
+ IncludeDir.appendComponent(Ver);
+ addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
+}
+
+ToolChain::CXXStdlibType
+Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
+ Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+ if (!A)
+ return ToolChain::CST_Libstdcxx;
+
+ StringRef Value = A->getValue();
+ if (Value != "libstdc++") {
+ getDriver().Diag(diag::err_drv_invalid_stdlib_name)
+ << A->getAsString(Args);
}
- return *T;
+ return ToolChain::CST_Libstdcxx;
}
-bool Hexagon_TC::isPICDefault() const {
- return false;
+static Arg *GetLastHexagonArchArg(const ArgList &Args)
+{
+ Arg *A = NULL;
+
+ for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+ it != ie; ++it) {
+ if ((*it)->getOption().matches(options::OPT_march_EQ) ||
+ (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
+ A = *it;
+ A->claim();
+ } else if ((*it)->getOption().matches(options::OPT_m_Joined)) {
+ StringRef Value = (*it)->getValue(0);
+ if (Value.startswith("v")) {
+ A = *it;
+ A->claim();
+ }
+ }
+ }
+ return A;
}
-bool Hexagon_TC::isPICDefaultForced() const {
- return false;
+StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
+{
+ // Select the default CPU (v4) if none was given or detection failed.
+ Arg *A = GetLastHexagonArchArg (Args);
+ if (A) {
+ StringRef WhichHexagon = A->getValue();
+ if (WhichHexagon.startswith("hexagon"))
+ return WhichHexagon.substr(sizeof("hexagon") - 1);
+ if (WhichHexagon != "")
+ return WhichHexagon;
+ }
+
+ return "v4";
}
+// 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.
-TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple) {
+TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args)
+ : ToolChain(D, Triple, Args) {
// Path mangling to find libexec
std::string Path(getDriver().Dir);
@@ -1459,9 +1620,6 @@ TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple)
}
TCEToolChain::~TCEToolChain() {
- for (llvm::DenseMap<unsigned, Tool*>::iterator
- it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
- delete it->second;
}
bool TCEToolChain::IsMathErrnoDefault() const {
@@ -1476,26 +1634,6 @@ bool TCEToolChain::isPICDefaultForced() const {
return false;
}
-Tool &TCEToolChain::SelectTool(const Compilation &C,
- const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- Key = Action::AnalyzeJobClass;
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::PreprocessJobClass:
- T = new tools::gcc::Preprocess(*this); break;
- case Action::AnalyzeJobClass:
- T = new tools::Clang(*this); break;
- default:
- llvm_unreachable("Unsupported action for TCE target.");
- }
- }
- return *T;
-}
-
/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
@@ -1504,36 +1642,12 @@ OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg
getFilePaths().push_back("/usr/lib");
}
-Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass: {
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::openbsd::Assemble(*this);
- break;
- }
- case Action::LinkJobClass:
- T = new tools::openbsd::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *OpenBSD::buildAssembler() const {
+ return new tools::openbsd::Assemble(*this);
+}
- return *T;
+Tool *OpenBSD::buildLinker() const {
+ return new tools::openbsd::Link(*this);
}
/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
@@ -1544,36 +1658,12 @@ Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
getFilePaths().push_back("/usr/lib");
}
-Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass: {
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::bitrig::Assemble(*this);
- break;
- }
- case Action::LinkJobClass:
- T = new tools::bitrig::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *Bitrig::buildAssembler() const {
+ return new tools::bitrig::Assemble(*this);
+}
- return *T;
+Tool *Bitrig::buildLinker() const {
+ return new tools::bitrig::Link(*this);
}
void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
@@ -1636,35 +1726,12 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg
getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
}
-Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::freebsd::Assemble(*this);
- break;
- case Action::LinkJobClass:
- T = new tools::freebsd::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *FreeBSD::buildAssembler() const {
+ return new tools::freebsd::Assemble(*this);
+}
- return *T;
+Tool *FreeBSD::buildLinker() const {
+ return new tools::freebsd::Link(*this);
}
bool FreeBSD::UseSjLjExceptions() const {
@@ -1698,36 +1765,12 @@ NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
}
}
-Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::netbsd::Assemble(*this);
- break;
- case Action::LinkJobClass:
- T = new tools::netbsd::Link(*this);
- break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *NetBSD::buildAssembler() const {
+ return new tools::netbsd::Assemble(*this);
+}
- return *T;
+Tool *NetBSD::buildLinker() const {
+ return new tools::netbsd::Link(*this);
}
/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
@@ -1738,27 +1781,12 @@ Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
getFilePaths().push_back("/usr/lib");
}
-Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- T = new tools::minix::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::minix::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *Minix::buildAssembler() const {
+ return new tools::minix::Assemble(*this);
+}
- return *T;
+Tool *Minix::buildLinker() const {
+ return new tools::minix::Link(*this);
}
/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
@@ -1779,27 +1807,12 @@ AuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
}
-Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- T = new tools::auroraux::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::auroraux::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *AuroraUX::buildAssembler() const {
+ return new tools::auroraux::Assemble(*this);
+}
- return *T;
+Tool *AuroraUX::buildLinker() const {
+ return new tools::auroraux::Link(*this);
}
/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
@@ -1816,36 +1829,22 @@ Solaris::Solaris(const Driver &D, const llvm::Triple& Triple,
getFilePaths().push_back("/usr/lib");
}
-Tool &Solaris::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- T = new tools::solaris::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::solaris::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *Solaris::buildAssembler() const {
+ return new tools::solaris::Assemble(*this);
+}
- return *T;
+Tool *Solaris::buildLinker() const {
+ return new tools::solaris::Link(*this);
}
-/// Linux toolchain (very bare-bones at the moment).
+/// Distribution (very bare-bones at the moment).
-enum LinuxDistro {
+enum Distro {
ArchLinux,
DebianLenny,
DebianSqueeze,
DebianWheezy,
+ DebianJessie,
Exherbo,
RHEL4,
RHEL5,
@@ -1873,33 +1872,33 @@ enum LinuxDistro {
UnknownDistro
};
-static bool IsRedhat(enum LinuxDistro Distro) {
+static bool IsRedhat(enum Distro Distro) {
return (Distro >= Fedora13 && Distro <= FedoraRawhide) ||
(Distro >= RHEL4 && Distro <= RHEL6);
}
-static bool IsOpenSuse(enum LinuxDistro Distro) {
+static bool IsOpenSuse(enum Distro Distro) {
return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2;
}
-static bool IsDebian(enum LinuxDistro Distro) {
- return Distro >= DebianLenny && Distro <= DebianWheezy;
+static bool IsDebian(enum Distro Distro) {
+ return Distro >= DebianLenny && Distro <= DebianJessie;
}
-static bool IsUbuntu(enum LinuxDistro Distro) {
+static bool IsUbuntu(enum Distro Distro) {
return Distro >= UbuntuHardy && Distro <= UbuntuRaring;
}
-static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
+static Distro DetectDistro(llvm::Triple::ArchType Arch) {
OwningPtr<llvm::MemoryBuffer> File;
if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
StringRef Data = File.get()->getBuffer();
SmallVector<StringRef, 8> Lines;
Data.split(Lines, "\n");
- LinuxDistro Version = UnknownDistro;
+ Distro Version = UnknownDistro;
for (unsigned i = 0, s = Lines.size(); i != s; ++i)
if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME="))
- Version = llvm::StringSwitch<LinuxDistro>(Lines[i].substr(17))
+ Version = llvm::StringSwitch<Distro>(Lines[i].substr(17))
.Case("hardy", UbuntuHardy)
.Case("intrepid", UbuntuIntrepid)
.Case("jaunty", UbuntuJaunty)
@@ -1932,11 +1931,11 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
Data.find("release 6") != StringRef::npos)
return RHEL6;
else if ((Data.startswith("Red Hat Enterprise Linux") ||
- Data.startswith("CentOS")) &&
+ Data.startswith("CentOS")) &&
Data.find("release 5") != StringRef::npos)
return RHEL5;
else if ((Data.startswith("Red Hat Enterprise Linux") ||
- Data.startswith("CentOS")) &&
+ Data.startswith("CentOS")) &&
Data.find("release 4") != StringRef::npos)
return RHEL4;
return UnknownDistro;
@@ -1950,11 +1949,13 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
return DebianSqueeze;
else if (Data.startswith("wheezy/sid") || Data[0] == '7')
return DebianWheezy;
+ else if (Data.startswith("jessie/sid") || Data[0] == '8')
+ return DebianJessie;
return UnknownDistro;
}
if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File))
- return llvm::StringSwitch<LinuxDistro>(File.get()->getBuffer())
+ return llvm::StringSwitch<Distro>(File.get()->getBuffer())
.StartsWith("openSUSE 11.3", OpenSuse11_3)
.StartsWith("openSUSE 11.4", OpenSuse11_4)
.StartsWith("openSUSE 12.1", OpenSuse12_1)
@@ -2007,6 +2008,9 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
return "x86_64-linux-gnu";
return TargetTriple.str();
+ case llvm::Triple::aarch64:
+ if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
+ return "aarch64-linux-gnu";
case llvm::Triple::mips:
if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
return "mips-linux-gnu";
@@ -2016,6 +2020,8 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
return "mipsel-linux-gnu";
return TargetTriple.str();
case llvm::Triple::ppc:
+ if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
+ return "powerpc-linux-gnuspe";
if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))
return "powerpc-linux-gnu";
return TargetTriple.str();
@@ -2083,7 +2089,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Linker = GetProgramPath("ld");
- LinuxDistro Distro = DetectLinuxDistro(Arch);
+ Distro Distro = DetectDistro(Arch);
if (IsOpenSuse(Distro) || IsUbuntu(Distro)) {
ExtraOpts.push_back("-z");
@@ -2114,7 +2120,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
ExtraOpts.push_back("--no-add-needed");
if (Distro == DebianSqueeze || Distro == DebianWheezy ||
- IsOpenSuse(Distro) ||
+ Distro == DebianJessie || IsOpenSuse(Distro) ||
(IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
(IsUbuntu(Distro) && Distro >= UbuntuKarmic))
ExtraOpts.push_back("--build-id");
@@ -2197,40 +2203,24 @@ bool Linux::HasNativeLLVMSupport() const {
return true;
}
-Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- if (UseIntegratedAs)
- T = new tools::ClangAs(*this);
- else
- T = new tools::linuxtools::Assemble(*this);
- break;
- case Action::LinkJobClass:
- T = new tools::linuxtools::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *Linux::buildLinker() const {
+ return new tools::gnutools::Link(*this);
+}
- return *T;
+Tool *Linux::buildAssembler() const {
+ return new tools::gnutools::Assemble(*this);
}
-void Linux::addClangTargetOptions(ArgStringList &CC1Args) const {
+void Linux::addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
- if (V >= Generic_GCC::GCCVersion::Parse("4.7.0"))
+ bool UseInitArrayDefault
+ = V >= Generic_GCC::GCCVersion::Parse("4.7.0") ||
+ getTriple().getArch() == llvm::Triple::aarch64 ||
+ getTriple().getEnvironment() == llvm::Triple::Android;
+ if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
+ options::OPT_fno_use_init_array,
+ UseInitArrayDefault))
CC1Args.push_back("-fuse-init-array");
}
@@ -2289,6 +2279,9 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
"/usr/include/i686-linux-gnu",
"/usr/include/i486-linux-gnu"
};
+ const StringRef AArch64MultiarchIncludeDirs[] = {
+ "/usr/include/aarch64-linux-gnu"
+ };
const StringRef ARMMultiarchIncludeDirs[] = {
"/usr/include/arm-linux-gnueabi"
};
@@ -2312,6 +2305,8 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::x86) {
MultiarchIncludeDirs = X86MultiarchIncludeDirs;
+ } else if (getTriple().getArch() == llvm::Triple::aarch64) {
+ MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::arm) {
if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
@@ -2346,7 +2341,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
}
-/// \brief Helper to add the thre variant paths for a libstdc++ installation.
+/// \brief Helper to add the three variant paths for a libstdc++ installation.
/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
const ArgList &DriverArgs,
ArgStringList &CC1Args) {
@@ -2358,6 +2353,22 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
return true;
}
+/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
+/// libstdc++ installation.
+/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
+ Twine TargetArchDir,
+ Twine MultiLibSuffix,
+ const ArgList &DriverArgs,
+ ArgStringList &CC1Args) {
+ if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix,
+ DriverArgs, CC1Args))
+ return false;
+
+ addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
+ + MultiLibSuffix);
+ return true;
+}
+
void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
@@ -2385,8 +2396,14 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
StringRef Version = GCCInstallation.getVersion().Text;
StringRef TripleStr = GCCInstallation.getTriple().str();
+ if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
+ "/c++/" + Version.str(),
+ TripleStr,
+ GCCInstallation.getMultiarchSuffix(),
+ DriverArgs, CC1Args))
+ return;
+
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.
InstallDir.str() + "/include/g++-v4",
@@ -2420,25 +2437,10 @@ DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList
getFilePaths().push_back("/usr/lib/gcc41");
}
-Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::AssembleJobClass:
- T = new tools::dragonfly::Assemble(*this); break;
- case Action::LinkJobClass:
- T = new tools::dragonfly::Link(*this); break;
- default:
- T = &Generic_GCC::SelectTool(C, JA, Inputs);
- }
- }
+Tool *DragonFly::buildAssembler() const {
+ return new tools::dragonfly::Assemble(*this);
+}
- return *T;
+Tool *DragonFly::buildLinker() const {
+ return new tools::dragonfly::Link(*this);
}
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
index 6f0ca83..3421c53 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
@@ -10,15 +10,13 @@
#ifndef CLANG_LIB_DRIVER_TOOLCHAINS_H_
#define CLANG_LIB_DRIVER_TOOLCHAINS_H_
+#include "Tools.h"
+#include "clang/Basic/VersionTuple.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/ToolChain.h"
-
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Compiler.h"
-#include "Tools.h"
-
namespace clang {
namespace driver {
namespace toolchains {
@@ -119,20 +117,19 @@ protected:
GCCInstallationDetector GCCInstallation;
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
-
public:
Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
~Generic_GCC();
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
virtual bool IsUnwindTablesDefault() const;
virtual bool isPICDefault() const;
virtual bool isPICDefaultForced() const;
protected:
+ virtual Tool *getTool(Action::ActionClass AC) const;
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+
/// \name ToolChain Implementation Helper Functions
/// @{
@@ -143,21 +140,11 @@ protected:
bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
/// @}
-};
-
-class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain {
-protected:
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
-
-public:
- Hexagon_TC(const Driver &D, const llvm::Triple& Triple);
- ~Hexagon_TC();
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
- virtual bool isPICDefault() const;
- virtual bool isPICDefaultForced() const;
+private:
+ mutable OwningPtr<tools::gcc::Preprocess> Preprocess;
+ mutable OwningPtr<tools::gcc::Precompile> Precompile;
+ mutable OwningPtr<tools::gcc::Compile> Compile;
};
/// Darwin - The base Darwin tool chain.
@@ -166,8 +153,15 @@ public:
/// The host version.
unsigned DarwinVersion[3];
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+ virtual Tool *getTool(Action::ActionClass AC) const;
+
private:
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
+ mutable OwningPtr<tools::darwin::Lipo> Lipo;
+ mutable OwningPtr<tools::darwin::Dsymutil> Dsymutil;
+ mutable OwningPtr<tools::darwin::VerifyDebug> VerifyDebug;
/// Whether the information on the target has been initialized.
//
@@ -198,7 +192,7 @@ private:
void AddDeploymentTarget(DerivedArgList &Args) const;
public:
- Darwin(const Driver &D, const llvm::Triple& Triple);
+ Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
~Darwin();
std::string ComputeEffectiveClangTriple(const ArgList &Args,
@@ -286,9 +280,6 @@ public:
virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
const char *BoundArch) const;
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
virtual bool IsBlocksDefault() const {
// Always allow blocks on Darwin; users interested in versioning are
// expected to use /usr/include/Blocks.h.
@@ -314,10 +305,6 @@ public:
return false;
}
- virtual bool IsObjCDefaultSynthPropertiesDefault() const {
- return true;
- }
-
virtual bool IsEncodeExtendedBlockSignatureDefault() const {
return true;
}
@@ -363,16 +350,17 @@ public:
/// DarwinClang - The Darwin toolchain used by Clang.
class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
public:
- DarwinClang(const Driver &D, const llvm::Triple& Triple);
+ DarwinClang(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
/// @name Darwin ToolChain Implementation
/// {
virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
- void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
- const char *DarwinStaticLib) const;
-
+ void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
+ const char *DarwinStaticLib,
+ bool AlwaysLink = false) const;
+
virtual void AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
@@ -393,7 +381,7 @@ public:
std::string ComputeEffectiveClangTriple(const ArgList &Args,
types::ID InputType) const;
- virtual bool isPICDefault() const { return false; };
+ virtual bool isPICDefault() const { return false; }
};
class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
@@ -404,7 +392,8 @@ public:
virtual bool IsIntegratedAssemblerDefault() const {
// Default integrated assembler to on for x86.
- return (getTriple().getArch() == llvm::Triple::x86 ||
+ return (getTriple().getArch() == llvm::Triple::aarch64 ||
+ getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64);
}
};
@@ -413,18 +402,20 @@ class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
public:
AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
public:
Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
virtual bool IsIntegratedAssemblerDefault() const { return true; }
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+
};
@@ -435,8 +426,9 @@ public:
virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
@@ -447,9 +439,6 @@ public:
virtual bool IsObjCNonFragileABIDefault() const { return true; }
virtual bool IsObjCLegacyDispatchDefault() const { return false; }
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
virtual void AddCXXStdlibLibArgs(const ArgList &Args,
@@ -457,6 +446,10 @@ public:
virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
return 1;
}
+
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
@@ -466,9 +459,10 @@ public:
virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
virtual bool UseSjLjExceptions() const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
@@ -478,16 +472,18 @@ public:
virtual bool IsMathErrnoDefault() const { return false; }
virtual bool IsObjCNonFragileABIDefault() const { return true; }
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
public:
Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
@@ -496,8 +492,9 @@ public:
virtual bool IsMathErrnoDefault() const { return false; }
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
};
class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
@@ -506,55 +503,71 @@ public:
virtual bool HasNativeLLVMSupport() const;
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
- virtual void addClangTargetOptions(ArgStringList &CC1Args) const;
+ virtual void addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
std::string Linker;
std::vector<std::string> ExtraOpts;
+protected:
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+
private:
+ static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
+ Twine TargetArchDir,
+ Twine MultiLibSuffix,
+ const ArgList &DriverArgs,
+ ArgStringList &CC1Args);
static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
const ArgList &DriverArgs,
ArgStringList &CC1Args);
};
+class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux {
+protected:
+ GCCVersion GCCLibAndIncVersion;
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+
+public:
+ Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args);
+ ~Hexagon_TC();
+
+ virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
+ virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
+ virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const;
+
+ StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
+
+ static std::string GetGnuDir(const std::string &InstalledDir);
+
+ static StringRef GetTargetCPU(const ArgList &Args);
+};
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
public:
- TCEToolChain(const Driver &D, const llvm::Triple& Triple);
+ TCEToolChain(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args);
~TCEToolChain();
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
bool IsMathErrnoDefault() const;
bool isPICDefault() const;
bool isPICDefaultForced() const;
-
-private:
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
-
};
class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
-
public:
- Windows(const Driver &D, const llvm::Triple& Triple);
-
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
- virtual bool IsObjCDefaultSynthPropertiesDefault() const {
- return true;
- }
+ Windows(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
virtual bool IsIntegratedAssemblerDefault() const;
virtual bool IsUnwindTablesDefault() const;
@@ -565,7 +578,9 @@ public:
ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
-
+protected:
+ virtual Tool *buildLinker() const;
+ virtual Tool *buildAssembler() const;
};
} // end namespace toolchains
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index 5739fa1..294b791 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -8,33 +8,31 @@
//===----------------------------------------------------------------------===//
#include "Tools.h"
-
+#include "InputInfo.h"
+#include "SanitizerArgs.h"
+#include "ToolChains.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Version.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/Compilation.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
-#include "clang/Basic/ObjCRuntime.h"
-
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Process.h"
-#include "llvm/Support/ErrorHandling.h"
-
-#include "InputInfo.h"
-#include "SanitizerArgs.h"
-#include "ToolChains.h"
+#include "llvm/Support/raw_ostream.h"
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -230,6 +228,7 @@ static bool forwardToGCC(const Option &O) {
}
void Clang::AddPreprocessingOptions(Compilation &C,
+ const JobAction &JA,
const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
@@ -250,15 +249,15 @@ void Clang::AddPreprocessingOptions(Compilation &C,
const char *DepFile;
if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
DepFile = MF->getValue();
- C.addFailureResultFile(DepFile);
+ C.addFailureResultFile(DepFile, &JA);
} else if (Output.getType() == types::TY_Dependencies) {
DepFile = Output.getFilename();
} else if (A->getOption().matches(options::OPT_M) ||
A->getOption().matches(options::OPT_MM)) {
DepFile = "-";
} else {
- DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
- C.addFailureResultFile(DepFile);
+ DepFile = getDependencyFileName(Args, Inputs);
+ C.addFailureResultFile(DepFile, &JA);
}
CmdArgs.push_back("-dependency-file");
CmdArgs.push_back(DepFile);
@@ -415,21 +414,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
}
}
-
- // If a module path was provided, pass it along. Otherwise, use a temporary
- // directory.
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_cache_path)) {
- A->claim();
- A->render(Args, CmdArgs);
- } else {
- SmallString<128> DefaultModuleCache;
- llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
- DefaultModuleCache);
- llvm::sys::path::append(DefaultModuleCache, "clang-module-cache");
- CmdArgs.push_back("-fmodule-cache-path");
- CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
- }
-
+
// Parse additional include paths from environment variables.
// FIXME: We should probably sink the logic for handling these from the
// frontend into the driver. It will allow deleting 4 otherwise unused flags.
@@ -471,10 +456,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", "cortex-a15", "v7")
- .Case("cortex-m3", "v7m")
- .Case("cortex-m4", "v7m")
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
+ .Cases("cortex-a9", "cortex-a15", "v7")
+ .Case("cortex-r5", "v7r")
.Case("cortex-m0", "v6m")
+ .Case("cortex-m3", "v7m")
+ .Case("cortex-m4", "v7em")
.Case("cortex-a9-mp", "v7f")
.Case("swift", "v7s")
.Default("");
@@ -530,7 +517,9 @@ static std::string getARMTargetCPU(const ArgList &Args,
.Case("armv6j", "arm1136j-s")
.Cases("armv6z", "armv6zk", "arm1176jzf-s")
.Case("armv6t2", "arm1156t2-s")
+ .Cases("armv6m", "armv6-m", "cortex-m0")
.Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
+ .Cases("armv7em", "armv7e-m", "cortex-m4")
.Cases("armv7f", "armv7-f", "cortex-a9-mp")
.Cases("armv7s", "armv7-s", "swift")
.Cases("armv7r", "armv7-r", "cortex-r4")
@@ -538,7 +527,6 @@ static std::string getARMTargetCPU(const ArgList &Args,
.Case("ep9312", "ep9312")
.Case("iwmmxt", "iwmmxt")
.Case("xscale", "xscale")
- .Cases("armv6m", "armv6-m", "cortex-m0")
// If all else failed, return the most base CPU LLVM supports.
.Default("arm7tdmi");
}
@@ -549,6 +537,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
default:
return true;
+ case llvm::Triple::aarch64:
case llvm::Triple::arm:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
@@ -609,8 +598,9 @@ static void addFPMathArgs(const Driver &D, const Arg *A, const ArgList &Args,
CmdArgs.push_back("-target-feature");
CmdArgs.push_back("+neonfp");
- if (CPU != "cortex-a8" && CPU != "cortex-a9" && CPU != "cortex-a9-mp" &&
- CPU != "cortex-a15")
+ if (CPU != "cortex-a5" && CPU != "cortex-a7" &&
+ 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" ||
@@ -883,8 +873,8 @@ static void getMipsCPUAndABI(const ArgList &Args,
if (!ABIName.empty()) {
// Deduce CPU name from ABI name.
CPUName = llvm::StringSwitch<const char *>(ABIName)
- .Cases("o32", "eabi", DefMips32CPU)
- .Cases("n32", "n64", DefMips64CPU)
+ .Cases("32", "o32", "eabi", DefMips32CPU)
+ .Cases("n32", "n64", "64", DefMips64CPU)
.Default("");
}
else if (!CPUName.empty()) {
@@ -898,6 +888,14 @@ static void getMipsCPUAndABI(const ArgList &Args,
// FIXME: Warn on inconsistent cpu and abi usage.
}
+// Convert ABI name to the GNU tools acceptable variant.
+static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
+ return llvm::StringSwitch<llvm::StringRef>(ABI)
+ .Case("o32", "32")
+ .Case("n64", "64")
+ .Default(ABI);
+}
+
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
// and -mfloat-abi=.
static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
@@ -960,7 +958,9 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
StringRef FloatABI = getMipsFloatABI(D, Args);
- if (FloatABI == "soft") {
+ bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
+
+ if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
// Floating point operations and argument passing are soft.
CmdArgs.push_back("-msoft-float");
CmdArgs.push_back("-mfloat-abi");
@@ -971,6 +971,11 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
// Now it is the only method.
CmdArgs.push_back("-target-feature");
CmdArgs.push_back("+soft-float");
+
+ if (FloatABI == "hard" && IsMips16) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-mips16-hard-float");
+ }
}
else if (FloatABI == "single") {
// Restrict the use of hardware floating-point
@@ -995,6 +1000,13 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
options::OPT_mdspr2, options::OPT_mno_dspr2,
"dspr2");
+ if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
+ if (A->getOption().matches(options::OPT_mxgot)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-mxgot");
+ }
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_G)) {
StringRef v = A->getValue();
CmdArgs.push_back("-mllvm");
@@ -1029,6 +1041,7 @@ static std::string getPPCTargetCPU(const ArgList &Args) {
.Case("604", "604")
.Case("604e", "604e")
.Case("620", "620")
+ .Case("630", "pwr3")
.Case("G3", "g3")
.Case("7400", "7400")
.Case("G4", "g4")
@@ -1038,10 +1051,23 @@ static std::string getPPCTargetCPU(const ArgList &Args) {
.Case("970", "970")
.Case("G5", "g5")
.Case("a2", "a2")
+ .Case("a2q", "a2q")
.Case("e500mc", "e500mc")
.Case("e5500", "e5500")
+ .Case("power3", "pwr3")
+ .Case("power4", "pwr4")
+ .Case("power5", "pwr5")
+ .Case("power5x", "pwr5x")
.Case("power6", "pwr6")
+ .Case("power6x", "pwr6x")
.Case("power7", "pwr7")
+ .Case("pwr3", "pwr3")
+ .Case("pwr4", "pwr4")
+ .Case("pwr5", "pwr5")
+ .Case("pwr5x", "pwr5x")
+ .Case("pwr6", "pwr6")
+ .Case("pwr6x", "pwr6x")
+ .Case("pwr7", "pwr7")
.Case("powerpc", "ppc")
.Case("powerpc64", "ppc64")
.Default("");
@@ -1069,6 +1095,55 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
CmdArgs.push_back("-target-cpu");
CmdArgs.push_back(Args.MakeArgString(TargetCPUName.c_str()));
}
+
+ // Allow override of the Altivec feature.
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_faltivec, options::OPT_fno_altivec,
+ "altivec");
+
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mfprnd, options::OPT_mno_fprnd,
+ "fprnd");
+
+ // Note that gcc calls this mfcrf and LLVM calls this mfocrf.
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mmfcrf, options::OPT_mno_mfcrf,
+ "mfocrf");
+
+ AddTargetFeature(Args, CmdArgs,
+ options::OPT_mpopcntd, options::OPT_mno_popcntd,
+ "popcntd");
+
+ // It is really only possible to turn qpx off because turning qpx on is tied
+ // to using the a2q CPU.
+ if (Args.hasFlag(options::OPT_mno_qpx, options::OPT_mqpx, false)) {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-qpx");
+ }
+}
+
+/// Get the (LLVM) name of the R600 gpu we are targeting.
+static std::string getR600TargetGPU(const ArgList &Args) {
+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ std::string GPUName = A->getValue();
+ return llvm::StringSwitch<const char *>(GPUName)
+ .Cases("rv610", "rv620", "rv630", "r600")
+ .Cases("rv635", "rs780", "rs880", "r600")
+ .Case("rv740", "rv770")
+ .Case("palm", "cedar")
+ .Cases("sumo", "sumo2", "redwood")
+ .Case("hemlock", "cypress")
+ .Case("aruba", "cayman")
+ .Default(GPUName.c_str());
+ }
+ return "";
+}
+
+void Clang::AddR600TargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ std::string TargetGPUName = getR600TargetGPU(Args);
+ CmdArgs.push_back("-target-cpu");
+ CmdArgs.push_back(Args.MakeArgString(TargetGPUName.c_str()));
}
void Clang::AddSparcTargetArgs(const ArgList &Args,
@@ -1174,9 +1249,18 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
Args.hasArg(options::OPT_fapple_kext))
CmdArgs.push_back("-disable-red-zone");
- if (Args.hasFlag(options::OPT_msoft_float,
- options::OPT_mno_soft_float,
- false))
+ // Default to avoid implicit floating-point for kernel/kext code, but allow
+ // that to be overridden with -mno-soft-float.
+ bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_fapple_kext));
+ if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
+ options::OPT_mno_soft_float,
+ options::OPT_mno_implicit_float)) {
+ const Option &O = A->getOption();
+ NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
+ O.matches(options::OPT_msoft_float));
+ }
+ if (NoImplicitFloat)
CmdArgs.push_back("-no-implicit-float");
if (const char *CPUName = getX86TargetCPU(Args, getToolChain().getTriple())) {
@@ -1219,43 +1303,26 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
}
}
-static Arg* getLastHexagonArchArg (const ArgList &Args)
-{
- Arg * A = NULL;
-
- for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
- it != ie; ++it) {
- if ((*it)->getOption().matches(options::OPT_march_EQ) ||
- (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
- A = *it;
- A->claim();
- }
- else if ((*it)->getOption().matches(options::OPT_m_Joined)){
- StringRef Value = (*it)->getValue(0);
- if (Value.startswith("v")) {
- A = *it;
- A->claim();
- }
- }
- }
- return A;
+static inline bool HasPICArg(const ArgList &Args) {
+ return Args.hasArg(options::OPT_fPIC)
+ || Args.hasArg(options::OPT_fpic);
}
-static StringRef getHexagonTargetCPU(const ArgList &Args)
-{
- Arg *A;
- llvm::StringRef WhichHexagon;
+static Arg *GetLastSmallDataThresholdArg(const ArgList &Args) {
+ return Args.getLastArg(options::OPT_G,
+ options::OPT_G_EQ,
+ options::OPT_msmall_data_threshold_EQ);
+}
- // Select the default CPU (v4) if none was given or detection failed.
- if ((A = getLastHexagonArchArg (Args))) {
- WhichHexagon = A->getValue();
- if (WhichHexagon == "")
- return "v4";
- else
- return WhichHexagon;
+static std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) {
+ std::string value;
+ if (HasPICArg(Args))
+ value = "0";
+ else if (Arg *A = GetLastSmallDataThresholdArg(Args)) {
+ value = A->getValue();
+ A->claim();
}
- else
- return "v4";
+ return value;
}
void Clang::AddHexagonTargetArgs(const ArgList &Args,
@@ -1263,20 +1330,18 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
llvm::Triple Triple = getToolChain().getTriple();
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString("hexagon" + getHexagonTargetCPU(Args)));
+ CmdArgs.push_back(Args.MakeArgString(
+ "hexagon"
+ + toolchains::Hexagon_TC::GetTargetCPU(Args)));
CmdArgs.push_back("-fno-signed-char");
- CmdArgs.push_back("-nobuiltininc");
-
- if (Args.hasArg(options::OPT_mqdsp6_compat))
- CmdArgs.push_back("-mqdsp6-compat");
+ CmdArgs.push_back("-mqdsp6-compat");
+ CmdArgs.push_back("-Wreturn-type");
- if (Arg *A = Args.getLastArg(options::OPT_G,
- options::OPT_msmall_data_threshold_EQ)) {
- std::string SmallDataThreshold="-small-data-threshold=";
- SmallDataThreshold += A->getValue();
+ std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
+ if (!SmallDataThreshold.empty()) {
CmdArgs.push_back ("-mllvm");
- CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold));
- A->claim();
+ CmdArgs.push_back(Args.MakeArgString(
+ "-hexagon-small-data-threshold=" + SmallDataThreshold));
}
if (!Args.hasArg(options::OPT_fno_short_enums))
@@ -1393,24 +1458,18 @@ static bool ShouldDisableCFI(const ArgList &Args,
if (TC.getTriple().isOSDarwin()) {
// The native darwin assembler doesn't support cfi directives, so
// we disable them if we think the .s file will be passed to it.
- Default = Args.hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- TC.IsIntegratedAssemblerDefault());
+ Default = TC.useIntegratedAs();
}
return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
- options::OPT_fno_dwarf2_cfi_asm,
- Default);
+ options::OPT_fno_dwarf2_cfi_asm,
+ Default);
}
static bool ShouldDisableDwarfDirectory(const ArgList &Args,
const ToolChain &TC) {
- bool IsIADefault = TC.IsIntegratedAssemblerDefault();
- bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIADefault);
bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
options::OPT_fno_dwarf_directory_asm,
- UseIntegratedAs);
+ TC.useIntegratedAs());
return !UseDwarfDirectory;
}
@@ -1449,63 +1508,147 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault);
}
-SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) {
- Kind = 0;
-
- const Arg *AsanArg, *TsanArg, *UbsanArg;
+SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args)
+ : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+ AsanZeroBaseShadow(false) {
+ unsigned AllKinds = 0; // All kinds of sanitizers that were turned on
+ // at least once (possibly, disabled further).
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 {
+ unsigned Add, Remove;
+ if (!parse(D, Args, *I, Add, Remove, true))
continue;
- }
-
(*I)->claim();
-
Kind |= Add;
Kind &= ~Remove;
+ AllKinds |= Add;
+ }
- if (Add & NeedsAsanRt) AsanArg = *I;
- if (Add & NeedsTsanRt) TsanArg = *I;
- if (Add & NeedsUbsanRt) UbsanArg = *I;
+ UbsanTrapOnError =
+ Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
+ Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
+ options::OPT_fno_sanitize_undefined_trap_on_error, false);
- // 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;
+ if (Args.hasArg(options::OPT_fcatch_undefined_behavior) &&
+ !Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
+ options::OPT_fno_sanitize_undefined_trap_on_error, true)) {
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fcatch-undefined-behavior"
+ << "-fno-sanitize-undefined-trap-on-error";
+ }
+
+ // Warn about undefined sanitizer options that require runtime support.
+ if (UbsanTrapOnError && notAllowedWithTrap()) {
+ if (Args.hasArg(options::OPT_fcatch_undefined_behavior))
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << lastArgumentForKind(D, Args, NotAllowedWithTrap)
+ << "-fcatch-undefined-behavior";
+ else if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
+ options::OPT_fno_sanitize_undefined_trap_on_error,
+ false))
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << lastArgumentForKind(D, Args, NotAllowedWithTrap)
+ << "-fsanitize-undefined-trap-on-error";
}
// 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)
+ bool NeedsMsan = needsMsanRt();
+ if (NeedsAsan && NeedsTsan)
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);
+ << lastArgumentForKind(D, Args, NeedsAsanRt)
+ << lastArgumentForKind(D, Args, NeedsTsanRt);
+ if (NeedsAsan && NeedsMsan)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << lastArgumentForKind(D, Args, NeedsAsanRt)
+ << lastArgumentForKind(D, Args, NeedsMsanRt);
+ if (NeedsTsan && NeedsMsan)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << lastArgumentForKind(D, Args, NeedsTsanRt)
+ << lastArgumentForKind(D, Args, NeedsMsanRt);
+
+ // If -fsanitize contains extra features of ASan, it should also
+ // explicitly contain -fsanitize=address (probably, turned off later in the
+ // command line).
+ if ((Kind & AddressFull) != 0 && (AllKinds & Address) == 0)
+ D.Diag(diag::warn_drv_unused_sanitizer)
+ << lastArgumentForKind(D, Args, AddressFull)
+ << "-fsanitize=address";
+
+ // Parse -f(no-)sanitize-blacklist options.
+ if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
+ options::OPT_fno_sanitize_blacklist)) {
+ if (BLArg->getOption().matches(options::OPT_fsanitize_blacklist)) {
+ std::string BLPath = BLArg->getValue();
+ bool BLExists = false;
+ if (!llvm::sys::fs::exists(BLPath, BLExists) && BLExists)
+ BlacklistFile = BLPath;
+ else
+ D.Diag(diag::err_drv_no_such_file) << BLPath;
+ }
+ } else {
+ // If no -fsanitize-blacklist option is specified, try to look up for
+ // blacklist in the resource directory.
+ std::string BLPath;
+ bool BLExists = false;
+ if (getDefaultBlacklistForKind(D, Kind, BLPath) &&
+ !llvm::sys::fs::exists(BLPath, BLExists) && BLExists)
+ BlacklistFile = BLPath;
+ }
+
+ // Parse -f(no-)sanitize-memory-track-origins options.
+ if (NeedsMsan)
+ MsanTrackOrigins =
+ Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
+ options::OPT_fno_sanitize_memory_track_origins,
+ /* Default */false);
+
+ // Parse -f(no-)sanitize-address-zero-base-shadow options.
+ if (NeedsAsan)
+ AsanZeroBaseShadow =
+ Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
+ options::OPT_fno_sanitize_address_zero_base_shadow,
+ /* Default */false);
+}
+
+static void addSanitizerRTLinkFlagsLinux(
+ const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
+ const StringRef Sanitizer, bool BeforeLibStdCXX,
+ bool ExportSymbols = true) {
+ // Sanitizer runtime is located in the Linux library directory and
+ // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
+ SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(
+ LibSanitizer, "lib", "linux",
+ (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a"));
+
+ // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
+ // etc.) so that the linker picks custom versions of the global 'operator
+ // new' and 'operator delete' symbols. We take the extreme (but simple)
+ // strategy of inserting it at the front of the link command. It also
+ // needs to be forced to end up in the executable, so wrap it in
+ // whole-archive.
+ SmallVector<const char *, 3> LibSanitizerArgs;
+ LibSanitizerArgs.push_back("-whole-archive");
+ LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+ LibSanitizerArgs.push_back("-no-whole-archive");
+
+ CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
+ LibSanitizerArgs.begin(), LibSanitizerArgs.end());
+
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-ldl");
+
+ // If possible, use a dynamic symbols file to export the symbols from the
+ // runtime library. If we can't do so, use -export-dynamic instead to export
+ // all symbols from the binary.
+ if (ExportSymbols) {
+ if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
+ CmdArgs.push_back(
+ Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
+ else
+ CmdArgs.push_back("-export-dynamic");
+ }
}
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
@@ -1522,19 +1665,17 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
llvm::sys::path::append(LibAsan, "lib", "linux",
(Twine("libclang_rt.asan-") +
TC.getArchName() + "-android.so"));
- CmdArgs.push_back(Args.MakeArgString(LibAsan));
+ CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
} else {
if (!Args.hasArg(options::OPT_shared)) {
- // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibAsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibAsan, "lib", "linux",
- (Twine("libclang_rt.asan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibAsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
+ bool ZeroBaseShadow = Args.hasFlag(
+ options::OPT_fsanitize_address_zero_base_shadow,
+ options::OPT_fno_sanitize_address_zero_base_shadow, false);
+ if (ZeroBaseShadow && !Args.hasArg(options::OPT_pie)) {
+ TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
+ "-fsanitize-address-zero-base-shadow" << "-pie";
+ }
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
}
}
}
@@ -1544,33 +1685,44 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) {
- // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibTsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibTsan, "lib", "linux",
- (Twine("libclang_rt.tsan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibTsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
+ if (!Args.hasArg(options::OPT_pie))
+ TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
+ "-fsanitize=thread" << "-pie";
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
+ }
+}
+
+/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
+/// This needs to be called before we add the C run-time (malloc, etc).
+static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ if (!Args.hasArg(options::OPT_pie))
+ TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
+ "-fsanitize=memory" << "-pie";
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
}
}
/// 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");
- }
+ ArgStringList &CmdArgs, bool IsCXX,
+ bool HasOtherSanitizerRt) {
+ if (Args.hasArg(options::OPT_shared))
+ return;
+
+ // Need a copy of sanitizer_common. This could come from another sanitizer
+ // runtime; if we're not including one, include our own copy.
+ if (!HasOtherSanitizerRt)
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
+
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
+
+ // Only include the bits of the runtime which need a C++ ABI library if
+ // we're linking in C++ mode.
+ if (IsCXX)
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
}
static bool shouldUseFramePointer(const ArgList &Args,
@@ -1591,6 +1743,80 @@ static bool shouldUseFramePointer(const ArgList &Args,
return true;
}
+static bool shouldUseLeafFramePointer(const ArgList &Args,
+ const llvm::Triple &Triple) {
+ if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
+ options::OPT_momit_leaf_frame_pointer))
+ return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
+
+ // Don't use a leaf frame pointer on linux x86 and x86_64 if optimizing.
+ if ((Triple.getArch() == llvm::Triple::x86_64 ||
+ Triple.getArch() == llvm::Triple::x86) &&
+ Triple.getOS() == llvm::Triple::Linux) {
+ if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+ if (!A->getOption().matches(options::OPT_O0))
+ return false;
+ }
+
+ return true;
+}
+
+/// If the PWD environment variable is set, add a CC1 option to specify the
+/// debug compilation directory.
+static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
+ if (const char *pwd = ::getenv("PWD")) {
+ // GCC also verifies that stat(pwd) and stat(".") have the same inode
+ // number. Not doing those because stats are slow, but we could.
+ if (llvm::sys::path::is_absolute(pwd)) {
+ std::string CompDir = pwd;
+ CmdArgs.push_back("-fdebug-compilation-dir");
+ CmdArgs.push_back(Args.MakeArgString(CompDir));
+ }
+ }
+}
+
+static const char *SplitDebugName(const ArgList &Args,
+ const InputInfoList &Inputs) {
+ Arg *FinalOutput = Args.getLastArg(options::OPT_o);
+ if (FinalOutput && Args.hasArg(options::OPT_c)) {
+ SmallString<128> T(FinalOutput->getValue());
+ llvm::sys::path::replace_extension(T, "dwo");
+ return Args.MakeArgString(T);
+ } else {
+ // Use the compilation dir.
+ SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
+ SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput()));
+ llvm::sys::path::replace_extension(F, "dwo");
+ T += F;
+ return Args.MakeArgString(F);
+ }
+}
+
+static void SplitDebugInfo(const ToolChain &TC, Compilation &C,
+ const Tool &T, const JobAction &JA,
+ const ArgList &Args, const InputInfo &Output,
+ const char *OutFile) {
+ ArgStringList ExtractArgs;
+ ExtractArgs.push_back("--extract-dwo");
+
+ ArgStringList StripArgs;
+ StripArgs.push_back("--strip-dwo");
+
+ // Grabbing the output of the earlier compile step.
+ StripArgs.push_back(Output.getFilename());
+ ExtractArgs.push_back(Output.getFilename());
+ ExtractArgs.push_back(OutFile);
+
+ const char *Exec =
+ Args.MakeArgString(TC.GetProgramPath("objcopy"));
+
+ // First extract the dwo sections.
+ C.addCommand(new Command(JA, T, Exec, ExtractArgs));
+
+ // Then remove them from the original .o file.
+ C.addCommand(new Command(JA, T, Exec, StripArgs));
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -1624,8 +1850,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
} else if (isa<PreprocessJobAction>(JA)) {
if (Output.getType() == types::TY_Dependencies)
CmdArgs.push_back("-Eonly");
- else
+ else {
CmdArgs.push_back("-E");
+ if (Args.hasArg(options::OPT_rewrite_objc) &&
+ !Args.hasArg(options::OPT_g_Group))
+ CmdArgs.push_back("-P");
+ }
} else if (isa<AssembleJobAction>(JA)) {
CmdArgs.push_back("-emit-obj");
@@ -1686,6 +1916,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-S");
} else if (JA.getType() == types::TY_AST) {
CmdArgs.push_back("-emit-pch");
+ } else if (JA.getType() == types::TY_ModuleFile) {
+ CmdArgs.push_back("-module-file-info");
} else if (JA.getType() == types::TY_RewrittenObjC) {
CmdArgs.push_back("-rewrite-objc");
rewriteKind = RK_NonFragile;
@@ -1709,10 +1941,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Set the main file name, so that debug info works even with
// -save-temps.
CmdArgs.push_back("-main-file-name");
- CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
+ CmdArgs.push_back(getBaseInputName(Args, Inputs));
// Some flags which affect the language (via preprocessor
- // defines). See darwin::CC1::AddCPPArgs.
+ // defines).
if (Args.hasArg(options::OPT_static))
CmdArgs.push_back("-static-define");
@@ -1808,8 +2040,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// 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.
llvm::Triple Triple(TripleStr);
- if ((Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) &&
+ if (KernelOrKext &&
(Triple.getOS() != llvm::Triple::IOS ||
Triple.isOSVersionLT(6)))
PIC = PIE = false;
@@ -1874,6 +2105,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_strict_aliasing,
getToolChain().IsStrictAliasingDefault()))
CmdArgs.push_back("-relaxed-aliasing");
+ if (Args.hasArg(options::OPT_fstruct_path_tbaa))
+ CmdArgs.push_back("-struct-path-tbaa");
if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
false))
CmdArgs.push_back("-fstrict-enums");
@@ -1881,6 +2114,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_optimize_sibling_calls))
CmdArgs.push_back("-mdisable-tail-calls");
+ // Handle segmented stacks.
+ if (Args.hasArg(options::OPT_fsplit_stack))
+ CmdArgs.push_back("-split-stacks");
+
// Handle various floating point optimization flags, mapping them to the
// appropriate LLVM code generation flags. The pattern for all of these is to
// default off the codegen optimizations, and if any flag enables them and no
@@ -2043,7 +2280,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
AsynchronousUnwindTables))
CmdArgs.push_back("-munwind-tables");
- getToolChain().addClangTargetOptions(CmdArgs);
+ getToolChain().addClangTargetOptions(Args, CmdArgs);
if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("-mlimit-float-precision");
@@ -2080,6 +2317,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
AddPPCTargetArgs(Args, CmdArgs);
break;
+ case llvm::Triple::r600:
+ AddR600TargetArgs(Args, CmdArgs);
+ break;
+
case llvm::Triple::sparc:
AddSparcTargetArgs(Args, CmdArgs);
break;
@@ -2102,10 +2343,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
- // -mno-omit-leaf-frame-pointer is the default on Darwin.
- if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
- options::OPT_mno_omit_leaf_frame_pointer,
- !getToolChain().getTriple().isOSDarwin()))
+ if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
CmdArgs.push_back("-momit-leaf-frame-pointer");
// Explicitly error on some things we know we don't support and can't just
@@ -2139,16 +2377,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
D.CCLogDiagnosticsFilename : "-");
}
- // Use the last option from "-g" group. "-gline-tables-only" is
- // preserved, all other debug options are substituted with "-g".
+ // Use the last option from "-g" group. "-gline-tables-only"
+ // is preserved, all other debug options are substituted with "-g".
Args.ClaimAllArgs(options::OPT_g_Group);
if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
- if (A->getOption().matches(options::OPT_gline_tables_only)) {
+ if (A->getOption().matches(options::OPT_gline_tables_only))
CmdArgs.push_back("-gline-tables-only");
- } else if (!A->getOption().matches(options::OPT_g0) &&
- !A->getOption().matches(options::OPT_ggdb0)) {
+ else if (!A->getOption().matches(options::OPT_g0) &&
+ !A->getOption().matches(options::OPT_ggdb0))
CmdArgs.push_back("-g");
- }
}
// We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
@@ -2156,6 +2393,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_gcolumn_info))
CmdArgs.push_back("-dwarf-column-info");
+ // -gsplit-dwarf should turn on -g and enable the backend dwarf
+ // splitting and extraction.
+ // FIXME: Currently only works on Linux.
+ if (getToolChain().getTriple().getOS() == llvm::Triple::Linux &&
+ Args.hasArg(options::OPT_gsplit_dwarf)) {
+ CmdArgs.push_back("-g");
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-split-dwarf=Enable");
+ }
+
Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
@@ -2172,9 +2419,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
C.getArgs().hasArg(options::OPT_S)) {
if (Output.isFilename()) {
CmdArgs.push_back("-coverage-file");
- SmallString<128> absFilename(Output.getFilename());
- llvm::sys::fs::make_absolute(absFilename);
- CmdArgs.push_back(Args.MakeArgString(absFilename));
+ SmallString<128> CoverageFilename(Output.getFilename());
+ if (llvm::sys::path::is_relative(CoverageFilename.str())) {
+ if (const char *pwd = ::getenv("PWD")) {
+ if (llvm::sys::path::is_absolute(pwd)) {
+ SmallString<128> Pwd(pwd);
+ llvm::sys::path::append(Pwd, CoverageFilename.str());
+ CoverageFilename.swap(Pwd);
+ }
+ }
+ }
+ CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
}
}
@@ -2246,7 +2501,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
//
// FIXME: Support -fpreprocessed
if (types::getPreprocessedType(InputType) != types::TY_INVALID)
- AddPreprocessingOptions(C, D, Args, CmdArgs, Output, Inputs);
+ AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
// Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
// that "The compiler can only warn and ignore the option if not recognized".
@@ -2266,6 +2521,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->render(Args, CmdArgs);
}
+ // Don't warn about unused -flto. This can happen when we're preprocessing or
+ // precompiling.
+ Args.ClaimAllArgs(options::OPT_flto);
+
Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
CmdArgs.push_back("-pedantic");
@@ -2338,15 +2597,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (ShouldDisableDwarfDirectory(Args, getToolChain()))
CmdArgs.push_back("-fno-dwarf-directory-asm");
- if (const char *pwd = ::getenv("PWD")) {
- // GCC also verifies that stat(pwd) and stat(".") have the same inode
- // number. Not doing those because stats are slow, but we could.
- if (llvm::sys::path::is_absolute(pwd)) {
- std::string CompDir = pwd;
- CmdArgs.push_back("-fdebug-compilation-dir");
- CmdArgs.push_back(Args.MakeArgString(CompDir));
- }
- }
+ // Add in -fdebug-compilation-dir if necessary.
+ addDebugCompDirArg(Args, CmdArgs);
if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
options::OPT_ftemplate_depth_EQ)) {
@@ -2359,6 +2611,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
+ CmdArgs.push_back("-fbracket-depth");
+ 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()) {
@@ -2368,14 +2625,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
}
- if (Arg *A = Args.getLastArg(options::OPT_fbounds_checking,
- options::OPT_fbounds_checking_EQ)) {
- if (A->getNumValues()) {
- StringRef val = A->getValue();
- CmdArgs.push_back(Args.MakeArgString("-fbounds-checking=" + val));
- } else
- CmdArgs.push_back("-fbounds-checking=1");
- }
if (Args.hasArg(options::OPT_relocatable_pch))
CmdArgs.push_back("-relocatable-pch");
@@ -2422,9 +2671,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Twine(N)));
}
- if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
- CmdArgs.push_back("-fvisibility");
- CmdArgs.push_back(A->getValue());
+ // -fvisibility= and -fvisibility-ms-compat are of a piece.
+ if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
+ options::OPT_fvisibility_ms_compat)) {
+ if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
+ CmdArgs.push_back("-fvisibility");
+ CmdArgs.push_back(A->getValue());
+ } else {
+ assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
+ CmdArgs.push_back("-fvisibility");
+ CmdArgs.push_back("hidden");
+ CmdArgs.push_back("-ftype-visibility");
+ CmdArgs.push_back("default");
+ }
}
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
@@ -2450,7 +2709,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
SanitizerArgs Sanitize(D, Args);
Sanitize.addArgs(Args, CmdArgs);
- // Report and error for -faltivec on anything other then PowerPC.
+ if (!Args.hasFlag(options::OPT_fsanitize_recover,
+ options::OPT_fno_sanitize_recover,
+ true))
+ CmdArgs.push_back("-fno-sanitize-recover");
+
+ if (Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
+ Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
+ options::OPT_fno_sanitize_undefined_trap_on_error, false))
+ CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
+
+ // Report an error for -faltivec on anything other than PowerPC.
if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
if (!(getToolChain().getTriple().getArch() == llvm::Triple::ppc ||
getToolChain().getTriple().getArch() == llvm::Triple::ppc64))
@@ -2549,7 +2818,8 @@ 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)) {
+ // -mkernel implies -mstrict-align; don't add the redundant option.
+ if (Args.hasArg(options::OPT_mstrict_align) && !KernelOrKext) {
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-arm-strict-align");
}
@@ -2588,12 +2858,49 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fmodules enables modules (off by default). However, for C++/Objective-C++,
// users must also pass -fcxx-modules. The latter flag will disappear once the
// modules implementation is solid for C++/Objective-C++ programs as well.
+ bool HaveModules = false;
if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
options::OPT_fno_cxx_modules,
false);
- if (AllowedInCXX || !types::isCXX(InputType))
+ if (AllowedInCXX || !types::isCXX(InputType)) {
CmdArgs.push_back("-fmodules");
+ HaveModules = true;
+ }
+ }
+
+ // If a module path was provided, pass it along. Otherwise, use a temporary
+ // directory.
+ if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
+ A->claim();
+ if (HaveModules) {
+ A->render(Args, CmdArgs);
+ }
+ } else if (HaveModules) {
+ SmallString<128> DefaultModuleCache;
+ llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+ DefaultModuleCache);
+ llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
+ llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
+ const char Arg[] = "-fmodules-cache-path=";
+ DefaultModuleCache.insert(DefaultModuleCache.begin(),
+ Arg, Arg + strlen(Arg));
+ CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
+ }
+
+ // Pass through all -fmodules-ignore-macro arguments.
+ Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
+ Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
+ Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
+
+ // -fmodules-autolink (on by default when modules is enabled) automatically
+ // links against libraries for imported modules. This requires the
+ // integrated assembler.
+ if (HaveModules && getToolChain().useIntegratedAs() &&
+ Args.hasFlag(options::OPT_fmodules_autolink,
+ options::OPT_fno_modules_autolink,
+ true)) {
+ CmdArgs.push_back("-fmodules-autolink");
}
// -faccess-control is default.
@@ -2655,10 +2962,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().getTriple().getOS() == llvm::Triple::Win32))
CmdArgs.push_back("-fms-extensions");
- // -fms-inline-asm.
- if (Args.hasArg(options::OPT_fenable_experimental_ms_inline_asm))
- CmdArgs.push_back("-fenable-experimental-ms-inline-asm");
-
// -fms-compatibility=0 is default.
if (Args.hasFlag(options::OPT_fms_compatibility,
options::OPT_fno_ms_compatibility,
@@ -2680,7 +2983,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
- // -fborland-extensions=0 is default.
+ // -fno-borland-extensions is default.
if (Args.hasFlag(options::OPT_fborland_extensions,
options::OPT_fno_borland_extensions, false))
CmdArgs.push_back("-fborland-extensions");
@@ -2834,8 +3137,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fpack-struct=1");
}
- if (Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) {
+ if (KernelOrKext) {
if (!Args.hasArg(options::OPT_fcommon))
CmdArgs.push_back("-fno-common");
Args.ClaimAllArgs(options::OPT_fno_common);
@@ -2916,9 +3218,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fno-spell-checking");
- // Silently ignore -fasm-blocks for now.
- (void) Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
- false);
+ // -fno-asm-blocks is default.
+ if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
+ false))
+ CmdArgs.push_back("-fasm-blocks");
+
+ // -fvectorize is default.
+ if (Args.hasFlag(options::OPT_fvectorize,
+ options::OPT_fno_vectorize, true)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-vectorize-loops");
+ }
+
+ // -fno-slp-vectorize is default.
+ if (Args.hasFlag(options::OPT_fslp_vectorize,
+ options::OPT_fno_slp_vectorize, false)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-vectorize");
+ }
if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
A->render(Args, CmdArgs);
@@ -2980,6 +3297,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
CmdArgs.push_back("-fretain-comments-from-system-headers");
+ // Forward -fcomment-block-commands to -cc1.
+ Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
+
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
// parser.
Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
@@ -3040,8 +3360,27 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Flags.str()));
}
+ // Add the split debug info name to the command lines here so we
+ // can propagate it to the backend.
+ bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) &&
+ (getToolChain().getTriple().getOS() == llvm::Triple::Linux) &&
+ (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA));
+ const char *SplitDwarfOut;
+ if (SplitDwarf) {
+ CmdArgs.push_back("-split-dwarf-file");
+ SplitDwarfOut = SplitDebugName(Args, Inputs);
+ CmdArgs.push_back(SplitDwarfOut);
+ }
+
+ // Finally add the compile command to the compilation.
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ // Handle the debug info splitting at object creation time if we're
+ // creating an object.
+ // TODO: Currently only works on linux with newer objcopy.
+ if (SplitDwarf && !isa<CompileJobAction>(JA))
+ SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
+
if (Arg *A = Args.getLastArg(options::OPT_pg))
if (Args.hasArg(options::OPT_fomit_frame_pointer))
D.Diag(diag::err_drv_argument_not_allowed_with)
@@ -3249,6 +3588,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-filetype");
CmdArgs.push_back("obj");
+ // Set the main file name, so that debug info works even with
+ // -save-temps or preprocessed assembly.
+ CmdArgs.push_back("-main-file-name");
+ CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs));
+
if (UseRelaxAll(C, Args))
CmdArgs.push_back("-relax-all");
@@ -3278,13 +3622,22 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
SourceAction = SourceAction->getInputs()[0];
}
- // Forward -g, assuming we are dealing with an actual assembly file.
+ // Forward -g and handle debug info related flags, assuming we are dealing
+ // with an actual assembly file.
if (SourceAction->getType() == types::TY_Asm ||
SourceAction->getType() == types::TY_PP_Asm) {
Args.ClaimAllArgs(options::OPT_g_Group);
if (Arg *A = Args.getLastArg(options::OPT_g_Group))
if (!A->getOption().matches(options::OPT_g0))
CmdArgs.push_back("-g");
+
+ // Add the -fdebug-compilation-dir flag if needed.
+ addDebugCompDirArg(Args, CmdArgs);
+
+ // Set the AT_producer to the clang version when using the integrated
+ // assembler on assembly source files.
+ CmdArgs.push_back("-dwarf-debug-producer");
+ CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
}
// Optionally embed the -cc1as level arguments into the debug info, for build
@@ -3372,7 +3725,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
// here.
if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
CmdArgs.push_back("-m32");
- else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86_64)
+ else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64)
CmdArgs.push_back("-m64");
if (Output.isFilename()) {
@@ -3406,6 +3759,9 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
else if (II.getType() == types::TY_AST)
D.Diag(diag::err_drv_no_ast_support)
<< getToolChain().getTripleString();
+ else if (II.getType() == types::TY_ModuleFile)
+ D.Diag(diag::err_drv_no_module_support)
+ << getToolChain().getTripleString();
if (types::canTypeBeUserSpecified(II.getType())) {
CmdArgs.push_back("-x");
@@ -3494,7 +3850,7 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
ArgStringList CmdArgs;
std::string MarchString = "-march=";
- MarchString += getHexagonTargetCPU(Args);
+ MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
CmdArgs.push_back(Args.MakeArgString(MarchString));
RenderExtraToolArgs(JA, CmdArgs);
@@ -3507,6 +3863,14 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fsyntax-only");
}
+ std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
+ if (!SmallDataThreshold.empty())
+ CmdArgs.push_back(
+ Args.MakeArgString(std::string("-G") + SmallDataThreshold));
+
+ Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
// Only pass -x if gcc will understand it; otherwise hope gcc
// understands the suffix correctly. The main use case this would go
@@ -3528,6 +3892,9 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
else if (II.getType() == types::TY_AST)
D.Diag(clang::diag::err_drv_no_ast_support)
<< getToolChain().getTripleString();
+ else if (II.getType() == types::TY_ModuleFile)
+ D.Diag(diag::err_drv_no_module_support)
+ << getToolChain().getTripleString();
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
@@ -3553,77 +3920,168 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
const ArgList &Args,
const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
+ const toolchains::Hexagon_TC& ToolChain =
+ static_cast<const toolchains::Hexagon_TC&>(getToolChain());
+ const Driver &D = ToolChain.getDriver();
+
ArgStringList CmdArgs;
- for (ArgList::const_iterator
- it = Args.begin(), ie = Args.end(); it != ie; ++it) {
- Arg *A = *it;
- if (forwardToGCC(A->getOption())) {
- // Don't forward any -g arguments to assembly steps.
- if (isa<AssembleJobAction>(JA) &&
- A->getOption().matches(options::OPT_g_Group))
- continue;
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ bool hasStaticArg = Args.hasArg(options::OPT_static);
+ bool buildingLib = Args.hasArg(options::OPT_shared);
+ bool buildPIE = Args.hasArg(options::OPT_pie);
+ bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
+ bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
+ bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
+ bool useShared = buildingLib && !hasStaticArg;
+
+ //----------------------------------------------------------------------------
+ // Silence warnings for various options
+ //----------------------------------------------------------------------------
- // It is unfortunate that we have to claim here, as this means
- // we will basically never report anything interesting for
- // platforms using a generic gcc, even if we are just using gcc
- // to get to the assembler.
- A->claim();
- A->render(Args, CmdArgs);
- }
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
+ // handled somewhere else.
+ Args.ClaimAllArgs(options::OPT_static_libgcc);
+
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
+ e = ToolChain.ExtraOpts.end();
+ i != e; ++i)
+ CmdArgs.push_back(i->c_str());
+
+ std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
+ CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
+
+ if (buildingLib) {
+ CmdArgs.push_back("-shared");
+ CmdArgs.push_back("-call_shared"); // should be the default, but doing as
+ // hexagon-gcc does
}
- RenderExtraToolArgs(JA, CmdArgs);
+ if (hasStaticArg)
+ CmdArgs.push_back("-static");
- // Add Arch Information
- Arg *A;
- if ((A = getLastHexagonArchArg(Args))) {
- if (A->getOption().matches(options::OPT_m_Joined))
- A->render(Args, CmdArgs);
- else
- CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args)));
+ if (buildPIE && !buildingLib)
+ CmdArgs.push_back("-pie");
+
+ std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
+ if (!SmallDataThreshold.empty()) {
+ CmdArgs.push_back(
+ Args.MakeArgString(std::string("-G") + SmallDataThreshold));
}
- else {
- CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args)));
+
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ const std::string MarchSuffix = "/" + MarchString;
+ const std::string G0Suffix = "/G0";
+ const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
+ const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
+ + "/";
+ const std::string StartFilesDir = RootDir
+ + "hexagon/lib"
+ + (buildingLib
+ ? MarchG0Suffix : MarchSuffix);
+
+ //----------------------------------------------------------------------------
+ // moslib
+ //----------------------------------------------------------------------------
+ std::vector<std::string> oslibs;
+ bool hasStandalone= false;
+
+ for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ (*it)->claim();
+ oslibs.push_back((*it)->getValue());
+ hasStandalone = hasStandalone || (oslibs.back() == "standalone");
+ }
+ if (oslibs.empty()) {
+ oslibs.push_back("standalone");
+ hasStandalone = true;
}
- CmdArgs.push_back("-mqdsp6-compat");
+ //----------------------------------------------------------------------------
+ // Start Files
+ //----------------------------------------------------------------------------
+ if (incStdLib && incStartFiles) {
- const char *GCCName;
- if (C.getDriver().CCCIsCXX)
- GCCName = "hexagon-g++";
- else
- GCCName = "hexagon-gcc";
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+ if (!buildingLib) {
+ if (hasStandalone) {
+ CmdArgs.push_back(
+ Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
+ }
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
+ }
+ std::string initObj = useShared ? "/initS.o" : "/init.o";
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
+ }
+
+ //----------------------------------------------------------------------------
+ // Library Search Paths
+ //----------------------------------------------------------------------------
+ const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
+ for (ToolChain::path_list::const_iterator
+ i = LibPaths.begin(),
+ e = LibPaths.end();
+ i != e;
+ ++i)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- }
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_e);
+ Args.AddAllArgs(CmdArgs, options::OPT_s);
+ Args.AddAllArgs(CmdArgs, options::OPT_t);
+ Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- // Don't try to pass LLVM or AST inputs to a generic gcc.
- if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
- II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
- D.Diag(clang::diag::err_drv_no_linker_llvm_support)
- << getToolChain().getTripleString();
- else if (II.getType() == types::TY_AST)
- D.Diag(clang::diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
+ //----------------------------------------------------------------------------
+ // Libraries
+ //----------------------------------------------------------------------------
+ if (incStdLib && incDefLibs) {
+ if (D.CCCIsCXX) {
+ ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+ CmdArgs.push_back("-lm");
+ }
- if (II.isFilename())
- CmdArgs.push_back(II.getFilename());
- else
- // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
- II.getInputArg().render(Args, CmdArgs);
+ CmdArgs.push_back("--start-group");
+
+ if (!buildingLib) {
+ for(std::vector<std::string>::iterator i = oslibs.begin(),
+ e = oslibs.end(); i != e; ++i)
+ CmdArgs.push_back(Args.MakeArgString("-l" + *i));
+ CmdArgs.push_back("-lc");
+ }
+ CmdArgs.push_back("-lgcc");
+
+ CmdArgs.push_back("--end-group");
+ }
+
+ //----------------------------------------------------------------------------
+ // End files
+ //----------------------------------------------------------------------------
+ if (incStdLib && incStartFiles) {
+ std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
}
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
+ C.addCommand(
+ new Command(
+ JA, *this,
+ Args.MakeArgString(Linker), CmdArgs));
}
// Hexagon tools end.
@@ -3649,8 +4107,9 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
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)
+ .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
+ .Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
+ .Cases("armv7s", "xscale", llvm::Triple::arm)
.Case("r600", llvm::Triple::r600)
.Case("nvptx", llvm::Triple::nvptx)
.Case("nvptx64", llvm::Triple::nvptx64)
@@ -3659,38 +4118,14 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
.Default(llvm::Triple::UnknownArch);
}
-const char *darwin::CC1::getCC1Name(types::ID Type) const {
- switch (Type) {
- default:
- llvm_unreachable("Unexpected type for Darwin CC1 tool.");
- case types::TY_Asm:
- case types::TY_C: case types::TY_CHeader:
- case types::TY_PP_C: case types::TY_PP_CHeader:
- return "cc1";
- case types::TY_ObjC: case types::TY_ObjCHeader:
- case types::TY_PP_ObjC: case types::TY_PP_ObjC_Alias:
- case types::TY_PP_ObjCHeader:
- return "cc1obj";
- case types::TY_CXX: case types::TY_CXXHeader:
- case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
- return "cc1plus";
- case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
- case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXX_Alias:
- case types::TY_PP_ObjCXXHeader:
- return "cc1objplus";
- }
-}
-
-void darwin::CC1::anchor() {}
-
-const char *darwin::CC1::getBaseInputName(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *Clang::getBaseInputName(const ArgList &Args,
+ const InputInfoList &Inputs) {
return Args.MakeArgString(
llvm::sys::path::filename(Inputs[0].getBaseInput()));
}
-const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *Clang::getBaseInputStem(const ArgList &Args,
+ const InputInfoList &Inputs) {
const char *Str = getBaseInputName(Args, Inputs);
if (const char *End = strrchr(Str, '.'))
@@ -3699,9 +4134,8 @@ const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
return Str;
}
-const char *
-darwin::CC1::getDependencyFileName(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *Clang::getDependencyFileName(const ArgList &Args,
+ const InputInfoList &Inputs) {
// FIXME: Think about this more.
std::string Res;
@@ -3709,588 +4143,11 @@ darwin::CC1::getDependencyFileName(const ArgList &Args,
std::string Str(OutputOpt->getValue());
Res = Str.substr(0, Str.rfind('.'));
} else {
- Res = darwin::CC1::getBaseInputStem(Args, Inputs);
+ Res = getBaseInputStem(Args, Inputs);
}
return Args.MakeArgString(Res + ".d");
}
-void darwin::CC1::RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const {
- for (ArgStringList::iterator it = CmdArgs.begin(), ie = CmdArgs.end();
- it != ie;) {
-
- StringRef Option = *it;
- bool RemoveOption = false;
-
- // Erase both -fmodule-cache-path and its argument.
- if (Option.equals("-fmodule-cache-path") && it+2 != ie) {
- it = CmdArgs.erase(it, it+2);
- ie = CmdArgs.end();
- continue;
- }
-
- // Remove unsupported -f options.
- if (Option.startswith("-f")) {
- // Remove -f/-fno- to reduce the number of cases.
- if (Option.startswith("-fno-"))
- Option = Option.substr(5);
- else
- Option = Option.substr(2);
- RemoveOption = llvm::StringSwitch<bool>(Option)
- .Case("altivec", true)
- .Case("modules", true)
- .Case("diagnostics-show-note-include-stack", true)
- .Default(false);
- }
-
- // Handle machine specific options.
- if (Option.startswith("-m")) {
- RemoveOption = llvm::StringSwitch<bool>(Option)
- .Case("-mthumb", true)
- .Case("-mno-thumb", true)
- .Case("-mno-fused-madd", true)
- .Case("-mlong-branch", true)
- .Case("-mlongcall", true)
- .Case("-mcpu=G4", true)
- .Case("-mcpu=G5", true)
- .Default(false);
- }
-
- // Handle warning options.
- if (Option.startswith("-W")) {
- // Remove -W/-Wno- to reduce the number of cases.
- if (Option.startswith("-Wno-"))
- Option = Option.substr(5);
- else
- Option = Option.substr(2);
-
- RemoveOption = llvm::StringSwitch<bool>(Option)
- .Case("address-of-temporary", true)
- .Case("ambiguous-member-template", true)
- .Case("analyzer-incompatible-plugin", true)
- .Case("array-bounds", true)
- .Case("array-bounds-pointer-arithmetic", true)
- .Case("bind-to-temporary-copy", true)
- .Case("bitwise-op-parentheses", true)
- .Case("bool-conversions", true)
- .Case("builtin-macro-redefined", true)
- .Case("c++-hex-floats", true)
- .Case("c++0x-compat", true)
- .Case("c++0x-extensions", true)
- .Case("c++0x-narrowing", true)
- .Case("c++11-compat", true)
- .Case("c++11-extensions", true)
- .Case("c++11-narrowing", true)
- .Case("conditional-uninitialized", true)
- .Case("constant-conversion", true)
- .Case("conversion-null", true)
- .Case("CFString-literal", true)
- .Case("constant-logical-operand", true)
- .Case("custom-atomic-properties", true)
- .Case("default-arg-special-member", true)
- .Case("delegating-ctor-cycles", true)
- .Case("delete-non-virtual-dtor", true)
- .Case("deprecated-implementations", true)
- .Case("deprecated-writable-strings", true)
- .Case("distributed-object-modifiers", true)
- .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)
- .Case("header-hygiene", true)
- .Case("idiomatic-parentheses", true)
- .Case("ignored-qualifiers", true)
- .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)
- .Case("language-extension-token", true)
- .Case("literal-conversion", true)
- .Case("literal-range", true)
- .Case("local-type-template-args", true)
- .Case("logical-op-parentheses", true)
- .Case("method-signatures", true)
- .Case("microsoft", true)
- .Case("mismatched-tags", true)
- .Case("missing-method-return-type", true)
- .Case("non-pod-varargs", true)
- .Case("nonfragile-abi2", true)
- .Case("null-arithmetic", true)
- .Case("null-dereference", true)
- .Case("out-of-line-declaration", true)
- .Case("overriding-method-mismatch", true)
- .Case("readonly-setter-attrs", true)
- .Case("return-stack-address", true)
- .Case("self-assign", true)
- .Case("semicolon-before-method-body", true)
- .Case("sentinel", true)
- .Case("shift-overflow", true)
- .Case("shift-sign-overflow", true)
- .Case("sign-conversion", true)
- .Case("sizeof-array-argument", true)
- .Case("sizeof-pointer-memaccess", true)
- .Case("string-compare", true)
- .Case("super-class-method-mismatch", true)
- .Case("tautological-compare", true)
- .Case("typedef-redefinition", true)
- .Case("typename-missing", true)
- .Case("undefined-reinterpret-cast", true)
- .Case("unknown-warning-option", true)
- .Case("unnamed-type-template-args", true)
- .Case("unneeded-internal-declaration", true)
- .Case("unneeded-member-function", true)
- .Case("unused-comparison", true)
- .Case("unused-exception-parameter", true)
- .Case("unused-member-function", true)
- .Case("unused-result", true)
- .Case("vector-conversions", true)
- .Case("vla", true)
- .Case("used-but-marked-unused", true)
- .Case("weak-vtables", true)
- .Default(false);
- } // if (Option.startswith("-W"))
- if (RemoveOption) {
- it = CmdArgs.erase(it);
- ie = CmdArgs.end();
- } else {
- ++it;
- }
- }
-}
-
-void darwin::CC1::AddCC1Args(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
-
- CheckCodeGenerationOptions(D, Args);
-
- // Derived from cc1 spec.
- 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");
-
- if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
- getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
- if (!Args.hasArg(options::OPT_fbuiltin_strcat))
- CmdArgs.push_back("-fno-builtin-strcat");
- if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
- CmdArgs.push_back("-fno-builtin-strcpy");
- }
-
- if (Args.hasArg(options::OPT_g_Flag) &&
- !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
- CmdArgs.push_back("-feliminate-unused-debug-symbols");
-}
-
-void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
- const InputInfoList &Inputs,
- const ArgStringList &OutputArgs) const {
- const Driver &D = getToolChain().getDriver();
-
- // Derived from cc1_options spec.
- if (Args.hasArg(options::OPT_fast) ||
- Args.hasArg(options::OPT_fastf) ||
- Args.hasArg(options::OPT_fastcp))
- CmdArgs.push_back("-O3");
-
- if (Arg *A = Args.getLastArg(options::OPT_pg))
- if (Args.hasArg(options::OPT_fomit_frame_pointer))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << A->getAsString(Args) << "-fomit-frame-pointer";
-
- AddCC1Args(Args, CmdArgs);
-
- if (!Args.hasArg(options::OPT_Q))
- CmdArgs.push_back("-quiet");
-
- CmdArgs.push_back("-dumpbase");
- CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
-
- Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
-
- Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
-
- // FIXME: The goal is to use the user provided -o if that is our
- // final output, otherwise to drive from the original input
- // name. Find a clean way to go about this.
- if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
- Args.hasArg(options::OPT_o)) {
- Arg *OutputOpt = Args.getLastArg(options::OPT_o);
- CmdArgs.push_back("-auxbase-strip");
- CmdArgs.push_back(OutputOpt->getValue());
- } else {
- CmdArgs.push_back("-auxbase");
- CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
- }
-
- Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
-
- Args.AddAllArgs(CmdArgs, options::OPT_O);
- // FIXME: -Wall is getting some special treatment. Investigate.
- Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
- Args.AddLastArg(CmdArgs, options::OPT_w);
- Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
- options::OPT_trigraphs);
- if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
- // Honor -std-default.
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
- "-std=", /*Joined=*/true);
- }
-
- if (Args.hasArg(options::OPT_v))
- CmdArgs.push_back("-version");
- if (Args.hasArg(options::OPT_pg) &&
- getToolChain().SupportsProfiling())
- CmdArgs.push_back("-p");
- Args.AddLastArg(CmdArgs, options::OPT_p);
-
- // The driver treats -fsyntax-only specially.
- if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
- getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
- // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
- // used to inhibit the default -fno-builtin-str{cat,cpy}.
- //
- // FIXME: Should we grow a better way to deal with "removing" args?
- for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
- options::OPT_fsyntax_only),
- ie = Args.filtered_end(); it != ie; ++it) {
- if (!(*it)->getOption().matches(options::OPT_fbuiltin_strcat) &&
- !(*it)->getOption().matches(options::OPT_fbuiltin_strcpy)) {
- (*it)->claim();
- (*it)->render(Args, CmdArgs);
- }
- }
- } else
- Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
-
- // Claim Clang only -f options, they aren't worth warning about.
- Args.ClaimAllArgs(options::OPT_f_clang_Group);
-
- Args.AddAllArgs(CmdArgs, options::OPT_undef);
- if (Args.hasArg(options::OPT_Qn))
- CmdArgs.push_back("-fno-ident");
-
- // FIXME: This isn't correct.
- //Args.AddLastArg(CmdArgs, options::OPT__help)
- //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
-
- CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
-
- // FIXME: Still don't get what is happening here. Investigate.
- Args.AddAllArgs(CmdArgs, options::OPT__param);
-
- if (Args.hasArg(options::OPT_fmudflap) ||
- Args.hasArg(options::OPT_fmudflapth)) {
- CmdArgs.push_back("-fno-builtin");
- CmdArgs.push_back("-fno-merge-constants");
- }
-
- if (Args.hasArg(options::OPT_coverage)) {
- CmdArgs.push_back("-fprofile-arcs");
- CmdArgs.push_back("-ftest-coverage");
- }
-
- if (types::isCXX(Inputs[0].getType()))
- CmdArgs.push_back("-D__private_extern__=extern");
-}
-
-void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
- const InputInfoList &Inputs,
- const ArgStringList &OutputArgs) const {
- // Derived from cpp_options
- AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
-
- CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
-
- AddCC1Args(Args, CmdArgs);
-
- // NOTE: The code below has some commonality with cpp_options, but
- // in classic gcc style ends up sending things in different
- // orders. This may be a good merge candidate once we drop pedantic
- // compatibility.
-
- Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
- options::OPT_trigraphs);
- if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
- // Honor -std-default.
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
- "-std=", /*Joined=*/true);
- }
- Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
- Args.AddLastArg(CmdArgs, options::OPT_w);
-
- // The driver treats -fsyntax-only specially.
- Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
-
- // Claim Clang only -f options, they aren't worth warning about.
- Args.ClaimAllArgs(options::OPT_f_clang_Group);
-
- if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
- !Args.hasArg(options::OPT_fno_working_directory))
- CmdArgs.push_back("-fworking-directory");
-
- Args.AddAllArgs(CmdArgs, options::OPT_O);
- Args.AddAllArgs(CmdArgs, options::OPT_undef);
- if (Args.hasArg(options::OPT_save_temps))
- CmdArgs.push_back("-fpch-preprocess");
-}
-
-void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
- ArgStringList &CmdArgs,
- const InputInfoList &Inputs) const {
- const Driver &D = getToolChain().getDriver();
-
- CheckPreprocessingOptions(D, Args);
-
- // Derived from cpp_unique_options.
- // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
- Args.AddLastArg(CmdArgs, options::OPT_C);
- Args.AddLastArg(CmdArgs, options::OPT_CC);
- if (!Args.hasArg(options::OPT_Q))
- CmdArgs.push_back("-quiet");
- Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
- Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx);
- Args.AddLastArg(CmdArgs, options::OPT_v);
- Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
- Args.AddLastArg(CmdArgs, options::OPT_P);
-
- // FIXME: Handle %I properly.
- if (getToolChain().getArch() == llvm::Triple::x86_64) {
- CmdArgs.push_back("-imultilib");
- CmdArgs.push_back("x86_64");
- }
-
- if (Args.hasArg(options::OPT_MD)) {
- CmdArgs.push_back("-MD");
- CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
- }
-
- if (Args.hasArg(options::OPT_MMD)) {
- CmdArgs.push_back("-MMD");
- CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
- }
-
- Args.AddLastArg(CmdArgs, options::OPT_M);
- Args.AddLastArg(CmdArgs, options::OPT_MM);
- Args.AddAllArgs(CmdArgs, options::OPT_MF);
- Args.AddLastArg(CmdArgs, options::OPT_MG);
- Args.AddLastArg(CmdArgs, options::OPT_MP);
- Args.AddAllArgs(CmdArgs, options::OPT_MQ);
- Args.AddAllArgs(CmdArgs, options::OPT_MT);
- if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
- (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.AddLastArg(CmdArgs, options::OPT_remap);
- if (Args.hasArg(options::OPT_g3))
- CmdArgs.push_back("-dD");
- Args.AddLastArg(CmdArgs, options::OPT_H);
-
- AddCPPArgs(Args, CmdArgs);
-
- Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
- Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
-
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
- CmdArgs.push_back(II.getFilename());
- }
-
- Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
- options::OPT_Xpreprocessor);
-
- if (Args.hasArg(options::OPT_fmudflap)) {
- CmdArgs.push_back("-D_MUDFLAP");
- CmdArgs.push_back("-include");
- CmdArgs.push_back("mf-runtime.h");
- }
-
- if (Args.hasArg(options::OPT_fmudflapth)) {
- CmdArgs.push_back("-D_MUDFLAP");
- CmdArgs.push_back("-D_MUDFLAPTH");
- CmdArgs.push_back("-include");
- CmdArgs.push_back("mf-runtime.h");
- }
-}
-
-void darwin::CC1::AddCPPArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- // Derived from cpp spec.
-
- if (Args.hasArg(options::OPT_static)) {
- // The gcc spec is broken here, it refers to dynamic but
- // that has been translated. Start by being bug compatible.
-
- // if (!Args.hasArg(arglist.parser.dynamicOption))
- CmdArgs.push_back("-D__STATIC__");
- } else
- CmdArgs.push_back("-D__DYNAMIC__");
-
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-D_REENTRANT");
-}
-
-void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
-
- assert(Inputs.size() == 1 && "Unexpected number of inputs!");
-
- CmdArgs.push_back("-E");
-
- if (Args.hasArg(options::OPT_traditional) ||
- Args.hasArg(options::OPT_traditional_cpp))
- CmdArgs.push_back("-traditional-cpp");
-
- ArgStringList OutputArgs;
- assert(Output.isFilename() && "Unexpected CC1 output.");
- OutputArgs.push_back("-o");
- OutputArgs.push_back(Output.getFilename());
-
- if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) {
- AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
- } else {
- AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
- CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
- }
-
- Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
-
- RemoveCC1UnsupportedArgs(CmdArgs);
-
- const char *CC1Name = getCC1Name(Inputs[0].getType());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-}
-
-void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
-
- assert(Inputs.size() == 1 && "Unexpected number of inputs!");
-
- // Silence warning about unused --serialize-diagnostics
- Args.ClaimAllArgs(options::OPT__serialize_diags);
-
- types::ID InputType = Inputs[0].getType();
- if (const Arg *A = Args.getLastArg(options::OPT_traditional))
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "-E";
-
- if (JA.getType() == types::TY_LLVM_IR ||
- JA.getType() == types::TY_LTO_IR)
- CmdArgs.push_back("-emit-llvm");
- else if (JA.getType() == types::TY_LLVM_BC ||
- JA.getType() == types::TY_LTO_BC)
- CmdArgs.push_back("-emit-llvm-bc");
- else if (Output.getType() == types::TY_AST)
- D.Diag(diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
- else if (JA.getType() != types::TY_PP_Asm &&
- JA.getType() != types::TY_PCH)
- D.Diag(diag::err_drv_invalid_gcc_output_type)
- << getTypeName(JA.getType());
-
- ArgStringList OutputArgs;
- if (Output.getType() != types::TY_PCH) {
- OutputArgs.push_back("-o");
- if (Output.isNothing())
- OutputArgs.push_back("/dev/null");
- else
- OutputArgs.push_back(Output.getFilename());
- }
-
- // There is no need for this level of compatibility, but it makes
- // diffing easier.
- bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
- Args.hasArg(options::OPT_S));
-
- if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
- AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
- if (OutputArgsEarly) {
- AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
- } else {
- AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
- CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
- }
- } else {
- CmdArgs.push_back("-fpreprocessed");
-
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
- // Reject AST inputs.
- if (II.getType() == types::TY_AST) {
- D.Diag(diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
- return;
- }
-
- CmdArgs.push_back(II.getFilename());
- }
-
- if (OutputArgsEarly) {
- AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
- } else {
- AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
- CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
- }
- }
-
- if (Output.getType() == types::TY_PCH) {
- assert(Output.isFilename() && "Invalid PCH output.");
-
- CmdArgs.push_back("-o");
- // NOTE: gcc uses a temp .s file for this, but there doesn't seem
- // to be a good reason.
- const char *TmpPath = C.getArgs().MakeArgString(
- D.GetTemporaryPath("cc", "s"));
- C.addTempFile(TmpPath);
- CmdArgs.push_back(TmpPath);
-
- // If we're emitting a pch file with the last 4 characters of ".pth"
- // and falling back to llvm-gcc we want to use ".gch" instead.
- std::string OutputFile(Output.getFilename());
- size_t loc = OutputFile.rfind(".pth");
- if (loc != std::string::npos)
- OutputFile.replace(loc, 4, ".gch");
- const char *Tmp = C.getArgs().MakeArgString("--output-pch="+OutputFile);
- CmdArgs.push_back(Tmp);
- }
-
- RemoveCC1UnsupportedArgs(CmdArgs);
-
- const char *CC1Name = getCC1Name(Inputs[0].getType());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-}
-
void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4624,6 +4481,9 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
CmdArgs.push_back("-ObjC");
+ if (Args.hasArg(options::OPT_rdynamic))
+ CmdArgs.push_back("-export_dynamic");
+
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
@@ -4721,11 +4581,11 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
SanitizerArgs Sanitize(getToolChain().getDriver(), Args);
- // If we're building a dynamic lib with -fsanitize=address, or
- // -fsanitize=undefined, unresolved symbols may appear. Mark all
+ // If we're building a dynamic lib with -fsanitize=address,
+ // unresolved symbols may appear. Mark all
// of them as dynamic_lookup. Linking executables is handled in
// lib/Driver/ToolChains.cpp.
- if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) {
+ if (Sanitize.needsAsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) {
CmdArgs.push_back("-undefined");
@@ -4839,10 +4699,10 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
}
void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
ArgStringList CmdArgs;
CmdArgs.push_back("--verify");
CmdArgs.push_back("--debug-info");
@@ -5136,6 +4996,14 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
+ // Silence warning for "clang -g foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ // and "clang -emit-llvm foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ // and for "clang -w foo.o -o foo". Other warning options are already
+ // handled somewhere else.
+ Args.ClaimAllArgs(options::OPT_w);
+
if ((!Args.hasArg(options::OPT_nostdlib)) &&
(!Args.hasArg(options::OPT_shared))) {
CmdArgs.push_back("-e");
@@ -5190,6 +5058,10 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
+ Args.AddAllArgs(CmdArgs, options::OPT_s);
+ Args.AddAllArgs(CmdArgs, options::OPT_t);
+ Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
+ Args.AddAllArgs(CmdArgs, options::OPT_r);
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
@@ -5406,14 +5278,8 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
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());
+ CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -5788,11 +5654,11 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
-void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
+void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
ArgStringList CmdArgs;
// Add --32/--64 to make sure we get the format we want.
@@ -5832,14 +5698,8 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
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());
+ CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -5880,12 +5740,12 @@ 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::Android;
- bool StaticLibgcc = isAndroid || Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_static_libgcc);
+ bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
+ Args.hasArg(options::OPT_static);
if (!D.CCCIsCXX)
CmdArgs.push_back("-lgcc");
- if (StaticLibgcc) {
+ if (StaticLibgcc || isAndroid) {
if (D.CCCIsCXX)
CmdArgs.push_back("-lgcc");
} else {
@@ -5900,6 +5760,14 @@ static void AddLibgcc(llvm::Triple Triple, const Driver &D,
CmdArgs.push_back("-lgcc_eh");
else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
CmdArgs.push_back("-lgcc");
+
+ // According to Android ABI, we have to link with libdl if we are
+ // linking with non-static libgcc.
+ //
+ // NOTE: This fixes a link error on Android MIPS as well. The non-static
+ // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
+ if (isAndroid && !StaticLibgcc)
+ CmdArgs.push_back("-ldl");
}
static bool hasMipsN32ABIArg(const ArgList &Args) {
@@ -5907,11 +5775,11 @@ static bool hasMipsN32ABIArg(const ArgList &Args) {
return A && (A->getValue() == StringRef("n32"));
}
-void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
+void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
const toolchains::Linux& ToolChain =
static_cast<const toolchains::Linux&>(getToolChain());
const Driver &D = ToolChain.getDriver();
@@ -5931,7 +5799,7 @@ void linuxtools::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))
+ if (Args.hasArg(options::OPT_pie) && !Args.hasArg(options::OPT_shared))
CmdArgs.push_back("-pie");
if (Args.hasArg(options::OPT_rdynamic))
@@ -5952,6 +5820,8 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-m");
if (ToolChain.getArch() == llvm::Triple::x86)
CmdArgs.push_back("elf_i386");
+ else if (ToolChain.getArch() == llvm::Triple::aarch64)
+ CmdArgs.push_back("aarch64linux");
else if (ToolChain.getArch() == llvm::Triple::arm
|| ToolChain.getArch() == llvm::Triple::thumb)
CmdArgs.push_back("armelf_linux_eabi");
@@ -6000,6 +5870,8 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("/system/bin/linker");
else if (ToolChain.getArch() == llvm::Triple::x86)
CmdArgs.push_back("/lib/ld-linux.so.2");
+ else if (ToolChain.getArch() == llvm::Triple::aarch64)
+ CmdArgs.push_back("/lib/ld-linux-aarch64.so.1");
else if (ToolChain.getArch() == llvm::Triple::arm ||
ToolChain.getArch() == llvm::Triple::thumb) {
if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
@@ -6102,9 +5974,17 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
SanitizerArgs Sanitize(D, Args);
- // Call this before we add the C++ ABI library.
+ // Call these before we add the C++ ABI library.
if (Sanitize.needsUbsanRt())
- addUbsanRTLinux(getToolChain(), Args, CmdArgs);
+ addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX,
+ Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
+ Sanitize.needsMsanRt());
+ if (Sanitize.needsAsanRt())
+ addAsanRTLinux(getToolChain(), Args, CmdArgs);
+ if (Sanitize.needsTsanRt())
+ addTsanRTLinux(getToolChain(), Args, CmdArgs);
+ if (Sanitize.needsMsanRt())
+ addMsanRTLinux(getToolChain(), Args, CmdArgs);
if (D.CCCIsCXX &&
!Args.hasArg(options::OPT_nostdlib) &&
@@ -6119,21 +5999,24 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lm");
}
- // Call this before we add the C run-time.
- 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)) {
if (Args.hasArg(options::OPT_static))
CmdArgs.push_back("--start-group");
+ bool OpenMP = Args.hasArg(options::OPT_fopenmp);
+ if (OpenMP) {
+ CmdArgs.push_back("-lgomp");
+
+ // FIXME: Exclude this for platforms whith libgomp that doesn't require
+ // librt. Most modern Linux platfroms require it, but some may not.
+ CmdArgs.push_back("-lrt");
+ }
+
AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
if (Args.hasArg(options::OPT_pthread) ||
- Args.hasArg(options::OPT_pthreads))
+ Args.hasArg(options::OPT_pthreads) || OpenMP)
CmdArgs.push_back("-lpthread");
CmdArgs.push_back("-lc");
@@ -6235,7 +6118,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lCompilerRT-Generic");
CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+ Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
}
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h
index 7ac43ec..d647171 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.h
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h
@@ -13,7 +13,6 @@
#include "clang/Driver/Tool.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
-
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
@@ -31,7 +30,17 @@ namespace tools {
/// \brief Clang compiler tool.
class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
+ public:
+ static const char *getBaseInputName(const ArgList &Args,
+ const InputInfoList &Inputs);
+ static const char *getBaseInputStem(const ArgList &Args,
+ const InputInfoList &Inputs);
+ static const char *getDependencyFileName(const ArgList &Args,
+ const InputInfoList &Inputs);
+
+ private:
void AddPreprocessingOptions(Compilation &C,
+ const JobAction &JA,
const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
@@ -42,6 +51,7 @@ namespace tools {
bool KernelOrKext) const;
void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddPPCTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+ void AddR600TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
@@ -219,63 +229,6 @@ namespace darwin {
const ToolChain &TC) : Tool(Name, ShortName, TC) {}
};
- class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool {
- virtual void anchor();
- public:
- static const char *getBaseInputName(const ArgList &Args,
- const InputInfoList &Input);
- static const char *getBaseInputStem(const ArgList &Args,
- const InputInfoList &Input);
- static const char *getDependencyFileName(const ArgList &Args,
- const InputInfoList &Inputs);
-
- protected:
- const char *getCC1Name(types::ID Type) const;
-
- void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
- void RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const;
- void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
- const InputInfoList &Inputs,
- const ArgStringList &OutputArgs) const;
- void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
- const InputInfoList &Inputs,
- const ArgStringList &OutputArgs) const;
- void AddCPPUniqueOptionsArgs(const ArgList &Args,
- ArgStringList &CmdArgs,
- const InputInfoList &Inputs) const;
- void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
-
- public:
- CC1(const char *Name, const char *ShortName,
- const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {}
-
- virtual bool hasGoodDiagnostics() const { return true; }
- virtual bool hasIntegratedCPP() const { return true; }
- };
-
- class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1 {
- public:
- Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess",
- "gcc preprocessor", TC) {}
-
- virtual void ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &TCArgs,
- const char *LinkingOutput) const;
- };
-
- class LLVM_LIBRARY_VISIBILITY Compile : public CC1 {
- public:
- Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {}
-
- virtual void ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &TCArgs,
- const char *LinkingOutput) const;
- };
-
class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool {
public:
Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",
@@ -327,6 +280,7 @@ namespace darwin {
"dsymutil", TC) {}
virtual bool hasIntegratedCPP() const { return false; }
+ virtual bool isDsymutilJob() const { return true; }
virtual void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
@@ -338,15 +292,15 @@ namespace darwin {
class LLVM_LIBRARY_VISIBILITY VerifyDebug : public DarwinTool {
public:
VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug",
- "dwarfdump", TC) {}
+ "dwarfdump", TC) {}
virtual bool hasIntegratedCPP() const { return false; }
virtual void ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &TCArgs,
- const char *LinkingOutput) const;
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
};
}
@@ -474,12 +428,11 @@ namespace netbsd {
};
} // end namespace netbsd
- /// linux -- Directly call GNU Binutils assembler and linker
-namespace linuxtools {
+ /// Directly call GNU Binutils' assembler and linker.
+namespace gnutools {
class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
public:
- Assemble(const ToolChain &TC) : Tool("linux::Assemble", "assembler",
- TC) {}
+ Assemble(const ToolChain &TC) : Tool("GNU::Assemble", "assembler", TC) {}
virtual bool hasIntegratedCPP() const { return false; }
@@ -491,7 +444,7 @@ namespace linuxtools {
};
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
- Link(const ToolChain &TC) : Tool("linux::Link", "linker", TC) {}
+ Link(const ToolChain &TC) : Tool("GNU::Link", "linker", TC) {}
virtual bool hasIntegratedCPP() const { return false; }
virtual bool isLinkJob() const { return true; }
diff --git a/contrib/llvm/tools/clang/lib/Driver/Types.cpp b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
index 862025e..7d22596 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Types.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Types.cpp
@@ -8,10 +8,9 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Types.h"
-
#include "llvm/ADT/StringSwitch.h"
-#include <string.h>
#include <cassert>
+#include <string.h>
using namespace clang::driver;
using namespace clang::driver::types;
@@ -88,7 +87,7 @@ bool types::isAcceptedByClang(ID Id) {
case TY_ObjCHeader: case TY_PP_ObjCHeader:
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
- case TY_AST:
+ case TY_AST: case TY_ModuleFile:
case TY_LLVM_IR: case TY_LLVM_BC:
return true;
}
@@ -113,7 +112,7 @@ bool types::isCXX(ID Id) {
return false;
case TY_CXX: case TY_PP_CXX:
- case TY_ObjCXX: case TY_PP_ObjCXX:
+ case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
case TY_CUDA:
@@ -165,16 +164,15 @@ types::ID types::lookupTypeForExtension(const char *Ext) {
.Case("F90", TY_Fortran)
.Case("F95", TY_Fortran)
.Case("mii", TY_PP_ObjCXX)
+ .Case("pcm", TY_ModuleFile)
.Default(TY_INVALID);
}
types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
- unsigned N = strlen(Name);
-
for (unsigned i=0; i<numTypes; ++i) {
types::ID Id = (types::ID) (i + 1);
if (canTypeBeUserSpecified(Id) &&
- memcmp(Name, getInfo(Id).Name, N + 1) == 0)
+ strcmp(Name, getInfo(Id).Name) == 0)
return Id;
}
@@ -182,54 +180,36 @@ types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
}
// FIXME: Why don't we just put this list in the defs file, eh.
-
-unsigned types::getNumCompilationPhases(ID Id) {
- if (Id == TY_Object)
- return 1;
-
- unsigned N = 0;
- if (getPreprocessedType(Id) != TY_INVALID)
- N += 1;
-
- if (onlyAssembleType(Id))
- return N + 2; // assemble, link
- if (onlyPrecompileType(Id))
- return N + 1; // precompile
-
- return N + 3; // compile, assemble, link
-}
-
-phases::ID types::getCompilationPhase(ID Id, unsigned N) {
- assert(N < getNumCompilationPhases(Id) && "Invalid index.");
-
- if (Id == TY_Object)
- return phases::Link;
-
- if (getPreprocessedType(Id) != TY_INVALID) {
- if (N == 0)
- return phases::Preprocess;
- --N;
+void types::getCompilationPhases(
+ ID Id,
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &P) {
+ if (Id != TY_Object) {
+ if (getPreprocessedType(Id) != TY_INVALID) {
+ P.push_back(phases::Preprocess);
+ }
+
+ if (onlyPrecompileType(Id)) {
+ P.push_back(phases::Precompile);
+ } else {
+ if (!onlyAssembleType(Id)) {
+ P.push_back(phases::Compile);
+ }
+ P.push_back(phases::Assemble);
+ }
}
-
- if (onlyAssembleType(Id))
- return N == 0 ? phases::Assemble : phases::Link;
-
- if (onlyPrecompileType(Id))
- return phases::Precompile;
-
- if (N == 0)
- return phases::Compile;
- if (N == 1)
- return phases::Assemble;
-
- return phases::Link;
+ if (!onlyPrecompileType(Id)) {
+ P.push_back(phases::Link);
+ }
+ assert(0 < P.size() && "Not enough phases in list");
+ assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");
+ return;
}
ID types::lookupCXXTypeForCType(ID Id) {
switch (Id) {
default:
return Id;
-
+
case types::TY_C:
return types::TY_CXX;
case types::TY_PP_C:
diff --git a/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
index de2d535..dac7e77 100644
--- a/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
@@ -8,13 +8,14 @@
//===----------------------------------------------------------------------===//
#include "ToolChains.h"
-
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Version.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
-#include "clang/Basic/Version.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
@@ -31,49 +32,20 @@ using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
-Windows::Windows(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple) {
+Windows::Windows(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args)
+ : ToolChain(D, Triple, Args) {
}
-Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const {
- Action::ActionClass Key;
- if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
- Key = Action::AnalyzeJobClass;
- else
- Key = JA.getKind();
-
- bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIntegratedAssemblerDefault());
-
- Tool *&T = Tools[Key];
- if (!T) {
- switch (Key) {
- case Action::InputClass:
- case Action::BindArchClass:
- case Action::LipoJobClass:
- case Action::DsymutilJobClass:
- case Action::VerifyJobClass:
- llvm_unreachable("Invalid tool kind.");
- case Action::PreprocessJobClass:
- case Action::PrecompileJobClass:
- case Action::AnalyzeJobClass:
- case Action::MigrateJobClass:
- case Action::CompileJobClass:
- T = new tools::Clang(*this); break;
- case Action::AssembleJobClass:
- if (!UseIntegratedAs && getTriple().getEnvironment() == llvm::Triple::MachO)
- T = new tools::darwin::Assemble(*this);
- else
- T = new tools::ClangAs(*this);
- break;
- case Action::LinkJobClass:
- T = new tools::visualstudio::Link(*this); break;
- }
- }
+Tool *Windows::buildLinker() const {
+ return new tools::visualstudio::Link(*this);
+}
- return *T;
+Tool *Windows::buildAssembler() const {
+ if (getTriple().getEnvironment() == llvm::Triple::MachO)
+ return new tools::darwin::Assemble(*this);
+ getDriver().Diag(clang::diag::err_no_external_windows_assembler);
+ return NULL;
}
bool Windows::IsIntegratedAssemblerDefault() const {
@@ -158,12 +130,12 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
const char *sp = keyName;
- while (*sp && !isdigit(*sp))
+ while (*sp && !isDigit(*sp))
sp++;
if (!*sp)
continue;
const char *ep = sp + 1;
- while (*ep && (isdigit(*ep) || (*ep == '.')))
+ while (*ep && (isDigit(*ep) || (*ep == '.')))
ep++;
char numBuf[32];
strncpy(numBuf, sp, sizeof(numBuf) - 1);
OpenPOWER on IntegriCloud