ToolChains.cpp revision 201361
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" 17199512Srdivacky#include "clang/Driver/OptTable.h" 18193326Sed#include "clang/Driver/Option.h" 19199512Srdivacky#include "clang/Driver/Options.h" 20193326Sed 21193326Sed#include "llvm/ADT/StringExtras.h" 22198092Srdivacky#include "llvm/Support/ErrorHandling.h" 23193326Sed#include "llvm/Support/raw_ostream.h" 24193326Sed#include "llvm/System/Path.h" 25193326Sed 26193326Sed#include <cstdlib> // ::getenv 27193326Sed 28193326Sedusing namespace clang::driver; 29193326Sedusing namespace clang::driver::toolchains; 30193326Sed 31198092Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 32193326Sed 33198092SrdivackyDarwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple, 34198092Srdivacky const unsigned (&_DarwinVersion)[3], bool _IsIPhoneOS) 35198092Srdivacky : ToolChain(Host, Triple), 36198092Srdivacky IsIPhoneOS(_IsIPhoneOS) 37198092Srdivacky{ 38193326Sed DarwinVersion[0] = _DarwinVersion[0]; 39193326Sed DarwinVersion[1] = _DarwinVersion[1]; 40193326Sed DarwinVersion[2] = _DarwinVersion[2]; 41198092Srdivacky 42198092Srdivacky llvm::raw_string_ostream(MacosxVersionMin) 43198398Srdivacky << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.' 44198398Srdivacky << DarwinVersion[1]; 45198092Srdivacky 46198092Srdivacky // FIXME: Lift default up. 47198092Srdivacky IPhoneOSVersionMin = "3.0"; 48198092Srdivacky} 49198092Srdivacky 50198092SrdivackyDarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple, 51198092Srdivacky const unsigned (&DarwinVersion)[3], 52198092Srdivacky const unsigned (&_GCCVersion)[3], bool IsIPhoneOS) 53198092Srdivacky : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) 54198092Srdivacky{ 55193326Sed GCCVersion[0] = _GCCVersion[0]; 56193326Sed GCCVersion[1] = _GCCVersion[1]; 57193326Sed GCCVersion[2] = _GCCVersion[2]; 58193326Sed 59198092Srdivacky // Set up the tool chain paths to match gcc. 60193326Sed ToolChainDir = "i686-apple-darwin"; 61193326Sed ToolChainDir += llvm::utostr(DarwinVersion[0]); 62193326Sed ToolChainDir += "/"; 63193326Sed ToolChainDir += llvm::utostr(GCCVersion[0]); 64193326Sed ToolChainDir += '.'; 65193326Sed ToolChainDir += llvm::utostr(GCCVersion[1]); 66193326Sed ToolChainDir += '.'; 67193326Sed ToolChainDir += llvm::utostr(GCCVersion[2]); 68193326Sed 69198398Srdivacky // Try the next major version if that tool chain dir is invalid. 70198398Srdivacky std::string Tmp = "/usr/lib/gcc/" + ToolChainDir; 71198398Srdivacky if (!llvm::sys::Path(Tmp).exists()) { 72198398Srdivacky std::string Next = "i686-apple-darwin"; 73198398Srdivacky Next += llvm::utostr(DarwinVersion[0] + 1); 74198398Srdivacky Next += "/"; 75198398Srdivacky Next += llvm::utostr(GCCVersion[0]); 76198398Srdivacky Next += '.'; 77198398Srdivacky Next += llvm::utostr(GCCVersion[1]); 78198398Srdivacky Next += '.'; 79198398Srdivacky Next += llvm::utostr(GCCVersion[2]); 80198398Srdivacky 81198398Srdivacky // Use that if it exists, otherwise hope the user isn't linking. 82198398Srdivacky // 83198398Srdivacky // FIXME: Drop dependency on gcc's tool chain. 84198398Srdivacky Tmp = "/usr/lib/gcc/" + Next; 85198398Srdivacky if (llvm::sys::Path(Tmp).exists()) 86198398Srdivacky ToolChainDir = Next; 87198398Srdivacky } 88198398Srdivacky 89193326Sed std::string Path; 90193326Sed if (getArchName() == "x86_64") { 91201361Srdivacky Path = getDriver().Dir; 92193326Sed Path += "/../lib/gcc/"; 93198092Srdivacky Path += ToolChainDir; 94193326Sed Path += "/x86_64"; 95193326Sed getFilePaths().push_back(Path); 96193326Sed 97193326Sed Path = "/usr/lib/gcc/"; 98198092Srdivacky Path += ToolChainDir; 99193326Sed Path += "/x86_64"; 100193326Sed getFilePaths().push_back(Path); 101193326Sed } 102198092Srdivacky 103201361Srdivacky Path = getDriver().Dir; 104193326Sed Path += "/../lib/gcc/"; 105198092Srdivacky Path += ToolChainDir; 106193326Sed getFilePaths().push_back(Path); 107193326Sed 108193326Sed Path = "/usr/lib/gcc/"; 109198092Srdivacky Path += ToolChainDir; 110193326Sed getFilePaths().push_back(Path); 111193326Sed 112201361Srdivacky Path = getDriver().Dir; 113193326Sed Path += "/../libexec/gcc/"; 114198092Srdivacky Path += ToolChainDir; 115193326Sed getProgramPaths().push_back(Path); 116193326Sed 117193326Sed Path = "/usr/libexec/gcc/"; 118198092Srdivacky Path += ToolChainDir; 119193326Sed getProgramPaths().push_back(Path); 120193326Sed 121201361Srdivacky Path = getDriver().Dir; 122193326Sed Path += "/../libexec"; 123193326Sed getProgramPaths().push_back(Path); 124193326Sed 125201361Srdivacky getProgramPaths().push_back(getDriver().Dir); 126193326Sed} 127193326Sed 128198092SrdivackyDarwin::~Darwin() { 129193326Sed // Free tool implementations. 130193326Sed for (llvm::DenseMap<unsigned, Tool*>::iterator 131193326Sed it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 132193326Sed delete it->second; 133193326Sed} 134193326Sed 135198092SrdivackyTool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { 136193326Sed Action::ActionClass Key; 137201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 138193326Sed Key = Action::AnalyzeJobClass; 139193326Sed else 140193326Sed Key = JA.getKind(); 141193326Sed 142193326Sed Tool *&T = Tools[Key]; 143193326Sed if (!T) { 144193326Sed switch (Key) { 145193326Sed case Action::InputClass: 146193326Sed case Action::BindArchClass: 147193326Sed assert(0 && "Invalid tool kind."); 148193326Sed case Action::PreprocessJobClass: 149193326Sed T = new tools::darwin::Preprocess(*this); break; 150193326Sed case Action::AnalyzeJobClass: 151193326Sed T = new tools::Clang(*this); break; 152193326Sed case Action::PrecompileJobClass: 153193326Sed case Action::CompileJobClass: 154193326Sed T = new tools::darwin::Compile(*this); break; 155193326Sed case Action::AssembleJobClass: 156193326Sed T = new tools::darwin::Assemble(*this); break; 157193326Sed case Action::LinkJobClass: 158198092Srdivacky T = new tools::darwin::Link(*this); break; 159193326Sed case Action::LipoJobClass: 160193326Sed T = new tools::darwin::Lipo(*this); break; 161193326Sed } 162193326Sed } 163193326Sed 164193326Sed return *T; 165193326Sed} 166193326Sed 167198092Srdivackyvoid DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args, 168198092Srdivacky ArgStringList &CmdArgs) const { 169198092Srdivacky // FIXME: Derive these correctly. 170198092Srdivacky if (getArchName() == "x86_64") { 171198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 172198092Srdivacky "/x86_64")); 173198092Srdivacky // Intentionally duplicated for (temporary) gcc bug compatibility. 174198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 175198092Srdivacky "/x86_64")); 176198092Srdivacky } 177198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir)); 178198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 179198092Srdivacky // Intentionally duplicated for (temporary) gcc bug compatibility. 180198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 181198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 182198092Srdivacky "/../../../" + ToolChainDir)); 183198092Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 184198092Srdivacky "/../../..")); 185198092Srdivacky} 186198092Srdivacky 187198092Srdivackyvoid DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, 188198092Srdivacky ArgStringList &CmdArgs) const { 189198092Srdivacky unsigned MacosxVersionMin[3]; 190198092Srdivacky getMacosxVersionMin(Args, MacosxVersionMin); 191198092Srdivacky 192198092Srdivacky // Derived from libgcc and lib specs but refactored. 193198092Srdivacky if (Args.hasArg(options::OPT_static)) { 194198092Srdivacky CmdArgs.push_back("-lgcc_static"); 195198092Srdivacky } else { 196198092Srdivacky if (Args.hasArg(options::OPT_static_libgcc)) { 197198092Srdivacky CmdArgs.push_back("-lgcc_eh"); 198198092Srdivacky } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { 199198092Srdivacky // Derived from darwin_iphoneos_libgcc spec. 200198092Srdivacky if (isIPhoneOS()) { 201198092Srdivacky CmdArgs.push_back("-lgcc_s.1"); 202198092Srdivacky } else { 203198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 204198092Srdivacky } 205198092Srdivacky } else if (Args.hasArg(options::OPT_shared_libgcc) || 206198092Srdivacky // FIXME: -fexceptions -fno-exceptions means no exceptions 207198092Srdivacky Args.hasArg(options::OPT_fexceptions) || 208198092Srdivacky Args.hasArg(options::OPT_fgnu_runtime)) { 209198092Srdivacky // FIXME: This is probably broken on 10.3? 210198092Srdivacky if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) 211198092Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 212198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 6)) 213198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 214198092Srdivacky } else { 215198092Srdivacky if (isMacosxVersionLT(MacosxVersionMin, 10, 3, 9)) 216198092Srdivacky ; // Do nothing. 217198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 5)) 218198092Srdivacky CmdArgs.push_back("-lgcc_s.10.4"); 219198092Srdivacky else if (isMacosxVersionLT(MacosxVersionMin, 10, 6)) 220198092Srdivacky CmdArgs.push_back("-lgcc_s.10.5"); 221198092Srdivacky } 222198092Srdivacky 223198092Srdivacky if (isIPhoneOS() || isMacosxVersionLT(MacosxVersionMin, 10, 6)) { 224198092Srdivacky CmdArgs.push_back("-lgcc"); 225198092Srdivacky CmdArgs.push_back("-lSystem"); 226198092Srdivacky } else { 227198092Srdivacky CmdArgs.push_back("-lSystem"); 228198092Srdivacky CmdArgs.push_back("-lgcc"); 229198092Srdivacky } 230198092Srdivacky } 231198092Srdivacky} 232198092Srdivacky 233198092SrdivackyDarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, 234198092Srdivacky const unsigned (&DarwinVersion)[3], 235198092Srdivacky bool IsIPhoneOS) 236198092Srdivacky : Darwin(Host, Triple, DarwinVersion, IsIPhoneOS) 237198092Srdivacky{ 238198092Srdivacky // Add the relative libexec dir (for clang-cc). 239198092Srdivacky // 240198092Srdivacky // FIXME: We should sink clang-cc into libexec/clang/<version>/. 241201361Srdivacky std::string Path = getDriver().Dir; 242198092Srdivacky Path += "/../libexec"; 243198092Srdivacky getProgramPaths().push_back(Path); 244198092Srdivacky 245198092Srdivacky // We expect 'as', 'ld', etc. to be adjacent to our install dir. 246201361Srdivacky getProgramPaths().push_back(getDriver().Dir); 247198092Srdivacky} 248198092Srdivacky 249198092Srdivackyvoid DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, 250198092Srdivacky ArgStringList &CmdArgs) const { 251198092Srdivacky // The Clang toolchain uses explicit paths for internal libraries. 252198092Srdivacky} 253198092Srdivacky 254198092Srdivackyvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 255198092Srdivacky ArgStringList &CmdArgs) const { 256198092Srdivacky // Check for static linking. 257198092Srdivacky if (Args.hasArg(options::OPT_static)) { 258198092Srdivacky // FIXME: We need to have compiler-rt available (perhaps as 259198092Srdivacky // libclang_static.a) to link against. 260198092Srdivacky return; 261198092Srdivacky } 262198092Srdivacky 263198092Srdivacky // Reject -static-libgcc for now, we can deal with this when and if someone 264198092Srdivacky // cares. This is useful in situations where someone wants to statically link 265198092Srdivacky // something like libstdc++, and needs its runtime support routines. 266198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 267201361Srdivacky getDriver().Diag(clang::diag::err_drv_unsupported_opt) 268198092Srdivacky << A->getAsString(Args); 269198092Srdivacky return; 270198092Srdivacky } 271198092Srdivacky 272198092Srdivacky // Otherwise link libSystem, which should have the support routines. 273198092Srdivacky // 274198092Srdivacky // FIXME: This is only true for 10.6 and beyond. Legacy support isn't 275198092Srdivacky // critical, but it should work... we should just link in the static 276198092Srdivacky // compiler-rt library. 277198092Srdivacky CmdArgs.push_back("-lSystem"); 278198092Srdivacky} 279198092Srdivacky 280198092Srdivackyvoid Darwin::getMacosxVersionMin(const ArgList &Args, 281198092Srdivacky unsigned (&Res)[3]) const { 282198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) { 283198092Srdivacky bool HadExtra; 284198092Srdivacky if (!Driver::GetReleaseVersion(A->getValue(Args), Res[0], Res[1], Res[2], 285198092Srdivacky HadExtra) || 286198092Srdivacky HadExtra) { 287201361Srdivacky const Driver &D = getDriver(); 288198092Srdivacky D.Diag(clang::diag::err_drv_invalid_version_number) 289198092Srdivacky << A->getAsString(Args); 290198092Srdivacky } 291198092Srdivacky } else 292198092Srdivacky return getMacosxVersion(Res); 293198092Srdivacky} 294198092Srdivacky 295198092SrdivackyDerivedArgList *Darwin::TranslateArgs(InputArgList &Args, 296198092Srdivacky const char *BoundArch) const { 297193326Sed DerivedArgList *DAL = new DerivedArgList(Args, false); 298201361Srdivacky const OptTable &Opts = getDriver().getOpts(); 299193326Sed 300193326Sed // FIXME: We really want to get out of the tool chain level argument 301193326Sed // translation business, as it makes the driver functionality much 302193326Sed // more opaque. For now, we follow gcc closely solely for the 303193326Sed // purpose of easily achieving feature parity & testability. Once we 304193326Sed // have something that works, we should reevaluate each translation 305198092Srdivacky // and try to push it down into tool specific logic. 306193326Sed 307198092Srdivacky Arg *OSXVersion = 308199512Srdivacky Args.getLastArgNoClaim(options::OPT_mmacosx_version_min_EQ); 309193326Sed Arg *iPhoneVersion = 310199512Srdivacky Args.getLastArgNoClaim(options::OPT_miphoneos_version_min_EQ); 311193326Sed if (OSXVersion && iPhoneVersion) { 312201361Srdivacky getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with) 313193326Sed << OSXVersion->getAsString(Args) 314198092Srdivacky << iPhoneVersion->getAsString(Args); 315193326Sed } else if (!OSXVersion && !iPhoneVersion) { 316193326Sed // Chose the default version based on the arch. 317193326Sed // 318198092Srdivacky // FIXME: Are there iPhone overrides for this? 319193326Sed 320198092Srdivacky if (!isIPhoneOS()) { 321198092Srdivacky // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version 322198092Srdivacky // from the host. 323198092Srdivacky const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET"); 324198092Srdivacky if (!Version) 325198092Srdivacky Version = MacosxVersionMin.c_str(); 326198092Srdivacky const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 327198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, O, Version)); 328198092Srdivacky } else { 329198092Srdivacky const char *Version = IPhoneOSVersionMin.c_str(); 330198092Srdivacky const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 331198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, O, Version)); 332198092Srdivacky } 333193326Sed } 334198092Srdivacky 335193326Sed for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { 336193326Sed Arg *A = *it; 337193326Sed 338193326Sed if (A->getOption().matches(options::OPT_Xarch__)) { 339193326Sed // FIXME: Canonicalize name. 340193326Sed if (getArchName() != A->getValue(Args, 0)) 341193326Sed continue; 342193326Sed 343193326Sed // FIXME: The arg is leaked here, and we should have a nicer 344193326Sed // interface for this. 345193326Sed unsigned Prev, Index = Prev = A->getIndex() + 1; 346193326Sed Arg *XarchArg = Opts.ParseOneArg(Args, Index); 347198092Srdivacky 348193326Sed // If the argument parsing failed or more than one argument was 349193326Sed // consumed, the -Xarch_ argument's parameter tried to consume 350193326Sed // extra arguments. Emit an error and ignore. 351193326Sed // 352193326Sed // We also want to disallow any options which would alter the 353193326Sed // driver behavior; that isn't going to work in our model. We 354193326Sed // use isDriverOption() as an approximation, although things 355193326Sed // like -O4 are going to slip through. 356198092Srdivacky if (!XarchArg || Index > Prev + 1 || 357193326Sed XarchArg->getOption().isDriverOption()) { 358201361Srdivacky getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument) 359193326Sed << A->getAsString(Args); 360193326Sed continue; 361193326Sed } 362193326Sed 363193326Sed XarchArg->setBaseArg(A); 364193326Sed A = XarchArg; 365198092Srdivacky } 366193326Sed 367193326Sed // Sob. These is strictly gcc compatible for the time being. Apple 368193326Sed // gcc translates options twice, which means that self-expanding 369193326Sed // options add duplicates. 370199512Srdivacky switch ((options::ID) A->getOption().getID()) { 371193326Sed default: 372193326Sed DAL->append(A); 373193326Sed break; 374193326Sed 375193326Sed case options::OPT_mkernel: 376193326Sed case options::OPT_fapple_kext: 377193326Sed DAL->append(A); 378193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 379193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 380193326Sed break; 381198092Srdivacky 382193326Sed case options::OPT_dependency_file: 383193326Sed DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF), 384193326Sed A->getValue(Args))); 385193326Sed break; 386193326Sed 387193326Sed case options::OPT_gfull: 388193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 389193326Sed DAL->append(DAL->MakeFlagArg(A, 390193326Sed Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols))); 391193326Sed break; 392193326Sed 393193326Sed case options::OPT_gused: 394193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 395193326Sed DAL->append(DAL->MakeFlagArg(A, 396193326Sed Opts.getOption(options::OPT_feliminate_unused_debug_symbols))); 397193326Sed break; 398193326Sed 399193326Sed case options::OPT_fterminated_vtables: 400193326Sed case options::OPT_findirect_virtual_calls: 401193326Sed DAL->append(DAL->MakeFlagArg(A, 402193326Sed Opts.getOption(options::OPT_fapple_kext))); 403193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 404193326Sed break; 405193326Sed 406193326Sed case options::OPT_shared: 407193326Sed DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib))); 408193326Sed break; 409193326Sed 410193326Sed case options::OPT_fconstant_cfstrings: 411193326Sed DAL->append(DAL->MakeFlagArg(A, 412193326Sed Opts.getOption(options::OPT_mconstant_cfstrings))); 413193326Sed break; 414193326Sed 415193326Sed case options::OPT_fno_constant_cfstrings: 416193326Sed DAL->append(DAL->MakeFlagArg(A, 417193326Sed Opts.getOption(options::OPT_mno_constant_cfstrings))); 418193326Sed break; 419193326Sed 420193326Sed case options::OPT_Wnonportable_cfstrings: 421193326Sed DAL->append(DAL->MakeFlagArg(A, 422193326Sed Opts.getOption(options::OPT_mwarn_nonportable_cfstrings))); 423193326Sed break; 424193326Sed 425193326Sed case options::OPT_Wno_nonportable_cfstrings: 426193326Sed DAL->append(DAL->MakeFlagArg(A, 427193326Sed Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings))); 428193326Sed break; 429193326Sed 430193326Sed case options::OPT_fpascal_strings: 431193326Sed DAL->append(DAL->MakeFlagArg(A, 432193326Sed Opts.getOption(options::OPT_mpascal_strings))); 433193326Sed break; 434193326Sed 435193326Sed case options::OPT_fno_pascal_strings: 436193326Sed DAL->append(DAL->MakeFlagArg(A, 437193326Sed Opts.getOption(options::OPT_mno_pascal_strings))); 438193326Sed break; 439193326Sed } 440193326Sed } 441193326Sed 442198092Srdivacky if (getTriple().getArch() == llvm::Triple::x86 || 443198092Srdivacky getTriple().getArch() == llvm::Triple::x86_64) 444199512Srdivacky if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 445198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), 446198092Srdivacky "core2")); 447198092Srdivacky 448198092Srdivacky // Add the arch options based on the particular spelling of -arch, to match 449198092Srdivacky // how the driver driver works. 450198092Srdivacky if (BoundArch) { 451198092Srdivacky llvm::StringRef Name = BoundArch; 452198092Srdivacky const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ); 453198092Srdivacky const Option *MArch = Opts.getOption(options::OPT_march_EQ); 454198092Srdivacky 455198092Srdivacky // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 456198092Srdivacky // which defines the list of which architectures we accept. 457198092Srdivacky if (Name == "ppc") 458198092Srdivacky ; 459198092Srdivacky else if (Name == "ppc601") 460198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "601")); 461198092Srdivacky else if (Name == "ppc603") 462198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "603")); 463198092Srdivacky else if (Name == "ppc604") 464198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "604")); 465198092Srdivacky else if (Name == "ppc604e") 466198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e")); 467198092Srdivacky else if (Name == "ppc750") 468198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "750")); 469198092Srdivacky else if (Name == "ppc7400") 470198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400")); 471198092Srdivacky else if (Name == "ppc7450") 472198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450")); 473198092Srdivacky else if (Name == "ppc970") 474198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MCpu, "970")); 475198092Srdivacky 476198092Srdivacky else if (Name == "ppc64") 477193326Sed DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 478193326Sed 479198092Srdivacky else if (Name == "i386") 480198092Srdivacky ; 481198092Srdivacky else if (Name == "i486") 482198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i486")); 483198092Srdivacky else if (Name == "i586") 484198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i586")); 485198092Srdivacky else if (Name == "i686") 486198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "i686")); 487198092Srdivacky else if (Name == "pentium") 488198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium")); 489198092Srdivacky else if (Name == "pentium2") 490198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2")); 491198092Srdivacky else if (Name == "pentpro") 492198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro")); 493198092Srdivacky else if (Name == "pentIIm3") 494198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2")); 495193326Sed 496198092Srdivacky else if (Name == "x86_64") 497198092Srdivacky DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 498198092Srdivacky 499198092Srdivacky else if (Name == "arm") 500198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t")); 501198092Srdivacky else if (Name == "armv4t") 502198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t")); 503198092Srdivacky else if (Name == "armv5") 504198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej")); 505198092Srdivacky else if (Name == "xscale") 506198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale")); 507198092Srdivacky else if (Name == "armv6") 508198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k")); 509198092Srdivacky else if (Name == "armv7") 510198092Srdivacky DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a")); 511198092Srdivacky 512198092Srdivacky else 513200583Srdivacky llvm_unreachable("invalid Darwin arch"); 514198092Srdivacky } 515198092Srdivacky 516193326Sed return DAL; 517198092Srdivacky} 518193326Sed 519198092Srdivackybool Darwin::IsMathErrnoDefault() const { 520198092Srdivacky return false; 521193326Sed} 522193326Sed 523198092Srdivackybool Darwin::IsUnwindTablesDefault() const { 524193326Sed // FIXME: Gross; we should probably have some separate target 525193326Sed // definition, possibly even reusing the one in clang. 526193326Sed return getArchName() == "x86_64"; 527193326Sed} 528193326Sed 529201361Srdivackybool Darwin::UseDwarfDebugFlags() const { 530201361Srdivacky if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 531201361Srdivacky return S[0] != '\0'; 532201361Srdivacky return false; 533201361Srdivacky} 534201361Srdivacky 535198092Srdivackyconst char *Darwin::GetDefaultRelocationModel() const { 536193326Sed return "pic"; 537193326Sed} 538193326Sed 539198092Srdivackyconst char *Darwin::GetForcedPicModel() const { 540193326Sed if (getArchName() == "x86_64") 541193326Sed return "pic"; 542193326Sed return 0; 543193326Sed} 544193326Sed 545193326Sed/// Generic_GCC - A tool chain using the 'gcc' command to perform 546193326Sed/// all subcommands; this relies on gcc translating the majority of 547193326Sed/// command line options. 548193326Sed 549193326SedGeneric_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) 550198092Srdivacky : ToolChain(Host, Triple) { 551201361Srdivacky std::string Path(getDriver().Dir); 552193326Sed Path += "/../libexec"; 553193326Sed getProgramPaths().push_back(Path); 554193326Sed 555201361Srdivacky getProgramPaths().push_back(getDriver().Dir); 556193326Sed} 557193326Sed 558193326SedGeneric_GCC::~Generic_GCC() { 559193326Sed // Free tool implementations. 560193326Sed for (llvm::DenseMap<unsigned, Tool*>::iterator 561193326Sed it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 562193326Sed delete it->second; 563193326Sed} 564193326Sed 565198092SrdivackyTool &Generic_GCC::SelectTool(const Compilation &C, 566193326Sed const JobAction &JA) const { 567193326Sed Action::ActionClass Key; 568201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 569193326Sed Key = Action::AnalyzeJobClass; 570193326Sed else 571193326Sed Key = JA.getKind(); 572193326Sed 573193326Sed Tool *&T = Tools[Key]; 574193326Sed if (!T) { 575193326Sed switch (Key) { 576193326Sed case Action::InputClass: 577193326Sed case Action::BindArchClass: 578193326Sed assert(0 && "Invalid tool kind."); 579193326Sed case Action::PreprocessJobClass: 580193326Sed T = new tools::gcc::Preprocess(*this); break; 581193326Sed case Action::PrecompileJobClass: 582193326Sed T = new tools::gcc::Precompile(*this); break; 583193326Sed case Action::AnalyzeJobClass: 584193326Sed T = new tools::Clang(*this); break; 585193326Sed case Action::CompileJobClass: 586193326Sed T = new tools::gcc::Compile(*this); break; 587193326Sed case Action::AssembleJobClass: 588193326Sed T = new tools::gcc::Assemble(*this); break; 589193326Sed case Action::LinkJobClass: 590193326Sed T = new tools::gcc::Link(*this); break; 591198092Srdivacky 592193326Sed // This is a bit ungeneric, but the only platform using a driver 593193326Sed // driver is Darwin. 594193326Sed case Action::LipoJobClass: 595193326Sed T = new tools::darwin::Lipo(*this); break; 596193326Sed } 597193326Sed } 598193326Sed 599193326Sed return *T; 600193326Sed} 601193326Sed 602198092Srdivackybool Generic_GCC::IsMathErrnoDefault() const { 603198092Srdivacky return true; 604193326Sed} 605193326Sed 606193326Sedbool Generic_GCC::IsUnwindTablesDefault() const { 607193326Sed // FIXME: Gross; we should probably have some separate target 608193326Sed // definition, possibly even reusing the one in clang. 609193326Sed return getArchName() == "x86_64"; 610193326Sed} 611193326Sed 612193326Sedconst char *Generic_GCC::GetDefaultRelocationModel() const { 613193326Sed return "static"; 614193326Sed} 615193326Sed 616193326Sedconst char *Generic_GCC::GetForcedPicModel() const { 617193326Sed return 0; 618193326Sed} 619193326Sed 620198092SrdivackyDerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args, 621198092Srdivacky const char *BoundArch) const { 622193326Sed return new DerivedArgList(Args, true); 623193326Sed} 624193326Sed 625195341Sed/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 626195341Sed 627195341SedOpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple) 628195341Sed : Generic_GCC(Host, Triple) { 629201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 630195341Sed getFilePaths().push_back("/usr/lib"); 631195341Sed} 632195341Sed 633195341SedTool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 634195341Sed Action::ActionClass Key; 635201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 636195341Sed Key = Action::AnalyzeJobClass; 637195341Sed else 638195341Sed Key = JA.getKind(); 639195341Sed 640195341Sed Tool *&T = Tools[Key]; 641195341Sed if (!T) { 642195341Sed switch (Key) { 643195341Sed case Action::AssembleJobClass: 644195341Sed T = new tools::openbsd::Assemble(*this); break; 645195341Sed case Action::LinkJobClass: 646195341Sed T = new tools::openbsd::Link(*this); break; 647195341Sed default: 648195341Sed T = &Generic_GCC::SelectTool(C, JA); 649195341Sed } 650195341Sed } 651195341Sed 652195341Sed return *T; 653195341Sed} 654195341Sed 655193326Sed/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 656193326Sed 657193326SedFreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) 658193326Sed : Generic_GCC(Host, Triple) { 659193326Sed if (Lib32) { 660201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib32"); 661193326Sed getFilePaths().push_back("/usr/lib32"); 662193326Sed } else { 663201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 664193326Sed getFilePaths().push_back("/usr/lib"); 665193326Sed } 666193326Sed} 667193326Sed 668193326SedTool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 669193326Sed Action::ActionClass Key; 670201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 671193326Sed Key = Action::AnalyzeJobClass; 672193326Sed else 673193326Sed Key = JA.getKind(); 674193326Sed 675193326Sed Tool *&T = Tools[Key]; 676193326Sed if (!T) { 677193326Sed switch (Key) { 678193326Sed case Action::AssembleJobClass: 679193326Sed T = new tools::freebsd::Assemble(*this); break; 680193326Sed case Action::LinkJobClass: 681193326Sed T = new tools::freebsd::Link(*this); break; 682193326Sed default: 683193326Sed T = &Generic_GCC::SelectTool(C, JA); 684193326Sed } 685193326Sed } 686193326Sed 687193326Sed return *T; 688193326Sed} 689193326Sed 690198092Srdivacky/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 691198092Srdivacky 692198092SrdivackyAuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) 693198092Srdivacky : Generic_GCC(Host, Triple) { 694198092Srdivacky 695198092Srdivacky // Path mangling to find libexec 696201361Srdivacky std::string Path(getDriver().Dir); 697198092Srdivacky 698198092Srdivacky Path += "/../libexec"; 699198092Srdivacky getProgramPaths().push_back(Path); 700201361Srdivacky getProgramPaths().push_back(getDriver().Dir); 701198092Srdivacky 702201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 703198092Srdivacky getFilePaths().push_back("/usr/lib"); 704198092Srdivacky getFilePaths().push_back("/usr/sfw/lib"); 705198092Srdivacky getFilePaths().push_back("/opt/gcc4/lib"); 706198398Srdivacky getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 707198092Srdivacky 708198092Srdivacky} 709198092Srdivacky 710198092SrdivackyTool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { 711198092Srdivacky Action::ActionClass Key; 712201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 713198092Srdivacky Key = Action::AnalyzeJobClass; 714198092Srdivacky else 715198092Srdivacky Key = JA.getKind(); 716198092Srdivacky 717198092Srdivacky Tool *&T = Tools[Key]; 718198092Srdivacky if (!T) { 719198092Srdivacky switch (Key) { 720198092Srdivacky case Action::AssembleJobClass: 721198092Srdivacky T = new tools::auroraux::Assemble(*this); break; 722198092Srdivacky case Action::LinkJobClass: 723198092Srdivacky T = new tools::auroraux::Link(*this); break; 724198092Srdivacky default: 725198092Srdivacky T = &Generic_GCC::SelectTool(C, JA); 726198092Srdivacky } 727198092Srdivacky } 728198092Srdivacky 729198092Srdivacky return *T; 730198092Srdivacky} 731198092Srdivacky 732198092Srdivacky 733193326Sed/// Linux toolchain (very bare-bones at the moment). 734193326Sed 735193326SedLinux::Linux(const HostInfo &Host, const llvm::Triple& Triple) 736193326Sed : Generic_GCC(Host, Triple) { 737201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib/clang/1.0/"); 738193326Sed getFilePaths().push_back("/lib/"); 739193326Sed getFilePaths().push_back("/usr/lib/"); 740198092Srdivacky 741198092Srdivacky // Depending on the Linux distribution, any combination of lib{,32,64} is 742198092Srdivacky // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems, 743198092Srdivacky // openSUSE uses lib and lib64 for the same purpose. 744198092Srdivacky getFilePaths().push_back("/lib32/"); 745198092Srdivacky getFilePaths().push_back("/usr/lib32/"); 746198092Srdivacky getFilePaths().push_back("/lib64/"); 747198092Srdivacky getFilePaths().push_back("/usr/lib64/"); 748198092Srdivacky 749193326Sed // FIXME: Figure out some way to get gcc's libdir 750193326Sed // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need 751193326Sed // crtbegin.o/crtend.o/etc., and want static versions of various 752193326Sed // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably 753193326Sed // get away with using shared versions in /usr/lib, though. 754193326Sed // We could fall back to the approach we used for includes (a massive 755193326Sed // list), but that's messy at best. 756193326Sed} 757193326Sed 758193326Sed/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 759193326Sed 760193326SedDragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) 761193326Sed : Generic_GCC(Host, Triple) { 762193326Sed 763193326Sed // Path mangling to find libexec 764201361Srdivacky std::string Path(getDriver().Dir); 765193326Sed 766193326Sed Path += "/../libexec"; 767193326Sed getProgramPaths().push_back(Path); 768201361Srdivacky getProgramPaths().push_back(getDriver().Dir); 769193326Sed 770201361Srdivacky getFilePaths().push_back(getDriver().Dir + "/../lib"); 771193326Sed getFilePaths().push_back("/usr/lib"); 772193326Sed getFilePaths().push_back("/usr/lib/gcc41"); 773193326Sed} 774193326Sed 775193326SedTool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { 776193326Sed Action::ActionClass Key; 777201361Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 778193326Sed Key = Action::AnalyzeJobClass; 779193326Sed else 780193326Sed Key = JA.getKind(); 781193326Sed 782193326Sed Tool *&T = Tools[Key]; 783193326Sed if (!T) { 784193326Sed switch (Key) { 785193326Sed case Action::AssembleJobClass: 786193326Sed T = new tools::dragonfly::Assemble(*this); break; 787193326Sed case Action::LinkJobClass: 788193326Sed T = new tools::dragonfly::Link(*this); break; 789193326Sed default: 790193326Sed T = &Generic_GCC::SelectTool(C, JA); 791193326Sed } 792193326Sed } 793193326Sed 794193326Sed return *T; 795193326Sed} 796