diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Driver.cpp | 31 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp | 15 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp | 205 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.h | 5 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Tools.cpp | 242 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Tools.h | 14 |
6 files changed, 360 insertions, 152 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp index 302779b..20bc495 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp @@ -46,14 +46,14 @@ using namespace clang::driver; using namespace clang; -Driver::Driver(llvm::StringRef _ClangExecutable, - llvm::StringRef _DefaultHostTriple, - llvm::StringRef _DefaultImageName, +Driver::Driver(llvm::StringRef ClangExecutable, + llvm::StringRef DefaultHostTriple, + llvm::StringRef DefaultImageName, bool IsProduction, bool CXXIsProduction, - Diagnostic &_Diags) - : Opts(createDriverOptTable()), Diags(_Diags), - ClangExecutable(_ClangExecutable), UseStdLib(true), - DefaultHostTriple(_DefaultHostTriple), DefaultImageName(_DefaultImageName), + Diagnostic &Diags) + : Opts(createDriverOptTable()), Diags(Diags), + ClangExecutable(ClangExecutable), UseStdLib(true), + DefaultHostTriple(DefaultHostTriple), DefaultImageName(DefaultImageName), DriverTitle("clang \"gcc-compatible\" driver"), Host(0), CCPrintOptionsFilename(0), CCPrintHeadersFilename(0), @@ -398,9 +398,10 @@ void Driver::PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const { /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories /// option. static void PrintDiagnosticCategories(llvm::raw_ostream &OS) { - for (unsigned i = 1; // Skip the empty category. - const char *CategoryName = DiagnosticIDs::getCategoryNameFromID(i); ++i) - OS << i << ',' << CategoryName << '\n'; + // Skip the empty category. + for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); + i != max; ++i) + OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; } bool Driver::HandleImmediateArgs(const Compilation &C) { @@ -569,14 +570,14 @@ void Driver::PrintActions(const Compilation &C) const { PrintActions1(C, *it, Ids); } -/// \brief Check whether the given input tree contains any compilation (or -/// assembly) actions. -static bool ContainsCompileAction(const Action *A) { +/// \brief Check whether the given input tree contains any compilation or +/// assembly actions. +static bool ContainsCompileOrAssembleAction(const Action *A) { if (isa<CompileJobAction>(A) || isa<AssembleJobAction>(A)) return true; for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it) - if (ContainsCompileAction(*it)) + if (ContainsCompileOrAssembleAction(*it)) return true; return false; @@ -667,7 +668,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC, Arg *A = Args.getLastArg(options::OPT_g_Group); if (A && !A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_gstabs) && - ContainsCompileAction(Actions.back())) { + ContainsCompileOrAssembleAction(Actions.back())) { ActionList Inputs; Inputs.push_back(Actions.back()); Actions.pop_back(); diff --git a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp index 198af54..3b1c2c7 100644 --- a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp @@ -414,15 +414,20 @@ ToolChain *NetBSDHostInfo::CreateToolChain(const ArgList &Args, (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64"; } } + llvm::Triple TargetTriple(getTriple()); + TargetTriple.setArchName(ArchName); - ToolChain *&TC = ToolChains[ArchName]; - if (!TC) { - llvm::Triple TCTriple(getTriple()); - TCTriple.setArchName(ArchName); + ToolChain *TC; - TC = new toolchains::NetBSD(*this, TCTriple); + // XXX Cache toolchain even if -m32 is used + if (Arch == ArchName) { + TC = ToolChains[ArchName]; + if (TC) + return TC; } + TC = new toolchains::NetBSD(*this, TargetTriple, getTriple()); + return TC; } diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index 499587a..2f7bd75 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -9,6 +9,10 @@ #include "ToolChains.h" +#ifdef HAVE_CLANG_CONFIG_H +# include "clang/Config/config.h" +#endif + #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/Compilation.h" @@ -119,7 +123,7 @@ llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const { switch (getTriple().getArch()) { default: return getArchName(); - + case llvm::Triple::thumb: case llvm::Triple::arm: { if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) @@ -149,10 +153,10 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const { // the default triple). if (!isTargetInitialized()) return Triple.getTriple(); - + unsigned Version[3]; getTargetVersion(Version); - + llvm::SmallString<16> Str; llvm::raw_svector_ostream(Str) << (isTargetIPhoneOS() ? "ios" : "macosx") @@ -562,7 +566,7 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args, P.appendComponent("lib"); P.appendComponent("darwin"); P.appendComponent("libclang_rt.cc_kext.a"); - + // For now, allow missing resource libraries to support developers who may // not have compiler-rt checked out or integrated into their build. bool Exists; @@ -628,7 +632,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, DAL->AddSeparateArg(OriginalArg, Opts.getOption(options::OPT_Zlinker_input), A->getValue(Args, i)); - + } continue; } @@ -919,8 +923,8 @@ TCEToolChain::~TCEToolChain() { delete it->second; } -bool TCEToolChain::IsMathErrnoDefault() const { - return true; +bool TCEToolChain::IsMathErrnoDefault() const { + return true; } bool TCEToolChain::IsUnwindTablesDefault() const { @@ -935,7 +939,7 @@ const char *TCEToolChain::GetForcedPicModel() const { return 0; } -Tool &TCEToolChain::SelectTool(const Compilation &C, +Tool &TCEToolChain::SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const { Action::ActionClass Key; @@ -1006,7 +1010,12 @@ FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple) llvm::Triple(getDriver().DefaultHostTriple).getArch() == llvm::Triple::x86_64) Lib32 = true; - + + if (Triple.getArch() == llvm::Triple::ppc && + llvm::Triple(getDriver().DefaultHostTriple).getArch() == + llvm::Triple::ppc64) + Lib32 = true; + if (Lib32) { getFilePaths().push_back(CLANG_PREFIX "/usr/lib32"); } else { @@ -1047,14 +1056,14 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA, /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. -NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple) - : Generic_ELF(Host, Triple) { +NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple, + const llvm::Triple& ToolTriple) + : Generic_ELF(Host, Triple), ToolTriple(ToolTriple) { // 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) + if (ToolTriple.getArch() == llvm::Triple::x86_64 && + Triple.getArch() == llvm::Triple::x86) Lib32 = true; if (getDriver().UseStdLib) { @@ -1084,10 +1093,11 @@ Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA, if (UseIntegratedAs) T = new tools::ClangAs(*this); else - T = new tools::netbsd::Assemble(*this); + T = new tools::netbsd::Assemble(*this, ToolTriple); break; case Action::LinkJobClass: - T = new tools::netbsd::Link(*this); break; + T = new tools::netbsd::Link(*this, ToolTriple); + break; default: T = &Generic_GCC::SelectTool(C, JA, Inputs); } @@ -1176,12 +1186,18 @@ enum LinuxDistro { ArchLinux, DebianLenny, DebianSqueeze, + DebianWheezy, Exherbo, + RHEL4, + RHEL5, + RHEL6, Fedora13, Fedora14, Fedora15, FedoraRawhide, OpenSuse11_3, + OpenSuse11_4, + OpenSuse12_1, UbuntuHardy, UbuntuIntrepid, UbuntuJaunty, @@ -1189,27 +1205,31 @@ enum LinuxDistro { UbuntuLucid, UbuntuMaverick, UbuntuNatty, + UbuntuOneiric, UnknownDistro }; -static bool IsFedora(enum LinuxDistro Distro) { +static bool IsRedhat(enum LinuxDistro Distro) { return Distro == Fedora13 || Distro == Fedora14 || - Distro == Fedora15 || Distro == FedoraRawhide; + Distro == Fedora15 || Distro == FedoraRawhide || + Distro == RHEL4 || Distro == RHEL5 || Distro == RHEL6; } static bool IsOpenSuse(enum LinuxDistro Distro) { - return Distro == OpenSuse11_3; + return Distro == OpenSuse11_3 || Distro == OpenSuse11_4 || + Distro == OpenSuse12_1; } static bool IsDebian(enum LinuxDistro Distro) { - return Distro == DebianLenny || Distro == DebianSqueeze; + return Distro == DebianLenny || Distro == DebianSqueeze || + Distro == DebianWheezy; } static bool IsUbuntu(enum LinuxDistro Distro) { return Distro == UbuntuHardy || Distro == UbuntuIntrepid || - Distro == UbuntuLucid || Distro == UbuntuMaverick || + Distro == UbuntuLucid || Distro == UbuntuMaverick || Distro == UbuntuJaunty || Distro == UbuntuKarmic || - Distro == UbuntuNatty; + Distro == UbuntuNatty || Distro == UbuntuOneiric; } static bool IsDebianBased(enum LinuxDistro Distro) { @@ -1227,7 +1247,8 @@ static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) { } if (Arch == llvm::Triple::ppc64) return true; - if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) && IsDebianBased(Distro)) + if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) && + IsDebianBased(Distro)) return true; return false; } @@ -1253,6 +1274,8 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return UbuntuMaverick; else if (Lines[i] == "DISTRIB_CODENAME=natty") return UbuntuNatty; + else if (Lines[i] == "DISTRIB_CODENAME=oneiric") + return UbuntuOneiric; } return UnknownDistro; } @@ -1268,6 +1291,17 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { else if (Data.startswith("Fedora release") && Data.find("Rawhide") != llvm::StringRef::npos) return FedoraRawhide; + else if (Data.startswith("Red Hat Enterprise Linux") && + Data.find("release 6") != llvm::StringRef::npos) + return RHEL6; + else if ((Data.startswith("Red Hat Enterprise Linux") || + Data.startswith("CentOS")) && + Data.find("release 5") != llvm::StringRef::npos) + return RHEL5; + else if ((Data.startswith("Red Hat Enterprise Linux") || + Data.startswith("CentOS")) && + Data.find("release 4") != llvm::StringRef::npos) + return RHEL4; return UnknownDistro; } @@ -1277,6 +1311,8 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return DebianLenny; else if (Data.startswith("squeeze/sid")) return DebianSqueeze; + else if (Data.startswith("wheezy/sid")) + return DebianWheezy; return UnknownDistro; } @@ -1284,6 +1320,10 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { llvm::StringRef Data = File.get()->getBuffer(); if (Data.startswith("openSUSE 11.3")) return OpenSuse11_3; + else if (Data.startswith("openSUSE 11.4")) + return OpenSuse11_4; + else if (Data.startswith("openSUSE 12.1")) + return OpenSuse12_1; return UnknownDistro; } @@ -1297,6 +1337,54 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return UnknownDistro; } +static std::string findGCCBaseLibDir(const std::string &GccTriple) { + // FIXME: Using CXX_INCLUDE_ROOT is here is a bit of a hack, but + // avoids adding yet another option to configure/cmake. + // It would probably be cleaner to break it in two variables + // CXX_GCC_ROOT with just /foo/bar + // CXX_GCC_VER with 4.5.2 + // Then we would have + // CXX_INCLUDE_ROOT = CXX_GCC_ROOT/include/c++/CXX_GCC_VER + // and this function would return + // CXX_GCC_ROOT/lib/gcc/CXX_INCLUDE_ARCH/CXX_GCC_VER + llvm::SmallString<128> CxxIncludeRoot(CXX_INCLUDE_ROOT); + if (CxxIncludeRoot != "") { + // This is of the form /foo/bar/include/c++/4.5.2/ + if (CxxIncludeRoot.back() == '/') + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the / + llvm::StringRef Version = llvm::sys::path::filename(CxxIncludeRoot); + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the version + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the c++ + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the include + std::string ret(CxxIncludeRoot.c_str()); + ret.append("/lib/gcc/"); + ret.append(CXX_INCLUDE_ARCH); + ret.append("/"); + ret.append(Version); + return ret; + } + static const char* GccVersions[] = {"4.6.0", "4.6", + "4.5.2", "4.5.1", "4.5", + "4.4.5", "4.4.4", "4.4.3", "4.4", + "4.3.4", "4.3.3", "4.3.2", "4.3", + "4.2.4", "4.2.3", "4.2.2", "4.2.1", + "4.2", "4.1.1"}; + bool Exists; + for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { + std::string Suffix = GccTriple + "/" + GccVersions[i]; + std::string t1 = "/usr/lib/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) + return t1; + std::string t2 = "/usr/lib64/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) + return t2; + std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) + return t3; + } + return ""; +} + Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) : Generic_ELF(Host, Triple) { llvm::Triple::ArchType Arch = @@ -1370,42 +1458,23 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) } else if (Arch == llvm::Triple::ppc) { if (!llvm::sys::fs::exists("/usr/lib/powerpc-linux-gnu", Exists) && Exists) GccTriple = "powerpc-linux-gnu"; - else if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc-unknown-linux-gnu", Exists) && Exists) + else if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc-unknown-linux-gnu", + Exists) && Exists) GccTriple = "powerpc-unknown-linux-gnu"; } else if (Arch == llvm::Triple::ppc64) { - if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists) + if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc64-unknown-linux-gnu", + Exists) && Exists) GccTriple = "powerpc64-unknown-linux-gnu"; - else if (!llvm::sys::fs::exists("/usr/lib64/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists) + else if (!llvm::sys::fs::exists("/usr/lib64/gcc/" + "powerpc64-unknown-linux-gnu", Exists) && + Exists) GccTriple = "powerpc64-unknown-linux-gnu"; } - const char* GccVersions[] = {"4.6.0", - "4.5.2", "4.5.1", "4.5", - "4.4.5", "4.4.4", "4.4.3", "4.4", - "4.3.4", "4.3.3", "4.3.2", "4.3", - "4.2.4", "4.2.3", "4.2.2", "4.2.1", "4.2"}; - std::string Base = ""; - for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { - std::string Suffix = GccTriple + "/" + GccVersions[i]; - std::string t1 = "/usr/lib/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) { - Base = t1; - break; - } - std::string t2 = "/usr/lib64/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) { - Base = t2; - break; - } - std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) { - Base = t3; - break; - } - } - + std::string Base = findGCCBaseLibDir(GccTriple); path_list &Paths = getFilePaths(); - bool Is32Bits = (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::ppc); + bool Is32Bits = (getArch() == llvm::Triple::x86 || + getArch() == llvm::Triple::ppc); std::string Suffix; std::string Lib; @@ -1426,7 +1495,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) LinuxDistro Distro = DetectLinuxDistro(Arch); - if (IsUbuntu(Distro)) { + if (IsOpenSuse(Distro) || IsUbuntu(Distro)) { ExtraOpts.push_back("-z"); ExtraOpts.push_back("relro"); } @@ -1434,21 +1503,28 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) ExtraOpts.push_back("-X"); - if (IsFedora(Distro) || Distro == UbuntuMaverick || Distro == UbuntuNatty) + if (IsRedhat(Distro) || IsOpenSuse(Distro) || Distro == UbuntuMaverick || + Distro == UbuntuNatty || Distro == UbuntuOneiric) ExtraOpts.push_back("--hash-style=gnu"); - if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty || - Distro == UbuntuKarmic) + if (IsDebian(Distro) || IsOpenSuse(Distro) || Distro == UbuntuLucid || + Distro == UbuntuJaunty || Distro == UbuntuKarmic) ExtraOpts.push_back("--hash-style=both"); - if (IsFedora(Distro)) + if (IsRedhat(Distro)) ExtraOpts.push_back("--no-add-needed"); - if (Distro == DebianSqueeze || IsOpenSuse(Distro) || - IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick || - Distro == UbuntuKarmic || Distro == UbuntuNatty) + if (Distro == DebianSqueeze || Distro == DebianWheezy || + IsOpenSuse(Distro) || + (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || + Distro == UbuntuLucid || + Distro == UbuntuMaverick || Distro == UbuntuKarmic || + Distro == UbuntuNatty || Distro == UbuntuOneiric) ExtraOpts.push_back("--build-id"); + if (IsOpenSuse(Distro)) + ExtraOpts.push_back("--enable-new-dtags"); + if (Distro == ArchLinux) Lib = "lib"; @@ -1457,9 +1533,14 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) if (IsOpenSuse(Distro) && Is32Bits) Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib"); Paths.push_back(Base + "/../../../../" + Lib); - Paths.push_back("/lib/../" + Lib); - Paths.push_back("/usr/lib/../" + Lib); } + + // FIXME: This is in here to find crt1.o. It is provided by libc, and + // libc (like gcc), can be installed in any directory. Once we are + // fetching this from a config file, we should have a libc prefix. + Paths.push_back("/lib/../" + Lib); + Paths.push_back("/usr/lib/../" + Lib); + if (!Suffix.empty()) Paths.push_back(Base); if (IsOpenSuse(Distro)) diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h index 7a1a050..ace9b84 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h @@ -308,8 +308,11 @@ public: }; class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { + const llvm::Triple ToolTriple; + public: - NetBSD(const HostInfo &Host, const llvm::Triple& Triple); + NetBSD(const HostInfo &Host, const llvm::Triple& Triple, + const llvm::Triple& ToolTriple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp index 7b78cd5..b7f0f83 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp @@ -47,8 +47,9 @@ using namespace clang::driver::tools; /// FindTargetProgramPath - Return path of the target specific version of /// ProgName. If it doesn't exist, return path of ProgName itself. static std::string FindTargetProgramPath(const ToolChain &TheToolChain, + const std::string TripleString, const char *ProgName) { - std::string Executable(TheToolChain.getTripleString() + "-" + ProgName); + std::string Executable(TripleString + "-" + ProgName); std::string Path(TheToolChain.GetProgramPath(Executable.c_str())); if (Path != Executable) return Path; @@ -146,6 +147,22 @@ static void AddLinkerInputs(const ToolChain &TC, } } +static void addProfileRT(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_fprofile_arcs) || + Args.hasArg(options::OPT_fprofile_generate) || + Args.hasArg(options::OPT_fcreate_profile) || + Args.hasArg(options::OPT_coverage)) { + // GCC links libgcov.a by adding -L<inst>/gcc/lib/gcc/<triple>/<ver> -lgcov + // to the link line. We cannot do the same thing because unlike gcov + // there is a libprofile_rt.so. We used to use the -l:libprofile_rt.a + // syntax, but that is not supported by old linkers. + const char *lib = Args.MakeArgString(TC.getDriver().Dir + "/../lib/" + + "libprofile_rt.a"); + CmdArgs.push_back(lib); + } +} + void Clang::AddPreprocessingOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, @@ -428,6 +445,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { default: return true; + case llvm::Triple::arm: case llvm::Triple::ppc: case llvm::Triple::ppc64: if (Triple.getOS() == llvm::Triple::Darwin) @@ -652,7 +670,7 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, else if (MArch == "r6000") CmdArgs.push_back("mips2"); else - CmdArgs.push_back(MArch.str().c_str()); + CmdArgs.push_back(Args.MakeArgString(MArch)); } // Select the float ABI as determined by -msoft-float, -mhard-float, and @@ -761,34 +779,34 @@ void Clang::AddX86TargetArgs(const ArgList &Args, if (!CPUName) { // FIXME: Need target hooks. if (getToolChain().getOS().startswith("darwin")) { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "core2"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "yonah"; } else if (getToolChain().getOS().startswith("haiku")) { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "x86-64"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "i586"; } else if (getToolChain().getOS().startswith("openbsd")) { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "x86-64"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "i486"; } else if (getToolChain().getOS().startswith("freebsd")) { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "x86-64"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "i486"; } else if (getToolChain().getOS().startswith("netbsd")) { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "x86-64"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "i486"; } else { - if (getToolChain().getArchName() == "x86_64") + if (getToolChain().getArch() == llvm::Triple::x86_64) CPUName = "x86-64"; - else if (getToolChain().getArchName() == "i386") + else if (getToolChain().getArch() == llvm::Triple::x86) CPUName = "pentium4"; } } @@ -907,21 +925,63 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, static bool ShouldDisableCFI(const ArgList &Args, const ToolChain &TC) { + if (TC.getTriple().getOS() == llvm::Triple::Darwin) { + // The native darwin assembler doesn't support cfi directives, so + // we disable them if we think the .s file will be passed to it. + + // FIXME: Duplicated code with ToolChains.cpp + // FIXME: This doesn't belong here, but ideally we will support static soon + // anyway. + bool HasStatic = (Args.hasArg(options::OPT_mkernel) || + Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_fapple_kext)); + bool IsIADefault = TC.IsIntegratedAssemblerDefault() && !HasStatic; + bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as, + options::OPT_no_integrated_as, + IsIADefault); + bool UseCFI = Args.hasFlag(options::OPT_fdwarf2_cfi_asm, + options::OPT_fno_dwarf2_cfi_asm, + UseIntegratedAs); + return !UseCFI; + } + + // For now we assume that every other assembler support CFI. + return false; +} + +/// \brief Check whether the given input tree contains any compilation actions. +static bool ContainsCompileAction(const Action *A) { + if (isa<CompileJobAction>(A)) + return true; + + for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it) + if (ContainsCompileAction(*it)) + return true; - // FIXME: Duplicated code with ToolChains.cpp - // FIXME: This doesn't belong here, but ideally we will support static soon - // anyway. - bool HasStatic = (Args.hasArg(options::OPT_mkernel) || - Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_fapple_kext)); - bool IsIADefault = TC.IsIntegratedAssemblerDefault() && !HasStatic; - bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as, - options::OPT_no_integrated_as, - IsIADefault); - bool UseCFI = Args.hasFlag(options::OPT_fdwarf2_cfi_asm, - options::OPT_fno_dwarf2_cfi_asm, - UseIntegratedAs); - return !UseCFI; + return false; +} + +/// \brief Check if -relax-all should be passed to the internal assembler. +/// This is done by default when compiling non-assembler source with -O0. +static bool UseRelaxAll(Compilation &C, const ArgList &Args) { + bool RelaxDefault = true; + + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) + RelaxDefault = A->getOption().matches(options::OPT_O0); + + if (RelaxDefault) { + RelaxDefault = false; + for (ActionList::const_iterator it = C.getActions().begin(), + ie = C.getActions().end(); it != ie; ++it) { + if (ContainsCompileAction(*it)) { + RelaxDefault = true; + break; + } + } + } + + return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all, + RelaxDefault); } void Clang::ConstructJob(Compilation &C, const JobAction &JA, @@ -959,13 +1019,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (isa<AssembleJobAction>(JA)) { CmdArgs.push_back("-emit-obj"); - // At -O0, we use -mrelax-all by default. - bool IsOpt = false; - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) - IsOpt = !A->getOption().matches(options::OPT_O0); - if (Args.hasFlag(options::OPT_mrelax_all, - options::OPT_mno_relax_all, - !IsOpt)) + if (UseRelaxAll(C, Args)) CmdArgs.push_back("-mrelax-all"); // When using an integrated assembler, translate -Wa, and -Xassembler @@ -983,6 +1037,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Do nothing, this is the default and we don't support anything else. } else if (Value == "-L") { CmdArgs.push_back("-msave-temp-labels"); + } else if (Value == "--fatal-warnings") { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-fatal-assembler-warnings"); } else { D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; @@ -1303,6 +1360,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasArg(options::OPT_coverage)) CmdArgs.push_back("-femit-coverage-data"); + if (C.getArgs().hasArg(options::OPT_c) || + C.getArgs().hasArg(options::OPT_S)) { + if (Output.isFilename()) { + CmdArgs.push_back("-coverage-file"); + CmdArgs.push_back(Args.MakeArgString(Output.getFilename())); + } + } + Args.AddLastArg(CmdArgs, options::OPT_nostdinc); Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); @@ -1478,6 +1543,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_lax_vector_conversions)) CmdArgs.push_back("-fno-lax-vector-conversions"); + // -fobjc-infer-related-result-type is the default. + if (Args.hasFlag(options::OPT_fobjc_infer_related_result_type, + options::OPT_fno_objc_infer_related_result_type, + /*Default=*/true)) + CmdArgs.push_back("-fobjc-infer-related-result-type"); + // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only // takes precedence. const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only); @@ -1496,7 +1567,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.getLastArg(options::OPT_fapple_kext)) CmdArgs.push_back("-fapple-kext"); - 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); @@ -1547,6 +1617,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel))); } + // Translate -mstackrealign + if (Args.hasArg(options::OPT_mstackrealign)) { + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-force-align-stack"); + } + // Forward -f options with positive and negative forms; we translate // these by hand. @@ -1654,6 +1730,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_gnu_keywords)) A->render(Args, CmdArgs); + if (Args.hasFlag(options::OPT_fgnu89_inline, + options::OPT_fno_gnu89_inline, + false)) + CmdArgs.push_back("-fgnu89-inline"); + // -fnext-runtime defaults to on Darwin and when rewriting Objective-C, and is // -the -cc1 default. bool NeXTRuntimeIsDefault = @@ -1816,6 +1897,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + if (const Arg *A = + Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { + CmdArgs.push_back("-fdiagnostics-format"); + CmdArgs.push_back(A->getValue(Args)); + } + if (Arg *A = Args.getLastArg( options::OPT_fdiagnostics_show_note_include_stack, options::OPT_fno_diagnostics_show_note_include_stack)) { @@ -1837,6 +1924,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_show_source_location)) CmdArgs.push_back("-fno-show-source-location"); + if (!Args.hasFlag(options::OPT_fshow_column, + options::OPT_fno_show_column, + true)) + CmdArgs.push_back("-fno-show-column"); + if (!Args.hasFlag(options::OPT_fspell_checking, options::OPT_fno_spell_checking)) CmdArgs.push_back("-fno-spell-checking"); @@ -2006,13 +2098,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-filetype"); CmdArgs.push_back("obj"); - // At -O0, we use -mrelax-all by default. - bool IsOpt = false; - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) - IsOpt = !A->getOption().matches(options::OPT_O0); - if (Args.hasFlag(options::OPT_mrelax_all, - options::OPT_mno_relax_all, - !IsOpt)) + if (UseRelaxAll(C, Args)) CmdArgs.push_back("-relax-all"); // Ignore explicit -force_cpusubtype_ALL option. @@ -2894,12 +2980,17 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddAllArgs(CmdArgs, options::OPT_sub__library); Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); - Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot"); - if (getDarwinToolChain().isTargetIPhoneOS()) { - if (!Args.hasArg(options::OPT_isysroot)) { - CmdArgs.push_back("-syslibroot"); - CmdArgs.push_back("/Developer/SDKs/Extra"); - } + // Give --sysroot= preference, over the Apple specific behavior to also use + // --isysroot as the syslibroot. + if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) { + CmdArgs.push_back("-syslibroot"); + CmdArgs.push_back(A->getValue(Args)); + } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { + CmdArgs.push_back("-syslibroot"); + CmdArgs.push_back(A->getValue(Args)); + } else if (getDarwinToolChain().isTargetIPhoneOS()) { + CmdArgs.push_back("-syslibroot"); + CmdArgs.push_back("/Developer/SDKs/Extra"); } Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); @@ -3060,12 +3151,6 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(LinkingOutput); } - if (Args.hasArg(options::OPT_fprofile_arcs) || - Args.hasArg(options::OPT_fprofile_generate) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage)) - CmdArgs.push_back("-lgcov"); - if (Args.hasArg(options::OPT_fnested_functions)) CmdArgs.push_back("-allow_stack_execute"); @@ -3086,6 +3171,8 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, // endfile_spec is empty. } + addProfileRT(getToolChain(), Args, CmdArgs); + Args.AddAllArgs(CmdArgs, options::OPT_T_Group); Args.AddAllArgs(CmdArgs, options::OPT_F); @@ -3125,14 +3212,14 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, const char *LinkingOutput) const { ArgStringList CmdArgs; + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); const InputInfo &Input = Inputs[0]; assert(Input.isFilename() && "Unexpected dsymutil input."); CmdArgs.push_back(Input.getFilename()); - CmdArgs.push_back("-o"); - CmdArgs.push_back(Output.getFilename()); - const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); @@ -3243,6 +3330,8 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().GetFilePath("crtend.o"))); } + addProfileRT(getToolChain(), Args, CmdArgs); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); @@ -3378,6 +3467,8 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getArchName() == "i386") CmdArgs.push_back("--32"); + if (getToolChain().getArchName() == "powerpc") + CmdArgs.push_back("-a32"); // Set byte order explicitly if (getToolChain().getArchName() == "mips") @@ -3434,6 +3525,11 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf_i386_fbsd"); } + if (getToolChain().getArchName() == "powerpc") { + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf32ppc"); + } + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -3542,6 +3638,8 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, "crtn.o"))); } + addProfileRT(getToolChain(), Args, CmdArgs); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); @@ -3556,7 +3654,8 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // When building 32-bit code on NetBSD/amd64, we have to explicitly // instruct as in the base system to assemble 32-bit code. - if (getToolChain().getArchName() == "i386") + if (ToolTriple.getArch() == llvm::Triple::x86_64 && + getToolChain().getArch() == llvm::Triple::x86) CmdArgs.push_back("--32"); @@ -3579,7 +3678,8 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), - "as")); + ToolTriple.getTriple(), + "as")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } @@ -3610,7 +3710,8 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, // When building 32-bit code on NetBSD/amd64, we have to explicitly // instruct ld in the base system to link 32-bit code. - if (getToolChain().getArchName() == "i386") { + if (ToolTriple.getArch() == llvm::Triple::x86_64 && + getToolChain().getArch() == llvm::Triple::x86) { CmdArgs.push_back("-m"); CmdArgs.push_back("elf_i386"); } @@ -3657,7 +3758,6 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding // the default system libraries. Just mimic this for now. - CmdArgs.push_back("-lgcc"); if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-lgcc_eh"); } else { @@ -3665,6 +3765,7 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lgcc_s"); CmdArgs.push_back("--no-as-needed"); } + CmdArgs.push_back("-lgcc"); if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); @@ -3692,8 +3793,11 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, "crtn.o"))); } + addProfileRT(getToolChain(), Args, CmdArgs); + const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), - "ld")); + ToolTriple.getTriple(), + "ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } @@ -3855,10 +3959,10 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lm"); } - if (Args.hasArg(options::OPT_static)) - CmdArgs.push_back("--start-group"); - if (!Args.hasArg(options::OPT_nostdlib)) { + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("--start-group"); + if (!D.CCCIsCXX) CmdArgs.push_back("-lgcc"); @@ -3913,6 +4017,8 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, } } + addProfileRT(getToolChain(), Args, CmdArgs); + if (Args.hasArg(options::OPT_use_gold_plugin)) { CmdArgs.push_back("-plugin"); std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; @@ -3995,6 +4101,8 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, "/usr/gnu/lib/libend.a"))); } + addProfileRT(getToolChain(), Args, CmdArgs); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("/usr/gnu/bin/gld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); @@ -4150,6 +4258,8 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().GetFilePath("crtn.o"))); } + addProfileRT(getToolChain(), Args, CmdArgs); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); 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 93abf75..4a5a7e4 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.h +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h @@ -14,6 +14,7 @@ #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -338,9 +339,12 @@ namespace freebsd { /// netbsd -- Directly call GNU Binutils assembler and linker namespace netbsd { class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { + private: + const llvm::Triple ToolTriple; + public: - Assemble(const ToolChain &TC) : Tool("netbsd::Assemble", "assembler", - TC) {} + Assemble(const ToolChain &TC, const llvm::Triple &ToolTriple) + : Tool("netbsd::Assemble", "assembler", TC), ToolTriple(ToolTriple) {} virtual bool hasIntegratedCPP() const { return false; } @@ -351,8 +355,12 @@ namespace netbsd { const char *LinkingOutput) const; }; class LLVM_LIBRARY_VISIBILITY Link : public Tool { + private: + const llvm::Triple ToolTriple; + public: - Link(const ToolChain &TC) : Tool("netbsd::Link", "linker", TC) {} + Link(const ToolChain &TC, const llvm::Triple &ToolTriple) + : Tool("netbsd::Ling", "linker", TC), ToolTriple(ToolTriple) {} virtual bool hasIntegratedCPP() const { return false; } |