Update Clang for rebase to r212749.
This also fixes a small issue with arm_neon.h not being generated always.
Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android
Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/Driver/Android.mk b/lib/Driver/Android.mk
index 559ca83..a80df60 100644
--- a/lib/Driver/Android.mk
+++ b/lib/Driver/Android.mk
@@ -11,12 +11,10 @@
DiagnosticDriverKinds.inc \
DiagnosticSemaKinds.inc \
Options.inc \
- CC1Options.inc \
- CC1AsOptions.inc
+ CC1Options.inc
clang_driver_SRC_FILES := \
Action.cpp \
- CC1AsOptions.cpp \
Compilation.cpp \
Driver.cpp \
DriverOptions.cpp \
diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp
deleted file mode 100644
index 22180c9..0000000
--- a/lib/Driver/CC1AsOptions.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- CC1AsOptions.cpp - Clang Assembler Options Table -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/CC1AsOptions.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Option/OptTable.h"
-#include "llvm/Option/Option.h"
-using namespace clang;
-using namespace clang::driver;
-using namespace llvm::opt;
-using namespace clang::driver::cc1asoptions;
-
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
-#include "clang/Driver/CC1AsOptions.inc"
-#undef PREFIX
-
-static const OptTable::Info CC1AsInfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
- FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "clang/Driver/CC1AsOptions.inc"
-#undef OPTION
-};
-
-namespace {
-
-class CC1AsOptTable : public OptTable {
-public:
- CC1AsOptTable()
- : OptTable(CC1AsInfoTable, llvm::array_lengthof(CC1AsInfoTable)) {}
-};
-
-}
-
-OptTable *clang::driver::createCC1AsOptTable() {
- return new CC1AsOptTable();
-}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index f2bdaee..33db5e9 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -1,12 +1,10 @@
set(LLVM_LINK_COMPONENTS
Option
Support
- TransformUtils
)
add_clang_library(clangDriver
Action.cpp
- CC1AsOptions.cpp
Compilation.cpp
Driver.cpp
DriverOptions.cpp
@@ -22,7 +20,6 @@
Types.cpp
DEPENDS
- ClangCC1AsOptions
ClangDriverOptions
LINK_LIBS
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 8ec643c..49b7edd 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -17,8 +17,6 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
-#include <errno.h>
-#include <sys/stat.h>
using namespace clang::driver;
using namespace clang;
@@ -26,9 +24,9 @@
Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
InputArgList *_Args, DerivedArgList *_TranslatedArgs)
- : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
- TranslatedArgs(_TranslatedArgs), Redirects(nullptr) {
-}
+ : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
+ TranslatedArgs(_TranslatedArgs), Redirects(nullptr),
+ ForDiagnostics(false) {}
Compilation::~Compilation() {
delete TranslatedArgs;
@@ -86,7 +84,7 @@
if (!llvm::sys::fs::can_write(File) || !llvm::sys::fs::is_regular_file(File))
return true;
- if (llvm::error_code EC = llvm::sys::fs::remove(File)) {
+ if (std::error_code EC = llvm::sys::fs::remove(File)) {
// Failure is only failure if the file exists and is "regular". We checked
// for it being regular before, and llvm::sys::fs::remove ignores ENOENT,
// so we don't need to check again.
@@ -211,6 +209,8 @@
}
void Compilation::initCompilationForDiagnostics() {
+ ForDiagnostics = true;
+
// Free actions and jobs.
DeleteContainerPointers(Actions);
Jobs.clear();
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index a0fcf41..2844033 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -11,6 +11,7 @@
#include "InputInfo.h"
#include "ToolChains.h"
#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/DriverDiagnostic.h"
@@ -20,6 +21,7 @@
#include "clang/Driver/ToolChain.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
@@ -32,15 +34,12 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <memory>
-// 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;
using namespace clang;
using namespace llvm::opt;
@@ -155,9 +154,10 @@
Arg *PhaseArg = nullptr;
phases::ID FinalPhase;
- // -{E,M,MM} and /P only run the preprocessor.
+ // -{E,EP,P,M,MM} only run the preprocessor.
if (CCCIsCPP() ||
(PhaseArg = DAL.getLastArg(options::OPT_E)) ||
+ (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
(PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
FinalPhase = phases::Preprocess;
@@ -419,8 +419,6 @@
// Suppress driver output and emit preprocessor output to temp file.
Mode = CPPMode;
CCGenDiagnostics = true;
- C.getArgs().AddFlagArg(nullptr,
- Opts->getOption(options::OPT_frewrite_includes));
// Save the original job command(s).
std::string Cmd;
@@ -521,16 +519,25 @@
for (ArgStringList::const_iterator it = Files.begin(), ie = Files.end();
it != ie; ++it) {
Diag(clang::diag::note_drv_command_failed_diag_msg) << *it;
+ std::string Script = StringRef(*it).rsplit('.').first;
+ // In some cases (modules) we'll dump extra data to help with reproducing
+ // the crash into a directory next to the output.
+ SmallString<128> VFS;
+ if (llvm::sys::fs::exists(Script + ".cache")) {
+ Diag(clang::diag::note_drv_command_failed_diag_msg)
+ << Script + ".cache";
+ VFS = llvm::sys::path::filename(Script + ".cache");
+ llvm::sys::path::append(VFS, "vfs", "vfs.yaml");
+ }
std::string Err;
- std::string Script = StringRef(*it).rsplit('.').first;
Script += ".sh";
llvm::raw_fd_ostream ScriptOS(Script.c_str(), Err, llvm::sys::fs::F_Excl);
if (!Err.empty()) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating run script: " + Script + " " + Err;
} else {
- // Append the new filename with correct preprocessed suffix.
+ // Replace the original filename with the preprocessed one.
size_t I, E;
I = Cmd.find("-main-file-name ");
assert (I != std::string::npos && "Expected to find -main-file-name");
@@ -543,6 +550,11 @@
E = I + OldFilename.size();
I = Cmd.rfind(" ", I) + 1;
Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size());
+ if (!VFS.empty()) {
+ // Add the VFS overlay to the reproduction script.
+ I += NewFilename.size();
+ Cmd.insert(I, std::string(" -ivfsoverlay ") + VFS.c_str());
+ }
ScriptOS << Cmd;
Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
}
@@ -600,7 +612,7 @@
// 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
+ // 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.
@@ -952,6 +964,9 @@
if (llvm::sys::fs::exists(Twine(Path)))
return true;
+ if (D.IsCLMode() && llvm::sys::Process::FindInEnvPath("LIB", Value))
+ return true;
+
D.Diag(clang::diag::err_drv_no_such_file) << Path.str();
return false;
}
@@ -1268,7 +1283,8 @@
} else {
OutputTy = Input->getType();
if (!Args.hasFlag(options::OPT_frewrite_includes,
- options::OPT_fno_rewrite_includes, false))
+ options::OPT_fno_rewrite_includes, false) &&
+ !CCGenDiagnostics)
OutputTy = types::getPreprocessedType(OutputTy);
assert(OutputTy != types::TY_INVALID &&
"Cannot preprocess this input type!");
@@ -1574,7 +1590,7 @@
static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
StringRef BaseName, types::ID FileType) {
SmallString<128> Filename = ArgValue;
-
+
if (ArgValue.empty()) {
// If the argument is empty, output to BaseName in the current dir.
Filename = BaseName;
@@ -1617,7 +1633,10 @@
if (C.getArgs().hasArg(options::OPT__SLASH_P)) {
assert(AtTopLevel && isa<PreprocessJobAction>(JA));
StringRef BaseName = llvm::sys::path::filename(BaseInput);
- return C.addResultFile(MakeCLOutputFilename(C.getArgs(), "", BaseName,
+ StringRef NameArg;
+ if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
+ NameArg = A->getValue();
+ return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName,
types::TY_PP_C), &JA);
}
@@ -1826,8 +1845,7 @@
std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
const {
SmallString<128> Path;
- llvm::error_code EC =
- llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
+ std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
if (EC) {
Diag(clang::diag::err_unable_to_make_temp) << EC.message();
return "";
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 38f68eb..42cc1bc 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -41,7 +41,7 @@
.Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
.Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
.Cases("-resource-dir", "-serialize-diagnostic-file", true)
- .Case("-dwarf-debug-flags", true)
+ .Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
.Default(false);
// Match found.
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index c336195..b64f027 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -15,7 +15,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
+#include "llvm/Support/SpecialCaseList.h"
#include <memory>
using namespace clang::driver;
@@ -113,14 +113,6 @@
// -f(-no)sanitize=leak should change whether leak detection is enabled by
// default in ASan?
- // 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 && (AllAdd & 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)) {
@@ -171,8 +163,8 @@
if (NeedsAsan) {
AsanSharedRuntime =
- (TC.getTriple().getEnvironment() == llvm::Triple::Android) ||
- Args.hasArg(options::OPT_shared_libasan);
+ Args.hasArg(options::OPT_shared_libasan) ||
+ (TC.getTriple().getEnvironment() == llvm::Triple::Android);
AsanZeroBaseShadow =
(TC.getTriple().getEnvironment() == llvm::Triple::Android);
}
@@ -210,11 +202,6 @@
#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
#include "clang/Basic/Sanitizers.def"
.Default(SanitizeKind());
- // Assume -fsanitize=address implies -fsanitize=init-order,use-after-return.
- // FIXME: This should be either specified in Sanitizers.def, or go away when
- // we get rid of "-fsanitize=init-order,use-after-return" flags at all.
- if (ParsedKind & Address)
- ParsedKind |= InitOrder | UseAfterReturn;
return ParsedKind;
}
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index eefe487..4f90d08 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -15,6 +15,7 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -147,6 +148,30 @@
return D.GetProgramPath(Name, *this);
}
+std::string ToolChain::GetLinkerPath() const {
+ if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+ StringRef Suffix = A->getValue();
+
+ // If we're passed -fuse-ld= with no argument, or with the argument ld,
+ // then use whatever the default system linker is.
+ if (Suffix.empty() || Suffix == "ld")
+ return GetProgramPath("ld");
+
+ llvm::SmallString<8> LinkerName("ld.");
+ LinkerName.append(Suffix);
+
+ std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
+ if (llvm::sys::fs::exists(LinkerPath))
+ return LinkerPath;
+
+ getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
+ return "";
+ }
+
+ return GetProgramPath("ld");
+}
+
+
types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
return types::lookupTypeForExtension(Ext);
}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 8d8e7c7..2d8669b 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -10,6 +10,7 @@
#include "ToolChains.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
+#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
@@ -29,13 +30,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.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 <system_error>
using namespace clang::driver;
using namespace clang::driver::toolchains;
@@ -1345,8 +1341,9 @@
"x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
"x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
"x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux",
- "x86_64-linux-android"
+ "x86_64-linux-android", "x86_64-unknown-linux"
};
+ static const char *const X32LibDirs[] = { "/libx32" };
static const char *const X86LibDirs[] = { "/lib32", "/lib" };
static const char *const X86Triples[] = {
"i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
@@ -1357,18 +1354,24 @@
static const char *const MIPSLibDirs[] = { "/lib" };
static const char *const MIPSTriples[] = { "mips-linux-gnu",
- "mips-mti-linux-gnu" };
+ "mips-mti-linux-gnu",
+ "mips-img-linux-gnu" };
static const char *const MIPSELLibDirs[] = { "/lib" };
static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
- "mipsel-linux-android" };
+ "mipsel-linux-android",
+ "mips-img-linux-gnu" };
static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
- "mips-mti-linux-gnu" };
+ "mips-mti-linux-gnu",
+ "mips-img-linux-gnu",
+ "mips64-linux-gnuabi64" };
static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
"mips-mti-linux-gnu",
- "mips64el-linux-android" };
+ "mips-img-linux-gnu",
+ "mips64el-linux-android",
+ "mips64el-linux-gnuabi64" };
static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
static const char *const PPCTriples[] = {
@@ -1449,10 +1452,19 @@
X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
TripleAliases.append(X86_64Triples,
X86_64Triples + llvm::array_lengthof(X86_64Triples));
- BiarchLibDirs.append(X86LibDirs,
- X86LibDirs + llvm::array_lengthof(X86LibDirs));
- BiarchTripleAliases.append(X86Triples,
- X86Triples + llvm::array_lengthof(X86Triples));
+ // x32 is always available when x86_64 is available, so adding it as secondary
+ // arch with x86_64 triples
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
+ BiarchLibDirs.append(X32LibDirs,
+ X32LibDirs + llvm::array_lengthof(X32LibDirs));
+ BiarchTripleAliases.append(X86_64Triples,
+ X86_64Triples + llvm::array_lengthof(X86_64Triples));
+ } else {
+ BiarchLibDirs.append(X86LibDirs,
+ X86LibDirs + llvm::array_lengthof(X86LibDirs));
+ BiarchTripleAliases.append(X86Triples,
+ X86Triples + llvm::array_lengthof(X86Triples));
+ }
break;
case llvm::Triple::x86:
LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
@@ -1635,7 +1647,8 @@
Arg *A = Args.getLastArg(options::OPT_march_EQ,
options::OPT_mcpu_EQ);
- return A && A->getValue() == StringRef("mips64r2");
+ return A && (A->getValue() == StringRef("mips64r2") ||
+ A->getValue() == StringRef("octeon"));
}
static bool isMicroMips(const ArgList &Args) {
@@ -1870,6 +1883,33 @@
.FilterOut(NonExistent);
}
+ MultilibSet ImgMultilibs;
+ {
+ Multilib Mips64r6 = Multilib()
+ .gccSuffix("/mips64r6")
+ .osSuffix("/mips64r6")
+ .includeSuffix("/mips64r6")
+ .flag("+m64").flag("-m32");
+
+ Multilib LittleEndian = Multilib()
+ .gccSuffix("/el")
+ .osSuffix("/el")
+ .includeSuffix("/el")
+ .flag("+EL").flag("-EB");
+
+ Multilib MAbi64 = Multilib()
+ .gccSuffix("/64")
+ .osSuffix("/64")
+ .includeSuffix("/64")
+ .flag("+mabi=64").flag("-mabi=n32").flag("-m32");
+
+ ImgMultilibs = MultilibSet()
+ .Maybe(Mips64r6)
+ .Maybe(MAbi64)
+ .Maybe(LittleEndian)
+ .FilterOut(NonExistent);
+ }
+
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
Multilib::flags_list Flags;
@@ -1904,6 +1944,17 @@
return false;
}
+ if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+ TargetTriple.getOS() == llvm::Triple::Linux &&
+ TargetTriple.getEnvironment() == llvm::Triple::GNU) {
+ // Select mips-img-linux-gnu toolchain.
+ if (ImgMultilibs.select(Flags, Result.SelectedMultilib)) {
+ Result.Multilibs = ImgMultilibs;
+ return true;
+ }
+ return false;
+ }
+
// Sort candidates. Toolchain that best meets the directories goes first.
// Then select the first toolchains matches command line flags.
MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs,
@@ -1920,6 +1971,18 @@
}
}
+ {
+ // Fallback to the regular toolchain-tree structure.
+ Multilib Default;
+ Result.Multilibs.push_back(Default);
+ Result.Multilibs.FilterOut(NonExistent);
+
+ if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
+ Result.BiarchSibling = Multilib();
+ return true;
+ }
+ }
+
return false;
}
@@ -1939,47 +2002,64 @@
Multilib Alt64 = Multilib()
.gccSuffix("/64")
.includeSuffix("/64")
- .flag("-m32").flag("+m64");
+ .flag("-m32").flag("+m64").flag("-mx32");
Multilib Alt32 = Multilib()
.gccSuffix("/32")
.includeSuffix("/32")
- .flag("+m32").flag("-m64");
+ .flag("+m32").flag("-m64").flag("-mx32");
+ Multilib Altx32 = Multilib()
+ .gccSuffix("/x32")
+ .includeSuffix("/x32")
+ .flag("-m32").flag("-m64").flag("+mx32");
FilterNonExistent NonExistent(Path);
- // Decide whether the default multilib is 32bit, correcting for
- // when the default multilib and the alternate appear backwards
- bool DefaultIs32Bit;
+ // Determine default multilib from: 32, 64, x32
+ // Also handle cases such as 64 on 32, 32 on 64, etc.
+ enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
+ const bool IsX32 {TargetTriple.getEnvironment() == llvm::Triple::GNUX32};
if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
- DefaultIs32Bit = false;
- else if (TargetTriple.isArch64Bit() && !NonExistent(Alt64))
- DefaultIs32Bit = true;
+ Want = WANT64;
+ else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
+ Want = WANT64;
+ else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
+ Want = WANT32;
else {
- if (NeedsBiarchSuffix)
- DefaultIs32Bit = TargetTriple.isArch64Bit();
+ if (TargetTriple.isArch32Bit())
+ Want = NeedsBiarchSuffix ? WANT64 : WANT32;
+ else if (IsX32)
+ Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
else
- DefaultIs32Bit = TargetTriple.isArch32Bit();
+ Want = NeedsBiarchSuffix ? WANT32 : WANT64;
}
- if (DefaultIs32Bit)
- Default.flag("+m32").flag("-m64");
+ if (Want == WANT32)
+ Default.flag("+m32").flag("-m64").flag("-mx32");
+ else if (Want == WANT64)
+ Default.flag("-m32").flag("+m64").flag("-mx32");
+ else if (Want == WANTX32)
+ Default.flag("-m32").flag("-m64").flag("+mx32");
else
- Default.flag("-m32").flag("+m64");
+ return false;
Result.Multilibs.push_back(Default);
Result.Multilibs.push_back(Alt64);
Result.Multilibs.push_back(Alt32);
+ Result.Multilibs.push_back(Altx32);
Result.Multilibs.FilterOut(NonExistent);
Multilib::flags_list Flags;
- addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags);
+ addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
+ addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
return false;
- if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32)
+ if (Result.SelectedMultilib == Alt64 ||
+ Result.SelectedMultilib == Alt32 ||
+ Result.SelectedMultilib == Altx32)
Result.BiarchSibling = Default;
return true;
@@ -2021,7 +2101,7 @@
(llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
for (unsigned i = 0; i < NumLibSuffixes; ++i) {
StringRef LibSuffix = LibSuffixes[i];
- llvm::error_code EC;
+ std::error_code EC;
for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
!EC && LI != LE; LI = LI.increment(EC)) {
StringRef VersionText = llvm::sys::path::filename(LI->path());
@@ -2231,7 +2311,7 @@
// Determine version of GCC libraries and headers to use.
const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
- llvm::error_code ec;
+ std::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)) {
@@ -2783,8 +2863,9 @@
}
static Distro DetectDistro(llvm::Triple::ArchType Arch) {
- std::unique_ptr<llvm::MemoryBuffer> File;
- if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+ llvm::MemoryBuffer::getFile("/etc/lsb-release");
+ if (File) {
StringRef Data = File.get()->getBuffer();
SmallVector<StringRef, 8> Lines;
Data.split(Lines, "\n");
@@ -2809,7 +2890,8 @@
return Version;
}
- if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
+ File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
+ if (File) {
StringRef Data = File.get()->getBuffer();
if (Data.startswith("Fedora release"))
return Fedora;
@@ -2825,7 +2907,8 @@
return UnknownDistro;
}
- if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
+ File = llvm::MemoryBuffer::getFile("/etc/debian_version");
+ if (File) {
StringRef Data = File.get()->getBuffer();
if (Data[0] == '5')
return DebianLenny;
@@ -2893,7 +2976,9 @@
return "i386-linux-gnu";
return TargetTriple.str();
case llvm::Triple::x86_64:
- if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
+ // We don't want this for x32, otherwise it will match x86_64 libs
+ if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 &&
+ llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
return "x86_64-linux-gnu";
return TargetTriple.str();
case llvm::Triple::arm64:
@@ -2914,6 +2999,18 @@
if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
return "mipsel-linux-gnu";
return TargetTriple.str();
+ case llvm::Triple::mips64:
+ if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu"))
+ return "mips64-linux-gnu";
+ if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
+ return "mips64-linux-gnuabi64";
+ return TargetTriple.str();
+ case llvm::Triple::mips64el:
+ if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu"))
+ return "mips64el-linux-gnu";
+ if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
+ return "mips64el-linux-gnuabi64";
+ return TargetTriple.str();
case llvm::Triple::ppc:
if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
return "powerpc-linux-gnuspe";
@@ -2957,6 +3054,10 @@
Triple.getArch() == llvm::Triple::ppc)
return "lib32";
+ if (Triple.getArch() == llvm::Triple::x86_64 &&
+ Triple.getEnvironment() == llvm::Triple::GNUX32)
+ return "libx32";
+
return Triple.isArch32Bit() ? "lib" : "lib64";
}
@@ -2979,7 +3080,7 @@
PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
GCCInstallation.getTriple().str() + "/bin").str());
- Linker = GetProgramPath("ld");
+ Linker = GetLinkerPath();
Distro Distro = DetectDistro(Arch);
@@ -3262,12 +3363,23 @@
const StringRef MIPSELMultiarchIncludeDirs[] = {
"/usr/include/mipsel-linux-gnu"
};
+ const StringRef MIPS64MultiarchIncludeDirs[] = {
+ "/usr/include/mips64-linux-gnu",
+ "/usr/include/mips64-linux-gnuabi64"
+ };
+ const StringRef MIPS64ELMultiarchIncludeDirs[] = {
+ "/usr/include/mips64el-linux-gnu",
+ "/usr/include/mips64el-linux-gnuabi64"
+ };
const StringRef PPCMultiarchIncludeDirs[] = {
"/usr/include/powerpc-linux-gnu"
};
const StringRef PPC64MultiarchIncludeDirs[] = {
"/usr/include/powerpc64-linux-gnu"
};
+ const StringRef PPC64LEMultiarchIncludeDirs[] = {
+ "/usr/include/powerpc64le-linux-gnu"
+ };
ArrayRef<StringRef> MultiarchIncludeDirs;
if (getTriple().getArch() == llvm::Triple::x86_64) {
MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
@@ -3287,10 +3399,16 @@
MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::mipsel) {
MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+ } else if (getTriple().getArch() == llvm::Triple::mips64) {
+ MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+ } else if (getTriple().getArch() == llvm::Triple::mips64el) {
+ MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::ppc) {
MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::ppc64) {
MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
+ } else if (getTriple().getArch() == llvm::Triple::ppc64le) {
+ MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
}
for (StringRef Dir : MultiarchIncludeDirs) {
if (llvm::sys::fs::exists(SysRoot + Dir)) {
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 13e9d67..8931aec 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -537,6 +537,12 @@
return 2;
}
+ virtual bool IsIntegratedAssemblerDefault() const {
+ if (getTriple().getArch() == llvm::Triple::ppc)
+ return true;
+ return Generic_ELF::IsIntegratedAssemblerDefault();
+ }
+
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 76b7962..e3532aa 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -38,7 +38,6 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
-#include <sys/stat.h>
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -63,10 +62,14 @@
/// CheckPreprocessingOptions - Perform some validation of preprocessing
/// arguments that is shared with gcc.
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
- if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
- if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP())
+ if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
+ if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
+ !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "-E";
+ << A->getBaseArg().getAsString(Args)
+ << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
+ }
+ }
}
/// CheckCodeGenerationOptions - Perform some validation of code generation
@@ -173,10 +176,7 @@
// (constructed via -Xarch_).
Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
+ for (const auto &II : Inputs) {
if (!TC.HasNativeLLVMSupport()) {
// Don't try to pass LLVM inputs unless we have native support.
if (II.getType() == types::TY_LLVM_IR ||
@@ -197,11 +197,11 @@
const Arg &A = II.getInputArg();
// Handle reserved library options.
- if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
+ if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
TC.AddCXXStdlibLibArgs(Args, CmdArgs);
- } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
+ else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
TC.AddCCKextLibArgs(Args, CmdArgs);
- } else
+ else
A.renderAsInput(Args, CmdArgs);
}
@@ -897,6 +897,14 @@
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-aarch64-strict-align");
}
+
+ // Setting -mno-global-merge disables the codegen global merge pass. Setting
+ // -mglobal-merge has no effect as the pass is enabled by default.
+ if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
+ options::OPT_mno_global_merge)) {
+ if (A->getOption().matches(options::OPT_mno_global_merge))
+ CmdArgs.push_back("-mno-global-merge");
+ }
}
// Get CPU and ABI names. They are not independent
@@ -908,6 +916,14 @@
const char *DefMips32CPU = "mips32r2";
const char *DefMips64CPU = "mips64r2";
+ // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
+ // default for mips64(el)?-img-linux-gnu.
+ if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+ Triple.getEnvironment() == llvm::Triple::GNU) {
+ DefMips32CPU = "mips32r6";
+ DefMips64CPU = "mips64r6";
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
options::OPT_mcpu_EQ))
CPUName = A->getValue();
@@ -938,22 +954,22 @@
}
}
- if (!ABIName.empty()) {
- // Deduce CPU name from ABI name.
- CPUName = llvm::StringSwitch<const char *>(ABIName)
- .Cases("32", "o32", "eabi", DefMips32CPU)
- .Cases("n32", "n64", "64", DefMips64CPU)
- .Default("");
- }
- else if (!CPUName.empty()) {
- // Deduce ABI name from CPU name.
- ABIName = llvm::StringSwitch<const char *>(CPUName)
- .Cases("mips32", "mips32r2", "o32")
- .Cases("mips64", "mips64r2", "n64")
- .Default("");
+ if (ABIName.empty()) {
+ // Deduce ABI name from the target triple.
+ if (Triple.getArch() == llvm::Triple::mips ||
+ Triple.getArch() == llvm::Triple::mipsel)
+ ABIName = "o32";
+ else
+ ABIName = "n64";
}
- // FIXME: Warn on inconsistent cpu and abi usage.
+ if (CPUName.empty()) {
+ // Deduce CPU name from ABI name.
+ CPUName = llvm::StringSwitch<const char *>(ABIName)
+ .Cases("o32", "eabi", DefMips32CPU)
+ .Cases("n32", "n64", DefMips64CPU)
+ .Default("");
+ }
}
// Convert ABI name to the GNU tools acceptable variant.
@@ -1042,6 +1058,8 @@
"msa");
AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
"fp64");
+ AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
+ options::OPT_modd_spreg, "nooddspreg");
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
@@ -1147,6 +1165,7 @@
.Case("power6", "pwr6")
.Case("power6x", "pwr6x")
.Case("power7", "pwr7")
+ .Case("power8", "pwr8")
.Case("pwr3", "pwr3")
.Case("pwr4", "pwr4")
.Case("pwr5", "pwr5")
@@ -1154,6 +1173,7 @@
.Case("pwr6", "pwr6")
.Case("pwr6x", "pwr6x")
.Case("pwr7", "pwr7")
+ .Case("pwr8", "pwr8")
.Case("powerpc", "ppc")
.Case("powerpc64", "ppc64")
.Case("powerpc64le", "ppc64le")
@@ -1417,9 +1437,13 @@
Features.push_back("-fsgsbase");
}
+ // Add features to comply with gcc on Android
if (Triple.getEnvironment() == llvm::Triple::Android) {
- // Add sse3 feature to comply with gcc on Android
- Features.push_back("+sse3");
+ if (Triple.getArch() == llvm::Triple::x86_64) {
+ Features.push_back("+sse4.2");
+ Features.push_back("+popcnt");
+ } else
+ Features.push_back("+ssse3");
}
// Now add any that the user explicitly requested on the command line,
@@ -1752,8 +1776,8 @@
if (isa<CompileJobAction>(A))
return true;
- for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
- if (ContainsCompileAction(*it))
+ for (const auto &Act : *A)
+ if (ContainsCompileAction(Act))
return true;
return false;
@@ -1769,9 +1793,8 @@
if (RelaxDefault) {
RelaxDefault = false;
- for (ActionList::const_iterator it = C.getActions().begin(),
- ie = C.getActions().end(); it != ie; ++it) {
- if (ContainsCompileAction(*it)) {
+ for (const auto &Act : C.getActions()) {
+ if (ContainsCompileAction(Act)) {
RelaxDefault = true;
break;
}
@@ -2025,17 +2048,21 @@
static void addUbsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool IsCXX,
bool HasOtherSanitizerRt) {
+ // Do not link runtime into shared libraries.
+ 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)
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "san", true, false);
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false);
+ addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false, true);
// Only include the bits of the runtime which need a C++ ABI library if
// we're linking in C++ mode.
if (IsCXX)
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false);
+ addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false, true);
}
static void addDfsanRT(const ToolChain &TC, const ArgList &Args,
@@ -2313,8 +2340,11 @@
}
}
- // The make clang go fast button.
- CmdArgs.push_back("-disable-free");
+ // We normally speed up the clang process a bit by skipping destructors at
+ // exit, but when we're generating diagnostics we can rely on some of the
+ // cleanup.
+ if (!C.isForDiagnostics())
+ CmdArgs.push_back("-disable-free");
// Disable the verification pass in -asserts builds.
#ifdef NDEBUG
@@ -2415,6 +2445,27 @@
}
}
+ // OpenBSD-specific defaults for PIE
+ if (getToolChain().getTriple().getOS() == llvm::Triple::OpenBSD) {
+ switch (getToolChain().getTriple().getArch()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::sparc:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ IsPICLevelTwo = false; // "-fpie"
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::sparcv9:
+ IsPICLevelTwo = true; // "-fPIE"
+ break;
+
+ default:
+ break;
+ }
+ }
+
// For the PIC and PIE flag options, this logic is different from the
// legacy logic in very old versions of GCC, as that logic was just
// a bug no one had ever fixed. This logic is both more rational and
@@ -2503,6 +2554,13 @@
// LLVM Code Generator Options.
+ if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
+ StringRef v = A->getValue();
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
+ A->claim();
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
CmdArgs.push_back("-mregparm");
CmdArgs.push_back(A->getValue());
@@ -2864,8 +2922,10 @@
// FIXME: we should support specifying dwarf version with
// -gline-tables-only.
CmdArgs.push_back("-gline-tables-only");
- // Default is dwarf-2 for darwin.
- if (getToolChain().getTriple().isOSDarwin())
+ // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+ Triple.getOS() == llvm::Triple::FreeBSD)
CmdArgs.push_back("-gdwarf-2");
} else if (A->getOption().matches(options::OPT_gdwarf_2))
CmdArgs.push_back("-gdwarf-2");
@@ -2875,8 +2935,10 @@
CmdArgs.push_back("-gdwarf-4");
else if (!A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_ggdb0)) {
- // Default is dwarf-2 for darwin.
- if (getToolChain().getTriple().isOSDarwin())
+ // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+ Triple.getOS() == llvm::Triple::FreeBSD)
CmdArgs.push_back("-gdwarf-2");
else
CmdArgs.push_back("-g");
@@ -3314,10 +3376,6 @@
if (Args.getLastArg(options::OPT_fapple_kext))
CmdArgs.push_back("-fapple-kext");
- if (Args.hasFlag(options::OPT_frewrite_includes,
- options::OPT_fno_rewrite_includes, false))
- CmdArgs.push_back("-frewrite-includes");
-
Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
@@ -3448,6 +3506,17 @@
CmdArgs.push_back("-arm-restrict-it");
}
+ if (TT.getArch() == llvm::Triple::arm ||
+ TT.getArch() == llvm::Triple::thumb) {
+ if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+ options::OPT_mno_long_calls)) {
+ if (A->getOption().matches(options::OPT_mlong_calls)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-arm-long-calls");
+ }
+ }
+ }
+
// Forward -f options with positive and negative forms; we translate
// these by hand.
if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
@@ -3461,6 +3530,12 @@
if (Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
A->render(Args, CmdArgs);
+ if (Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
+ A->render(Args, CmdArgs);
+
+ if (Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
+ A->render(Args, CmdArgs);
+
if (Args.hasArg(options::OPT_mkernel)) {
if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
CmdArgs.push_back("-fapple-kext");
@@ -3528,44 +3603,51 @@
// -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps).
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) {
- A->claim();
+ if (Arg *A = Args.getLastArg(options::OPT_fmodule_name))
A->render(Args, CmdArgs);
- }
// -fmodule-map-file can be used to specify a file containing module
// definitions.
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) {
- A->claim();
+ if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file))
A->render(Args, CmdArgs);
- }
- // 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);
+ // -fmodule-cache-path specifies where our module files should be written.
+ SmallString<128> ModuleCachePath;
+ if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
+ ModuleCachePath = A->getValue();
+ if (HaveModules) {
+ if (C.isForDiagnostics()) {
+ // When generating crash reports, we want to emit the modules along with
+ // the reproduction sources, so we ignore any provided module path.
+ ModuleCachePath = Output.getFilename();
+ llvm::sys::path::replace_extension(ModuleCachePath, ".cache");
+ llvm::sys::path::append(ModuleCachePath, "modules");
+ } else if (ModuleCachePath.empty()) {
+ // No module path was provided: use the default.
+ llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+ ModuleCachePath);
+ llvm::sys::path::append(ModuleCachePath, "org.llvm.clang");
+ llvm::sys::path::append(ModuleCachePath, "ModuleCache");
}
- } 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));
+ ModuleCachePath.insert(ModuleCachePath.begin(), Arg, Arg + strlen(Arg));
+ CmdArgs.push_back(Args.MakeArgString(ModuleCachePath));
}
- if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path)) {
- A->claim();
- if (HaveModules) {
- A->render(Args, CmdArgs);
- }
+ // When building modules and generating crashdumps, we need to dump a module
+ // dependency VFS alongside the output.
+ if (HaveModules && C.isForDiagnostics()) {
+ SmallString<128> VFSDir(Output.getFilename());
+ llvm::sys::path::replace_extension(VFSDir, ".cache");
+ llvm::sys::path::append(VFSDir, "vfs");
+ CmdArgs.push_back("-module-dependency-dir");
+ CmdArgs.push_back(Args.MakeArgString(VFSDir));
}
+ if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path))
+ if (HaveModules)
+ A->render(Args, CmdArgs);
+
// Pass through all -fmodules-ignore-macro arguments.
Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
@@ -3771,9 +3853,10 @@
}
}
- // Add exception args.
- addExceptionArgs(Args, InputType, getToolChain().getTriple(),
- KernelOrKext, objcRuntime, CmdArgs);
+ // Handle GCC-style exception args.
+ if (!C.getDriver().IsCLMode())
+ addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext,
+ objcRuntime, CmdArgs);
if (getToolChain().UseSjLjExceptions())
CmdArgs.push_back("-fsjlj-exceptions");
@@ -3837,6 +3920,14 @@
D.Diag(diag::err_drv_clang_unsupported)
<< Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
+ // -finput_charset=UTF-8 is default. Reject others
+ if (Arg *inputCharset = Args.getLastArg(
+ options::OPT_finput_charset_EQ)) {
+ StringRef value = inputCharset->getValue();
+ if (value != "UTF-8")
+ D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value;
+ }
+
// -fcaret-diagnostics is default.
if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
options::OPT_fno_caret_diagnostics, true))
@@ -3879,9 +3970,8 @@
// Support both clang's -f[no-]color-diagnostics and gcc's
// -f[no-]diagnostics-colors[=never|always|auto].
enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
- for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
- it != ie; ++it) {
- const Option &O = (*it)->getOption();
+ for (const auto &Arg : Args) {
+ const Option &O = Arg->getOption();
if (!O.matches(options::OPT_fcolor_diagnostics) &&
!O.matches(options::OPT_fdiagnostics_color) &&
!O.matches(options::OPT_fno_color_diagnostics) &&
@@ -3889,7 +3979,7 @@
!O.matches(options::OPT_fdiagnostics_color_EQ))
continue;
- (*it)->claim();
+ Arg->claim();
if (O.matches(options::OPT_fcolor_diagnostics) ||
O.matches(options::OPT_fdiagnostics_color)) {
ShowColors = Colors_On;
@@ -3898,7 +3988,7 @@
ShowColors = Colors_Off;
} else {
assert(O.matches(options::OPT_fdiagnostics_color_EQ));
- StringRef value((*it)->getValue());
+ StringRef value(Arg->getValue());
if (value == "always")
ShowColors = Colors_On;
else if (value == "never")
@@ -4005,6 +4095,15 @@
}
#endif
+ // Enable rewrite includes if the user's asked for it or if we're generating
+ // diagnostics.
+ // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
+ // nice to enable this when doing a crashdump for modules as well.
+ if (Args.hasFlag(options::OPT_frewrite_includes,
+ options::OPT_fno_rewrite_includes, false) ||
+ (C.isForDiagnostics() && !HaveModules))
+ CmdArgs.push_back("-frewrite-includes");
+
// Only allow -traditional or -traditional-cpp outside in preprocessing modes.
if (Arg *A = Args.getLastArg(options::OPT_traditional,
options::OPT_traditional_cpp)) {
@@ -4055,10 +4154,7 @@
assert(Output.isNothing() && "Invalid output.");
}
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
+ for (const auto &II : Inputs) {
addDashXForInput(Args, II, CmdArgs);
if (II.isFilename())
@@ -4075,9 +4171,8 @@
// analysis.
if (getToolChain().UseDwarfDebugFlags()) {
ArgStringList OriginalArgs;
- for (ArgList::const_iterator it = Args.begin(),
- ie = Args.end(); it != ie; ++it)
- (*it)->render(Args, OriginalArgs);
+ for (const auto &Arg : Args)
+ Arg->render(Args, OriginalArgs);
SmallString<256> Flags;
Flags += Exec;
@@ -4105,18 +4200,9 @@
if (Args.hasArg(options::OPT__SLASH_fallback) &&
Output.getType() == types::TY_Object &&
(InputType == types::TY_C || InputType == types::TY_CXX)) {
- tools::visualstudio::Compile CL(getToolChain());
- Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args,
- LinkingOutput);
- // RTTI support in clang-cl is a work in progress. Fall back to MSVC early
- // if we are using 'clang-cl /fallback /GR'.
- // FIXME: Remove this when RTTI is finished.
- if (Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, false)) {
- D.Diag(diag::warn_drv_rtti_fallback) << CLCommand->getExecutable();
- C.addCommand(CLCommand);
- } else {
- C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
- }
+ Command *CLCommand = getCLFallback()->GetCommand(C, JA, Output, Inputs,
+ Args, LinkingOutput);
+ C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
} else {
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -4274,6 +4360,45 @@
return runtime;
}
+static bool maybeConsumeDash(const std::string &EH, size_t &I) {
+ bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
+ I += HaveDash;
+ return !HaveDash;
+}
+
+struct EHFlags {
+ EHFlags() : Synch(false), Asynch(false), NoExceptC(false) {}
+ bool Synch;
+ bool Asynch;
+ bool NoExceptC;
+};
+
+/// /EH controls whether to run destructor cleanups when exceptions are
+/// thrown. There are three modifiers:
+/// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
+/// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
+/// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
+/// - c: Assume that extern "C" functions are implicitly noexcept. This
+/// modifier is an optimization, so we ignore it for now.
+/// The default is /EHs-c-, meaning cleanups are disabled.
+static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
+ EHFlags EH;
+ std::vector<std::string> EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH);
+ for (auto EHVal : EHArgs) {
+ for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
+ switch (EHVal[I]) {
+ case 'a': EH.Asynch = maybeConsumeDash(EHVal, I); continue;
+ case 'c': EH.NoExceptC = maybeConsumeDash(EHVal, I); continue;
+ case 's': EH.Synch = maybeConsumeDash(EHVal, I); continue;
+ default: break;
+ }
+ D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
+ break;
+ }
+ }
+ return EH;
+}
+
void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
unsigned RTOptionID = options::OPT__SLASH_MT;
@@ -4322,11 +4447,25 @@
if (Arg *A = Args.getLastArg(options::OPT_show_includes))
A->render(Args, CmdArgs);
- // RTTI is currently not supported, so disable it by default.
- if (!Args.hasArg(options::OPT_frtti, options::OPT_fno_rtti))
- CmdArgs.push_back("-fno-rtti");
+ // This controls whether or not we emit RTTI data for polymorphic types.
+ if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+ /*default=*/false))
+ CmdArgs.push_back("-fno-rtti-data");
const Driver &D = getToolChain().getDriver();
+ EHFlags EH = parseClangCLEHFlags(D, Args);
+ // FIXME: Do something with NoExceptC.
+ if (EH.Synch || EH.Asynch) {
+ CmdArgs.push_back("-fexceptions");
+ CmdArgs.push_back("-fcxx-exceptions");
+ }
+
+ // /EP should expand to -E -P.
+ if (Args.hasArg(options::OPT__SLASH_EP)) {
+ CmdArgs.push_back("-E");
+ CmdArgs.push_back("-P");
+ }
+
Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
if (MostGeneralArg && BestCaseArg)
@@ -4365,6 +4504,12 @@
}
}
+visualstudio::Compile *Clang::getCLFallback() const {
+ if (!CLFallback)
+ CLFallback.reset(new visualstudio::Compile(getToolChain()));
+ return CLFallback.get();
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4452,9 +4597,8 @@
// analysis.
if (getToolChain().UseDwarfDebugFlags()) {
ArgStringList OriginalArgs;
- for (ArgList::const_iterator it = Args.begin(),
- ie = Args.end(); it != ie; ++it)
- (*it)->render(Args, OriginalArgs);
+ for (const auto &Arg : Args)
+ Arg->render(Args, OriginalArgs);
SmallString<256> Flags;
const char *Exec = getToolChain().getDriver().getClangProgramPath();
@@ -4511,9 +4655,7 @@
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
- for (ArgList::const_iterator
- it = Args.begin(), ie = Args.end(); it != ie; ++it) {
- Arg *A = *it;
+ for (const auto &A : Args) {
if (forwardToGCC(A->getOption())) {
// Don't forward any -g arguments to assembly steps.
if (isa<AssembleJobAction>(JA) &&
@@ -4582,10 +4724,7 @@
//
// FIXME: For the linker case specifically, can we safely convert
// inputs into '-Wl,' options?
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
+ for (const auto &II : Inputs) {
// 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)
@@ -4704,10 +4843,7 @@
//
// FIXME: For the linker case specifically, can we safely convert
// inputs into '-Wl,' options?
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
-
+ for (const auto &II : Inputs) {
// 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)
@@ -4728,11 +4864,10 @@
}
const char *GCCName = "hexagon-as";
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-
}
+
void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
ArgStringList &CmdArgs) const {
// The types are (hopefully) good enough.
@@ -4774,10 +4909,8 @@
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
- for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
- e = ToolChain.ExtraOpts.end();
- i != e; ++i)
- CmdArgs.push_back(i->c_str());
+ for (const auto &Opt : ToolChain.ExtraOpts)
+ CmdArgs.push_back(Opt.c_str());
std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
@@ -4853,12 +4986,8 @@
// 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));
+ for (const auto &LibPath : LibPaths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
//----------------------------------------------------------------------------
//
@@ -4906,9 +5035,6 @@
}
// Hexagon tools end.
-/// getARMCPUForMArch - Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting
-//
-// FIXME: tblgen this.
const char *arm::getARMCPUForMArch(const ArgList &Args,
const llvm::Triple &Triple) {
StringRef MArch;
@@ -4930,6 +5056,14 @@
}
}
+ return driver::getARMCPUForMArch(MArch, Triple);
+}
+
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+//
+// FIXME: tblgen this.
+const char *driver::getARMCPUForMArch(StringRef MArch,
+ const llvm::Triple &Triple) {
switch (Triple.getOS()) {
case llvm::Triple::NetBSD:
if (MArch == "armv6")
@@ -5060,6 +5194,21 @@
return A && (A->getValue() == StringRef(Value));
}
+bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
+ if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
+ return llvm::StringSwitch<bool>(NaNArg->getValue())
+ .Case("2008", true)
+ .Case("legacy", false)
+ .Default(false);
+
+ // NaN2008 is the default for MIPS32r6/MIPS64r6.
+ return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
+ .Cases("mips32r6", "mips64r6", true)
+ .Default(false);
+
+ return false;
+}
+
llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
// archs which Darwin doesn't use.
@@ -5225,9 +5374,8 @@
// We only need to generate a temp path for LTO if we aren't compiling object
// files. When compiling source files, we run 'dsymutil' after linking. We
// don't run 'dsymutil' when compiling object files.
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
- if (it->getType() != types::TY_Object)
+ for (const auto &Input : Inputs)
+ if (Input.getType() != types::TY_Object)
return true;
return false;
@@ -5428,8 +5576,8 @@
/// Hack(tm) to ignore linking errors when we are doing ARC migration.
if (Args.hasArg(options::OPT_ccc_arcmt_check,
options::OPT_ccc_arcmt_migrate)) {
- for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
- (*I)->claim();
+ for (const auto &Arg : Args)
+ Arg->claim();
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("touch"));
CmdArgs.push_back(Output.getFilename());
@@ -5530,7 +5678,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_F);
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5547,14 +5695,12 @@
CmdArgs.push_back("-output");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs) {
assert(II.isFilename() && "Unexpected lipo input.");
CmdArgs.push_back(II.getFilename());
}
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
+
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5614,18 +5760,13 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
-
void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -5727,7 +5868,7 @@
addProfileRT(getToolChain(), Args, CmdArgs);
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5744,14 +5885,10 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("gas"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5839,7 +5976,7 @@
addProfileRT(getToolChain(), Args, CmdArgs);
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -5905,11 +6042,8 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("as"));
@@ -6044,7 +6178,7 @@
}
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6061,14 +6195,10 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6184,7 +6314,7 @@
}
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6262,14 +6392,10 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6370,9 +6496,8 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
const ToolChain::path_list Paths = ToolChain.getFilePaths();
- for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
- i != e; ++i)
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+ for (const auto &Path : Paths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
Args.AddAllArgs(CmdArgs, options::OPT_s);
@@ -6453,7 +6578,7 @@
addProfileRT(ToolChain, Args, CmdArgs);
const char *Exec =
- Args.MakeArgString(ToolChain.GetProgramPath("ld"));
+ Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6524,11 +6649,8 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
@@ -6709,7 +6831,7 @@
addProfileRT(getToolChain(), Args, CmdArgs);
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -6726,7 +6848,10 @@
if (getToolChain().getArch() == llvm::Triple::x86) {
CmdArgs.push_back("--32");
} else if (getToolChain().getArch() == llvm::Triple::x86_64) {
- CmdArgs.push_back("--64");
+ if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ CmdArgs.push_back("--x32");
+ else
+ CmdArgs.push_back("--64");
} else if (getToolChain().getArch() == llvm::Triple::ppc) {
CmdArgs.push_back("-a32");
CmdArgs.push_back("-mppc");
@@ -6829,14 +6954,10 @@
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
// Handle the debug info splitting at object creation time if we're
@@ -6910,22 +7031,29 @@
else
return "/lib/ld-linux.so.3"; /* TODO: check which dynamic linker name. */
} else if (ToolChain.getArch() == llvm::Triple::mips ||
- ToolChain.getArch() == llvm::Triple::mipsel)
+ ToolChain.getArch() == llvm::Triple::mipsel) {
+ if (mips::isNaN2008(Args, ToolChain.getTriple()))
+ return "/lib/ld-linux-mipsn8.so.1";
return "/lib/ld.so.1";
- else if (ToolChain.getArch() == llvm::Triple::mips64 ||
- ToolChain.getArch() == llvm::Triple::mips64el) {
+ } else if (ToolChain.getArch() == llvm::Triple::mips64 ||
+ ToolChain.getArch() == llvm::Triple::mips64el) {
if (mips::hasMipsAbiArg(Args, "n32"))
- return "/lib32/ld.so.1";
- else
- return "/lib64/ld.so.1";
+ return mips::isNaN2008(Args, ToolChain.getTriple())
+ ? "/lib32/ld-linux-mipsn8.so.1" : "/lib32/ld.so.1";
+ return mips::isNaN2008(Args, ToolChain.getTriple())
+ ? "/lib64/ld-linux-mipsn8.so.1" : "/lib64/ld.so.1";
} else if (ToolChain.getArch() == llvm::Triple::ppc)
return "/lib/ld.so.1";
else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
- ToolChain.getArch() == llvm::Triple::ppc64le ||
ToolChain.getArch() == llvm::Triple::systemz)
return "/lib64/ld64.so.1";
+ else if (ToolChain.getArch() == llvm::Triple::ppc64le)
+ return "/lib64/ld64.so.2";
else if (ToolChain.getArch() == llvm::Triple::sparcv9)
return "/lib64/ld-linux.so.2";
+ else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+ ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ return "/libx32/ld-linux-x32.so.2";
else
return "/lib64/ld-linux-x86-64.so.2";
}
@@ -6986,10 +7114,8 @@
if (Args.hasArg(options::OPT_s))
CmdArgs.push_back("-s");
- for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
- e = ToolChain.ExtraOpts.end();
- i != e; ++i)
- CmdArgs.push_back(i->c_str());
+ for (const auto &Opt : ToolChain.ExtraOpts)
+ CmdArgs.push_back(Opt.c_str());
if (!Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("--eh-frame-hdr");
@@ -7038,6 +7164,9 @@
}
else if (ToolChain.getArch() == llvm::Triple::systemz)
CmdArgs.push_back("elf64_s390");
+ else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+ ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ CmdArgs.push_back("elf32_x86_64");
else
CmdArgs.push_back("elf_x86_64");
@@ -7051,9 +7180,6 @@
CmdArgs.push_back("-static");
} else if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-shared");
- if (isAndroid) {
- CmdArgs.push_back("-Bsymbolic");
- }
}
if (ToolChain.getArch() == llvm::Triple::arm ||
@@ -7104,12 +7230,12 @@
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
+ Args.AddAllArgs(CmdArgs, options::OPT_u);
const ToolChain::path_list Paths = ToolChain.getFilePaths();
- for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
- i != e; ++i)
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+ for (const auto &Path : Paths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
if (D.IsUsingLTO(Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
@@ -7169,8 +7295,9 @@
}
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
- if (Args.hasArg(options::OPT_pthread) ||
- Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown)
+ if ((Args.hasArg(options::OPT_pthread) ||
+ Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown) &&
+ !isAndroid)
CmdArgs.push_back("-lpthread");
CmdArgs.push_back("-lc");
@@ -7206,20 +7333,15 @@
const char *LinkingOutput) const {
ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -7273,7 +7395,7 @@
Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
}
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -7293,20 +7415,15 @@
if (getToolChain().getArch() == llvm::Triple::x86)
CmdArgs.push_back("--32");
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -7456,8 +7573,7 @@
addProfileRT(getToolChain(), Args, CmdArgs);
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -7524,13 +7640,11 @@
Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
// Add filenames immediately.
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- if (it->isFilename())
- CmdArgs.push_back(it->getFilename());
+ for (const auto &Input : Inputs)
+ if (Input.isFilename())
+ CmdArgs.push_back(Input.getFilename());
else
- it->getInputArg().renderAsInput(Args, CmdArgs);
- }
+ Input.getInputArg().renderAsInput(Args, CmdArgs);
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
@@ -7555,14 +7669,9 @@
if (!OptPath.hasValue())
return FallbackName;
-#ifdef LLVM_ON_WIN32
- const StringRef PathSeparators = ";";
-#else
- const StringRef PathSeparators = ":";
-#endif
-
+ const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
SmallVector<StringRef, 8> PathSegments;
- llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators);
+ llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
const StringRef &PathSegment = PathSegments[i];
@@ -7612,9 +7721,9 @@
// Flags for which clang-cl have an alias.
// FIXME: How can we ensure this stays in sync with relevant clang-cl options?
- if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti))
- CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR"
- : "/GR-");
+ if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+ /*default=*/false))
+ CmdArgs.push_back("/GR-");
if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
options::OPT_fno_function_sections))
CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
@@ -7630,12 +7739,13 @@
CmdArgs.push_back("/Z7");
std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
- for (size_t I = 0, E = Includes.size(); I != E; ++I)
- CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I]));
+ for (const auto &Include : Includes)
+ CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
// Flags that can simply be passed through.
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
+ Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
// The order of these flags is relevant, so pick the last one.
if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
@@ -7661,7 +7771,6 @@
const Driver &D = getToolChain().getDriver();
std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
-
return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
}
@@ -7695,14 +7804,10 @@
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
@@ -7729,7 +7834,6 @@
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+ const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 575c988..bc7f58b 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -29,6 +29,11 @@
}
namespace tools {
+
+namespace visualstudio {
+ class Compile;
+}
+
using llvm::opt::ArgStringList;
/// \brief Clang compiler tool.
@@ -78,6 +83,10 @@
void AddClangCLArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ visualstudio::Compile *getCLFallback() const;
+
+ mutable std::unique_ptr<visualstudio::Compile> CLFallback;
+
public:
Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
@@ -209,6 +218,7 @@
namespace mips {
bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+ bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
}
namespace darwin {
@@ -562,7 +572,7 @@
};
} // end namespace dragonfly
- /// Visual studio tools.
+/// Visual studio tools.
namespace visualstudio {
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp
index 5d4bbb5..913425a 100644
--- a/lib/Driver/WindowsToolChain.cpp
+++ b/lib/Driver/WindowsToolChain.cpp
@@ -14,6 +14,7 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/ErrorHandling.h"
@@ -21,11 +22,15 @@
// Include the necessary headers to interface with the Windows registry and
// environment.
-#ifdef _MSC_VER
+#if defined(LLVM_ON_WIN32)
+#define USE_WIN32
+#endif
+
+#ifdef USE_WIN32
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOMINMAX
- #include <Windows.h>
+ #include <windows.h>
#endif
using namespace clang::driver;
@@ -54,7 +59,11 @@
}
bool Windows::IsUnwindTablesDefault() const {
- return getArch() == llvm::Triple::x86_64;
+ // FIXME: LLVM's lowering of Win64 data is broken right now. MSVC's linker
+ // says that our object files provide invalid .pdata contributions. Until
+ // that is fixed, don't ask for unwind tables.
+ return false;
+ //return getArch() == llvm::Triple::x86_64;
}
bool Windows::isPICDefault() const {
@@ -69,9 +78,6 @@
return getArch() == llvm::Triple::x86_64;
}
-// FIXME: This probably should goto to some platform utils place.
-#ifdef _MSC_VER
-
/// \brief Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
@@ -82,6 +88,9 @@
/// characters are compared.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
char *value, size_t maxLength) {
+#ifndef USE_WIN32
+ return false;
+#else
HKEY hRootKey = NULL;
HKEY hKey = NULL;
const char* subKey = NULL;
@@ -183,6 +192,7 @@
}
}
return returnValue;
+#endif // USE_WIN32
}
/// \brief Get Windows SDK installation directory.
@@ -202,7 +212,7 @@
return false;
}
- // Get Visual Studio installation directory.
+// Get Visual Studio installation directory.
static bool getVisualStudioDir(std::string &path) {
// First check the environment variables that vsvars32.bat sets.
const char* vcinstalldir = getenv("VCINSTALLDIR");
@@ -244,25 +254,11 @@
const char *vs100comntools = getenv("VS100COMNTOOLS");
const char *vs90comntools = getenv("VS90COMNTOOLS");
const char *vs80comntools = getenv("VS80COMNTOOLS");
- const char *vscomntools = NULL;
- // Try to find the version that we were compiled with
- if(false) {}
- #if (_MSC_VER >= 1600) // VC100
- else if(vs100comntools) {
- vscomntools = vs100comntools;
- }
- #elif (_MSC_VER == 1500) // VC80
- else if(vs90comntools) {
- vscomntools = vs90comntools;
- }
- #elif (_MSC_VER == 1400) // VC80
- else if(vs80comntools) {
- vscomntools = vs80comntools;
- }
- #endif
- // Otherwise find any version we can
- else if (vs100comntools)
+ const char *vscomntools = nullptr;
+
+ // Find any version we can
+ if (vs100comntools)
vscomntools = vs100comntools;
else if (vs90comntools)
vscomntools = vs90comntools;
@@ -277,8 +273,6 @@
return false;
}
-#endif // _MSC_VER
-
void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
if (DriverArgs.hasArg(options::OPT_nostdinc))
@@ -293,7 +287,6 @@
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
-#ifdef _MSC_VER
// Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
if (const char *cl_include_dir = getenv("INCLUDE")) {
SmallVector<StringRef, 8> Dirs;
@@ -328,6 +321,7 @@
}
// As a fallback, select default install paths.
+ // FIXME: Don't guess drives and paths like this on Windows.
const StringRef Paths[] = {
"C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
"C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
@@ -336,7 +330,6 @@
"C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
};
addSystemIncludes(DriverArgs, CC1Args, Paths);
-#endif // _MSC_VER
}
void Windows::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,