Tools.cpp revision 208600
1193326Sed//===--- Tools.cpp - Tools 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 "Tools.h" 11193326Sed 12193326Sed#include "clang/Driver/Action.h" 13193326Sed#include "clang/Driver/Arg.h" 14193326Sed#include "clang/Driver/ArgList.h" 15198893Srdivacky#include "clang/Driver/Driver.h" 16198893Srdivacky#include "clang/Driver/DriverDiagnostic.h" 17193326Sed#include "clang/Driver/Compilation.h" 18193326Sed#include "clang/Driver/Job.h" 19193326Sed#include "clang/Driver/HostInfo.h" 20193326Sed#include "clang/Driver/Option.h" 21199512Srdivacky#include "clang/Driver/Options.h" 22193326Sed#include "clang/Driver/ToolChain.h" 23193326Sed#include "clang/Driver/Util.h" 24193326Sed 25198092Srdivacky#include "llvm/ADT/SmallString.h" 26198893Srdivacky#include "llvm/ADT/StringSwitch.h" 27198092Srdivacky#include "llvm/ADT/Twine.h" 28193326Sed#include "llvm/Support/Format.h" 29193326Sed#include "llvm/Support/raw_ostream.h" 30199482Srdivacky#include "llvm/System/Host.h" 31198893Srdivacky#include "llvm/System/Process.h" 32193326Sed 33193326Sed#include "InputInfo.h" 34193326Sed#include "ToolChains.h" 35193326Sed 36193326Sedusing namespace clang::driver; 37193326Sedusing namespace clang::driver::tools; 38193326Sed 39198092Srdivacky/// CheckPreprocessingOptions - Perform some validation of preprocessing 40198092Srdivacky/// arguments that is shared with gcc. 41198092Srdivackystatic void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { 42198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) 43198092Srdivacky if (!Args.hasArg(options::OPT_E)) 44198092Srdivacky D.Diag(clang::diag::err_drv_argument_only_allowed_with) 45198092Srdivacky << A->getAsString(Args) << "-E"; 46198092Srdivacky} 47198092Srdivacky 48198092Srdivacky/// CheckCodeGenerationOptions - Perform some validation of code generation 49198092Srdivacky/// arguments that is shared with gcc. 50198092Srdivackystatic void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) { 51198092Srdivacky // In gcc, only ARM checks this, but it seems reasonable to check universally. 52198092Srdivacky if (Args.hasArg(options::OPT_static)) 53198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_dynamic, 54198092Srdivacky options::OPT_mdynamic_no_pic)) 55198092Srdivacky D.Diag(clang::diag::err_drv_argument_not_allowed_with) 56198092Srdivacky << A->getAsString(Args) << "-static"; 57198092Srdivacky} 58198092Srdivacky 59206084Srdivacky// Quote target names for inclusion in GNU Make dependency files. 60206084Srdivacky// Only the characters '$', '#', ' ', '\t' are quoted. 61206084Srdivackystatic void QuoteTarget(llvm::StringRef Target, 62206084Srdivacky llvm::SmallVectorImpl<char> &Res) { 63206084Srdivacky for (unsigned i = 0, e = Target.size(); i != e; ++i) { 64206084Srdivacky switch (Target[i]) { 65206084Srdivacky case ' ': 66206084Srdivacky case '\t': 67206084Srdivacky // Escape the preceding backslashes 68206084Srdivacky for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j) 69206084Srdivacky Res.push_back('\\'); 70206084Srdivacky 71206084Srdivacky // Escape the space/tab 72206084Srdivacky Res.push_back('\\'); 73206084Srdivacky break; 74206084Srdivacky case '$': 75206084Srdivacky Res.push_back('$'); 76206084Srdivacky break; 77206084Srdivacky case '#': 78206084Srdivacky Res.push_back('\\'); 79206084Srdivacky break; 80206084Srdivacky default: 81206084Srdivacky break; 82206084Srdivacky } 83206084Srdivacky 84206084Srdivacky Res.push_back(Target[i]); 85206084Srdivacky } 86206084Srdivacky} 87206084Srdivacky 88198092Srdivackyvoid Clang::AddPreprocessingOptions(const Driver &D, 89193326Sed const ArgList &Args, 90193326Sed ArgStringList &CmdArgs, 91193326Sed const InputInfo &Output, 92193326Sed const InputInfoList &Inputs) const { 93194179Sed Arg *A; 94194179Sed 95198092Srdivacky CheckPreprocessingOptions(D, Args); 96194179Sed 97198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_C); 98198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_CC); 99198092Srdivacky 100193326Sed // Handle dependency file generation. 101193326Sed if ((A = Args.getLastArg(options::OPT_M)) || 102193326Sed (A = Args.getLastArg(options::OPT_MM)) || 103193326Sed (A = Args.getLastArg(options::OPT_MD)) || 104193326Sed (A = Args.getLastArg(options::OPT_MMD))) { 105193326Sed // Determine the output location. 106193326Sed const char *DepFile; 107193326Sed if (Output.getType() == types::TY_Dependencies) { 108193326Sed if (Output.isPipe()) 109193326Sed DepFile = "-"; 110193326Sed else 111193326Sed DepFile = Output.getFilename(); 112193326Sed } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) { 113193326Sed DepFile = MF->getValue(Args); 114199512Srdivacky } else if (A->getOption().matches(options::OPT_M) || 115199512Srdivacky A->getOption().matches(options::OPT_MM)) { 116193326Sed DepFile = "-"; 117193326Sed } else { 118193326Sed DepFile = darwin::CC1::getDependencyFileName(Args, Inputs); 119193326Sed } 120193326Sed CmdArgs.push_back("-dependency-file"); 121193326Sed CmdArgs.push_back(DepFile); 122193326Sed 123206084Srdivacky // Add a default target if one wasn't specified. 124193326Sed if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) { 125193326Sed const char *DepTarget; 126193326Sed 127193326Sed // If user provided -o, that is the dependency target, except 128193326Sed // when we are only generating a dependency file. 129193326Sed Arg *OutputOpt = Args.getLastArg(options::OPT_o); 130193326Sed if (OutputOpt && Output.getType() != types::TY_Dependencies) { 131193326Sed DepTarget = OutputOpt->getValue(Args); 132193326Sed } else { 133193326Sed // Otherwise derive from the base input. 134193326Sed // 135193326Sed // FIXME: This should use the computed output file location. 136193326Sed llvm::sys::Path P(Inputs[0].getBaseInput()); 137193326Sed 138193326Sed P.eraseSuffix(); 139193326Sed P.appendSuffix("o"); 140198092Srdivacky DepTarget = Args.MakeArgString(P.getLast()); 141193326Sed } 142193326Sed 143193326Sed CmdArgs.push_back("-MT"); 144206084Srdivacky llvm::SmallString<128> Quoted; 145206084Srdivacky QuoteTarget(DepTarget, Quoted); 146206084Srdivacky CmdArgs.push_back(Args.MakeArgString(Quoted)); 147193326Sed } 148193326Sed 149199512Srdivacky if (A->getOption().matches(options::OPT_M) || 150199512Srdivacky A->getOption().matches(options::OPT_MD)) 151193326Sed CmdArgs.push_back("-sys-header-deps"); 152193326Sed } 153193326Sed 154193326Sed Args.AddLastArg(CmdArgs, options::OPT_MP); 155193326Sed 156206084Srdivacky // Convert all -MQ <target> args to -MT <quoted target> 157206084Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_MT, 158206084Srdivacky options::OPT_MQ), 159206084Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 160206084Srdivacky 161206084Srdivacky it->claim(); 162206084Srdivacky 163206084Srdivacky if (it->getOption().matches(options::OPT_MQ)) { 164206084Srdivacky CmdArgs.push_back("-MT"); 165206084Srdivacky llvm::SmallString<128> Quoted; 166206084Srdivacky QuoteTarget(it->getValue(Args), Quoted); 167206084Srdivacky CmdArgs.push_back(Args.MakeArgString(Quoted)); 168206084Srdivacky 169206084Srdivacky // -MT flag - no change 170206084Srdivacky } else { 171206084Srdivacky it->render(Args, CmdArgs); 172206084Srdivacky } 173206084Srdivacky } 174206084Srdivacky 175193326Sed // Add -i* options, and automatically translate to 176193326Sed // -include-pch/-include-pth for transparent PCH support. It's 177193326Sed // wonky, but we include looking for .gch so we can support seamless 178193326Sed // replacement into a build system already set up to be generating 179193326Sed // .gch files. 180199990Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group), 181199990Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 182199990Srdivacky const Arg *A = it; 183193326Sed 184193326Sed if (A->getOption().matches(options::OPT_include)) { 185198398Srdivacky // Use PCH if the user requested it, except for C++ (for now). 186198398Srdivacky bool UsePCH = D.CCCUsePCH; 187198398Srdivacky if (types::isCXX(Inputs[0].getType())) 188198398Srdivacky UsePCH = false; 189198398Srdivacky 190193326Sed bool FoundPTH = false; 191193326Sed bool FoundPCH = false; 192193326Sed llvm::sys::Path P(A->getValue(Args)); 193198398Srdivacky if (UsePCH) { 194193326Sed P.appendSuffix("pch"); 195193326Sed if (P.exists()) 196193326Sed FoundPCH = true; 197198092Srdivacky else 198193326Sed P.eraseSuffix(); 199193326Sed } 200193326Sed 201193326Sed if (!FoundPCH) { 202193326Sed P.appendSuffix("pth"); 203198092Srdivacky if (P.exists()) 204193326Sed FoundPTH = true; 205193326Sed else 206193326Sed P.eraseSuffix(); 207198092Srdivacky } 208198092Srdivacky 209193326Sed if (!FoundPCH && !FoundPTH) { 210193326Sed P.appendSuffix("gch"); 211193326Sed if (P.exists()) { 212198398Srdivacky FoundPCH = UsePCH; 213198398Srdivacky FoundPTH = !UsePCH; 214193326Sed } 215198092Srdivacky else 216193326Sed P.eraseSuffix(); 217193326Sed } 218193326Sed 219193326Sed if (FoundPCH || FoundPTH) { 220193326Sed A->claim(); 221198398Srdivacky if (UsePCH) 222193326Sed CmdArgs.push_back("-include-pch"); 223193326Sed else 224193326Sed CmdArgs.push_back("-include-pth"); 225198092Srdivacky CmdArgs.push_back(Args.MakeArgString(P.str())); 226193326Sed continue; 227193326Sed } 228193326Sed } 229193326Sed 230193326Sed // Not translated, render as usual. 231193326Sed A->claim(); 232193326Sed A->render(Args, CmdArgs); 233193326Sed } 234193326Sed 235193326Sed Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); 236193326Sed Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F); 237193326Sed 238193326Sed // Add -Wp, and -Xassembler if using the preprocessor. 239193326Sed 240193326Sed // FIXME: There is a very unfortunate problem here, some troubled 241193326Sed // souls abuse -Wp, to pass preprocessor options in gcc syntax. To 242193326Sed // really support that we would have to parse and then translate 243193326Sed // those options. :( 244193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, 245193326Sed options::OPT_Xpreprocessor); 246198893Srdivacky 247198893Srdivacky // -I- is a deprecated GCC feature, reject it. 248198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_I_)) 249198893Srdivacky D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args); 250193326Sed} 251193326Sed 252198092Srdivacky/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting. 253198092Srdivacky// 254198092Srdivacky// FIXME: tblgen this. 255199990Srdivackystatic const char *getARMTargetCPU(const ArgList &Args) { 256198092Srdivacky // FIXME: Warn on inconsistent use of -mcpu and -march. 257198092Srdivacky 258198092Srdivacky // If we have -mcpu=, use that. 259198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 260198092Srdivacky return A->getValue(Args); 261198092Srdivacky 262198092Srdivacky // Otherwise, if we have -march= choose the base CPU for that arch. 263198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 264198092Srdivacky llvm::StringRef MArch = A->getValue(Args); 265198092Srdivacky 266198092Srdivacky if (MArch == "armv2" || MArch == "armv2a") 267198092Srdivacky return "arm2"; 268198092Srdivacky if (MArch == "armv3") 269198092Srdivacky return "arm6"; 270198092Srdivacky if (MArch == "armv3m") 271198092Srdivacky return "arm7m"; 272198092Srdivacky if (MArch == "armv4" || MArch == "armv4t") 273198092Srdivacky return "arm7tdmi"; 274198092Srdivacky if (MArch == "armv5" || MArch == "armv5t") 275198092Srdivacky return "arm10tdmi"; 276198092Srdivacky if (MArch == "armv5e" || MArch == "armv5te") 277198092Srdivacky return "arm1026ejs"; 278198092Srdivacky if (MArch == "armv5tej") 279201361Srdivacky return "arm926ej-s"; 280198092Srdivacky if (MArch == "armv6" || MArch == "armv6k") 281198092Srdivacky return "arm1136jf-s"; 282198092Srdivacky if (MArch == "armv6j") 283198092Srdivacky return "arm1136j-s"; 284198092Srdivacky if (MArch == "armv6z" || MArch == "armv6zk") 285198092Srdivacky return "arm1176jzf-s"; 286198092Srdivacky if (MArch == "armv6t2") 287198092Srdivacky return "arm1156t2-s"; 288198092Srdivacky if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") 289198092Srdivacky return "cortex-a8"; 290198092Srdivacky if (MArch == "armv7r" || MArch == "armv7-r") 291198092Srdivacky return "cortex-r4"; 292198092Srdivacky if (MArch == "armv7m" || MArch == "armv7-m") 293198092Srdivacky return "cortex-m3"; 294198092Srdivacky if (MArch == "ep9312") 295198092Srdivacky return "ep9312"; 296198092Srdivacky if (MArch == "iwmmxt") 297198092Srdivacky return "iwmmxt"; 298198092Srdivacky if (MArch == "xscale") 299198092Srdivacky return "xscale"; 300198092Srdivacky } 301198092Srdivacky 302198092Srdivacky // Otherwise return the most base CPU LLVM supports. 303198092Srdivacky return "arm7tdmi"; 304198092Srdivacky} 305198092Srdivacky 306198092Srdivacky/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 307198092Srdivacky/// CPU. 308198092Srdivacky// 309198092Srdivacky// FIXME: This is redundant with -mcpu, why does LLVM use this. 310198092Srdivacky// FIXME: tblgen this, or kill it! 311198092Srdivackystatic const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) { 312198092Srdivacky if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" || 313198092Srdivacky CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" || 314198092Srdivacky CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" || 315198092Srdivacky CPU == "arm940t" || CPU == "ep9312") 316198092Srdivacky return "v4t"; 317198092Srdivacky 318198092Srdivacky if (CPU == "arm10tdmi" || CPU == "arm1020t") 319198092Srdivacky return "v5"; 320198092Srdivacky 321198092Srdivacky if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" || 322198092Srdivacky CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" || 323198092Srdivacky CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" || 324198092Srdivacky CPU == "iwmmxt") 325198092Srdivacky return "v5e"; 326198092Srdivacky 327198092Srdivacky if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" || 328198092Srdivacky CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore") 329198092Srdivacky return "v6"; 330198092Srdivacky 331198092Srdivacky if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s") 332198092Srdivacky return "v6t2"; 333198092Srdivacky 334198092Srdivacky if (CPU == "cortex-a8" || CPU == "cortex-a9") 335198092Srdivacky return "v7"; 336198092Srdivacky 337198092Srdivacky return ""; 338198092Srdivacky} 339198092Srdivacky 340198092Srdivacky/// getLLVMTriple - Get the LLVM triple to use for a particular toolchain, which 341198092Srdivacky/// may depend on command line arguments. 342198092Srdivackystatic std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) { 343198092Srdivacky switch (TC.getTriple().getArch()) { 344198092Srdivacky default: 345198092Srdivacky return TC.getTripleString(); 346198092Srdivacky 347198092Srdivacky case llvm::Triple::arm: 348198092Srdivacky case llvm::Triple::thumb: { 349198092Srdivacky // FIXME: Factor into subclasses. 350198092Srdivacky llvm::Triple Triple = TC.getTriple(); 351198092Srdivacky 352198092Srdivacky // Thumb2 is the default for V7 on Darwin. 353198092Srdivacky // 354198092Srdivacky // FIXME: Thumb should just be another -target-feaure, not in the triple. 355198092Srdivacky llvm::StringRef Suffix = getLLVMArchSuffixForARM(getARMTargetCPU(Args)); 356198092Srdivacky bool ThumbDefault = 357198092Srdivacky (Suffix == "v7" && TC.getTriple().getOS() == llvm::Triple::Darwin); 358198092Srdivacky std::string ArchName = "arm"; 359198092Srdivacky if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) 360198092Srdivacky ArchName = "thumb"; 361198092Srdivacky Triple.setArchName(ArchName + Suffix.str()); 362198092Srdivacky 363198092Srdivacky return Triple.getTriple(); 364198092Srdivacky } 365198092Srdivacky } 366198092Srdivacky} 367198092Srdivacky 368199482Srdivacky// FIXME: Move to target hook. 369199482Srdivackystatic bool isSignedCharDefault(const llvm::Triple &Triple) { 370199482Srdivacky switch (Triple.getArch()) { 371199482Srdivacky default: 372199482Srdivacky return true; 373199482Srdivacky 374199482Srdivacky case llvm::Triple::ppc: 375199482Srdivacky case llvm::Triple::ppc64: 376199482Srdivacky if (Triple.getOS() == llvm::Triple::Darwin) 377199482Srdivacky return true; 378199482Srdivacky return false; 379199482Srdivacky 380199482Srdivacky case llvm::Triple::systemz: 381199482Srdivacky return false; 382199482Srdivacky } 383199482Srdivacky} 384199482Srdivacky 385198092Srdivackyvoid Clang::AddARMTargetArgs(const ArgList &Args, 386198092Srdivacky ArgStringList &CmdArgs) const { 387201361Srdivacky const Driver &D = getToolChain().getDriver(); 388198092Srdivacky 389198092Srdivacky // Select the ABI to use. 390198092Srdivacky // 391198092Srdivacky // FIXME: Support -meabi. 392198092Srdivacky const char *ABIName = 0; 393198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 394198092Srdivacky ABIName = A->getValue(Args); 395198092Srdivacky } else { 396198092Srdivacky // Select the default based on the platform. 397198092Srdivacky switch (getToolChain().getTriple().getOS()) { 398198092Srdivacky // FIXME: Is this right for non-Darwin and non-Linux? 399198092Srdivacky default: 400198092Srdivacky ABIName = "aapcs"; 401198092Srdivacky break; 402198092Srdivacky 403198092Srdivacky case llvm::Triple::Darwin: 404198092Srdivacky ABIName = "apcs-gnu"; 405198092Srdivacky break; 406198092Srdivacky 407198092Srdivacky case llvm::Triple::Linux: 408198092Srdivacky ABIName = "aapcs-linux"; 409198092Srdivacky break; 410198092Srdivacky } 411198092Srdivacky } 412198092Srdivacky CmdArgs.push_back("-target-abi"); 413198092Srdivacky CmdArgs.push_back(ABIName); 414198092Srdivacky 415198092Srdivacky // Set the CPU based on -march= and -mcpu=. 416201361Srdivacky CmdArgs.push_back("-target-cpu"); 417199990Srdivacky CmdArgs.push_back(getARMTargetCPU(Args)); 418198092Srdivacky 419198092Srdivacky // Select the float ABI as determined by -msoft-float, -mhard-float, and 420198092Srdivacky // -mfloat-abi=. 421198092Srdivacky llvm::StringRef FloatABI; 422198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 423198092Srdivacky options::OPT_mhard_float, 424198092Srdivacky options::OPT_mfloat_abi_EQ)) { 425198092Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 426198092Srdivacky FloatABI = "soft"; 427198092Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 428198092Srdivacky FloatABI = "hard"; 429198092Srdivacky else { 430198092Srdivacky FloatABI = A->getValue(Args); 431198092Srdivacky if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") { 432198092Srdivacky D.Diag(clang::diag::err_drv_invalid_mfloat_abi) 433198092Srdivacky << A->getAsString(Args); 434198092Srdivacky FloatABI = "soft"; 435198092Srdivacky } 436198092Srdivacky } 437198092Srdivacky } 438198092Srdivacky 439198092Srdivacky // If unspecified, choose the default based on the platform. 440198092Srdivacky if (FloatABI.empty()) { 441198092Srdivacky // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for 442198092Srdivacky // distinguishing things like linux-eabi vs linux-elf. 443198092Srdivacky switch (getToolChain().getTriple().getOS()) { 444198092Srdivacky case llvm::Triple::Darwin: { 445198092Srdivacky // Darwin defaults to "softfp" for v6 and v7. 446198092Srdivacky // 447198092Srdivacky // FIXME: Factor out an ARM class so we can cache the arch somewhere. 448198092Srdivacky llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args)); 449198092Srdivacky if (ArchName.startswith("v6") || ArchName.startswith("v7")) 450198092Srdivacky FloatABI = "softfp"; 451198092Srdivacky else 452198092Srdivacky FloatABI = "soft"; 453198092Srdivacky break; 454198092Srdivacky } 455198092Srdivacky 456198092Srdivacky default: 457198092Srdivacky // Assume "soft", but warn the user we are guessing. 458198092Srdivacky FloatABI = "soft"; 459198092Srdivacky D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 460198092Srdivacky break; 461198092Srdivacky } 462198092Srdivacky } 463198092Srdivacky 464198092Srdivacky if (FloatABI == "soft") { 465198092Srdivacky // Floating point operations and argument passing are soft. 466198092Srdivacky // 467198092Srdivacky // FIXME: This changes CPP defines, we need -target-soft-float. 468199990Srdivacky CmdArgs.push_back("-msoft-float"); 469200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 470200583Srdivacky CmdArgs.push_back("soft"); 471198092Srdivacky } else if (FloatABI == "softfp") { 472198092Srdivacky // Floating point operations are hard, but argument passing is soft. 473200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 474200583Srdivacky CmdArgs.push_back("soft"); 475198092Srdivacky } else { 476198092Srdivacky // Floating point operations and argument passing are hard. 477198092Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 478200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 479200583Srdivacky CmdArgs.push_back("hard"); 480198092Srdivacky } 481201361Srdivacky 482201361Srdivacky // Set appropriate target features for floating point mode. 483201361Srdivacky // 484201361Srdivacky // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these 485201361Srdivacky // yet (it uses the -mfloat-abi and -msoft-float options above), and it is 486201361Srdivacky // stripped out by the ARM target. 487201361Srdivacky 488201361Srdivacky // Use software floating point operations? 489201361Srdivacky if (FloatABI == "soft") { 490201361Srdivacky CmdArgs.push_back("-target-feature"); 491201361Srdivacky CmdArgs.push_back("+soft-float"); 492201361Srdivacky } 493201361Srdivacky 494201361Srdivacky // Use software floating point argument passing? 495201361Srdivacky if (FloatABI != "hard") { 496201361Srdivacky CmdArgs.push_back("-target-feature"); 497201361Srdivacky CmdArgs.push_back("+soft-float-abi"); 498201361Srdivacky } 499201361Srdivacky 500201361Srdivacky // Honor -mfpu=. 501201361Srdivacky // 502201361Srdivacky // FIXME: Centralize feature selection, defaulting shouldn't be also in the 503201361Srdivacky // frontend target. 504201361Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) { 505201361Srdivacky llvm::StringRef FPU = A->getValue(Args); 506201361Srdivacky 507201361Srdivacky // Set the target features based on the FPU. 508201361Srdivacky if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") { 509201361Srdivacky // Disable any default FPU support. 510201361Srdivacky CmdArgs.push_back("-target-feature"); 511201361Srdivacky CmdArgs.push_back("-vfp2"); 512201361Srdivacky CmdArgs.push_back("-target-feature"); 513201361Srdivacky CmdArgs.push_back("-vfp3"); 514201361Srdivacky CmdArgs.push_back("-target-feature"); 515201361Srdivacky CmdArgs.push_back("-neon"); 516201361Srdivacky } else if (FPU == "vfp") { 517201361Srdivacky CmdArgs.push_back("-target-feature"); 518201361Srdivacky CmdArgs.push_back("+vfp2"); 519201361Srdivacky } else if (FPU == "vfp3") { 520201361Srdivacky CmdArgs.push_back("-target-feature"); 521201361Srdivacky CmdArgs.push_back("+vfp3"); 522201361Srdivacky } else if (FPU == "neon") { 523201361Srdivacky CmdArgs.push_back("-target-feature"); 524201361Srdivacky CmdArgs.push_back("+neon"); 525201361Srdivacky } else 526201361Srdivacky D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 527201361Srdivacky } 528198092Srdivacky} 529198092Srdivacky 530204643Srdivackyvoid Clang::AddMIPSTargetArgs(const ArgList &Args, 531204643Srdivacky ArgStringList &CmdArgs) const { 532204643Srdivacky const Driver &D = getToolChain().getDriver(); 533204643Srdivacky 534204643Srdivacky // Select the ABI to use. 535204643Srdivacky const char *ABIName = 0; 536204643Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 537204643Srdivacky ABIName = A->getValue(Args); 538204643Srdivacky } else { 539204643Srdivacky ABIName = "o32"; 540204643Srdivacky } 541204643Srdivacky 542204643Srdivacky CmdArgs.push_back("-target-abi"); 543204643Srdivacky CmdArgs.push_back(ABIName); 544204643Srdivacky 545204643Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 546204643Srdivacky llvm::StringRef MArch = A->getValue(Args); 547204643Srdivacky CmdArgs.push_back("-target-cpu"); 548204643Srdivacky 549204643Srdivacky if ((MArch == "r2000") || (MArch == "r3000")) 550204643Srdivacky CmdArgs.push_back("mips1"); 551204643Srdivacky else if (MArch == "r6000") 552204643Srdivacky CmdArgs.push_back("mips2"); 553204643Srdivacky else 554204643Srdivacky CmdArgs.push_back(MArch.str().c_str()); 555204643Srdivacky } 556204643Srdivacky 557204643Srdivacky // Select the float ABI as determined by -msoft-float, -mhard-float, and 558204643Srdivacky llvm::StringRef FloatABI; 559204643Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 560204643Srdivacky options::OPT_mhard_float)) { 561204643Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 562204643Srdivacky FloatABI = "soft"; 563204643Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 564204643Srdivacky FloatABI = "hard"; 565204643Srdivacky } 566204643Srdivacky 567204643Srdivacky // If unspecified, choose the default based on the platform. 568204643Srdivacky if (FloatABI.empty()) { 569207619Srdivacky // Assume "soft", but warn the user we are guessing. 570207619Srdivacky FloatABI = "soft"; 571207619Srdivacky D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 572204643Srdivacky } 573204643Srdivacky 574204643Srdivacky if (FloatABI == "soft") { 575204643Srdivacky // Floating point operations and argument passing are soft. 576204643Srdivacky // 577204643Srdivacky // FIXME: This changes CPP defines, we need -target-soft-float. 578204643Srdivacky CmdArgs.push_back("-msoft-float"); 579204643Srdivacky } else { 580204643Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 581204643Srdivacky CmdArgs.push_back("-mhard-float"); 582204643Srdivacky } 583204643Srdivacky} 584204643Srdivacky 585198092Srdivackyvoid Clang::AddX86TargetArgs(const ArgList &Args, 586198092Srdivacky ArgStringList &CmdArgs) const { 587198092Srdivacky if (!Args.hasFlag(options::OPT_mred_zone, 588198092Srdivacky options::OPT_mno_red_zone, 589198092Srdivacky true) || 590198092Srdivacky Args.hasArg(options::OPT_mkernel) || 591198092Srdivacky Args.hasArg(options::OPT_fapple_kext)) 592199990Srdivacky CmdArgs.push_back("-disable-red-zone"); 593198092Srdivacky 594198092Srdivacky if (Args.hasFlag(options::OPT_msoft_float, 595198092Srdivacky options::OPT_mno_soft_float, 596198092Srdivacky false)) 597199990Srdivacky CmdArgs.push_back("-no-implicit-float"); 598198092Srdivacky 599199482Srdivacky const char *CPUName = 0; 600198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 601199482Srdivacky if (llvm::StringRef(A->getValue(Args)) == "native") { 602199482Srdivacky // FIXME: Reject attempts to use -march=native unless the target matches 603199482Srdivacky // the host. 604199482Srdivacky // 605199482Srdivacky // FIXME: We should also incorporate the detected target features for use 606199482Srdivacky // with -native. 607199482Srdivacky std::string CPU = llvm::sys::getHostCPUName(); 608199482Srdivacky if (!CPU.empty()) 609199482Srdivacky CPUName = Args.MakeArgString(CPU); 610199482Srdivacky } else 611199482Srdivacky CPUName = A->getValue(Args); 612199482Srdivacky } 613198092Srdivacky 614199482Srdivacky // Select the default CPU if none was given (or detection failed). 615199482Srdivacky if (!CPUName) { 616198092Srdivacky // FIXME: Need target hooks. 617203955Srdivacky if (getToolChain().getOS().startswith("darwin")) { 618198092Srdivacky if (getToolChain().getArchName() == "x86_64") 619199482Srdivacky CPUName = "core2"; 620198092Srdivacky else if (getToolChain().getArchName() == "i386") 621199482Srdivacky CPUName = "yonah"; 622207619Srdivacky } else if (getToolChain().getOS().startswith("haiku")) { 623207619Srdivacky if (getToolChain().getArchName() == "x86_64") 624207619Srdivacky CPUName = "x86-64"; 625207619Srdivacky else if (getToolChain().getArchName() == "i386") 626207619Srdivacky CPUName = "i586"; 627198092Srdivacky } else { 628198092Srdivacky if (getToolChain().getArchName() == "x86_64") 629199482Srdivacky CPUName = "x86-64"; 630198092Srdivacky else if (getToolChain().getArchName() == "i386") 631199482Srdivacky CPUName = "pentium4"; 632198092Srdivacky } 633198092Srdivacky } 634198092Srdivacky 635199482Srdivacky if (CPUName) { 636201361Srdivacky CmdArgs.push_back("-target-cpu"); 637199482Srdivacky CmdArgs.push_back(CPUName); 638199482Srdivacky } 639199482Srdivacky 640199990Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group), 641199990Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 642199990Srdivacky llvm::StringRef Name = it->getOption().getName(); 643199990Srdivacky it->claim(); 644198092Srdivacky 645199990Srdivacky // Skip over "-m". 646199990Srdivacky assert(Name.startswith("-m") && "Invalid feature name."); 647199990Srdivacky Name = Name.substr(2); 648198092Srdivacky 649199990Srdivacky bool IsNegative = Name.startswith("no-"); 650199990Srdivacky if (IsNegative) 651199990Srdivacky Name = Name.substr(3); 652198092Srdivacky 653199990Srdivacky CmdArgs.push_back("-target-feature"); 654199990Srdivacky CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); 655198092Srdivacky } 656198092Srdivacky} 657198092Srdivacky 658198092Srdivackystatic bool needsExceptions(const ArgList &Args, types::ID InputType, 659198092Srdivacky const llvm::Triple &Triple) { 660198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fexceptions, 661198092Srdivacky options::OPT_fno_exceptions)) { 662198092Srdivacky if (A->getOption().matches(options::OPT_fexceptions)) 663198092Srdivacky return true; 664198092Srdivacky else 665198092Srdivacky return false; 666198092Srdivacky } 667198092Srdivacky switch (InputType) { 668198092Srdivacky case types::TY_CXX: case types::TY_CXXHeader: 669198092Srdivacky case types::TY_PP_CXX: case types::TY_PP_CXXHeader: 670198092Srdivacky case types::TY_ObjCXX: case types::TY_ObjCXXHeader: 671198092Srdivacky case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader: 672198092Srdivacky return true; 673198092Srdivacky 674198092Srdivacky case types::TY_ObjC: case types::TY_ObjCHeader: 675198092Srdivacky case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader: 676198092Srdivacky if (Args.hasArg(options::OPT_fobjc_nonfragile_abi)) 677198092Srdivacky return true; 678198092Srdivacky if (Triple.getOS() != llvm::Triple::Darwin) 679198092Srdivacky return false; 680198092Srdivacky return (Triple.getDarwinMajorNumber() >= 9 && 681198092Srdivacky Triple.getArch() == llvm::Triple::x86_64); 682198092Srdivacky 683198092Srdivacky default: 684198092Srdivacky return false; 685198092Srdivacky } 686198092Srdivacky} 687198092Srdivacky 688198893Srdivacky/// getEffectiveClangTriple - Get the "effective" target triple, which is the 689198893Srdivacky/// triple for the target but with the OS version potentially modified for 690198893Srdivacky/// Darwin's -mmacosx-version-min. 691198893Srdivackystatic std::string getEffectiveClangTriple(const Driver &D, 692198893Srdivacky const ToolChain &TC, 693198893Srdivacky const ArgList &Args) { 694198893Srdivacky llvm::Triple Triple(getLLVMTriple(TC, Args)); 695198893Srdivacky 696203955Srdivacky // Handle -mmacosx-version-min and -miphoneos-version-min. 697198893Srdivacky if (Triple.getOS() != llvm::Triple::Darwin) { 698198893Srdivacky // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on 699198893Srdivacky // non-Darwin. 700198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, 701198893Srdivacky options::OPT_miphoneos_version_min_EQ)) 702198893Srdivacky D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 703203955Srdivacky } else { 704203955Srdivacky const toolchains::Darwin &DarwinTC( 705203955Srdivacky reinterpret_cast<const toolchains::Darwin&>(TC)); 706205408Srdivacky 707205408Srdivacky // If the target isn't initialized (e.g., an unknown Darwin platform, return 708205408Srdivacky // the default triple). 709205408Srdivacky if (!DarwinTC.isTargetInitialized()) 710205408Srdivacky return Triple.getTriple(); 711205408Srdivacky 712203955Srdivacky unsigned Version[3]; 713203955Srdivacky DarwinTC.getTargetVersion(Version); 714198893Srdivacky 715203955Srdivacky // Mangle the target version into the OS triple component. For historical 716203955Srdivacky // reasons that make little sense, the version passed here is the "darwin" 717203955Srdivacky // version, which drops the 10 and offsets by 4. See inverse code when 718203955Srdivacky // setting the OS version preprocessor define. 719203955Srdivacky if (!DarwinTC.isTargetIPhoneOS()) { 720203955Srdivacky Version[0] = Version[1] + 4; 721203955Srdivacky Version[1] = Version[2]; 722203955Srdivacky Version[2] = 0; 723203955Srdivacky } else { 724203955Srdivacky // Use the environment to communicate that we are targetting iPhoneOS. 725203955Srdivacky Triple.setEnvironmentName("iphoneos"); 726203955Srdivacky } 727198893Srdivacky 728198893Srdivacky llvm::SmallString<16> Str; 729203955Srdivacky llvm::raw_svector_ostream(Str) << "darwin" << Version[0] 730203955Srdivacky << "." << Version[1] << "." << Version[2]; 731198893Srdivacky Triple.setOSName(Str.str()); 732198893Srdivacky } 733198893Srdivacky 734198893Srdivacky return Triple.getTriple(); 735198893Srdivacky} 736198893Srdivacky 737193326Sedvoid Clang::ConstructJob(Compilation &C, const JobAction &JA, 738193326Sed Job &Dest, 739193326Sed const InputInfo &Output, 740193326Sed const InputInfoList &Inputs, 741193326Sed const ArgList &Args, 742193326Sed const char *LinkingOutput) const { 743205408Srdivacky bool KernelOrKext = Args.hasArg(options::OPT_mkernel, 744205408Srdivacky options::OPT_fapple_kext); 745201361Srdivacky const Driver &D = getToolChain().getDriver(); 746193326Sed ArgStringList CmdArgs; 747193326Sed 748193326Sed assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 749193326Sed 750200583Srdivacky // Invoke ourselves in -cc1 mode. 751200583Srdivacky // 752200583Srdivacky // FIXME: Implement custom jobs for internal actions. 753200583Srdivacky CmdArgs.push_back("-cc1"); 754200583Srdivacky 755198893Srdivacky // Add the "effective" target triple. 756193326Sed CmdArgs.push_back("-triple"); 757198893Srdivacky std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); 758198893Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 759198092Srdivacky 760198893Srdivacky // Select the appropriate action. 761193326Sed if (isa<AnalyzeJobAction>(JA)) { 762193326Sed assert(JA.getType() == types::TY_Plist && "Invalid output type."); 763193326Sed CmdArgs.push_back("-analyze"); 764193326Sed } else if (isa<PreprocessJobAction>(JA)) { 765193326Sed if (Output.getType() == types::TY_Dependencies) 766193326Sed CmdArgs.push_back("-Eonly"); 767193326Sed else 768193326Sed CmdArgs.push_back("-E"); 769203955Srdivacky } else if (isa<AssembleJobAction>(JA)) { 770203955Srdivacky CmdArgs.push_back("-emit-obj"); 771208600Srdivacky 772208600Srdivacky // At -O0, we use -mrelax-all by default. 773208600Srdivacky bool IsOpt = false; 774208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 775208600Srdivacky IsOpt = !A->getOption().matches(options::OPT_O0); 776208600Srdivacky if (Args.hasFlag(options::OPT_mrelax_all, 777208600Srdivacky options::OPT_mno_relax_all, 778208600Srdivacky !IsOpt)) 779208600Srdivacky CmdArgs.push_back("-mrelax-all"); 780193326Sed } else if (isa<PrecompileJobAction>(JA)) { 781198398Srdivacky // Use PCH if the user requested it, except for C++ (for now). 782198398Srdivacky bool UsePCH = D.CCCUsePCH; 783198398Srdivacky if (types::isCXX(Inputs[0].getType())) 784198398Srdivacky UsePCH = false; 785198398Srdivacky 786198398Srdivacky if (UsePCH) 787193326Sed CmdArgs.push_back("-emit-pch"); 788193326Sed else 789193326Sed CmdArgs.push_back("-emit-pth"); 790193326Sed } else { 791193326Sed assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool."); 792193326Sed 793193326Sed if (JA.getType() == types::TY_Nothing) { 794193326Sed CmdArgs.push_back("-fsyntax-only"); 795193326Sed } else if (JA.getType() == types::TY_LLVMAsm) { 796193326Sed CmdArgs.push_back("-emit-llvm"); 797193326Sed } else if (JA.getType() == types::TY_LLVMBC) { 798193326Sed CmdArgs.push_back("-emit-llvm-bc"); 799193326Sed } else if (JA.getType() == types::TY_PP_Asm) { 800193326Sed CmdArgs.push_back("-S"); 801198092Srdivacky } else if (JA.getType() == types::TY_AST) { 802198092Srdivacky CmdArgs.push_back("-emit-pch"); 803203955Srdivacky } else if (JA.getType() == types::TY_RewrittenObjC) { 804203955Srdivacky CmdArgs.push_back("-rewrite-objc"); 805203955Srdivacky } else { 806203955Srdivacky assert(JA.getType() == types::TY_PP_Asm && 807203955Srdivacky "Unexpected output type!"); 808193326Sed } 809193326Sed } 810193326Sed 811193326Sed // The make clang go fast button. 812193326Sed CmdArgs.push_back("-disable-free"); 813193326Sed 814203955Srdivacky // Disable the verification pass in -asserts builds. 815203955Srdivacky#ifdef NDEBUG 816203955Srdivacky CmdArgs.push_back("-disable-llvm-verifier"); 817203955Srdivacky#endif 818203955Srdivacky 819193326Sed // Set the main file name, so that debug info works even with 820193326Sed // -save-temps. 821193326Sed CmdArgs.push_back("-main-file-name"); 822193326Sed CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs)); 823193326Sed 824193326Sed // Some flags which affect the language (via preprocessor 825193326Sed // defines). See darwin::CC1::AddCPPArgs. 826193326Sed if (Args.hasArg(options::OPT_static)) 827193326Sed CmdArgs.push_back("-static-define"); 828193326Sed 829193326Sed if (isa<AnalyzeJobAction>(JA)) { 830198092Srdivacky // Enable region store model by default. 831198092Srdivacky CmdArgs.push_back("-analyzer-store=region"); 832198092Srdivacky 833200583Srdivacky // Treat blocks as analysis entry points. 834200583Srdivacky CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks"); 835200583Srdivacky 836193326Sed // Add default argument set. 837193326Sed if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) { 838203955Srdivacky CmdArgs.push_back("-analyzer-check-dead-stores"); 839207619Srdivacky // Do not enable the security-syntatic check since it 840207619Srdivacky // it needs to be refined (known issues). 841207619Srdivacky // CmdArgs.push_back("-analyzer-check-security-syntactic"); 842203955Srdivacky CmdArgs.push_back("-analyzer-check-objc-mem"); 843193326Sed CmdArgs.push_back("-analyzer-eagerly-assume"); 844203955Srdivacky CmdArgs.push_back("-analyzer-check-objc-methodsigs"); 845193326Sed // Do not enable the missing -dealloc check. 846203955Srdivacky // '-analyzer-check-objc-missing-dealloc', 847203955Srdivacky CmdArgs.push_back("-analyzer-check-objc-unused-ivars"); 848193326Sed } 849193326Sed 850193326Sed // Set the output format. The default is plist, for (lame) historical 851193326Sed // reasons. 852193326Sed CmdArgs.push_back("-analyzer-output"); 853193326Sed if (Arg *A = Args.getLastArg(options::OPT__analyzer_output)) 854193326Sed CmdArgs.push_back(A->getValue(Args)); 855193326Sed else 856193326Sed CmdArgs.push_back("plist"); 857193326Sed 858206084Srdivacky // Disable the presentation of standard compiler warnings when 859206084Srdivacky // using --analyze. We only want to show static analyzer diagnostics 860206084Srdivacky // or frontend errors. 861206084Srdivacky CmdArgs.push_back("-w"); 862206084Srdivacky 863193326Sed // Add -Xanalyzer arguments when running as analyzer. 864193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer); 865198092Srdivacky } 866198092Srdivacky 867198092Srdivacky CheckCodeGenerationOptions(D, Args); 868198092Srdivacky 869193326Sed // Perform argument translation for LLVM backend. This 870193326Sed // takes some care in reconciling with llvm-gcc. The 871193326Sed // issue is that llvm-gcc translates these options based on 872193326Sed // the values in cc1, whereas we are processing based on 873193326Sed // the driver arguments. 874193326Sed 875193326Sed // This comes from the default translation the driver + cc1 876193326Sed // would do to enable flag_pic. 877193326Sed // 878193326Sed // FIXME: Centralize this code. 879193326Sed bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || 880193326Sed Args.hasArg(options::OPT_fpic) || 881193326Sed Args.hasArg(options::OPT_fPIE) || 882193326Sed Args.hasArg(options::OPT_fpie)); 883193326Sed bool PICDisabled = (Args.hasArg(options::OPT_mkernel) || 884193326Sed Args.hasArg(options::OPT_static)); 885193326Sed const char *Model = getToolChain().GetForcedPicModel(); 886193326Sed if (!Model) { 887193326Sed if (Args.hasArg(options::OPT_mdynamic_no_pic)) 888193326Sed Model = "dynamic-no-pic"; 889193326Sed else if (PICDisabled) 890193326Sed Model = "static"; 891193326Sed else if (PICEnabled) 892193326Sed Model = "pic"; 893193326Sed else 894193326Sed Model = getToolChain().GetDefaultRelocationModel(); 895193326Sed } 896199990Srdivacky if (llvm::StringRef(Model) != "pic") { 897199990Srdivacky CmdArgs.push_back("-mrelocation-model"); 898199990Srdivacky CmdArgs.push_back(Model); 899199990Srdivacky } 900193326Sed 901193326Sed // Infer the __PIC__ value. 902193326Sed // 903193326Sed // FIXME: This isn't quite right on Darwin, which always sets 904193326Sed // __PIC__=2. 905193326Sed if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) { 906199990Srdivacky CmdArgs.push_back("-pic-level"); 907199990Srdivacky CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1"); 908193326Sed } 909199990Srdivacky if (!Args.hasFlag(options::OPT_fmerge_all_constants, 910199990Srdivacky options::OPT_fno_merge_all_constants)) 911199990Srdivacky CmdArgs.push_back("-no-merge-all-constants"); 912193326Sed 913199990Srdivacky // LLVM Code Generator Options. 914199990Srdivacky 915193326Sed // FIXME: Set --enable-unsafe-fp-math. 916198092Srdivacky if (Args.hasFlag(options::OPT_fno_omit_frame_pointer, 917198092Srdivacky options::OPT_fomit_frame_pointer)) 918199990Srdivacky CmdArgs.push_back("-mdisable-fp-elim"); 919193326Sed if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, 920199990Srdivacky options::OPT_fno_zero_initialized_in_bss)) 921199990Srdivacky CmdArgs.push_back("-mno-zero-initialized-in-bss"); 922208600Srdivacky 923208600Srdivacky // Decide whether to use verbose asm. Verbose assembly is the default on 924208600Srdivacky // toolchains which have the integrated assembler on by default. 925208600Srdivacky bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault(); 926208600Srdivacky if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, 927208600Srdivacky IsVerboseAsmDefault) || 928208600Srdivacky Args.hasArg(options::OPT_dA)) 929199990Srdivacky CmdArgs.push_back("-masm-verbose"); 930208600Srdivacky 931199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_structure)) { 932199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 933199990Srdivacky CmdArgs.push_back("Structure"); 934199990Srdivacky } 935199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_arguments)) { 936199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 937199990Srdivacky CmdArgs.push_back("Arguments"); 938199990Srdivacky } 939198092Srdivacky 940204643Srdivacky // Enable -mconstructor-aliases except on darwin, where we have to 941204643Srdivacky // work around a linker bug; see <rdar://problem/7651567>. 942204643Srdivacky if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin) 943204643Srdivacky CmdArgs.push_back("-mconstructor-aliases"); 944204643Srdivacky 945198092Srdivacky // This is a coarse approximation of what llvm-gcc actually does, both 946198092Srdivacky // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more 947198092Srdivacky // complicated ways. 948198092Srdivacky bool AsynchronousUnwindTables = 949198092Srdivacky Args.hasFlag(options::OPT_fasynchronous_unwind_tables, 950198092Srdivacky options::OPT_fno_asynchronous_unwind_tables, 951198092Srdivacky getToolChain().IsUnwindTablesDefault() && 952205408Srdivacky !KernelOrKext); 953198092Srdivacky if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, 954198092Srdivacky AsynchronousUnwindTables)) 955199990Srdivacky CmdArgs.push_back("-munwind-tables"); 956193326Sed 957199990Srdivacky if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { 958199990Srdivacky CmdArgs.push_back("-mlimit-float-precision"); 959199990Srdivacky CmdArgs.push_back(A->getValue(Args)); 960199990Srdivacky } 961199990Srdivacky 962193326Sed // FIXME: Handle -mtune=. 963193326Sed (void) Args.hasArg(options::OPT_mtune_EQ); 964193326Sed 965198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) { 966199990Srdivacky CmdArgs.push_back("-mcode-model"); 967193326Sed CmdArgs.push_back(A->getValue(Args)); 968193326Sed } 969193326Sed 970198092Srdivacky // Add target specific cpu and features flags. 971198092Srdivacky switch(getToolChain().getTriple().getArch()) { 972198092Srdivacky default: 973198092Srdivacky break; 974193326Sed 975198092Srdivacky case llvm::Triple::arm: 976198092Srdivacky case llvm::Triple::thumb: 977198092Srdivacky AddARMTargetArgs(Args, CmdArgs); 978198092Srdivacky break; 979193326Sed 980204643Srdivacky case llvm::Triple::mips: 981204643Srdivacky case llvm::Triple::mipsel: 982204643Srdivacky AddMIPSTargetArgs(Args, CmdArgs); 983204643Srdivacky break; 984204643Srdivacky 985198092Srdivacky case llvm::Triple::x86: 986198092Srdivacky case llvm::Triple::x86_64: 987198092Srdivacky AddX86TargetArgs(Args, CmdArgs); 988198092Srdivacky break; 989193326Sed } 990193326Sed 991202379Srdivacky // -fno-math-errno is default. 992202379Srdivacky if (Args.hasFlag(options::OPT_fmath_errno, 993193326Sed options::OPT_fno_math_errno, 994202379Srdivacky false)) 995202379Srdivacky CmdArgs.push_back("-fmath-errno"); 996193326Sed 997208600Srdivacky // Explicitly error on some things we know we don't support and can't just 998208600Srdivacky // ignore. 999208600Srdivacky types::ID InputType = Inputs[0].getType(); 1000193326Sed Arg *Unsupported; 1001193326Sed if ((Unsupported = Args.getLastArg(options::OPT_MG)) || 1002200583Srdivacky (Unsupported = Args.getLastArg(options::OPT_iframework)) || 1003200583Srdivacky (Unsupported = Args.getLastArg(options::OPT_fshort_enums))) 1004193326Sed D.Diag(clang::diag::err_drv_clang_unsupported) 1005193326Sed << Unsupported->getOption().getName(); 1006193326Sed 1007208600Srdivacky if (types::isCXX(InputType) && 1008208600Srdivacky getToolChain().getTriple().getOS() == llvm::Triple::Darwin && 1009208600Srdivacky getToolChain().getTriple().getArch() == llvm::Triple::x86) { 1010208600Srdivacky if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext))) 1011208600Srdivacky D.Diag(clang::diag::err_drv_clang_unsupported_opt_cxx_darwin_i386) 1012208600Srdivacky << Unsupported->getOption().getName(); 1013208600Srdivacky } 1014208600Srdivacky 1015193326Sed Args.AddAllArgs(CmdArgs, options::OPT_v); 1016193326Sed Args.AddLastArg(CmdArgs, options::OPT_P); 1017198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); 1018193326Sed 1019193326Sed // Special case debug options to only pass -g to clang. This is 1020193326Sed // wrong. 1021204962Srdivacky Args.ClaimAllArgs(options::OPT_g_Group); 1022208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_g_Group)) 1023208600Srdivacky if (!A->getOption().matches(options::OPT_g0)) 1024208600Srdivacky CmdArgs.push_back("-g"); 1025193326Sed 1026208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections); 1027208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections); 1028208600Srdivacky 1029193326Sed Args.AddLastArg(CmdArgs, options::OPT_nostdinc); 1030206084Srdivacky Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); 1031198893Srdivacky Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); 1032193326Sed 1033200583Srdivacky // Pass the path to compiler resource files. 1034200583Srdivacky CmdArgs.push_back("-resource-dir"); 1035202879Srdivacky CmdArgs.push_back(D.ResourceDir.c_str()); 1036193326Sed 1037193326Sed // Add preprocessing options like -I, -D, etc. if we are using the 1038193326Sed // preprocessor. 1039193326Sed // 1040193326Sed // FIXME: Support -fpreprocessed 1041193326Sed if (types::getPreprocessedType(InputType) != types::TY_INVALID) 1042193326Sed AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs); 1043193326Sed 1044198092Srdivacky // Manually translate -O to -O2 and -O4 to -O3; let clang reject 1045193326Sed // others. 1046193326Sed if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 1047199512Srdivacky if (A->getOption().matches(options::OPT_O4)) 1048193326Sed CmdArgs.push_back("-O3"); 1049208600Srdivacky else if (A->getOption().matches(options::OPT_O) && 1050208600Srdivacky A->getValue(Args)[0] == '\0') 1051198092Srdivacky CmdArgs.push_back("-O2"); 1052193326Sed else 1053193326Sed A->render(Args, CmdArgs); 1054193326Sed } 1055193326Sed 1056198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_W_Group); 1057198893Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pedantic); 1058198893Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors); 1059193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 1060193326Sed 1061193326Sed // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi} 1062193326Sed // (-ansi is equivalent to -std=c89). 1063193326Sed // 1064193326Sed // If a std is supplied, only add -trigraphs if it follows the 1065193326Sed // option. 1066193326Sed if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 1067193326Sed if (Std->getOption().matches(options::OPT_ansi)) 1068198398Srdivacky if (types::isCXX(InputType)) 1069198893Srdivacky CmdArgs.push_back("-std=c++98"); 1070198398Srdivacky else 1071198893Srdivacky CmdArgs.push_back("-std=c89"); 1072193326Sed else 1073193326Sed Std->render(Args, CmdArgs); 1074193326Sed 1075193326Sed if (Arg *A = Args.getLastArg(options::OPT_trigraphs)) 1076193326Sed if (A->getIndex() > Std->getIndex()) 1077193326Sed A->render(Args, CmdArgs); 1078193326Sed } else { 1079193326Sed // Honor -std-default. 1080203955Srdivacky // 1081203955Srdivacky // FIXME: Clang doesn't correctly handle -std= when the input language 1082203955Srdivacky // doesn't match. For the time being just ignore this for C++ inputs; 1083203955Srdivacky // eventually we want to do all the standard defaulting here instead of 1084203955Srdivacky // splitting it between the driver and clang -cc1. 1085203955Srdivacky if (!types::isCXX(InputType)) 1086203955Srdivacky Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, 1087203955Srdivacky "-std=", /*Joined=*/true); 1088193326Sed Args.AddLastArg(CmdArgs, options::OPT_trigraphs); 1089193326Sed } 1090193326Sed 1091208600Srdivacky // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'. 1092208600Srdivacky if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) { 1093208600Srdivacky if (Asm->getOption().matches(options::OPT_fasm)) 1094208600Srdivacky CmdArgs.push_back("-fgnu-keywords"); 1095208600Srdivacky else 1096208600Srdivacky CmdArgs.push_back("-fno-gnu-keywords"); 1097208600Srdivacky } 1098208600Srdivacky 1099193326Sed if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) { 1100193326Sed CmdArgs.push_back("-ftemplate-depth"); 1101193326Sed CmdArgs.push_back(A->getValue(Args)); 1102193326Sed } 1103193326Sed 1104199512Srdivacky if (Args.hasArg(options::OPT__relocatable_pch)) 1105199990Srdivacky CmdArgs.push_back("-relocatable-pch"); 1106198092Srdivacky 1107198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { 1108198893Srdivacky CmdArgs.push_back("-fconstant-string-class"); 1109198893Srdivacky CmdArgs.push_back(A->getValue(Args)); 1110198893Srdivacky } 1111198092Srdivacky 1112202379Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) { 1113202379Srdivacky CmdArgs.push_back("-ftabstop"); 1114202379Srdivacky CmdArgs.push_back(A->getValue(Args)); 1115202379Srdivacky } 1116202379Srdivacky 1117207619Srdivacky CmdArgs.push_back("-ferror-limit"); 1118207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ)) 1119207619Srdivacky CmdArgs.push_back(A->getValue(Args)); 1120207619Srdivacky else 1121207619Srdivacky CmdArgs.push_back("19"); 1122207619Srdivacky 1123208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) { 1124208600Srdivacky CmdArgs.push_back("-fmacro-backtrace-limit"); 1125207632Srdivacky CmdArgs.push_back(A->getValue(Args)); 1126208600Srdivacky } 1127208600Srdivacky 1128208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) { 1129208600Srdivacky CmdArgs.push_back("-ftemplate-backtrace-limit"); 1130207619Srdivacky CmdArgs.push_back(A->getValue(Args)); 1131208600Srdivacky } 1132208600Srdivacky 1133198893Srdivacky // Pass -fmessage-length=. 1134199990Srdivacky CmdArgs.push_back("-fmessage-length"); 1135198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { 1136199990Srdivacky CmdArgs.push_back(A->getValue(Args)); 1137198893Srdivacky } else { 1138198893Srdivacky // If -fmessage-length=N was not specified, determine whether this is a 1139198893Srdivacky // terminal and, if so, implicitly define -fmessage-length appropriately. 1140198893Srdivacky unsigned N = llvm::sys::Process::StandardErrColumns(); 1141198893Srdivacky CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N))); 1142198893Srdivacky } 1143198893Srdivacky 1144200583Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) { 1145200583Srdivacky CmdArgs.push_back("-fvisibility"); 1146200583Srdivacky CmdArgs.push_back(A->getValue(Args)); 1147200583Srdivacky } 1148200583Srdivacky 1149205408Srdivacky // -fhosted is default. 1150205408Srdivacky if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding, 1151205408Srdivacky options::OPT_fhosted, 1152205408Srdivacky false)) 1153205408Srdivacky CmdArgs.push_back("-ffreestanding"); 1154205408Srdivacky 1155200583Srdivacky // Forward -f (flag) options which we can pass directly. 1156200583Srdivacky Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior); 1157193326Sed Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); 1158193326Sed Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); 1159205408Srdivacky 1160205408Srdivacky // -flax-vector-conversions is default. 1161205408Srdivacky if (!Args.hasFlag(options::OPT_flax_vector_conversions, 1162205408Srdivacky options::OPT_fno_lax_vector_conversions)) 1163205408Srdivacky CmdArgs.push_back("-fno-lax-vector-conversions"); 1164205408Srdivacky 1165207619Srdivacky // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only 1166207619Srdivacky // takes precedence. 1167207619Srdivacky const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only); 1168207619Srdivacky if (!GCArg) 1169207619Srdivacky GCArg = Args.getLastArg(options::OPT_fobjc_gc); 1170207619Srdivacky if (GCArg) { 1171207619Srdivacky if (getToolChain().SupportsObjCGC()) { 1172207619Srdivacky GCArg->render(Args, CmdArgs); 1173207619Srdivacky } else { 1174207619Srdivacky // FIXME: We should move this to a hard error. 1175207619Srdivacky D.Diag(clang::diag::warn_drv_objc_gc_unsupported) 1176207619Srdivacky << GCArg->getAsString(Args); 1177207619Srdivacky } 1178207619Srdivacky } 1179207619Srdivacky 1180193326Sed Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics); 1181193326Sed Args.AddLastArg(CmdArgs, options::OPT_fno_show_column); 1182193326Sed Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch); 1183193326Sed Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); 1184193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftime_report); 1185193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftrapv); 1186193326Sed Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); 1187193326Sed 1188198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pthread); 1189198092Srdivacky 1190199482Srdivacky // -stack-protector=0 is default. 1191199482Srdivacky unsigned StackProtectorLevel = 0; 1192195341Sed if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, 1193195341Sed options::OPT_fstack_protector_all, 1194195341Sed options::OPT_fstack_protector)) { 1195199482Srdivacky if (A->getOption().matches(options::OPT_fstack_protector)) 1196199482Srdivacky StackProtectorLevel = 1; 1197199482Srdivacky else if (A->getOption().matches(options::OPT_fstack_protector_all)) 1198199482Srdivacky StackProtectorLevel = 2; 1199199482Srdivacky } else 1200199482Srdivacky StackProtectorLevel = getToolChain().GetDefaultStackProtectorLevel(); 1201199482Srdivacky if (StackProtectorLevel) { 1202199482Srdivacky CmdArgs.push_back("-stack-protector"); 1203199482Srdivacky CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel))); 1204195341Sed } 1205195341Sed 1206193326Sed // Forward -f options with positive and negative forms; we translate 1207193326Sed // these by hand. 1208193326Sed 1209199482Srdivacky // -fbuiltin is default. 1210193326Sed if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin)) 1211199512Srdivacky CmdArgs.push_back("-fno-builtin"); 1212193326Sed 1213201361Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 1214201361Srdivacky options::OPT_fno_assume_sane_operator_new)) 1215201361Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 1216201361Srdivacky 1217199482Srdivacky // -fblocks=0 is default. 1218199482Srdivacky if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks, 1219199482Srdivacky getToolChain().IsBlocksDefault())) { 1220199482Srdivacky CmdArgs.push_back("-fblocks"); 1221193326Sed } 1222193326Sed 1223207619Srdivacky // -faccess-control is default. 1224207619Srdivacky if (Args.hasFlag(options::OPT_fno_access_control, 1225207619Srdivacky options::OPT_faccess_control, 1226205408Srdivacky false)) 1227207619Srdivacky CmdArgs.push_back("-fno-access-control"); 1228205408Srdivacky 1229199990Srdivacky // -fexceptions=0 is default. 1230198092Srdivacky if (needsExceptions(Args, InputType, getToolChain().getTriple())) 1231198092Srdivacky CmdArgs.push_back("-fexceptions"); 1232198092Srdivacky 1233203955Srdivacky if (getToolChain().UseSjLjExceptions()) 1234203955Srdivacky CmdArgs.push_back("-fsjlj-exceptions"); 1235203955Srdivacky 1236199482Srdivacky // -frtti is default. 1237205408Srdivacky if (KernelOrKext || 1238205408Srdivacky !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) 1239199512Srdivacky CmdArgs.push_back("-fno-rtti"); 1240198092Srdivacky 1241199482Srdivacky // -fsigned-char is default. 1242199990Srdivacky if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char, 1243199482Srdivacky isSignedCharDefault(getToolChain().getTriple()))) 1244199990Srdivacky CmdArgs.push_back("-fno-signed-char"); 1245199482Srdivacky 1246203955Srdivacky // -fthreadsafe-static is default. 1247203955Srdivacky if (!Args.hasFlag(options::OPT_fthreadsafe_statics, 1248203955Srdivacky options::OPT_fno_threadsafe_statics)) 1249203955Srdivacky CmdArgs.push_back("-fno-threadsafe-statics"); 1250203955Srdivacky 1251205408Srdivacky // -fuse-cxa-atexit is default. 1252205408Srdivacky if (KernelOrKext || !Args.hasFlag(options::OPT_fuse_cxa_atexit, 1253205408Srdivacky options::OPT_fno_use_cxa_atexit)) 1254205408Srdivacky CmdArgs.push_back("-fno-use-cxa-atexit"); 1255205408Srdivacky 1256199482Srdivacky // -fms-extensions=0 is default. 1257199990Srdivacky if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 1258199482Srdivacky getToolChain().getTriple().getOS() == llvm::Triple::Win32)) 1259199482Srdivacky CmdArgs.push_back("-fms-extensions"); 1260199482Srdivacky 1261207619Srdivacky // -fgnu-keywords default varies depending on language; only pass if 1262207619Srdivacky // specified. 1263207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, 1264207619Srdivacky options::OPT_fno_gnu_keywords)) 1265207619Srdivacky A->render(Args, CmdArgs); 1266207619Srdivacky 1267199482Srdivacky // -fnext-runtime is default. 1268199990Srdivacky if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime, 1269199482Srdivacky getToolChain().getTriple().getOS() == llvm::Triple::Darwin)) 1270199482Srdivacky CmdArgs.push_back("-fgnu-runtime"); 1271199482Srdivacky 1272199482Srdivacky // -fobjc-nonfragile-abi=0 is default. 1273199482Srdivacky if (types::isObjC(InputType)) { 1274207619Srdivacky unsigned Version = 1; 1275199482Srdivacky if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) || 1276207619Srdivacky getToolChain().IsObjCNonFragileABIDefault()) 1277207619Srdivacky Version = 2; 1278207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fobjc_abi_version_EQ)) { 1279207619Srdivacky if (llvm::StringRef(A->getValue(Args)) == "1") 1280207619Srdivacky Version = 1; 1281207619Srdivacky else if (llvm::StringRef(A->getValue(Args)) == "2") 1282207619Srdivacky Version = 2; 1283207619Srdivacky else 1284207619Srdivacky D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 1285207619Srdivacky } 1286207619Srdivacky 1287207619Srdivacky if (Version == 2) { 1288199482Srdivacky CmdArgs.push_back("-fobjc-nonfragile-abi"); 1289207619Srdivacky 1290207619Srdivacky // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and 1291207619Srdivacky // legacy is the default. 1292207619Srdivacky if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch, 1293207619Srdivacky options::OPT_fno_objc_legacy_dispatch, 1294207619Srdivacky getToolChain().IsObjCLegacyDispatchDefault())) { 1295207619Srdivacky if (getToolChain().UseObjCMixedDispatch()) 1296207619Srdivacky CmdArgs.push_back("-fobjc-dispatch-method=mixed"); 1297207619Srdivacky else 1298207619Srdivacky CmdArgs.push_back("-fobjc-dispatch-method=non-legacy"); 1299207619Srdivacky } 1300203955Srdivacky } 1301208600Srdivacky 1302208600Srdivacky // FIXME: -fobjc-nonfragile-abi2 is a transient option meant to expose 1303208600Srdivacky // features in testing. It will eventually be removed. 1304208600Srdivacky if (Args.hasArg(options::OPT_fobjc_nonfragile_abi2)) 1305208600Srdivacky CmdArgs.push_back("-fobjc-nonfragile-abi2"); 1306199482Srdivacky } 1307199482Srdivacky 1308203955Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 1309203955Srdivacky options::OPT_fno_assume_sane_operator_new)) 1310203955Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 1311203955Srdivacky 1312207619Srdivacky // -fconstant-cfstrings is default, and may be subject to argument translation 1313207619Srdivacky // on Darwin. 1314207619Srdivacky if (!Args.hasFlag(options::OPT_fconstant_cfstrings, 1315207619Srdivacky options::OPT_fno_constant_cfstrings) || 1316207619Srdivacky !Args.hasFlag(options::OPT_mconstant_cfstrings, 1317207619Srdivacky options::OPT_mno_constant_cfstrings)) 1318207619Srdivacky CmdArgs.push_back("-fno-constant-cfstrings"); 1319207619Srdivacky 1320199482Srdivacky // -fshort-wchar default varies depending on platform; only 1321193576Sed // pass if specified. 1322207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) 1323207619Srdivacky A->render(Args, CmdArgs); 1324193576Sed 1325198893Srdivacky // -fno-pascal-strings is default, only pass non-default. If the tool chain 1326198893Srdivacky // happened to translate to -mpascal-strings, we want to back translate here. 1327193326Sed // 1328193326Sed // FIXME: This is gross; that translation should be pulled from the 1329193326Sed // tool chain. 1330193326Sed if (Args.hasFlag(options::OPT_fpascal_strings, 1331193326Sed options::OPT_fno_pascal_strings, 1332193326Sed false) || 1333193326Sed Args.hasFlag(options::OPT_mpascal_strings, 1334193326Sed options::OPT_mno_pascal_strings, 1335193326Sed false)) 1336193326Sed CmdArgs.push_back("-fpascal-strings"); 1337193326Sed 1338193326Sed // -fcommon is default, only pass non-default. 1339193326Sed if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common)) 1340193326Sed CmdArgs.push_back("-fno-common"); 1341193326Sed 1342193326Sed // -fsigned-bitfields is default, and clang doesn't yet support 1343193326Sed // --funsigned-bitfields. 1344198092Srdivacky if (!Args.hasFlag(options::OPT_fsigned_bitfields, 1345193326Sed options::OPT_funsigned_bitfields)) 1346193326Sed D.Diag(clang::diag::warn_drv_clang_unsupported) 1347193326Sed << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args); 1348193326Sed 1349193326Sed // -fdiagnostics-fixit-info is default, only pass non-default. 1350198092Srdivacky if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info, 1351193326Sed options::OPT_fno_diagnostics_fixit_info)) 1352193326Sed CmdArgs.push_back("-fno-diagnostics-fixit-info"); 1353193326Sed 1354203955Srdivacky Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_binary); 1355203955Srdivacky 1356193326Sed // Enable -fdiagnostics-show-option by default. 1357198092Srdivacky if (Args.hasFlag(options::OPT_fdiagnostics_show_option, 1358193326Sed options::OPT_fno_diagnostics_show_option)) 1359193326Sed CmdArgs.push_back("-fdiagnostics-show-option"); 1360198893Srdivacky 1361208600Srdivacky if (const Arg *A = 1362208600Srdivacky Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { 1363208600Srdivacky CmdArgs.push_back("-fdiagnostics-show-category"); 1364208600Srdivacky CmdArgs.push_back(A->getValue(Args)); 1365208600Srdivacky } 1366208600Srdivacky 1367198893Srdivacky // Color diagnostics are the default, unless the terminal doesn't support 1368198893Srdivacky // them. 1369198893Srdivacky if (Args.hasFlag(options::OPT_fcolor_diagnostics, 1370198893Srdivacky options::OPT_fno_color_diagnostics) && 1371198893Srdivacky llvm::sys::Process::StandardErrHasColors()) 1372198893Srdivacky CmdArgs.push_back("-fcolor-diagnostics"); 1373198893Srdivacky 1374194179Sed if (!Args.hasFlag(options::OPT_fshow_source_location, 1375194179Sed options::OPT_fno_show_source_location)) 1376194179Sed CmdArgs.push_back("-fno-show-source-location"); 1377193326Sed 1378193326Sed // -fdollars-in-identifiers default varies depending on platform and 1379193326Sed // language; only pass if specified. 1380198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers, 1381193326Sed options::OPT_fno_dollars_in_identifiers)) { 1382193326Sed if (A->getOption().matches(options::OPT_fdollars_in_identifiers)) 1383201361Srdivacky CmdArgs.push_back("-fdollars-in-identifiers"); 1384193326Sed else 1385201361Srdivacky CmdArgs.push_back("-fno-dollars-in-identifiers"); 1386193326Sed } 1387193326Sed 1388193326Sed // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for 1389193326Sed // practical purposes. 1390198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time, 1391193326Sed options::OPT_fno_unit_at_a_time)) { 1392193326Sed if (A->getOption().matches(options::OPT_fno_unit_at_a_time)) 1393198092Srdivacky D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args); 1394193326Sed } 1395198092Srdivacky 1396198092Srdivacky // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM. 1397198092Srdivacky // 1398200583Srdivacky // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941. 1399198092Srdivacky#if 0 1400198092Srdivacky if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin && 1401198092Srdivacky (getToolChain().getTriple().getArch() == llvm::Triple::arm || 1402198092Srdivacky getToolChain().getTriple().getArch() == llvm::Triple::thumb)) { 1403198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcat)) 1404198092Srdivacky CmdArgs.push_back("-fno-builtin-strcat"); 1405198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcpy)) 1406198092Srdivacky CmdArgs.push_back("-fno-builtin-strcpy"); 1407198092Srdivacky } 1408198092Srdivacky#endif 1409198092Srdivacky 1410198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_traditional, 1411198092Srdivacky options::OPT_traditional_cpp)) 1412198092Srdivacky D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 1413198092Srdivacky 1414193326Sed Args.AddLastArg(CmdArgs, options::OPT_dM); 1415193326Sed Args.AddLastArg(CmdArgs, options::OPT_dD); 1416193326Sed 1417207619Srdivacky // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option 1418207619Srdivacky // parser. 1419193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xclang); 1420207619Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm), 1421207619Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 1422207619Srdivacky it->claim(); 1423193326Sed 1424207619Srdivacky // We translate this by hand to the -cc1 argument, since nightly test uses 1425207619Srdivacky // it and developers have been trained to spell it with -mllvm. 1426207619Srdivacky if (llvm::StringRef(it->getValue(Args, 0)) == "-disable-llvm-optzns") 1427207619Srdivacky CmdArgs.push_back("-disable-llvm-optzns"); 1428207619Srdivacky else 1429207619Srdivacky it->render(Args, CmdArgs); 1430207619Srdivacky } 1431207619Srdivacky 1432193326Sed if (Output.getType() == types::TY_Dependencies) { 1433193326Sed // Handled with other dependency code. 1434193326Sed } else if (Output.isPipe()) { 1435193326Sed CmdArgs.push_back("-o"); 1436193326Sed CmdArgs.push_back("-"); 1437193326Sed } else if (Output.isFilename()) { 1438193326Sed CmdArgs.push_back("-o"); 1439193326Sed CmdArgs.push_back(Output.getFilename()); 1440193326Sed } else { 1441193326Sed assert(Output.isNothing() && "Invalid output."); 1442193326Sed } 1443193326Sed 1444193326Sed for (InputInfoList::const_iterator 1445193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1446193326Sed const InputInfo &II = *it; 1447193326Sed CmdArgs.push_back("-x"); 1448193326Sed CmdArgs.push_back(types::getTypeName(II.getType())); 1449193326Sed if (II.isPipe()) 1450193326Sed CmdArgs.push_back("-"); 1451193326Sed else if (II.isFilename()) 1452193326Sed CmdArgs.push_back(II.getFilename()); 1453193326Sed else 1454193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 1455193326Sed } 1456193326Sed 1457198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_undef); 1458198893Srdivacky 1459193326Sed const char *Exec = 1460200583Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "clang")); 1461201361Srdivacky 1462201361Srdivacky // Optionally embed the -cc1 level arguments into the debug info, for build 1463201361Srdivacky // analysis. 1464201361Srdivacky if (getToolChain().UseDwarfDebugFlags()) { 1465201361Srdivacky llvm::SmallString<256> Flags; 1466201361Srdivacky Flags += Exec; 1467201361Srdivacky for (unsigned i = 0, e = CmdArgs.size(); i != e; ++i) { 1468201361Srdivacky Flags += " "; 1469201361Srdivacky Flags += CmdArgs[i]; 1470201361Srdivacky } 1471201361Srdivacky CmdArgs.push_back("-dwarf-debug-flags"); 1472201361Srdivacky CmdArgs.push_back(Args.MakeArgString(Flags.str())); 1473201361Srdivacky } 1474201361Srdivacky 1475200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 1476193326Sed 1477193326Sed // Explicitly warn that these options are unsupported, even though 1478193326Sed // we are allowing compilation to continue. 1479199990Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_pg), 1480199990Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 1481199990Srdivacky it->claim(); 1482199990Srdivacky D.Diag(clang::diag::warn_drv_clang_unsupported) << it->getAsString(Args); 1483193326Sed } 1484193326Sed 1485193326Sed // Claim some arguments which clang supports automatically. 1486193326Sed 1487207619Srdivacky // -fpch-preprocess is used with gcc to add a special marker in the output to 1488207619Srdivacky // include the PCH file. Clang's PTH solution is completely transparent, so we 1489207619Srdivacky // do not need to deal with it at all. 1490193326Sed Args.ClaimAllArgs(options::OPT_fpch_preprocess); 1491193326Sed 1492193326Sed // Claim some arguments which clang doesn't support, but we don't 1493193326Sed // care to warn the user about. 1494199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group); 1495199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group); 1496193326Sed} 1497193326Sed 1498208600Srdivackyvoid ClangAs::ConstructJob(Compilation &C, const JobAction &JA, 1499208600Srdivacky Job &Dest, 1500208600Srdivacky const InputInfo &Output, 1501208600Srdivacky const InputInfoList &Inputs, 1502208600Srdivacky const ArgList &Args, 1503208600Srdivacky const char *LinkingOutput) const { 1504208600Srdivacky const Driver &D = getToolChain().getDriver(); 1505208600Srdivacky ArgStringList CmdArgs; 1506208600Srdivacky 1507208600Srdivacky assert(Inputs.size() == 1 && "Unexpected number of inputs."); 1508208600Srdivacky const InputInfo &Input = Inputs[0]; 1509208600Srdivacky 1510208600Srdivacky // Invoke ourselves in -cc1as mode. 1511208600Srdivacky // 1512208600Srdivacky // FIXME: Implement custom jobs for internal actions. 1513208600Srdivacky CmdArgs.push_back("-cc1as"); 1514208600Srdivacky 1515208600Srdivacky // Add the "effective" target triple. 1516208600Srdivacky CmdArgs.push_back("-triple"); 1517208600Srdivacky std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); 1518208600Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 1519208600Srdivacky 1520208600Srdivacky // Set the output mode, we currently only expect to be used as a real 1521208600Srdivacky // assembler. 1522208600Srdivacky CmdArgs.push_back("-filetype"); 1523208600Srdivacky CmdArgs.push_back("obj"); 1524208600Srdivacky 1525208600Srdivacky // At -O0, we use -mrelax-all by default. 1526208600Srdivacky bool IsOpt = false; 1527208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 1528208600Srdivacky IsOpt = !A->getOption().matches(options::OPT_O0); 1529208600Srdivacky if (Args.hasFlag(options::OPT_mrelax_all, 1530208600Srdivacky options::OPT_mno_relax_all, 1531208600Srdivacky !IsOpt)) 1532208600Srdivacky CmdArgs.push_back("-mrelax-all"); 1533208600Srdivacky 1534208600Srdivacky // FIXME: Add -force_cpusubtype_ALL support, once we have it. 1535208600Srdivacky 1536208600Srdivacky // FIXME: Add -g support, once we have it. 1537208600Srdivacky 1538208600Srdivacky // FIXME: Add -static support, once we have it. 1539208600Srdivacky 1540208600Srdivacky Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 1541208600Srdivacky options::OPT_Xassembler); 1542208600Srdivacky 1543208600Srdivacky assert(Output.isFilename() && "Unexpected lipo output."); 1544208600Srdivacky CmdArgs.push_back("-o"); 1545208600Srdivacky CmdArgs.push_back(Output.getFilename()); 1546208600Srdivacky 1547208600Srdivacky if (Input.isPipe()) { 1548208600Srdivacky CmdArgs.push_back("-"); 1549208600Srdivacky } else { 1550208600Srdivacky assert(Input.isFilename() && "Invalid input."); 1551208600Srdivacky CmdArgs.push_back(Input.getFilename()); 1552208600Srdivacky } 1553208600Srdivacky 1554208600Srdivacky const char *Exec = 1555208600Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "clang")); 1556208600Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 1557208600Srdivacky} 1558208600Srdivacky 1559193326Sedvoid gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, 1560193326Sed Job &Dest, 1561193326Sed const InputInfo &Output, 1562193326Sed const InputInfoList &Inputs, 1563193326Sed const ArgList &Args, 1564193326Sed const char *LinkingOutput) const { 1565201361Srdivacky const Driver &D = getToolChain().getDriver(); 1566193326Sed ArgStringList CmdArgs; 1567193326Sed 1568193326Sed for (ArgList::const_iterator 1569193326Sed it = Args.begin(), ie = Args.end(); it != ie; ++it) { 1570193326Sed Arg *A = *it; 1571193326Sed if (A->getOption().hasForwardToGCC()) { 1572193326Sed // It is unfortunate that we have to claim here, as this means 1573193326Sed // we will basically never report anything interesting for 1574193326Sed // platforms using a generic gcc, even if we are just using gcc 1575193326Sed // to get to the assembler. 1576193326Sed A->claim(); 1577193326Sed A->render(Args, CmdArgs); 1578193326Sed } 1579193326Sed } 1580193326Sed 1581203955Srdivacky RenderExtraToolArgs(JA, CmdArgs); 1582193326Sed 1583193326Sed // If using a driver driver, force the arch. 1584193326Sed const std::string &Arch = getToolChain().getArchName(); 1585201361Srdivacky if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin) { 1586193326Sed CmdArgs.push_back("-arch"); 1587193326Sed 1588193326Sed // FIXME: Remove these special cases. 1589193326Sed if (Arch == "powerpc") 1590193326Sed CmdArgs.push_back("ppc"); 1591193326Sed else if (Arch == "powerpc64") 1592193326Sed CmdArgs.push_back("ppc64"); 1593193326Sed else 1594198092Srdivacky CmdArgs.push_back(Args.MakeArgString(Arch)); 1595193326Sed } 1596193326Sed 1597193326Sed // Try to force gcc to match the tool chain we want, if we recognize 1598193326Sed // the arch. 1599193326Sed // 1600193326Sed // FIXME: The triple class should directly provide the information we want 1601193326Sed // here. 1602193326Sed if (Arch == "i386" || Arch == "powerpc") 1603193326Sed CmdArgs.push_back("-m32"); 1604193326Sed else if (Arch == "x86_64" || Arch == "powerpc64") 1605193326Sed CmdArgs.push_back("-m64"); 1606193326Sed 1607193326Sed if (Output.isPipe()) { 1608193326Sed CmdArgs.push_back("-o"); 1609193326Sed CmdArgs.push_back("-"); 1610193326Sed } else if (Output.isFilename()) { 1611193326Sed CmdArgs.push_back("-o"); 1612193326Sed CmdArgs.push_back(Output.getFilename()); 1613193326Sed } else { 1614193326Sed assert(Output.isNothing() && "Unexpected output"); 1615193326Sed CmdArgs.push_back("-fsyntax-only"); 1616193326Sed } 1617193326Sed 1618193326Sed 1619193326Sed // Only pass -x if gcc will understand it; otherwise hope gcc 1620193326Sed // understands the suffix correctly. The main use case this would go 1621193326Sed // wrong in is for linker inputs if they happened to have an odd 1622193326Sed // suffix; really the only way to get this to happen is a command 1623193326Sed // like '-x foobar a.c' which will treat a.c like a linker input. 1624193326Sed // 1625193326Sed // FIXME: For the linker case specifically, can we safely convert 1626193326Sed // inputs into '-Wl,' options? 1627193326Sed for (InputInfoList::const_iterator 1628193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1629193326Sed const InputInfo &II = *it; 1630193326Sed 1631198092Srdivacky // Don't try to pass LLVM or AST inputs to a generic gcc. 1632193326Sed if (II.getType() == types::TY_LLVMBC) 1633193326Sed D.Diag(clang::diag::err_drv_no_linker_llvm_support) 1634198092Srdivacky << getToolChain().getTripleString(); 1635198092Srdivacky else if (II.getType() == types::TY_AST) 1636198092Srdivacky D.Diag(clang::diag::err_drv_no_ast_support) 1637198092Srdivacky << getToolChain().getTripleString(); 1638193326Sed 1639193326Sed if (types::canTypeBeUserSpecified(II.getType())) { 1640193326Sed CmdArgs.push_back("-x"); 1641193326Sed CmdArgs.push_back(types::getTypeName(II.getType())); 1642193326Sed } 1643193326Sed 1644193326Sed if (II.isPipe()) 1645193326Sed CmdArgs.push_back("-"); 1646193326Sed else if (II.isFilename()) 1647193326Sed CmdArgs.push_back(II.getFilename()); 1648193326Sed else 1649193326Sed // Don't render as input, we need gcc to do the translations. 1650193326Sed II.getInputArg().render(Args, CmdArgs); 1651193326Sed } 1652193326Sed 1653201361Srdivacky const char *GCCName = getToolChain().getDriver().CCCGenericGCCName.c_str(); 1654193326Sed const char *Exec = 1655198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName)); 1656200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 1657193326Sed} 1658193326Sed 1659203955Srdivackyvoid gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA, 1660203955Srdivacky ArgStringList &CmdArgs) const { 1661193326Sed CmdArgs.push_back("-E"); 1662193326Sed} 1663193326Sed 1664203955Srdivackyvoid gcc::Precompile::RenderExtraToolArgs(const JobAction &JA, 1665203955Srdivacky ArgStringList &CmdArgs) const { 1666193326Sed // The type is good enough. 1667193326Sed} 1668193326Sed 1669203955Srdivackyvoid gcc::Compile::RenderExtraToolArgs(const JobAction &JA, 1670203955Srdivacky ArgStringList &CmdArgs) const { 1671203955Srdivacky const Driver &D = getToolChain().getDriver(); 1672203955Srdivacky 1673203955Srdivacky // If -flto, etc. are present then make sure not to force assembly output. 1674203955Srdivacky if (JA.getType() == types::TY_LLVMBC) 1675203955Srdivacky CmdArgs.push_back("-c"); 1676203955Srdivacky else { 1677203955Srdivacky if (JA.getType() != types::TY_PP_Asm) 1678203955Srdivacky D.Diag(clang::diag::err_drv_invalid_gcc_output_type) 1679203955Srdivacky << getTypeName(JA.getType()); 1680203955Srdivacky 1681203955Srdivacky CmdArgs.push_back("-S"); 1682203955Srdivacky } 1683193326Sed} 1684193326Sed 1685203955Srdivackyvoid gcc::Assemble::RenderExtraToolArgs(const JobAction &JA, 1686203955Srdivacky ArgStringList &CmdArgs) const { 1687193326Sed CmdArgs.push_back("-c"); 1688193326Sed} 1689193326Sed 1690203955Srdivackyvoid gcc::Link::RenderExtraToolArgs(const JobAction &JA, 1691203955Srdivacky ArgStringList &CmdArgs) const { 1692193326Sed // The types are (hopefully) good enough. 1693193326Sed} 1694193326Sed 1695193326Sedconst char *darwin::CC1::getCC1Name(types::ID Type) const { 1696193326Sed switch (Type) { 1697193326Sed default: 1698193326Sed assert(0 && "Unexpected type for Darwin CC1 tool."); 1699193326Sed case types::TY_Asm: 1700193326Sed case types::TY_C: case types::TY_CHeader: 1701193326Sed case types::TY_PP_C: case types::TY_PP_CHeader: 1702193326Sed return "cc1"; 1703193326Sed case types::TY_ObjC: case types::TY_ObjCHeader: 1704193326Sed case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader: 1705193326Sed return "cc1obj"; 1706193326Sed case types::TY_CXX: case types::TY_CXXHeader: 1707193326Sed case types::TY_PP_CXX: case types::TY_PP_CXXHeader: 1708193326Sed return "cc1plus"; 1709193326Sed case types::TY_ObjCXX: case types::TY_ObjCXXHeader: 1710193326Sed case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader: 1711193326Sed return "cc1objplus"; 1712193326Sed } 1713193326Sed} 1714193326Sed 1715193326Sedconst char *darwin::CC1::getBaseInputName(const ArgList &Args, 1716193326Sed const InputInfoList &Inputs) { 1717193326Sed llvm::sys::Path P(Inputs[0].getBaseInput()); 1718198092Srdivacky return Args.MakeArgString(P.getLast()); 1719193326Sed} 1720193326Sed 1721193326Sedconst char *darwin::CC1::getBaseInputStem(const ArgList &Args, 1722193326Sed const InputInfoList &Inputs) { 1723193326Sed const char *Str = getBaseInputName(Args, Inputs); 1724193326Sed 1725193326Sed if (const char *End = strchr(Str, '.')) 1726198092Srdivacky return Args.MakeArgString(std::string(Str, End)); 1727193326Sed 1728193326Sed return Str; 1729193326Sed} 1730193326Sed 1731193326Sedconst char * 1732193326Seddarwin::CC1::getDependencyFileName(const ArgList &Args, 1733193326Sed const InputInfoList &Inputs) { 1734193326Sed // FIXME: Think about this more. 1735193326Sed std::string Res; 1736193326Sed 1737193326Sed if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 1738193326Sed std::string Str(OutputOpt->getValue(Args)); 1739193326Sed 1740193326Sed Res = Str.substr(0, Str.rfind('.')); 1741193326Sed } else 1742193326Sed Res = darwin::CC1::getBaseInputStem(Args, Inputs); 1743193326Sed 1744198092Srdivacky return Args.MakeArgString(Res + ".d"); 1745193326Sed} 1746193326Sed 1747193326Sedvoid darwin::CC1::AddCC1Args(const ArgList &Args, 1748193326Sed ArgStringList &CmdArgs) const { 1749201361Srdivacky const Driver &D = getToolChain().getDriver(); 1750198092Srdivacky 1751198092Srdivacky CheckCodeGenerationOptions(D, Args); 1752198092Srdivacky 1753193326Sed // Derived from cc1 spec. 1754193326Sed if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) && 1755193326Sed !Args.hasArg(options::OPT_mdynamic_no_pic)) 1756193326Sed CmdArgs.push_back("-fPIC"); 1757193326Sed 1758198092Srdivacky if (getToolChain().getTriple().getArch() == llvm::Triple::arm || 1759198092Srdivacky getToolChain().getTriple().getArch() == llvm::Triple::thumb) { 1760198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcat)) 1761198092Srdivacky CmdArgs.push_back("-fno-builtin-strcat"); 1762198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcpy)) 1763198092Srdivacky CmdArgs.push_back("-fno-builtin-strcpy"); 1764198092Srdivacky } 1765198092Srdivacky 1766193326Sed // gcc has some code here to deal with when no -mmacosx-version-min 1767193326Sed // and no -miphoneos-version-min is present, but this never happens 1768193326Sed // due to tool chain specific argument translation. 1769193326Sed 1770193326Sed if (Args.hasArg(options::OPT_g_Flag) && 1771193326Sed !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols)) 1772193326Sed CmdArgs.push_back("-feliminate-unused-debug-symbols"); 1773193326Sed} 1774193326Sed 1775193326Sedvoid darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, 1776193326Sed const InputInfoList &Inputs, 1777193326Sed const ArgStringList &OutputArgs) const { 1778201361Srdivacky const Driver &D = getToolChain().getDriver(); 1779193326Sed 1780193326Sed // Derived from cc1_options spec. 1781193326Sed if (Args.hasArg(options::OPT_fast) || 1782193326Sed Args.hasArg(options::OPT_fastf) || 1783193326Sed Args.hasArg(options::OPT_fastcp)) 1784193326Sed CmdArgs.push_back("-O3"); 1785193326Sed 1786193326Sed if (Arg *A = Args.getLastArg(options::OPT_pg)) 1787193326Sed if (Args.hasArg(options::OPT_fomit_frame_pointer)) 1788193326Sed D.Diag(clang::diag::err_drv_argument_not_allowed_with) 1789193326Sed << A->getAsString(Args) << "-fomit-frame-pointer"; 1790193326Sed 1791193326Sed AddCC1Args(Args, CmdArgs); 1792193326Sed 1793193326Sed if (!Args.hasArg(options::OPT_Q)) 1794193326Sed CmdArgs.push_back("-quiet"); 1795193326Sed 1796193326Sed CmdArgs.push_back("-dumpbase"); 1797193326Sed CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs)); 1798193326Sed 1799193326Sed Args.AddAllArgs(CmdArgs, options::OPT_d_Group); 1800193326Sed 1801193326Sed Args.AddAllArgs(CmdArgs, options::OPT_m_Group); 1802193326Sed Args.AddAllArgs(CmdArgs, options::OPT_a_Group); 1803193326Sed 1804193326Sed // FIXME: The goal is to use the user provided -o if that is our 1805193326Sed // final output, otherwise to drive from the original input 1806193326Sed // name. Find a clean way to go about this. 1807193326Sed if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) && 1808193326Sed Args.hasArg(options::OPT_o)) { 1809193326Sed Arg *OutputOpt = Args.getLastArg(options::OPT_o); 1810193326Sed CmdArgs.push_back("-auxbase-strip"); 1811193326Sed CmdArgs.push_back(OutputOpt->getValue(Args)); 1812193326Sed } else { 1813193326Sed CmdArgs.push_back("-auxbase"); 1814193326Sed CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs)); 1815193326Sed } 1816193326Sed 1817193326Sed Args.AddAllArgs(CmdArgs, options::OPT_g_Group); 1818193326Sed 1819193326Sed Args.AddAllArgs(CmdArgs, options::OPT_O); 1820193326Sed // FIXME: -Wall is getting some special treatment. Investigate. 1821193326Sed Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group); 1822193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 1823193326Sed Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi, 1824193326Sed options::OPT_trigraphs); 1825193326Sed if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 1826193326Sed // Honor -std-default. 1827193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, 1828193326Sed "-std=", /*Joined=*/true); 1829193326Sed } 1830193326Sed 1831193326Sed if (Args.hasArg(options::OPT_v)) 1832193326Sed CmdArgs.push_back("-version"); 1833193326Sed if (Args.hasArg(options::OPT_pg)) 1834193326Sed CmdArgs.push_back("-p"); 1835193326Sed Args.AddLastArg(CmdArgs, options::OPT_p); 1836193326Sed 1837193326Sed // The driver treats -fsyntax-only specially. 1838198092Srdivacky if (getToolChain().getTriple().getArch() == llvm::Triple::arm || 1839198092Srdivacky getToolChain().getTriple().getArch() == llvm::Triple::thumb) { 1840198092Srdivacky // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are 1841198092Srdivacky // used to inhibit the default -fno-builtin-str{cat,cpy}. 1842198092Srdivacky // 1843198092Srdivacky // FIXME: Should we grow a better way to deal with "removing" args? 1844199990Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group, 1845199990Srdivacky options::OPT_fsyntax_only), 1846199990Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 1847199990Srdivacky if (!it->getOption().matches(options::OPT_fbuiltin_strcat) && 1848199990Srdivacky !it->getOption().matches(options::OPT_fbuiltin_strcpy)) { 1849199990Srdivacky it->claim(); 1850199990Srdivacky it->render(Args, CmdArgs); 1851198092Srdivacky } 1852198092Srdivacky } 1853198092Srdivacky } else 1854198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); 1855193326Sed 1856193326Sed Args.AddAllArgs(CmdArgs, options::OPT_undef); 1857193326Sed if (Args.hasArg(options::OPT_Qn)) 1858193326Sed CmdArgs.push_back("-fno-ident"); 1859193326Sed 1860193326Sed // FIXME: This isn't correct. 1861193326Sed //Args.AddLastArg(CmdArgs, options::OPT__help) 1862193326Sed //Args.AddLastArg(CmdArgs, options::OPT__targetHelp) 1863193326Sed 1864193326Sed CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 1865193326Sed 1866193326Sed // FIXME: Still don't get what is happening here. Investigate. 1867193326Sed Args.AddAllArgs(CmdArgs, options::OPT__param); 1868193326Sed 1869193326Sed if (Args.hasArg(options::OPT_fmudflap) || 1870193326Sed Args.hasArg(options::OPT_fmudflapth)) { 1871193326Sed CmdArgs.push_back("-fno-builtin"); 1872193326Sed CmdArgs.push_back("-fno-merge-constants"); 1873193326Sed } 1874193326Sed 1875193326Sed if (Args.hasArg(options::OPT_coverage)) { 1876193326Sed CmdArgs.push_back("-fprofile-arcs"); 1877193326Sed CmdArgs.push_back("-ftest-coverage"); 1878193326Sed } 1879193326Sed 1880193326Sed if (types::isCXX(Inputs[0].getType())) 1881193326Sed CmdArgs.push_back("-D__private_extern__=extern"); 1882193326Sed} 1883193326Sed 1884193326Sedvoid darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, 1885193326Sed const InputInfoList &Inputs, 1886193326Sed const ArgStringList &OutputArgs) const { 1887193326Sed // Derived from cpp_options 1888193326Sed AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs); 1889193326Sed 1890193326Sed CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 1891193326Sed 1892193326Sed AddCC1Args(Args, CmdArgs); 1893193326Sed 1894193326Sed // NOTE: The code below has some commonality with cpp_options, but 1895193326Sed // in classic gcc style ends up sending things in different 1896193326Sed // orders. This may be a good merge candidate once we drop pedantic 1897193326Sed // compatibility. 1898193326Sed 1899193326Sed Args.AddAllArgs(CmdArgs, options::OPT_m_Group); 1900193326Sed Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi, 1901193326Sed options::OPT_trigraphs); 1902193326Sed if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 1903193326Sed // Honor -std-default. 1904193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, 1905193326Sed "-std=", /*Joined=*/true); 1906193326Sed } 1907193326Sed Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group); 1908193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 1909193326Sed 1910193326Sed // The driver treats -fsyntax-only specially. 1911193326Sed Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); 1912193326Sed 1913193326Sed if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) && 1914193326Sed !Args.hasArg(options::OPT_fno_working_directory)) 1915193326Sed CmdArgs.push_back("-fworking-directory"); 1916193326Sed 1917193326Sed Args.AddAllArgs(CmdArgs, options::OPT_O); 1918193326Sed Args.AddAllArgs(CmdArgs, options::OPT_undef); 1919193326Sed if (Args.hasArg(options::OPT_save_temps)) 1920193326Sed CmdArgs.push_back("-fpch-preprocess"); 1921193326Sed} 1922193326Sed 1923193326Sedvoid darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args, 1924193326Sed ArgStringList &CmdArgs, 1925198092Srdivacky const InputInfoList &Inputs) const { 1926201361Srdivacky const Driver &D = getToolChain().getDriver(); 1927193326Sed 1928198092Srdivacky CheckPreprocessingOptions(D, Args); 1929198092Srdivacky 1930193326Sed // Derived from cpp_unique_options. 1931198092Srdivacky // -{C,CC} only with -E is checked in CheckPreprocessingOptions(). 1932198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_C); 1933198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_CC); 1934193326Sed if (!Args.hasArg(options::OPT_Q)) 1935193326Sed CmdArgs.push_back("-quiet"); 1936193326Sed Args.AddAllArgs(CmdArgs, options::OPT_nostdinc); 1937206084Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx); 1938193326Sed Args.AddLastArg(CmdArgs, options::OPT_v); 1939193326Sed Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F); 1940193326Sed Args.AddLastArg(CmdArgs, options::OPT_P); 1941193326Sed 1942193326Sed // FIXME: Handle %I properly. 1943193326Sed if (getToolChain().getArchName() == "x86_64") { 1944193326Sed CmdArgs.push_back("-imultilib"); 1945193326Sed CmdArgs.push_back("x86_64"); 1946193326Sed } 1947193326Sed 1948193326Sed if (Args.hasArg(options::OPT_MD)) { 1949193326Sed CmdArgs.push_back("-MD"); 1950193326Sed CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs)); 1951193326Sed } 1952193326Sed 1953193326Sed if (Args.hasArg(options::OPT_MMD)) { 1954193326Sed CmdArgs.push_back("-MMD"); 1955193326Sed CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs)); 1956193326Sed } 1957193326Sed 1958193326Sed Args.AddLastArg(CmdArgs, options::OPT_M); 1959193326Sed Args.AddLastArg(CmdArgs, options::OPT_MM); 1960193326Sed Args.AddAllArgs(CmdArgs, options::OPT_MF); 1961193326Sed Args.AddLastArg(CmdArgs, options::OPT_MG); 1962193326Sed Args.AddLastArg(CmdArgs, options::OPT_MP); 1963193326Sed Args.AddAllArgs(CmdArgs, options::OPT_MQ); 1964193326Sed Args.AddAllArgs(CmdArgs, options::OPT_MT); 1965193326Sed if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) && 1966193326Sed (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) { 1967193326Sed if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 1968193326Sed CmdArgs.push_back("-MQ"); 1969193326Sed CmdArgs.push_back(OutputOpt->getValue(Args)); 1970193326Sed } 1971193326Sed } 1972193326Sed 1973193326Sed Args.AddLastArg(CmdArgs, options::OPT_remap); 1974193326Sed if (Args.hasArg(options::OPT_g3)) 1975193326Sed CmdArgs.push_back("-dD"); 1976193326Sed Args.AddLastArg(CmdArgs, options::OPT_H); 1977193326Sed 1978193326Sed AddCPPArgs(Args, CmdArgs); 1979193326Sed 1980193326Sed Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A); 1981193326Sed Args.AddAllArgs(CmdArgs, options::OPT_i_Group); 1982193326Sed 1983193326Sed for (InputInfoList::const_iterator 1984193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1985193326Sed const InputInfo &II = *it; 1986193326Sed 1987193326Sed if (II.isPipe()) 1988193326Sed CmdArgs.push_back("-"); 1989193326Sed else 1990193326Sed CmdArgs.push_back(II.getFilename()); 1991193326Sed } 1992193326Sed 1993193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, 1994193326Sed options::OPT_Xpreprocessor); 1995193326Sed 1996193326Sed if (Args.hasArg(options::OPT_fmudflap)) { 1997193326Sed CmdArgs.push_back("-D_MUDFLAP"); 1998193326Sed CmdArgs.push_back("-include"); 1999193326Sed CmdArgs.push_back("mf-runtime.h"); 2000193326Sed } 2001193326Sed 2002193326Sed if (Args.hasArg(options::OPT_fmudflapth)) { 2003193326Sed CmdArgs.push_back("-D_MUDFLAP"); 2004193326Sed CmdArgs.push_back("-D_MUDFLAPTH"); 2005193326Sed CmdArgs.push_back("-include"); 2006193326Sed CmdArgs.push_back("mf-runtime.h"); 2007193326Sed } 2008193326Sed} 2009193326Sed 2010193326Sedvoid darwin::CC1::AddCPPArgs(const ArgList &Args, 2011193326Sed ArgStringList &CmdArgs) const { 2012193326Sed // Derived from cpp spec. 2013193326Sed 2014193326Sed if (Args.hasArg(options::OPT_static)) { 2015193326Sed // The gcc spec is broken here, it refers to dynamic but 2016193326Sed // that has been translated. Start by being bug compatible. 2017193326Sed 2018193326Sed // if (!Args.hasArg(arglist.parser.dynamicOption)) 2019193326Sed CmdArgs.push_back("-D__STATIC__"); 2020193326Sed } else 2021193326Sed CmdArgs.push_back("-D__DYNAMIC__"); 2022193326Sed 2023193326Sed if (Args.hasArg(options::OPT_pthread)) 2024193326Sed CmdArgs.push_back("-D_REENTRANT"); 2025193326Sed} 2026193326Sed 2027193326Sedvoid darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, 2028193326Sed Job &Dest, const InputInfo &Output, 2029193326Sed const InputInfoList &Inputs, 2030193326Sed const ArgList &Args, 2031193326Sed const char *LinkingOutput) const { 2032193326Sed ArgStringList CmdArgs; 2033193326Sed 2034193326Sed assert(Inputs.size() == 1 && "Unexpected number of inputs!"); 2035193326Sed 2036193326Sed CmdArgs.push_back("-E"); 2037193326Sed 2038193326Sed if (Args.hasArg(options::OPT_traditional) || 2039193326Sed Args.hasArg(options::OPT_traditional_cpp)) 2040193326Sed CmdArgs.push_back("-traditional-cpp"); 2041193326Sed 2042193326Sed ArgStringList OutputArgs; 2043193326Sed if (Output.isFilename()) { 2044193326Sed OutputArgs.push_back("-o"); 2045193326Sed OutputArgs.push_back(Output.getFilename()); 2046193326Sed } else { 2047193326Sed assert(Output.isPipe() && "Unexpected CC1 output."); 2048193326Sed } 2049193326Sed 2050193326Sed if (Args.hasArg(options::OPT_E)) { 2051193326Sed AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 2052193326Sed } else { 2053193326Sed AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 2054193326Sed CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 2055193326Sed } 2056193326Sed 2057193326Sed Args.AddAllArgs(CmdArgs, options::OPT_d_Group); 2058193326Sed 2059193326Sed const char *CC1Name = getCC1Name(Inputs[0].getType()); 2060193326Sed const char *Exec = 2061198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name)); 2062200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2063193326Sed} 2064193326Sed 2065193326Sedvoid darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, 2066193326Sed Job &Dest, const InputInfo &Output, 2067193326Sed const InputInfoList &Inputs, 2068193326Sed const ArgList &Args, 2069193326Sed const char *LinkingOutput) const { 2070201361Srdivacky const Driver &D = getToolChain().getDriver(); 2071193326Sed ArgStringList CmdArgs; 2072193326Sed 2073193326Sed assert(Inputs.size() == 1 && "Unexpected number of inputs!"); 2074193326Sed 2075193326Sed types::ID InputType = Inputs[0].getType(); 2076193326Sed const Arg *A; 2077198092Srdivacky if ((A = Args.getLastArg(options::OPT_traditional))) 2078193326Sed D.Diag(clang::diag::err_drv_argument_only_allowed_with) 2079193326Sed << A->getAsString(Args) << "-E"; 2080193326Sed 2081193326Sed if (Output.getType() == types::TY_LLVMAsm) 2082193326Sed CmdArgs.push_back("-emit-llvm"); 2083193326Sed else if (Output.getType() == types::TY_LLVMBC) 2084193326Sed CmdArgs.push_back("-emit-llvm-bc"); 2085198092Srdivacky else if (Output.getType() == types::TY_AST) 2086198092Srdivacky D.Diag(clang::diag::err_drv_no_ast_support) 2087198092Srdivacky << getToolChain().getTripleString(); 2088203955Srdivacky else if (JA.getType() != types::TY_PP_Asm && 2089203955Srdivacky JA.getType() != types::TY_PCH) 2090203955Srdivacky D.Diag(clang::diag::err_drv_invalid_gcc_output_type) 2091203955Srdivacky << getTypeName(JA.getType()); 2092193326Sed 2093193326Sed ArgStringList OutputArgs; 2094193326Sed if (Output.getType() != types::TY_PCH) { 2095193326Sed OutputArgs.push_back("-o"); 2096193326Sed if (Output.isPipe()) 2097193326Sed OutputArgs.push_back("-"); 2098193326Sed else if (Output.isNothing()) 2099193326Sed OutputArgs.push_back("/dev/null"); 2100193326Sed else 2101193326Sed OutputArgs.push_back(Output.getFilename()); 2102193326Sed } 2103193326Sed 2104193326Sed // There is no need for this level of compatibility, but it makes 2105193326Sed // diffing easier. 2106193326Sed bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) || 2107193326Sed Args.hasArg(options::OPT_S)); 2108193326Sed 2109193326Sed if (types::getPreprocessedType(InputType) != types::TY_INVALID) { 2110193326Sed AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs); 2111193326Sed if (OutputArgsEarly) { 2112193326Sed AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 2113193326Sed } else { 2114193326Sed AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 2115193326Sed CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 2116193326Sed } 2117193326Sed } else { 2118193326Sed CmdArgs.push_back("-fpreprocessed"); 2119193326Sed 2120193326Sed for (InputInfoList::const_iterator 2121193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2122193326Sed const InputInfo &II = *it; 2123193326Sed 2124198092Srdivacky // Reject AST inputs. 2125198092Srdivacky if (II.getType() == types::TY_AST) { 2126198092Srdivacky D.Diag(clang::diag::err_drv_no_ast_support) 2127198092Srdivacky << getToolChain().getTripleString(); 2128198092Srdivacky return; 2129198092Srdivacky } 2130198092Srdivacky 2131193326Sed if (II.isPipe()) 2132193326Sed CmdArgs.push_back("-"); 2133193326Sed else 2134193326Sed CmdArgs.push_back(II.getFilename()); 2135193326Sed } 2136193326Sed 2137193326Sed if (OutputArgsEarly) { 2138193326Sed AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 2139193326Sed } else { 2140193326Sed AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 2141193326Sed CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 2142193326Sed } 2143193326Sed } 2144193326Sed 2145193326Sed if (Output.getType() == types::TY_PCH) { 2146193326Sed assert(Output.isFilename() && "Invalid PCH output."); 2147193326Sed 2148193326Sed CmdArgs.push_back("-o"); 2149193326Sed // NOTE: gcc uses a temp .s file for this, but there doesn't seem 2150193326Sed // to be a good reason. 2151193326Sed CmdArgs.push_back("/dev/null"); 2152193326Sed 2153193326Sed CmdArgs.push_back("--output-pch="); 2154193326Sed CmdArgs.push_back(Output.getFilename()); 2155193326Sed } 2156193326Sed 2157193326Sed const char *CC1Name = getCC1Name(Inputs[0].getType()); 2158193326Sed const char *Exec = 2159198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name)); 2160200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2161193326Sed} 2162193326Sed 2163193326Sedvoid darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 2164193326Sed Job &Dest, const InputInfo &Output, 2165193326Sed const InputInfoList &Inputs, 2166193326Sed const ArgList &Args, 2167193326Sed const char *LinkingOutput) const { 2168193326Sed ArgStringList CmdArgs; 2169193326Sed 2170193326Sed assert(Inputs.size() == 1 && "Unexpected number of inputs."); 2171193326Sed const InputInfo &Input = Inputs[0]; 2172193326Sed 2173193326Sed // Bit of a hack, this is only used for original inputs. 2174193326Sed // 2175193326Sed // FIXME: This is broken for preprocessed .s inputs. 2176193326Sed if (Input.isFilename() && 2177193326Sed strcmp(Input.getFilename(), Input.getBaseInput()) == 0) { 2178193326Sed if (Args.hasArg(options::OPT_gstabs)) 2179193326Sed CmdArgs.push_back("--gstabs"); 2180193326Sed else if (Args.hasArg(options::OPT_g_Group)) 2181193326Sed CmdArgs.push_back("--gdwarf2"); 2182193326Sed } 2183193326Sed 2184193326Sed // Derived from asm spec. 2185198092Srdivacky AddDarwinArch(Args, CmdArgs); 2186193326Sed 2187203955Srdivacky if (!getDarwinToolChain().isTargetIPhoneOS() || 2188198092Srdivacky Args.hasArg(options::OPT_force__cpusubtype__ALL)) 2189198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 2190198092Srdivacky 2191198092Srdivacky if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 && 2192198092Srdivacky (Args.hasArg(options::OPT_mkernel) || 2193193326Sed Args.hasArg(options::OPT_static) || 2194198092Srdivacky Args.hasArg(options::OPT_fapple_kext))) 2195193326Sed CmdArgs.push_back("-static"); 2196193326Sed 2197193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 2198193326Sed options::OPT_Xassembler); 2199193326Sed 2200193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 2201193326Sed CmdArgs.push_back("-o"); 2202193326Sed CmdArgs.push_back(Output.getFilename()); 2203193326Sed 2204193326Sed if (Input.isPipe()) { 2205193326Sed CmdArgs.push_back("-"); 2206193326Sed } else { 2207193326Sed assert(Input.isFilename() && "Invalid input."); 2208193326Sed CmdArgs.push_back(Input.getFilename()); 2209193326Sed } 2210193326Sed 2211193326Sed // asm_final spec is empty. 2212193326Sed 2213193326Sed const char *Exec = 2214198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "as")); 2215200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2216193326Sed} 2217193326Sed 2218193326Sed/// Helper routine for seeing if we should use dsymutil; this is a 2219193326Sed/// gcc compatible hack, we should remove it and use the input 2220193326Sed/// type information. 2221193326Sedstatic bool isSourceSuffix(const char *Str) { 2222193326Sed // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm', 2223193326Sed // 'mm'. 2224198893Srdivacky return llvm::StringSwitch<bool>(Str) 2225198893Srdivacky .Case("C", true) 2226198893Srdivacky .Case("c", true) 2227198893Srdivacky .Case("m", true) 2228198893Srdivacky .Case("cc", true) 2229198893Srdivacky .Case("cp", true) 2230198893Srdivacky .Case("mm", true) 2231198893Srdivacky .Case("CPP", true) 2232198893Srdivacky .Case("c++", true) 2233198893Srdivacky .Case("cpp", true) 2234198893Srdivacky .Case("cxx", true) 2235198893Srdivacky .Default(false); 2236193326Sed} 2237193326Sed 2238198092Srdivackyvoid darwin::DarwinTool::AddDarwinArch(const ArgList &Args, 2239198092Srdivacky ArgStringList &CmdArgs) const { 2240202879Srdivacky llvm::StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args); 2241202879Srdivacky 2242193326Sed // Derived from darwin_arch spec. 2243193326Sed CmdArgs.push_back("-arch"); 2244202879Srdivacky CmdArgs.push_back(Args.MakeArgString(ArchName)); 2245198092Srdivacky 2246202879Srdivacky // FIXME: Is this needed anymore? 2247202879Srdivacky if (ArchName == "arm") 2248198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 2249193326Sed} 2250193326Sed 2251193326Sedvoid darwin::Link::AddLinkArgs(const ArgList &Args, 2252193326Sed ArgStringList &CmdArgs) const { 2253201361Srdivacky const Driver &D = getToolChain().getDriver(); 2254193326Sed 2255193326Sed // Derived from the "link" spec. 2256193326Sed Args.AddAllArgs(CmdArgs, options::OPT_static); 2257193326Sed if (!Args.hasArg(options::OPT_static)) 2258193326Sed CmdArgs.push_back("-dynamic"); 2259193326Sed if (Args.hasArg(options::OPT_fgnu_runtime)) { 2260193326Sed // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 2261193326Sed // here. How do we wish to handle such things? 2262193326Sed } 2263193326Sed 2264193326Sed if (!Args.hasArg(options::OPT_dynamiclib)) { 2265202879Srdivacky AddDarwinArch(Args, CmdArgs); 2266202879Srdivacky // FIXME: Why do this only on this path? 2267202879Srdivacky Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 2268193326Sed 2269193326Sed Args.AddLastArg(CmdArgs, options::OPT_bundle); 2270193326Sed Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 2271193326Sed Args.AddAllArgs(CmdArgs, options::OPT_client__name); 2272193326Sed 2273193326Sed Arg *A; 2274193326Sed if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 2275193326Sed (A = Args.getLastArg(options::OPT_current__version)) || 2276193326Sed (A = Args.getLastArg(options::OPT_install__name))) 2277193326Sed D.Diag(clang::diag::err_drv_argument_only_allowed_with) 2278193326Sed << A->getAsString(Args) << "-dynamiclib"; 2279193326Sed 2280193326Sed Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 2281193326Sed Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 2282193326Sed Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 2283193326Sed } else { 2284193326Sed CmdArgs.push_back("-dylib"); 2285193326Sed 2286193326Sed Arg *A; 2287193326Sed if ((A = Args.getLastArg(options::OPT_bundle)) || 2288193326Sed (A = Args.getLastArg(options::OPT_bundle__loader)) || 2289193326Sed (A = Args.getLastArg(options::OPT_client__name)) || 2290193326Sed (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 2291193326Sed (A = Args.getLastArg(options::OPT_keep__private__externs)) || 2292193326Sed (A = Args.getLastArg(options::OPT_private__bundle))) 2293193326Sed D.Diag(clang::diag::err_drv_argument_not_allowed_with) 2294193326Sed << A->getAsString(Args) << "-dynamiclib"; 2295193326Sed 2296193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 2297193326Sed "-dylib_compatibility_version"); 2298193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 2299193326Sed "-dylib_current_version"); 2300193326Sed 2301202879Srdivacky AddDarwinArch(Args, CmdArgs); 2302193326Sed 2303193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 2304193326Sed "-dylib_install_name"); 2305193326Sed } 2306193326Sed 2307193326Sed Args.AddLastArg(CmdArgs, options::OPT_all__load); 2308193326Sed Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 2309193326Sed Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 2310203955Srdivacky if (getDarwinToolChain().isTargetIPhoneOS()) 2311198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 2312193326Sed Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 2313193326Sed Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 2314193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 2315193326Sed Args.AddLastArg(CmdArgs, options::OPT_dynamic); 2316193326Sed Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 2317193326Sed Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 2318193326Sed Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 2319193326Sed Args.AddAllArgs(CmdArgs, options::OPT_image__base); 2320193326Sed Args.AddAllArgs(CmdArgs, options::OPT_init); 2321193326Sed 2322203955Srdivacky // Adding all arguments doesn't make sense here but this is what gcc does. One 2323203955Srdivacky // of this should always be present thanks to argument translation. 2324203955Srdivacky assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) || 2325203955Srdivacky Args.hasArg(options::OPT_miphoneos_version_min_EQ)) && 2326203955Srdivacky "Missing version argument (lost in translation)?"); 2327198092Srdivacky Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ, 2328198893Srdivacky "-macosx_version_min"); 2329193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ, 2330193326Sed "-iphoneos_version_min"); 2331193326Sed Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 2332193326Sed Args.AddLastArg(CmdArgs, options::OPT_multi__module); 2333193326Sed Args.AddLastArg(CmdArgs, options::OPT_single__module); 2334193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 2335193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 2336193326Sed 2337193326Sed if (Args.hasArg(options::OPT_fpie)) 2338193326Sed CmdArgs.push_back("-pie"); 2339193326Sed 2340193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind); 2341193326Sed Args.AddLastArg(CmdArgs, options::OPT_noprebind); 2342193326Sed Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 2343193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 2344193326Sed Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 2345193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 2346193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 2347193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 2348193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segprot); 2349193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 2350193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 2351193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 2352193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 2353193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 2354193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 2355193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 2356198092Srdivacky 2357193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot"); 2358203955Srdivacky if (getDarwinToolChain().isTargetIPhoneOS()) { 2359198092Srdivacky if (!Args.hasArg(options::OPT_isysroot)) { 2360198092Srdivacky CmdArgs.push_back("-syslibroot"); 2361198092Srdivacky CmdArgs.push_back("/Developer/SDKs/Extra"); 2362198092Srdivacky } 2363198092Srdivacky } 2364198092Srdivacky 2365193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 2366193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 2367193326Sed Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 2368193326Sed Args.AddAllArgs(CmdArgs, options::OPT_undefined); 2369193326Sed Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 2370193326Sed Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 2371193326Sed Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 2372193326Sed Args.AddAllArgs(CmdArgs, options::OPT_y); 2373193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 2374193326Sed Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 2375193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 2376193326Sed Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 2377193326Sed Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 2378193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 2379193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 2380193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 2381193326Sed Args.AddLastArg(CmdArgs, options::OPT_whyload); 2382193326Sed Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 2383193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 2384193326Sed Args.AddLastArg(CmdArgs, options::OPT_dylinker); 2385193326Sed Args.AddLastArg(CmdArgs, options::OPT_Mach); 2386193326Sed} 2387193326Sed 2388193326Sedvoid darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, 2389193326Sed Job &Dest, const InputInfo &Output, 2390193326Sed const InputInfoList &Inputs, 2391193326Sed const ArgList &Args, 2392193326Sed const char *LinkingOutput) const { 2393193326Sed assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 2394198092Srdivacky 2395193326Sed // The logic here is derived from gcc's behavior; most of which 2396193326Sed // comes from specs (starting with link_command). Consult gcc for 2397193326Sed // more information. 2398193326Sed ArgStringList CmdArgs; 2399193326Sed 2400193326Sed // I'm not sure why this particular decomposition exists in gcc, but 2401193326Sed // we follow suite for ease of comparison. 2402193326Sed AddLinkArgs(Args, CmdArgs); 2403193326Sed 2404193326Sed Args.AddAllArgs(CmdArgs, options::OPT_d_Flag); 2405193326Sed Args.AddAllArgs(CmdArgs, options::OPT_s); 2406193326Sed Args.AddAllArgs(CmdArgs, options::OPT_t); 2407193326Sed Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 2408193326Sed Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 2409193326Sed Args.AddAllArgs(CmdArgs, options::OPT_A); 2410193326Sed Args.AddLastArg(CmdArgs, options::OPT_e); 2411193326Sed Args.AddAllArgs(CmdArgs, options::OPT_m_Separate); 2412193326Sed Args.AddAllArgs(CmdArgs, options::OPT_r); 2413193326Sed 2414193326Sed CmdArgs.push_back("-o"); 2415193326Sed CmdArgs.push_back(Output.getFilename()); 2416193326Sed 2417193326Sed if (!Args.hasArg(options::OPT_A) && 2418193326Sed !Args.hasArg(options::OPT_nostdlib) && 2419193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 2420193326Sed // Derived from startfile spec. 2421193326Sed if (Args.hasArg(options::OPT_dynamiclib)) { 2422193326Sed // Derived from darwin_dylib1 spec. 2423203955Srdivacky if (getDarwinToolChain().isTargetIPhoneOS()) { 2424203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 2425203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 2426203955Srdivacky } else { 2427203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 2428203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 2429203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 2430203955Srdivacky CmdArgs.push_back("-ldylib1.10.5.o"); 2431203955Srdivacky } 2432193326Sed } else { 2433193326Sed if (Args.hasArg(options::OPT_bundle)) { 2434193326Sed if (!Args.hasArg(options::OPT_static)) { 2435193326Sed // Derived from darwin_bundle1 spec. 2436203955Srdivacky if (getDarwinToolChain().isTargetIPhoneOS()) { 2437203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 2438203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 2439203955Srdivacky } else { 2440203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 2441203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 2442203955Srdivacky } 2443193326Sed } 2444193326Sed } else { 2445193326Sed if (Args.hasArg(options::OPT_pg)) { 2446193326Sed if (Args.hasArg(options::OPT_static) || 2447193326Sed Args.hasArg(options::OPT_object) || 2448193326Sed Args.hasArg(options::OPT_preload)) { 2449193326Sed CmdArgs.push_back("-lgcrt0.o"); 2450193326Sed } else { 2451193326Sed CmdArgs.push_back("-lgcrt1.o"); 2452193326Sed 2453193326Sed // darwin_crt2 spec is empty. 2454193326Sed } 2455193326Sed } else { 2456193326Sed if (Args.hasArg(options::OPT_static) || 2457193326Sed Args.hasArg(options::OPT_object) || 2458193326Sed Args.hasArg(options::OPT_preload)) { 2459193326Sed CmdArgs.push_back("-lcrt0.o"); 2460193326Sed } else { 2461193326Sed // Derived from darwin_crt1 spec. 2462203955Srdivacky if (getDarwinToolChain().isTargetIPhoneOS()) { 2463203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 2464203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 2465203955Srdivacky else 2466203955Srdivacky CmdArgs.push_back("-lcrt1.3.1.o"); 2467203955Srdivacky } else { 2468203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 2469203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 2470203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 2471203955Srdivacky CmdArgs.push_back("-lcrt1.10.5.o"); 2472203955Srdivacky else 2473203955Srdivacky CmdArgs.push_back("-lcrt1.10.6.o"); 2474193326Sed 2475203955Srdivacky // darwin_crt2 spec is empty. 2476203955Srdivacky } 2477193326Sed } 2478193326Sed } 2479193326Sed } 2480193326Sed } 2481193326Sed 2482203955Srdivacky if (!getDarwinToolChain().isTargetIPhoneOS() && 2483203955Srdivacky Args.hasArg(options::OPT_shared_libgcc) && 2484203955Srdivacky getDarwinToolChain().isMacosxVersionLT(10, 5)) { 2485198092Srdivacky const char *Str = 2486198092Srdivacky Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o")); 2487198092Srdivacky CmdArgs.push_back(Str); 2488193326Sed } 2489193326Sed } 2490193326Sed 2491193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 2492193326Sed 2493193326Sed if (Args.hasArg(options::OPT_fopenmp)) 2494193326Sed // This is more complicated in gcc... 2495193326Sed CmdArgs.push_back("-lgomp"); 2496193326Sed 2497198092Srdivacky getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs); 2498193326Sed 2499193326Sed for (InputInfoList::const_iterator 2500193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2501193326Sed const InputInfo &II = *it; 2502193326Sed if (II.isFilename()) 2503193326Sed CmdArgs.push_back(II.getFilename()); 2504193326Sed else 2505193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 2506193326Sed } 2507193326Sed 2508193326Sed if (LinkingOutput) { 2509193326Sed CmdArgs.push_back("-arch_multiple"); 2510193326Sed CmdArgs.push_back("-final_output"); 2511193326Sed CmdArgs.push_back(LinkingOutput); 2512193326Sed } 2513193326Sed 2514193326Sed if (Args.hasArg(options::OPT_fprofile_arcs) || 2515193326Sed Args.hasArg(options::OPT_fprofile_generate) || 2516193326Sed Args.hasArg(options::OPT_fcreate_profile) || 2517193326Sed Args.hasArg(options::OPT_coverage)) 2518193326Sed CmdArgs.push_back("-lgcov"); 2519193326Sed 2520193326Sed if (Args.hasArg(options::OPT_fnested_functions)) 2521193326Sed CmdArgs.push_back("-allow_stack_execute"); 2522193326Sed 2523193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 2524193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 2525193326Sed // FIXME: g++ is more complicated here, it tries to put -lstdc++ 2526193326Sed // before -lm, for example. 2527201361Srdivacky if (getToolChain().getDriver().CCCIsCXX) 2528193326Sed CmdArgs.push_back("-lstdc++"); 2529193326Sed 2530193326Sed // link_ssp spec is empty. 2531193326Sed 2532198092Srdivacky // Let the tool chain choose which runtime library to link. 2533198092Srdivacky getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); 2534193326Sed } 2535193326Sed 2536193326Sed if (!Args.hasArg(options::OPT_A) && 2537193326Sed !Args.hasArg(options::OPT_nostdlib) && 2538193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 2539193326Sed // endfile_spec is empty. 2540193326Sed } 2541193326Sed 2542193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 2543193326Sed Args.AddAllArgs(CmdArgs, options::OPT_F); 2544193326Sed 2545193326Sed const char *Exec = 2546198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "ld")); 2547200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2548193326Sed 2549193326Sed // Find the first non-empty base input (we want to ignore linker 2550193326Sed // inputs). 2551193326Sed const char *BaseInput = ""; 2552193326Sed for (unsigned i = 0, e = Inputs.size(); i != e; ++i) { 2553193326Sed if (Inputs[i].getBaseInput()[0] != '\0') { 2554193326Sed BaseInput = Inputs[i].getBaseInput(); 2555193326Sed break; 2556193326Sed } 2557193326Sed } 2558193326Sed 2559193326Sed // Run dsymutil if we are making an executable in a single step. 2560193326Sed // 2561193326Sed // FIXME: Currently we don't want to do this when we are part of a 2562193326Sed // universal build step, as this would end up creating stray temp 2563193326Sed // files. 2564193326Sed if (!LinkingOutput && 2565193326Sed Args.getLastArg(options::OPT_g_Group) && 2566193326Sed !Args.getLastArg(options::OPT_gstabs) && 2567193326Sed !Args.getLastArg(options::OPT_g0)) { 2568193326Sed // FIXME: This is gross, but matches gcc. The test only considers 2569193326Sed // the suffix (not the -x type), and then only of the first 2570193326Sed // source input. Awesome. 2571193326Sed const char *Suffix = strrchr(BaseInput, '.'); 2572193326Sed if (Suffix && isSourceSuffix(Suffix + 1)) { 2573193326Sed const char *Exec = 2574198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil")); 2575193326Sed ArgStringList CmdArgs; 2576193326Sed CmdArgs.push_back(Output.getFilename()); 2577200583Srdivacky C.getJobs().addCommand(new Command(JA, *this, Exec, CmdArgs)); 2578193326Sed } 2579193326Sed } 2580193326Sed} 2581193326Sed 2582193326Sedvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 2583193326Sed Job &Dest, const InputInfo &Output, 2584193326Sed const InputInfoList &Inputs, 2585193326Sed const ArgList &Args, 2586193326Sed const char *LinkingOutput) const { 2587193326Sed ArgStringList CmdArgs; 2588193326Sed 2589193326Sed CmdArgs.push_back("-create"); 2590193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 2591193326Sed 2592193326Sed CmdArgs.push_back("-output"); 2593193326Sed CmdArgs.push_back(Output.getFilename()); 2594193326Sed 2595193326Sed for (InputInfoList::const_iterator 2596193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2597193326Sed const InputInfo &II = *it; 2598193326Sed assert(II.isFilename() && "Unexpected lipo input."); 2599193326Sed CmdArgs.push_back(II.getFilename()); 2600193326Sed } 2601193326Sed const char *Exec = 2602198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo")); 2603200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2604193326Sed} 2605193326Sed 2606198092Srdivackyvoid auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 2607198893Srdivacky Job &Dest, const InputInfo &Output, 2608198893Srdivacky const InputInfoList &Inputs, 2609198893Srdivacky const ArgList &Args, 2610198893Srdivacky const char *LinkingOutput) const { 2611198092Srdivacky ArgStringList CmdArgs; 2612198092Srdivacky 2613198092Srdivacky Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 2614198092Srdivacky options::OPT_Xassembler); 2615198092Srdivacky 2616198092Srdivacky CmdArgs.push_back("-o"); 2617198092Srdivacky if (Output.isPipe()) 2618198092Srdivacky CmdArgs.push_back("-"); 2619198092Srdivacky else 2620198092Srdivacky CmdArgs.push_back(Output.getFilename()); 2621198092Srdivacky 2622198092Srdivacky for (InputInfoList::const_iterator 2623198092Srdivacky it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2624198092Srdivacky const InputInfo &II = *it; 2625198092Srdivacky if (II.isPipe()) 2626198092Srdivacky CmdArgs.push_back("-"); 2627198092Srdivacky else 2628198092Srdivacky CmdArgs.push_back(II.getFilename()); 2629198092Srdivacky } 2630198092Srdivacky 2631198092Srdivacky const char *Exec = 2632198398Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "gas")); 2633200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2634198092Srdivacky} 2635198092Srdivacky 2636198092Srdivackyvoid auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, 2637198893Srdivacky Job &Dest, const InputInfo &Output, 2638198893Srdivacky const InputInfoList &Inputs, 2639198893Srdivacky const ArgList &Args, 2640198893Srdivacky const char *LinkingOutput) const { 2641201361Srdivacky const Driver &D = getToolChain().getDriver(); 2642198092Srdivacky ArgStringList CmdArgs; 2643198092Srdivacky 2644198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 2645198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 2646198092Srdivacky CmdArgs.push_back("-e"); 2647198398Srdivacky CmdArgs.push_back("_start"); 2648198092Srdivacky } 2649198092Srdivacky 2650198092Srdivacky if (Args.hasArg(options::OPT_static)) { 2651198092Srdivacky CmdArgs.push_back("-Bstatic"); 2652198398Srdivacky CmdArgs.push_back("-dn"); 2653198092Srdivacky } else { 2654198398Srdivacky// CmdArgs.push_back("--eh-frame-hdr"); 2655198092Srdivacky CmdArgs.push_back("-Bdynamic"); 2656198092Srdivacky if (Args.hasArg(options::OPT_shared)) { 2657198092Srdivacky CmdArgs.push_back("-shared"); 2658198092Srdivacky } else { 2659198398Srdivacky CmdArgs.push_back("--dynamic-linker"); 2660198092Srdivacky CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1 2661198092Srdivacky } 2662198092Srdivacky } 2663198092Srdivacky 2664198092Srdivacky if (Output.isPipe()) { 2665198092Srdivacky CmdArgs.push_back("-o"); 2666198092Srdivacky CmdArgs.push_back("-"); 2667198092Srdivacky } else if (Output.isFilename()) { 2668198092Srdivacky CmdArgs.push_back("-o"); 2669198092Srdivacky CmdArgs.push_back(Output.getFilename()); 2670198092Srdivacky } else { 2671198092Srdivacky assert(Output.isNothing() && "Invalid output."); 2672198092Srdivacky } 2673198092Srdivacky 2674198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 2675198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 2676198092Srdivacky if (!Args.hasArg(options::OPT_shared)) { 2677198398Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o"))); 2678198398Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 2679198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); 2680198092Srdivacky } else { 2681198398Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 2682198092Srdivacky } 2683198398Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o"))); 2684198092Srdivacky } 2685198092Srdivacky 2686198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/" 2687198893Srdivacky + getToolChain().getTripleString() 2688198893Srdivacky + "/4.2.4")); 2689198092Srdivacky 2690198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_L); 2691198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 2692198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_e); 2693198092Srdivacky 2694198092Srdivacky for (InputInfoList::const_iterator 2695198092Srdivacky it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2696198092Srdivacky const InputInfo &II = *it; 2697198092Srdivacky 2698198092Srdivacky // Don't try to pass LLVM inputs to a generic gcc. 2699198092Srdivacky if (II.getType() == types::TY_LLVMBC) 2700198092Srdivacky D.Diag(clang::diag::err_drv_no_linker_llvm_support) 2701198092Srdivacky << getToolChain().getTripleString(); 2702198092Srdivacky 2703198092Srdivacky if (II.isPipe()) 2704198092Srdivacky CmdArgs.push_back("-"); 2705198092Srdivacky else if (II.isFilename()) 2706198092Srdivacky CmdArgs.push_back(II.getFilename()); 2707198092Srdivacky else 2708198092Srdivacky II.getInputArg().renderAsInput(Args, CmdArgs); 2709198092Srdivacky } 2710198092Srdivacky 2711198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 2712198092Srdivacky !Args.hasArg(options::OPT_nodefaultlibs)) { 2713198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 2714198092Srdivacky // the default system libraries. Just mimic this for now. 2715198092Srdivacky CmdArgs.push_back("-lgcc"); 2716198092Srdivacky 2717198092Srdivacky if (Args.hasArg(options::OPT_pthread)) 2718198092Srdivacky CmdArgs.push_back("-pthread"); 2719198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 2720198092Srdivacky CmdArgs.push_back("-lc"); 2721198092Srdivacky CmdArgs.push_back("-lgcc"); 2722198092Srdivacky } 2723198092Srdivacky 2724198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 2725198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 2726198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 2727198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o"))); 2728198398Srdivacky// else 2729198398Srdivacky// CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o"))); 2730198092Srdivacky } 2731198092Srdivacky 2732198092Srdivacky const char *Exec = 2733198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "ld")); 2734200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2735198092Srdivacky} 2736198092Srdivacky 2737195341Sedvoid openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 2738195341Sed Job &Dest, const InputInfo &Output, 2739195341Sed const InputInfoList &Inputs, 2740195341Sed const ArgList &Args, 2741198092Srdivacky const char *LinkingOutput) const { 2742195341Sed ArgStringList CmdArgs; 2743193326Sed 2744195341Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 2745195341Sed options::OPT_Xassembler); 2746195341Sed 2747195341Sed CmdArgs.push_back("-o"); 2748195341Sed if (Output.isPipe()) 2749195341Sed CmdArgs.push_back("-"); 2750195341Sed else 2751195341Sed CmdArgs.push_back(Output.getFilename()); 2752195341Sed 2753195341Sed for (InputInfoList::const_iterator 2754195341Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2755195341Sed const InputInfo &II = *it; 2756195341Sed if (II.isPipe()) 2757195341Sed CmdArgs.push_back("-"); 2758195341Sed else 2759195341Sed CmdArgs.push_back(II.getFilename()); 2760195341Sed } 2761195341Sed 2762195341Sed const char *Exec = 2763198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "as")); 2764200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2765195341Sed} 2766195341Sed 2767195341Sedvoid openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 2768195341Sed Job &Dest, const InputInfo &Output, 2769195341Sed const InputInfoList &Inputs, 2770195341Sed const ArgList &Args, 2771195341Sed const char *LinkingOutput) const { 2772201361Srdivacky const Driver &D = getToolChain().getDriver(); 2773195341Sed ArgStringList CmdArgs; 2774195341Sed 2775198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 2776198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 2777198092Srdivacky CmdArgs.push_back("-e"); 2778198092Srdivacky CmdArgs.push_back("__start"); 2779198092Srdivacky } 2780198092Srdivacky 2781195341Sed if (Args.hasArg(options::OPT_static)) { 2782195341Sed CmdArgs.push_back("-Bstatic"); 2783195341Sed } else { 2784195341Sed CmdArgs.push_back("--eh-frame-hdr"); 2785198092Srdivacky CmdArgs.push_back("-Bdynamic"); 2786195341Sed if (Args.hasArg(options::OPT_shared)) { 2787198092Srdivacky CmdArgs.push_back("-shared"); 2788195341Sed } else { 2789195341Sed CmdArgs.push_back("-dynamic-linker"); 2790195341Sed CmdArgs.push_back("/usr/libexec/ld.so"); 2791195341Sed } 2792195341Sed } 2793195341Sed 2794195341Sed if (Output.isPipe()) { 2795195341Sed CmdArgs.push_back("-o"); 2796195341Sed CmdArgs.push_back("-"); 2797195341Sed } else if (Output.isFilename()) { 2798195341Sed CmdArgs.push_back("-o"); 2799195341Sed CmdArgs.push_back(Output.getFilename()); 2800195341Sed } else { 2801195341Sed assert(Output.isNothing() && "Invalid output."); 2802195341Sed } 2803195341Sed 2804195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 2805195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 2806195341Sed if (!Args.hasArg(options::OPT_shared)) { 2807198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o"))); 2808198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); 2809195341Sed } else { 2810198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o"))); 2811195341Sed } 2812195341Sed } 2813195341Sed 2814198893Srdivacky std::string Triple = getToolChain().getTripleString(); 2815198893Srdivacky if (Triple.substr(0, 6) == "x86_64") 2816198893Srdivacky Triple.replace(0, 6, "amd64"); 2817198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + 2818198893Srdivacky "/3.3.5")); 2819198092Srdivacky 2820195341Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 2821195341Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 2822195341Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 2823195341Sed 2824195341Sed for (InputInfoList::const_iterator 2825195341Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2826195341Sed const InputInfo &II = *it; 2827195341Sed 2828195341Sed // Don't try to pass LLVM inputs to a generic gcc. 2829195341Sed if (II.getType() == types::TY_LLVMBC) 2830195341Sed D.Diag(clang::diag::err_drv_no_linker_llvm_support) 2831198092Srdivacky << getToolChain().getTripleString(); 2832195341Sed 2833195341Sed if (II.isPipe()) 2834195341Sed CmdArgs.push_back("-"); 2835195341Sed else if (II.isFilename()) 2836195341Sed CmdArgs.push_back(II.getFilename()); 2837195341Sed else 2838195341Sed II.getInputArg().renderAsInput(Args, CmdArgs); 2839195341Sed } 2840195341Sed 2841195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 2842195341Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 2843198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 2844198092Srdivacky // the default system libraries. Just mimic this for now. 2845198092Srdivacky CmdArgs.push_back("-lgcc"); 2846195341Sed 2847195341Sed if (Args.hasArg(options::OPT_pthread)) 2848195341Sed CmdArgs.push_back("-pthread"); 2849198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 2850198092Srdivacky CmdArgs.push_back("-lc"); 2851198092Srdivacky CmdArgs.push_back("-lgcc"); 2852195341Sed } 2853195341Sed 2854195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 2855195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 2856195341Sed if (!Args.hasArg(options::OPT_shared)) 2857198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o"))); 2858195341Sed else 2859198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o"))); 2860195341Sed } 2861195341Sed 2862195341Sed const char *Exec = 2863198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "ld")); 2864200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2865195341Sed} 2866195341Sed 2867193326Sedvoid freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 2868193326Sed Job &Dest, const InputInfo &Output, 2869193326Sed const InputInfoList &Inputs, 2870193326Sed const ArgList &Args, 2871198092Srdivacky const char *LinkingOutput) const { 2872193326Sed ArgStringList CmdArgs; 2873193326Sed 2874193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 2875193326Sed // instruct as in the base system to assemble 32-bit code. 2876193326Sed if (getToolChain().getArchName() == "i386") 2877193326Sed CmdArgs.push_back("--32"); 2878193326Sed 2879204643Srdivacky 2880204643Srdivacky // Set byte order explicitly 2881204643Srdivacky if (getToolChain().getArchName() == "mips") 2882204643Srdivacky CmdArgs.push_back("-EB"); 2883204643Srdivacky else if (getToolChain().getArchName() == "mipsel") 2884204643Srdivacky CmdArgs.push_back("-EL"); 2885204643Srdivacky 2886193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 2887193326Sed options::OPT_Xassembler); 2888193326Sed 2889193326Sed CmdArgs.push_back("-o"); 2890193326Sed if (Output.isPipe()) 2891193326Sed CmdArgs.push_back("-"); 2892193326Sed else 2893193326Sed CmdArgs.push_back(Output.getFilename()); 2894193326Sed 2895193326Sed for (InputInfoList::const_iterator 2896193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2897193326Sed const InputInfo &II = *it; 2898193326Sed if (II.isPipe()) 2899193326Sed CmdArgs.push_back("-"); 2900193326Sed else 2901193326Sed CmdArgs.push_back(II.getFilename()); 2902193326Sed } 2903193326Sed 2904193326Sed const char *Exec = 2905198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "as")); 2906200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 2907193326Sed} 2908193326Sed 2909193326Sedvoid freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 2910193326Sed Job &Dest, const InputInfo &Output, 2911193326Sed const InputInfoList &Inputs, 2912193326Sed const ArgList &Args, 2913193326Sed const char *LinkingOutput) const { 2914201361Srdivacky const Driver &D = getToolChain().getDriver(); 2915193326Sed ArgStringList CmdArgs; 2916193326Sed 2917193326Sed if (Args.hasArg(options::OPT_static)) { 2918193326Sed CmdArgs.push_back("-Bstatic"); 2919193326Sed } else { 2920193326Sed CmdArgs.push_back("--eh-frame-hdr"); 2921193326Sed if (Args.hasArg(options::OPT_shared)) { 2922193326Sed CmdArgs.push_back("-Bshareable"); 2923193326Sed } else { 2924193326Sed CmdArgs.push_back("-dynamic-linker"); 2925193326Sed CmdArgs.push_back("/libexec/ld-elf.so.1"); 2926193326Sed } 2927193326Sed } 2928193326Sed 2929193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 2930193326Sed // instruct ld in the base system to link 32-bit code. 2931193326Sed if (getToolChain().getArchName() == "i386") { 2932193326Sed CmdArgs.push_back("-m"); 2933193326Sed CmdArgs.push_back("elf_i386_fbsd"); 2934193326Sed } 2935193326Sed 2936193326Sed if (Output.isPipe()) { 2937193326Sed CmdArgs.push_back("-o"); 2938193326Sed CmdArgs.push_back("-"); 2939193326Sed } else if (Output.isFilename()) { 2940193326Sed CmdArgs.push_back("-o"); 2941193326Sed CmdArgs.push_back(Output.getFilename()); 2942193326Sed } else { 2943193326Sed assert(Output.isNothing() && "Invalid output."); 2944193326Sed } 2945193326Sed 2946193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 2947193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 2948193326Sed if (!Args.hasArg(options::OPT_shared)) { 2949198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o"))); 2950198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 2951198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); 2952193326Sed } else { 2953198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 2954198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o"))); 2955193326Sed } 2956193326Sed } 2957193326Sed 2958193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 2959193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 2960193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 2961193326Sed 2962193326Sed for (InputInfoList::const_iterator 2963193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 2964193326Sed const InputInfo &II = *it; 2965193326Sed 2966193326Sed // Don't try to pass LLVM inputs to a generic gcc. 2967193326Sed if (II.getType() == types::TY_LLVMBC) 2968193326Sed D.Diag(clang::diag::err_drv_no_linker_llvm_support) 2969198092Srdivacky << getToolChain().getTripleString(); 2970193326Sed 2971193326Sed if (II.isPipe()) 2972193326Sed CmdArgs.push_back("-"); 2973193326Sed else if (II.isFilename()) 2974193326Sed CmdArgs.push_back(II.getFilename()); 2975193326Sed else 2976193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 2977193326Sed } 2978193326Sed 2979193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 2980193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 2981204643Srdivacky if (D.CCCIsCXX) { 2982204643Srdivacky CmdArgs.push_back("-lstdc++"); 2983204643Srdivacky CmdArgs.push_back("-lm"); 2984204643Srdivacky } 2985193326Sed // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding 2986193326Sed // the default system libraries. Just mimic this for now. 2987193326Sed CmdArgs.push_back("-lgcc"); 2988193326Sed if (Args.hasArg(options::OPT_static)) { 2989193326Sed CmdArgs.push_back("-lgcc_eh"); 2990193326Sed } else { 2991193326Sed CmdArgs.push_back("--as-needed"); 2992193326Sed CmdArgs.push_back("-lgcc_s"); 2993193326Sed CmdArgs.push_back("--no-as-needed"); 2994193326Sed } 2995193326Sed 2996193326Sed if (Args.hasArg(options::OPT_pthread)) 2997193326Sed CmdArgs.push_back("-lpthread"); 2998193326Sed CmdArgs.push_back("-lc"); 2999193326Sed 3000193326Sed CmdArgs.push_back("-lgcc"); 3001193326Sed if (Args.hasArg(options::OPT_static)) { 3002193326Sed CmdArgs.push_back("-lgcc_eh"); 3003193326Sed } else { 3004193326Sed CmdArgs.push_back("--as-needed"); 3005193326Sed CmdArgs.push_back("-lgcc_s"); 3006193326Sed CmdArgs.push_back("--no-as-needed"); 3007193326Sed } 3008193326Sed } 3009193326Sed 3010193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 3011193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 3012193326Sed if (!Args.hasArg(options::OPT_shared)) 3013198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o"))); 3014193326Sed else 3015198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o"))); 3016198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o"))); 3017193326Sed } 3018193326Sed 3019193326Sed const char *Exec = 3020198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "ld")); 3021200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 3022193326Sed} 3023193326Sed 3024193326Sed/// DragonFly Tools 3025193326Sed 3026193326Sed// For now, DragonFly Assemble does just about the same as for 3027193326Sed// FreeBSD, but this may change soon. 3028193326Sedvoid dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 3029198893Srdivacky Job &Dest, const InputInfo &Output, 3030198893Srdivacky const InputInfoList &Inputs, 3031198893Srdivacky const ArgList &Args, 3032198893Srdivacky const char *LinkingOutput) const { 3033193326Sed ArgStringList CmdArgs; 3034193326Sed 3035193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 3036193326Sed // instruct as in the base system to assemble 32-bit code. 3037193326Sed if (getToolChain().getArchName() == "i386") 3038193326Sed CmdArgs.push_back("--32"); 3039193326Sed 3040193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 3041193326Sed options::OPT_Xassembler); 3042193326Sed 3043193326Sed CmdArgs.push_back("-o"); 3044193326Sed if (Output.isPipe()) 3045193326Sed CmdArgs.push_back("-"); 3046193326Sed else 3047193326Sed CmdArgs.push_back(Output.getFilename()); 3048193326Sed 3049193326Sed for (InputInfoList::const_iterator 3050193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 3051193326Sed const InputInfo &II = *it; 3052193326Sed if (II.isPipe()) 3053193326Sed CmdArgs.push_back("-"); 3054193326Sed else 3055193326Sed CmdArgs.push_back(II.getFilename()); 3056193326Sed } 3057193326Sed 3058193326Sed const char *Exec = 3059198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "as")); 3060200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 3061193326Sed} 3062193326Sed 3063193326Sedvoid dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, 3064193326Sed Job &Dest, const InputInfo &Output, 3065193326Sed const InputInfoList &Inputs, 3066193326Sed const ArgList &Args, 3067193326Sed const char *LinkingOutput) const { 3068201361Srdivacky const Driver &D = getToolChain().getDriver(); 3069193326Sed ArgStringList CmdArgs; 3070193326Sed 3071193326Sed if (Args.hasArg(options::OPT_static)) { 3072193326Sed CmdArgs.push_back("-Bstatic"); 3073193326Sed } else { 3074193326Sed if (Args.hasArg(options::OPT_shared)) 3075193326Sed CmdArgs.push_back("-Bshareable"); 3076193326Sed else { 3077193326Sed CmdArgs.push_back("-dynamic-linker"); 3078193326Sed CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); 3079193326Sed } 3080193326Sed } 3081193326Sed 3082193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 3083193326Sed // instruct ld in the base system to link 32-bit code. 3084193326Sed if (getToolChain().getArchName() == "i386") { 3085193326Sed CmdArgs.push_back("-m"); 3086193326Sed CmdArgs.push_back("elf_i386"); 3087193326Sed } 3088193326Sed 3089193326Sed if (Output.isPipe()) { 3090193326Sed CmdArgs.push_back("-o"); 3091193326Sed CmdArgs.push_back("-"); 3092193326Sed } else if (Output.isFilename()) { 3093193326Sed CmdArgs.push_back("-o"); 3094193326Sed CmdArgs.push_back(Output.getFilename()); 3095193326Sed } else { 3096193326Sed assert(Output.isNothing() && "Invalid output."); 3097193326Sed } 3098193326Sed 3099193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 3100193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 3101193326Sed if (!Args.hasArg(options::OPT_shared)) { 3102198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o"))); 3103198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 3104198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); 3105193326Sed } else { 3106198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); 3107198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o"))); 3108193326Sed } 3109193326Sed } 3110193326Sed 3111193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 3112193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 3113193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 3114193326Sed 3115193326Sed for (InputInfoList::const_iterator 3116193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 3117193326Sed const InputInfo &II = *it; 3118193326Sed 3119193326Sed // Don't try to pass LLVM inputs to a generic gcc. 3120193326Sed if (II.getType() == types::TY_LLVMBC) 3121193326Sed D.Diag(clang::diag::err_drv_no_linker_llvm_support) 3122198092Srdivacky << getToolChain().getTripleString(); 3123193326Sed 3124193326Sed if (II.isPipe()) 3125193326Sed CmdArgs.push_back("-"); 3126193326Sed else if (II.isFilename()) 3127193326Sed CmdArgs.push_back(II.getFilename()); 3128193326Sed else 3129193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 3130193326Sed } 3131193326Sed 3132193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 3133193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 3134193326Sed // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of 3135193326Sed // rpaths 3136193326Sed CmdArgs.push_back("-L/usr/lib/gcc41"); 3137193326Sed 3138193326Sed if (!Args.hasArg(options::OPT_static)) { 3139193326Sed CmdArgs.push_back("-rpath"); 3140193326Sed CmdArgs.push_back("/usr/lib/gcc41"); 3141193326Sed 3142193326Sed CmdArgs.push_back("-rpath-link"); 3143193326Sed CmdArgs.push_back("/usr/lib/gcc41"); 3144193326Sed 3145193326Sed CmdArgs.push_back("-rpath"); 3146193326Sed CmdArgs.push_back("/usr/lib"); 3147193326Sed 3148193326Sed CmdArgs.push_back("-rpath-link"); 3149193326Sed CmdArgs.push_back("/usr/lib"); 3150193326Sed } 3151193326Sed 3152193326Sed if (Args.hasArg(options::OPT_shared)) { 3153193326Sed CmdArgs.push_back("-lgcc_pic"); 3154193326Sed } else { 3155193326Sed CmdArgs.push_back("-lgcc"); 3156193326Sed } 3157193326Sed 3158193326Sed 3159193326Sed if (Args.hasArg(options::OPT_pthread)) 3160198893Srdivacky CmdArgs.push_back("-lpthread"); 3161193326Sed 3162193326Sed if (!Args.hasArg(options::OPT_nolibc)) { 3163193326Sed CmdArgs.push_back("-lc"); 3164193326Sed } 3165193326Sed 3166193326Sed if (Args.hasArg(options::OPT_shared)) { 3167193326Sed CmdArgs.push_back("-lgcc_pic"); 3168193326Sed } else { 3169193326Sed CmdArgs.push_back("-lgcc"); 3170193326Sed } 3171193326Sed } 3172193326Sed 3173193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 3174193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 3175193326Sed if (!Args.hasArg(options::OPT_shared)) 3176198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o"))); 3177193326Sed else 3178198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o"))); 3179198092Srdivacky CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o"))); 3180193326Sed } 3181193326Sed 3182193326Sed const char *Exec = 3183198092Srdivacky Args.MakeArgString(getToolChain().GetProgramPath(C, "ld")); 3184200583Srdivacky Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); 3185193326Sed} 3186