Index: cfe/trunk/include/clang/Driver/Driver.h =================================================================== --- cfe/trunk/include/clang/Driver/Driver.h +++ cfe/trunk/include/clang/Driver/Driver.h @@ -405,12 +405,12 @@ bool IsUsingLTO(const llvm::opt::ArgList &Args) const; private: - /// \brief Retrieves a ToolChain for a particular target triple. + /// \brief Retrieves a ToolChain for a particular \p Target triple. /// /// Will cache ToolChains for the life of the driver object, and create them /// on-demand. const ToolChain &getToolChain(const llvm::opt::ArgList &Args, - StringRef DarwinArchName = "") const; + const llvm::Triple &Target) const; /// @} Index: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -281,6 +281,83 @@ return DAL; } +/// \brief Compute target triple from args. +/// +/// This routine provides the logic to compute a target triple from various +/// args passed to the driver and the default triple string. +static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, + const ArgList &Args, + StringRef DarwinArchName = "") { + // FIXME: Already done in Compilation *Driver::BuildCompilation + if (const Arg *A = Args.getLastArg(options::OPT_target)) + DefaultTargetTriple = A->getValue(); + + llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple)); + + // Handle Apple-specific options available here. + if (Target.isOSBinFormatMachO()) { + // If an explict Darwin arch name is given, that trumps all. + if (!DarwinArchName.empty()) { + tools::darwin::setTripleTypeForMachOArchName(Target, DarwinArchName); + return Target; + } + + // Handle the Darwin '-arch' flag. + if (Arg *A = Args.getLastArg(options::OPT_arch)) { + StringRef ArchName = A->getValue(); + tools::darwin::setTripleTypeForMachOArchName(Target, ArchName); + } + } + + // Handle pseudo-target flags '-mlittle-endian'/'-EL' and + // '-mbig-endian'/'-EB'. + if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, + options::OPT_mbig_endian)) { + if (A->getOption().matches(options::OPT_mlittle_endian)) { + llvm::Triple LE = Target.getLittleEndianArchVariant(); + if (LE.getArch() != llvm::Triple::UnknownArch) + Target = std::move(LE); + } else { + llvm::Triple BE = Target.getBigEndianArchVariant(); + if (BE.getArch() != llvm::Triple::UnknownArch) + Target = std::move(BE); + } + } + + // Skip further flag support on OSes which don't support '-m32' or '-m64'. + if (Target.getArchName() == "tce" || Target.getOS() == llvm::Triple::Minix) + return Target; + + // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'. + if (Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32, + options::OPT_m32, options::OPT_m16)) { + llvm::Triple::ArchType AT = llvm::Triple::UnknownArch; + + if (A->getOption().matches(options::OPT_m64)) { + AT = Target.get64BitArchVariant().getArch(); + if (Target.getEnvironment() == llvm::Triple::GNUX32) + Target.setEnvironment(llvm::Triple::GNU); + } else if (A->getOption().matches(options::OPT_mx32) && + Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { + AT = llvm::Triple::x86_64; + Target.setEnvironment(llvm::Triple::GNUX32); + } else if (A->getOption().matches(options::OPT_m32)) { + AT = Target.get32BitArchVariant().getArch(); + if (Target.getEnvironment() == llvm::Triple::GNUX32) + Target.setEnvironment(llvm::Triple::GNU); + } else if (A->getOption().matches(options::OPT_m16) && + Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { + AT = llvm::Triple::x86; + Target.setEnvironment(llvm::Triple::CODE16); + } + + if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) + Target.setArch(AT); + } + + return Target; +} + Compilation *Driver::BuildCompilation(ArrayRef ArgList) { llvm::PrettyStackTraceString CrashInfo("Compilation construction"); @@ -367,7 +444,8 @@ DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs); // Owned by the host. - const ToolChain &TC = getToolChain(*UArgs); + const ToolChain &TC = + getToolChain(*UArgs, computeTargetTriple(DefaultTargetTriple, *UArgs)); // The compilation takes ownership of Args. Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs); @@ -1551,7 +1629,9 @@ const char *ArchName = BAA->getArchName(); if (ArchName) - TC = &getToolChain(C.getArgs(), ArchName); + TC = &getToolChain( + C.getArgs(), + computeTargetTriple(DefaultTargetTriple, C.getArgs(), ArchName)); else TC = &C.getDefaultToolChain(); @@ -1906,87 +1986,8 @@ return Path.str(); } -/// \brief Compute target triple from args. -/// -/// This routine provides the logic to compute a target triple from various -/// args passed to the driver and the default triple string. -static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, - const ArgList &Args, - StringRef DarwinArchName) { - // FIXME: Already done in Compilation *Driver::BuildCompilation - if (const Arg *A = Args.getLastArg(options::OPT_target)) - DefaultTargetTriple = A->getValue(); - - llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple)); - - // Handle Apple-specific options available here. - if (Target.isOSBinFormatMachO()) { - // If an explict Darwin arch name is given, that trumps all. - if (!DarwinArchName.empty()) { - tools::darwin::setTripleTypeForMachOArchName(Target, DarwinArchName); - return Target; - } - - // Handle the Darwin '-arch' flag. - if (Arg *A = Args.getLastArg(options::OPT_arch)) { - StringRef ArchName = A->getValue(); - tools::darwin::setTripleTypeForMachOArchName(Target, ArchName); - } - } - - // Handle pseudo-target flags '-mlittle-endian'/'-EL' and - // '-mbig-endian'/'-EB'. - if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, - options::OPT_mbig_endian)) { - if (A->getOption().matches(options::OPT_mlittle_endian)) { - llvm::Triple LE = Target.getLittleEndianArchVariant(); - if (LE.getArch() != llvm::Triple::UnknownArch) - Target = std::move(LE); - } else { - llvm::Triple BE = Target.getBigEndianArchVariant(); - if (BE.getArch() != llvm::Triple::UnknownArch) - Target = std::move(BE); - } - } - - // Skip further flag support on OSes which don't support '-m32' or '-m64'. - if (Target.getArchName() == "tce" || Target.getOS() == llvm::Triple::Minix) - return Target; - - // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'. - if (Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32, - options::OPT_m32, options::OPT_m16)) { - llvm::Triple::ArchType AT = llvm::Triple::UnknownArch; - - if (A->getOption().matches(options::OPT_m64)) { - AT = Target.get64BitArchVariant().getArch(); - if (Target.getEnvironment() == llvm::Triple::GNUX32) - Target.setEnvironment(llvm::Triple::GNU); - } else if (A->getOption().matches(options::OPT_mx32) && - Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { - AT = llvm::Triple::x86_64; - Target.setEnvironment(llvm::Triple::GNUX32); - } else if (A->getOption().matches(options::OPT_m32)) { - AT = Target.get32BitArchVariant().getArch(); - if (Target.getEnvironment() == llvm::Triple::GNUX32) - Target.setEnvironment(llvm::Triple::GNU); - } else if (A->getOption().matches(options::OPT_m16) && - Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { - AT = llvm::Triple::x86; - Target.setEnvironment(llvm::Triple::CODE16); - } - - if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) - Target.setArch(AT); - } - - return Target; -} - const ToolChain &Driver::getToolChain(const ArgList &Args, - StringRef DarwinArchName) const { - llvm::Triple Target = - computeTargetTriple(DefaultTargetTriple, Args, DarwinArchName); + const llvm::Triple &Target) const { ToolChain *&TC = ToolChains[Target.str()]; if (!TC) {