ToolChains.cpp revision 198398
1193326Sed//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed 10193326Sed#include "ToolChains.h" 11193326Sed 12193326Sed#include "clang/Driver/Arg.h" 13193326Sed#include "clang/Driver/ArgList.h" 14193326Sed#include "clang/Driver/Driver.h" 15193326Sed#include "clang/Driver/DriverDiagnostic.h" 16193326Sed#include "clang/Driver/HostInfo.h" 17193326Sed#include "clang/Driver/Option.h" 18193326Sed 19193326Sed#include "llvm/ADT/StringExtras.h" 20198092Srdivacky#include "llvm/Support/ErrorHandling.h" 21193326Sed#include "llvm/Support/raw_ostream.h" 22193326Sed#include "llvm/System/Path.h" 23193326Sed 24193326Sed#include <cstdlib> // ::getenv 25193326Sed 26193326Sedusing namespace clang::driver; 27193326Sedusing namespace clang::driver::toolchains; 28193326Sed 29198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 30193326Sed 31198092SrdivackyDarwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple, 32198092Srdivacky const unsigned (&_DarwinVersion)[3], bool _IsIPhoneOS) 33198092Srdivacky : ToolChain(Host, Triple), 34198092Srdivacky IsIPhoneOS(_IsIPhoneOS) 35198092Srdivacky{ 36193326Sed DarwinVersion[0] = _DarwinVersion[0]; 37193326Sed DarwinVersion[1] = _DarwinVersion[1]; 38193326Sed DarwinVersion[2] = _DarwinVersion[2]; 39198092Srdivacky 40198092Srdivacky llvm::raw_string_ostream(MacosxVersionMin) 41198398Srdivacky << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.' 42198398Srdivacky << DarwinVersion[1]; 43198092Srdivacky 44198092Srdivacky // FIXME: Lift default up. 45198092Srdivacky IPhoneOSVersionMin = "3.0"; 46198092Srdivacky} 47198092Srdivacky 48198092SrdivackyDarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, 49198092Srdivacky const unsigned (&DarwinVersion)[3], 50198092Srdivacky const unsigned (&_GCCVersion)[3], bool IsIPhoneOS) 51198092Srdivacky : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) 52198092Srdivacky{ 53193326Sed GCCVersion[0] = _GCCVersion[0]; 54193326Sed GCCVersion[1] = _GCCVersion[1]; 55193326Sed GCCVersion[2] = _GCCVersion[2]; 56193326Sed 57198092Srdivacky // Set up the tool chain paths to match gcc. 58193326Sed ToolChainDir = "i686-apple-darwin"; 59193326Sed ToolChainDir += llvm::utostr(DarwinVersion[0]); 60193326Sed ToolChainDir += "/"; 61193326Sed ToolChainDir += llvm::utostr(GCCVersion[0]); 62193326Sed ToolChainDir += '.'; 63193326Sed ToolChainDir += llvm::utostr(GCCVersion[1]); 64193326Sed ToolChainDir += '.'; 65193326Sed ToolChainDir += llvm::utostr(GCCVersion[2]); 66193326Sed 67198398Srdivacky // Try the next major version if that tool chain dir is invalid. 68198398Srdivacky std::string Tmp = "/usr/lib/gcc/" + ToolChainDir; 69198398Srdivacky if (!llvm::sys::Path(Tmp).exists()) { 70198398Srdivacky std::string Next = "i686-apple-darwin"; 71198398Srdivacky Next += llvm::utostr(DarwinVersion[0] + 1); 72198398Srdivacky Next += "/"; 73198398Srdivacky Next += llvm::utostr(GCCVersion[0]); 74198398Srdivacky Next += '.'; 75198398Srdivacky Next += llvm::utostr(GCCVersion[1]); 76198398Srdivacky Next += '.'; 77198398Srdivacky Next += llvm::utostr(GCCVersion[2]); 78198398Srdivacky 79198398Srdivacky // Use that if it exists, otherwise hope the user isn't linking. 80198398Srdivacky // 81198398Srdivacky // FIXME: Drop dependency on gcc's tool chain. 82198398Srdivacky Tmp = "/usr/lib/gcc/" + Next; 83198398Srdivacky if (llvm::sys::Path(Tmp).exists()) 84198398Srdivacky ToolChainDir = Next; 85198398Srdivacky } 86198398Srdivacky 87193326Sed std::string Path; 88193326Sed if (getArchName() == "x86_64") { 89193326Sed Path = getHost().getDriver().Dir; 90193326Sed Path += "/../lib/gcc/"; 91198092Srdivacky Path += ToolChainDir; 92193326Sed Path += "/x86_64"; 93193326Sed getFilePaths().push_back(Path); 94193326Sed 95193326Sed Path = "/usr/lib/gcc/"; 96198092Srdivacky Path += ToolChainDir; 97193326Sed Path += "/x86_64"; 98193326Sed getFilePaths().push_back(Path); 99193326Sed } 100198092Srdivacky 101193326Sed Path = getHost().getDriver().Dir; 102193326Sed Path += "/../lib/gcc/"; 103198092Srdivacky Path += ToolChainDir; 104193326Sed getFilePaths().push_back(Path); 105193326Sed 106193326Sed Path = "/usr/lib/gcc/"; 107198092Srdivacky Path += ToolChainDir; 108193326Sed getFilePaths().push_back(Path); 109193326Sed 110193326Sed Path = getHost().getDriver().Dir; 111193326Sed Path += "/../libexec/gcc/"; 112198092Srdivacky Path += ToolChainDir; 113193326Sed getProgramPaths().push_back(Path); 114193326Sed 115193326Sed Path = "/usr/libexec/gcc/"; 116198092Srdivacky Path += ToolChainDir; 117193326Sed getProgramPaths().push_back(Path); 118193326Sed 119193326Sed Path = getHost().getDriver().Dir; 120193326Sed Path += "/../libexec"; 121193326Sed getProgramPaths().push_back(Path); 122193326Sed 123193326Sed getProgramPaths().push_back(getHost().getDriver().Dir); 124193326Sed} 125193326Sed 126198092SrdivackyDarwin::~Darwin() { 127193326Sed // Free tool implementations. 128193326Sed for (llvm::DenseMap<unsigned, Tool*>::iterator 129193326Sed it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 130193326Sed delete it->second; 131193326Sed} 132193326Sed 133198092SrdivackyTool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { 134193326Sed Action::ActionClass Key; 135198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 136193326Sed Key = Action::AnalyzeJobClass; 137193326Sed else 138193326Sed Key = JA.getKind(); 139193326Sed 140193326Sed Tool *&T = Tools[Key]; 141193326Sed if (!T) { 142193326Sed switch (Key) { 143193326Sed case Action::InputClass: 144193326Sed case Action::BindArchClass: 145193326Sed assert(0 && "Invalid tool kind."); 146193326Sed case Action::PreprocessJobClass: 147193326Sed T = new tools::darwin::Preprocess(*this); break; 148193326Sed case Action::AnalyzeJobClass: 149193326Sed T = new tools::Clang(*this); break; 150193326Sed case Action::PrecompileJobClass: 151193326Sed case Action::CompileJobClass: 152193326Sed T = new tools::darwin::Compile(*this); break; 153193326Sed case Action::AssembleJobClass: 154193326Sed T = new tools::darwin::Assemble(*this); break; 155193326Sed case Action::LinkJobClass: 156198092Srdivacky T = new tools::darwin::Link(*this); break; 157193326Sed case Action::LipoJobClass: 158193326Sed T = new tools::darwin::Lipo(*this); break; 159193326Sed } 160193326Sed } 161193326Sed 162193326Sed return *T; 163193326Sed} 164193326Sed 165198092Srdivackyvoid DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args, 166198092Srdivacky ArgStringList &CmdArgs) const { 167198092Srdivacky // FIXME: Derive these correctly. 168198092Srdivacky if (getArchName() == "x86_64") { 169198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 170198092Srdivacky "/x86_64")); 171198092Srdivacky // Intentionally duplicated for (temporary) gcc bug compatibility. 172198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 173198092Srdivacky "/x86_64")); 174198092Srdivacky } 175198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir)); 176198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 177198092Srdivacky // Intentionally duplicated for (temporary) gcc bug compatibility. 178198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 179198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 180198092Srdivacky "/../../../" + ToolChainDir)); 181198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 182198092Srdivacky "/../../..")); 183198092Srdivacky} 184198092Srdivacky 185198092Srdivackyvoid DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, 186198092Srdivacky ArgStringList &CmdArgs) const { 187198092Srdivacky unsigned MacosxVersionMin[3]; 188198092Srdivacky getMacosxVersionMin(Args, MacosxVersionMin); 189198092Srdivacky 190198092Srdivacky // Derived from libgcc and lib specs but refactored. 191198092Srdivacky if (Args.hasArg(options::OPT_static)) { 192198092Srdivacky CmdArgs.push_back("-lgcc_static"); 193198092Srdivacky } else { 194198092Srdivacky if (Args.hasArg(options::OPT_static_libgcc)) { 195198092Srdivacky CmdArgs.push_back("-lgcc_eh"); 196198092Srdivacky } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { 197198092Srdivacky // Derived from darwin_iphoneos_libgcc spec. 198198092Srdivacky if (isIPhoneOS()) { 199198092Srdivacky CmdArgs.push_back("-lgcc_s.1"); 200198092Srdivacky } else { 201198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 202198092Srdivacky } 203198092Srdivacky } else if (Args.hasArg(options::OPT_shared_libgcc) || 204198092Srdivacky // FIXME: -fexceptions -fno-exceptions means no exceptions 205198092Srdivacky Args.hasArg(options::OPT_fexceptions) || 206198092Srdivacky Args.hasArg(options::OPT_fgnu_runtime)) { 207198092Srdivacky // FIXME: This is probably broken on 10.3? 208198092Srdivacky if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) 209198092Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 210198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 6)) 211198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 212198092Srdivacky } else { 213198092Srdivacky if (isMacosxVersionLT(MacosxVersionMin, 10, 3, 9)) 214198092Srdivacky ; // Do nothing. 215198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) 216198092Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 217198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 6)) 218198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 219198092Srdivacky } 220198092Srdivacky 221198092Srdivacky if (isIPhoneOS() || isMacosxVersionLT(MacosxVersionMin, 10, 6)) { 222198092Srdivacky CmdArgs.push_back("-lgcc"); 223198092Srdivacky CmdArgs.push_back("-lSystem"); 224198092Srdivacky } else { 225198092Srdivacky CmdArgs.push_back("-lSystem"); 226198092Srdivacky CmdArgs.push_back("-lgcc"); 227198092Srdivacky } 228198092Srdivacky } 229198092Srdivacky} 230198092Srdivacky 231198092SrdivackyDarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, 232198092Srdivacky const unsigned (&DarwinVersion)[3], 233198092Srdivacky bool IsIPhoneOS) 234198092Srdivacky : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) 235198092Srdivacky{ 236198092Srdivacky // Add the relative libexec dir (for clang-cc). 237198092Srdivacky // 238198092Srdivacky // FIXME: We should sink clang-cc into libexec/clang/<version>/. 239198092Srdivacky std::string Path = getHost().getDriver().Dir; 240198092Srdivacky Path += "/../libexec"; 241198092Srdivacky getProgramPaths().push_back(Path); 242198092Srdivacky 243198092Srdivacky // We expect 'as', 'ld', etc. to be adjacent to our install dir. 244198092Srdivacky getProgramPaths().push_back(getHost().getDriver().Dir); 245198092Srdivacky} 246198092Srdivacky 247198092Srdivackyvoid DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, 248198092Srdivacky ArgStringList &CmdArgs) const { 249198092Srdivacky // The Clang toolchain uses explicit paths for internal libraries. 250198092Srdivacky} 251198092Srdivacky 252198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 253198092Srdivacky ArgStringList &CmdArgs) const { 254198092Srdivacky // Check for static linking. 255198092Srdivacky if (Args.hasArg(options::OPT_static)) { 256198092Srdivacky // FIXME: We need to have compiler-rt available (perhaps as 257198092Srdivacky // libclang_static.a) to link against. 258198092Srdivacky return; 259198092Srdivacky } 260198092Srdivacky 261198092Srdivacky // Reject -static-libgcc for now, we can deal with this when and if someone 262198092Srdivacky // cares. This is useful in situations where someone wants to statically link 263198092Srdivacky // something like libstdc++, and needs its runtime support routines. 264198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 265198092Srdivacky getHost().getDriver().Diag(clang::diag::err_drv_unsupported_opt) 266198092Srdivacky << A->getAsString(Args); 267198092Srdivacky return; 268198092Srdivacky } 269198092Srdivacky 270198092Srdivacky // Otherwise link libSystem, which should have the support routines. 271198092Srdivacky // 272198092Srdivacky // FIXME: This is only true for 10.6 and beyond. Legacy support isn't 273198092Srdivacky // critical, but it should work... we should just link in the static 274198092Srdivacky // compiler-rt library. 275198092Srdivacky CmdArgs.push_back("-lSystem"); 276198092Srdivacky} 277198092Srdivacky 278198092Srdivackyvoid Darwin::getMacosxVersionMin(const ArgList &Args, 279198092Srdivacky unsigned (&Res)[3]) const { 280198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) { 281198092Srdivacky bool HadExtra; 282198092Srdivacky if (!Driver::GetReleaseVersion(A->getValue(Args), Res[0], Res[1], Res[2], 283198092Srdivacky HadExtra) || 284198092Srdivacky HadExtra) { 285198092Srdivacky const Driver &D = getHost().getDriver(); 286198092Srdivacky D.Diag(clang::diag::err_drv_invalid_version_number) 287198092Srdivacky << A->getAsString(Args); 288198092Srdivacky } 289198092Srdivacky } else 290198092Srdivacky return getMacosxVersion(Res); 291198092Srdivacky} 292198092Srdivacky 293198092SrdivackyDerivedArgList *Darwin::TranslateArgs(InputArgList &Args, 294198092Srdivacky const char *BoundArch) const { 295193326Sed DerivedArgList *DAL = new DerivedArgList(Args, false); 296193326Sed const OptTable &Opts = getHost().getDriver().getOpts(); 297193326Sed 298193326Sed // FIXME: We really want to get out of the tool chain level argument 299193326Sed // translation business, as it makes the driver functionality much 300193326Sed // more opaque. For now, we follow gcc closely solely for the 301193326Sed // purpose of easily achieving feature parity & testability. Once we 302193326Sed // have something that works, we should reevaluate each translation 303198092Srdivacky // and try to push it down into tool specific logic. 304193326Sed 305198092Srdivacky Arg *OSXVersion = 306193326Sed Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false); 307193326Sed Arg *iPhoneVersion = 308198092Srdivacky Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false); 309193326Sed if (OSXVersion && iPhoneVersion) { 310193326Sed getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with) 311193326Sed << OSXVersion->getAsString(Args) 312198092Srdivacky << iPhoneVersion->getAsString(Args); 313193326Sed } else if (!OSXVersion && !iPhoneVersion) { 314193326Sed // Chose the default version based on the arch. 315193326Sed // 316198092Srdivacky // FIXME: Are there iPhone overrides for this? 317193326Sed 318198092Srdivacky if (!isIPhoneOS()) { 319198092Srdivacky // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version 320198092Srdivacky // from the host. 321198092Srdivacky const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET"); 322198092Srdivacky if (!Version) 323198092Srdivacky Version = MacosxVersionMin.c_str(); 324198092Srdivacky const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 325198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, O, Version)); 326198092Srdivacky } else { 327198092Srdivacky const char *Version = IPhoneOSVersionMin.c_str(); 328198092Srdivacky const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 329198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, O, Version)); 330198092Srdivacky } 331193326Sed } 332198092Srdivacky 333193326Sed for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { 334193326Sed Arg *A = *it; 335193326Sed 336193326Sed if (A->getOption().matches(options::OPT_Xarch__)) { 337193326Sed // FIXME: Canonicalize name. 338193326Sed if (getArchName() != A->getValue(Args, 0)) 339193326Sed continue; 340193326Sed 341193326Sed // FIXME: The arg is leaked here, and we should have a nicer 342193326Sed // interface for this. 343193326Sed unsigned Prev, Index = Prev = A->getIndex() + 1; 344193326Sed Arg *XarchArg = Opts.ParseOneArg(Args, Index); 345198092Srdivacky 346193326Sed // If the argument parsing failed or more than one argument was 347193326Sed // consumed, the -Xarch_ argument's parameter tried to consume 348193326Sed // extra arguments. Emit an error and ignore. 349193326Sed // 350193326Sed // We also want to disallow any options which would alter the 351193326Sed // driver behavior; that isn't going to work in our model. We 352193326Sed // use isDriverOption() as an approximation, although things 353193326Sed // like -O4 are going to slip through. 354198092Srdivacky if (!XarchArg || Index > Prev + 1 || 355193326Sed XarchArg->getOption().isDriverOption()) { 356193326Sed getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument) 357193326Sed << A->getAsString(Args); 358193326Sed continue; 359193326Sed } 360193326Sed 361193326Sed XarchArg->setBaseArg(A); 362193326Sed A = XarchArg; 363198092Srdivacky } 364193326Sed 365193326Sed // Sob. These is strictly gcc compatible for the time being. Apple 366193326Sed // gcc translates options twice, which means that self-expanding 367193326Sed // options add duplicates. 368193326Sed options::ID id = A->getOption().getId(); 369193326Sed switch (id) { 370193326Sed default: 371193326Sed DAL->append(A); 372193326Sed break; 373193326Sed 374193326Sed case options::OPT_mkernel: 375193326Sed case options::OPT_fapple_kext: 376193326Sed DAL->append(A); 377193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 378193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 379193326Sed break; 380198092Srdivacky 381193326Sed case options::OPT_dependency_file: 382193326Sed DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF), 383193326Sed A->getValue(Args))); 384193326Sed break; 385193326Sed 386193326Sed case options::OPT_gfull: 387193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 388193326Sed DAL->append(DAL->MakeFlagArg(A, 389193326Sed Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols))); 390193326Sed break; 391193326Sed 392193326Sed case options::OPT_gused: 393193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 394193326Sed DAL->append(DAL->MakeFlagArg(A, 395193326Sed Opts.getOption(options::OPT_feliminate_unused_debug_symbols))); 396193326Sed break; 397193326Sed 398193326Sed case options::OPT_fterminated_vtables: 399193326Sed case options::OPT_findirect_virtual_calls: 400193326Sed DAL->append(DAL->MakeFlagArg(A, 401193326Sed Opts.getOption(options::OPT_fapple_kext))); 402193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 403193326Sed break; 404193326Sed 405193326Sed case options::OPT_shared: 406193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib))); 407193326Sed break; 408193326Sed 409193326Sed case options::OPT_fconstant_cfstrings: 410193326Sed DAL->append(DAL->MakeFlagArg(A, 411193326Sed Opts.getOption(options::OPT_mconstant_cfstrings))); 412193326Sed break; 413193326Sed 414193326Sed case options::OPT_fno_constant_cfstrings: 415193326Sed DAL->append(DAL->MakeFlagArg(A, 416193326Sed Opts.getOption(options::OPT_mno_constant_cfstrings))); 417193326Sed break; 418193326Sed 419193326Sed case options::OPT_Wnonportable_cfstrings: 420193326Sed DAL->append(DAL->MakeFlagArg(A, 421193326Sed Opts.getOption(options::OPT_mwarn_nonportable_cfstrings))); 422193326Sed break; 423193326Sed 424193326Sed case options::OPT_Wno_nonportable_cfstrings: 425193326Sed DAL->append(DAL->MakeFlagArg(A, 426193326Sed Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings))); 427193326Sed break; 428193326Sed 429193326Sed case options::OPT_fpascal_strings: 430193326Sed DAL->append(DAL->MakeFlagArg(A, 431193326Sed Opts.getOption(options::OPT_mpascal_strings))); 432193326Sed break; 433193326Sed 434193326Sed case options::OPT_fno_pascal_strings: 435193326Sed DAL->append(DAL->MakeFlagArg(A, 436193326Sed Opts.getOption(options::OPT_mno_pascal_strings))); 437193326Sed break; 438193326Sed } 439193326Sed } 440193326Sed 441198092Srdivacky if (getTriple().getArch() == llvm::Triple::x86 || 442198092Srdivacky getTriple().getArch() == llvm::Triple::x86_64) 443198092Srdivacky if (!Args.hasArg(options::OPT_mtune_EQ, false)) 444198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), 445198092Srdivacky "core2")); 446198092Srdivacky 447198092Srdivacky // Add the arch options based on the particular spelling of -arch, to match 448198092Srdivacky // how the driver driver works. 449198092Srdivacky if (BoundArch) { 450198092Srdivacky llvm::StringRef Name = BoundArch; 451198092Srdivacky const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ); 452198092Srdivacky const Option *MArch = Opts.getOption(options::OPT_march_EQ); 453198092Srdivacky 454198092Srdivacky // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 455198092Srdivacky // which defines the list of which architectures we accept. 456198092Srdivacky if (Name == "ppc") 457198092Srdivacky ; 458198092Srdivacky else if (Name == "ppc601") 459198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "601")); 460198092Srdivacky else if (Name == "ppc603") 461198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "603")); 462198092Srdivacky else if (Name == "ppc604") 463198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "604")); 464198092Srdivacky else if (Name == "ppc604e") 465198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e")); 466198092Srdivacky else if (Name == "ppc750") 467198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "750")); 468198092Srdivacky else if (Name == "ppc7400") 469198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400")); 470198092Srdivacky else if (Name == "ppc7450") 471198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450")); 472198092Srdivacky else if (Name == "ppc970") 473198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "970")); 474198092Srdivacky 475198092Srdivacky else if (Name == "ppc64") 476193326Sed DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 477193326Sed 478198092Srdivacky else if (Name == "i386") 479198092Srdivacky ; 480198092Srdivacky else if (Name == "i486") 481198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i486")); 482198092Srdivacky else if (Name == "i586") 483198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i586")); 484198092Srdivacky else if (Name == "i686") 485198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i686")); 486198092Srdivacky else if (Name == "pentium") 487198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium")); 488198092Srdivacky else if (Name == "pentium2") 489198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2")); 490198092Srdivacky else if (Name == "pentpro") 491198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro")); 492198092Srdivacky else if (Name == "pentIIm3") 493198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2")); 494193326Sed 495198092Srdivacky else if (Name == "x86_64") 496198092Srdivacky DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 497198092Srdivacky 498198092Srdivacky else if (Name == "arm") 499198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t")); 500198092Srdivacky else if (Name == "armv4t") 501198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t")); 502198092Srdivacky else if (Name == "armv5") 503198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej")); 504198092Srdivacky else if (Name == "xscale") 505198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale")); 506198092Srdivacky else if (Name == "armv6") 507198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k")); 508198092Srdivacky else if (Name == "armv7") 509198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a")); 510198092Srdivacky 511198092Srdivacky else 512198092Srdivacky llvm::llvm_unreachable("invalid Darwin arch"); 513198092Srdivacky } 514198092Srdivacky 515193326Sed return DAL; 516198092Srdivacky} 517193326Sed 518198092Srdivackybool Darwin::IsMathErrnoDefault() const { 519198092Srdivacky return false; 520193326Sed} 521193326Sed 522198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 523193326Sed // FIXME: Gross; we should probably have some separate target 524193326Sed // definition, possibly even reusing the one in clang. 525193326Sed return getArchName() == "x86_64"; 526193326Sed} 527193326Sed 528198092Srdivackyconst char *Darwin::GetDefaultRelocationModel() const { 529193326Sed return "pic"; 530193326Sed} 531193326Sed 532198092Srdivackyconst char *Darwin::GetForcedPicModel() const { 533193326Sed if (getArchName() == "x86_64") 534193326Sed return "pic"; 535193326Sed return 0; 536193326Sed} 537193326Sed 538193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform 539193326Sed/// all subcommands; this relies on gcc translating the majority of 540193326Sed/// command line options. 541193326Sed 542193326SedGeneric_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) 543198092Srdivacky : ToolChain(Host, Triple) { 544193326Sed std::string Path(getHost().getDriver().Dir); 545193326Sed Path += "/../libexec"; 546193326Sed getProgramPaths().push_back(Path); 547193326Sed 548198092Srdivacky getProgramPaths().push_back(getHost().getDriver().Dir); 549193326Sed} 550193326Sed 551193326SedGeneric_GCC::~Generic_GCC() { 552193326Sed // Free tool implementations. 553193326Sed for (llvm::DenseMap<unsigned, Tool*>::iterator 554193326Sed it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 555193326Sed delete it->second; 556193326Sed} 557193326Sed 558198092SrdivackyTool &Generic_GCC::SelectTool(const Compilation &C, 559193326Sed const JobAction &JA) const { 560193326Sed Action::ActionClass Key; 561198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 562193326Sed Key = Action::AnalyzeJobClass; 563193326Sed else 564193326Sed Key = JA.getKind(); 565193326Sed 566193326Sed Tool *&T = Tools[Key]; 567193326Sed if (!T) { 568193326Sed switch (Key) { 569193326Sed case Action::InputClass: 570193326Sed case Action::BindArchClass: 571193326Sed assert(0 && "Invalid tool kind."); 572193326Sed case Action::PreprocessJobClass: 573193326Sed T = new tools::gcc::Preprocess(*this); break; 574193326Sed case Action::PrecompileJobClass: 575193326Sed T = new tools::gcc::Precompile(*this); break; 576193326Sed case Action::AnalyzeJobClass: 577193326Sed T = new tools::Clang(*this); break; 578193326Sed case Action::CompileJobClass: 579193326Sed T = new tools::gcc::Compile(*this); break; 580193326Sed case Action::AssembleJobClass: 581193326Sed T = new tools::gcc::Assemble(*this); break; 582193326Sed case Action::LinkJobClass: 583193326Sed T = new tools::gcc::Link(*this); break; 584198092Srdivacky 585193326Sed // This is a bit ungeneric, but the only platform using a driver 586193326Sed // driver is Darwin. 587193326Sed case Action::LipoJobClass: 588193326Sed T = new tools::darwin::Lipo(*this); break; 589193326Sed } 590193326Sed } 591193326Sed 592193326Sed return *T; 593193326Sed} 594193326Sed 595198092Srdivackybool Generic_GCC::IsMathErrnoDefault() const { 596198092Srdivacky return true; 597193326Sed} 598193326Sed 599193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 600193326Sed // FIXME: Gross; we should probably have some separate target 601193326Sed // definition, possibly even reusing the one in clang. 602193326Sed return getArchName() == "x86_64"; 603193326Sed} 604193326Sed 605193326Sedconst char *Generic_GCC::GetDefaultRelocationModel() const { 606193326Sed return "static"; 607193326Sed} 608193326Sed 609193326Sedconst char *Generic_GCC::GetForcedPicModel() const { 610193326Sed return 0; 611193326Sed} 612193326Sed 613198092SrdivackyDerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args, 614198092Srdivacky const char *BoundArch) const { 615193326Sed return new DerivedArgList(Args, true); 616193326Sed} 617193326Sed 618195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 619195341Sed 620195341SedOpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple) 621195341Sed : Generic_GCC(Host, Triple) { 622195341Sed getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 623195341Sed getFilePaths().push_back("/usr/lib"); 624195341Sed} 625195341Sed 626195341SedTool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 627195341Sed Action::ActionClass Key; 628198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 629195341Sed Key = Action::AnalyzeJobClass; 630195341Sed else 631195341Sed Key = JA.getKind(); 632195341Sed 633195341Sed Tool *&T = Tools[Key]; 634195341Sed if (!T) { 635195341Sed switch (Key) { 636195341Sed case Action::AssembleJobClass: 637195341Sed T = new tools::openbsd::Assemble(*this); break; 638195341Sed case Action::LinkJobClass: 639195341Sed T = new tools::openbsd::Link(*this); break; 640195341Sed default: 641195341Sed T = &Generic_GCC::SelectTool(C, JA); 642195341Sed } 643195341Sed } 644195341Sed 645195341Sed return *T; 646195341Sed} 647195341Sed 648193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 649193326Sed 650193326SedFreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) 651193326Sed : Generic_GCC(Host, Triple) { 652193326Sed if (Lib32) { 653193326Sed getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32"); 654193326Sed getFilePaths().push_back("/usr/lib32"); 655193326Sed } else { 656193326Sed getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 657193326Sed getFilePaths().push_back("/usr/lib"); 658193326Sed } 659193326Sed} 660193326Sed 661193326SedTool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 662193326Sed Action::ActionClass Key; 663198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 664193326Sed Key = Action::AnalyzeJobClass; 665193326Sed else 666193326Sed Key = JA.getKind(); 667193326Sed 668193326Sed Tool *&T = Tools[Key]; 669193326Sed if (!T) { 670193326Sed switch (Key) { 671193326Sed case Action::AssembleJobClass: 672193326Sed T = new tools::freebsd::Assemble(*this); break; 673193326Sed case Action::LinkJobClass: 674193326Sed T = new tools::freebsd::Link(*this); break; 675193326Sed default: 676193326Sed T = &Generic_GCC::SelectTool(C, JA); 677193326Sed } 678193326Sed } 679193326Sed 680193326Sed return *T; 681193326Sed} 682193326Sed 683198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 684198092Srdivacky 685198092SrdivackyAuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) 686198092Srdivacky : Generic_GCC(Host, Triple) { 687198092Srdivacky 688198092Srdivacky // Path mangling to find libexec 689198092Srdivacky std::string Path(getHost().getDriver().Dir); 690198092Srdivacky 691198092Srdivacky Path += "/../libexec"; 692198092Srdivacky getProgramPaths().push_back(Path); 693198092Srdivacky getProgramPaths().push_back(getHost().getDriver().Dir); 694198092Srdivacky 695198092Srdivacky getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 696198092Srdivacky getFilePaths().push_back("/usr/lib"); 697198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 698198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 699198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 700198092Srdivacky 701198092Srdivacky} 702198092Srdivacky 703198092SrdivackyTool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { 704198092Srdivacky Action::ActionClass Key; 705198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 706198092Srdivacky Key = Action::AnalyzeJobClass; 707198092Srdivacky else 708198092Srdivacky Key = JA.getKind(); 709198092Srdivacky 710198092Srdivacky Tool *&T = Tools[Key]; 711198092Srdivacky if (!T) { 712198092Srdivacky switch (Key) { 713198092Srdivacky case Action::AssembleJobClass: 714198092Srdivacky T = new tools::auroraux::Assemble(*this); break; 715198092Srdivacky case Action::LinkJobClass: 716198092Srdivacky T = new tools::auroraux::Link(*this); break; 717198092Srdivacky default: 718198092Srdivacky T = &Generic_GCC::SelectTool(C, JA); 719198092Srdivacky } 720198092Srdivacky } 721198092Srdivacky 722198092Srdivacky return *T; 723198092Srdivacky} 724198092Srdivacky 725198092Srdivacky 726193326Sed/// Linux toolchain (very bare-bones at the moment). 727193326Sed 728193326SedLinux::Linux(const HostInfo &Host, const llvm::Triple& Triple) 729193326Sed : Generic_GCC(Host, Triple) { 730193326Sed getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/"); 731193326Sed getFilePaths().push_back("/lib/"); 732193326Sed getFilePaths().push_back("/usr/lib/"); 733198092Srdivacky 734198092Srdivacky // Depending on the Linux distribution, any combination of lib{,32,64} is 735198092Srdivacky // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems, 736198092Srdivacky // openSUSE uses lib and lib64 for the same purpose. 737198092Srdivacky getFilePaths().push_back("/lib32/"); 738198092Srdivacky getFilePaths().push_back("/usr/lib32/"); 739198092Srdivacky getFilePaths().push_back("/lib64/"); 740198092Srdivacky getFilePaths().push_back("/usr/lib64/"); 741198092Srdivacky 742193326Sed // FIXME: Figure out some way to get gcc's libdir 743193326Sed // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need 744193326Sed // crtbegin.o/crtend.o/etc., and want static versions of various 745193326Sed // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably 746193326Sed // get away with using shared versions in /usr/lib, though. 747193326Sed // We could fall back to the approach we used for includes (a massive 748193326Sed // list), but that's messy at best. 749193326Sed} 750193326Sed 751193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 752193326Sed 753193326SedDragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) 754193326Sed : Generic_GCC(Host, Triple) { 755193326Sed 756193326Sed // Path mangling to find libexec 757193326Sed std::string Path(getHost().getDriver().Dir); 758193326Sed 759193326Sed Path += "/../libexec"; 760193326Sed getProgramPaths().push_back(Path); 761198092Srdivacky getProgramPaths().push_back(getHost().getDriver().Dir); 762193326Sed 763193326Sed getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 764193326Sed getFilePaths().push_back("/usr/lib"); 765193326Sed getFilePaths().push_back("/usr/lib/gcc41"); 766193326Sed} 767193326Sed 768193326SedTool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { 769193326Sed Action::ActionClass Key; 770198092Srdivacky if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 771193326Sed Key = Action::AnalyzeJobClass; 772193326Sed else 773193326Sed Key = JA.getKind(); 774193326Sed 775193326Sed Tool *&T = Tools[Key]; 776193326Sed if (!T) { 777193326Sed switch (Key) { 778193326Sed case Action::AssembleJobClass: 779193326Sed T = new tools::dragonfly::Assemble(*this); break; 780193326Sed case Action::LinkJobClass: 781193326Sed T = new tools::dragonfly::Link(*this); break; 782193326Sed default: 783193326Sed T = &Generic_GCC::SelectTool(C, JA); 784193326Sed } 785193326Sed } 786193326Sed 787193326Sed return *T; 788193326Sed} 789