diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Compilation.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Driver.cpp | 126 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp | 177 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/InputInfo.h | 15 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Job.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Makefile | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/OptTable.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Option.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp | 140 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp | 265 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.h | 50 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Tools.cpp | 500 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Tools.h | 95 |
13 files changed, 822 insertions, 575 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp index 282e9fe..c059afd 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp @@ -83,10 +83,6 @@ void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J, OS << '"'; } OS << Terminator; - } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { - for (PipedJob::const_iterator - it = PJ->begin(), ie = PJ->end(); it != ie; ++it) - PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote); } else { const JobList *Jobs = cast<JobList>(&J); for (JobList::const_iterator @@ -190,14 +186,6 @@ int Compilation::ExecuteJob(const Job &J, const Command *&FailingCommand) const { if (const Command *C = dyn_cast<Command>(&J)) { return ExecuteCommand(*C, FailingCommand); - } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { - // Piped commands with a single job are easy. - if (PJ->size() == 1) - return ExecuteCommand(**PJ->begin(), FailingCommand); - - FailingCommand = *PJ->begin(); - getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe"; - return 1; } else { const JobList *Jobs = cast<JobList>(&J); for (JobList::const_iterator diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp index 2fc0a53..82f9134 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp @@ -25,6 +25,7 @@ #include "clang/Basic/Version.h" +#include "llvm/Config/config.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/PrettyStackTrace.h" @@ -39,13 +40,13 @@ using namespace clang::driver; using namespace clang; -Driver::Driver(llvm::StringRef _Name, llvm::StringRef _Dir, +Driver::Driver(llvm::StringRef _ClangExecutable, llvm::StringRef _DefaultHostTriple, llvm::StringRef _DefaultImageName, bool IsProduction, bool CXXIsProduction, Diagnostic &_Diags) : Opts(createDriverOptTable()), Diags(_Diags), - Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple), + ClangExecutable(_ClangExecutable), DefaultHostTriple(_DefaultHostTriple), DefaultImageName(_DefaultImageName), DriverTitle("clang \"gcc-compatible\" driver"), Host(0), @@ -68,6 +69,10 @@ Driver::Driver(llvm::StringRef _Name, llvm::StringRef _Dir, CCCUseClangCXX = false; } + llvm::sys::Path Executable(ClangExecutable); + Name = Executable.getBasename(); + Dir = Executable.getDirname(); + // Compute the path to the resource directory. llvm::sys::Path P(Dir); P.eraseComponent(); // Remove /bin from foo/bin @@ -75,11 +80,6 @@ Driver::Driver(llvm::StringRef _Name, llvm::StringRef _Dir, P.appendComponent("clang"); P.appendComponent(CLANG_VERSION_STRING); ResourceDir = P.str(); - - // Save the original clang executable path. - P = Dir; - P.appendComponent(Name); - ClangExecutable = P.str(); } Driver::~Driver() { @@ -160,6 +160,16 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { DAL->append(*it); } + // Add a default value of -mlinker-version=, if one was given and the user + // didn't specify one. +#if defined(HOST_LINK_VERSION) + if (!Args.hasArg(options::OPT_mlinker_version_EQ)) { + DAL->AddJoinedArg(0, Opts->getOption(options::OPT_mlinker_version_EQ), + HOST_LINK_VERSION); + DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim(); + } +#endif + return DAL; } @@ -176,13 +186,15 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { bool CCCPrintOptions = false, CCCPrintActions = false; const char **Start = argv + 1, **End = argv + argc; - const char *HostTriple = DefaultHostTriple.c_str(); InputArgList *Args = ParseArgStrings(Start, End); // -no-canonical-prefixes is used very early in main. Args->ClaimAllArgs(options::OPT_no_canonical_prefixes); + // Ignore -pipe. + Args->ClaimAllArgs(options::OPT_pipe); + // Extract -ccc args. // // FIXME: We need to figure out where this behavior should live. Most of it @@ -223,14 +235,16 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { Cur = Split.second; } } + // FIXME: We shouldn't overwrite the default host triple here, but we have + // nowhere else to put this currently. if (const Arg *A = Args->getLastArg(options::OPT_ccc_host_triple)) - HostTriple = A->getValue(*Args); + DefaultHostTriple = A->getValue(*Args); if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir)) - Dir = A->getValue(*Args); + Dir = InstalledDir = A->getValue(*Args); if (const Arg *A = Args->getLastArg(options::OPT_B)) PrefixDir = A->getValue(*Args); - Host = GetHostInfo(HostTriple); + Host = GetHostInfo(DefaultHostTriple.c_str()); // Perform the default argument translations. DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args); @@ -248,14 +262,12 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { if (!HandleImmediateArgs(*C)) return C; - // Construct the list of abstract actions to perform for this compilation. We - // avoid passing a Compilation here simply to enforce the abstraction that - // pipelining is not host or toolchain dependent (other than the driver driver - // test). + // Construct the list of abstract actions to perform for this compilation. if (Host->useDriverDriver()) - BuildUniversalActions(C->getArgs(), C->getActions()); + BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(), + C->getActions()); else - BuildActions(C->getArgs(), C->getActions()); + BuildActions(C->getDefaultToolChain(), C->getArgs(), C->getActions()); if (CCCPrintActions) { PrintActions(*C); @@ -525,7 +537,8 @@ static bool ContainsCompileAction(const Action *A) { return false; } -void Driver::BuildUniversalActions(const ArgList &Args, +void Driver::BuildUniversalActions(const ToolChain &TC, + const ArgList &Args, ActionList &Actions) const { llvm::PrettyStackTraceString CrashInfo("Building universal build actions"); // Collect the list of architectures. Duplicates are allowed, but should only @@ -570,7 +583,7 @@ void Driver::BuildUniversalActions(const ArgList &Args, } ActionList SingleActions; - BuildActions(Args, SingleActions); + BuildActions(TC, Args, SingleActions); // Add in arch bindings for every top level action, as well as lipo and // dsymutil steps if needed. @@ -620,7 +633,8 @@ void Driver::BuildUniversalActions(const ArgList &Args, } } -void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const { +void Driver::BuildActions(const ToolChain &TC, const ArgList &Args, + ActionList &Actions) const { llvm::PrettyStackTraceString CrashInfo("Building compilation actions"); // Start by constructing the list of inputs and their types. @@ -660,7 +674,7 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const { // found. We use a host hook here because Darwin at least has its own // idea of what .s is. if (const char *Ext = strrchr(Value, '.')) - Ty = Host->lookupTypeForExtension(Ext + 1); + Ty = TC.LookupTypeForExtension(Ext + 1); if (Ty == types::TY_INVALID) Ty = types::TY_Object; @@ -885,16 +899,6 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, void Driver::BuildJobs(Compilation &C) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); - bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps); - bool UsePipes = C.getArgs().hasArg(options::OPT_pipe); - - // FIXME: Pipes are forcibly disabled until we support executing them. - if (!CCCPrintBindings) - UsePipes = false; - - // -save-temps inhibits pipes. - if (SaveTemps && UsePipes) - Diag(clang::diag::warn_drv_pipe_ignored_with_save_temps); Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); @@ -934,7 +938,6 @@ void Driver::BuildJobs(Compilation &C) const { InputInfo II; BuildJobsForAction(C, A, &C.getDefaultToolChain(), /*BoundArch*/0, - /*CanAcceptPipe*/ true, /*AtTopLevel*/ true, /*LinkingOutput*/ LinkingOutput, II); @@ -1032,17 +1035,11 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, const char *BoundArch, - bool CanAcceptPipe, bool AtTopLevel, const char *LinkingOutput, InputInfo &Result) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); - bool UsePipes = C.getArgs().hasArg(options::OPT_pipe); - // FIXME: Pipes are forcibly disabled until we support executing them. - if (!CCCPrintBindings) - UsePipes = false; - if (const InputAction *IA = dyn_cast<InputAction>(A)) { // FIXME: It would be nice to not claim this here; maybe the old scheme of // just using Args was better? @@ -1064,7 +1061,7 @@ void Driver::BuildJobsForAction(Compilation &C, TC = Host->CreateToolChain(C.getArgs(), BAA->getArchName()); BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), - CanAcceptPipe, AtTopLevel, LinkingOutput, Result); + AtTopLevel, LinkingOutput, Result); return; } @@ -1074,7 +1071,6 @@ void Driver::BuildJobsForAction(Compilation &C, const Tool &T = SelectToolForJob(C, TC, JA, Inputs); // Only use pipes when there is exactly one input. - bool TryToUsePipeInput = Inputs->size() == 1 && T.acceptsPipedInput(); InputInfoList InputInfos; for (ActionList::const_iterator it = Inputs->begin(), ie = Inputs->end(); it != ie; ++it) { @@ -1087,33 +1083,11 @@ void Driver::BuildJobsForAction(Compilation &C, SubJobAtTopLevel = true; InputInfo II; - BuildJobsForAction(C, *it, TC, BoundArch, TryToUsePipeInput, + BuildJobsForAction(C, *it, TC, BoundArch, SubJobAtTopLevel, LinkingOutput, II); InputInfos.push_back(II); } - // Determine if we should output to a pipe. - bool OutputToPipe = false; - if (CanAcceptPipe && T.canPipeOutput()) { - // Some actions default to writing to a pipe if they are the top level phase - // and there was no user override. - // - // FIXME: Is there a better way to handle this? - if (AtTopLevel) { - if (isa<PreprocessJobAction>(A) && !C.getArgs().hasArg(options::OPT_o)) - OutputToPipe = true; - } else if (UsePipes) - OutputToPipe = true; - } - - // Figure out where to put the job (pipes). - Job *Dest = &C.getJobs(); - if (InputInfos[0].isPipe()) { - assert(TryToUsePipeInput && "Unrequested pipe!"); - assert(InputInfos.size() == 1 && "Unexpected pipe with multiple inputs."); - Dest = &InputInfos[0].getPipe(); - } - // Always use the first input as the base input. const char *BaseInput = InputInfos[0].getBaseInput(); @@ -1122,22 +1096,9 @@ void Driver::BuildJobsForAction(Compilation &C, if (JA->getType() == types::TY_dSYM) BaseInput = InputInfos[0].getFilename(); - // Determine the place to write output to (nothing, pipe, or filename) and - // where to put the new job. + // Determine the place to write output to, if any. if (JA->getType() == types::TY_Nothing) { Result = InputInfo(A->getType(), BaseInput); - } else if (OutputToPipe) { - // Append to current piped job or create a new one as appropriate. - PipedJob *PJ = dyn_cast<PipedJob>(Dest); - if (!PJ) { - PJ = new PipedJob(); - // FIXME: Temporary hack so that -ccc-print-bindings work until we have - // pipe support. Please remove later. - if (!CCCPrintBindings) - cast<JobList>(Dest)->addJob(PJ); - Dest = PJ; - } - Result = InputInfo(PJ, A->getType(), BaseInput); } else { Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel), A->getType(), BaseInput); @@ -1153,7 +1114,7 @@ void Driver::BuildJobsForAction(Compilation &C, } llvm::errs() << "], output: " << Result.getAsString() << "\n"; } else { - T.ConstructJob(C, *JA, *Dest, Result, InputInfos, + T.ConstructJob(C, *JA, Result, InputInfos, C.getArgsForToolChain(TC, BoundArch), LinkingOutput); } } @@ -1169,6 +1130,10 @@ const char *Driver::GetNamedOutputPath(Compilation &C, return C.addResultFile(FinalOutput->getValue(C.getArgs())); } + // Default to writing to stdout? + if (AtTopLevel && isa<PreprocessJobAction>(JA)) + return "-"; + // Output to a temporary file? if (!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps)) { std::string TmpName = @@ -1307,6 +1272,11 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const { return createMinixHostInfo(*this, Triple); case llvm::Triple::Linux: return createLinuxHostInfo(*this, Triple); + case llvm::Triple::Win32: + return createWindowsHostInfo(*this, Triple); + case llvm::Triple::MinGW32: + case llvm::Triple::MinGW64: + return createMinGWHostInfo(*this, Triple); default: return createUnknownHostInfo(*this, Triple); } diff --git a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp index 0636d9e..7c5e430 100644 --- a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp @@ -38,12 +38,6 @@ namespace { /// DarwinHostInfo - Darwin host information implementation. class DarwinHostInfo : public HostInfo { - /// Darwin version of host. - unsigned DarwinVersion[3]; - - /// GCC version to use on this host. - unsigned GCCVersion[3]; - /// Cache of tool chains we have created. mutable llvm::DenseMap<unsigned, ToolChain*> ToolChains; @@ -53,37 +47,12 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - types::ID Ty = types::lookupTypeForExtension(Ext); - - // Darwin always preprocesses assembly files (unless -x is used - // explicitly). - if (Ty == types::TY_PP_Asm) - return types::TY_Asm; - - return Ty; - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple) : HostInfo(D, Triple) { - - assert(Triple.getArch() != llvm::Triple::UnknownArch && "Invalid arch!"); - assert(memcmp(&getOSName()[0], "darwin", 6) == 0 && - "Unknown Darwin platform."); - bool HadExtra; - if (!Driver::GetReleaseVersion(&getOSName()[6], - DarwinVersion[0], DarwinVersion[1], - DarwinVersion[2], HadExtra)) - D.Diag(clang::diag::err_drv_invalid_darwin_version) << getOSName(); - - // We can only call 4.2.1 for now. - GCCVersion[0] = 4; - GCCVersion[1] = 2; - GCCVersion[2] = 1; } DarwinHostInfo::~DarwinHostInfo() { @@ -147,11 +116,10 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args, const char *UseNewToolChain = ::getenv("CCC_ENABLE_NEW_DARWIN_TOOLCHAIN"); if (UseNewToolChain || Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) { - TC = new toolchains::DarwinClang(*this, TCTriple, DarwinVersion); + TC = new toolchains::DarwinClang(*this, TCTriple); } else if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { // We still use the legacy DarwinGCC toolchain on X86. - TC = new toolchains::DarwinGCC(*this, TCTriple, DarwinVersion, - GCCVersion); + TC = new toolchains::DarwinGCC(*this, TCTriple); } else TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple); } @@ -170,15 +138,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - types::ID Ty = types::lookupTypeForExtension(Ext); - - if (Ty == types::TY_PP_Asm) - return types::TY_Asm; - - return Ty; - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -212,10 +171,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -279,10 +234,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -330,10 +281,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -379,10 +326,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -399,19 +342,22 @@ bool FreeBSDHostInfo::useDriverDriver() const { ToolChain *FreeBSDHostInfo::CreateToolChain(const ArgList &Args, const char *ArchName) const { - bool Lib32 = false; - assert(!ArchName && "Unexpected arch name on platform without driver driver support."); - // On x86_64 we need to be able to compile 32-bits binaries as well. - // Compiling 64-bit binaries on i386 is not supported. We don't have a - // lib64. + // Automatically handle some instances of -m32/-m64 we know about. std::string Arch = getArchName(); ArchName = Arch.c_str(); - if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") { - ArchName = "i386"; - Lib32 = true; + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64"; + } } ToolChain *&TC = ToolChains[ArchName]; @@ -419,7 +365,7 @@ ToolChain *FreeBSDHostInfo::CreateToolChain(const ArgList &Args, llvm::Triple TCTriple(getTriple()); TCTriple.setArchName(ArchName); - TC = new toolchains::FreeBSD(*this, TCTriple, Lib32); + TC = new toolchains::FreeBSD(*this, TCTriple); } return TC; @@ -439,10 +385,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -491,10 +433,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -540,10 +478,6 @@ public: virtual bool useDriverDriver() const; - virtual types::ID lookupTypeForExtension(const char *Ext) const { - return types::lookupTypeForExtension(Ext); - } - virtual ToolChain *CreateToolChain(const ArgList &Args, const char *ArchName) const; }; @@ -591,8 +525,79 @@ ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args, return TC; } +// Windows Host Info + +/// WindowsHostInfo - Host information to use on Microsoft Windows. +class WindowsHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + WindowsHostInfo(const Driver &D, const llvm::Triple& Triple); + ~WindowsHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +WindowsHostInfo::WindowsHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { +} + +WindowsHostInfo::~WindowsHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool WindowsHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *WindowsHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + // Automatically handle some instances of -m32/-m64 we know about. + std::string Arch = getArchName(); + ArchName = Arch.c_str(); + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Windows(*this, TCTriple); + } + + return TC; } +// FIXME: This is a placeholder. +class MinGWHostInfo : public UnknownHostInfo { +public: + MinGWHostInfo(const Driver &D, const llvm::Triple& Triple); +}; + +MinGWHostInfo::MinGWHostInfo(const Driver &D, const llvm::Triple& Triple) + : UnknownHostInfo(D, Triple) {} + +} // end anon namespace + const HostInfo * clang::driver::createAuroraUXHostInfo(const Driver &D, const llvm::Triple& Triple){ @@ -642,6 +647,18 @@ clang::driver::createTCEHostInfo(const Driver &D, } const HostInfo * +clang::driver::createWindowsHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new WindowsHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createMinGWHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new MinGWHostInfo(D, Triple); +} + +const HostInfo * clang::driver::createUnknownHostInfo(const Driver &D, const llvm::Triple& Triple) { return new UnknownHostInfo(D, Triple); diff --git a/contrib/llvm/tools/clang/lib/Driver/InputInfo.h b/contrib/llvm/tools/clang/lib/Driver/InputInfo.h index c657bef..2a2f4b9 100644 --- a/contrib/llvm/tools/clang/lib/Driver/InputInfo.h +++ b/contrib/llvm/tools/clang/lib/Driver/InputInfo.h @@ -17,7 +17,6 @@ namespace clang { namespace driver { - class PipedJob; /// InputInfo - Wrapper for information about an input source. class InputInfo { @@ -37,7 +36,6 @@ class InputInfo { union { const char *Filename; const Arg *InputArg; - PipedJob *Pipe; } Data; Class Kind; types::ID Type; @@ -56,15 +54,10 @@ public: : Kind(InputArg), Type(_Type), BaseInput(_BaseInput) { Data.InputArg = _InputArg; } - InputInfo(PipedJob *_Pipe, types::ID _Type, const char *_BaseInput) - : Kind(Pipe), Type(_Type), BaseInput(_BaseInput) { - Data.Pipe = _Pipe; - } bool isNothing() const { return Kind == Nothing; } bool isFilename() const { return Kind == Filename; } bool isInputArg() const { return Kind == InputArg; } - bool isPipe() const { return Kind == Pipe; } types::ID getType() const { return Type; } const char *getBaseInput() const { return BaseInput; } @@ -76,17 +69,11 @@ public: assert(isInputArg() && "Invalid accessor."); return *Data.InputArg; } - PipedJob &getPipe() const { - assert(isPipe() && "Invalid accessor."); - return *Data.Pipe; - } /// getAsString - Return a string name for this input, for /// debugging. std::string getAsString() const { - if (isPipe()) - return "(pipe)"; - else if (isFilename()) + if (isFilename()) return std::string("\"") + getFilename() + '"'; else if (isInputArg()) return "(input arg)"; diff --git a/contrib/llvm/tools/clang/lib/Driver/Job.cpp b/contrib/llvm/tools/clang/lib/Driver/Job.cpp index bfeb41a..fa7d060 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Job.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Job.cpp @@ -21,13 +21,6 @@ Command::Command(const Action &_Source, const Tool &_Creator, { } -PipedJob::PipedJob() : Job(PipedJobClass) {} - -PipedJob::~PipedJob() { - for (iterator it = begin(), ie = end(); it != ie; ++it) - delete *it; -} - JobList::JobList() : Job(JobListClass) {} JobList::~JobList() { @@ -36,9 +29,6 @@ JobList::~JobList() { } void Job::addCommand(Command *C) { - if (PipedJob *PJ = dyn_cast<PipedJob>(this)) - PJ->addCommand(C); - else - cast<JobList>(this)->addJob(C); + cast<JobList>(this)->addJob(C); } diff --git a/contrib/llvm/tools/clang/lib/Driver/Makefile b/contrib/llvm/tools/clang/lib/Driver/Makefile index 7bc340e..454ab86 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Makefile +++ b/contrib/llvm/tools/clang/lib/Driver/Makefile @@ -9,6 +9,5 @@ CLANG_LEVEL := ../.. LIBRARYNAME := clangDriver -BUILD_ARCHIVE = 1 include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp index 39530f2..3c36314 100644 --- a/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/OptTable.cpp @@ -164,6 +164,8 @@ Option *OptTable::CreateOption(unsigned id) const { Opt->setLinkerInput(true); if (info.Flags & NoArgumentUnused) Opt->setNoArgumentUnused(true); + if (info.Flags & NoForward) + Opt->setNoForward(true); if (info.Flags & RenderAsInput) Opt->setNoOptAsInput(true); if (info.Flags & RenderJoined) { diff --git a/contrib/llvm/tools/clang/lib/Driver/Option.cpp b/contrib/llvm/tools/clang/lib/Driver/Option.cpp index dd48af8..5396250 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Option.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Option.cpp @@ -20,7 +20,7 @@ Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name, const OptionGroup *_Group, const Option *_Alias) : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias), Unsupported(false), LinkerInput(false), NoOptAsInput(false), - DriverOption(false), NoArgumentUnused(false) { + DriverOption(false), NoArgumentUnused(false), NoForward(false) { // Multi-level aliases are not supported, and alias options cannot // have groups. This just simplifies option tracking, it is not an diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp index 9fae67d..94c1c6b 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp @@ -10,8 +10,12 @@ #include "clang/Driver/ToolChain.h" #include "clang/Driver/Action.h" +#include "clang/Driver/Arg.h" +#include "clang/Driver/ArgList.h" #include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/HostInfo.h" +#include "clang/Driver/Options.h" using namespace clang::driver; @@ -34,3 +38,139 @@ std::string ToolChain::GetFilePath(const char *Name) const { std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const { return Host.getDriver().GetProgramPath(Name, *this, WantFile); } + +types::ID ToolChain::LookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); +} + +/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting. +// +// FIXME: tblgen this. +static const char *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); + + llvm::StringRef MArch; + if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + // Otherwise, if we have -march= choose the base CPU for that arch. + MArch = A->getValue(Args); + } else { + // Otherwise, use the Arch from the triple. + MArch = Triple.getArchName(); + } + + if (MArch == "armv2" || MArch == "armv2a") + return "arm2"; + if (MArch == "armv3") + return "arm6"; + if (MArch == "armv3m") + return "arm7m"; + if (MArch == "armv4" || MArch == "armv4t") + return "arm7tdmi"; + if (MArch == "armv5" || MArch == "armv5t") + return "arm10tdmi"; + if (MArch == "armv5e" || MArch == "armv5te") + return "arm1026ejs"; + if (MArch == "armv5tej") + return "arm926ej-s"; + if (MArch == "armv6" || MArch == "armv6k") + return "arm1136jf-s"; + if (MArch == "armv6j") + return "arm1136j-s"; + if (MArch == "armv6z" || MArch == "armv6zk") + return "arm1176jzf-s"; + if (MArch == "armv6t2") + return "arm1156t2-s"; + if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") + return "cortex-a8"; + if (MArch == "armv7r" || MArch == "armv7-r") + return "cortex-r4"; + if (MArch == "armv7m" || MArch == "armv7-m") + return "cortex-m3"; + if (MArch == "ep9312") + return "ep9312"; + if (MArch == "iwmmxt") + return "iwmmxt"; + if (MArch == "xscale") + return "xscale"; + + // If all else failed, return the most base CPU LLVM supports. + return "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(llvm::StringRef CPU) { + if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" || + CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" || + CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" || + CPU == "arm940t" || CPU == "ep9312") + return "v4t"; + + if (CPU == "arm10tdmi" || CPU == "arm1020t") + return "v5"; + + if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" || + CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" || + CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" || + CPU == "iwmmxt") + return "v5e"; + + if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" || + CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore") + return "v6"; + + if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s") + return "v6t2"; + + if (CPU == "cortex-a8" || CPU == "cortex-a9") + return "v7"; + + return ""; +} + +std::string ToolChain::ComputeLLVMTriple(const ArgList &Args) const { + switch (getTriple().getArch()) { + default: + return getTripleString(); + + case llvm::Triple::arm: + case llvm::Triple::thumb: { + // FIXME: Factor into subclasses. + llvm::Triple Triple = getTriple(); + + // Thumb2 is the default for V7 on Darwin. + // + // FIXME: Thumb should just be another -target-feaure, not in the triple. + llvm::StringRef Suffix = + getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); + bool ThumbDefault = + (Suffix == "v7" && getTriple().getOS() == llvm::Triple::Darwin); + std::string ArchName = "arm"; + if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) + ArchName = "thumb"; + Triple.setArchName(ArchName + Suffix.str()); + + return Triple.getTriple(); + } + } +} + +std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args) const { + // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on + // non-Darwin. + if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, + options::OPT_miphoneos_version_min_EQ)) + getDriver().Diag(clang::diag::err_drv_clang_unsupported) + << A->getAsString(Args); + + return ComputeLLVMTriple(Args); +} + diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index 3506590..596173d 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -18,7 +18,9 @@ #include "clang/Driver/OptTable.h" #include "clang/Driver/Option.h" #include "clang/Driver/Options.h" +#include "clang/Basic/Version.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -35,13 +37,30 @@ using namespace clang::driver::toolchains; /// Darwin - Darwin tool chain for i386 and x86_64. -Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&_DarwinVersion)[3]) +Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple) : ToolChain(Host, Triple), TargetInitialized(false) { + // Compute the initial Darwin version based on the host. + bool HadExtra; + std::string OSName = Triple.getOSName(); + if (!Driver::GetReleaseVersion(&OSName[6], + DarwinVersion[0], DarwinVersion[1], + DarwinVersion[2], HadExtra)) + getDriver().Diag(clang::diag::err_drv_invalid_darwin_version) << OSName; + llvm::raw_string_ostream(MacosxVersionMin) - << "10." << std::max(0, (int)_DarwinVersion[0] - 4) << '.' - << _DarwinVersion[1]; + << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.' + << DarwinVersion[1]; +} + +types::ID Darwin::LookupTypeForExtension(const char *Ext) const { + types::ID Ty = types::lookupTypeForExtension(Ext); + + // Darwin always preprocesses assembly files (unless -x is used explicitly). + if (Ty == types::TY_PP_Asm) + return types::TY_Asm; + + return Ty; } // FIXME: Can we tablegen this? @@ -107,14 +126,13 @@ llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const { } } -DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3], - const unsigned (&_GCCVersion)[3]) - : Darwin(Host, Triple, DarwinVersion) +DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple) + : Darwin(Host, Triple) { - GCCVersion[0] = _GCCVersion[0]; - GCCVersion[1] = _GCCVersion[1]; - GCCVersion[2] = _GCCVersion[2]; + // We can only work with 4.2.1 currently. + GCCVersion[0] = 4; + GCCVersion[1] = 2; + GCCVersion[2] = 1; // Set up the tool chain paths to match gcc. ToolChainDir = "i686-apple-darwin"; @@ -178,7 +196,9 @@ DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, Path += ToolChainDir; getProgramPaths().push_back(Path); - getProgramPaths().push_back(getDriver().Dir); + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir) + getProgramPaths().push_back(getDriver().Dir); } Darwin::~Darwin() { @@ -188,6 +208,38 @@ Darwin::~Darwin() { delete it->second; } +std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const { + llvm::Triple Triple(ComputeLLVMTriple(Args)); + + // If the target isn't initialized (e.g., an unknown Darwin platform, return + // the default triple). + if (!isTargetInitialized()) + return Triple.getTriple(); + + unsigned Version[3]; + getTargetVersion(Version); + + // Mangle the target version into the OS triple component. For historical + // reasons that make little sense, the version passed here is the "darwin" + // version, which drops the 10 and offsets by 4. See inverse code when + // setting the OS version preprocessor define. + if (!isTargetIPhoneOS()) { + Version[0] = Version[1] + 4; + Version[1] = Version[2]; + Version[2] = 0; + } else { + // Use the environment to communicate that we are targetting iPhoneOS. + Triple.setEnvironmentName("iphoneos"); + } + + llvm::SmallString<16> Str; + llvm::raw_svector_ostream(Str) << "darwin" << Version[0] + << "." << Version[1] << "." << Version[2]; + Triple.setOSName(Str.str()); + + return Triple.getTriple(); +} + Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { Action::ActionClass Key; if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) @@ -249,7 +301,7 @@ void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args, CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + "/x86_64")); } - + CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir)); Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir; @@ -318,12 +370,13 @@ void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, } } -DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3]) - : Darwin(Host, Triple, DarwinVersion) +DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple) + : Darwin(Host, Triple) { // We expect 'as', 'ld', etc. to be adjacent to our install dir. - getProgramPaths().push_back(getDriver().Dir); + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir) + getProgramPaths().push_back(getDriver().Dir); } void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, @@ -354,6 +407,39 @@ void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, 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); + llvm::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); + if (P.exists()) + CmdArgs.push_back(Args.MakeArgString("-L" + P.str())); + P.eraseComponent(); + } + if (P.exists()) CmdArgs.push_back(Args.MakeArgString("-L" + P.str())); } @@ -419,18 +505,9 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, } } -DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, - const char *BoundArch) const { - DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); +void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { const OptTable &Opts = getDriver().getOpts(); - // FIXME: We really want to get out of the tool chain level argument - // translation business, as it makes the driver functionality much - // more opaque. For now, we follow gcc closely solely for the - // purpose of easily achieving feature parity & testability. Once we - // have something that works, we should reevaluate each translation - // and try to push it down into tool specific logic. - Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); if (OSXVersion && iPhoneVersion) { @@ -466,17 +543,17 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, if (OSXTarget) { const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); - OSXVersion = DAL->MakeJoinedArg(0, O, OSXTarget); - DAL->append(OSXVersion); + OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); + Args.append(OSXVersion); } else if (iPhoneOSTarget) { const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); - iPhoneVersion = DAL->MakeJoinedArg(0, O, iPhoneOSTarget); - DAL->append(iPhoneVersion); + iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget); + Args.append(iPhoneVersion); } else { // Otherwise, assume we are targeting OS X. const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); - OSXVersion = DAL->MakeJoinedArg(0, O, MacosxVersionMin); - DAL->append(OSXVersion); + OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); + Args.append(OSXVersion); } } @@ -499,6 +576,19 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, << iPhoneVersion->getAsString(Args); } setTarget(iPhoneVersion, Major, Minor, Micro); +} + +DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, + const char *BoundArch) const { + DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); + const OptTable &Opts = getDriver().getOpts(); + + // FIXME: We really want to get out of the tool chain level argument + // translation business, as it makes the driver functionality much + // more opaque. For now, we follow gcc closely solely for the + // purpose of easily achieving feature parity & testability. Once we + // have something that works, we should reevaluate each translation + // and try to push it down into tool specific logic. for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { @@ -677,6 +767,11 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, llvm_unreachable("invalid Darwin arch"); } + // 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); + return DAL; } @@ -713,13 +808,20 @@ bool Darwin::SupportsObjCGC() const { return !isTargetIPhoneOS(); } +std::string +Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const { + return ComputeLLVMTriple(Args); +} + /// Generic_GCC - A tool chain using the 'gcc' command to perform /// all subcommands; this relies on gcc translating the majority of /// command line options. Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) : ToolChain(Host, Triple) { - getProgramPaths().push_back(getDriver().Dir); + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) + getProgramPaths().push_back(getDriver().Dir); } Generic_GCC::~Generic_GCC() { @@ -868,8 +970,16 @@ Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. -FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) +FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { + + // Determine if we are compiling 32-bit code on an x86_64 platform. + bool Lib32 = false; + if (Triple.getArch() == llvm::Triple::x86 && + llvm::Triple(getDriver().DefaultHostTriple).getArch() == + llvm::Triple::x86_64) + Lib32 = true; + getProgramPaths().push_back(getDriver().Dir + "/../libexec"); getProgramPaths().push_back("/usr/libexec"); if (Lib32) { @@ -938,7 +1048,9 @@ Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const { AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { - getProgramPaths().push_back(getDriver().Dir); + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) + getProgramPaths().push_back(getDriver().Dir); getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); @@ -975,7 +1087,8 @@ Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { - getFilePaths().push_back(getDriver().Dir + "/../lib/clang/1.0/"); + getFilePaths().push_back(getDriver().Dir + + "/../lib/clang/" CLANG_VERSION_STRING "/"); getFilePaths().push_back("/lib/"); getFilePaths().push_back("/usr/lib/"); @@ -996,13 +1109,35 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple) // list), but that's messy at best. } +Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const { + Action::ActionClass Key; + if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) + Key = Action::AnalyzeJobClass; + else + Key = JA.getKind(); + + Tool *&T = Tools[Key]; + if (!T) { + switch (Key) { + case Action::AssembleJobClass: + T = new tools::linuxtools::Assemble(*this); break; + default: + T = &Generic_GCC::SelectTool(C, JA); + } + } + + return *T; +} + /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { // Path mangling to find libexec - getProgramPaths().push_back(getDriver().Dir); + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) + getProgramPaths().push_back(getDriver().Dir); getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); @@ -1030,3 +1165,57 @@ Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { return *T; } + +Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple) + : ToolChain(Host, Triple) { +} + +Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const { + Action::ActionClass Key; + if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) + Key = Action::AnalyzeJobClass; + else + Key = JA.getKind(); + + Tool *&T = Tools[Key]; + if (!T) { + switch (Key) { + case Action::InputClass: + case Action::BindArchClass: + case Action::LipoJobClass: + case Action::DsymutilJobClass: + assert(0 && "Invalid tool kind."); + case Action::PreprocessJobClass: + case Action::PrecompileJobClass: + case Action::AnalyzeJobClass: + case Action::CompileJobClass: + T = new tools::Clang(*this); break; + case Action::AssembleJobClass: + T = new tools::ClangAs(*this); break; + case Action::LinkJobClass: + T = new tools::visualstudio::Link(*this); break; + } + } + + return *T; +} + +bool Windows::IsIntegratedAssemblerDefault() const { + return true; +} + +bool Windows::IsUnwindTablesDefault() const { + // FIXME: Gross; we should probably have some separate target + // definition, possibly even reusing the one in clang. + return getArchName() == "x86_64"; +} + +const char *Windows::GetDefaultRelocationModel() const { + return "static"; +} + +const char *Windows::GetForcedPicModel() const { + if (getArchName() == "x86_64") + return "pic"; + return 0; +} diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h index 4bdd00f..d1f1556 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h @@ -42,6 +42,11 @@ public: /// Darwin - The base Darwin tool chain. class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { +public: + /// The host version. + unsigned DarwinVersion[3]; + +private: mutable llvm::DenseMap<unsigned, Tool*> Tools; /// Whether the information on the target has been initialized. @@ -61,11 +66,15 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { /// initialized. std::string MacosxVersionMin; +private: + void AddDeploymentTarget(DerivedArgList &Args) const; + public: - Darwin(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3]); + Darwin(const HostInfo &Host, const llvm::Triple& Triple); ~Darwin(); + std::string ComputeEffectiveClangTriple(const ArgList &Args) const; + /// @name Darwin Specific Toolchain API /// { @@ -144,17 +153,17 @@ public: /// @name ToolChain Implementation /// { + virtual types::ID LookupTypeForExtension(const char *Ext) const; + virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args, const char *BoundArch) const; virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; virtual bool IsBlocksDefault() const { - // Blocks default to on for OS X 10.6 and iPhoneOS 3.0 and beyond. - if (isTargetIPhoneOS()) - return !isIPhoneOSVersionLT(3); - else - return !isMacosxVersionLT(10, 6); + // Always allow blocks on Darwin; users interested in versioning are + // expected to use /usr/include/Blocks.h. + return true; } virtual bool IsIntegratedAssemblerDefault() const { #ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER @@ -201,8 +210,7 @@ public: /// DarwinClang - The Darwin toolchain used by Clang. class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { public: - DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3]); + DarwinClang(const HostInfo &Host, const llvm::Triple& Triple); /// @name Darwin ToolChain Implementation /// { @@ -225,9 +233,7 @@ class LLVM_LIBRARY_VISIBILITY DarwinGCC : public Darwin { std::string ToolChainDir; public: - DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, - const unsigned (&DarwinVersion)[3], - const unsigned (&GCCVersion)[3]); + DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple); /// @name Darwin ToolChain Implementation /// { @@ -247,6 +253,8 @@ public: Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) {} + std::string ComputeEffectiveClangTriple(const ArgList &Args) const; + virtual const char *GetDefaultRelocationModel() const { return "pic"; } }; @@ -266,7 +274,7 @@ public: class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_GCC { public: - FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32); + FreeBSD(const HostInfo &Host, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; @@ -288,6 +296,8 @@ public: class LLVM_LIBRARY_VISIBILITY Linux : public Generic_GCC { public: Linux(const HostInfo &Host, const llvm::Triple& Triple); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; @@ -309,6 +319,20 @@ private: }; +class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { + mutable llvm::DenseMap<unsigned, Tool*> Tools; + +public: + Windows(const HostInfo &Host, const llvm::Triple& Triple); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; + + virtual bool IsIntegratedAssemblerDefault() const; + virtual bool IsUnwindTablesDefault() const; + virtual const char *GetDefaultRelocationModel() const; + virtual const char *GetForcedPicModel() const; +}; + } // end namespace toolchains } // end namespace driver } // end namespace clang diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp index c2cb1fb..5c16cd3 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp @@ -105,10 +105,7 @@ void Clang::AddPreprocessingOptions(const Driver &D, // Determine the output location. const char *DepFile; if (Output.getType() == types::TY_Dependencies) { - if (Output.isPipe()) - DepFile = "-"; - else - DepFile = Output.getFilename(); + DepFile = Output.getFilename(); } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) { DepFile = MF->getValue(Args); } else if (A->getOption().matches(options::OPT_M) || @@ -182,10 +179,8 @@ void Clang::AddPreprocessingOptions(const Driver &D, const Arg *A = it; if (A->getOption().matches(options::OPT_include)) { - // Use PCH if the user requested it, except for C++ (for now). + // Use PCH if the user requested it. bool UsePCH = D.CCCUsePCH; - if (types::isCXX(Inputs[0].getType())) - UsePCH = false; bool FoundPTH = false; bool FoundPCH = false; @@ -342,35 +337,6 @@ static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) { return ""; } -/// getLLVMTriple - Get the LLVM triple to use for a particular toolchain, which -/// may depend on command line arguments. -static std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) { - switch (TC.getTriple().getArch()) { - default: - return TC.getTripleString(); - - case llvm::Triple::arm: - case llvm::Triple::thumb: { - // FIXME: Factor into subclasses. - llvm::Triple Triple = TC.getTriple(); - - // Thumb2 is the default for V7 on Darwin. - // - // FIXME: Thumb should just be another -target-feaure, not in the triple. - llvm::StringRef Suffix = - getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); - bool ThumbDefault = - (Suffix == "v7" && TC.getTriple().getOS() == llvm::Triple::Darwin); - std::string ArchName = "arm"; - if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) - ArchName = "thumb"; - Triple.setArchName(ArchName + Suffix.str()); - - return Triple.getTriple(); - } - } -} - // FIXME: Move to target hook. static bool isSignedCharDefault(const llvm::Triple &Triple) { switch (Triple.getArch()) { @@ -633,6 +599,11 @@ void Clang::AddX86TargetArgs(const ArgList &Args, CPUName = "x86-64"; else if (getToolChain().getArchName() == "i386") CPUName = "i586"; + } else if (getToolChain().getOS().startswith("openbsd")) { + if (getToolChain().getArchName() == "x86_64") + CPUName = "x86-64"; + else if (getToolChain().getArchName() == "i386") + CPUName = "i486"; } else { if (getToolChain().getArchName() == "x86_64") CPUName = "x86-64"; @@ -694,57 +665,7 @@ static bool needsExceptions(const ArgList &Args, types::ID InputType, } } -/// getEffectiveClangTriple - Get the "effective" target triple, which is the -/// triple for the target but with the OS version potentially modified for -/// Darwin's -mmacosx-version-min. -static std::string getEffectiveClangTriple(const Driver &D, - const ToolChain &TC, - const ArgList &Args) { - llvm::Triple Triple(getLLVMTriple(TC, Args)); - - // Handle -mmacosx-version-min and -miphoneos-version-min. - if (Triple.getOS() != llvm::Triple::Darwin) { - // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on - // non-Darwin. - if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, - options::OPT_miphoneos_version_min_EQ)) - D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); - } else { - const toolchains::Darwin &DarwinTC( - reinterpret_cast<const toolchains::Darwin&>(TC)); - - // If the target isn't initialized (e.g., an unknown Darwin platform, return - // the default triple). - if (!DarwinTC.isTargetInitialized()) - return Triple.getTriple(); - - unsigned Version[3]; - DarwinTC.getTargetVersion(Version); - - // Mangle the target version into the OS triple component. For historical - // reasons that make little sense, the version passed here is the "darwin" - // version, which drops the 10 and offsets by 4. See inverse code when - // setting the OS version preprocessor define. - if (!DarwinTC.isTargetIPhoneOS()) { - Version[0] = Version[1] + 4; - Version[1] = Version[2]; - Version[2] = 0; - } else { - // Use the environment to communicate that we are targetting iPhoneOS. - Triple.setEnvironmentName("iphoneos"); - } - - llvm::SmallString<16> Str; - llvm::raw_svector_ostream(Str) << "darwin" << Version[0] - << "." << Version[1] << "." << Version[2]; - Triple.setOSName(Str.str()); - } - - return Triple.getTriple(); -} - void Clang::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -763,10 +684,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Add the "effective" target triple. CmdArgs.push_back("-triple"); - std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); + std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); CmdArgs.push_back(Args.MakeArgString(TripleStr)); // Select the appropriate action. + bool IsRewriter = false; if (isa<AnalyzeJobAction>(JA)) { assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); @@ -786,11 +708,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_mno_relax_all, !IsOpt)) CmdArgs.push_back("-mrelax-all"); + + // When using an integrated assembler, we send -Wa, and -Xassembler options + // to -cc1. + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, + options::OPT_Xassembler); } else if (isa<PrecompileJobAction>(JA)) { - // Use PCH if the user requested it, except for C++ (for now). + // Use PCH if the user requested it. bool UsePCH = D.CCCUsePCH; - if (types::isCXX(Inputs[0].getType())) - UsePCH = false; if (UsePCH) CmdArgs.push_back("-emit-pch"); @@ -813,6 +738,7 @@ 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"); + IsRewriter = true; } else { assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!"); @@ -856,6 +782,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Do not enable the missing -dealloc check. // '-analyzer-check-objc-missing-dealloc', CmdArgs.push_back("-analyzer-check-objc-unused-ivars"); + CmdArgs.push_back("-analyzer-check-idempotent-operations"); } // Set the output format. The default is plist, for (lame) historical @@ -999,6 +926,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, break; } + // Pass the linker version in use. + if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { + CmdArgs.push_back("-target-linker-version"); + CmdArgs.push_back(A->getValue(Args)); + } + // -mno-omit-leaf-frame-pointer is default. if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer, options::OPT_mno_omit_leaf_frame_pointer, false)) @@ -1029,6 +962,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddAllArgs(CmdArgs, options::OPT_v); + Args.AddLastArg(CmdArgs, options::OPT_H); Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); @@ -1202,10 +1136,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fno_show_column); 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); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); Args.AddLastArg(CmdArgs, options::OPT_fwrapv); Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); + Args.AddLastArg(CmdArgs, options::OPT_funroll_loops); Args.AddLastArg(CmdArgs, options::OPT_pthread); @@ -1280,15 +1216,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().getTriple().getOS() == llvm::Triple::Win32)) CmdArgs.push_back("-fms-extensions"); + // -fborland-extensions=0 is default. + if (Args.hasFlag(options::OPT_fborland_extensions, + options::OPT_fno_borland_extensions, false)) + CmdArgs.push_back("-fborland-extensions"); + // -fgnu-keywords default varies depending on language; only pass if // specified. if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, options::OPT_fno_gnu_keywords)) A->render(Args, CmdArgs); - // -fnext-runtime is default. + // -fnext-runtime defaults to on Darwin and when rewriting Objective-C, and is + // -the -cc1 default. + bool NeXTRuntimeIsDefault = + IsRewriter || getToolChain().getTriple().getOS() == llvm::Triple::Darwin; if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime, - getToolChain().getTriple().getOS() == llvm::Triple::Darwin)) + NeXTRuntimeIsDefault)) CmdArgs.push_back("-fgnu-runtime"); // -fobjc-nonfragile-abi=0 is default. @@ -1390,7 +1334,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fdiagnostics-show-category"); CmdArgs.push_back(A->getValue(Args)); } - + // Color diagnostics are the default, unless the terminal doesn't support // them. if (Args.hasFlag(options::OPT_fcolor_diagnostics, @@ -1405,7 +1349,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fspell_checking, options::OPT_fno_spell_checking)) CmdArgs.push_back("-fno-spell-checking"); - + if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ)) A->render(Args, CmdArgs); @@ -1465,9 +1409,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Output.getType() == types::TY_Dependencies) { // Handled with other dependency code. - } else if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); } else if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -1480,9 +1421,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &II = *it; CmdArgs.push_back("-x"); CmdArgs.push_back(types::getTypeName(II.getType())); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -1490,7 +1429,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_undef); - std::string Exec = getToolChain().getDriver().getClangProgramPath(); + const char *Exec = getToolChain().getDriver().getClangProgramPath(); // Optionally embed the -cc1 level arguments into the debug info, for build // analysis. @@ -1499,7 +1438,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) (*it)->render(Args, OriginalArgs); - + llvm::SmallString<256> Flags; Flags += Exec; for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { @@ -1510,7 +1449,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(Flags.str())); } - Dest.addCommand(new Command(JA, *this, Exec.c_str(), CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); // Explicitly warn that these options are unsupported, even though // we are allowing compilation to continue. @@ -1534,12 +1473,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; assert(Inputs.size() == 1 && "Unexpected number of inputs."); @@ -1552,7 +1489,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, // Add the "effective" target triple. CmdArgs.push_back("-triple"); - std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); + std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); CmdArgs.push_back(Args.MakeArgString(TripleStr)); // Set the output mode, we currently only expect to be used as a real @@ -1582,19 +1519,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (Input.isPipe()) { - CmdArgs.push_back("-"); - } else { - assert(Input.isFilename() && "Invalid input."); - CmdArgs.push_back(Input.getFilename()); - } + assert(Input.isFilename() && "Invalid input."); + CmdArgs.push_back(Input.getFilename()); - std::string Exec = getToolChain().getDriver().getClangProgramPath(); - Dest.addCommand(new Command(JA, *this, Exec.c_str(), CmdArgs)); + const char *Exec = getToolChain().getDriver().getClangProgramPath(); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -1606,6 +1538,11 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, it = Args.begin(), ie = Args.end(); it != ie; ++it) { Arg *A = *it; if (A->getOption().hasForwardToGCC()) { + // Don't forward any -g arguments to assembly steps. + if (isa<AssembleJobAction>(JA) && + A->getOption().matches(options::OPT_g_Group)) + continue; + // It is unfortunate that we have to claim here, as this means // we will basically never report anything interesting for // platforms using a generic gcc, even if we are just using gcc @@ -1641,10 +1578,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, else if (Arch == "x86_64" || Arch == "powerpc64") CmdArgs.push_back("-m64"); - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -1679,9 +1613,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(types::getTypeName(II.getType())); } - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else // Don't render as input, we need gcc to do the translations. @@ -1691,7 +1623,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, const char *GCCName = getToolChain().getDriver().CCCGenericGCCName.c_str(); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA, @@ -2023,10 +1955,7 @@ void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args, it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, @@ -2064,7 +1993,7 @@ void darwin::CC1::AddCPPArgs(const ArgList &Args, } void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2079,12 +2008,9 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-traditional-cpp"); ArgStringList OutputArgs; - if (Output.isFilename()) { - OutputArgs.push_back("-o"); - OutputArgs.push_back(Output.getFilename()); - } else { - assert(Output.isPipe() && "Unexpected CC1 output."); - } + assert(Output.isFilename() && "Unexpected CC1 output."); + OutputArgs.push_back("-o"); + OutputArgs.push_back(Output.getFilename()); if (Args.hasArg(options::OPT_E)) { AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs); @@ -2098,11 +2024,11 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, const char *CC1Name = getCC1Name(Inputs[0].getType()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(CC1Name)); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2134,9 +2060,7 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList OutputArgs; if (Output.getType() != types::TY_PCH) { OutputArgs.push_back("-o"); - if (Output.isPipe()) - OutputArgs.push_back("-"); - else if (Output.isNothing()) + if (Output.isNothing()) OutputArgs.push_back("/dev/null"); else OutputArgs.push_back(Output.getFilename()); @@ -2169,10 +2093,7 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, return; } - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } if (OutputArgsEarly) { @@ -2198,11 +2119,11 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, const char *CC1Name = getCC1Name(Inputs[0].getType()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(CC1Name)); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2225,7 +2146,9 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // Derived from asm spec. AddDarwinArch(Args, CmdArgs); - if (!getDarwinToolChain().isTargetIPhoneOS() || + // Use -force_cpusubtype_ALL on x86 by default. + if (getToolChain().getTriple().getArch() == llvm::Triple::x86 || + getToolChain().getTriple().getArch() == llvm::Triple::x86_64 || Args.hasArg(options::OPT_force__cpusubtype__ALL)) CmdArgs.push_back("-force_cpusubtype_ALL"); @@ -2242,18 +2165,14 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (Input.isPipe()) { - CmdArgs.push_back("-"); - } else { - assert(Input.isFilename() && "Invalid input."); - CmdArgs.push_back(Input.getFilename()); - } + assert(Input.isFilename() && "Invalid input."); + CmdArgs.push_back(Input.getFilename()); // asm_final spec is empty. const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void darwin::DarwinTool::AddDarwinArch(const ArgList &Args, @@ -2273,6 +2192,22 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); + unsigned Version[3] = { 0, 0, 0 }; + if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { + bool HadExtra; + if (!Driver::GetReleaseVersion(A->getValue(Args), Version[0], + Version[1], Version[2], HadExtra) || + HadExtra) + D.Diag(clang::diag::err_drv_invalid_version_number) + << A->getAsString(Args); + } + + // Newer linkers support -demangle, pass it if supported and not disabled by + // the user. + if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) { + CmdArgs.push_back("-demangle"); + } + // Derived from the "link" spec. Args.AddAllArgs(CmdArgs, options::OPT_static); if (!Args.hasArg(options::OPT_static)) @@ -2414,7 +2349,7 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, } void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2572,11 +2507,11 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2596,11 +2531,11 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2616,11 +2551,11 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2630,27 +2565,21 @@ void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_Xassembler); CmdArgs.push_back("-o"); - if (Output.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(Output.getFilename()); + CmdArgs.push_back(Output.getFilename()); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2677,10 +2606,7 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -2722,9 +2648,7 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -2752,11 +2676,11 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2766,27 +2690,21 @@ void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_Xassembler); CmdArgs.push_back("-o"); - if (Output.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(Output.getFilename()); + CmdArgs.push_back(Output.getFilename()); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2812,10 +2730,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -2839,7 +2754,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Triple.substr(0, 6) == "x86_64") Triple.replace(0, 6, "amd64"); CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + - "/3.3.5")); + "/4.2.1")); Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); @@ -2855,9 +2770,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -2865,6 +2778,11 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { + if (D.CCCIsCXX) { + CmdArgs.push_back("-lstdc++"); + CmdArgs.push_back("-lm"); + } + // FIXME: For some reason GCC passes -lgcc before adding // the default system libraries. Just mimic this for now. CmdArgs.push_back("-lgcc"); @@ -2888,11 +2806,11 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2914,27 +2832,21 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_Xassembler); CmdArgs.push_back("-o"); - if (Output.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(Output.getFilename()); + CmdArgs.push_back(Output.getFilename()); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -2960,10 +2872,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf_i386_fbsd"); } - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -2990,6 +2899,10 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); Args.AddAllArgs(CmdArgs, options::OPT_e); + Args.AddAllArgs(CmdArgs, options::OPT_s); + Args.AddAllArgs(CmdArgs, options::OPT_t); + Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); + Args.AddAllArgs(CmdArgs, options::OPT_r); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { @@ -3001,9 +2914,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -3054,51 +2965,79 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} + +void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + ArgStringList CmdArgs; + + // Add --32/--64 to make sure we get the format we want. + // This is incomplete + if (getToolChain().getArch() == llvm::Triple::x86) { + CmdArgs.push_back("--32"); + } else if (getToolChain().getArch() == llvm::Triple::x86_64) { + CmdArgs.push_back("--64"); + } else if (getToolChain().getArch() == llvm::Triple::arm) { + llvm::StringRef MArch = getToolChain().getArchName(); + if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") + CmdArgs.push_back("-mfpu=neon"); + } + + 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 minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); - if (Output.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(Output.getFilename()); + CmdArgs.push_back(Output.getFilename()); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -3124,9 +3063,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -3157,7 +3094,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("/usr/gnu/bin/gld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } /// DragonFly Tools @@ -3165,7 +3102,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, // For now, DragonFly Assemble does just about the same as for // FreeBSD, but this may change soon. void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -3180,30 +3117,24 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_Xassembler); CmdArgs.push_back("-o"); - if (Output.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(Output.getFilename()); + CmdArgs.push_back(Output.getFilename()); for (InputInfoList::const_iterator it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { const InputInfo &II = *it; - if (II.isPipe()) - CmdArgs.push_back("-"); - else - CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back(II.getFilename()); } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -3225,10 +3156,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf_i386"); } - if (Output.isPipe()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back("-"); - } else if (Output.isFilename()) { + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else { @@ -3266,9 +3194,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); - if (II.isPipe()) - CmdArgs.push_back("-"); - else if (II.isFilename()) + if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else II.getInputArg().renderAsInput(Args, CmdArgs); @@ -3294,6 +3220,11 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("/usr/lib"); } + if (D.CCCIsCXX) { + CmdArgs.push_back("-lstdc++"); + CmdArgs.push_back("-lm"); + } + if (Args.hasArg(options::OPT_shared)) { CmdArgs.push_back("-lgcc_pic"); } else { @@ -3329,5 +3260,46 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} + +void visualstudio::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 (Output.isFilename()) { + CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + Output.getFilename())); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + CmdArgs.push_back("-defaultlib:libcmt"); + } + + CmdArgs.push_back("-nologo"); + + for (InputInfoList::const_iterator + it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { + const InputInfo &II = *it; + + // Don't try to pass LLVM inputs to visual studio linker. + if (II.getType() == types::TY_LLVM_BC) + D.Diag(clang::diag::err_drv_no_linker_llvm_support) + << getToolChain().getTripleString(); + + if (II.isFilename()) + CmdArgs.push_back(II.getFilename()); + else + II.getInputArg().renderAsInput(Args, CmdArgs); + } + + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h index 2a18103..b5defa4 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.h +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h @@ -41,14 +41,11 @@ namespace tools { public: Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedAssembler() const { return true; } virtual bool hasIntegratedCPP() const { return true; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -61,14 +58,11 @@ namespace tools { ClangAs(const ToolChain &TC) : Tool("clang::as", "clang integrated assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedAssembler() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -83,7 +77,6 @@ namespace gcc { const ToolChain &TC) : Tool(Name, ShortName, TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -101,8 +94,6 @@ namespace gcc { Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", "gcc preprocessor", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedCPP() const { return false; } @@ -115,8 +106,6 @@ namespace gcc { Precompile(const ToolChain &TC) : Common("gcc::Precompile", "gcc precompile", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return false; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedCPP() const { return true; } @@ -129,8 +118,6 @@ namespace gcc { Compile(const ToolChain &TC) : Common("gcc::Compile", "gcc frontend", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedCPP() const { return true; } @@ -143,8 +130,6 @@ namespace gcc { Assemble(const ToolChain &TC) : Common("gcc::Assemble", "assembler (via gcc)", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void RenderExtraToolArgs(const JobAction &JA, @@ -156,8 +141,6 @@ namespace gcc { Link(const ToolChain &TC) : Common("gcc::Link", "linker (via gcc)", TC) {} - virtual bool acceptsPipedInput() const { return false; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void RenderExtraToolArgs(const JobAction &JA, @@ -207,8 +190,6 @@ namespace darwin { CC1(const char *Name, const char *ShortName, const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasGoodDiagnostics() const { return true; } virtual bool hasIntegratedCPP() const { return true; } }; @@ -219,7 +200,6 @@ namespace darwin { "gcc preprocessor", TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -231,7 +211,6 @@ namespace darwin { Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -243,12 +222,9 @@ namespace darwin { Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -261,12 +237,9 @@ namespace darwin { public: Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return false; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -277,12 +250,9 @@ namespace darwin { public: Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {} - virtual bool acceptsPipedInput() const { return false; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -294,12 +264,9 @@ namespace darwin { Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil", "dsymutil", TC) {} - virtual bool acceptsPipedInput() const { return false; } - virtual bool canPipeOutput() const { return false; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -314,12 +281,9 @@ namespace openbsd { Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -329,12 +293,9 @@ namespace openbsd { public: Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -349,12 +310,9 @@ namespace freebsd { Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -364,12 +322,9 @@ namespace freebsd { public: Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -377,6 +332,22 @@ namespace freebsd { }; } // end namespace freebsd + /// linux -- Directly call GNU Binutils assembler and linker +namespace linuxtools { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { + public: + Assemble(const ToolChain &TC) : Tool("linux::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; + }; +} /// minix -- Directly call GNU Binutils assembler and linker namespace minix { class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { @@ -384,12 +355,9 @@ namespace minix { Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -399,12 +367,9 @@ namespace minix { public: Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -419,12 +384,9 @@ namespace auroraux { Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -434,12 +396,9 @@ namespace auroraux { public: Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -454,12 +413,9 @@ namespace dragonfly { Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -469,12 +425,9 @@ namespace dragonfly { public: Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {} - virtual bool acceptsPipedInput() const { return true; } - virtual bool canPipeOutput() const { return true; } virtual bool hasIntegratedCPP() const { return false; } virtual void ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &TCArgs, @@ -482,6 +435,22 @@ namespace dragonfly { }; } // end namespace dragonfly + /// Visual studio tools. +namespace visualstudio { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { + public: + Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", 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; + }; +} // end namespace visualstudio + } // end namespace toolchains } // end namespace driver } // end namespace clang |