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