Tools.cpp revision 269011
1218893Sdim//===--- 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" 11249423Sdim#include "InputInfo.h" 12249423Sdim#include "ToolChains.h" 13249423Sdim#include "clang/Basic/ObjCRuntime.h" 14249423Sdim#include "clang/Basic/Version.h" 15193326Sed#include "clang/Driver/Action.h" 16249423Sdim#include "clang/Driver/Compilation.h" 17198893Srdivacky#include "clang/Driver/Driver.h" 18198893Srdivacky#include "clang/Driver/DriverDiagnostic.h" 19193326Sed#include "clang/Driver/Job.h" 20199512Srdivacky#include "clang/Driver/Options.h" 21263508Sdim#include "clang/Driver/SanitizerArgs.h" 22193326Sed#include "clang/Driver/ToolChain.h" 23193326Sed#include "clang/Driver/Util.h" 24263508Sdim#include "clang/Sema/SemaDiagnostic.h" 25198092Srdivacky#include "llvm/ADT/SmallString.h" 26263508Sdim#include "llvm/ADT/StringExtras.h" 27198893Srdivacky#include "llvm/ADT/StringSwitch.h" 28198092Srdivacky#include "llvm/ADT/Twine.h" 29263508Sdim#include "llvm/Option/Arg.h" 30263508Sdim#include "llvm/Option/ArgList.h" 31263508Sdim#include "llvm/Option/Option.h" 32249423Sdim#include "llvm/Support/ErrorHandling.h" 33218893Sdim#include "llvm/Support/FileSystem.h" 34193326Sed#include "llvm/Support/Format.h" 35218893Sdim#include "llvm/Support/Host.h" 36263508Sdim#include "llvm/Support/Path.h" 37263508Sdim#include "llvm/Support/Program.h" 38218893Sdim#include "llvm/Support/Process.h" 39249423Sdim#include "llvm/Support/raw_ostream.h" 40263508Sdim#include <sys/stat.h> 41193326Sed 42193326Sedusing namespace clang::driver; 43193326Sedusing namespace clang::driver::tools; 44226633Sdimusing namespace clang; 45263508Sdimusing namespace llvm::opt; 46193326Sed 47198092Srdivacky/// CheckPreprocessingOptions - Perform some validation of preprocessing 48198092Srdivacky/// arguments that is shared with gcc. 49198092Srdivackystatic void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { 50198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) 51263508Sdim if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP()) 52226633Sdim D.Diag(diag::err_drv_argument_only_allowed_with) 53198092Srdivacky << A->getAsString(Args) << "-E"; 54198092Srdivacky} 55198092Srdivacky 56198092Srdivacky/// CheckCodeGenerationOptions - Perform some validation of code generation 57198092Srdivacky/// arguments that is shared with gcc. 58198092Srdivackystatic void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) { 59198092Srdivacky // In gcc, only ARM checks this, but it seems reasonable to check universally. 60198092Srdivacky if (Args.hasArg(options::OPT_static)) 61198092Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_dynamic, 62198092Srdivacky options::OPT_mdynamic_no_pic)) 63226633Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 64198092Srdivacky << A->getAsString(Args) << "-static"; 65198092Srdivacky} 66198092Srdivacky 67206084Srdivacky// Quote target names for inclusion in GNU Make dependency files. 68206084Srdivacky// Only the characters '$', '#', ' ', '\t' are quoted. 69226633Sdimstatic void QuoteTarget(StringRef Target, 70226633Sdim SmallVectorImpl<char> &Res) { 71206084Srdivacky for (unsigned i = 0, e = Target.size(); i != e; ++i) { 72206084Srdivacky switch (Target[i]) { 73206084Srdivacky case ' ': 74206084Srdivacky case '\t': 75206084Srdivacky // Escape the preceding backslashes 76206084Srdivacky for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j) 77206084Srdivacky Res.push_back('\\'); 78206084Srdivacky 79206084Srdivacky // Escape the space/tab 80206084Srdivacky Res.push_back('\\'); 81206084Srdivacky break; 82206084Srdivacky case '$': 83206084Srdivacky Res.push_back('$'); 84206084Srdivacky break; 85206084Srdivacky case '#': 86206084Srdivacky Res.push_back('\\'); 87206084Srdivacky break; 88206084Srdivacky default: 89206084Srdivacky break; 90206084Srdivacky } 91206084Srdivacky 92206084Srdivacky Res.push_back(Target[i]); 93206084Srdivacky } 94206084Srdivacky} 95206084Srdivacky 96234353Sdimstatic void addDirectoryList(const ArgList &Args, 97234353Sdim ArgStringList &CmdArgs, 98234353Sdim const char *ArgName, 99234353Sdim const char *EnvVar) { 100234353Sdim const char *DirList = ::getenv(EnvVar); 101243830Sdim bool CombinedArg = false; 102243830Sdim 103234353Sdim if (!DirList) 104234353Sdim return; // Nothing to do. 105234353Sdim 106243830Sdim StringRef Name(ArgName); 107243830Sdim if (Name.equals("-I") || Name.equals("-L")) 108243830Sdim CombinedArg = true; 109243830Sdim 110234353Sdim StringRef Dirs(DirList); 111234353Sdim if (Dirs.empty()) // Empty string should not add '.'. 112234353Sdim return; 113234353Sdim 114234353Sdim StringRef::size_type Delim; 115263508Sdim while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) { 116234353Sdim if (Delim == 0) { // Leading colon. 117243830Sdim if (CombinedArg) { 118243830Sdim CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + ".")); 119243830Sdim } else { 120243830Sdim CmdArgs.push_back(ArgName); 121243830Sdim CmdArgs.push_back("."); 122243830Sdim } 123234353Sdim } else { 124243830Sdim if (CombinedArg) { 125243830Sdim CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim))); 126243830Sdim } else { 127243830Sdim CmdArgs.push_back(ArgName); 128243830Sdim CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim))); 129243830Sdim } 130234353Sdim } 131234353Sdim Dirs = Dirs.substr(Delim + 1); 132234353Sdim } 133234353Sdim 134234353Sdim if (Dirs.empty()) { // Trailing colon. 135243830Sdim if (CombinedArg) { 136243830Sdim CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + ".")); 137243830Sdim } else { 138243830Sdim CmdArgs.push_back(ArgName); 139243830Sdim CmdArgs.push_back("."); 140243830Sdim } 141234353Sdim } else { // Add the last path. 142243830Sdim if (CombinedArg) { 143243830Sdim CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs)); 144243830Sdim } else { 145243830Sdim CmdArgs.push_back(ArgName); 146243830Sdim CmdArgs.push_back(Args.MakeArgString(Dirs)); 147243830Sdim } 148234353Sdim } 149234353Sdim} 150234353Sdim 151218893Sdimstatic void AddLinkerInputs(const ToolChain &TC, 152218893Sdim const InputInfoList &Inputs, const ArgList &Args, 153218893Sdim ArgStringList &CmdArgs) { 154218893Sdim const Driver &D = TC.getDriver(); 155218893Sdim 156218893Sdim // Add extra linker input arguments which are not treated as inputs 157218893Sdim // (constructed via -Xarch_). 158218893Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input); 159218893Sdim 160218893Sdim for (InputInfoList::const_iterator 161218893Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 162218893Sdim const InputInfo &II = *it; 163218893Sdim 164218893Sdim if (!TC.HasNativeLLVMSupport()) { 165218893Sdim // Don't try to pass LLVM inputs unless we have native support. 166218893Sdim if (II.getType() == types::TY_LLVM_IR || 167218893Sdim II.getType() == types::TY_LTO_IR || 168218893Sdim II.getType() == types::TY_LLVM_BC || 169218893Sdim II.getType() == types::TY_LTO_BC) 170226633Sdim D.Diag(diag::err_drv_no_linker_llvm_support) 171218893Sdim << TC.getTripleString(); 172218893Sdim } 173218893Sdim 174218893Sdim // Add filenames immediately. 175218893Sdim if (II.isFilename()) { 176218893Sdim CmdArgs.push_back(II.getFilename()); 177218893Sdim continue; 178218893Sdim } 179218893Sdim 180218893Sdim // Otherwise, this is a linker input argument. 181218893Sdim const Arg &A = II.getInputArg(); 182218893Sdim 183218893Sdim // Handle reserved library options. 184218893Sdim if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) { 185218893Sdim TC.AddCXXStdlibLibArgs(Args, CmdArgs); 186218893Sdim } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) { 187218893Sdim TC.AddCCKextLibArgs(Args, CmdArgs); 188218893Sdim } else 189218893Sdim A.renderAsInput(Args, CmdArgs); 190218893Sdim } 191234353Sdim 192234353Sdim // LIBRARY_PATH - included following the user specified library paths. 193234353Sdim addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); 194218893Sdim} 195218893Sdim 196224145Sdim/// \brief Determine whether Objective-C automated reference counting is 197224145Sdim/// enabled. 198224145Sdimstatic bool isObjCAutoRefCount(const ArgList &Args) { 199224145Sdim return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false); 200224145Sdim} 201224145Sdim 202234353Sdim/// \brief Determine whether we are linking the ObjC runtime. 203234353Sdimstatic bool isObjCRuntimeLinked(const ArgList &Args) { 204239462Sdim if (isObjCAutoRefCount(Args)) { 205239462Sdim Args.ClaimAllArgs(options::OPT_fobjc_link_runtime); 206234353Sdim return true; 207239462Sdim } 208234353Sdim return Args.hasArg(options::OPT_fobjc_link_runtime); 209234353Sdim} 210234353Sdim 211223017Sdimstatic void addProfileRT(const ToolChain &TC, const ArgList &Args, 212224145Sdim ArgStringList &CmdArgs, 213224145Sdim llvm::Triple Triple) { 214224145Sdim if (!(Args.hasArg(options::OPT_fprofile_arcs) || 215224145Sdim Args.hasArg(options::OPT_fprofile_generate) || 216224145Sdim Args.hasArg(options::OPT_fcreate_profile) || 217224145Sdim Args.hasArg(options::OPT_coverage))) 218224145Sdim return; 219224145Sdim 220224145Sdim // GCC links libgcov.a by adding -L<inst>/gcc/lib/gcc/<triple>/<ver> -lgcov to 221224145Sdim // the link line. We cannot do the same thing because unlike gcov there is a 222224145Sdim // libprofile_rt.so. We used to use the -l:libprofile_rt.a syntax, but that is 223224145Sdim // not supported by old linkers. 224234353Sdim std::string ProfileRT = 225234353Sdim std::string(TC.getDriver().Dir) + "/../lib/libprofile_rt.a"; 226224145Sdim 227224145Sdim CmdArgs.push_back(Args.MakeArgString(ProfileRT)); 228223017Sdim} 229223017Sdim 230243830Sdimstatic bool forwardToGCC(const Option &O) { 231263508Sdim // Don't forward inputs from the original command line. They are added from 232263508Sdim // InputInfoList. 233263508Sdim return O.getKind() != Option::InputClass && 234243830Sdim !O.hasFlag(options::DriverOption) && 235243830Sdim !O.hasFlag(options::LinkerInput); 236243830Sdim} 237243830Sdim 238234353Sdimvoid Clang::AddPreprocessingOptions(Compilation &C, 239249423Sdim const JobAction &JA, 240234353Sdim const Driver &D, 241193326Sed const ArgList &Args, 242193326Sed ArgStringList &CmdArgs, 243193326Sed const InputInfo &Output, 244193326Sed const InputInfoList &Inputs) const { 245194179Sed Arg *A; 246194179Sed 247198092Srdivacky CheckPreprocessingOptions(D, Args); 248194179Sed 249198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_C); 250198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_CC); 251198092Srdivacky 252193326Sed // Handle dependency file generation. 253218893Sdim if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) || 254193326Sed (A = Args.getLastArg(options::OPT_MD)) || 255193326Sed (A = Args.getLastArg(options::OPT_MMD))) { 256193326Sed // Determine the output location. 257193326Sed const char *DepFile; 258241163Sdim if (Arg *MF = Args.getLastArg(options::OPT_MF)) { 259243830Sdim DepFile = MF->getValue(); 260249423Sdim C.addFailureResultFile(DepFile, &JA); 261241163Sdim } else if (Output.getType() == types::TY_Dependencies) { 262241163Sdim DepFile = Output.getFilename(); 263199512Srdivacky } else if (A->getOption().matches(options::OPT_M) || 264199512Srdivacky A->getOption().matches(options::OPT_MM)) { 265193326Sed DepFile = "-"; 266193326Sed } else { 267249423Sdim DepFile = getDependencyFileName(Args, Inputs); 268249423Sdim C.addFailureResultFile(DepFile, &JA); 269193326Sed } 270193326Sed CmdArgs.push_back("-dependency-file"); 271193326Sed CmdArgs.push_back(DepFile); 272193326Sed 273206084Srdivacky // Add a default target if one wasn't specified. 274193326Sed if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) { 275193326Sed const char *DepTarget; 276193326Sed 277193326Sed // If user provided -o, that is the dependency target, except 278193326Sed // when we are only generating a dependency file. 279193326Sed Arg *OutputOpt = Args.getLastArg(options::OPT_o); 280193326Sed if (OutputOpt && Output.getType() != types::TY_Dependencies) { 281243830Sdim DepTarget = OutputOpt->getValue(); 282193326Sed } else { 283193326Sed // Otherwise derive from the base input. 284193326Sed // 285193326Sed // FIXME: This should use the computed output file location. 286234353Sdim SmallString<128> P(Inputs[0].getBaseInput()); 287218893Sdim llvm::sys::path::replace_extension(P, "o"); 288218893Sdim DepTarget = Args.MakeArgString(llvm::sys::path::filename(P)); 289193326Sed } 290193326Sed 291193326Sed CmdArgs.push_back("-MT"); 292234353Sdim SmallString<128> Quoted; 293206084Srdivacky QuoteTarget(DepTarget, Quoted); 294206084Srdivacky CmdArgs.push_back(Args.MakeArgString(Quoted)); 295193326Sed } 296193326Sed 297199512Srdivacky if (A->getOption().matches(options::OPT_M) || 298199512Srdivacky A->getOption().matches(options::OPT_MD)) 299193326Sed CmdArgs.push_back("-sys-header-deps"); 300193326Sed } 301193326Sed 302224145Sdim if (Args.hasArg(options::OPT_MG)) { 303224145Sdim if (!A || A->getOption().matches(options::OPT_MD) || 304224145Sdim A->getOption().matches(options::OPT_MMD)) 305226633Sdim D.Diag(diag::err_drv_mg_requires_m_or_mm); 306224145Sdim CmdArgs.push_back("-MG"); 307224145Sdim } 308224145Sdim 309193326Sed Args.AddLastArg(CmdArgs, options::OPT_MP); 310193326Sed 311206084Srdivacky // Convert all -MQ <target> args to -MT <quoted target> 312206084Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_MT, 313206084Srdivacky options::OPT_MQ), 314206084Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 315210299Sed const Arg *A = *it; 316210299Sed A->claim(); 317206084Srdivacky 318210299Sed if (A->getOption().matches(options::OPT_MQ)) { 319206084Srdivacky CmdArgs.push_back("-MT"); 320234353Sdim SmallString<128> Quoted; 321243830Sdim QuoteTarget(A->getValue(), Quoted); 322206084Srdivacky CmdArgs.push_back(Args.MakeArgString(Quoted)); 323206084Srdivacky 324206084Srdivacky // -MT flag - no change 325206084Srdivacky } else { 326210299Sed A->render(Args, CmdArgs); 327206084Srdivacky } 328206084Srdivacky } 329206084Srdivacky 330193326Sed // Add -i* options, and automatically translate to 331193326Sed // -include-pch/-include-pth for transparent PCH support. It's 332193326Sed // wonky, but we include looking for .gch so we can support seamless 333193326Sed // replacement into a build system already set up to be generating 334193326Sed // .gch files. 335218893Sdim bool RenderedImplicitInclude = false; 336199990Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group), 337199990Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 338199990Srdivacky const Arg *A = it; 339193326Sed 340193326Sed if (A->getOption().matches(options::OPT_include)) { 341218893Sdim bool IsFirstImplicitInclude = !RenderedImplicitInclude; 342218893Sdim RenderedImplicitInclude = true; 343218893Sdim 344212904Sdim // Use PCH if the user requested it. 345198398Srdivacky bool UsePCH = D.CCCUsePCH; 346198398Srdivacky 347193326Sed bool FoundPTH = false; 348193326Sed bool FoundPCH = false; 349263508Sdim SmallString<128> P(A->getValue()); 350263508Sdim // We want the files to have a name like foo.h.pch. Add a dummy extension 351263508Sdim // so that replace_extension does the right thing. 352263508Sdim P += ".dummy"; 353198398Srdivacky if (UsePCH) { 354263508Sdim llvm::sys::path::replace_extension(P, "pch"); 355263508Sdim if (llvm::sys::fs::exists(P.str())) 356193326Sed FoundPCH = true; 357193326Sed } 358193326Sed 359193326Sed if (!FoundPCH) { 360263508Sdim llvm::sys::path::replace_extension(P, "pth"); 361263508Sdim if (llvm::sys::fs::exists(P.str())) 362193326Sed FoundPTH = true; 363198092Srdivacky } 364198092Srdivacky 365193326Sed if (!FoundPCH && !FoundPTH) { 366263508Sdim llvm::sys::path::replace_extension(P, "gch"); 367263508Sdim if (llvm::sys::fs::exists(P.str())) { 368198398Srdivacky FoundPCH = UsePCH; 369198398Srdivacky FoundPTH = !UsePCH; 370193326Sed } 371193326Sed } 372193326Sed 373193326Sed if (FoundPCH || FoundPTH) { 374218893Sdim if (IsFirstImplicitInclude) { 375218893Sdim A->claim(); 376218893Sdim if (UsePCH) 377218893Sdim CmdArgs.push_back("-include-pch"); 378218893Sdim else 379218893Sdim CmdArgs.push_back("-include-pth"); 380218893Sdim CmdArgs.push_back(Args.MakeArgString(P.str())); 381218893Sdim continue; 382218893Sdim } else { 383218893Sdim // Ignore the PCH if not first on command line and emit warning. 384226633Sdim D.Diag(diag::warn_drv_pch_not_first_include) 385218893Sdim << P.str() << A->getAsString(Args); 386218893Sdim } 387193326Sed } 388193326Sed } 389193326Sed 390193326Sed // Not translated, render as usual. 391193326Sed A->claim(); 392193326Sed A->render(Args, CmdArgs); 393193326Sed } 394193326Sed 395193326Sed Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); 396226633Sdim Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F, 397226633Sdim options::OPT_index_header_map); 398193326Sed 399193326Sed // Add -Wp, and -Xassembler if using the preprocessor. 400193326Sed 401193326Sed // FIXME: There is a very unfortunate problem here, some troubled 402193326Sed // souls abuse -Wp, to pass preprocessor options in gcc syntax. To 403193326Sed // really support that we would have to parse and then translate 404193326Sed // those options. :( 405193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, 406193326Sed options::OPT_Xpreprocessor); 407198893Srdivacky 408198893Srdivacky // -I- is a deprecated GCC feature, reject it. 409198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_I_)) 410226633Sdim D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args); 411218893Sdim 412218893Sdim // If we have a --sysroot, and don't have an explicit -isysroot flag, add an 413218893Sdim // -isysroot to the CC1 invocation. 414234982Sdim StringRef sysroot = C.getSysRoot(); 415234982Sdim if (sysroot != "") { 416218893Sdim if (!Args.hasArg(options::OPT_isysroot)) { 417218893Sdim CmdArgs.push_back("-isysroot"); 418234982Sdim CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 419218893Sdim } 420218893Sdim } 421249423Sdim 422226633Sdim // Parse additional include paths from environment variables. 423234353Sdim // FIXME: We should probably sink the logic for handling these from the 424234353Sdim // frontend into the driver. It will allow deleting 4 otherwise unused flags. 425226633Sdim // CPATH - included following the user specified includes (but prior to 426226633Sdim // builtin and standard includes). 427234353Sdim addDirectoryList(Args, CmdArgs, "-I", "CPATH"); 428226633Sdim // C_INCLUDE_PATH - system includes enabled when compiling C. 429234353Sdim addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH"); 430226633Sdim // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++. 431234353Sdim addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH"); 432226633Sdim // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC. 433234353Sdim addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH"); 434226633Sdim // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++. 435234353Sdim addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH"); 436228379Sdim 437228379Sdim // Add C++ include arguments, if needed. 438228379Sdim if (types::isCXX(Inputs[0].getType())) 439228379Sdim getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs); 440228379Sdim 441228379Sdim // Add system include arguments. 442228379Sdim getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs); 443193326Sed} 444193326Sed 445239462Sdim/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 446239462Sdim/// CPU. 447239462Sdim// 448239462Sdim// FIXME: This is redundant with -mcpu, why does LLVM use this. 449239462Sdim// FIXME: tblgen this, or kill it! 450239462Sdimstatic const char *getLLVMArchSuffixForARM(StringRef CPU) { 451239462Sdim return llvm::StringSwitch<const char *>(CPU) 452263508Sdim .Case("strongarm", "v4") 453239462Sdim .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t") 454239462Sdim .Cases("arm720t", "arm9", "arm9tdmi", "v4t") 455239462Sdim .Cases("arm920", "arm920t", "arm922t", "v4t") 456239462Sdim .Cases("arm940t", "ep9312","v4t") 457239462Sdim .Cases("arm10tdmi", "arm1020t", "v5") 458239462Sdim .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e") 459239462Sdim .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e") 460239462Sdim .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e") 461239462Sdim .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6") 462239462Sdim .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6") 463239462Sdim .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2") 464249423Sdim .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7") 465263508Sdim .Cases("cortex-a9", "cortex-a12", "cortex-a15", "v7") 466263508Sdim .Cases("cortex-r4", "cortex-r5", "v7r") 467249423Sdim .Case("cortex-m0", "v6m") 468239462Sdim .Case("cortex-m3", "v7m") 469249423Sdim .Case("cortex-m4", "v7em") 470243830Sdim .Case("cortex-a9-mp", "v7f") 471243830Sdim .Case("swift", "v7s") 472263508Sdim .Cases("cortex-a53", "cortex-a57", "v8") 473239462Sdim .Default(""); 474239462Sdim} 475239462Sdim 476221345Sdim/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. 477198092Srdivacky// 478198092Srdivacky// FIXME: tblgen this. 479239462Sdimstatic std::string getARMTargetCPU(const ArgList &Args, 480210299Sed const llvm::Triple &Triple) { 481198092Srdivacky // FIXME: Warn on inconsistent use of -mcpu and -march. 482198092Srdivacky 483198092Srdivacky // If we have -mcpu=, use that. 484239462Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 485243830Sdim StringRef MCPU = A->getValue(); 486239462Sdim // Handle -mcpu=native. 487239462Sdim if (MCPU == "native") 488239462Sdim return llvm::sys::getHostCPUName(); 489239462Sdim else 490239462Sdim return MCPU; 491239462Sdim } 492198092Srdivacky 493226633Sdim StringRef MArch; 494198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 495210299Sed // Otherwise, if we have -march= choose the base CPU for that arch. 496243830Sdim MArch = A->getValue(); 497210299Sed } else { 498210299Sed // Otherwise, use the Arch from the triple. 499210299Sed MArch = Triple.getArchName(); 500198092Srdivacky } 501198092Srdivacky 502263508Sdim if (Triple.getOS() == llvm::Triple::NetBSD) { 503263508Sdim if (MArch == "armv6") 504263508Sdim return "arm1176jzf-s"; 505263508Sdim } 506263508Sdim 507239462Sdim // Handle -march=native. 508239462Sdim std::string NativeMArch; 509239462Sdim if (MArch == "native") { 510239462Sdim std::string CPU = llvm::sys::getHostCPUName(); 511239462Sdim if (CPU != "generic") { 512239462Sdim // Translate the native cpu into the architecture. The switch below will 513239462Sdim // then chose the minimum cpu for that arch. 514239462Sdim NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU); 515239462Sdim MArch = NativeMArch; 516239462Sdim } 517239462Sdim } 518239462Sdim 519226633Sdim return llvm::StringSwitch<const char *>(MArch) 520226633Sdim .Cases("armv2", "armv2a","arm2") 521226633Sdim .Case("armv3", "arm6") 522226633Sdim .Case("armv3m", "arm7m") 523263508Sdim .Case("armv4", "strongarm") 524263508Sdim .Case("armv4t", "arm7tdmi") 525226633Sdim .Cases("armv5", "armv5t", "arm10tdmi") 526239462Sdim .Cases("armv5e", "armv5te", "arm1022e") 527226633Sdim .Case("armv5tej", "arm926ej-s") 528226633Sdim .Cases("armv6", "armv6k", "arm1136jf-s") 529226633Sdim .Case("armv6j", "arm1136j-s") 530226633Sdim .Cases("armv6z", "armv6zk", "arm1176jzf-s") 531226633Sdim .Case("armv6t2", "arm1156t2-s") 532249423Sdim .Cases("armv6m", "armv6-m", "cortex-m0") 533226633Sdim .Cases("armv7", "armv7a", "armv7-a", "cortex-a8") 534249423Sdim .Cases("armv7em", "armv7e-m", "cortex-m4") 535243830Sdim .Cases("armv7f", "armv7-f", "cortex-a9-mp") 536243830Sdim .Cases("armv7s", "armv7-s", "swift") 537226633Sdim .Cases("armv7r", "armv7-r", "cortex-r4") 538226633Sdim .Cases("armv7m", "armv7-m", "cortex-m3") 539263508Sdim .Cases("armv8", "armv8a", "armv8-a", "cortex-a53") 540226633Sdim .Case("ep9312", "ep9312") 541226633Sdim .Case("iwmmxt", "iwmmxt") 542226633Sdim .Case("xscale", "xscale") 543263508Sdim // If all else failed, return the most base CPU with thumb interworking 544263508Sdim // supported by LLVM. 545226633Sdim .Default("arm7tdmi"); 546198092Srdivacky} 547198092Srdivacky 548263508Sdim/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are targeting. 549263508Sdim// 550263508Sdim// FIXME: tblgen this. 551263508Sdimstatic std::string getAArch64TargetCPU(const ArgList &Args, 552263508Sdim const llvm::Triple &Triple) { 553263508Sdim // FIXME: Warn on inconsistent use of -mcpu and -march. 554263508Sdim 555263508Sdim // If we have -mcpu=, use that. 556263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 557263508Sdim StringRef MCPU = A->getValue(); 558263508Sdim // Handle -mcpu=native. 559263508Sdim if (MCPU == "native") 560263508Sdim return llvm::sys::getHostCPUName(); 561263508Sdim else 562263508Sdim return MCPU; 563263508Sdim } 564263508Sdim 565263508Sdim return "generic"; 566263508Sdim} 567263508Sdim 568199482Srdivacky// FIXME: Move to target hook. 569199482Srdivackystatic bool isSignedCharDefault(const llvm::Triple &Triple) { 570199482Srdivacky switch (Triple.getArch()) { 571199482Srdivacky default: 572199482Srdivacky return true; 573199482Srdivacky 574249423Sdim case llvm::Triple::aarch64: 575223017Sdim case llvm::Triple::arm: 576199482Srdivacky case llvm::Triple::ppc: 577199482Srdivacky case llvm::Triple::ppc64: 578226633Sdim if (Triple.isOSDarwin()) 579199482Srdivacky return true; 580199482Srdivacky return false; 581251662Sdim 582263508Sdim case llvm::Triple::ppc64le: 583251662Sdim case llvm::Triple::systemz: 584263508Sdim case llvm::Triple::xcore: 585251662Sdim return false; 586199482Srdivacky } 587199482Srdivacky} 588199482Srdivacky 589263508Sdimstatic bool isNoCommonDefault(const llvm::Triple &Triple) { 590263508Sdim switch (Triple.getArch()) { 591263508Sdim default: 592263508Sdim return false; 593263508Sdim 594263508Sdim case llvm::Triple::xcore: 595263508Sdim return true; 596263508Sdim } 597263508Sdim} 598263508Sdim 599234353Sdim// Handle -mfpu=. 600234353Sdim// 601234353Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the 602234353Sdim// frontend target. 603263508Sdimstatic void getAArch64FPUFeatures(const Driver &D, const Arg *A, 604263508Sdim const ArgList &Args, 605263508Sdim std::vector<const char *> &Features) { 606243830Sdim StringRef FPU = A->getValue(); 607263508Sdim if (FPU == "fp-armv8") { 608263508Sdim Features.push_back("+fp-armv8"); 609263508Sdim } else if (FPU == "neon-fp-armv8") { 610263508Sdim Features.push_back("+fp-armv8"); 611263508Sdim Features.push_back("+neon"); 612263508Sdim } else if (FPU == "crypto-neon-fp-armv8") { 613263508Sdim Features.push_back("+fp-armv8"); 614263508Sdim Features.push_back("+neon"); 615263508Sdim Features.push_back("+crypto"); 616263508Sdim } else if (FPU == "neon") { 617263508Sdim Features.push_back("+neon"); 618263508Sdim } else if (FPU == "none") { 619263508Sdim Features.push_back("-fp-armv8"); 620263508Sdim Features.push_back("-crypto"); 621263508Sdim Features.push_back("-neon"); 622263508Sdim } else 623263508Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 624263508Sdim} 625198092Srdivacky 626263508Sdim// Handle -mhwdiv=. 627263508Sdimstatic void getARMHWDivFeatures(const Driver &D, const Arg *A, 628263508Sdim const ArgList &Args, 629263508Sdim std::vector<const char *> &Features) { 630263508Sdim StringRef HWDiv = A->getValue(); 631263508Sdim if (HWDiv == "arm") { 632263508Sdim Features.push_back("+hwdiv-arm"); 633263508Sdim Features.push_back("-hwdiv"); 634263508Sdim } else if (HWDiv == "thumb") { 635263508Sdim Features.push_back("-hwdiv-arm"); 636263508Sdim Features.push_back("+hwdiv"); 637263508Sdim } else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") { 638263508Sdim Features.push_back("+hwdiv-arm"); 639263508Sdim Features.push_back("+hwdiv"); 640263508Sdim } else if (HWDiv == "none") { 641263508Sdim Features.push_back("-hwdiv-arm"); 642263508Sdim Features.push_back("-hwdiv"); 643263508Sdim } else 644263508Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 645263508Sdim} 646263508Sdim 647263508Sdim// Handle -mfpu=. 648263508Sdim// 649263508Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the 650263508Sdim// frontend target. 651263508Sdimstatic void getARMFPUFeatures(const Driver &D, const Arg *A, 652263508Sdim const ArgList &Args, 653263508Sdim std::vector<const char *> &Features) { 654263508Sdim StringRef FPU = A->getValue(); 655263508Sdim 656234353Sdim // Set the target features based on the FPU. 657234353Sdim if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") { 658234353Sdim // Disable any default FPU support. 659263508Sdim Features.push_back("-vfp2"); 660263508Sdim Features.push_back("-vfp3"); 661263508Sdim Features.push_back("-neon"); 662234353Sdim } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") { 663263508Sdim Features.push_back("+vfp3"); 664263508Sdim Features.push_back("+d16"); 665263508Sdim Features.push_back("-neon"); 666234353Sdim } else if (FPU == "vfp") { 667263508Sdim Features.push_back("+vfp2"); 668263508Sdim Features.push_back("-neon"); 669234353Sdim } else if (FPU == "vfp3" || FPU == "vfpv3") { 670263508Sdim Features.push_back("+vfp3"); 671263508Sdim Features.push_back("-neon"); 672263508Sdim } else if (FPU == "fp-armv8") { 673263508Sdim Features.push_back("+fp-armv8"); 674263508Sdim Features.push_back("-neon"); 675263508Sdim Features.push_back("-crypto"); 676263508Sdim } else if (FPU == "neon-fp-armv8") { 677263508Sdim Features.push_back("+fp-armv8"); 678263508Sdim Features.push_back("+neon"); 679263508Sdim Features.push_back("-crypto"); 680263508Sdim } else if (FPU == "crypto-neon-fp-armv8") { 681263508Sdim Features.push_back("+fp-armv8"); 682263508Sdim Features.push_back("+neon"); 683263508Sdim Features.push_back("+crypto"); 684234353Sdim } else if (FPU == "neon") { 685263508Sdim Features.push_back("+neon"); 686263508Sdim } else if (FPU == "none") { 687263508Sdim Features.push_back("-vfp2"); 688263508Sdim Features.push_back("-vfp3"); 689263508Sdim Features.push_back("-vfp4"); 690263508Sdim Features.push_back("-fp-armv8"); 691263508Sdim Features.push_back("-crypto"); 692263508Sdim Features.push_back("-neon"); 693234353Sdim } else 694234353Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 695234353Sdim} 696198092Srdivacky 697234353Sdim// Select the float ABI as determined by -msoft-float, -mhard-float, and 698234353Sdim// -mfloat-abi=. 699234353Sdimstatic StringRef getARMFloatABI(const Driver &D, 700234353Sdim const ArgList &Args, 701234353Sdim const llvm::Triple &Triple) { 702226633Sdim StringRef FloatABI; 703198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 704198092Srdivacky options::OPT_mhard_float, 705198092Srdivacky options::OPT_mfloat_abi_EQ)) { 706198092Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 707198092Srdivacky FloatABI = "soft"; 708198092Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 709198092Srdivacky FloatABI = "hard"; 710198092Srdivacky else { 711243830Sdim FloatABI = A->getValue(); 712198092Srdivacky if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") { 713226633Sdim D.Diag(diag::err_drv_invalid_mfloat_abi) 714198092Srdivacky << A->getAsString(Args); 715198092Srdivacky FloatABI = "soft"; 716198092Srdivacky } 717198092Srdivacky } 718198092Srdivacky } 719198092Srdivacky 720198092Srdivacky // If unspecified, choose the default based on the platform. 721198092Srdivacky if (FloatABI.empty()) { 722210299Sed switch (Triple.getOS()) { 723226633Sdim case llvm::Triple::Darwin: 724226633Sdim case llvm::Triple::MacOSX: 725226633Sdim case llvm::Triple::IOS: { 726198092Srdivacky // Darwin defaults to "softfp" for v6 and v7. 727198092Srdivacky // 728198092Srdivacky // FIXME: Factor out an ARM class so we can cache the arch somewhere. 729239462Sdim std::string ArchName = 730210299Sed getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 731239462Sdim if (StringRef(ArchName).startswith("v6") || 732239462Sdim StringRef(ArchName).startswith("v7")) 733198092Srdivacky FloatABI = "softfp"; 734198092Srdivacky else 735198092Srdivacky FloatABI = "soft"; 736198092Srdivacky break; 737198092Srdivacky } 738198092Srdivacky 739244640Sandrew case llvm::Triple::FreeBSD: 740244640Sandrew // FreeBSD defaults to soft float 741244640Sandrew FloatABI = "soft"; 742244640Sandrew break; 743244640Sandrew 744198092Srdivacky default: 745218893Sdim switch(Triple.getEnvironment()) { 746239462Sdim case llvm::Triple::GNUEABIHF: 747239462Sdim FloatABI = "hard"; 748239462Sdim break; 749218893Sdim case llvm::Triple::GNUEABI: 750218893Sdim FloatABI = "softfp"; 751218893Sdim break; 752218893Sdim case llvm::Triple::EABI: 753218893Sdim // EABI is always AAPCS, and if it was not marked 'hard', it's softfp 754218893Sdim FloatABI = "softfp"; 755218893Sdim break; 756243830Sdim case llvm::Triple::Android: { 757239462Sdim std::string ArchName = 758234353Sdim getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 759239462Sdim if (StringRef(ArchName).startswith("v7")) 760234353Sdim FloatABI = "softfp"; 761234353Sdim else 762234353Sdim FloatABI = "soft"; 763234353Sdim break; 764234353Sdim } 765218893Sdim default: 766218893Sdim // Assume "soft", but warn the user we are guessing. 767218893Sdim FloatABI = "soft"; 768226633Sdim D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 769218893Sdim break; 770218893Sdim } 771198092Srdivacky } 772198092Srdivacky } 773198092Srdivacky 774234353Sdim return FloatABI; 775234353Sdim} 776234353Sdim 777263508Sdimstatic void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, 778263508Sdim const ArgList &Args, 779263508Sdim std::vector<const char *> &Features) { 780263508Sdim StringRef FloatABI = getARMFloatABI(D, Args, Triple); 781263508Sdim // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these 782263508Sdim // yet (it uses the -mfloat-abi and -msoft-float options), and it is 783263508Sdim // stripped out by the ARM target. 784263508Sdim // Use software floating point operations? 785263508Sdim if (FloatABI == "soft") 786263508Sdim Features.push_back("+soft-float"); 787234353Sdim 788263508Sdim // Use software floating point argument passing? 789263508Sdim if (FloatABI != "hard") 790263508Sdim Features.push_back("+soft-float-abi"); 791263508Sdim 792263508Sdim // Honor -mfpu=. 793263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 794263508Sdim getARMFPUFeatures(D, A, Args, Features); 795263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ)) 796263508Sdim getARMHWDivFeatures(D, A, Args, Features); 797263508Sdim 798263508Sdim // Setting -msoft-float effectively disables NEON because of the GCC 799263508Sdim // implementation, although the same isn't true of VFP or VFP3. 800263508Sdim if (FloatABI == "soft") 801263508Sdim Features.push_back("-neon"); 802263508Sdim 803263508Sdim // En/disable crc 804263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcrc, 805263508Sdim options::OPT_mnocrc)) { 806263508Sdim if (A->getOption().matches(options::OPT_mcrc)) 807263508Sdim Features.push_back("+crc"); 808263508Sdim else 809263508Sdim Features.push_back("-crc"); 810263508Sdim } 811263508Sdim} 812263508Sdim 813234353Sdimvoid Clang::AddARMTargetArgs(const ArgList &Args, 814234353Sdim ArgStringList &CmdArgs, 815234353Sdim bool KernelOrKext) const { 816234353Sdim const Driver &D = getToolChain().getDriver(); 817243830Sdim // Get the effective triple, which takes into account the deployment target. 818243830Sdim std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 819243830Sdim llvm::Triple Triple(TripleStr); 820243830Sdim std::string CPUName = getARMTargetCPU(Args, Triple); 821234353Sdim 822234353Sdim // Select the ABI to use. 823234353Sdim // 824234353Sdim // FIXME: Support -meabi. 825234353Sdim const char *ABIName = 0; 826234353Sdim if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 827243830Sdim ABIName = A->getValue(); 828243830Sdim } else if (Triple.isOSDarwin()) { 829243830Sdim // The backend is hardwired to assume AAPCS for M-class processors, ensure 830243830Sdim // the frontend matches that. 831263508Sdim if (Triple.getEnvironment() == llvm::Triple::EABI || 832263508Sdim StringRef(CPUName).startswith("cortex-m")) { 833243830Sdim ABIName = "aapcs"; 834243830Sdim } else { 835243830Sdim ABIName = "apcs-gnu"; 836243830Sdim } 837234353Sdim } else { 838234353Sdim // Select the default based on the platform. 839234353Sdim switch(Triple.getEnvironment()) { 840243830Sdim case llvm::Triple::Android: 841234353Sdim case llvm::Triple::GNUEABI: 842239462Sdim case llvm::Triple::GNUEABIHF: 843234353Sdim ABIName = "aapcs-linux"; 844234353Sdim break; 845234353Sdim case llvm::Triple::EABI: 846234353Sdim ABIName = "aapcs"; 847234353Sdim break; 848234353Sdim default: 849234353Sdim ABIName = "apcs-gnu"; 850234353Sdim } 851234353Sdim } 852234353Sdim CmdArgs.push_back("-target-abi"); 853234353Sdim CmdArgs.push_back(ABIName); 854234353Sdim 855234353Sdim // Determine floating point ABI from the options & target defaults. 856234353Sdim StringRef FloatABI = getARMFloatABI(D, Args, Triple); 857198092Srdivacky if (FloatABI == "soft") { 858198092Srdivacky // Floating point operations and argument passing are soft. 859198092Srdivacky // 860198092Srdivacky // FIXME: This changes CPP defines, we need -target-soft-float. 861199990Srdivacky CmdArgs.push_back("-msoft-float"); 862200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 863200583Srdivacky CmdArgs.push_back("soft"); 864198092Srdivacky } else if (FloatABI == "softfp") { 865198092Srdivacky // Floating point operations are hard, but argument passing is soft. 866200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 867200583Srdivacky CmdArgs.push_back("soft"); 868198092Srdivacky } else { 869198092Srdivacky // Floating point operations and argument passing are hard. 870198092Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 871200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 872200583Srdivacky CmdArgs.push_back("hard"); 873198092Srdivacky } 874201361Srdivacky 875221345Sdim // Kernel code has more strict alignment requirements. 876221345Sdim if (KernelOrKext) { 877263508Sdim if (!Triple.isiOS() || Triple.isOSVersionLT(6)) { 878243830Sdim CmdArgs.push_back("-backend-option"); 879243830Sdim CmdArgs.push_back("-arm-long-calls"); 880243830Sdim } 881221345Sdim 882221345Sdim CmdArgs.push_back("-backend-option"); 883221345Sdim CmdArgs.push_back("-arm-strict-align"); 884221345Sdim 885221345Sdim // The kext linker doesn't know how to deal with movw/movt. 886221345Sdim CmdArgs.push_back("-backend-option"); 887263508Sdim CmdArgs.push_back("-arm-use-movt=0"); 888221345Sdim } 889226633Sdim 890226633Sdim // Setting -mno-global-merge disables the codegen global merge pass. Setting 891226633Sdim // -mglobal-merge has no effect as the pass is enabled by default. 892226633Sdim if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, 893226633Sdim options::OPT_mno_global_merge)) { 894226633Sdim if (A->getOption().matches(options::OPT_mno_global_merge)) 895226633Sdim CmdArgs.push_back("-mno-global-merge"); 896226633Sdim } 897239462Sdim 898251662Sdim if (!Args.hasFlag(options::OPT_mimplicit_float, 899251662Sdim options::OPT_mno_implicit_float, 900251662Sdim true)) 901239462Sdim CmdArgs.push_back("-no-implicit-float"); 902198092Srdivacky 903263508Sdim // llvm does not support reserving registers in general. There is support 904263508Sdim // for reserving r9 on ARM though (defined as a platform-specific register 905263508Sdim // in ARM EABI). 906263508Sdim if (Args.hasArg(options::OPT_ffixed_r9)) { 907263508Sdim CmdArgs.push_back("-backend-option"); 908263508Sdim CmdArgs.push_back("-arm-reserve-r9"); 909263508Sdim } 910226633Sdim} 911226633Sdim 912234353Sdim// Get CPU and ABI names. They are not independent 913234353Sdim// so we have to calculate them together. 914234353Sdimstatic void getMipsCPUAndABI(const ArgList &Args, 915263508Sdim const llvm::Triple &Triple, 916234353Sdim StringRef &CPUName, 917234353Sdim StringRef &ABIName) { 918243830Sdim const char *DefMips32CPU = "mips32"; 919243830Sdim const char *DefMips64CPU = "mips64"; 920226633Sdim 921243830Sdim if (Arg *A = Args.getLastArg(options::OPT_march_EQ, 922263508Sdim options::OPT_mcpu_EQ)) 923263508Sdim CPUName = A->getValue(); 924243830Sdim 925251662Sdim if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 926243830Sdim ABIName = A->getValue(); 927251662Sdim // Convert a GNU style Mips ABI name to the name 928251662Sdim // accepted by LLVM Mips backend. 929251662Sdim ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) 930251662Sdim .Case("32", "o32") 931251662Sdim .Case("64", "n64") 932251662Sdim .Default(ABIName); 933251662Sdim } 934243830Sdim 935243830Sdim // Setup default CPU and ABI names. 936243830Sdim if (CPUName.empty() && ABIName.empty()) { 937263508Sdim switch (Triple.getArch()) { 938243830Sdim default: 939243830Sdim llvm_unreachable("Unexpected triple arch name"); 940243830Sdim case llvm::Triple::mips: 941243830Sdim case llvm::Triple::mipsel: 942243830Sdim CPUName = DefMips32CPU; 943243830Sdim break; 944243830Sdim case llvm::Triple::mips64: 945243830Sdim case llvm::Triple::mips64el: 946243830Sdim CPUName = DefMips64CPU; 947243830Sdim break; 948243830Sdim } 949243830Sdim } 950243830Sdim 951243830Sdim if (!ABIName.empty()) { 952243830Sdim // Deduce CPU name from ABI name. 953243830Sdim CPUName = llvm::StringSwitch<const char *>(ABIName) 954249423Sdim .Cases("32", "o32", "eabi", DefMips32CPU) 955249423Sdim .Cases("n32", "n64", "64", DefMips64CPU) 956243830Sdim .Default(""); 957243830Sdim } 958243830Sdim else if (!CPUName.empty()) { 959243830Sdim // Deduce ABI name from CPU name. 960243830Sdim ABIName = llvm::StringSwitch<const char *>(CPUName) 961243830Sdim .Cases("mips32", "mips32r2", "o32") 962243830Sdim .Cases("mips64", "mips64r2", "n64") 963243830Sdim .Default(""); 964243830Sdim } 965243830Sdim 966243830Sdim // FIXME: Warn on inconsistent cpu and abi usage. 967234353Sdim} 968204643Srdivacky 969249423Sdim// Convert ABI name to the GNU tools acceptable variant. 970249423Sdimstatic StringRef getGnuCompatibleMipsABIName(StringRef ABI) { 971249423Sdim return llvm::StringSwitch<llvm::StringRef>(ABI) 972249423Sdim .Case("o32", "32") 973249423Sdim .Case("n64", "64") 974249423Sdim .Default(ABI); 975249423Sdim} 976249423Sdim 977239462Sdim// Select the MIPS float ABI as determined by -msoft-float, -mhard-float, 978239462Sdim// and -mfloat-abi=. 979239462Sdimstatic StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) { 980226633Sdim StringRef FloatABI; 981204643Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 982234353Sdim options::OPT_mhard_float, 983234353Sdim options::OPT_mfloat_abi_EQ)) { 984204643Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 985204643Srdivacky FloatABI = "soft"; 986204643Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 987204643Srdivacky FloatABI = "hard"; 988234353Sdim else { 989243830Sdim FloatABI = A->getValue(); 990251662Sdim if (FloatABI != "soft" && FloatABI != "hard") { 991239462Sdim D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 992234353Sdim FloatABI = "hard"; 993234353Sdim } 994234353Sdim } 995204643Srdivacky } 996204643Srdivacky 997204643Srdivacky // If unspecified, choose the default based on the platform. 998204643Srdivacky if (FloatABI.empty()) { 999234353Sdim // Assume "hard", because it's a default value used by gcc. 1000234353Sdim // When we start to recognize specific target MIPS processors, 1001234353Sdim // we will be able to select the default more correctly. 1002234353Sdim FloatABI = "hard"; 1003204643Srdivacky } 1004204643Srdivacky 1005239462Sdim return FloatABI; 1006239462Sdim} 1007239462Sdim 1008239462Sdimstatic void AddTargetFeature(const ArgList &Args, 1009263508Sdim std::vector<const char *> &Features, 1010263508Sdim OptSpecifier OnOpt, OptSpecifier OffOpt, 1011239462Sdim StringRef FeatureName) { 1012239462Sdim if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) { 1013239462Sdim if (A->getOption().matches(OnOpt)) 1014263508Sdim Features.push_back(Args.MakeArgString("+" + FeatureName)); 1015239462Sdim else 1016263508Sdim Features.push_back(Args.MakeArgString("-" + FeatureName)); 1017239462Sdim } 1018239462Sdim} 1019239462Sdim 1020263508Sdimstatic void getMIPSTargetFeatures(const Driver &D, const ArgList &Args, 1021263508Sdim std::vector<const char *> &Features) { 1022263508Sdim StringRef FloatABI = getMipsFloatABI(D, Args); 1023263508Sdim bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL; 1024263508Sdim if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) { 1025263508Sdim // FIXME: Note, this is a hack. We need to pass the selected float 1026263508Sdim // mode to the MipsTargetInfoBase to define appropriate macros there. 1027263508Sdim // Now it is the only method. 1028263508Sdim Features.push_back("+soft-float"); 1029263508Sdim } 1030263508Sdim 1031263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 1032263508Sdim if (StringRef(A->getValue()) == "2008") 1033263508Sdim Features.push_back("+nan2008"); 1034263508Sdim } 1035263508Sdim 1036263508Sdim AddTargetFeature(Args, Features, options::OPT_msingle_float, 1037263508Sdim options::OPT_mdouble_float, "single-float"); 1038263508Sdim AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, 1039263508Sdim "mips16"); 1040263508Sdim AddTargetFeature(Args, Features, options::OPT_mmicromips, 1041263508Sdim options::OPT_mno_micromips, "micromips"); 1042263508Sdim AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, 1043263508Sdim "dsp"); 1044263508Sdim AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, 1045263508Sdim "dspr2"); 1046263508Sdim AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, 1047263508Sdim "msa"); 1048263508Sdim AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32, 1049263508Sdim "fp64"); 1050263508Sdim} 1051263508Sdim 1052239462Sdimvoid Clang::AddMIPSTargetArgs(const ArgList &Args, 1053251662Sdim ArgStringList &CmdArgs) const { 1054239462Sdim const Driver &D = getToolChain().getDriver(); 1055239462Sdim StringRef CPUName; 1056239462Sdim StringRef ABIName; 1057263508Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 1058263508Sdim getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 1059239462Sdim 1060239462Sdim CmdArgs.push_back("-target-abi"); 1061239462Sdim CmdArgs.push_back(ABIName.data()); 1062239462Sdim 1063239462Sdim StringRef FloatABI = getMipsFloatABI(D, Args); 1064239462Sdim 1065249423Sdim bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL; 1066249423Sdim 1067249423Sdim if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) { 1068204643Srdivacky // Floating point operations and argument passing are soft. 1069204643Srdivacky CmdArgs.push_back("-msoft-float"); 1070234353Sdim CmdArgs.push_back("-mfloat-abi"); 1071234353Sdim CmdArgs.push_back("soft"); 1072234353Sdim 1073249423Sdim if (FloatABI == "hard" && IsMips16) { 1074249423Sdim CmdArgs.push_back("-mllvm"); 1075249423Sdim CmdArgs.push_back("-mips16-hard-float"); 1076249423Sdim } 1077234353Sdim } 1078234353Sdim else { 1079234353Sdim // Floating point operations and argument passing are hard. 1080204643Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 1081234353Sdim CmdArgs.push_back("-mfloat-abi"); 1082234353Sdim CmdArgs.push_back("hard"); 1083204643Srdivacky } 1084239462Sdim 1085249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) { 1086249423Sdim if (A->getOption().matches(options::OPT_mxgot)) { 1087249423Sdim CmdArgs.push_back("-mllvm"); 1088249423Sdim CmdArgs.push_back("-mxgot"); 1089249423Sdim } 1090249423Sdim } 1091249423Sdim 1092263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1, 1093263508Sdim options::OPT_mno_ldc1_sdc1)) { 1094263508Sdim if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) { 1095263508Sdim CmdArgs.push_back("-mllvm"); 1096263508Sdim CmdArgs.push_back("-mno-ldc1-sdc1"); 1097263508Sdim } 1098263508Sdim } 1099263508Sdim 1100263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division, 1101263508Sdim options::OPT_mno_check_zero_division)) { 1102263508Sdim if (A->getOption().matches(options::OPT_mno_check_zero_division)) { 1103263508Sdim CmdArgs.push_back("-mllvm"); 1104263508Sdim CmdArgs.push_back("-mno-check-zero-division"); 1105263508Sdim } 1106263508Sdim } 1107263508Sdim 1108243830Sdim if (Arg *A = Args.getLastArg(options::OPT_G)) { 1109243830Sdim StringRef v = A->getValue(); 1110243830Sdim CmdArgs.push_back("-mllvm"); 1111243830Sdim CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v)); 1112243830Sdim A->claim(); 1113243830Sdim } 1114204643Srdivacky} 1115204643Srdivacky 1116239462Sdim/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. 1117239462Sdimstatic std::string getPPCTargetCPU(const ArgList &Args) { 1118239462Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 1119243830Sdim StringRef CPUName = A->getValue(); 1120239462Sdim 1121239462Sdim if (CPUName == "native") { 1122239462Sdim std::string CPU = llvm::sys::getHostCPUName(); 1123239462Sdim if (!CPU.empty() && CPU != "generic") 1124239462Sdim return CPU; 1125239462Sdim else 1126239462Sdim return ""; 1127239462Sdim } 1128239462Sdim 1129239462Sdim return llvm::StringSwitch<const char *>(CPUName) 1130239462Sdim .Case("common", "generic") 1131239462Sdim .Case("440", "440") 1132239462Sdim .Case("440fp", "440") 1133239462Sdim .Case("450", "450") 1134239462Sdim .Case("601", "601") 1135239462Sdim .Case("602", "602") 1136239462Sdim .Case("603", "603") 1137239462Sdim .Case("603e", "603e") 1138239462Sdim .Case("603ev", "603ev") 1139239462Sdim .Case("604", "604") 1140239462Sdim .Case("604e", "604e") 1141239462Sdim .Case("620", "620") 1142249423Sdim .Case("630", "pwr3") 1143239462Sdim .Case("G3", "g3") 1144239462Sdim .Case("7400", "7400") 1145239462Sdim .Case("G4", "g4") 1146239462Sdim .Case("7450", "7450") 1147239462Sdim .Case("G4+", "g4+") 1148239462Sdim .Case("750", "750") 1149239462Sdim .Case("970", "970") 1150239462Sdim .Case("G5", "g5") 1151239462Sdim .Case("a2", "a2") 1152249423Sdim .Case("a2q", "a2q") 1153243830Sdim .Case("e500mc", "e500mc") 1154243830Sdim .Case("e5500", "e5500") 1155249423Sdim .Case("power3", "pwr3") 1156249423Sdim .Case("power4", "pwr4") 1157249423Sdim .Case("power5", "pwr5") 1158249423Sdim .Case("power5x", "pwr5x") 1159239462Sdim .Case("power6", "pwr6") 1160249423Sdim .Case("power6x", "pwr6x") 1161239462Sdim .Case("power7", "pwr7") 1162249423Sdim .Case("pwr3", "pwr3") 1163249423Sdim .Case("pwr4", "pwr4") 1164249423Sdim .Case("pwr5", "pwr5") 1165249423Sdim .Case("pwr5x", "pwr5x") 1166249423Sdim .Case("pwr6", "pwr6") 1167249423Sdim .Case("pwr6x", "pwr6x") 1168249423Sdim .Case("pwr7", "pwr7") 1169239462Sdim .Case("powerpc", "ppc") 1170239462Sdim .Case("powerpc64", "ppc64") 1171263508Sdim .Case("powerpc64le", "ppc64le") 1172239462Sdim .Default(""); 1173239462Sdim } 1174239462Sdim 1175239462Sdim return ""; 1176239462Sdim} 1177239462Sdim 1178263508Sdimstatic void getPPCTargetFeatures(const ArgList &Args, 1179263508Sdim std::vector<const char *> &Features) { 1180263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_m_ppc_Features_Group), 1181263508Sdim ie = Args.filtered_end(); 1182263508Sdim it != ie; ++it) { 1183263508Sdim StringRef Name = (*it)->getOption().getName(); 1184263508Sdim (*it)->claim(); 1185239462Sdim 1186263508Sdim // Skip over "-m". 1187263508Sdim assert(Name.startswith("m") && "Invalid feature name."); 1188263508Sdim Name = Name.substr(1); 1189239462Sdim 1190263508Sdim bool IsNegative = Name.startswith("no-"); 1191263508Sdim if (IsNegative) 1192263508Sdim Name = Name.substr(3); 1193249423Sdim 1194263508Sdim // Note that gcc calls this mfcrf and LLVM calls this mfocrf so we 1195263508Sdim // pass the correct option to the backend while calling the frontend 1196263508Sdim // option the same. 1197263508Sdim // TODO: Change the LLVM backend option maybe? 1198263508Sdim if (Name == "mfcrf") 1199263508Sdim Name = "mfocrf"; 1200249423Sdim 1201263508Sdim Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); 1202263508Sdim } 1203249423Sdim 1204263508Sdim // Altivec is a bit weird, allow overriding of the Altivec feature here. 1205263508Sdim AddTargetFeature(Args, Features, options::OPT_faltivec, 1206263508Sdim options::OPT_fno_altivec, "altivec"); 1207239462Sdim} 1208239462Sdim 1209249423Sdim/// Get the (LLVM) name of the R600 gpu we are targeting. 1210249423Sdimstatic std::string getR600TargetGPU(const ArgList &Args) { 1211249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 1212263508Sdim const char *GPUName = A->getValue(); 1213249423Sdim return llvm::StringSwitch<const char *>(GPUName) 1214251662Sdim .Cases("rv630", "rv635", "r600") 1215251662Sdim .Cases("rv610", "rv620", "rs780", "rs880") 1216249423Sdim .Case("rv740", "rv770") 1217249423Sdim .Case("palm", "cedar") 1218251662Sdim .Cases("sumo", "sumo2", "sumo") 1219249423Sdim .Case("hemlock", "cypress") 1220249423Sdim .Case("aruba", "cayman") 1221263508Sdim .Default(GPUName); 1222249423Sdim } 1223249423Sdim return ""; 1224249423Sdim} 1225249423Sdim 1226263508Sdimstatic void getSparcTargetFeatures(const ArgList &Args, 1227263508Sdim std::vector<const char *> Features) { 1228263508Sdim bool SoftFloatABI = true; 1229263508Sdim if (Arg *A = 1230263508Sdim Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { 1231263508Sdim if (A->getOption().matches(options::OPT_mhard_float)) 1232263508Sdim SoftFloatABI = false; 1233263508Sdim } 1234263508Sdim if (SoftFloatABI) 1235263508Sdim Features.push_back("+soft-float"); 1236249423Sdim} 1237249423Sdim 1238218893Sdimvoid Clang::AddSparcTargetArgs(const ArgList &Args, 1239218893Sdim ArgStringList &CmdArgs) const { 1240218893Sdim const Driver &D = getToolChain().getDriver(); 1241218893Sdim 1242218893Sdim // Select the float ABI as determined by -msoft-float, -mhard-float, and 1243226633Sdim StringRef FloatABI; 1244218893Sdim if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 1245218893Sdim options::OPT_mhard_float)) { 1246218893Sdim if (A->getOption().matches(options::OPT_msoft_float)) 1247218893Sdim FloatABI = "soft"; 1248218893Sdim else if (A->getOption().matches(options::OPT_mhard_float)) 1249218893Sdim FloatABI = "hard"; 1250218893Sdim } 1251218893Sdim 1252218893Sdim // If unspecified, choose the default based on the platform. 1253218893Sdim if (FloatABI.empty()) { 1254263508Sdim // Assume "soft", but warn the user we are guessing. 1255263508Sdim FloatABI = "soft"; 1256263508Sdim D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 1257218893Sdim } 1258218893Sdim 1259218893Sdim if (FloatABI == "soft") { 1260218893Sdim // Floating point operations and argument passing are soft. 1261218893Sdim // 1262218893Sdim // FIXME: This changes CPP defines, we need -target-soft-float. 1263218893Sdim CmdArgs.push_back("-msoft-float"); 1264218893Sdim } else { 1265218893Sdim assert(FloatABI == "hard" && "Invalid float abi!"); 1266218893Sdim CmdArgs.push_back("-mhard-float"); 1267218893Sdim } 1268218893Sdim} 1269218893Sdim 1270263508Sdimstatic const char *getSystemZTargetCPU(const ArgList &Args) { 1271263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 1272263508Sdim return A->getValue(); 1273263508Sdim return "z10"; 1274263508Sdim} 1275263508Sdim 1276247166Sdimstatic const char *getX86TargetCPU(const ArgList &Args, 1277247166Sdim const llvm::Triple &Triple) { 1278247166Sdim if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 1279263508Sdim if (StringRef(A->getValue()) != "native") { 1280263508Sdim if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h") 1281263508Sdim return "core-avx2"; 1282263508Sdim 1283247166Sdim return A->getValue(); 1284263508Sdim } 1285247166Sdim 1286247166Sdim // FIXME: Reject attempts to use -march=native unless the target matches 1287247166Sdim // the host. 1288247166Sdim // 1289247166Sdim // FIXME: We should also incorporate the detected target features for use 1290247166Sdim // with -native. 1291247166Sdim std::string CPU = llvm::sys::getHostCPUName(); 1292247166Sdim if (!CPU.empty() && CPU != "generic") 1293247166Sdim return Args.MakeArgString(CPU); 1294247166Sdim } 1295247166Sdim 1296247166Sdim // Select the default CPU if none was given (or detection failed). 1297247166Sdim 1298247166Sdim if (Triple.getArch() != llvm::Triple::x86_64 && 1299247166Sdim Triple.getArch() != llvm::Triple::x86) 1300247166Sdim return 0; // This routine is only handling x86 targets. 1301247166Sdim 1302247166Sdim bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; 1303247166Sdim 1304247166Sdim // FIXME: Need target hooks. 1305263508Sdim if (Triple.isOSDarwin()) { 1306263508Sdim if (Triple.getArchName() == "x86_64h") 1307263508Sdim return "core-avx2"; 1308247166Sdim return Is64Bit ? "core2" : "yonah"; 1309263508Sdim } 1310247166Sdim 1311263508Sdim // All x86 devices running Android have core2 as their common 1312263508Sdim // denominator. This makes a better choice than pentium4. 1313263508Sdim if (Triple.getEnvironment() == llvm::Triple::Android) 1314263508Sdim return "core2"; 1315263508Sdim 1316247166Sdim // Everything else goes to x86-64 in 64-bit mode. 1317247166Sdim if (Is64Bit) 1318247166Sdim return "x86-64"; 1319247166Sdim 1320263508Sdim switch (Triple.getOS()) { 1321263508Sdim case llvm::Triple::FreeBSD: 1322263508Sdim case llvm::Triple::NetBSD: 1323263508Sdim case llvm::Triple::OpenBSD: 1324263508Sdim return "i486"; 1325263508Sdim case llvm::Triple::Haiku: 1326247166Sdim return "i586"; 1327263508Sdim case llvm::Triple::Bitrig: 1328247166Sdim return "i686"; 1329263508Sdim default: 1330263508Sdim // Fallback to p4. 1331263508Sdim return "pentium4"; 1332263508Sdim } 1333263508Sdim} 1334247166Sdim 1335263508Sdimstatic std::string getCPUName(const ArgList &Args, const llvm::Triple &T) { 1336263508Sdim switch(T.getArch()) { 1337263508Sdim default: 1338263508Sdim return ""; 1339263508Sdim 1340263508Sdim case llvm::Triple::aarch64: 1341263508Sdim return getAArch64TargetCPU(Args, T); 1342263508Sdim 1343263508Sdim case llvm::Triple::arm: 1344263508Sdim case llvm::Triple::thumb: 1345263508Sdim return getARMTargetCPU(Args, T); 1346263508Sdim 1347263508Sdim case llvm::Triple::mips: 1348263508Sdim case llvm::Triple::mipsel: 1349263508Sdim case llvm::Triple::mips64: 1350263508Sdim case llvm::Triple::mips64el: { 1351263508Sdim StringRef CPUName; 1352263508Sdim StringRef ABIName; 1353263508Sdim getMipsCPUAndABI(Args, T, CPUName, ABIName); 1354263508Sdim return CPUName; 1355263508Sdim } 1356263508Sdim 1357263508Sdim case llvm::Triple::ppc: 1358263508Sdim case llvm::Triple::ppc64: 1359263508Sdim case llvm::Triple::ppc64le: { 1360263508Sdim std::string TargetCPUName = getPPCTargetCPU(Args); 1361263508Sdim // LLVM may default to generating code for the native CPU, 1362263508Sdim // but, like gcc, we default to a more generic option for 1363263508Sdim // each architecture. (except on Darwin) 1364263508Sdim if (TargetCPUName.empty() && !T.isOSDarwin()) { 1365263508Sdim if (T.getArch() == llvm::Triple::ppc64) 1366263508Sdim TargetCPUName = "ppc64"; 1367263508Sdim else if (T.getArch() == llvm::Triple::ppc64le) 1368263508Sdim TargetCPUName = "ppc64le"; 1369263508Sdim else 1370263508Sdim TargetCPUName = "ppc"; 1371263508Sdim } 1372263508Sdim return TargetCPUName; 1373263508Sdim } 1374263508Sdim 1375263508Sdim case llvm::Triple::sparc: 1376263763Sdim case llvm::Triple::sparcv9: 1377263763Sdim if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 1378263508Sdim return A->getValue(); 1379263508Sdim return ""; 1380263508Sdim 1381263508Sdim case llvm::Triple::x86: 1382263508Sdim case llvm::Triple::x86_64: 1383263508Sdim return getX86TargetCPU(Args, T); 1384263508Sdim 1385263508Sdim case llvm::Triple::hexagon: 1386263508Sdim return "hexagon" + toolchains::Hexagon_TC::GetTargetCPU(Args).str(); 1387263508Sdim 1388263508Sdim case llvm::Triple::systemz: 1389263508Sdim return getSystemZTargetCPU(Args); 1390263508Sdim 1391263508Sdim case llvm::Triple::r600: 1392263508Sdim return getR600TargetGPU(Args); 1393263508Sdim } 1394247166Sdim} 1395247166Sdim 1396263508Sdimstatic void getX86TargetFeatures(const llvm::Triple &Triple, 1397263508Sdim const ArgList &Args, 1398263508Sdim std::vector<const char *> &Features) { 1399263508Sdim if (Triple.getArchName() == "x86_64h") { 1400263508Sdim // x86_64h implies quite a few of the more modern subtarget features 1401263508Sdim // for Haswell class CPUs, but not all of them. Opt-out of a few. 1402263508Sdim Features.push_back("-rdrnd"); 1403263508Sdim Features.push_back("-aes"); 1404263508Sdim Features.push_back("-pclmul"); 1405263508Sdim Features.push_back("-rtm"); 1406263508Sdim Features.push_back("-hle"); 1407263508Sdim Features.push_back("-fsgsbase"); 1408263508Sdim } 1409263508Sdim 1410263508Sdim // Now add any that the user explicitly requested on the command line, 1411263508Sdim // which may override the defaults. 1412263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group), 1413263508Sdim ie = Args.filtered_end(); 1414263508Sdim it != ie; ++it) { 1415263508Sdim StringRef Name = (*it)->getOption().getName(); 1416263508Sdim (*it)->claim(); 1417263508Sdim 1418263508Sdim // Skip over "-m". 1419263508Sdim assert(Name.startswith("m") && "Invalid feature name."); 1420263508Sdim Name = Name.substr(1); 1421263508Sdim 1422263508Sdim bool IsNegative = Name.startswith("no-"); 1423263508Sdim if (IsNegative) 1424263508Sdim Name = Name.substr(3); 1425263508Sdim 1426263508Sdim Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); 1427263508Sdim } 1428263508Sdim} 1429263508Sdim 1430198092Srdivackyvoid Clang::AddX86TargetArgs(const ArgList &Args, 1431198092Srdivacky ArgStringList &CmdArgs) const { 1432198092Srdivacky if (!Args.hasFlag(options::OPT_mred_zone, 1433198092Srdivacky options::OPT_mno_red_zone, 1434198092Srdivacky true) || 1435198092Srdivacky Args.hasArg(options::OPT_mkernel) || 1436198092Srdivacky Args.hasArg(options::OPT_fapple_kext)) 1437199990Srdivacky CmdArgs.push_back("-disable-red-zone"); 1438198092Srdivacky 1439249423Sdim // Default to avoid implicit floating-point for kernel/kext code, but allow 1440249423Sdim // that to be overridden with -mno-soft-float. 1441249423Sdim bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) || 1442249423Sdim Args.hasArg(options::OPT_fapple_kext)); 1443249423Sdim if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 1444249423Sdim options::OPT_mno_soft_float, 1445251662Sdim options::OPT_mimplicit_float, 1446249423Sdim options::OPT_mno_implicit_float)) { 1447249423Sdim const Option &O = A->getOption(); 1448249423Sdim NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) || 1449249423Sdim O.matches(options::OPT_msoft_float)); 1450249423Sdim } 1451249423Sdim if (NoImplicitFloat) 1452199990Srdivacky CmdArgs.push_back("-no-implicit-float"); 1453198092Srdivacky} 1454198092Srdivacky 1455249423Sdimstatic inline bool HasPICArg(const ArgList &Args) { 1456249423Sdim return Args.hasArg(options::OPT_fPIC) 1457249423Sdim || Args.hasArg(options::OPT_fpic); 1458249423Sdim} 1459234353Sdim 1460249423Sdimstatic Arg *GetLastSmallDataThresholdArg(const ArgList &Args) { 1461249423Sdim return Args.getLastArg(options::OPT_G, 1462249423Sdim options::OPT_G_EQ, 1463249423Sdim options::OPT_msmall_data_threshold_EQ); 1464234353Sdim} 1465234353Sdim 1466249423Sdimstatic std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) { 1467249423Sdim std::string value; 1468249423Sdim if (HasPICArg(Args)) 1469249423Sdim value = "0"; 1470249423Sdim else if (Arg *A = GetLastSmallDataThresholdArg(Args)) { 1471249423Sdim value = A->getValue(); 1472249423Sdim A->claim(); 1473234353Sdim } 1474249423Sdim return value; 1475234353Sdim} 1476234353Sdim 1477234353Sdimvoid Clang::AddHexagonTargetArgs(const ArgList &Args, 1478234353Sdim ArgStringList &CmdArgs) const { 1479234353Sdim CmdArgs.push_back("-fno-signed-char"); 1480249423Sdim CmdArgs.push_back("-mqdsp6-compat"); 1481249423Sdim CmdArgs.push_back("-Wreturn-type"); 1482234353Sdim 1483249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 1484249423Sdim if (!SmallDataThreshold.empty()) { 1485234353Sdim CmdArgs.push_back ("-mllvm"); 1486249423Sdim CmdArgs.push_back(Args.MakeArgString( 1487249423Sdim "-hexagon-small-data-threshold=" + SmallDataThreshold)); 1488234353Sdim } 1489234353Sdim 1490239462Sdim if (!Args.hasArg(options::OPT_fno_short_enums)) 1491239462Sdim CmdArgs.push_back("-fshort-enums"); 1492239462Sdim if (Args.getLastArg(options::OPT_mieee_rnd_near)) { 1493239462Sdim CmdArgs.push_back ("-mllvm"); 1494239462Sdim CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near"); 1495239462Sdim } 1496234353Sdim CmdArgs.push_back ("-mllvm"); 1497234353Sdim CmdArgs.push_back ("-machine-sink-split=0"); 1498234353Sdim} 1499234353Sdim 1500263508Sdimstatic void getAArch64TargetFeatures(const Driver &D, const ArgList &Args, 1501263508Sdim std::vector<const char *> &Features) { 1502263508Sdim // Honor -mfpu=. 1503263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 1504263508Sdim getAArch64FPUFeatures(D, A, Args, Features); 1505263508Sdim} 1506263508Sdim 1507263508Sdimstatic void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, 1508263508Sdim const ArgList &Args, ArgStringList &CmdArgs) { 1509263508Sdim std::vector<const char *> Features; 1510263508Sdim switch (Triple.getArch()) { 1511263508Sdim default: 1512263508Sdim break; 1513263508Sdim case llvm::Triple::mips: 1514263508Sdim case llvm::Triple::mipsel: 1515263508Sdim case llvm::Triple::mips64: 1516263508Sdim case llvm::Triple::mips64el: 1517263508Sdim getMIPSTargetFeatures(D, Args, Features); 1518263508Sdim break; 1519263508Sdim 1520263508Sdim case llvm::Triple::arm: 1521263508Sdim case llvm::Triple::thumb: 1522263508Sdim getARMTargetFeatures(D, Triple, Args, Features); 1523263508Sdim break; 1524263508Sdim 1525263508Sdim case llvm::Triple::ppc: 1526263508Sdim case llvm::Triple::ppc64: 1527263508Sdim case llvm::Triple::ppc64le: 1528263508Sdim getPPCTargetFeatures(Args, Features); 1529263508Sdim break; 1530263508Sdim case llvm::Triple::sparc: 1531263508Sdim getSparcTargetFeatures(Args, Features); 1532263508Sdim break; 1533263508Sdim case llvm::Triple::aarch64: 1534263508Sdim getAArch64TargetFeatures(D, Args, Features); 1535263508Sdim break; 1536263508Sdim case llvm::Triple::x86: 1537263508Sdim case llvm::Triple::x86_64: 1538263508Sdim getX86TargetFeatures(Triple, Args, Features); 1539263508Sdim break; 1540263508Sdim } 1541263508Sdim 1542263508Sdim // Find the last of each feature. 1543263508Sdim llvm::StringMap<unsigned> LastOpt; 1544263508Sdim for (unsigned I = 0, N = Features.size(); I < N; ++I) { 1545263508Sdim const char *Name = Features[I]; 1546263508Sdim assert(Name[0] == '-' || Name[0] == '+'); 1547263508Sdim LastOpt[Name + 1] = I; 1548263508Sdim } 1549263508Sdim 1550263508Sdim for (unsigned I = 0, N = Features.size(); I < N; ++I) { 1551263508Sdim // If this feature was overridden, ignore it. 1552263508Sdim const char *Name = Features[I]; 1553263508Sdim llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1); 1554263508Sdim assert(LastI != LastOpt.end()); 1555263508Sdim unsigned Last = LastI->second; 1556263508Sdim if (Last != I) 1557263508Sdim continue; 1558263508Sdim 1559263508Sdim CmdArgs.push_back("-target-feature"); 1560263508Sdim CmdArgs.push_back(Name); 1561263508Sdim } 1562263508Sdim} 1563263508Sdim 1564226633Sdimstatic bool 1565239462SdimshouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, 1566221345Sdim const llvm::Triple &Triple) { 1567221345Sdim // We use the zero-cost exception tables for Objective-C if the non-fragile 1568221345Sdim // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and 1569221345Sdim // later. 1570239462Sdim if (runtime.isNonFragile()) 1571221345Sdim return true; 1572221345Sdim 1573226633Sdim if (!Triple.isOSDarwin()) 1574221345Sdim return false; 1575221345Sdim 1576224145Sdim return (!Triple.isMacOSXVersionLT(10,5) && 1577221345Sdim (Triple.getArch() == llvm::Triple::x86_64 || 1578226633Sdim Triple.getArch() == llvm::Triple::arm)); 1579221345Sdim} 1580221345Sdim 1581221345Sdim/// addExceptionArgs - Adds exception related arguments to the driver command 1582221345Sdim/// arguments. There's a master flag, -fexceptions and also language specific 1583221345Sdim/// flags to enable/disable C++ and Objective-C exceptions. 1584221345Sdim/// This makes it possible to for example disable C++ exceptions but enable 1585221345Sdim/// Objective-C exceptions. 1586221345Sdimstatic void addExceptionArgs(const ArgList &Args, types::ID InputType, 1587221345Sdim const llvm::Triple &Triple, 1588234353Sdim bool KernelOrKext, 1589239462Sdim const ObjCRuntime &objcRuntime, 1590221345Sdim ArgStringList &CmdArgs) { 1591234353Sdim if (KernelOrKext) { 1592234353Sdim // -mkernel and -fapple-kext imply no exceptions, so claim exception related 1593234353Sdim // arguments now to avoid warnings about unused arguments. 1594234353Sdim Args.ClaimAllArgs(options::OPT_fexceptions); 1595234353Sdim Args.ClaimAllArgs(options::OPT_fno_exceptions); 1596234353Sdim Args.ClaimAllArgs(options::OPT_fobjc_exceptions); 1597234353Sdim Args.ClaimAllArgs(options::OPT_fno_objc_exceptions); 1598234353Sdim Args.ClaimAllArgs(options::OPT_fcxx_exceptions); 1599234353Sdim Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions); 1600221345Sdim return; 1601234353Sdim } 1602221345Sdim 1603221345Sdim // Exceptions are enabled by default. 1604221345Sdim bool ExceptionsEnabled = true; 1605221345Sdim 1606221345Sdim // This keeps track of whether exceptions were explicitly turned on or off. 1607221345Sdim bool DidHaveExplicitExceptionFlag = false; 1608221345Sdim 1609198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fexceptions, 1610198092Srdivacky options::OPT_fno_exceptions)) { 1611198092Srdivacky if (A->getOption().matches(options::OPT_fexceptions)) 1612221345Sdim ExceptionsEnabled = true; 1613226633Sdim else 1614221345Sdim ExceptionsEnabled = false; 1615221345Sdim 1616221345Sdim DidHaveExplicitExceptionFlag = true; 1617198092Srdivacky } 1618218893Sdim 1619221345Sdim bool ShouldUseExceptionTables = false; 1620198092Srdivacky 1621221345Sdim // Exception tables and cleanups can be enabled with -fexceptions even if the 1622221345Sdim // language itself doesn't support exceptions. 1623221345Sdim if (ExceptionsEnabled && DidHaveExplicitExceptionFlag) 1624221345Sdim ShouldUseExceptionTables = true; 1625221345Sdim 1626221345Sdim // Obj-C exceptions are enabled by default, regardless of -fexceptions. This 1627221345Sdim // is not necessarily sensible, but follows GCC. 1628221345Sdim if (types::isObjC(InputType) && 1629226633Sdim Args.hasFlag(options::OPT_fobjc_exceptions, 1630221345Sdim options::OPT_fno_objc_exceptions, 1631221345Sdim true)) { 1632221345Sdim CmdArgs.push_back("-fobjc-exceptions"); 1633221345Sdim 1634226633Sdim ShouldUseExceptionTables |= 1635239462Sdim shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple); 1636218893Sdim } 1637198092Srdivacky 1638221345Sdim if (types::isCXX(InputType)) { 1639221345Sdim bool CXXExceptionsEnabled = ExceptionsEnabled; 1640221345Sdim 1641226633Sdim if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions, 1642226633Sdim options::OPT_fno_cxx_exceptions, 1643221345Sdim options::OPT_fexceptions, 1644221345Sdim options::OPT_fno_exceptions)) { 1645221345Sdim if (A->getOption().matches(options::OPT_fcxx_exceptions)) 1646221345Sdim CXXExceptionsEnabled = true; 1647221345Sdim else if (A->getOption().matches(options::OPT_fno_cxx_exceptions)) 1648221345Sdim CXXExceptionsEnabled = false; 1649221345Sdim } 1650221345Sdim 1651221345Sdim if (CXXExceptionsEnabled) { 1652221345Sdim CmdArgs.push_back("-fcxx-exceptions"); 1653221345Sdim 1654221345Sdim ShouldUseExceptionTables = true; 1655221345Sdim } 1656221345Sdim } 1657221345Sdim 1658221345Sdim if (ShouldUseExceptionTables) 1659221345Sdim CmdArgs.push_back("-fexceptions"); 1660198092Srdivacky} 1661198092Srdivacky 1662251662Sdimstatic bool ShouldDisableAutolink(const ArgList &Args, 1663251662Sdim const ToolChain &TC) { 1664251662Sdim bool Default = true; 1665251662Sdim if (TC.getTriple().isOSDarwin()) { 1666251662Sdim // The native darwin assembler doesn't support the linker_option directives, 1667251662Sdim // so we disable them if we think the .s file will be passed to it. 1668251662Sdim Default = TC.useIntegratedAs(); 1669251662Sdim } 1670251662Sdim return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink, 1671251662Sdim Default); 1672251662Sdim} 1673251662Sdim 1674221345Sdimstatic bool ShouldDisableCFI(const ArgList &Args, 1675221345Sdim const ToolChain &TC) { 1676234353Sdim bool Default = true; 1677226633Sdim if (TC.getTriple().isOSDarwin()) { 1678223017Sdim // The native darwin assembler doesn't support cfi directives, so 1679223017Sdim // we disable them if we think the .s file will be passed to it. 1680249423Sdim Default = TC.useIntegratedAs(); 1681223017Sdim } 1682234353Sdim return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm, 1683249423Sdim options::OPT_fno_dwarf2_cfi_asm, 1684249423Sdim Default); 1685234353Sdim} 1686223017Sdim 1687234353Sdimstatic bool ShouldDisableDwarfDirectory(const ArgList &Args, 1688234353Sdim const ToolChain &TC) { 1689234353Sdim bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm, 1690234353Sdim options::OPT_fno_dwarf_directory_asm, 1691249423Sdim TC.useIntegratedAs()); 1692234353Sdim return !UseDwarfDirectory; 1693221345Sdim} 1694221345Sdim 1695223017Sdim/// \brief Check whether the given input tree contains any compilation actions. 1696223017Sdimstatic bool ContainsCompileAction(const Action *A) { 1697223017Sdim if (isa<CompileJobAction>(A)) 1698223017Sdim return true; 1699223017Sdim 1700223017Sdim for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it) 1701223017Sdim if (ContainsCompileAction(*it)) 1702223017Sdim return true; 1703223017Sdim 1704223017Sdim return false; 1705223017Sdim} 1706223017Sdim 1707223017Sdim/// \brief Check if -relax-all should be passed to the internal assembler. 1708223017Sdim/// This is done by default when compiling non-assembler source with -O0. 1709223017Sdimstatic bool UseRelaxAll(Compilation &C, const ArgList &Args) { 1710223017Sdim bool RelaxDefault = true; 1711223017Sdim 1712223017Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 1713223017Sdim RelaxDefault = A->getOption().matches(options::OPT_O0); 1714223017Sdim 1715223017Sdim if (RelaxDefault) { 1716223017Sdim RelaxDefault = false; 1717223017Sdim for (ActionList::const_iterator it = C.getActions().begin(), 1718223017Sdim ie = C.getActions().end(); it != ie; ++it) { 1719223017Sdim if (ContainsCompileAction(*it)) { 1720223017Sdim RelaxDefault = true; 1721223017Sdim break; 1722223017Sdim } 1723223017Sdim } 1724223017Sdim } 1725223017Sdim 1726223017Sdim return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all, 1727223017Sdim RelaxDefault); 1728223017Sdim} 1729223017Sdim 1730263508Sdimstatic void CollectArgsForIntegratedAssembler(Compilation &C, 1731263508Sdim const ArgList &Args, 1732263508Sdim ArgStringList &CmdArgs, 1733263508Sdim const Driver &D) { 1734263508Sdim if (UseRelaxAll(C, Args)) 1735263508Sdim CmdArgs.push_back("-mrelax-all"); 1736243830Sdim 1737263508Sdim // When passing -I arguments to the assembler we sometimes need to 1738263508Sdim // unconditionally take the next argument. For example, when parsing 1739263508Sdim // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the 1740263508Sdim // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo' 1741263508Sdim // arg after parsing the '-I' arg. 1742263508Sdim bool TakeNextArg = false; 1743243830Sdim 1744263508Sdim // When using an integrated assembler, translate -Wa, and -Xassembler 1745263508Sdim // options. 1746263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA, 1747263508Sdim options::OPT_Xassembler), 1748263508Sdim ie = Args.filtered_end(); it != ie; ++it) { 1749263508Sdim const Arg *A = *it; 1750263508Sdim A->claim(); 1751243830Sdim 1752263508Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 1753263508Sdim StringRef Value = A->getValue(i); 1754263508Sdim if (TakeNextArg) { 1755263508Sdim CmdArgs.push_back(Value.data()); 1756263508Sdim TakeNextArg = false; 1757263508Sdim continue; 1758263508Sdim } 1759249423Sdim 1760263508Sdim if (Value == "-force_cpusubtype_ALL") { 1761263508Sdim // Do nothing, this is the default and we don't support anything else. 1762263508Sdim } else if (Value == "-L") { 1763263508Sdim CmdArgs.push_back("-msave-temp-labels"); 1764263508Sdim } else if (Value == "--fatal-warnings") { 1765263508Sdim CmdArgs.push_back("-mllvm"); 1766263508Sdim CmdArgs.push_back("-fatal-assembler-warnings"); 1767263508Sdim } else if (Value == "--noexecstack") { 1768263508Sdim CmdArgs.push_back("-mnoexecstack"); 1769263508Sdim } else if (Value.startswith("-I")) { 1770263508Sdim CmdArgs.push_back(Value.data()); 1771263508Sdim // We need to consume the next argument if the current arg is a plain 1772263508Sdim // -I. The next arg will be the include directory. 1773263508Sdim if (Value == "-I") 1774263508Sdim TakeNextArg = true; 1775263508Sdim } else { 1776263508Sdim D.Diag(diag::err_drv_unsupported_option_argument) 1777263508Sdim << A->getOption().getName() << Value; 1778263508Sdim } 1779263508Sdim } 1780263508Sdim } 1781263508Sdim} 1782249423Sdim 1783263508Sdimstatic void addProfileRTLinux( 1784263508Sdim const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { 1785263508Sdim if (!(Args.hasArg(options::OPT_fprofile_arcs) || 1786263508Sdim Args.hasArg(options::OPT_fprofile_generate) || 1787263508Sdim Args.hasArg(options::OPT_fcreate_profile) || 1788263508Sdim Args.hasArg(options::OPT_coverage))) 1789263508Sdim return; 1790249423Sdim 1791263508Sdim // The profile runtime is located in the Linux library directory and has name 1792263508Sdim // "libclang_rt.profile-<ArchName>.a". 1793263508Sdim SmallString<128> LibProfile(TC.getDriver().ResourceDir); 1794263508Sdim llvm::sys::path::append( 1795263508Sdim LibProfile, "lib", "linux", 1796263508Sdim Twine("libclang_rt.profile-") + TC.getArchName() + ".a"); 1797249423Sdim 1798263508Sdim CmdArgs.push_back(Args.MakeArgString(LibProfile)); 1799243830Sdim} 1800243830Sdim 1801249423Sdimstatic void addSanitizerRTLinkFlagsLinux( 1802249423Sdim const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, 1803249423Sdim const StringRef Sanitizer, bool BeforeLibStdCXX, 1804249423Sdim bool ExportSymbols = true) { 1805249423Sdim // Sanitizer runtime is located in the Linux library directory and 1806249423Sdim // has name "libclang_rt.<Sanitizer>-<ArchName>.a". 1807249423Sdim SmallString<128> LibSanitizer(TC.getDriver().ResourceDir); 1808249423Sdim llvm::sys::path::append( 1809249423Sdim LibSanitizer, "lib", "linux", 1810249423Sdim (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a")); 1811249423Sdim 1812249423Sdim // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a, 1813249423Sdim // etc.) so that the linker picks custom versions of the global 'operator 1814249423Sdim // new' and 'operator delete' symbols. We take the extreme (but simple) 1815249423Sdim // strategy of inserting it at the front of the link command. It also 1816249423Sdim // needs to be forced to end up in the executable, so wrap it in 1817249423Sdim // whole-archive. 1818249423Sdim SmallVector<const char *, 3> LibSanitizerArgs; 1819249423Sdim LibSanitizerArgs.push_back("-whole-archive"); 1820249423Sdim LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer)); 1821249423Sdim LibSanitizerArgs.push_back("-no-whole-archive"); 1822249423Sdim 1823249423Sdim CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(), 1824249423Sdim LibSanitizerArgs.begin(), LibSanitizerArgs.end()); 1825249423Sdim 1826249423Sdim CmdArgs.push_back("-lpthread"); 1827251662Sdim CmdArgs.push_back("-lrt"); 1828249423Sdim CmdArgs.push_back("-ldl"); 1829263508Sdim CmdArgs.push_back("-lm"); 1830249423Sdim 1831249423Sdim // If possible, use a dynamic symbols file to export the symbols from the 1832249423Sdim // runtime library. If we can't do so, use -export-dynamic instead to export 1833249423Sdim // all symbols from the binary. 1834249423Sdim if (ExportSymbols) { 1835249423Sdim if (llvm::sys::fs::exists(LibSanitizer + ".syms")) 1836249423Sdim CmdArgs.push_back( 1837249423Sdim Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms")); 1838249423Sdim else 1839249423Sdim CmdArgs.push_back("-export-dynamic"); 1840249423Sdim } 1841249423Sdim} 1842249423Sdim 1843234353Sdim/// If AddressSanitizer is enabled, add appropriate linker flags (Linux). 1844234353Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1845234353Sdimstatic void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, 1846234353Sdim ArgStringList &CmdArgs) { 1847263508Sdim if (TC.getTriple().getEnvironment() == llvm::Triple::Android) { 1848243830Sdim SmallString<128> LibAsan(TC.getDriver().ResourceDir); 1849243830Sdim llvm::sys::path::append(LibAsan, "lib", "linux", 1850243830Sdim (Twine("libclang_rt.asan-") + 1851243830Sdim TC.getArchName() + "-android.so")); 1852249423Sdim CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan)); 1853239462Sdim } else { 1854263508Sdim if (!Args.hasArg(options::OPT_shared)) 1855249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true); 1856239462Sdim } 1857234353Sdim} 1858234353Sdim 1859239462Sdim/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux). 1860239462Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1861239462Sdimstatic void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, 1862239462Sdim ArgStringList &CmdArgs) { 1863263508Sdim if (!Args.hasArg(options::OPT_shared)) 1864249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true); 1865239462Sdim} 1866239462Sdim 1867249423Sdim/// If MemorySanitizer is enabled, add appropriate linker flags (Linux). 1868249423Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1869249423Sdimstatic void addMsanRTLinux(const ToolChain &TC, const ArgList &Args, 1870249423Sdim ArgStringList &CmdArgs) { 1871263508Sdim if (!Args.hasArg(options::OPT_shared)) 1872249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true); 1873249423Sdim} 1874249423Sdim 1875263508Sdim/// If LeakSanitizer is enabled, add appropriate linker flags (Linux). 1876263508Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1877263508Sdimstatic void addLsanRTLinux(const ToolChain &TC, const ArgList &Args, 1878263508Sdim ArgStringList &CmdArgs) { 1879263508Sdim if (!Args.hasArg(options::OPT_shared)) 1880263508Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true); 1881263508Sdim} 1882263508Sdim 1883243830Sdim/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags 1884243830Sdim/// (Linux). 1885243830Sdimstatic void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args, 1886249423Sdim ArgStringList &CmdArgs, bool IsCXX, 1887249423Sdim bool HasOtherSanitizerRt) { 1888249423Sdim // Need a copy of sanitizer_common. This could come from another sanitizer 1889249423Sdim // runtime; if we're not including one, include our own copy. 1890249423Sdim if (!HasOtherSanitizerRt) 1891249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false); 1892249423Sdim 1893249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false); 1894249423Sdim 1895249423Sdim // Only include the bits of the runtime which need a C++ ABI library if 1896249423Sdim // we're linking in C++ mode. 1897249423Sdim if (IsCXX) 1898249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false); 1899243830Sdim} 1900243830Sdim 1901263508Sdimstatic void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args, 1902263508Sdim ArgStringList &CmdArgs) { 1903263508Sdim if (!Args.hasArg(options::OPT_shared)) 1904263508Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true); 1905263508Sdim} 1906263508Sdim 1907263508Sdimstatic bool shouldUseFramePointerForTarget(const ArgList &Args, 1908263508Sdim const llvm::Triple &Triple) { 1909263508Sdim switch (Triple.getArch()) { 1910263508Sdim // Don't use a frame pointer on linux if optimizing for certain targets. 1911263508Sdim case llvm::Triple::mips64: 1912263508Sdim case llvm::Triple::mips64el: 1913263508Sdim case llvm::Triple::mips: 1914263508Sdim case llvm::Triple::mipsel: 1915263508Sdim case llvm::Triple::systemz: 1916263508Sdim case llvm::Triple::x86: 1917263508Sdim case llvm::Triple::x86_64: 1918263508Sdim if (Triple.isOSLinux()) 1919263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 1920263508Sdim if (!A->getOption().matches(options::OPT_O0)) 1921263508Sdim return false; 1922263508Sdim return true; 1923263508Sdim case llvm::Triple::xcore: 1924263508Sdim return false; 1925263508Sdim default: 1926263508Sdim return true; 1927263508Sdim } 1928263508Sdim} 1929263508Sdim 1930234353Sdimstatic bool shouldUseFramePointer(const ArgList &Args, 1931234353Sdim const llvm::Triple &Triple) { 1932234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer, 1933234353Sdim options::OPT_fomit_frame_pointer)) 1934234353Sdim return A->getOption().matches(options::OPT_fno_omit_frame_pointer); 1935234353Sdim 1936263508Sdim return shouldUseFramePointerForTarget(Args, Triple); 1937234353Sdim} 1938234353Sdim 1939249423Sdimstatic bool shouldUseLeafFramePointer(const ArgList &Args, 1940249423Sdim const llvm::Triple &Triple) { 1941249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer, 1942249423Sdim options::OPT_momit_leaf_frame_pointer)) 1943249423Sdim return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer); 1944249423Sdim 1945263508Sdim return shouldUseFramePointerForTarget(Args, Triple); 1946249423Sdim} 1947249423Sdim 1948263508Sdim/// Add a CC1 option to specify the debug compilation directory. 1949249423Sdimstatic void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { 1950251662Sdim SmallString<128> cwd; 1951251662Sdim if (!llvm::sys::fs::current_path(cwd)) { 1952251662Sdim CmdArgs.push_back("-fdebug-compilation-dir"); 1953251662Sdim CmdArgs.push_back(Args.MakeArgString(cwd)); 1954251662Sdim } 1955249423Sdim} 1956249423Sdim 1957249423Sdimstatic const char *SplitDebugName(const ArgList &Args, 1958249423Sdim const InputInfoList &Inputs) { 1959249423Sdim Arg *FinalOutput = Args.getLastArg(options::OPT_o); 1960249423Sdim if (FinalOutput && Args.hasArg(options::OPT_c)) { 1961249423Sdim SmallString<128> T(FinalOutput->getValue()); 1962249423Sdim llvm::sys::path::replace_extension(T, "dwo"); 1963249423Sdim return Args.MakeArgString(T); 1964249423Sdim } else { 1965249423Sdim // Use the compilation dir. 1966249423Sdim SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir)); 1967249423Sdim SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput())); 1968249423Sdim llvm::sys::path::replace_extension(F, "dwo"); 1969249423Sdim T += F; 1970249423Sdim return Args.MakeArgString(F); 1971249423Sdim } 1972249423Sdim} 1973249423Sdim 1974249423Sdimstatic void SplitDebugInfo(const ToolChain &TC, Compilation &C, 1975249423Sdim const Tool &T, const JobAction &JA, 1976249423Sdim const ArgList &Args, const InputInfo &Output, 1977249423Sdim const char *OutFile) { 1978249423Sdim ArgStringList ExtractArgs; 1979249423Sdim ExtractArgs.push_back("--extract-dwo"); 1980249423Sdim 1981249423Sdim ArgStringList StripArgs; 1982249423Sdim StripArgs.push_back("--strip-dwo"); 1983249423Sdim 1984249423Sdim // Grabbing the output of the earlier compile step. 1985249423Sdim StripArgs.push_back(Output.getFilename()); 1986249423Sdim ExtractArgs.push_back(Output.getFilename()); 1987249423Sdim ExtractArgs.push_back(OutFile); 1988249423Sdim 1989249423Sdim const char *Exec = 1990249423Sdim Args.MakeArgString(TC.GetProgramPath("objcopy")); 1991249423Sdim 1992249423Sdim // First extract the dwo sections. 1993249423Sdim C.addCommand(new Command(JA, T, Exec, ExtractArgs)); 1994249423Sdim 1995249423Sdim // Then remove them from the original .o file. 1996249423Sdim C.addCommand(new Command(JA, T, Exec, StripArgs)); 1997249423Sdim} 1998249423Sdim 1999263508Sdim/// \brief Vectorize at all optimization levels greater than 1 except for -Oz. 2000263508Sdimstatic bool shouldEnableVectorizerAtOLevel(const ArgList &Args) { 2001263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 2002263508Sdim if (A->getOption().matches(options::OPT_O4) || 2003263508Sdim A->getOption().matches(options::OPT_Ofast)) 2004263508Sdim return true; 2005263508Sdim 2006263508Sdim if (A->getOption().matches(options::OPT_O0)) 2007263508Sdim return false; 2008263508Sdim 2009263508Sdim assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag"); 2010263508Sdim 2011263508Sdim // Vectorize -Os. 2012263508Sdim StringRef S(A->getValue()); 2013263508Sdim if (S == "s") 2014263508Sdim return true; 2015263508Sdim 2016263508Sdim // Don't vectorize -Oz. 2017263508Sdim if (S == "z") 2018263508Sdim return false; 2019263508Sdim 2020263508Sdim unsigned OptLevel = 0; 2021263508Sdim if (S.getAsInteger(10, OptLevel)) 2022263508Sdim return false; 2023263508Sdim 2024263508Sdim return OptLevel > 1; 2025263508Sdim } 2026263508Sdim 2027263508Sdim return false; 2028263508Sdim} 2029263508Sdim 2030193326Sedvoid Clang::ConstructJob(Compilation &C, const JobAction &JA, 2031193326Sed const InputInfo &Output, 2032193326Sed const InputInfoList &Inputs, 2033193326Sed const ArgList &Args, 2034193326Sed const char *LinkingOutput) const { 2035205408Srdivacky bool KernelOrKext = Args.hasArg(options::OPT_mkernel, 2036205408Srdivacky options::OPT_fapple_kext); 2037201361Srdivacky const Driver &D = getToolChain().getDriver(); 2038193326Sed ArgStringList CmdArgs; 2039193326Sed 2040193326Sed assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 2041193326Sed 2042200583Srdivacky // Invoke ourselves in -cc1 mode. 2043200583Srdivacky // 2044200583Srdivacky // FIXME: Implement custom jobs for internal actions. 2045200583Srdivacky CmdArgs.push_back("-cc1"); 2046200583Srdivacky 2047198893Srdivacky // Add the "effective" target triple. 2048193326Sed CmdArgs.push_back("-triple"); 2049212904Sdim std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 2050198893Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 2051198092Srdivacky 2052198893Srdivacky // Select the appropriate action. 2053239462Sdim RewriteKind rewriteKind = RK_None; 2054234353Sdim 2055193326Sed if (isa<AnalyzeJobAction>(JA)) { 2056193326Sed assert(JA.getType() == types::TY_Plist && "Invalid output type."); 2057193326Sed CmdArgs.push_back("-analyze"); 2058234353Sdim } else if (isa<MigrateJobAction>(JA)) { 2059234353Sdim CmdArgs.push_back("-migrate"); 2060193326Sed } else if (isa<PreprocessJobAction>(JA)) { 2061193326Sed if (Output.getType() == types::TY_Dependencies) 2062193326Sed CmdArgs.push_back("-Eonly"); 2063249423Sdim else { 2064193326Sed CmdArgs.push_back("-E"); 2065249423Sdim if (Args.hasArg(options::OPT_rewrite_objc) && 2066249423Sdim !Args.hasArg(options::OPT_g_Group)) 2067249423Sdim CmdArgs.push_back("-P"); 2068249423Sdim } 2069203955Srdivacky } else if (isa<AssembleJobAction>(JA)) { 2070203955Srdivacky CmdArgs.push_back("-emit-obj"); 2071208600Srdivacky 2072263508Sdim CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D); 2073212904Sdim 2074218893Sdim // Also ignore explicit -force_cpusubtype_ALL option. 2075218893Sdim (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); 2076193326Sed } else if (isa<PrecompileJobAction>(JA)) { 2077212904Sdim // Use PCH if the user requested it. 2078198398Srdivacky bool UsePCH = D.CCCUsePCH; 2079198398Srdivacky 2080239462Sdim if (JA.getType() == types::TY_Nothing) 2081239462Sdim CmdArgs.push_back("-fsyntax-only"); 2082239462Sdim else if (UsePCH) 2083193326Sed CmdArgs.push_back("-emit-pch"); 2084193326Sed else 2085193326Sed CmdArgs.push_back("-emit-pth"); 2086193326Sed } else { 2087193326Sed assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool."); 2088193326Sed 2089193326Sed if (JA.getType() == types::TY_Nothing) { 2090193326Sed CmdArgs.push_back("-fsyntax-only"); 2091210299Sed } else if (JA.getType() == types::TY_LLVM_IR || 2092210299Sed JA.getType() == types::TY_LTO_IR) { 2093193326Sed CmdArgs.push_back("-emit-llvm"); 2094210299Sed } else if (JA.getType() == types::TY_LLVM_BC || 2095210299Sed JA.getType() == types::TY_LTO_BC) { 2096193326Sed CmdArgs.push_back("-emit-llvm-bc"); 2097193326Sed } else if (JA.getType() == types::TY_PP_Asm) { 2098193326Sed CmdArgs.push_back("-S"); 2099198092Srdivacky } else if (JA.getType() == types::TY_AST) { 2100198092Srdivacky CmdArgs.push_back("-emit-pch"); 2101249423Sdim } else if (JA.getType() == types::TY_ModuleFile) { 2102249423Sdim CmdArgs.push_back("-module-file-info"); 2103203955Srdivacky } else if (JA.getType() == types::TY_RewrittenObjC) { 2104203955Srdivacky CmdArgs.push_back("-rewrite-objc"); 2105239462Sdim rewriteKind = RK_NonFragile; 2106234353Sdim } else if (JA.getType() == types::TY_RewrittenLegacyObjC) { 2107234353Sdim CmdArgs.push_back("-rewrite-objc"); 2108239462Sdim rewriteKind = RK_Fragile; 2109203955Srdivacky } else { 2110203955Srdivacky assert(JA.getType() == types::TY_PP_Asm && 2111203955Srdivacky "Unexpected output type!"); 2112193326Sed } 2113193326Sed } 2114193326Sed 2115193326Sed // The make clang go fast button. 2116193326Sed CmdArgs.push_back("-disable-free"); 2117193326Sed 2118203955Srdivacky // Disable the verification pass in -asserts builds. 2119203955Srdivacky#ifdef NDEBUG 2120203955Srdivacky CmdArgs.push_back("-disable-llvm-verifier"); 2121203955Srdivacky#endif 2122203955Srdivacky 2123193326Sed // Set the main file name, so that debug info works even with 2124193326Sed // -save-temps. 2125193326Sed CmdArgs.push_back("-main-file-name"); 2126249423Sdim CmdArgs.push_back(getBaseInputName(Args, Inputs)); 2127193326Sed 2128193326Sed // Some flags which affect the language (via preprocessor 2129249423Sdim // defines). 2130193326Sed if (Args.hasArg(options::OPT_static)) 2131193326Sed CmdArgs.push_back("-static-define"); 2132193326Sed 2133193326Sed if (isa<AnalyzeJobAction>(JA)) { 2134198092Srdivacky // Enable region store model by default. 2135198092Srdivacky CmdArgs.push_back("-analyzer-store=region"); 2136198092Srdivacky 2137200583Srdivacky // Treat blocks as analysis entry points. 2138200583Srdivacky CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks"); 2139200583Srdivacky 2140221345Sdim CmdArgs.push_back("-analyzer-eagerly-assume"); 2141221345Sdim 2142193326Sed // Add default argument set. 2143193326Sed if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) { 2144221345Sdim CmdArgs.push_back("-analyzer-checker=core"); 2145218893Sdim 2146218893Sdim if (getToolChain().getTriple().getOS() != llvm::Triple::Win32) 2147218893Sdim CmdArgs.push_back("-analyzer-checker=unix"); 2148221345Sdim 2149218893Sdim if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple) 2150221345Sdim CmdArgs.push_back("-analyzer-checker=osx"); 2151234353Sdim 2152234353Sdim CmdArgs.push_back("-analyzer-checker=deadcode"); 2153234353Sdim 2154251662Sdim if (types::isCXX(Inputs[0].getType())) 2155251662Sdim CmdArgs.push_back("-analyzer-checker=cplusplus"); 2156251662Sdim 2157234353Sdim // Enable the following experimental checkers for testing. 2158234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn"); 2159234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw"); 2160234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets"); 2161234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp"); 2162234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp"); 2163234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork"); 2164193326Sed } 2165193326Sed 2166193326Sed // Set the output format. The default is plist, for (lame) historical 2167193326Sed // reasons. 2168193326Sed CmdArgs.push_back("-analyzer-output"); 2169193326Sed if (Arg *A = Args.getLastArg(options::OPT__analyzer_output)) 2170243830Sdim CmdArgs.push_back(A->getValue()); 2171193326Sed else 2172193326Sed CmdArgs.push_back("plist"); 2173193326Sed 2174206084Srdivacky // Disable the presentation of standard compiler warnings when 2175206084Srdivacky // using --analyze. We only want to show static analyzer diagnostics 2176206084Srdivacky // or frontend errors. 2177206084Srdivacky CmdArgs.push_back("-w"); 2178206084Srdivacky 2179193326Sed // Add -Xanalyzer arguments when running as analyzer. 2180193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer); 2181198092Srdivacky } 2182198092Srdivacky 2183198092Srdivacky CheckCodeGenerationOptions(D, Args); 2184198092Srdivacky 2185251662Sdim bool PIE = getToolChain().isPIEDefault(); 2186251662Sdim bool PIC = PIE || getToolChain().isPICDefault(); 2187243830Sdim bool IsPICLevelTwo = PIC; 2188251662Sdim 2189251662Sdim // For the PIC and PIE flag options, this logic is different from the 2190251662Sdim // legacy logic in very old versions of GCC, as that logic was just 2191251662Sdim // a bug no one had ever fixed. This logic is both more rational and 2192251662Sdim // consistent with GCC's new logic now that the bugs are fixed. The last 2193251662Sdim // argument relating to either PIC or PIE wins, and no other argument is 2194251662Sdim // used. If the last argument is any flavor of the '-fno-...' arguments, 2195251662Sdim // both PIC and PIE are disabled. Any PIE option implicitly enables PIC 2196251662Sdim // at the same level. 2197251662Sdim Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 2198251662Sdim options::OPT_fpic, options::OPT_fno_pic, 2199251662Sdim options::OPT_fPIE, options::OPT_fno_PIE, 2200251662Sdim options::OPT_fpie, options::OPT_fno_pie); 2201243830Sdim // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness 2202243830Sdim // is forced, then neither PIC nor PIE flags will have no effect. 2203251662Sdim if (!getToolChain().isPICDefaultForced()) { 2204251662Sdim if (LastPICArg) { 2205251662Sdim Option O = LastPICArg->getOption(); 2206251662Sdim if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || 2207251662Sdim O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { 2208251662Sdim PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); 2209251662Sdim PIC = PIE || O.matches(options::OPT_fPIC) || 2210251662Sdim O.matches(options::OPT_fpic); 2211251662Sdim IsPICLevelTwo = O.matches(options::OPT_fPIE) || 2212251662Sdim O.matches(options::OPT_fPIC); 2213251662Sdim } else { 2214251662Sdim PIE = PIC = false; 2215251662Sdim } 2216251662Sdim } 2217243830Sdim } 2218193326Sed 2219263508Sdim // Introduce a Darwin-specific hack. If the default is PIC but the flags 2220243830Sdim // specified while enabling PIC enabled level 1 PIC, just force it back to 2221243830Sdim // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my 2222243830Sdim // informal testing). 2223243830Sdim if (PIC && getToolChain().getTriple().isOSDarwin()) 2224243830Sdim IsPICLevelTwo |= getToolChain().isPICDefault(); 2225239462Sdim 2226234353Sdim // Note that these flags are trump-cards. Regardless of the order w.r.t. the 2227234353Sdim // PIC or PIE options above, if these show up, PIC is disabled. 2228243830Sdim llvm::Triple Triple(TripleStr); 2229249423Sdim if (KernelOrKext && 2230263508Sdim (!Triple.isiOS() || Triple.isOSVersionLT(6))) 2231243830Sdim PIC = PIE = false; 2232234353Sdim if (Args.hasArg(options::OPT_static)) 2233243830Sdim PIC = PIE = false; 2234234353Sdim 2235243830Sdim if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) { 2236243830Sdim // This is a very special mode. It trumps the other modes, almost no one 2237243830Sdim // uses it, and it isn't even valid on any OS but Darwin. 2238243830Sdim if (!getToolChain().getTriple().isOSDarwin()) 2239243830Sdim D.Diag(diag::err_drv_unsupported_opt_for_target) 2240243830Sdim << A->getSpelling() << getToolChain().getTriple().str(); 2241243830Sdim 2242243830Sdim // FIXME: Warn when this flag trumps some other PIC or PIE flag. 2243243830Sdim 2244199990Srdivacky CmdArgs.push_back("-mrelocation-model"); 2245243830Sdim CmdArgs.push_back("dynamic-no-pic"); 2246193326Sed 2247243830Sdim // Only a forced PIC mode can cause the actual compile to have PIC defines 2248243830Sdim // etc., no flags are sufficient. This behavior was selected to closely 2249243830Sdim // match that of llvm-gcc and Apple GCC before that. 2250243830Sdim if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) { 2251243830Sdim CmdArgs.push_back("-pic-level"); 2252243830Sdim CmdArgs.push_back("2"); 2253243830Sdim } 2254243830Sdim } else { 2255243830Sdim // Currently, LLVM only knows about PIC vs. static; the PIE differences are 2256243830Sdim // handled in Clang's IRGen by the -pie-level flag. 2257243830Sdim CmdArgs.push_back("-mrelocation-model"); 2258243830Sdim CmdArgs.push_back(PIC ? "pic" : "static"); 2259243830Sdim 2260243830Sdim if (PIC) { 2261243830Sdim CmdArgs.push_back("-pic-level"); 2262243830Sdim CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); 2263243830Sdim if (PIE) { 2264243830Sdim CmdArgs.push_back("-pie-level"); 2265243830Sdim CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); 2266243830Sdim } 2267243830Sdim } 2268193326Sed } 2269234353Sdim 2270199990Srdivacky if (!Args.hasFlag(options::OPT_fmerge_all_constants, 2271199990Srdivacky options::OPT_fno_merge_all_constants)) 2272221345Sdim CmdArgs.push_back("-fno-merge-all-constants"); 2273193326Sed 2274199990Srdivacky // LLVM Code Generator Options. 2275199990Srdivacky 2276218893Sdim if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) { 2277218893Sdim CmdArgs.push_back("-mregparm"); 2278243830Sdim CmdArgs.push_back(A->getValue()); 2279218893Sdim } 2280218893Sdim 2281263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return, 2282263508Sdim options::OPT_freg_struct_return)) { 2283263508Sdim if (getToolChain().getArch() != llvm::Triple::x86) { 2284263508Sdim D.Diag(diag::err_drv_unsupported_opt_for_target) 2285263508Sdim << A->getSpelling() << getToolChain().getTriple().str(); 2286263508Sdim } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) { 2287263508Sdim CmdArgs.push_back("-fpcc-struct-return"); 2288263508Sdim } else { 2289263508Sdim assert(A->getOption().matches(options::OPT_freg_struct_return)); 2290263508Sdim CmdArgs.push_back("-freg-struct-return"); 2291263508Sdim } 2292263508Sdim } 2293263508Sdim 2294221345Sdim if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) 2295221345Sdim CmdArgs.push_back("-mrtd"); 2296221345Sdim 2297234353Sdim if (shouldUseFramePointer(Args, getToolChain().getTriple())) 2298199990Srdivacky CmdArgs.push_back("-mdisable-fp-elim"); 2299193326Sed if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, 2300199990Srdivacky options::OPT_fno_zero_initialized_in_bss)) 2301199990Srdivacky CmdArgs.push_back("-mno-zero-initialized-in-bss"); 2302251662Sdim 2303251662Sdim bool OFastEnabled = isOptimizationLevelFast(Args); 2304251662Sdim // If -Ofast is the optimization level, then -fstrict-aliasing should be 2305251662Sdim // enabled. This alias option is being used to simplify the hasFlag logic. 2306251662Sdim OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : 2307251662Sdim options::OPT_fstrict_aliasing; 2308251662Sdim if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, 2309263508Sdim options::OPT_fno_strict_aliasing, true)) 2310218893Sdim CmdArgs.push_back("-relaxed-aliasing"); 2311263508Sdim if (!Args.hasFlag(options::OPT_fstruct_path_tbaa, 2312263508Sdim options::OPT_fno_struct_path_tbaa)) 2313263508Sdim CmdArgs.push_back("-no-struct-path-tbaa"); 2314234353Sdim if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums, 2315234353Sdim false)) 2316234353Sdim CmdArgs.push_back("-fstrict-enums"); 2317234353Sdim if (!Args.hasFlag(options::OPT_foptimize_sibling_calls, 2318234353Sdim options::OPT_fno_optimize_sibling_calls)) 2319234353Sdim CmdArgs.push_back("-mdisable-tail-calls"); 2320208600Srdivacky 2321249423Sdim // Handle segmented stacks. 2322249423Sdim if (Args.hasArg(options::OPT_fsplit_stack)) 2323249423Sdim CmdArgs.push_back("-split-stacks"); 2324251662Sdim 2325251662Sdim // If -Ofast is the optimization level, then -ffast-math should be enabled. 2326251662Sdim // This alias option is being used to simplify the getLastArg logic. 2327251662Sdim OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast : 2328251662Sdim options::OPT_ffast_math; 2329249423Sdim 2330234353Sdim // Handle various floating point optimization flags, mapping them to the 2331234353Sdim // appropriate LLVM code generation flags. The pattern for all of these is to 2332234353Sdim // default off the codegen optimizations, and if any flag enables them and no 2333234353Sdim // flag disables them after the flag enabling them, enable the codegen 2334234353Sdim // optimization. This is complicated by several "umbrella" flags. 2335251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2336243830Sdim options::OPT_fno_fast_math, 2337234353Sdim options::OPT_ffinite_math_only, 2338234353Sdim options::OPT_fno_finite_math_only, 2339234353Sdim options::OPT_fhonor_infinities, 2340234353Sdim options::OPT_fno_honor_infinities)) 2341243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2342243830Sdim A->getOption().getID() != options::OPT_fno_finite_math_only && 2343234353Sdim A->getOption().getID() != options::OPT_fhonor_infinities) 2344234353Sdim CmdArgs.push_back("-menable-no-infs"); 2345251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2346243830Sdim options::OPT_fno_fast_math, 2347234353Sdim options::OPT_ffinite_math_only, 2348234353Sdim options::OPT_fno_finite_math_only, 2349234353Sdim options::OPT_fhonor_nans, 2350234353Sdim options::OPT_fno_honor_nans)) 2351243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2352243830Sdim A->getOption().getID() != options::OPT_fno_finite_math_only && 2353234353Sdim A->getOption().getID() != options::OPT_fhonor_nans) 2354234353Sdim CmdArgs.push_back("-menable-no-nans"); 2355234353Sdim 2356239462Sdim // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. 2357239462Sdim bool MathErrno = getToolChain().IsMathErrnoDefault(); 2358251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2359243830Sdim options::OPT_fno_fast_math, 2360234353Sdim options::OPT_fmath_errno, 2361263508Sdim options::OPT_fno_math_errno)) { 2362263508Sdim // Turning on -ffast_math (with either flag) removes the need for MathErrno. 2363263508Sdim // However, turning *off* -ffast_math merely restores the toolchain default 2364263508Sdim // (which may be false). 2365263508Sdim if (A->getOption().getID() == options::OPT_fno_math_errno || 2366263508Sdim A->getOption().getID() == options::OPT_ffast_math || 2367263508Sdim A->getOption().getID() == options::OPT_Ofast) 2368263508Sdim MathErrno = false; 2369263508Sdim else if (A->getOption().getID() == options::OPT_fmath_errno) 2370263508Sdim MathErrno = true; 2371263508Sdim } 2372239462Sdim if (MathErrno) 2373239462Sdim CmdArgs.push_back("-fmath-errno"); 2374234353Sdim 2375234353Sdim // There are several flags which require disabling very specific 2376234353Sdim // optimizations. Any of these being disabled forces us to turn off the 2377234353Sdim // entire set of LLVM optimizations, so collect them through all the flag 2378234353Sdim // madness. 2379234353Sdim bool AssociativeMath = false; 2380251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2381243830Sdim options::OPT_fno_fast_math, 2382234353Sdim options::OPT_funsafe_math_optimizations, 2383234353Sdim options::OPT_fno_unsafe_math_optimizations, 2384234353Sdim options::OPT_fassociative_math, 2385234353Sdim options::OPT_fno_associative_math)) 2386243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2387243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2388234353Sdim A->getOption().getID() != options::OPT_fno_associative_math) 2389234353Sdim AssociativeMath = true; 2390234353Sdim bool ReciprocalMath = false; 2391251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2392243830Sdim options::OPT_fno_fast_math, 2393234353Sdim options::OPT_funsafe_math_optimizations, 2394234353Sdim options::OPT_fno_unsafe_math_optimizations, 2395234353Sdim options::OPT_freciprocal_math, 2396234353Sdim options::OPT_fno_reciprocal_math)) 2397243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2398243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2399234353Sdim A->getOption().getID() != options::OPT_fno_reciprocal_math) 2400234353Sdim ReciprocalMath = true; 2401234353Sdim bool SignedZeros = true; 2402251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2403243830Sdim options::OPT_fno_fast_math, 2404234353Sdim options::OPT_funsafe_math_optimizations, 2405234353Sdim options::OPT_fno_unsafe_math_optimizations, 2406234353Sdim options::OPT_fsigned_zeros, 2407234353Sdim options::OPT_fno_signed_zeros)) 2408243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2409243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2410234353Sdim A->getOption().getID() != options::OPT_fsigned_zeros) 2411234353Sdim SignedZeros = false; 2412234353Sdim bool TrappingMath = true; 2413251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2414243830Sdim options::OPT_fno_fast_math, 2415234353Sdim options::OPT_funsafe_math_optimizations, 2416234353Sdim options::OPT_fno_unsafe_math_optimizations, 2417234353Sdim options::OPT_ftrapping_math, 2418234353Sdim options::OPT_fno_trapping_math)) 2419243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2420243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2421234353Sdim A->getOption().getID() != options::OPT_ftrapping_math) 2422234353Sdim TrappingMath = false; 2423234353Sdim if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros && 2424234353Sdim !TrappingMath) 2425234353Sdim CmdArgs.push_back("-menable-unsafe-fp-math"); 2426234353Sdim 2427239462Sdim 2428239462Sdim // Validate and pass through -fp-contract option. 2429251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2430243830Sdim options::OPT_fno_fast_math, 2431239462Sdim options::OPT_ffp_contract)) { 2432239462Sdim if (A->getOption().getID() == options::OPT_ffp_contract) { 2433243830Sdim StringRef Val = A->getValue(); 2434239462Sdim if (Val == "fast" || Val == "on" || Val == "off") { 2435239462Sdim CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val)); 2436239462Sdim } else { 2437239462Sdim D.Diag(diag::err_drv_unsupported_option_argument) 2438239462Sdim << A->getOption().getName() << Val; 2439239462Sdim } 2440251662Sdim } else if (A->getOption().matches(options::OPT_ffast_math) || 2441251662Sdim (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) { 2442239462Sdim // If fast-math is set then set the fp-contract mode to fast. 2443239462Sdim CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); 2444239462Sdim } 2445239462Sdim } 2446239462Sdim 2447239462Sdim // We separately look for the '-ffast-math' and '-ffinite-math-only' flags, 2448239462Sdim // and if we find them, tell the frontend to provide the appropriate 2449239462Sdim // preprocessor macros. This is distinct from enabling any optimizations as 2450239462Sdim // these options induce language changes which must survive serialization 2451239462Sdim // and deserialization, etc. 2452251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2453251662Sdim options::OPT_fno_fast_math)) 2454251662Sdim if (!A->getOption().matches(options::OPT_fno_fast_math)) 2455251662Sdim CmdArgs.push_back("-ffast-math"); 2456243830Sdim if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math)) 2457243830Sdim if (A->getOption().matches(options::OPT_ffinite_math_only)) 2458243830Sdim CmdArgs.push_back("-ffinite-math-only"); 2459234353Sdim 2460208600Srdivacky // Decide whether to use verbose asm. Verbose assembly is the default on 2461208600Srdivacky // toolchains which have the integrated assembler on by default. 2462208600Srdivacky bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault(); 2463208600Srdivacky if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, 2464218893Sdim IsVerboseAsmDefault) || 2465208600Srdivacky Args.hasArg(options::OPT_dA)) 2466199990Srdivacky CmdArgs.push_back("-masm-verbose"); 2467208600Srdivacky 2468199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_structure)) { 2469199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 2470199990Srdivacky CmdArgs.push_back("Structure"); 2471199990Srdivacky } 2472199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_arguments)) { 2473199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 2474199990Srdivacky CmdArgs.push_back("Arguments"); 2475199990Srdivacky } 2476198092Srdivacky 2477204643Srdivacky // Enable -mconstructor-aliases except on darwin, where we have to 2478204643Srdivacky // work around a linker bug; see <rdar://problem/7651567>. 2479226633Sdim if (!getToolChain().getTriple().isOSDarwin()) 2480204643Srdivacky CmdArgs.push_back("-mconstructor-aliases"); 2481204643Srdivacky 2482221345Sdim // Darwin's kernel doesn't support guard variables; just die if we 2483221345Sdim // try to use them. 2484226633Sdim if (KernelOrKext && getToolChain().getTriple().isOSDarwin()) 2485221345Sdim CmdArgs.push_back("-fforbid-guard-variables"); 2486221345Sdim 2487218893Sdim if (Args.hasArg(options::OPT_mms_bitfields)) { 2488218893Sdim CmdArgs.push_back("-mms-bitfields"); 2489218893Sdim } 2490218893Sdim 2491198092Srdivacky // This is a coarse approximation of what llvm-gcc actually does, both 2492198092Srdivacky // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more 2493198092Srdivacky // complicated ways. 2494198092Srdivacky bool AsynchronousUnwindTables = 2495198092Srdivacky Args.hasFlag(options::OPT_fasynchronous_unwind_tables, 2496198092Srdivacky options::OPT_fno_asynchronous_unwind_tables, 2497198092Srdivacky getToolChain().IsUnwindTablesDefault() && 2498205408Srdivacky !KernelOrKext); 2499198092Srdivacky if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, 2500198092Srdivacky AsynchronousUnwindTables)) 2501199990Srdivacky CmdArgs.push_back("-munwind-tables"); 2502193326Sed 2503249423Sdim getToolChain().addClangTargetOptions(Args, CmdArgs); 2504239462Sdim 2505199990Srdivacky if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { 2506199990Srdivacky CmdArgs.push_back("-mlimit-float-precision"); 2507243830Sdim CmdArgs.push_back(A->getValue()); 2508199990Srdivacky } 2509199990Srdivacky 2510193326Sed // FIXME: Handle -mtune=. 2511193326Sed (void) Args.hasArg(options::OPT_mtune_EQ); 2512193326Sed 2513198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) { 2514199990Srdivacky CmdArgs.push_back("-mcode-model"); 2515243830Sdim CmdArgs.push_back(A->getValue()); 2516193326Sed } 2517193326Sed 2518263508Sdim // Add the target cpu 2519263508Sdim std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 2520263508Sdim llvm::Triple ETriple(ETripleStr); 2521263508Sdim std::string CPU = getCPUName(Args, ETriple); 2522263508Sdim if (!CPU.empty()) { 2523263508Sdim CmdArgs.push_back("-target-cpu"); 2524263508Sdim CmdArgs.push_back(Args.MakeArgString(CPU)); 2525263508Sdim } 2526263508Sdim 2527263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) { 2528263508Sdim CmdArgs.push_back("-mfpmath"); 2529263508Sdim CmdArgs.push_back(A->getValue()); 2530263508Sdim } 2531263508Sdim 2532263508Sdim // Add the target features 2533263508Sdim getTargetFeatures(D, ETriple, Args, CmdArgs); 2534263508Sdim 2535263508Sdim // Add target specific flags. 2536263508Sdim switch(getToolChain().getArch()) { 2537198092Srdivacky default: 2538198092Srdivacky break; 2539193326Sed 2540198092Srdivacky case llvm::Triple::arm: 2541198092Srdivacky case llvm::Triple::thumb: 2542221345Sdim AddARMTargetArgs(Args, CmdArgs, KernelOrKext); 2543198092Srdivacky break; 2544193326Sed 2545204643Srdivacky case llvm::Triple::mips: 2546204643Srdivacky case llvm::Triple::mipsel: 2547226633Sdim case llvm::Triple::mips64: 2548226633Sdim case llvm::Triple::mips64el: 2549204643Srdivacky AddMIPSTargetArgs(Args, CmdArgs); 2550204643Srdivacky break; 2551204643Srdivacky 2552218893Sdim case llvm::Triple::sparc: 2553218893Sdim AddSparcTargetArgs(Args, CmdArgs); 2554218893Sdim break; 2555218893Sdim 2556198092Srdivacky case llvm::Triple::x86: 2557198092Srdivacky case llvm::Triple::x86_64: 2558198092Srdivacky AddX86TargetArgs(Args, CmdArgs); 2559198092Srdivacky break; 2560234353Sdim 2561234353Sdim case llvm::Triple::hexagon: 2562234353Sdim AddHexagonTargetArgs(Args, CmdArgs); 2563234353Sdim break; 2564193326Sed } 2565193326Sed 2566263508Sdim // Add clang-cl arguments. 2567263508Sdim if (getToolChain().getDriver().IsCLMode()) 2568263508Sdim AddClangCLArgs(Args, CmdArgs); 2569234353Sdim 2570212904Sdim // Pass the linker version in use. 2571212904Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 2572212904Sdim CmdArgs.push_back("-target-linker-version"); 2573243830Sdim CmdArgs.push_back(A->getValue()); 2574212904Sdim } 2575212904Sdim 2576249423Sdim if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple())) 2577210299Sed CmdArgs.push_back("-momit-leaf-frame-pointer"); 2578210299Sed 2579208600Srdivacky // Explicitly error on some things we know we don't support and can't just 2580208600Srdivacky // ignore. 2581208600Srdivacky types::ID InputType = Inputs[0].getType(); 2582218893Sdim if (!Args.hasArg(options::OPT_fallow_unsupported)) { 2583218893Sdim Arg *Unsupported; 2584218893Sdim if (types::isCXX(InputType) && 2585226633Sdim getToolChain().getTriple().isOSDarwin() && 2586263508Sdim getToolChain().getArch() == llvm::Triple::x86) { 2587226633Sdim if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) || 2588226633Sdim (Unsupported = Args.getLastArg(options::OPT_mkernel))) 2589226633Sdim D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386) 2590218893Sdim << Unsupported->getOption().getName(); 2591218893Sdim } 2592208600Srdivacky } 2593208600Srdivacky 2594193326Sed Args.AddAllArgs(CmdArgs, options::OPT_v); 2595212904Sdim Args.AddLastArg(CmdArgs, options::OPT_H); 2596226633Sdim if (D.CCPrintHeaders && !D.CCGenDiagnostics) { 2597218893Sdim CmdArgs.push_back("-header-include-file"); 2598218893Sdim CmdArgs.push_back(D.CCPrintHeadersFilename ? 2599218893Sdim D.CCPrintHeadersFilename : "-"); 2600218893Sdim } 2601193326Sed Args.AddLastArg(CmdArgs, options::OPT_P); 2602198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); 2603193326Sed 2604226633Sdim if (D.CCLogDiagnostics && !D.CCGenDiagnostics) { 2605221345Sdim CmdArgs.push_back("-diagnostic-log-file"); 2606221345Sdim CmdArgs.push_back(D.CCLogDiagnosticsFilename ? 2607221345Sdim D.CCLogDiagnosticsFilename : "-"); 2608221345Sdim } 2609221345Sdim 2610249423Sdim // Use the last option from "-g" group. "-gline-tables-only" 2611249423Sdim // is preserved, all other debug options are substituted with "-g". 2612204962Srdivacky Args.ClaimAllArgs(options::OPT_g_Group); 2613239462Sdim if (Arg *A = Args.getLastArg(options::OPT_g_Group)) { 2614249423Sdim if (A->getOption().matches(options::OPT_gline_tables_only)) 2615239462Sdim CmdArgs.push_back("-gline-tables-only"); 2616263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_2)) 2617263508Sdim CmdArgs.push_back("-gdwarf-2"); 2618263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_3)) 2619263508Sdim CmdArgs.push_back("-gdwarf-3"); 2620263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_4)) 2621263508Sdim CmdArgs.push_back("-gdwarf-4"); 2622249423Sdim else if (!A->getOption().matches(options::OPT_g0) && 2623263508Sdim !A->getOption().matches(options::OPT_ggdb0)) { 2624264464Sdim // Default is dwarf-2 for darwin and FreeBSD. 2625263984Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 2626264464Sdim if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::FreeBSD) 2627263508Sdim CmdArgs.push_back("-gdwarf-2"); 2628263508Sdim else 2629263508Sdim CmdArgs.push_back("-g"); 2630263508Sdim } 2631239462Sdim } 2632193326Sed 2633239462Sdim // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now. 2634239462Sdim Args.ClaimAllArgs(options::OPT_g_flags_Group); 2635243830Sdim if (Args.hasArg(options::OPT_gcolumn_info)) 2636243830Sdim CmdArgs.push_back("-dwarf-column-info"); 2637239462Sdim 2638263508Sdim // FIXME: Move backend command line options to the module. 2639249423Sdim // -gsplit-dwarf should turn on -g and enable the backend dwarf 2640249423Sdim // splitting and extraction. 2641249423Sdim // FIXME: Currently only works on Linux. 2642263508Sdim if (getToolChain().getTriple().isOSLinux() && 2643249423Sdim Args.hasArg(options::OPT_gsplit_dwarf)) { 2644249423Sdim CmdArgs.push_back("-g"); 2645249423Sdim CmdArgs.push_back("-backend-option"); 2646249423Sdim CmdArgs.push_back("-split-dwarf=Enable"); 2647249423Sdim } 2648249423Sdim 2649263508Sdim // -ggnu-pubnames turns on gnu style pubnames in the backend. 2650263508Sdim if (Args.hasArg(options::OPT_ggnu_pubnames)) { 2651263508Sdim CmdArgs.push_back("-backend-option"); 2652263508Sdim CmdArgs.push_back("-generate-gnu-dwarf-pub-sections"); 2653263508Sdim } 2654263508Sdim 2655263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_fdebug_types_section); 2656263508Sdim 2657208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections); 2658208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections); 2659208600Srdivacky 2660210299Sed Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions); 2661210299Sed 2662221345Sdim if (Args.hasArg(options::OPT_ftest_coverage) || 2663221345Sdim Args.hasArg(options::OPT_coverage)) 2664221345Sdim CmdArgs.push_back("-femit-coverage-notes"); 2665221345Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 2666221345Sdim Args.hasArg(options::OPT_coverage)) 2667221345Sdim CmdArgs.push_back("-femit-coverage-data"); 2668221345Sdim 2669223017Sdim if (C.getArgs().hasArg(options::OPT_c) || 2670223017Sdim C.getArgs().hasArg(options::OPT_S)) { 2671223017Sdim if (Output.isFilename()) { 2672223017Sdim CmdArgs.push_back("-coverage-file"); 2673249423Sdim SmallString<128> CoverageFilename(Output.getFilename()); 2674249423Sdim if (llvm::sys::path::is_relative(CoverageFilename.str())) { 2675263508Sdim SmallString<128> Pwd; 2676263508Sdim if (!llvm::sys::fs::current_path(Pwd)) { 2677263508Sdim llvm::sys::path::append(Pwd, CoverageFilename.str()); 2678263508Sdim CoverageFilename.swap(Pwd); 2679249423Sdim } 2680249423Sdim } 2681249423Sdim CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); 2682223017Sdim } 2683223017Sdim } 2684223017Sdim 2685226633Sdim // Pass options for controlling the default header search paths. 2686226633Sdim if (Args.hasArg(options::OPT_nostdinc)) { 2687226633Sdim CmdArgs.push_back("-nostdsysteminc"); 2688226633Sdim CmdArgs.push_back("-nobuiltininc"); 2689226633Sdim } else { 2690226633Sdim if (Args.hasArg(options::OPT_nostdlibinc)) 2691226633Sdim CmdArgs.push_back("-nostdsysteminc"); 2692226633Sdim Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); 2693226633Sdim Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); 2694226633Sdim } 2695193326Sed 2696200583Srdivacky // Pass the path to compiler resource files. 2697200583Srdivacky CmdArgs.push_back("-resource-dir"); 2698202879Srdivacky CmdArgs.push_back(D.ResourceDir.c_str()); 2699193326Sed 2700218893Sdim Args.AddLastArg(CmdArgs, options::OPT_working_directory); 2701218893Sdim 2702234353Sdim bool ARCMTEnabled = false; 2703263508Sdim if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) { 2704224145Sdim if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check, 2705224145Sdim options::OPT_ccc_arcmt_modify, 2706224145Sdim options::OPT_ccc_arcmt_migrate)) { 2707234353Sdim ARCMTEnabled = true; 2708224145Sdim switch (A->getOption().getID()) { 2709224145Sdim default: 2710224145Sdim llvm_unreachable("missed a case"); 2711224145Sdim case options::OPT_ccc_arcmt_check: 2712224145Sdim CmdArgs.push_back("-arcmt-check"); 2713224145Sdim break; 2714224145Sdim case options::OPT_ccc_arcmt_modify: 2715224145Sdim CmdArgs.push_back("-arcmt-modify"); 2716224145Sdim break; 2717224145Sdim case options::OPT_ccc_arcmt_migrate: 2718224145Sdim CmdArgs.push_back("-arcmt-migrate"); 2719234353Sdim CmdArgs.push_back("-mt-migrate-directory"); 2720243830Sdim CmdArgs.push_back(A->getValue()); 2721226633Sdim 2722226633Sdim Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output); 2723226633Sdim Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors); 2724224145Sdim break; 2725224145Sdim } 2726224145Sdim } 2727263508Sdim } else { 2728263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_check); 2729263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify); 2730263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate); 2731224145Sdim } 2732226633Sdim 2733234353Sdim if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) { 2734234353Sdim if (ARCMTEnabled) { 2735234353Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 2736234353Sdim << A->getAsString(Args) << "-ccc-arcmt-migrate"; 2737234353Sdim } 2738234353Sdim CmdArgs.push_back("-mt-migrate-directory"); 2739243830Sdim CmdArgs.push_back(A->getValue()); 2740234353Sdim 2741234353Sdim if (!Args.hasArg(options::OPT_objcmt_migrate_literals, 2742263508Sdim options::OPT_objcmt_migrate_subscripting, 2743263508Sdim options::OPT_objcmt_migrate_property)) { 2744234353Sdim // None specified, means enable them all. 2745234353Sdim CmdArgs.push_back("-objcmt-migrate-literals"); 2746234353Sdim CmdArgs.push_back("-objcmt-migrate-subscripting"); 2747263508Sdim CmdArgs.push_back("-objcmt-migrate-property"); 2748234353Sdim } else { 2749234353Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); 2750234353Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); 2751263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); 2752234353Sdim } 2753263508Sdim } else { 2754263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); 2755263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); 2756263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); 2757263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all); 2758263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property); 2759263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property); 2760263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation); 2761263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype); 2762263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros); 2763263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance); 2764263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property); 2765263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property); 2766263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly); 2767263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_white_list_dir_path); 2768234353Sdim } 2769234353Sdim 2770193326Sed // Add preprocessing options like -I, -D, etc. if we are using the 2771193326Sed // preprocessor. 2772193326Sed // 2773193326Sed // FIXME: Support -fpreprocessed 2774193326Sed if (types::getPreprocessedType(InputType) != types::TY_INVALID) 2775249423Sdim AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs); 2776193326Sed 2777226633Sdim // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes 2778226633Sdim // that "The compiler can only warn and ignore the option if not recognized". 2779226633Sdim // When building with ccache, it will pass -D options to clang even on 2780226633Sdim // preprocessed inputs and configure concludes that -fPIC is not supported. 2781226633Sdim Args.ClaimAllArgs(options::OPT_D); 2782226633Sdim 2783263508Sdim // Manually translate -O4 to -O3; let clang reject others. 2784193326Sed if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 2785263508Sdim if (A->getOption().matches(options::OPT_O4)) { 2786193326Sed CmdArgs.push_back("-O3"); 2787263508Sdim D.Diag(diag::warn_O4_is_O3); 2788263508Sdim } else { 2789193326Sed A->render(Args, CmdArgs); 2790263508Sdim } 2791193326Sed } 2792193326Sed 2793249423Sdim // Don't warn about unused -flto. This can happen when we're preprocessing or 2794249423Sdim // precompiling. 2795249423Sdim Args.ClaimAllArgs(options::OPT_flto); 2796249423Sdim 2797198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_W_Group); 2798239462Sdim if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false)) 2799239462Sdim CmdArgs.push_back("-pedantic"); 2800198893Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors); 2801193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 2802193326Sed 2803193326Sed // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi} 2804263508Sdim // (-ansi is equivalent to -std=c89 or -std=c++98). 2805193326Sed // 2806193326Sed // If a std is supplied, only add -trigraphs if it follows the 2807193326Sed // option. 2808193326Sed if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 2809193326Sed if (Std->getOption().matches(options::OPT_ansi)) 2810198398Srdivacky if (types::isCXX(InputType)) 2811198893Srdivacky CmdArgs.push_back("-std=c++98"); 2812198398Srdivacky else 2813198893Srdivacky CmdArgs.push_back("-std=c89"); 2814193326Sed else 2815193326Sed Std->render(Args, CmdArgs); 2816193326Sed 2817210299Sed if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi, 2818210299Sed options::OPT_trigraphs)) 2819210299Sed if (A != Std) 2820193326Sed A->render(Args, CmdArgs); 2821193326Sed } else { 2822193326Sed // Honor -std-default. 2823203955Srdivacky // 2824203955Srdivacky // FIXME: Clang doesn't correctly handle -std= when the input language 2825203955Srdivacky // doesn't match. For the time being just ignore this for C++ inputs; 2826203955Srdivacky // eventually we want to do all the standard defaulting here instead of 2827203955Srdivacky // splitting it between the driver and clang -cc1. 2828203955Srdivacky if (!types::isCXX(InputType)) 2829243830Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, 2830243830Sdim "-std=", /*Joined=*/true); 2831243830Sdim else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32) 2832243830Sdim CmdArgs.push_back("-std=c++11"); 2833243830Sdim 2834193326Sed Args.AddLastArg(CmdArgs, options::OPT_trigraphs); 2835193326Sed } 2836193326Sed 2837263508Sdim // GCC's behavior for -Wwrite-strings is a bit strange: 2838263508Sdim // * In C, this "warning flag" changes the types of string literals from 2839263508Sdim // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning 2840263508Sdim // for the discarded qualifier. 2841263508Sdim // * In C++, this is just a normal warning flag. 2842263508Sdim // 2843263508Sdim // Implementing this warning correctly in C is hard, so we follow GCC's 2844263508Sdim // behavior for now. FIXME: Directly diagnose uses of a string literal as 2845263508Sdim // a non-const char* in C, rather than using this crude hack. 2846263508Sdim if (!types::isCXX(InputType)) { 2847263508Sdim DiagnosticsEngine::Level DiagLevel = D.getDiags().getDiagnosticLevel( 2848263508Sdim diag::warn_deprecated_string_literal_conversion_c, SourceLocation()); 2849263508Sdim if (DiagLevel > DiagnosticsEngine::Ignored) 2850263508Sdim CmdArgs.push_back("-fconst-strings"); 2851221345Sdim } 2852221345Sdim 2853221345Sdim // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active 2854221345Sdim // during C++ compilation, which it is by default. GCC keeps this define even 2855221345Sdim // in the presence of '-w', match this behavior bug-for-bug. 2856221345Sdim if (types::isCXX(InputType) && 2857221345Sdim Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated, 2858221345Sdim true)) { 2859221345Sdim CmdArgs.push_back("-fdeprecated-macro"); 2860221345Sdim } 2861221345Sdim 2862208600Srdivacky // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'. 2863208600Srdivacky if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) { 2864208600Srdivacky if (Asm->getOption().matches(options::OPT_fasm)) 2865208600Srdivacky CmdArgs.push_back("-fgnu-keywords"); 2866208600Srdivacky else 2867208600Srdivacky CmdArgs.push_back("-fno-gnu-keywords"); 2868208600Srdivacky } 2869208600Srdivacky 2870221345Sdim if (ShouldDisableCFI(Args, getToolChain())) 2871221345Sdim CmdArgs.push_back("-fno-dwarf2-cfi-asm"); 2872221345Sdim 2873234353Sdim if (ShouldDisableDwarfDirectory(Args, getToolChain())) 2874234353Sdim CmdArgs.push_back("-fno-dwarf-directory-asm"); 2875234353Sdim 2876251662Sdim if (ShouldDisableAutolink(Args, getToolChain())) 2877251662Sdim CmdArgs.push_back("-fno-autolink"); 2878251662Sdim 2879249423Sdim // Add in -fdebug-compilation-dir if necessary. 2880249423Sdim addDebugCompDirArg(Args, CmdArgs); 2881234353Sdim 2882234353Sdim if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_, 2883234353Sdim options::OPT_ftemplate_depth_EQ)) { 2884193326Sed CmdArgs.push_back("-ftemplate-depth"); 2885243830Sdim CmdArgs.push_back(A->getValue()); 2886193326Sed } 2887193326Sed 2888263508Sdim if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) { 2889263508Sdim CmdArgs.push_back("-foperator-arrow-depth"); 2890263508Sdim CmdArgs.push_back(A->getValue()); 2891263508Sdim } 2892263508Sdim 2893234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) { 2894234353Sdim CmdArgs.push_back("-fconstexpr-depth"); 2895243830Sdim CmdArgs.push_back(A->getValue()); 2896234353Sdim } 2897234353Sdim 2898263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) { 2899263508Sdim CmdArgs.push_back("-fconstexpr-steps"); 2900263508Sdim CmdArgs.push_back(A->getValue()); 2901263508Sdim } 2902263508Sdim 2903249423Sdim if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) { 2904249423Sdim CmdArgs.push_back("-fbracket-depth"); 2905249423Sdim CmdArgs.push_back(A->getValue()); 2906249423Sdim } 2907249423Sdim 2908218893Sdim if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ, 2909218893Sdim options::OPT_Wlarge_by_value_copy_def)) { 2910239462Sdim if (A->getNumValues()) { 2911243830Sdim StringRef bytes = A->getValue(); 2912239462Sdim CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes)); 2913239462Sdim } else 2914239462Sdim CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value 2915218893Sdim } 2916218893Sdim 2917239462Sdim 2918243830Sdim if (Args.hasArg(options::OPT_relocatable_pch)) 2919199990Srdivacky CmdArgs.push_back("-relocatable-pch"); 2920198092Srdivacky 2921198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { 2922198893Srdivacky CmdArgs.push_back("-fconstant-string-class"); 2923243830Sdim CmdArgs.push_back(A->getValue()); 2924198893Srdivacky } 2925198092Srdivacky 2926202379Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) { 2927202379Srdivacky CmdArgs.push_back("-ftabstop"); 2928243830Sdim CmdArgs.push_back(A->getValue()); 2929202379Srdivacky } 2930202379Srdivacky 2931207619Srdivacky CmdArgs.push_back("-ferror-limit"); 2932207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ)) 2933243830Sdim CmdArgs.push_back(A->getValue()); 2934207619Srdivacky else 2935207619Srdivacky CmdArgs.push_back("19"); 2936207619Srdivacky 2937208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) { 2938208600Srdivacky CmdArgs.push_back("-fmacro-backtrace-limit"); 2939243830Sdim CmdArgs.push_back(A->getValue()); 2940208600Srdivacky } 2941208600Srdivacky 2942208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) { 2943208600Srdivacky CmdArgs.push_back("-ftemplate-backtrace-limit"); 2944243830Sdim CmdArgs.push_back(A->getValue()); 2945208600Srdivacky } 2946208600Srdivacky 2947234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) { 2948234353Sdim CmdArgs.push_back("-fconstexpr-backtrace-limit"); 2949243830Sdim CmdArgs.push_back(A->getValue()); 2950234353Sdim } 2951234353Sdim 2952198893Srdivacky // Pass -fmessage-length=. 2953199990Srdivacky CmdArgs.push_back("-fmessage-length"); 2954198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { 2955243830Sdim CmdArgs.push_back(A->getValue()); 2956198893Srdivacky } else { 2957198893Srdivacky // If -fmessage-length=N was not specified, determine whether this is a 2958198893Srdivacky // terminal and, if so, implicitly define -fmessage-length appropriately. 2959198893Srdivacky unsigned N = llvm::sys::Process::StandardErrColumns(); 2960226633Sdim CmdArgs.push_back(Args.MakeArgString(Twine(N))); 2961198893Srdivacky } 2962198893Srdivacky 2963249423Sdim // -fvisibility= and -fvisibility-ms-compat are of a piece. 2964249423Sdim if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ, 2965249423Sdim options::OPT_fvisibility_ms_compat)) { 2966249423Sdim if (A->getOption().matches(options::OPT_fvisibility_EQ)) { 2967249423Sdim CmdArgs.push_back("-fvisibility"); 2968249423Sdim CmdArgs.push_back(A->getValue()); 2969249423Sdim } else { 2970249423Sdim assert(A->getOption().matches(options::OPT_fvisibility_ms_compat)); 2971249423Sdim CmdArgs.push_back("-fvisibility"); 2972249423Sdim CmdArgs.push_back("hidden"); 2973249423Sdim CmdArgs.push_back("-ftype-visibility"); 2974249423Sdim CmdArgs.push_back("default"); 2975249423Sdim } 2976200583Srdivacky } 2977200583Srdivacky 2978210299Sed Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); 2979218893Sdim 2980239462Sdim Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); 2981239462Sdim 2982205408Srdivacky // -fhosted is default. 2983234353Sdim if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) || 2984234353Sdim KernelOrKext) 2985205408Srdivacky CmdArgs.push_back("-ffreestanding"); 2986205408Srdivacky 2987200583Srdivacky // Forward -f (flag) options which we can pass directly. 2988193326Sed Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); 2989218893Sdim Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions); 2990193326Sed Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); 2991269011Semaste Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug); 2992269011Semaste Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug); 2993234353Sdim Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); 2994263508Sdim // AltiVec language extensions aren't relevant for assembling. 2995263508Sdim if (!isa<PreprocessJobAction>(JA) || 2996263508Sdim Output.getType() != types::TY_PP_Asm) 2997263508Sdim Args.AddLastArg(CmdArgs, options::OPT_faltivec); 2998239462Sdim Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); 2999239462Sdim Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); 3000234353Sdim 3001263508Sdim const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs(); 3002243830Sdim Sanitize.addArgs(Args, CmdArgs); 3003243830Sdim 3004249423Sdim if (!Args.hasFlag(options::OPT_fsanitize_recover, 3005249423Sdim options::OPT_fno_sanitize_recover, 3006249423Sdim true)) 3007249423Sdim CmdArgs.push_back("-fno-sanitize-recover"); 3008249423Sdim 3009249423Sdim if (Args.hasArg(options::OPT_fcatch_undefined_behavior) || 3010249423Sdim Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, 3011249423Sdim options::OPT_fno_sanitize_undefined_trap_on_error, false)) 3012249423Sdim CmdArgs.push_back("-fsanitize-undefined-trap-on-error"); 3013249423Sdim 3014249423Sdim // Report an error for -faltivec on anything other than PowerPC. 3015234353Sdim if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) 3016263508Sdim if (!(getToolChain().getArch() == llvm::Triple::ppc || 3017263508Sdim getToolChain().getArch() == llvm::Triple::ppc64 || 3018263508Sdim getToolChain().getArch() == llvm::Triple::ppc64le)) 3019234353Sdim D.Diag(diag::err_drv_argument_only_allowed_with) 3020263508Sdim << A->getAsString(Args) << "ppc/ppc64/ppc64le"; 3021234353Sdim 3022221345Sdim if (getToolChain().SupportsProfiling()) 3023221345Sdim Args.AddLastArg(CmdArgs, options::OPT_pg); 3024205408Srdivacky 3025205408Srdivacky // -flax-vector-conversions is default. 3026205408Srdivacky if (!Args.hasFlag(options::OPT_flax_vector_conversions, 3027205408Srdivacky options::OPT_fno_lax_vector_conversions)) 3028205408Srdivacky CmdArgs.push_back("-fno-lax-vector-conversions"); 3029205408Srdivacky 3030218893Sdim if (Args.getLastArg(options::OPT_fapple_kext)) 3031218893Sdim CmdArgs.push_back("-fapple-kext"); 3032218893Sdim 3033239462Sdim if (Args.hasFlag(options::OPT_frewrite_includes, 3034239462Sdim options::OPT_fno_rewrite_includes, false)) 3035239462Sdim CmdArgs.push_back("-frewrite-includes"); 3036239462Sdim 3037193326Sed Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch); 3038193326Sed Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); 3039212904Sdim Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits); 3040193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftime_report); 3041193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftrapv); 3042218893Sdim 3043218893Sdim if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { 3044218893Sdim CmdArgs.push_back("-ftrapv-handler"); 3045243830Sdim CmdArgs.push_back(A->getValue()); 3046218893Sdim } 3047218893Sdim 3048234353Sdim Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ); 3049221345Sdim 3050221345Sdim // -fno-strict-overflow implies -fwrapv if it isn't disabled, but 3051221345Sdim // -fstrict-overflow won't turn off an explicitly enabled -fwrapv. 3052221345Sdim if (Arg *A = Args.getLastArg(options::OPT_fwrapv, 3053221345Sdim options::OPT_fno_wrapv)) { 3054221345Sdim if (A->getOption().matches(options::OPT_fwrapv)) 3055221345Sdim CmdArgs.push_back("-fwrapv"); 3056221345Sdim } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow, 3057221345Sdim options::OPT_fno_strict_overflow)) { 3058221345Sdim if (A->getOption().matches(options::OPT_fno_strict_overflow)) 3059221345Sdim CmdArgs.push_back("-fwrapv"); 3060221345Sdim } 3061263508Sdim 3062263508Sdim if (Arg *A = Args.getLastArg(options::OPT_freroll_loops, 3063263508Sdim options::OPT_fno_reroll_loops)) 3064263508Sdim if (A->getOption().matches(options::OPT_freroll_loops)) 3065263508Sdim CmdArgs.push_back("-freroll-loops"); 3066263508Sdim 3067193326Sed Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); 3068263508Sdim Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, 3069263508Sdim options::OPT_fno_unroll_loops); 3070193326Sed 3071198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pthread); 3072198092Srdivacky 3073243830Sdim 3074199482Srdivacky // -stack-protector=0 is default. 3075199482Srdivacky unsigned StackProtectorLevel = 0; 3076195341Sed if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, 3077195341Sed options::OPT_fstack_protector_all, 3078195341Sed options::OPT_fstack_protector)) { 3079199482Srdivacky if (A->getOption().matches(options::OPT_fstack_protector)) 3080199482Srdivacky StackProtectorLevel = 1; 3081199482Srdivacky else if (A->getOption().matches(options::OPT_fstack_protector_all)) 3082199482Srdivacky StackProtectorLevel = 2; 3083226633Sdim } else { 3084226633Sdim StackProtectorLevel = 3085226633Sdim getToolChain().GetDefaultStackProtectorLevel(KernelOrKext); 3086226633Sdim } 3087199482Srdivacky if (StackProtectorLevel) { 3088199482Srdivacky CmdArgs.push_back("-stack-protector"); 3089226633Sdim CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel))); 3090195341Sed } 3091195341Sed 3092243830Sdim // --param ssp-buffer-size= 3093243830Sdim for (arg_iterator it = Args.filtered_begin(options::OPT__param), 3094243830Sdim ie = Args.filtered_end(); it != ie; ++it) { 3095243830Sdim StringRef Str((*it)->getValue()); 3096243830Sdim if (Str.startswith("ssp-buffer-size=")) { 3097243830Sdim if (StackProtectorLevel) { 3098243830Sdim CmdArgs.push_back("-stack-protector-buffer-size"); 3099243830Sdim // FIXME: Verify the argument is a valid integer. 3100243830Sdim CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16))); 3101243830Sdim } 3102243830Sdim (*it)->claim(); 3103243830Sdim } 3104243830Sdim } 3105243830Sdim 3106223017Sdim // Translate -mstackrealign 3107234353Sdim if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign, 3108234353Sdim false)) { 3109223017Sdim CmdArgs.push_back("-backend-option"); 3110223017Sdim CmdArgs.push_back("-force-align-stack"); 3111223017Sdim } 3112234353Sdim if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign, 3113234353Sdim false)) { 3114234353Sdim CmdArgs.push_back(Args.MakeArgString("-mstackrealign")); 3115234353Sdim } 3116226633Sdim 3117234353Sdim if (Args.hasArg(options::OPT_mstack_alignment)) { 3118234353Sdim StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment); 3119234353Sdim CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment)); 3120234353Sdim } 3121249423Sdim // -mkernel implies -mstrict-align; don't add the redundant option. 3122263508Sdim if (!KernelOrKext) { 3123263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, 3124263508Sdim options::OPT_munaligned_access)) { 3125263508Sdim if (A->getOption().matches(options::OPT_mno_unaligned_access)) { 3126263508Sdim CmdArgs.push_back("-backend-option"); 3127263508Sdim CmdArgs.push_back("-arm-strict-align"); 3128263508Sdim } else { 3129263508Sdim CmdArgs.push_back("-backend-option"); 3130263508Sdim CmdArgs.push_back("-arm-no-strict-align"); 3131263508Sdim } 3132263508Sdim } 3133243830Sdim } 3134234353Sdim 3135263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it, 3136263508Sdim options::OPT_mno_restrict_it)) { 3137263508Sdim if (A->getOption().matches(options::OPT_mrestrict_it)) { 3138263508Sdim CmdArgs.push_back("-backend-option"); 3139263508Sdim CmdArgs.push_back("-arm-restrict-it"); 3140263508Sdim } else { 3141263508Sdim CmdArgs.push_back("-backend-option"); 3142263508Sdim CmdArgs.push_back("-arm-no-restrict-it"); 3143263508Sdim } 3144263508Sdim } 3145263508Sdim 3146193326Sed // Forward -f options with positive and negative forms; we translate 3147193326Sed // these by hand. 3148263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) { 3149263508Sdim StringRef fname = A->getValue(); 3150263508Sdim if (!llvm::sys::fs::exists(fname)) 3151263508Sdim D.Diag(diag::err_drv_no_such_file) << fname; 3152263508Sdim else 3153263508Sdim A->render(Args, CmdArgs); 3154263508Sdim } 3155193326Sed 3156218893Sdim if (Args.hasArg(options::OPT_mkernel)) { 3157218893Sdim if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType)) 3158218893Sdim CmdArgs.push_back("-fapple-kext"); 3159218893Sdim if (!Args.hasArg(options::OPT_fbuiltin)) 3160218893Sdim CmdArgs.push_back("-fno-builtin"); 3161234353Sdim Args.ClaimAllArgs(options::OPT_fno_builtin); 3162218893Sdim } 3163199482Srdivacky // -fbuiltin is default. 3164218893Sdim else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin)) 3165199512Srdivacky CmdArgs.push_back("-fno-builtin"); 3166193326Sed 3167201361Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 3168201361Srdivacky options::OPT_fno_assume_sane_operator_new)) 3169201361Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 3170201361Srdivacky 3171199482Srdivacky // -fblocks=0 is default. 3172199482Srdivacky if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks, 3173221345Sdim getToolChain().IsBlocksDefault()) || 3174221345Sdim (Args.hasArg(options::OPT_fgnu_runtime) && 3175221345Sdim Args.hasArg(options::OPT_fobjc_nonfragile_abi) && 3176221345Sdim !Args.hasArg(options::OPT_fno_blocks))) { 3177199482Srdivacky CmdArgs.push_back("-fblocks"); 3178226633Sdim 3179226633Sdim if (!Args.hasArg(options::OPT_fgnu_runtime) && 3180226633Sdim !getToolChain().hasBlocksRuntime()) 3181226633Sdim CmdArgs.push_back("-fblocks-runtime-optional"); 3182193326Sed } 3183193326Sed 3184234353Sdim // -fmodules enables modules (off by default). However, for C++/Objective-C++, 3185234353Sdim // users must also pass -fcxx-modules. The latter flag will disappear once the 3186234353Sdim // modules implementation is solid for C++/Objective-C++ programs as well. 3187249423Sdim bool HaveModules = false; 3188234353Sdim if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) { 3189234353Sdim bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, 3190234353Sdim options::OPT_fno_cxx_modules, 3191234353Sdim false); 3192249423Sdim if (AllowedInCXX || !types::isCXX(InputType)) { 3193234353Sdim CmdArgs.push_back("-fmodules"); 3194249423Sdim HaveModules = true; 3195249423Sdim } 3196234353Sdim } 3197234353Sdim 3198263508Sdim // -fmodule-maps enables module map processing (off by default) for header 3199263508Sdim // checking. It is implied by -fmodules. 3200263508Sdim if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps, 3201263508Sdim false)) { 3202263508Sdim CmdArgs.push_back("-fmodule-maps"); 3203263508Sdim } 3204263508Sdim 3205263508Sdim // -fmodules-decluse checks that modules used are declared so (off by 3206263508Sdim // default). 3207263508Sdim if (Args.hasFlag(options::OPT_fmodules_decluse, 3208263508Sdim options::OPT_fno_modules_decluse, 3209263508Sdim false)) { 3210263508Sdim CmdArgs.push_back("-fmodules-decluse"); 3211263508Sdim } 3212263508Sdim 3213263508Sdim // -fmodule-name specifies the module that is currently being built (or 3214263508Sdim // used for header checking by -fmodule-maps). 3215263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) { 3216263508Sdim A->claim(); 3217263508Sdim A->render(Args, CmdArgs); 3218263508Sdim } 3219263508Sdim 3220263508Sdim // -fmodule-map-file can be used to specify a file containing module 3221263508Sdim // definitions. 3222263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) { 3223263508Sdim A->claim(); 3224263508Sdim A->render(Args, CmdArgs); 3225263508Sdim } 3226263508Sdim 3227249423Sdim // If a module path was provided, pass it along. Otherwise, use a temporary 3228249423Sdim // directory. 3229249423Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) { 3230249423Sdim A->claim(); 3231249423Sdim if (HaveModules) { 3232249423Sdim A->render(Args, CmdArgs); 3233249423Sdim } 3234249423Sdim } else if (HaveModules) { 3235249423Sdim SmallString<128> DefaultModuleCache; 3236249423Sdim llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, 3237249423Sdim DefaultModuleCache); 3238249423Sdim llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang"); 3239249423Sdim llvm::sys::path::append(DefaultModuleCache, "ModuleCache"); 3240249423Sdim const char Arg[] = "-fmodules-cache-path="; 3241249423Sdim DefaultModuleCache.insert(DefaultModuleCache.begin(), 3242249423Sdim Arg, Arg + strlen(Arg)); 3243249423Sdim CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache)); 3244249423Sdim } 3245249423Sdim 3246249423Sdim // Pass through all -fmodules-ignore-macro arguments. 3247249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro); 3248249423Sdim Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval); 3249249423Sdim Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after); 3250249423Sdim 3251207619Srdivacky // -faccess-control is default. 3252207619Srdivacky if (Args.hasFlag(options::OPT_fno_access_control, 3253207619Srdivacky options::OPT_faccess_control, 3254205408Srdivacky false)) 3255207619Srdivacky CmdArgs.push_back("-fno-access-control"); 3256205408Srdivacky 3257218893Sdim // -felide-constructors is the default. 3258218893Sdim if (Args.hasFlag(options::OPT_fno_elide_constructors, 3259218893Sdim options::OPT_felide_constructors, 3260218893Sdim false)) 3261218893Sdim CmdArgs.push_back("-fno-elide-constructors"); 3262218893Sdim 3263199482Srdivacky // -frtti is default. 3264234353Sdim if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) || 3265243830Sdim KernelOrKext) { 3266199512Srdivacky CmdArgs.push_back("-fno-rtti"); 3267198092Srdivacky 3268243830Sdim // -fno-rtti cannot usefully be combined with -fsanitize=vptr. 3269243830Sdim if (Sanitize.sanitizesVptr()) { 3270243830Sdim std::string NoRttiArg = 3271243830Sdim Args.getLastArg(options::OPT_mkernel, 3272243830Sdim options::OPT_fapple_kext, 3273243830Sdim options::OPT_fno_rtti)->getAsString(Args); 3274243830Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 3275243830Sdim << "-fsanitize=vptr" << NoRttiArg; 3276243830Sdim } 3277243830Sdim } 3278243830Sdim 3279234353Sdim // -fshort-enums=0 is default for all architectures except Hexagon. 3280218893Sdim if (Args.hasFlag(options::OPT_fshort_enums, 3281234353Sdim options::OPT_fno_short_enums, 3282263508Sdim getToolChain().getArch() == 3283234353Sdim llvm::Triple::hexagon)) 3284218893Sdim CmdArgs.push_back("-fshort-enums"); 3285218893Sdim 3286199482Srdivacky // -fsigned-char is default. 3287199990Srdivacky if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char, 3288199482Srdivacky isSignedCharDefault(getToolChain().getTriple()))) 3289199990Srdivacky CmdArgs.push_back("-fno-signed-char"); 3290199482Srdivacky 3291203955Srdivacky // -fthreadsafe-static is default. 3292218893Sdim if (!Args.hasFlag(options::OPT_fthreadsafe_statics, 3293203955Srdivacky options::OPT_fno_threadsafe_statics)) 3294203955Srdivacky CmdArgs.push_back("-fno-threadsafe-statics"); 3295203955Srdivacky 3296205408Srdivacky // -fuse-cxa-atexit is default. 3297263508Sdim if (!Args.hasFlag( 3298263508Sdim options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, 3299263508Sdim getToolChain().getTriple().getOS() != llvm::Triple::Cygwin && 3300263508Sdim getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 && 3301263508Sdim getToolChain().getArch() != llvm::Triple::hexagon && 3302263508Sdim getToolChain().getArch() != llvm::Triple::xcore) || 3303234353Sdim KernelOrKext) 3304205408Srdivacky CmdArgs.push_back("-fno-use-cxa-atexit"); 3305205408Srdivacky 3306199482Srdivacky // -fms-extensions=0 is default. 3307199990Srdivacky if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 3308199482Srdivacky getToolChain().getTriple().getOS() == llvm::Triple::Win32)) 3309199482Srdivacky CmdArgs.push_back("-fms-extensions"); 3310199482Srdivacky 3311226633Sdim // -fms-compatibility=0 is default. 3312234353Sdim if (Args.hasFlag(options::OPT_fms_compatibility, 3313234353Sdim options::OPT_fno_ms_compatibility, 3314234353Sdim (getToolChain().getTriple().getOS() == llvm::Triple::Win32 && 3315234353Sdim Args.hasFlag(options::OPT_fms_extensions, 3316234353Sdim options::OPT_fno_ms_extensions, 3317234353Sdim true)))) 3318226633Sdim CmdArgs.push_back("-fms-compatibility"); 3319226633Sdim 3320263508Sdim // -fmsc-version=1700 is default. 3321218893Sdim if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 3322218893Sdim getToolChain().getTriple().getOS() == llvm::Triple::Win32) || 3323218893Sdim Args.hasArg(options::OPT_fmsc_version)) { 3324226633Sdim StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version); 3325218893Sdim if (msc_ver.empty()) 3326263508Sdim CmdArgs.push_back("-fmsc-version=1700"); 3327218893Sdim else 3328218893Sdim CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver)); 3329218893Sdim } 3330218893Sdim 3331218893Sdim 3332249423Sdim // -fno-borland-extensions is default. 3333212904Sdim if (Args.hasFlag(options::OPT_fborland_extensions, 3334212904Sdim options::OPT_fno_borland_extensions, false)) 3335212904Sdim CmdArgs.push_back("-fborland-extensions"); 3336212904Sdim 3337226633Sdim // -fno-delayed-template-parsing is default, except for Windows where MSVC STL 3338226633Sdim // needs it. 3339221345Sdim if (Args.hasFlag(options::OPT_fdelayed_template_parsing, 3340221345Sdim options::OPT_fno_delayed_template_parsing, 3341226633Sdim getToolChain().getTriple().getOS() == llvm::Triple::Win32)) 3342221345Sdim CmdArgs.push_back("-fdelayed-template-parsing"); 3343221345Sdim 3344207619Srdivacky // -fgnu-keywords default varies depending on language; only pass if 3345207619Srdivacky // specified. 3346207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, 3347207619Srdivacky options::OPT_fno_gnu_keywords)) 3348207619Srdivacky A->render(Args, CmdArgs); 3349207619Srdivacky 3350223017Sdim if (Args.hasFlag(options::OPT_fgnu89_inline, 3351223017Sdim options::OPT_fno_gnu89_inline, 3352223017Sdim false)) 3353223017Sdim CmdArgs.push_back("-fgnu89-inline"); 3354223017Sdim 3355234353Sdim if (Args.hasArg(options::OPT_fno_inline)) 3356234353Sdim CmdArgs.push_back("-fno-inline"); 3357234353Sdim 3358234353Sdim if (Args.hasArg(options::OPT_fno_inline_functions)) 3359234353Sdim CmdArgs.push_back("-fno-inline-functions"); 3360234353Sdim 3361239462Sdim ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind); 3362224145Sdim 3363239462Sdim // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and 3364263508Sdim // legacy is the default. Next runtime is always legacy dispatch and 3365263508Sdim // -fno-objc-legacy-dispatch gets ignored silently. 3366263508Sdim if (objcRuntime.isNonFragile() && !objcRuntime.isNeXTFamily()) { 3367226633Sdim if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch, 3368226633Sdim options::OPT_fno_objc_legacy_dispatch, 3369239462Sdim objcRuntime.isLegacyDispatchDefaultForArch( 3370263508Sdim getToolChain().getArch()))) { 3371226633Sdim if (getToolChain().UseObjCMixedDispatch()) 3372226633Sdim CmdArgs.push_back("-fobjc-dispatch-method=mixed"); 3373226633Sdim else 3374226633Sdim CmdArgs.push_back("-fobjc-dispatch-method=non-legacy"); 3375218893Sdim } 3376199482Srdivacky } 3377199482Srdivacky 3378263508Sdim // When ObjectiveC legacy runtime is in effect on MacOSX, 3379263508Sdim // turn on the option to do Array/Dictionary subscripting 3380263508Sdim // by default. 3381263508Sdim if (getToolChain().getTriple().getArch() == llvm::Triple::x86 && 3382263508Sdim getToolChain().getTriple().isMacOSX() && 3383263508Sdim !getToolChain().getTriple().isMacOSXVersionLT(10, 7) && 3384263508Sdim objcRuntime.getKind() == ObjCRuntime::FragileMacOSX && 3385263508Sdim objcRuntime.isNeXTFamily()) 3386263508Sdim CmdArgs.push_back("-fobjc-subscripting-legacy-runtime"); 3387263508Sdim 3388243830Sdim // -fencode-extended-block-signature=1 is default. 3389243830Sdim if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) { 3390243830Sdim CmdArgs.push_back("-fencode-extended-block-signature"); 3391243830Sdim } 3392243830Sdim 3393224145Sdim // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc. 3394224145Sdim // NOTE: This logic is duplicated in ToolChains.cpp. 3395224145Sdim bool ARC = isObjCAutoRefCount(Args); 3396224145Sdim if (ARC) { 3397243830Sdim getToolChain().CheckObjCARC(); 3398234353Sdim 3399224145Sdim CmdArgs.push_back("-fobjc-arc"); 3400224145Sdim 3401228379Sdim // FIXME: It seems like this entire block, and several around it should be 3402228379Sdim // wrapped in isObjC, but for now we just use it here as this is where it 3403228379Sdim // was being used previously. 3404228379Sdim if (types::isCXX(InputType) && types::isObjC(InputType)) { 3405228379Sdim if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) 3406228379Sdim CmdArgs.push_back("-fobjc-arc-cxxlib=libc++"); 3407228379Sdim else 3408228379Sdim CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++"); 3409228379Sdim } 3410228379Sdim 3411224145Sdim // Allow the user to enable full exceptions code emission. 3412224145Sdim // We define off for Objective-CC, on for Objective-C++. 3413224145Sdim if (Args.hasFlag(options::OPT_fobjc_arc_exceptions, 3414224145Sdim options::OPT_fno_objc_arc_exceptions, 3415224145Sdim /*default*/ types::isCXX(InputType))) 3416224145Sdim CmdArgs.push_back("-fobjc-arc-exceptions"); 3417224145Sdim } 3418224145Sdim 3419224145Sdim // -fobjc-infer-related-result-type is the default, except in the Objective-C 3420224145Sdim // rewriter. 3421239462Sdim if (rewriteKind != RK_None) 3422224145Sdim CmdArgs.push_back("-fno-objc-infer-related-result-type"); 3423226633Sdim 3424224145Sdim // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only 3425224145Sdim // takes precedence. 3426224145Sdim const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only); 3427224145Sdim if (!GCArg) 3428224145Sdim GCArg = Args.getLastArg(options::OPT_fobjc_gc); 3429224145Sdim if (GCArg) { 3430224145Sdim if (ARC) { 3431226633Sdim D.Diag(diag::err_drv_objc_gc_arr) 3432224145Sdim << GCArg->getAsString(Args); 3433224145Sdim } else if (getToolChain().SupportsObjCGC()) { 3434224145Sdim GCArg->render(Args, CmdArgs); 3435224145Sdim } else { 3436224145Sdim // FIXME: We should move this to a hard error. 3437226633Sdim D.Diag(diag::warn_drv_objc_gc_unsupported) 3438224145Sdim << GCArg->getAsString(Args); 3439224145Sdim } 3440224145Sdim } 3441224145Sdim 3442224145Sdim // Add exception args. 3443224145Sdim addExceptionArgs(Args, InputType, getToolChain().getTriple(), 3444239462Sdim KernelOrKext, objcRuntime, CmdArgs); 3445224145Sdim 3446224145Sdim if (getToolChain().UseSjLjExceptions()) 3447224145Sdim CmdArgs.push_back("-fsjlj-exceptions"); 3448224145Sdim 3449224145Sdim // C++ "sane" operator new. 3450203955Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 3451203955Srdivacky options::OPT_fno_assume_sane_operator_new)) 3452203955Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 3453203955Srdivacky 3454207619Srdivacky // -fconstant-cfstrings is default, and may be subject to argument translation 3455207619Srdivacky // on Darwin. 3456207619Srdivacky if (!Args.hasFlag(options::OPT_fconstant_cfstrings, 3457207619Srdivacky options::OPT_fno_constant_cfstrings) || 3458207619Srdivacky !Args.hasFlag(options::OPT_mconstant_cfstrings, 3459207619Srdivacky options::OPT_mno_constant_cfstrings)) 3460207619Srdivacky CmdArgs.push_back("-fno-constant-cfstrings"); 3461207619Srdivacky 3462199482Srdivacky // -fshort-wchar default varies depending on platform; only 3463193576Sed // pass if specified. 3464207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) 3465207619Srdivacky A->render(Args, CmdArgs); 3466193576Sed 3467263508Sdim // -fno-pascal-strings is default, only pass non-default. 3468193326Sed if (Args.hasFlag(options::OPT_fpascal_strings, 3469193326Sed options::OPT_fno_pascal_strings, 3470193326Sed false)) 3471193326Sed CmdArgs.push_back("-fpascal-strings"); 3472193326Sed 3473226633Sdim // Honor -fpack-struct= and -fpack-struct, if given. Note that 3474226633Sdim // -fno-pack-struct doesn't apply to -fpack-struct=. 3475226633Sdim if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) { 3476239462Sdim std::string PackStructStr = "-fpack-struct="; 3477243830Sdim PackStructStr += A->getValue(); 3478239462Sdim CmdArgs.push_back(Args.MakeArgString(PackStructStr)); 3479226633Sdim } else if (Args.hasFlag(options::OPT_fpack_struct, 3480226633Sdim options::OPT_fno_pack_struct, false)) { 3481239462Sdim CmdArgs.push_back("-fpack-struct=1"); 3482226633Sdim } 3483226633Sdim 3484263508Sdim if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) { 3485218893Sdim if (!Args.hasArg(options::OPT_fcommon)) 3486218893Sdim CmdArgs.push_back("-fno-common"); 3487234353Sdim Args.ClaimAllArgs(options::OPT_fno_common); 3488218893Sdim } 3489226633Sdim 3490193326Sed // -fcommon is default, only pass non-default. 3491218893Sdim else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common)) 3492193326Sed CmdArgs.push_back("-fno-common"); 3493193326Sed 3494193326Sed // -fsigned-bitfields is default, and clang doesn't yet support 3495218893Sdim // -funsigned-bitfields. 3496198092Srdivacky if (!Args.hasFlag(options::OPT_fsigned_bitfields, 3497193326Sed options::OPT_funsigned_bitfields)) 3498226633Sdim D.Diag(diag::warn_drv_clang_unsupported) 3499193326Sed << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args); 3500193326Sed 3501218893Sdim // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope. 3502218893Sdim if (!Args.hasFlag(options::OPT_ffor_scope, 3503218893Sdim options::OPT_fno_for_scope)) 3504226633Sdim D.Diag(diag::err_drv_clang_unsupported) 3505218893Sdim << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args); 3506218893Sdim 3507210299Sed // -fcaret-diagnostics is default. 3508210299Sed if (!Args.hasFlag(options::OPT_fcaret_diagnostics, 3509210299Sed options::OPT_fno_caret_diagnostics, true)) 3510210299Sed CmdArgs.push_back("-fno-caret-diagnostics"); 3511210299Sed 3512193326Sed // -fdiagnostics-fixit-info is default, only pass non-default. 3513198092Srdivacky if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info, 3514193326Sed options::OPT_fno_diagnostics_fixit_info)) 3515193326Sed CmdArgs.push_back("-fno-diagnostics-fixit-info"); 3516226633Sdim 3517193326Sed // Enable -fdiagnostics-show-option by default. 3518198092Srdivacky if (Args.hasFlag(options::OPT_fdiagnostics_show_option, 3519193326Sed options::OPT_fno_diagnostics_show_option)) 3520193326Sed CmdArgs.push_back("-fdiagnostics-show-option"); 3521198893Srdivacky 3522208600Srdivacky if (const Arg *A = 3523208600Srdivacky Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { 3524208600Srdivacky CmdArgs.push_back("-fdiagnostics-show-category"); 3525243830Sdim CmdArgs.push_back(A->getValue()); 3526208600Srdivacky } 3527212904Sdim 3528223017Sdim if (const Arg *A = 3529223017Sdim Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { 3530223017Sdim CmdArgs.push_back("-fdiagnostics-format"); 3531243830Sdim CmdArgs.push_back(A->getValue()); 3532223017Sdim } 3533223017Sdim 3534221345Sdim if (Arg *A = Args.getLastArg( 3535221345Sdim options::OPT_fdiagnostics_show_note_include_stack, 3536221345Sdim options::OPT_fno_diagnostics_show_note_include_stack)) { 3537221345Sdim if (A->getOption().matches( 3538221345Sdim options::OPT_fdiagnostics_show_note_include_stack)) 3539221345Sdim CmdArgs.push_back("-fdiagnostics-show-note-include-stack"); 3540221345Sdim else 3541221345Sdim CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); 3542221345Sdim } 3543221345Sdim 3544198893Srdivacky // Color diagnostics are the default, unless the terminal doesn't support 3545198893Srdivacky // them. 3546251662Sdim // Support both clang's -f[no-]color-diagnostics and gcc's 3547251662Sdim // -f[no-]diagnostics-colors[=never|always|auto]. 3548251662Sdim enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto; 3549251662Sdim for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 3550251662Sdim it != ie; ++it) { 3551251662Sdim const Option &O = (*it)->getOption(); 3552251662Sdim if (!O.matches(options::OPT_fcolor_diagnostics) && 3553251662Sdim !O.matches(options::OPT_fdiagnostics_color) && 3554251662Sdim !O.matches(options::OPT_fno_color_diagnostics) && 3555251662Sdim !O.matches(options::OPT_fno_diagnostics_color) && 3556251662Sdim !O.matches(options::OPT_fdiagnostics_color_EQ)) 3557251662Sdim continue; 3558251662Sdim 3559251662Sdim (*it)->claim(); 3560251662Sdim if (O.matches(options::OPT_fcolor_diagnostics) || 3561251662Sdim O.matches(options::OPT_fdiagnostics_color)) { 3562251662Sdim ShowColors = Colors_On; 3563251662Sdim } else if (O.matches(options::OPT_fno_color_diagnostics) || 3564251662Sdim O.matches(options::OPT_fno_diagnostics_color)) { 3565251662Sdim ShowColors = Colors_Off; 3566251662Sdim } else { 3567251662Sdim assert(O.matches(options::OPT_fdiagnostics_color_EQ)); 3568251662Sdim StringRef value((*it)->getValue()); 3569251662Sdim if (value == "always") 3570251662Sdim ShowColors = Colors_On; 3571251662Sdim else if (value == "never") 3572251662Sdim ShowColors = Colors_Off; 3573251662Sdim else if (value == "auto") 3574251662Sdim ShowColors = Colors_Auto; 3575251662Sdim else 3576251662Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3577251662Sdim << ("-fdiagnostics-color=" + value).str(); 3578251662Sdim } 3579251662Sdim } 3580251662Sdim if (ShowColors == Colors_On || 3581251662Sdim (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) 3582198893Srdivacky CmdArgs.push_back("-fcolor-diagnostics"); 3583198893Srdivacky 3584263508Sdim if (Args.hasArg(options::OPT_fansi_escape_codes)) 3585263508Sdim CmdArgs.push_back("-fansi-escape-codes"); 3586263508Sdim 3587194179Sed if (!Args.hasFlag(options::OPT_fshow_source_location, 3588194179Sed options::OPT_fno_show_source_location)) 3589194179Sed CmdArgs.push_back("-fno-show-source-location"); 3590193326Sed 3591223017Sdim if (!Args.hasFlag(options::OPT_fshow_column, 3592223017Sdim options::OPT_fno_show_column, 3593223017Sdim true)) 3594223017Sdim CmdArgs.push_back("-fno-show-column"); 3595223017Sdim 3596210299Sed if (!Args.hasFlag(options::OPT_fspell_checking, 3597210299Sed options::OPT_fno_spell_checking)) 3598210299Sed CmdArgs.push_back("-fno-spell-checking"); 3599212904Sdim 3600218893Sdim 3601249423Sdim // -fno-asm-blocks is default. 3602249423Sdim if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks, 3603249423Sdim false)) 3604249423Sdim CmdArgs.push_back("-fasm-blocks"); 3605218893Sdim 3606263508Sdim // Enable vectorization per default according to the optimization level 3607263508Sdim // selected. For optimization levels that want vectorization we use the alias 3608263508Sdim // option to simplify the hasFlag logic. 3609263508Sdim bool EnableVec = shouldEnableVectorizerAtOLevel(Args); 3610263508Sdim OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group : 3611251662Sdim options::OPT_fvectorize; 3612251662Sdim if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption, 3613263508Sdim options::OPT_fno_vectorize, EnableVec)) 3614249423Sdim CmdArgs.push_back("-vectorize-loops"); 3615249423Sdim 3616263508Sdim // -fslp-vectorize is default. 3617249423Sdim if (Args.hasFlag(options::OPT_fslp_vectorize, 3618263508Sdim options::OPT_fno_slp_vectorize, true)) 3619251662Sdim CmdArgs.push_back("-vectorize-slp"); 3620249423Sdim 3621251662Sdim // -fno-slp-vectorize-aggressive is default. 3622251662Sdim if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive, 3623263508Sdim options::OPT_fno_slp_vectorize_aggressive, false)) 3624251662Sdim CmdArgs.push_back("-vectorize-slp-aggressive"); 3625251662Sdim 3626210299Sed if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ)) 3627210299Sed A->render(Args, CmdArgs); 3628210299Sed 3629193326Sed // -fdollars-in-identifiers default varies depending on platform and 3630193326Sed // language; only pass if specified. 3631198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers, 3632193326Sed options::OPT_fno_dollars_in_identifiers)) { 3633193326Sed if (A->getOption().matches(options::OPT_fdollars_in_identifiers)) 3634201361Srdivacky CmdArgs.push_back("-fdollars-in-identifiers"); 3635193326Sed else 3636201361Srdivacky CmdArgs.push_back("-fno-dollars-in-identifiers"); 3637193326Sed } 3638193326Sed 3639193326Sed // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for 3640193326Sed // practical purposes. 3641198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time, 3642193326Sed options::OPT_fno_unit_at_a_time)) { 3643193326Sed if (A->getOption().matches(options::OPT_fno_unit_at_a_time)) 3644226633Sdim D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); 3645193326Sed } 3646198092Srdivacky 3647234353Sdim if (Args.hasFlag(options::OPT_fapple_pragma_pack, 3648234353Sdim options::OPT_fno_apple_pragma_pack, false)) 3649234353Sdim CmdArgs.push_back("-fapple-pragma-pack"); 3650234353Sdim 3651263508Sdim // le32-specific flags: 3652263508Sdim // -fno-math-builtin: clang should not convert math builtins to intrinsics 3653263508Sdim // by default. 3654263508Sdim if (getToolChain().getArch() == llvm::Triple::le32) { 3655263508Sdim CmdArgs.push_back("-fno-math-builtin"); 3656263508Sdim } 3657263508Sdim 3658198092Srdivacky // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM. 3659198092Srdivacky // 3660200583Srdivacky // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941. 3661198092Srdivacky#if 0 3662226633Sdim if (getToolChain().getTriple().isOSDarwin() && 3663263508Sdim (getToolChain().getArch() == llvm::Triple::arm || 3664263508Sdim getToolChain().getArch() == llvm::Triple::thumb)) { 3665198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcat)) 3666198092Srdivacky CmdArgs.push_back("-fno-builtin-strcat"); 3667198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcpy)) 3668198092Srdivacky CmdArgs.push_back("-fno-builtin-strcpy"); 3669198092Srdivacky } 3670198092Srdivacky#endif 3671198092Srdivacky 3672221345Sdim // Only allow -traditional or -traditional-cpp outside in preprocessing modes. 3673198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_traditional, 3674221345Sdim options::OPT_traditional_cpp)) { 3675221345Sdim if (isa<PreprocessJobAction>(JA)) 3676221345Sdim CmdArgs.push_back("-traditional-cpp"); 3677226633Sdim else 3678226633Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 3679221345Sdim } 3680198092Srdivacky 3681193326Sed Args.AddLastArg(CmdArgs, options::OPT_dM); 3682193326Sed Args.AddLastArg(CmdArgs, options::OPT_dD); 3683234353Sdim 3684234353Sdim // Handle serialized diagnostics. 3685234353Sdim if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) { 3686234353Sdim CmdArgs.push_back("-serialize-diagnostic-file"); 3687243830Sdim CmdArgs.push_back(Args.MakeArgString(A->getValue())); 3688234353Sdim } 3689193326Sed 3690243830Sdim if (Args.hasArg(options::OPT_fretain_comments_from_system_headers)) 3691243830Sdim CmdArgs.push_back("-fretain-comments-from-system-headers"); 3692243830Sdim 3693249423Sdim // Forward -fcomment-block-commands to -cc1. 3694249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); 3695251662Sdim // Forward -fparse-all-comments to -cc1. 3696251662Sdim Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments); 3697249423Sdim 3698207619Srdivacky // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option 3699207619Srdivacky // parser. 3700193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xclang); 3701207619Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm), 3702207619Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 3703210299Sed (*it)->claim(); 3704193326Sed 3705207619Srdivacky // We translate this by hand to the -cc1 argument, since nightly test uses 3706207619Srdivacky // it and developers have been trained to spell it with -mllvm. 3707243830Sdim if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns") 3708207619Srdivacky CmdArgs.push_back("-disable-llvm-optzns"); 3709207619Srdivacky else 3710210299Sed (*it)->render(Args, CmdArgs); 3711207619Srdivacky } 3712207619Srdivacky 3713193326Sed if (Output.getType() == types::TY_Dependencies) { 3714193326Sed // Handled with other dependency code. 3715193326Sed } else if (Output.isFilename()) { 3716193326Sed CmdArgs.push_back("-o"); 3717193326Sed CmdArgs.push_back(Output.getFilename()); 3718193326Sed } else { 3719193326Sed assert(Output.isNothing() && "Invalid output."); 3720193326Sed } 3721193326Sed 3722193326Sed for (InputInfoList::const_iterator 3723193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 3724193326Sed const InputInfo &II = *it; 3725193326Sed CmdArgs.push_back("-x"); 3726243830Sdim if (Args.hasArg(options::OPT_rewrite_objc)) 3727243830Sdim CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX)); 3728243830Sdim else 3729243830Sdim CmdArgs.push_back(types::getTypeName(II.getType())); 3730212904Sdim if (II.isFilename()) 3731193326Sed CmdArgs.push_back(II.getFilename()); 3732193326Sed else 3733193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 3734193326Sed } 3735193326Sed 3736198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_undef); 3737198893Srdivacky 3738212904Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 3739201361Srdivacky 3740201361Srdivacky // Optionally embed the -cc1 level arguments into the debug info, for build 3741201361Srdivacky // analysis. 3742201361Srdivacky if (getToolChain().UseDwarfDebugFlags()) { 3743210299Sed ArgStringList OriginalArgs; 3744210299Sed for (ArgList::const_iterator it = Args.begin(), 3745210299Sed ie = Args.end(); it != ie; ++it) 3746210299Sed (*it)->render(Args, OriginalArgs); 3747212904Sdim 3748234353Sdim SmallString<256> Flags; 3749201361Srdivacky Flags += Exec; 3750210299Sed for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { 3751201361Srdivacky Flags += " "; 3752210299Sed Flags += OriginalArgs[i]; 3753201361Srdivacky } 3754201361Srdivacky CmdArgs.push_back("-dwarf-debug-flags"); 3755201361Srdivacky CmdArgs.push_back(Args.MakeArgString(Flags.str())); 3756201361Srdivacky } 3757201361Srdivacky 3758249423Sdim // Add the split debug info name to the command lines here so we 3759249423Sdim // can propagate it to the backend. 3760249423Sdim bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) && 3761263508Sdim getToolChain().getTriple().isOSLinux() && 3762249423Sdim (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA)); 3763249423Sdim const char *SplitDwarfOut; 3764249423Sdim if (SplitDwarf) { 3765249423Sdim CmdArgs.push_back("-split-dwarf-file"); 3766249423Sdim SplitDwarfOut = SplitDebugName(Args, Inputs); 3767249423Sdim CmdArgs.push_back(SplitDwarfOut); 3768249423Sdim } 3769249423Sdim 3770249423Sdim // Finally add the compile command to the compilation. 3771263508Sdim if (Args.hasArg(options::OPT__SLASH_fallback)) { 3772263508Sdim tools::visualstudio::Compile CL(getToolChain()); 3773263508Sdim Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args, 3774263508Sdim LinkingOutput); 3775263508Sdim C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand)); 3776263508Sdim } else { 3777263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 3778263508Sdim } 3779193326Sed 3780263508Sdim 3781249423Sdim // Handle the debug info splitting at object creation time if we're 3782249423Sdim // creating an object. 3783249423Sdim // TODO: Currently only works on linux with newer objcopy. 3784249423Sdim if (SplitDwarf && !isa<CompileJobAction>(JA)) 3785249423Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut); 3786249423Sdim 3787218893Sdim if (Arg *A = Args.getLastArg(options::OPT_pg)) 3788218893Sdim if (Args.hasArg(options::OPT_fomit_frame_pointer)) 3789226633Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 3790218893Sdim << "-fomit-frame-pointer" << A->getAsString(Args); 3791193326Sed 3792193326Sed // Claim some arguments which clang supports automatically. 3793193326Sed 3794207619Srdivacky // -fpch-preprocess is used with gcc to add a special marker in the output to 3795207619Srdivacky // include the PCH file. Clang's PTH solution is completely transparent, so we 3796207619Srdivacky // do not need to deal with it at all. 3797193326Sed Args.ClaimAllArgs(options::OPT_fpch_preprocess); 3798193326Sed 3799193326Sed // Claim some arguments which clang doesn't support, but we don't 3800193326Sed // care to warn the user about. 3801199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group); 3802199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group); 3803221345Sdim 3804263508Sdim // Disable warnings for clang -E -emit-llvm foo.c 3805221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 3806193326Sed} 3807193326Sed 3808239462Sdim/// Add options related to the Objective-C runtime/ABI. 3809239462Sdim/// 3810239462Sdim/// Returns true if the runtime is non-fragile. 3811239462SdimObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, 3812239462Sdim ArgStringList &cmdArgs, 3813239462Sdim RewriteKind rewriteKind) const { 3814239462Sdim // Look for the controlling runtime option. 3815239462Sdim Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime, 3816239462Sdim options::OPT_fgnu_runtime, 3817239462Sdim options::OPT_fobjc_runtime_EQ); 3818239462Sdim 3819239462Sdim // Just forward -fobjc-runtime= to the frontend. This supercedes 3820239462Sdim // options about fragility. 3821239462Sdim if (runtimeArg && 3822239462Sdim runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) { 3823239462Sdim ObjCRuntime runtime; 3824243830Sdim StringRef value = runtimeArg->getValue(); 3825239462Sdim if (runtime.tryParse(value)) { 3826239462Sdim getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime) 3827239462Sdim << value; 3828239462Sdim } 3829239462Sdim 3830239462Sdim runtimeArg->render(args, cmdArgs); 3831239462Sdim return runtime; 3832239462Sdim } 3833239462Sdim 3834239462Sdim // Otherwise, we'll need the ABI "version". Version numbers are 3835239462Sdim // slightly confusing for historical reasons: 3836239462Sdim // 1 - Traditional "fragile" ABI 3837239462Sdim // 2 - Non-fragile ABI, version 1 3838239462Sdim // 3 - Non-fragile ABI, version 2 3839239462Sdim unsigned objcABIVersion = 1; 3840239462Sdim // If -fobjc-abi-version= is present, use that to set the version. 3841239462Sdim if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) { 3842243830Sdim StringRef value = abiArg->getValue(); 3843239462Sdim if (value == "1") 3844239462Sdim objcABIVersion = 1; 3845239462Sdim else if (value == "2") 3846239462Sdim objcABIVersion = 2; 3847239462Sdim else if (value == "3") 3848239462Sdim objcABIVersion = 3; 3849239462Sdim else 3850239462Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3851239462Sdim << value; 3852239462Sdim } else { 3853239462Sdim // Otherwise, determine if we are using the non-fragile ABI. 3854239462Sdim bool nonFragileABIIsDefault = 3855239462Sdim (rewriteKind == RK_NonFragile || 3856239462Sdim (rewriteKind == RK_None && 3857239462Sdim getToolChain().IsObjCNonFragileABIDefault())); 3858239462Sdim if (args.hasFlag(options::OPT_fobjc_nonfragile_abi, 3859239462Sdim options::OPT_fno_objc_nonfragile_abi, 3860239462Sdim nonFragileABIIsDefault)) { 3861239462Sdim // Determine the non-fragile ABI version to use. 3862239462Sdim#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO 3863239462Sdim unsigned nonFragileABIVersion = 1; 3864239462Sdim#else 3865239462Sdim unsigned nonFragileABIVersion = 2; 3866239462Sdim#endif 3867239462Sdim 3868239462Sdim if (Arg *abiArg = args.getLastArg( 3869239462Sdim options::OPT_fobjc_nonfragile_abi_version_EQ)) { 3870243830Sdim StringRef value = abiArg->getValue(); 3871239462Sdim if (value == "1") 3872239462Sdim nonFragileABIVersion = 1; 3873239462Sdim else if (value == "2") 3874239462Sdim nonFragileABIVersion = 2; 3875239462Sdim else 3876239462Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3877239462Sdim << value; 3878239462Sdim } 3879239462Sdim 3880239462Sdim objcABIVersion = 1 + nonFragileABIVersion; 3881239462Sdim } else { 3882239462Sdim objcABIVersion = 1; 3883239462Sdim } 3884239462Sdim } 3885239462Sdim 3886239462Sdim // We don't actually care about the ABI version other than whether 3887239462Sdim // it's non-fragile. 3888239462Sdim bool isNonFragile = objcABIVersion != 1; 3889239462Sdim 3890239462Sdim // If we have no runtime argument, ask the toolchain for its default runtime. 3891239462Sdim // However, the rewriter only really supports the Mac runtime, so assume that. 3892239462Sdim ObjCRuntime runtime; 3893239462Sdim if (!runtimeArg) { 3894239462Sdim switch (rewriteKind) { 3895239462Sdim case RK_None: 3896239462Sdim runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); 3897239462Sdim break; 3898239462Sdim case RK_Fragile: 3899239462Sdim runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple()); 3900239462Sdim break; 3901239462Sdim case RK_NonFragile: 3902239462Sdim runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple()); 3903239462Sdim break; 3904239462Sdim } 3905239462Sdim 3906239462Sdim // -fnext-runtime 3907239462Sdim } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) { 3908239462Sdim // On Darwin, make this use the default behavior for the toolchain. 3909239462Sdim if (getToolChain().getTriple().isOSDarwin()) { 3910239462Sdim runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); 3911239462Sdim 3912239462Sdim // Otherwise, build for a generic macosx port. 3913239462Sdim } else { 3914239462Sdim runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple()); 3915239462Sdim } 3916239462Sdim 3917239462Sdim // -fgnu-runtime 3918239462Sdim } else { 3919239462Sdim assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime)); 3920239462Sdim // Legacy behaviour is to target the gnustep runtime if we are i 3921239462Sdim // non-fragile mode or the GCC runtime in fragile mode. 3922239462Sdim if (isNonFragile) 3923243830Sdim runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6)); 3924239462Sdim else 3925239462Sdim runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple()); 3926239462Sdim } 3927239462Sdim 3928239462Sdim cmdArgs.push_back(args.MakeArgString( 3929239462Sdim "-fobjc-runtime=" + runtime.getAsString())); 3930239462Sdim return runtime; 3931239462Sdim} 3932239462Sdim 3933263508Sdimvoid Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const { 3934263508Sdim unsigned RTOptionID = options::OPT__SLASH_MT; 3935263508Sdim 3936263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3937263508Sdim // The /LDd option implies /MTd. The dependent lib part can be overridden, 3938263508Sdim // but defining _DEBUG is sticky. 3939263508Sdim RTOptionID = options::OPT__SLASH_MTd; 3940263508Sdim 3941263508Sdim if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) 3942263508Sdim RTOptionID = A->getOption().getID(); 3943263508Sdim 3944263508Sdim switch(RTOptionID) { 3945263508Sdim case options::OPT__SLASH_MD: 3946263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3947263508Sdim CmdArgs.push_back("-D_DEBUG"); 3948263508Sdim CmdArgs.push_back("-D_MT"); 3949263508Sdim CmdArgs.push_back("-D_DLL"); 3950263508Sdim CmdArgs.push_back("--dependent-lib=msvcrt"); 3951263508Sdim break; 3952263508Sdim case options::OPT__SLASH_MDd: 3953263508Sdim CmdArgs.push_back("-D_DEBUG"); 3954263508Sdim CmdArgs.push_back("-D_MT"); 3955263508Sdim CmdArgs.push_back("-D_DLL"); 3956263508Sdim CmdArgs.push_back("--dependent-lib=msvcrtd"); 3957263508Sdim break; 3958263508Sdim case options::OPT__SLASH_MT: 3959263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3960263508Sdim CmdArgs.push_back("-D_DEBUG"); 3961263508Sdim CmdArgs.push_back("-D_MT"); 3962263508Sdim CmdArgs.push_back("--dependent-lib=libcmt"); 3963263508Sdim break; 3964263508Sdim case options::OPT__SLASH_MTd: 3965263508Sdim CmdArgs.push_back("-D_DEBUG"); 3966263508Sdim CmdArgs.push_back("-D_MT"); 3967263508Sdim CmdArgs.push_back("--dependent-lib=libcmtd"); 3968263508Sdim break; 3969263508Sdim default: 3970263508Sdim llvm_unreachable("Unexpected option ID."); 3971263508Sdim } 3972263508Sdim 3973263508Sdim // This provides POSIX compatibility (maps 'open' to '_open'), which most 3974263508Sdim // users want. The /Za flag to cl.exe turns this off, but it's not 3975263508Sdim // implemented in clang. 3976263508Sdim CmdArgs.push_back("--dependent-lib=oldnames"); 3977263508Sdim 3978263508Sdim // FIXME: Make this default for the win32 triple. 3979263508Sdim CmdArgs.push_back("-cxx-abi"); 3980263508Sdim CmdArgs.push_back("microsoft"); 3981263508Sdim 3982263508Sdim if (Arg *A = Args.getLastArg(options::OPT_show_includes)) 3983263508Sdim A->render(Args, CmdArgs); 3984263508Sdim 3985263508Sdim if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) { 3986263508Sdim CmdArgs.push_back("-fdiagnostics-format"); 3987263508Sdim if (Args.hasArg(options::OPT__SLASH_fallback)) 3988263508Sdim CmdArgs.push_back("msvc-fallback"); 3989263508Sdim else 3990263508Sdim CmdArgs.push_back("msvc"); 3991263508Sdim } 3992263508Sdim} 3993263508Sdim 3994208600Srdivackyvoid ClangAs::ConstructJob(Compilation &C, const JobAction &JA, 3995208600Srdivacky const InputInfo &Output, 3996208600Srdivacky const InputInfoList &Inputs, 3997208600Srdivacky const ArgList &Args, 3998208600Srdivacky const char *LinkingOutput) const { 3999208600Srdivacky ArgStringList CmdArgs; 4000208600Srdivacky 4001208600Srdivacky assert(Inputs.size() == 1 && "Unexpected number of inputs."); 4002208600Srdivacky const InputInfo &Input = Inputs[0]; 4003208600Srdivacky 4004218893Sdim // Don't warn about "clang -w -c foo.s" 4005218893Sdim Args.ClaimAllArgs(options::OPT_w); 4006221345Sdim // and "clang -emit-llvm -c foo.s" 4007221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 4008218893Sdim 4009208600Srdivacky // Invoke ourselves in -cc1as mode. 4010208600Srdivacky // 4011208600Srdivacky // FIXME: Implement custom jobs for internal actions. 4012208600Srdivacky CmdArgs.push_back("-cc1as"); 4013208600Srdivacky 4014208600Srdivacky // Add the "effective" target triple. 4015208600Srdivacky CmdArgs.push_back("-triple"); 4016226633Sdim std::string TripleStr = 4017226633Sdim getToolChain().ComputeEffectiveClangTriple(Args, Input.getType()); 4018208600Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 4019208600Srdivacky 4020208600Srdivacky // Set the output mode, we currently only expect to be used as a real 4021208600Srdivacky // assembler. 4022208600Srdivacky CmdArgs.push_back("-filetype"); 4023208600Srdivacky CmdArgs.push_back("obj"); 4024208600Srdivacky 4025249423Sdim // Set the main file name, so that debug info works even with 4026249423Sdim // -save-temps or preprocessed assembly. 4027249423Sdim CmdArgs.push_back("-main-file-name"); 4028249423Sdim CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs)); 4029249423Sdim 4030263508Sdim // Add the target cpu 4031263508Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 4032263508Sdim std::string CPU = getCPUName(Args, Triple); 4033263508Sdim if (!CPU.empty()) { 4034263508Sdim CmdArgs.push_back("-target-cpu"); 4035263508Sdim CmdArgs.push_back(Args.MakeArgString(CPU)); 4036263508Sdim } 4037208600Srdivacky 4038263508Sdim // Add the target features 4039263508Sdim const Driver &D = getToolChain().getDriver(); 4040263508Sdim getTargetFeatures(D, Triple, Args, CmdArgs); 4041234353Sdim 4042221345Sdim // Ignore explicit -force_cpusubtype_ALL option. 4043221345Sdim (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); 4044208600Srdivacky 4045234353Sdim // Determine the original source input. 4046234353Sdim const Action *SourceAction = &JA; 4047234353Sdim while (SourceAction->getKind() != Action::InputClass) { 4048234353Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 4049234353Sdim SourceAction = SourceAction->getInputs()[0]; 4050234353Sdim } 4051208600Srdivacky 4052249423Sdim // Forward -g and handle debug info related flags, assuming we are dealing 4053249423Sdim // with an actual assembly file. 4054234353Sdim if (SourceAction->getType() == types::TY_Asm || 4055234353Sdim SourceAction->getType() == types::TY_PP_Asm) { 4056234353Sdim Args.ClaimAllArgs(options::OPT_g_Group); 4057234353Sdim if (Arg *A = Args.getLastArg(options::OPT_g_Group)) 4058234353Sdim if (!A->getOption().matches(options::OPT_g0)) 4059234353Sdim CmdArgs.push_back("-g"); 4060249423Sdim 4061249423Sdim // Add the -fdebug-compilation-dir flag if needed. 4062249423Sdim addDebugCompDirArg(Args, CmdArgs); 4063249423Sdim 4064249423Sdim // Set the AT_producer to the clang version when using the integrated 4065249423Sdim // assembler on assembly source files. 4066249423Sdim CmdArgs.push_back("-dwarf-debug-producer"); 4067249423Sdim CmdArgs.push_back(Args.MakeArgString(getClangFullVersion())); 4068234353Sdim } 4069234353Sdim 4070234353Sdim // Optionally embed the -cc1as level arguments into the debug info, for build 4071234353Sdim // analysis. 4072234353Sdim if (getToolChain().UseDwarfDebugFlags()) { 4073234353Sdim ArgStringList OriginalArgs; 4074234353Sdim for (ArgList::const_iterator it = Args.begin(), 4075234353Sdim ie = Args.end(); it != ie; ++it) 4076234353Sdim (*it)->render(Args, OriginalArgs); 4077234353Sdim 4078234353Sdim SmallString<256> Flags; 4079234353Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 4080234353Sdim Flags += Exec; 4081234353Sdim for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { 4082234353Sdim Flags += " "; 4083234353Sdim Flags += OriginalArgs[i]; 4084234353Sdim } 4085234353Sdim CmdArgs.push_back("-dwarf-debug-flags"); 4086234353Sdim CmdArgs.push_back(Args.MakeArgString(Flags.str())); 4087234353Sdim } 4088234353Sdim 4089208600Srdivacky // FIXME: Add -static support, once we have it. 4090208600Srdivacky 4091263508Sdim CollectArgsForIntegratedAssembler(C, Args, CmdArgs, 4092263508Sdim getToolChain().getDriver()); 4093263508Sdim 4094221345Sdim Args.AddAllArgs(CmdArgs, options::OPT_mllvm); 4095208600Srdivacky 4096208600Srdivacky assert(Output.isFilename() && "Unexpected lipo output."); 4097208600Srdivacky CmdArgs.push_back("-o"); 4098208600Srdivacky CmdArgs.push_back(Output.getFilename()); 4099208600Srdivacky 4100212904Sdim assert(Input.isFilename() && "Invalid input."); 4101212904Sdim CmdArgs.push_back(Input.getFilename()); 4102208600Srdivacky 4103212904Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 4104212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4105251662Sdim 4106251662Sdim // Handle the debug info splitting at object creation time if we're 4107251662Sdim // creating an object. 4108251662Sdim // TODO: Currently only works on linux with newer objcopy. 4109251662Sdim if (Args.hasArg(options::OPT_gsplit_dwarf) && 4110263508Sdim getToolChain().getTriple().isOSLinux()) 4111251662Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, 4112251662Sdim SplitDebugName(Args, Inputs)); 4113208600Srdivacky} 4114208600Srdivacky 4115193326Sedvoid gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, 4116193326Sed const InputInfo &Output, 4117193326Sed const InputInfoList &Inputs, 4118193326Sed const ArgList &Args, 4119193326Sed const char *LinkingOutput) const { 4120201361Srdivacky const Driver &D = getToolChain().getDriver(); 4121193326Sed ArgStringList CmdArgs; 4122193326Sed 4123193326Sed for (ArgList::const_iterator 4124193326Sed it = Args.begin(), ie = Args.end(); it != ie; ++it) { 4125193326Sed Arg *A = *it; 4126243830Sdim if (forwardToGCC(A->getOption())) { 4127212904Sdim // Don't forward any -g arguments to assembly steps. 4128212904Sdim if (isa<AssembleJobAction>(JA) && 4129212904Sdim A->getOption().matches(options::OPT_g_Group)) 4130212904Sdim continue; 4131212904Sdim 4132263508Sdim // Don't forward any -W arguments to assembly and link steps. 4133263508Sdim if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) && 4134263508Sdim A->getOption().matches(options::OPT_W_Group)) 4135263508Sdim continue; 4136263508Sdim 4137193326Sed // It is unfortunate that we have to claim here, as this means 4138193326Sed // we will basically never report anything interesting for 4139193326Sed // platforms using a generic gcc, even if we are just using gcc 4140193326Sed // to get to the assembler. 4141193326Sed A->claim(); 4142193326Sed A->render(Args, CmdArgs); 4143193326Sed } 4144193326Sed } 4145193326Sed 4146203955Srdivacky RenderExtraToolArgs(JA, CmdArgs); 4147193326Sed 4148193326Sed // If using a driver driver, force the arch. 4149243830Sdim llvm::Triple::ArchType Arch = getToolChain().getArch(); 4150226633Sdim if (getToolChain().getTriple().isOSDarwin()) { 4151193326Sed CmdArgs.push_back("-arch"); 4152193326Sed 4153193326Sed // FIXME: Remove these special cases. 4154243830Sdim if (Arch == llvm::Triple::ppc) 4155193326Sed CmdArgs.push_back("ppc"); 4156243830Sdim else if (Arch == llvm::Triple::ppc64) 4157193326Sed CmdArgs.push_back("ppc64"); 4158263508Sdim else if (Arch == llvm::Triple::ppc64le) 4159263508Sdim CmdArgs.push_back("ppc64le"); 4160193326Sed else 4161243830Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName())); 4162193326Sed } 4163193326Sed 4164193326Sed // Try to force gcc to match the tool chain we want, if we recognize 4165193326Sed // the arch. 4166193326Sed // 4167193326Sed // FIXME: The triple class should directly provide the information we want 4168193326Sed // here. 4169243830Sdim if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) 4170193326Sed CmdArgs.push_back("-m32"); 4171263508Sdim else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 || 4172263508Sdim Arch == llvm::Triple::ppc64le) 4173193326Sed CmdArgs.push_back("-m64"); 4174193326Sed 4175212904Sdim if (Output.isFilename()) { 4176193326Sed CmdArgs.push_back("-o"); 4177193326Sed CmdArgs.push_back(Output.getFilename()); 4178193326Sed } else { 4179193326Sed assert(Output.isNothing() && "Unexpected output"); 4180193326Sed CmdArgs.push_back("-fsyntax-only"); 4181193326Sed } 4182193326Sed 4183234353Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4184234353Sdim options::OPT_Xassembler); 4185193326Sed 4186193326Sed // Only pass -x if gcc will understand it; otherwise hope gcc 4187193326Sed // understands the suffix correctly. The main use case this would go 4188193326Sed // wrong in is for linker inputs if they happened to have an odd 4189193326Sed // suffix; really the only way to get this to happen is a command 4190193326Sed // like '-x foobar a.c' which will treat a.c like a linker input. 4191193326Sed // 4192193326Sed // FIXME: For the linker case specifically, can we safely convert 4193193326Sed // inputs into '-Wl,' options? 4194193326Sed for (InputInfoList::const_iterator 4195193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 4196193326Sed const InputInfo &II = *it; 4197193326Sed 4198198092Srdivacky // Don't try to pass LLVM or AST inputs to a generic gcc. 4199210299Sed if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || 4200210299Sed II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) 4201226633Sdim D.Diag(diag::err_drv_no_linker_llvm_support) 4202198092Srdivacky << getToolChain().getTripleString(); 4203198092Srdivacky else if (II.getType() == types::TY_AST) 4204226633Sdim D.Diag(diag::err_drv_no_ast_support) 4205198092Srdivacky << getToolChain().getTripleString(); 4206249423Sdim else if (II.getType() == types::TY_ModuleFile) 4207249423Sdim D.Diag(diag::err_drv_no_module_support) 4208249423Sdim << getToolChain().getTripleString(); 4209193326Sed 4210193326Sed if (types::canTypeBeUserSpecified(II.getType())) { 4211193326Sed CmdArgs.push_back("-x"); 4212193326Sed CmdArgs.push_back(types::getTypeName(II.getType())); 4213193326Sed } 4214193326Sed 4215212904Sdim if (II.isFilename()) 4216193326Sed CmdArgs.push_back(II.getFilename()); 4217218893Sdim else { 4218218893Sdim const Arg &A = II.getInputArg(); 4219218893Sdim 4220218893Sdim // Reverse translate some rewritten options. 4221218893Sdim if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) { 4222218893Sdim CmdArgs.push_back("-lstdc++"); 4223218893Sdim continue; 4224218893Sdim } 4225218893Sdim 4226193326Sed // Don't render as input, we need gcc to do the translations. 4227218893Sdim A.render(Args, CmdArgs); 4228218893Sdim } 4229193326Sed } 4230193326Sed 4231221345Sdim const std::string customGCCName = D.getCCCGenericGCCName(); 4232221345Sdim const char *GCCName; 4233221345Sdim if (!customGCCName.empty()) 4234221345Sdim GCCName = customGCCName.c_str(); 4235263508Sdim else if (D.CCCIsCXX()) { 4236221345Sdim GCCName = "g++"; 4237221345Sdim } else 4238221345Sdim GCCName = "gcc"; 4239221345Sdim 4240193326Sed const char *Exec = 4241210299Sed Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); 4242212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4243193326Sed} 4244193326Sed 4245203955Srdivackyvoid gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA, 4246203955Srdivacky ArgStringList &CmdArgs) const { 4247193326Sed CmdArgs.push_back("-E"); 4248193326Sed} 4249193326Sed 4250203955Srdivackyvoid gcc::Precompile::RenderExtraToolArgs(const JobAction &JA, 4251203955Srdivacky ArgStringList &CmdArgs) const { 4252193326Sed // The type is good enough. 4253193326Sed} 4254193326Sed 4255203955Srdivackyvoid gcc::Compile::RenderExtraToolArgs(const JobAction &JA, 4256203955Srdivacky ArgStringList &CmdArgs) const { 4257203955Srdivacky const Driver &D = getToolChain().getDriver(); 4258203955Srdivacky 4259203955Srdivacky // If -flto, etc. are present then make sure not to force assembly output. 4260210299Sed if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR || 4261210299Sed JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC) 4262203955Srdivacky CmdArgs.push_back("-c"); 4263203955Srdivacky else { 4264203955Srdivacky if (JA.getType() != types::TY_PP_Asm) 4265226633Sdim D.Diag(diag::err_drv_invalid_gcc_output_type) 4266203955Srdivacky << getTypeName(JA.getType()); 4267218893Sdim 4268203955Srdivacky CmdArgs.push_back("-S"); 4269203955Srdivacky } 4270193326Sed} 4271193326Sed 4272203955Srdivackyvoid gcc::Assemble::RenderExtraToolArgs(const JobAction &JA, 4273203955Srdivacky ArgStringList &CmdArgs) const { 4274193326Sed CmdArgs.push_back("-c"); 4275193326Sed} 4276193326Sed 4277203955Srdivackyvoid gcc::Link::RenderExtraToolArgs(const JobAction &JA, 4278203955Srdivacky ArgStringList &CmdArgs) const { 4279193326Sed // The types are (hopefully) good enough. 4280193326Sed} 4281193326Sed 4282234353Sdim// Hexagon tools start. 4283234353Sdimvoid hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA, 4284234353Sdim ArgStringList &CmdArgs) const { 4285234353Sdim 4286234353Sdim} 4287234353Sdimvoid hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 4288234353Sdim const InputInfo &Output, 4289234353Sdim const InputInfoList &Inputs, 4290234353Sdim const ArgList &Args, 4291234353Sdim const char *LinkingOutput) const { 4292234353Sdim 4293234353Sdim const Driver &D = getToolChain().getDriver(); 4294234353Sdim ArgStringList CmdArgs; 4295234353Sdim 4296234353Sdim std::string MarchString = "-march="; 4297249423Sdim MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args); 4298234353Sdim CmdArgs.push_back(Args.MakeArgString(MarchString)); 4299234353Sdim 4300234353Sdim RenderExtraToolArgs(JA, CmdArgs); 4301234353Sdim 4302234353Sdim if (Output.isFilename()) { 4303234353Sdim CmdArgs.push_back("-o"); 4304234353Sdim CmdArgs.push_back(Output.getFilename()); 4305234353Sdim } else { 4306234353Sdim assert(Output.isNothing() && "Unexpected output"); 4307234353Sdim CmdArgs.push_back("-fsyntax-only"); 4308234353Sdim } 4309234353Sdim 4310249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 4311249423Sdim if (!SmallDataThreshold.empty()) 4312249423Sdim CmdArgs.push_back( 4313249423Sdim Args.MakeArgString(std::string("-G") + SmallDataThreshold)); 4314234353Sdim 4315249423Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4316249423Sdim options::OPT_Xassembler); 4317249423Sdim 4318234353Sdim // Only pass -x if gcc will understand it; otherwise hope gcc 4319234353Sdim // understands the suffix correctly. The main use case this would go 4320234353Sdim // wrong in is for linker inputs if they happened to have an odd 4321234353Sdim // suffix; really the only way to get this to happen is a command 4322234353Sdim // like '-x foobar a.c' which will treat a.c like a linker input. 4323234353Sdim // 4324234353Sdim // FIXME: For the linker case specifically, can we safely convert 4325234353Sdim // inputs into '-Wl,' options? 4326234353Sdim for (InputInfoList::const_iterator 4327234353Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 4328234353Sdim const InputInfo &II = *it; 4329234353Sdim 4330234353Sdim // Don't try to pass LLVM or AST inputs to a generic gcc. 4331234353Sdim if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || 4332234353Sdim II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) 4333234353Sdim D.Diag(clang::diag::err_drv_no_linker_llvm_support) 4334234353Sdim << getToolChain().getTripleString(); 4335234353Sdim else if (II.getType() == types::TY_AST) 4336234353Sdim D.Diag(clang::diag::err_drv_no_ast_support) 4337234353Sdim << getToolChain().getTripleString(); 4338249423Sdim else if (II.getType() == types::TY_ModuleFile) 4339249423Sdim D.Diag(diag::err_drv_no_module_support) 4340249423Sdim << getToolChain().getTripleString(); 4341234353Sdim 4342234353Sdim if (II.isFilename()) 4343234353Sdim CmdArgs.push_back(II.getFilename()); 4344234353Sdim else 4345234353Sdim // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? 4346234353Sdim II.getInputArg().render(Args, CmdArgs); 4347234353Sdim } 4348234353Sdim 4349234353Sdim const char *GCCName = "hexagon-as"; 4350234353Sdim const char *Exec = 4351234353Sdim Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); 4352234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4353234353Sdim 4354234353Sdim} 4355234353Sdimvoid hexagon::Link::RenderExtraToolArgs(const JobAction &JA, 4356234353Sdim ArgStringList &CmdArgs) const { 4357234353Sdim // The types are (hopefully) good enough. 4358234353Sdim} 4359234353Sdim 4360234353Sdimvoid hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, 4361234353Sdim const InputInfo &Output, 4362234353Sdim const InputInfoList &Inputs, 4363234353Sdim const ArgList &Args, 4364234353Sdim const char *LinkingOutput) const { 4365234353Sdim 4366249423Sdim const toolchains::Hexagon_TC& ToolChain = 4367249423Sdim static_cast<const toolchains::Hexagon_TC&>(getToolChain()); 4368249423Sdim const Driver &D = ToolChain.getDriver(); 4369249423Sdim 4370234353Sdim ArgStringList CmdArgs; 4371234353Sdim 4372249423Sdim //---------------------------------------------------------------------------- 4373249423Sdim // 4374249423Sdim //---------------------------------------------------------------------------- 4375249423Sdim bool hasStaticArg = Args.hasArg(options::OPT_static); 4376249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 4377249423Sdim bool buildPIE = Args.hasArg(options::OPT_pie); 4378249423Sdim bool incStdLib = !Args.hasArg(options::OPT_nostdlib); 4379249423Sdim bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles); 4380249423Sdim bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs); 4381249423Sdim bool useShared = buildingLib && !hasStaticArg; 4382234353Sdim 4383249423Sdim //---------------------------------------------------------------------------- 4384249423Sdim // Silence warnings for various options 4385249423Sdim //---------------------------------------------------------------------------- 4386249423Sdim 4387249423Sdim Args.ClaimAllArgs(options::OPT_g_Group); 4388249423Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 4389249423Sdim Args.ClaimAllArgs(options::OPT_w); // Other warning options are already 4390249423Sdim // handled somewhere else. 4391249423Sdim Args.ClaimAllArgs(options::OPT_static_libgcc); 4392249423Sdim 4393249423Sdim //---------------------------------------------------------------------------- 4394249423Sdim // 4395249423Sdim //---------------------------------------------------------------------------- 4396249423Sdim for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), 4397249423Sdim e = ToolChain.ExtraOpts.end(); 4398249423Sdim i != e; ++i) 4399249423Sdim CmdArgs.push_back(i->c_str()); 4400249423Sdim 4401249423Sdim std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args); 4402249423Sdim CmdArgs.push_back(Args.MakeArgString("-m" + MarchString)); 4403249423Sdim 4404249423Sdim if (buildingLib) { 4405249423Sdim CmdArgs.push_back("-shared"); 4406249423Sdim CmdArgs.push_back("-call_shared"); // should be the default, but doing as 4407249423Sdim // hexagon-gcc does 4408234353Sdim } 4409234353Sdim 4410249423Sdim if (hasStaticArg) 4411249423Sdim CmdArgs.push_back("-static"); 4412234353Sdim 4413249423Sdim if (buildPIE && !buildingLib) 4414249423Sdim CmdArgs.push_back("-pie"); 4415249423Sdim 4416249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 4417249423Sdim if (!SmallDataThreshold.empty()) { 4418249423Sdim CmdArgs.push_back( 4419249423Sdim Args.MakeArgString(std::string("-G") + SmallDataThreshold)); 4420234353Sdim } 4421234353Sdim 4422249423Sdim //---------------------------------------------------------------------------- 4423249423Sdim // 4424249423Sdim //---------------------------------------------------------------------------- 4425249423Sdim CmdArgs.push_back("-o"); 4426249423Sdim CmdArgs.push_back(Output.getFilename()); 4427234353Sdim 4428249423Sdim const std::string MarchSuffix = "/" + MarchString; 4429249423Sdim const std::string G0Suffix = "/G0"; 4430249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 4431249423Sdim const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir) 4432249423Sdim + "/"; 4433249423Sdim const std::string StartFilesDir = RootDir 4434249423Sdim + "hexagon/lib" 4435249423Sdim + (buildingLib 4436249423Sdim ? MarchG0Suffix : MarchSuffix); 4437234353Sdim 4438249423Sdim //---------------------------------------------------------------------------- 4439249423Sdim // moslib 4440249423Sdim //---------------------------------------------------------------------------- 4441249423Sdim std::vector<std::string> oslibs; 4442249423Sdim bool hasStandalone= false; 4443249423Sdim 4444249423Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ), 4445249423Sdim ie = Args.filtered_end(); it != ie; ++it) { 4446249423Sdim (*it)->claim(); 4447249423Sdim oslibs.push_back((*it)->getValue()); 4448249423Sdim hasStandalone = hasStandalone || (oslibs.back() == "standalone"); 4449234353Sdim } 4450249423Sdim if (oslibs.empty()) { 4451249423Sdim oslibs.push_back("standalone"); 4452249423Sdim hasStandalone = true; 4453249423Sdim } 4454234353Sdim 4455249423Sdim //---------------------------------------------------------------------------- 4456249423Sdim // Start Files 4457249423Sdim //---------------------------------------------------------------------------- 4458249423Sdim if (incStdLib && incStartFiles) { 4459234353Sdim 4460249423Sdim if (!buildingLib) { 4461249423Sdim if (hasStandalone) { 4462249423Sdim CmdArgs.push_back( 4463249423Sdim Args.MakeArgString(StartFilesDir + "/crt0_standalone.o")); 4464249423Sdim } 4465249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o")); 4466249423Sdim } 4467249423Sdim std::string initObj = useShared ? "/initS.o" : "/init.o"; 4468249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj)); 4469249423Sdim } 4470234353Sdim 4471249423Sdim //---------------------------------------------------------------------------- 4472249423Sdim // Library Search Paths 4473249423Sdim //---------------------------------------------------------------------------- 4474249423Sdim const ToolChain::path_list &LibPaths = ToolChain.getFilePaths(); 4475249423Sdim for (ToolChain::path_list::const_iterator 4476249423Sdim i = LibPaths.begin(), 4477249423Sdim e = LibPaths.end(); 4478249423Sdim i != e; 4479249423Sdim ++i) 4480249423Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 4481249423Sdim 4482249423Sdim //---------------------------------------------------------------------------- 4483249423Sdim // 4484249423Sdim //---------------------------------------------------------------------------- 4485249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 4486249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 4487249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 4488249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 4489249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 4490249423Sdim 4491249423Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 4492249423Sdim 4493249423Sdim //---------------------------------------------------------------------------- 4494249423Sdim // Libraries 4495249423Sdim //---------------------------------------------------------------------------- 4496249423Sdim if (incStdLib && incDefLibs) { 4497263508Sdim if (D.CCCIsCXX()) { 4498249423Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 4499249423Sdim CmdArgs.push_back("-lm"); 4500249423Sdim } 4501249423Sdim 4502249423Sdim CmdArgs.push_back("--start-group"); 4503249423Sdim 4504249423Sdim if (!buildingLib) { 4505249423Sdim for(std::vector<std::string>::iterator i = oslibs.begin(), 4506249423Sdim e = oslibs.end(); i != e; ++i) 4507249423Sdim CmdArgs.push_back(Args.MakeArgString("-l" + *i)); 4508249423Sdim CmdArgs.push_back("-lc"); 4509249423Sdim } 4510249423Sdim CmdArgs.push_back("-lgcc"); 4511249423Sdim 4512249423Sdim CmdArgs.push_back("--end-group"); 4513234353Sdim } 4514234353Sdim 4515249423Sdim //---------------------------------------------------------------------------- 4516249423Sdim // End files 4517249423Sdim //---------------------------------------------------------------------------- 4518249423Sdim if (incStdLib && incStartFiles) { 4519249423Sdim std::string finiObj = useShared ? "/finiS.o" : "/fini.o"; 4520249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj)); 4521249423Sdim } 4522249423Sdim 4523249423Sdim std::string Linker = ToolChain.GetProgramPath("hexagon-ld"); 4524263508Sdim C.addCommand(new Command(JA, *this, Args.MakeArgString(Linker), CmdArgs)); 4525234353Sdim} 4526234353Sdim// Hexagon tools end. 4527234353Sdim 4528243830Sdimllvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) { 4529243830Sdim // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 4530243830Sdim // archs which Darwin doesn't use. 4531234353Sdim 4532243830Sdim // The matching this routine does is fairly pointless, since it is neither the 4533243830Sdim // complete architecture list, nor a reasonable subset. The problem is that 4534243830Sdim // historically the driver driver accepts this and also ties its -march= 4535243830Sdim // handling to the architecture name, so we need to be careful before removing 4536243830Sdim // support for it. 4537243830Sdim 4538243830Sdim // This code must be kept in sync with Clang's Darwin specific argument 4539243830Sdim // translation. 4540243830Sdim 4541243830Sdim return llvm::StringSwitch<llvm::Triple::ArchType>(Str) 4542243830Sdim .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) 4543243830Sdim .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) 4544243830Sdim .Case("ppc64", llvm::Triple::ppc64) 4545243830Sdim .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) 4546243830Sdim .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 4547243830Sdim llvm::Triple::x86) 4548263508Sdim .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) 4549243830Sdim // This is derived from the driver driver. 4550249423Sdim .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) 4551249423Sdim .Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm) 4552249423Sdim .Cases("armv7s", "xscale", llvm::Triple::arm) 4553243830Sdim .Case("r600", llvm::Triple::r600) 4554243830Sdim .Case("nvptx", llvm::Triple::nvptx) 4555243830Sdim .Case("nvptx64", llvm::Triple::nvptx64) 4556243830Sdim .Case("amdil", llvm::Triple::amdil) 4557243830Sdim .Case("spir", llvm::Triple::spir) 4558243830Sdim .Default(llvm::Triple::UnknownArch); 4559243830Sdim} 4560243830Sdim 4561249423Sdimconst char *Clang::getBaseInputName(const ArgList &Args, 4562249423Sdim const InputInfoList &Inputs) { 4563218893Sdim return Args.MakeArgString( 4564218893Sdim llvm::sys::path::filename(Inputs[0].getBaseInput())); 4565193326Sed} 4566193326Sed 4567249423Sdimconst char *Clang::getBaseInputStem(const ArgList &Args, 4568249423Sdim const InputInfoList &Inputs) { 4569193326Sed const char *Str = getBaseInputName(Args, Inputs); 4570193326Sed 4571218893Sdim if (const char *End = strrchr(Str, '.')) 4572198092Srdivacky return Args.MakeArgString(std::string(Str, End)); 4573193326Sed 4574193326Sed return Str; 4575193326Sed} 4576193326Sed 4577249423Sdimconst char *Clang::getDependencyFileName(const ArgList &Args, 4578249423Sdim const InputInfoList &Inputs) { 4579193326Sed // FIXME: Think about this more. 4580193326Sed std::string Res; 4581193326Sed 4582193326Sed if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 4583243830Sdim std::string Str(OutputOpt->getValue()); 4584193326Sed Res = Str.substr(0, Str.rfind('.')); 4585226633Sdim } else { 4586249423Sdim Res = getBaseInputStem(Args, Inputs); 4587226633Sdim } 4588198092Srdivacky return Args.MakeArgString(Res + ".d"); 4589193326Sed} 4590193326Sed 4591193326Sedvoid darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 4592212904Sdim const InputInfo &Output, 4593193326Sed const InputInfoList &Inputs, 4594193326Sed const ArgList &Args, 4595193326Sed const char *LinkingOutput) const { 4596193326Sed ArgStringList CmdArgs; 4597193326Sed 4598193326Sed assert(Inputs.size() == 1 && "Unexpected number of inputs."); 4599193326Sed const InputInfo &Input = Inputs[0]; 4600193326Sed 4601221345Sdim // Determine the original source input. 4602221345Sdim const Action *SourceAction = &JA; 4603221345Sdim while (SourceAction->getKind() != Action::InputClass) { 4604221345Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 4605221345Sdim SourceAction = SourceAction->getInputs()[0]; 4606221345Sdim } 4607221345Sdim 4608263508Sdim // If -no_integrated_as is used add -Q to the darwin assember driver to make 4609263508Sdim // sure it runs its system assembler not clang's integrated assembler. 4610266715Sdim // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as. 4611266715Sdim // FIXME: at run-time detect assembler capabilities or rely on version 4612266715Sdim // information forwarded by -target-assembler-version (future) 4613266715Sdim if (Args.hasArg(options::OPT_no_integrated_as)) { 4614266715Sdim const llvm::Triple& t(getToolChain().getTriple()); 4615266715Sdim if (!(t.isMacOSX() && t.isMacOSXVersionLT(10, 7))) 4616266715Sdim CmdArgs.push_back("-Q"); 4617266715Sdim } 4618263508Sdim 4619221345Sdim // Forward -g, assuming we are dealing with an actual assembly file. 4620226633Sdim if (SourceAction->getType() == types::TY_Asm || 4621221345Sdim SourceAction->getType() == types::TY_PP_Asm) { 4622193326Sed if (Args.hasArg(options::OPT_gstabs)) 4623193326Sed CmdArgs.push_back("--gstabs"); 4624193326Sed else if (Args.hasArg(options::OPT_g_Group)) 4625234353Sdim CmdArgs.push_back("-g"); 4626193326Sed } 4627193326Sed 4628193326Sed // Derived from asm spec. 4629198092Srdivacky AddDarwinArch(Args, CmdArgs); 4630193326Sed 4631212904Sdim // Use -force_cpusubtype_ALL on x86 by default. 4632263508Sdim if (getToolChain().getArch() == llvm::Triple::x86 || 4633263508Sdim getToolChain().getArch() == llvm::Triple::x86_64 || 4634198092Srdivacky Args.hasArg(options::OPT_force__cpusubtype__ALL)) 4635198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 4636198092Srdivacky 4637263508Sdim if (getToolChain().getArch() != llvm::Triple::x86_64 && 4638243830Sdim (((Args.hasArg(options::OPT_mkernel) || 4639243830Sdim Args.hasArg(options::OPT_fapple_kext)) && 4640243830Sdim (!getDarwinToolChain().isTargetIPhoneOS() || 4641243830Sdim getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) || 4642243830Sdim Args.hasArg(options::OPT_static))) 4643193326Sed CmdArgs.push_back("-static"); 4644193326Sed 4645193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4646193326Sed options::OPT_Xassembler); 4647193326Sed 4648193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 4649193326Sed CmdArgs.push_back("-o"); 4650193326Sed CmdArgs.push_back(Output.getFilename()); 4651193326Sed 4652212904Sdim assert(Input.isFilename() && "Invalid input."); 4653212904Sdim CmdArgs.push_back(Input.getFilename()); 4654193326Sed 4655193326Sed // asm_final spec is empty. 4656193326Sed 4657193326Sed const char *Exec = 4658210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 4659212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4660193326Sed} 4661193326Sed 4662234353Sdimvoid darwin::DarwinTool::anchor() {} 4663234353Sdim 4664198092Srdivackyvoid darwin::DarwinTool::AddDarwinArch(const ArgList &Args, 4665198092Srdivacky ArgStringList &CmdArgs) const { 4666226633Sdim StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args); 4667202879Srdivacky 4668193326Sed // Derived from darwin_arch spec. 4669193326Sed CmdArgs.push_back("-arch"); 4670202879Srdivacky CmdArgs.push_back(Args.MakeArgString(ArchName)); 4671198092Srdivacky 4672202879Srdivacky // FIXME: Is this needed anymore? 4673202879Srdivacky if (ArchName == "arm") 4674198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 4675193326Sed} 4676193326Sed 4677243830Sdimbool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const { 4678243830Sdim // We only need to generate a temp path for LTO if we aren't compiling object 4679243830Sdim // files. When compiling source files, we run 'dsymutil' after linking. We 4680243830Sdim // don't run 'dsymutil' when compiling object files. 4681243830Sdim for (InputInfoList::const_iterator 4682243830Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) 4683243830Sdim if (it->getType() != types::TY_Object) 4684243830Sdim return true; 4685243830Sdim 4686243830Sdim return false; 4687243830Sdim} 4688243830Sdim 4689218893Sdimvoid darwin::Link::AddLinkArgs(Compilation &C, 4690218893Sdim const ArgList &Args, 4691243830Sdim ArgStringList &CmdArgs, 4692243830Sdim const InputInfoList &Inputs) const { 4693201361Srdivacky const Driver &D = getToolChain().getDriver(); 4694221345Sdim const toolchains::Darwin &DarwinTC = getDarwinToolChain(); 4695193326Sed 4696212904Sdim unsigned Version[3] = { 0, 0, 0 }; 4697212904Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 4698212904Sdim bool HadExtra; 4699243830Sdim if (!Driver::GetReleaseVersion(A->getValue(), Version[0], 4700212904Sdim Version[1], Version[2], HadExtra) || 4701212904Sdim HadExtra) 4702226633Sdim D.Diag(diag::err_drv_invalid_version_number) 4703212904Sdim << A->getAsString(Args); 4704212904Sdim } 4705212904Sdim 4706212904Sdim // Newer linkers support -demangle, pass it if supported and not disabled by 4707212904Sdim // the user. 4708234353Sdim if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) { 4709218893Sdim // Don't pass -demangle to ld_classic. 4710218893Sdim // 4711218893Sdim // FIXME: This is a temporary workaround, ld should be handling this. 4712218893Sdim bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 && 4713218893Sdim Args.hasArg(options::OPT_static)); 4714218893Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 4715218893Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker, 4716218893Sdim options::OPT_Wl_COMMA), 4717218893Sdim ie = Args.filtered_end(); it != ie; ++it) { 4718218893Sdim const Arg *A = *it; 4719218893Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) 4720243830Sdim if (StringRef(A->getValue(i)) == "-kext") 4721218893Sdim UsesLdClassic = true; 4722218893Sdim } 4723218893Sdim } 4724218893Sdim if (!UsesLdClassic) 4725218893Sdim CmdArgs.push_back("-demangle"); 4726212904Sdim } 4727212904Sdim 4728263508Sdim if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137) 4729263508Sdim CmdArgs.push_back("-export_dynamic"); 4730263508Sdim 4731224145Sdim // If we are using LTO, then automatically create a temporary file path for 4732224145Sdim // the linker to use, so that it's lifetime will extend past a possible 4733224145Sdim // dsymutil step. 4734243830Sdim if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) { 4735224145Sdim const char *TmpPath = C.getArgs().MakeArgString( 4736226633Sdim D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object))); 4737224145Sdim C.addTempFile(TmpPath); 4738224145Sdim CmdArgs.push_back("-object_path_lto"); 4739224145Sdim CmdArgs.push_back(TmpPath); 4740224145Sdim } 4741224145Sdim 4742193326Sed // Derived from the "link" spec. 4743193326Sed Args.AddAllArgs(CmdArgs, options::OPT_static); 4744193326Sed if (!Args.hasArg(options::OPT_static)) 4745193326Sed CmdArgs.push_back("-dynamic"); 4746193326Sed if (Args.hasArg(options::OPT_fgnu_runtime)) { 4747193326Sed // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 4748193326Sed // here. How do we wish to handle such things? 4749193326Sed } 4750193326Sed 4751193326Sed if (!Args.hasArg(options::OPT_dynamiclib)) { 4752202879Srdivacky AddDarwinArch(Args, CmdArgs); 4753202879Srdivacky // FIXME: Why do this only on this path? 4754202879Srdivacky Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 4755193326Sed 4756193326Sed Args.AddLastArg(CmdArgs, options::OPT_bundle); 4757193326Sed Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 4758193326Sed Args.AddAllArgs(CmdArgs, options::OPT_client__name); 4759193326Sed 4760193326Sed Arg *A; 4761193326Sed if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 4762193326Sed (A = Args.getLastArg(options::OPT_current__version)) || 4763193326Sed (A = Args.getLastArg(options::OPT_install__name))) 4764226633Sdim D.Diag(diag::err_drv_argument_only_allowed_with) 4765193326Sed << A->getAsString(Args) << "-dynamiclib"; 4766193326Sed 4767193326Sed Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 4768193326Sed Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 4769193326Sed Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 4770193326Sed } else { 4771193326Sed CmdArgs.push_back("-dylib"); 4772193326Sed 4773193326Sed Arg *A; 4774193326Sed if ((A = Args.getLastArg(options::OPT_bundle)) || 4775193326Sed (A = Args.getLastArg(options::OPT_bundle__loader)) || 4776193326Sed (A = Args.getLastArg(options::OPT_client__name)) || 4777193326Sed (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 4778193326Sed (A = Args.getLastArg(options::OPT_keep__private__externs)) || 4779193326Sed (A = Args.getLastArg(options::OPT_private__bundle))) 4780226633Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 4781193326Sed << A->getAsString(Args) << "-dynamiclib"; 4782193326Sed 4783193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 4784193326Sed "-dylib_compatibility_version"); 4785193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 4786193326Sed "-dylib_current_version"); 4787193326Sed 4788202879Srdivacky AddDarwinArch(Args, CmdArgs); 4789193326Sed 4790193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 4791193326Sed "-dylib_install_name"); 4792193326Sed } 4793193326Sed 4794193326Sed Args.AddLastArg(CmdArgs, options::OPT_all__load); 4795193326Sed Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 4796193326Sed Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 4797221345Sdim if (DarwinTC.isTargetIPhoneOS()) 4798198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 4799193326Sed Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 4800193326Sed Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 4801193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 4802193326Sed Args.AddLastArg(CmdArgs, options::OPT_dynamic); 4803193326Sed Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 4804193326Sed Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 4805224145Sdim Args.AddAllArgs(CmdArgs, options::OPT_force__load); 4806193326Sed Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 4807193326Sed Args.AddAllArgs(CmdArgs, options::OPT_image__base); 4808193326Sed Args.AddAllArgs(CmdArgs, options::OPT_init); 4809193326Sed 4810221345Sdim // Add the deployment target. 4811234353Sdim VersionTuple TargetVersion = DarwinTC.getTargetVersion(); 4812221345Sdim 4813221345Sdim // If we had an explicit -mios-simulator-version-min argument, honor that, 4814221345Sdim // otherwise use the traditional deployment targets. We can't just check the 4815221345Sdim // is-sim attribute because existing code follows this path, and the linker 4816221345Sdim // may not handle the argument. 4817221345Sdim // 4818221345Sdim // FIXME: We may be able to remove this, once we can verify no one depends on 4819221345Sdim // it. 4820221345Sdim if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) 4821221345Sdim CmdArgs.push_back("-ios_simulator_version_min"); 4822221345Sdim else if (DarwinTC.isTargetIPhoneOS()) 4823221345Sdim CmdArgs.push_back("-iphoneos_version_min"); 4824221345Sdim else 4825221345Sdim CmdArgs.push_back("-macosx_version_min"); 4826234353Sdim CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 4827221345Sdim 4828193326Sed Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 4829193326Sed Args.AddLastArg(CmdArgs, options::OPT_multi__module); 4830193326Sed Args.AddLastArg(CmdArgs, options::OPT_single__module); 4831193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 4832193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 4833193326Sed 4834210299Sed if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, 4835210299Sed options::OPT_fno_pie, 4836210299Sed options::OPT_fno_PIE)) { 4837210299Sed if (A->getOption().matches(options::OPT_fpie) || 4838210299Sed A->getOption().matches(options::OPT_fPIE)) 4839210299Sed CmdArgs.push_back("-pie"); 4840210299Sed else 4841210299Sed CmdArgs.push_back("-no_pie"); 4842210299Sed } 4843193326Sed 4844193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind); 4845193326Sed Args.AddLastArg(CmdArgs, options::OPT_noprebind); 4846193326Sed Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 4847193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 4848193326Sed Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 4849193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 4850193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 4851193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 4852193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segprot); 4853193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 4854193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 4855193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 4856193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 4857193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 4858193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 4859193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 4860198092Srdivacky 4861223017Sdim // Give --sysroot= preference, over the Apple specific behavior to also use 4862223017Sdim // --isysroot as the syslibroot. 4863234982Sdim StringRef sysroot = C.getSysRoot(); 4864234982Sdim if (sysroot != "") { 4865223017Sdim CmdArgs.push_back("-syslibroot"); 4866234982Sdim CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 4867223017Sdim } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 4868223017Sdim CmdArgs.push_back("-syslibroot"); 4869243830Sdim CmdArgs.push_back(A->getValue()); 4870198092Srdivacky } 4871198092Srdivacky 4872193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 4873193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 4874193326Sed Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 4875193326Sed Args.AddAllArgs(CmdArgs, options::OPT_undefined); 4876193326Sed Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 4877193326Sed Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 4878193326Sed Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 4879193326Sed Args.AddAllArgs(CmdArgs, options::OPT_y); 4880193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 4881193326Sed Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 4882193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 4883193326Sed Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 4884193326Sed Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 4885193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 4886193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 4887193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 4888193326Sed Args.AddLastArg(CmdArgs, options::OPT_whyload); 4889193326Sed Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 4890193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 4891193326Sed Args.AddLastArg(CmdArgs, options::OPT_dylinker); 4892193326Sed Args.AddLastArg(CmdArgs, options::OPT_Mach); 4893193326Sed} 4894193326Sed 4895193326Sedvoid darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, 4896212904Sdim const InputInfo &Output, 4897193326Sed const InputInfoList &Inputs, 4898193326Sed const ArgList &Args, 4899193326Sed const char *LinkingOutput) const { 4900193326Sed assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 4901198092Srdivacky 4902193326Sed // The logic here is derived from gcc's behavior; most of which 4903193326Sed // comes from specs (starting with link_command). Consult gcc for 4904193326Sed // more information. 4905193326Sed ArgStringList CmdArgs; 4906193326Sed 4907226633Sdim /// Hack(tm) to ignore linking errors when we are doing ARC migration. 4908226633Sdim if (Args.hasArg(options::OPT_ccc_arcmt_check, 4909226633Sdim options::OPT_ccc_arcmt_migrate)) { 4910226633Sdim for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) 4911226633Sdim (*I)->claim(); 4912226633Sdim const char *Exec = 4913226633Sdim Args.MakeArgString(getToolChain().GetProgramPath("touch")); 4914226633Sdim CmdArgs.push_back(Output.getFilename()); 4915226633Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4916226633Sdim return; 4917226633Sdim } 4918226633Sdim 4919193326Sed // I'm not sure why this particular decomposition exists in gcc, but 4920193326Sed // we follow suite for ease of comparison. 4921243830Sdim AddLinkArgs(C, Args, CmdArgs, Inputs); 4922193326Sed 4923193326Sed Args.AddAllArgs(CmdArgs, options::OPT_d_Flag); 4924193326Sed Args.AddAllArgs(CmdArgs, options::OPT_s); 4925193326Sed Args.AddAllArgs(CmdArgs, options::OPT_t); 4926193326Sed Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 4927193326Sed Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 4928193326Sed Args.AddLastArg(CmdArgs, options::OPT_e); 4929193326Sed Args.AddAllArgs(CmdArgs, options::OPT_r); 4930193326Sed 4931218893Sdim // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading 4932218893Sdim // members of static archive libraries which implement Objective-C classes or 4933218893Sdim // categories. 4934218893Sdim if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX)) 4935218893Sdim CmdArgs.push_back("-ObjC"); 4936218893Sdim 4937193326Sed CmdArgs.push_back("-o"); 4938193326Sed CmdArgs.push_back(Output.getFilename()); 4939193326Sed 4940239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 4941193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 4942193326Sed // Derived from startfile spec. 4943193326Sed if (Args.hasArg(options::OPT_dynamiclib)) { 4944193326Sed // Derived from darwin_dylib1 spec. 4945221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 4946221345Sdim // The simulator doesn't have a versioned crt1 file. 4947221345Sdim CmdArgs.push_back("-ldylib1.o"); 4948221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 4949203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 4950203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 4951203955Srdivacky } else { 4952203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 4953203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 4954203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 4955203955Srdivacky CmdArgs.push_back("-ldylib1.10.5.o"); 4956203955Srdivacky } 4957193326Sed } else { 4958193326Sed if (Args.hasArg(options::OPT_bundle)) { 4959193326Sed if (!Args.hasArg(options::OPT_static)) { 4960193326Sed // Derived from darwin_bundle1 spec. 4961221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 4962221345Sdim // The simulator doesn't have a versioned crt1 file. 4963221345Sdim CmdArgs.push_back("-lbundle1.o"); 4964221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 4965203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 4966203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 4967203955Srdivacky } else { 4968203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 4969203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 4970203955Srdivacky } 4971193326Sed } 4972193326Sed } else { 4973221345Sdim if (Args.hasArg(options::OPT_pg) && 4974221345Sdim getToolChain().SupportsProfiling()) { 4975193326Sed if (Args.hasArg(options::OPT_static) || 4976193326Sed Args.hasArg(options::OPT_object) || 4977193326Sed Args.hasArg(options::OPT_preload)) { 4978193326Sed CmdArgs.push_back("-lgcrt0.o"); 4979193326Sed } else { 4980193326Sed CmdArgs.push_back("-lgcrt1.o"); 4981193326Sed 4982193326Sed // darwin_crt2 spec is empty. 4983193326Sed } 4984239462Sdim // By default on OS X 10.8 and later, we don't link with a crt1.o 4985239462Sdim // file and the linker knows to use _main as the entry point. But, 4986239462Sdim // when compiling with -pg, we need to link with the gcrt1.o file, 4987239462Sdim // so pass the -no_new_main option to tell the linker to use the 4988239462Sdim // "start" symbol as the entry point. 4989239462Sdim if (getDarwinToolChain().isTargetMacOS() && 4990239462Sdim !getDarwinToolChain().isMacosxVersionLT(10, 8)) 4991239462Sdim CmdArgs.push_back("-no_new_main"); 4992193326Sed } else { 4993193326Sed if (Args.hasArg(options::OPT_static) || 4994193326Sed Args.hasArg(options::OPT_object) || 4995193326Sed Args.hasArg(options::OPT_preload)) { 4996193326Sed CmdArgs.push_back("-lcrt0.o"); 4997193326Sed } else { 4998193326Sed // Derived from darwin_crt1 spec. 4999221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 5000221345Sdim // The simulator doesn't have a versioned crt1 file. 5001221345Sdim CmdArgs.push_back("-lcrt1.o"); 5002221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 5003203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 5004203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 5005243830Sdim else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0)) 5006203955Srdivacky CmdArgs.push_back("-lcrt1.3.1.o"); 5007203955Srdivacky } else { 5008203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 5009203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 5010203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 5011203955Srdivacky CmdArgs.push_back("-lcrt1.10.5.o"); 5012234353Sdim else if (getDarwinToolChain().isMacosxVersionLT(10, 8)) 5013203955Srdivacky CmdArgs.push_back("-lcrt1.10.6.o"); 5014193326Sed 5015203955Srdivacky // darwin_crt2 spec is empty. 5016203955Srdivacky } 5017193326Sed } 5018193326Sed } 5019193326Sed } 5020193326Sed } 5021193326Sed 5022203955Srdivacky if (!getDarwinToolChain().isTargetIPhoneOS() && 5023203955Srdivacky Args.hasArg(options::OPT_shared_libgcc) && 5024203955Srdivacky getDarwinToolChain().isMacosxVersionLT(10, 5)) { 5025198092Srdivacky const char *Str = 5026210299Sed Args.MakeArgString(getToolChain().GetFilePath("crt3.o")); 5027198092Srdivacky CmdArgs.push_back(Str); 5028193326Sed } 5029193326Sed } 5030193326Sed 5031193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5032193326Sed 5033193326Sed if (Args.hasArg(options::OPT_fopenmp)) 5034193326Sed // This is more complicated in gcc... 5035193326Sed CmdArgs.push_back("-lgomp"); 5036193326Sed 5037239462Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5038239462Sdim 5039239462Sdim if (isObjCRuntimeLinked(Args) && 5040239462Sdim !Args.hasArg(options::OPT_nostdlib) && 5041239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5042234353Sdim // Avoid linking compatibility stubs on i386 mac. 5043234353Sdim if (!getDarwinToolChain().isTargetMacOS() || 5044243830Sdim getDarwinToolChain().getArch() != llvm::Triple::x86) { 5045234353Sdim // If we don't have ARC or subscripting runtime support, link in the 5046234353Sdim // runtime stubs. We have to do this *before* adding any of the normal 5047234353Sdim // linker inputs so that its initializer gets run first. 5048239462Sdim ObjCRuntime runtime = 5049239462Sdim getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true); 5050234353Sdim // We use arclite library for both ARC and subscripting support. 5051243830Sdim if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) || 5052239462Sdim !runtime.hasSubscripting()) 5053234353Sdim getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs); 5054234353Sdim } 5055239462Sdim CmdArgs.push_back("-framework"); 5056239462Sdim CmdArgs.push_back("Foundation"); 5057234353Sdim // Link libobj. 5058234353Sdim CmdArgs.push_back("-lobjc"); 5059224145Sdim } 5060224145Sdim 5061193326Sed if (LinkingOutput) { 5062193326Sed CmdArgs.push_back("-arch_multiple"); 5063193326Sed CmdArgs.push_back("-final_output"); 5064193326Sed CmdArgs.push_back(LinkingOutput); 5065193326Sed } 5066193326Sed 5067193326Sed if (Args.hasArg(options::OPT_fnested_functions)) 5068193326Sed CmdArgs.push_back("-allow_stack_execute"); 5069193326Sed 5070193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 5071193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 5072263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5073218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5074193326Sed 5075193326Sed // link_ssp spec is empty. 5076193326Sed 5077198092Srdivacky // Let the tool chain choose which runtime library to link. 5078198092Srdivacky getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); 5079193326Sed } 5080193326Sed 5081239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5082193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 5083193326Sed // endfile_spec is empty. 5084193326Sed } 5085193326Sed 5086193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5087193326Sed Args.AddAllArgs(CmdArgs, options::OPT_F); 5088193326Sed 5089193326Sed const char *Exec = 5090210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5091212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5092193326Sed} 5093193326Sed 5094193326Sedvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 5095212904Sdim const InputInfo &Output, 5096193326Sed const InputInfoList &Inputs, 5097193326Sed const ArgList &Args, 5098193326Sed const char *LinkingOutput) const { 5099193326Sed ArgStringList CmdArgs; 5100193326Sed 5101193326Sed CmdArgs.push_back("-create"); 5102193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 5103193326Sed 5104193326Sed CmdArgs.push_back("-output"); 5105193326Sed CmdArgs.push_back(Output.getFilename()); 5106193326Sed 5107193326Sed for (InputInfoList::const_iterator 5108193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5109193326Sed const InputInfo &II = *it; 5110193326Sed assert(II.isFilename() && "Unexpected lipo input."); 5111193326Sed CmdArgs.push_back(II.getFilename()); 5112193326Sed } 5113193326Sed const char *Exec = 5114210299Sed Args.MakeArgString(getToolChain().GetProgramPath("lipo")); 5115212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5116193326Sed} 5117193326Sed 5118210299Sedvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, 5119212904Sdim const InputInfo &Output, 5120210299Sed const InputInfoList &Inputs, 5121210299Sed const ArgList &Args, 5122210299Sed const char *LinkingOutput) const { 5123210299Sed ArgStringList CmdArgs; 5124210299Sed 5125223017Sdim CmdArgs.push_back("-o"); 5126223017Sdim CmdArgs.push_back(Output.getFilename()); 5127223017Sdim 5128210299Sed assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 5129210299Sed const InputInfo &Input = Inputs[0]; 5130210299Sed assert(Input.isFilename() && "Unexpected dsymutil input."); 5131210299Sed CmdArgs.push_back(Input.getFilename()); 5132210299Sed 5133210299Sed const char *Exec = 5134210299Sed Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); 5135212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5136210299Sed} 5137210299Sed 5138226633Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, 5139249423Sdim const InputInfo &Output, 5140249423Sdim const InputInfoList &Inputs, 5141249423Sdim const ArgList &Args, 5142249423Sdim const char *LinkingOutput) const { 5143226633Sdim ArgStringList CmdArgs; 5144226633Sdim CmdArgs.push_back("--verify"); 5145234353Sdim CmdArgs.push_back("--debug-info"); 5146234353Sdim CmdArgs.push_back("--eh-frame"); 5147234353Sdim CmdArgs.push_back("--quiet"); 5148226633Sdim 5149226633Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 5150226633Sdim const InputInfo &Input = Inputs[0]; 5151226633Sdim assert(Input.isFilename() && "Unexpected verify input"); 5152226633Sdim 5153226633Sdim // Grabbing the output of the earlier dsymutil run. 5154226633Sdim CmdArgs.push_back(Input.getFilename()); 5155226633Sdim 5156226633Sdim const char *Exec = 5157226633Sdim Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); 5158226633Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5159226633Sdim} 5160226633Sdim 5161234353Sdimvoid solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5162234353Sdim const InputInfo &Output, 5163234353Sdim const InputInfoList &Inputs, 5164234353Sdim const ArgList &Args, 5165234353Sdim const char *LinkingOutput) const { 5166234353Sdim ArgStringList CmdArgs; 5167234353Sdim 5168234353Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5169234353Sdim options::OPT_Xassembler); 5170234353Sdim 5171234353Sdim CmdArgs.push_back("-o"); 5172234353Sdim CmdArgs.push_back(Output.getFilename()); 5173234353Sdim 5174234353Sdim for (InputInfoList::const_iterator 5175234353Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5176234353Sdim const InputInfo &II = *it; 5177234353Sdim CmdArgs.push_back(II.getFilename()); 5178234353Sdim } 5179234353Sdim 5180234353Sdim const char *Exec = 5181234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 5182234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5183234353Sdim} 5184234353Sdim 5185234353Sdim 5186234353Sdimvoid solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, 5187234353Sdim const InputInfo &Output, 5188234353Sdim const InputInfoList &Inputs, 5189234353Sdim const ArgList &Args, 5190234353Sdim const char *LinkingOutput) const { 5191234353Sdim // FIXME: Find a real GCC, don't hard-code versions here 5192234353Sdim std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/"; 5193234353Sdim const llvm::Triple &T = getToolChain().getTriple(); 5194234353Sdim std::string LibPath = "/usr/lib/"; 5195234353Sdim llvm::Triple::ArchType Arch = T.getArch(); 5196234353Sdim switch (Arch) { 5197263508Sdim case llvm::Triple::x86: 5198263508Sdim GCCLibPath += 5199263508Sdim ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/"; 5200263508Sdim break; 5201263508Sdim case llvm::Triple::x86_64: 5202263508Sdim GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str(); 5203263508Sdim GCCLibPath += "/4.5.2/amd64/"; 5204263508Sdim LibPath += "amd64/"; 5205263508Sdim break; 5206263508Sdim default: 5207263508Sdim llvm_unreachable("Unsupported architecture"); 5208234353Sdim } 5209234353Sdim 5210234353Sdim ArgStringList CmdArgs; 5211234353Sdim 5212234353Sdim // Demangle C++ names in errors 5213234353Sdim CmdArgs.push_back("-C"); 5214234353Sdim 5215234353Sdim if ((!Args.hasArg(options::OPT_nostdlib)) && 5216234353Sdim (!Args.hasArg(options::OPT_shared))) { 5217234353Sdim CmdArgs.push_back("-e"); 5218234353Sdim CmdArgs.push_back("_start"); 5219234353Sdim } 5220234353Sdim 5221234353Sdim if (Args.hasArg(options::OPT_static)) { 5222234353Sdim CmdArgs.push_back("-Bstatic"); 5223234353Sdim CmdArgs.push_back("-dn"); 5224234353Sdim } else { 5225234353Sdim CmdArgs.push_back("-Bdynamic"); 5226234353Sdim if (Args.hasArg(options::OPT_shared)) { 5227234353Sdim CmdArgs.push_back("-shared"); 5228234353Sdim } else { 5229234353Sdim CmdArgs.push_back("--dynamic-linker"); 5230234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1")); 5231234353Sdim } 5232234353Sdim } 5233234353Sdim 5234234353Sdim if (Output.isFilename()) { 5235234353Sdim CmdArgs.push_back("-o"); 5236234353Sdim CmdArgs.push_back(Output.getFilename()); 5237234353Sdim } else { 5238234353Sdim assert(Output.isNothing() && "Invalid output."); 5239234353Sdim } 5240234353Sdim 5241234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5242234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5243234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5244234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o")); 5245234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); 5246234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); 5247234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); 5248234353Sdim } else { 5249234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); 5250234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); 5251234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); 5252234353Sdim } 5253263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5254234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o")); 5255234353Sdim } 5256234353Sdim 5257234353Sdim CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath)); 5258234353Sdim 5259234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 5260234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5261234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 5262234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5263234353Sdim 5264234353Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5265234353Sdim 5266234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5267234353Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5268263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5269234353Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5270234353Sdim CmdArgs.push_back("-lgcc_s"); 5271234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5272234353Sdim CmdArgs.push_back("-lgcc"); 5273234353Sdim CmdArgs.push_back("-lc"); 5274234353Sdim CmdArgs.push_back("-lm"); 5275234353Sdim } 5276234353Sdim } 5277234353Sdim 5278234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5279234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5280234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o")); 5281234353Sdim } 5282234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o")); 5283234353Sdim 5284234353Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 5285234353Sdim 5286234353Sdim const char *Exec = 5287234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5288234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5289234353Sdim} 5290234353Sdim 5291198092Srdivackyvoid auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5292212904Sdim const InputInfo &Output, 5293198893Srdivacky const InputInfoList &Inputs, 5294198893Srdivacky const ArgList &Args, 5295198893Srdivacky const char *LinkingOutput) const { 5296198092Srdivacky ArgStringList CmdArgs; 5297198092Srdivacky 5298198092Srdivacky Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5299198092Srdivacky options::OPT_Xassembler); 5300198092Srdivacky 5301198092Srdivacky CmdArgs.push_back("-o"); 5302212904Sdim CmdArgs.push_back(Output.getFilename()); 5303198092Srdivacky 5304198092Srdivacky for (InputInfoList::const_iterator 5305198092Srdivacky it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5306198092Srdivacky const InputInfo &II = *it; 5307212904Sdim CmdArgs.push_back(II.getFilename()); 5308198092Srdivacky } 5309198092Srdivacky 5310198092Srdivacky const char *Exec = 5311210299Sed Args.MakeArgString(getToolChain().GetProgramPath("gas")); 5312212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5313198092Srdivacky} 5314198092Srdivacky 5315198092Srdivackyvoid auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, 5316212904Sdim const InputInfo &Output, 5317198893Srdivacky const InputInfoList &Inputs, 5318198893Srdivacky const ArgList &Args, 5319198893Srdivacky const char *LinkingOutput) const { 5320198092Srdivacky ArgStringList CmdArgs; 5321198092Srdivacky 5322198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 5323198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 5324198092Srdivacky CmdArgs.push_back("-e"); 5325198398Srdivacky CmdArgs.push_back("_start"); 5326198092Srdivacky } 5327198092Srdivacky 5328198092Srdivacky if (Args.hasArg(options::OPT_static)) { 5329198092Srdivacky CmdArgs.push_back("-Bstatic"); 5330198398Srdivacky CmdArgs.push_back("-dn"); 5331198092Srdivacky } else { 5332198398Srdivacky// CmdArgs.push_back("--eh-frame-hdr"); 5333198092Srdivacky CmdArgs.push_back("-Bdynamic"); 5334198092Srdivacky if (Args.hasArg(options::OPT_shared)) { 5335198092Srdivacky CmdArgs.push_back("-shared"); 5336198092Srdivacky } else { 5337198398Srdivacky CmdArgs.push_back("--dynamic-linker"); 5338198092Srdivacky CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1 5339198092Srdivacky } 5340198092Srdivacky } 5341198092Srdivacky 5342212904Sdim if (Output.isFilename()) { 5343198092Srdivacky CmdArgs.push_back("-o"); 5344198092Srdivacky CmdArgs.push_back(Output.getFilename()); 5345198092Srdivacky } else { 5346198092Srdivacky assert(Output.isNothing() && "Invalid output."); 5347198092Srdivacky } 5348198092Srdivacky 5349198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5350198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 5351198092Srdivacky if (!Args.hasArg(options::OPT_shared)) { 5352210299Sed CmdArgs.push_back(Args.MakeArgString( 5353210299Sed getToolChain().GetFilePath("crt1.o"))); 5354210299Sed CmdArgs.push_back(Args.MakeArgString( 5355210299Sed getToolChain().GetFilePath("crti.o"))); 5356210299Sed CmdArgs.push_back(Args.MakeArgString( 5357210299Sed getToolChain().GetFilePath("crtbegin.o"))); 5358198092Srdivacky } else { 5359210299Sed CmdArgs.push_back(Args.MakeArgString( 5360210299Sed getToolChain().GetFilePath("crti.o"))); 5361198092Srdivacky } 5362210299Sed CmdArgs.push_back(Args.MakeArgString( 5363210299Sed getToolChain().GetFilePath("crtn.o"))); 5364198092Srdivacky } 5365198092Srdivacky 5366198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/" 5367198893Srdivacky + getToolChain().getTripleString() 5368198893Srdivacky + "/4.2.4")); 5369198092Srdivacky 5370198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_L); 5371198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5372198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_e); 5373198092Srdivacky 5374218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5375198092Srdivacky 5376198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5377198092Srdivacky !Args.hasArg(options::OPT_nodefaultlibs)) { 5378198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 5379198092Srdivacky // the default system libraries. Just mimic this for now. 5380198092Srdivacky CmdArgs.push_back("-lgcc"); 5381198092Srdivacky 5382198092Srdivacky if (Args.hasArg(options::OPT_pthread)) 5383198092Srdivacky CmdArgs.push_back("-pthread"); 5384198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 5385198092Srdivacky CmdArgs.push_back("-lc"); 5386198092Srdivacky CmdArgs.push_back("-lgcc"); 5387198092Srdivacky } 5388198092Srdivacky 5389198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5390198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 5391198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 5392210299Sed CmdArgs.push_back(Args.MakeArgString( 5393210299Sed getToolChain().GetFilePath("crtend.o"))); 5394198092Srdivacky } 5395198092Srdivacky 5396224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 5397223017Sdim 5398198092Srdivacky const char *Exec = 5399210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5400212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5401198092Srdivacky} 5402198092Srdivacky 5403195341Sedvoid openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5404212904Sdim const InputInfo &Output, 5405195341Sed const InputInfoList &Inputs, 5406195341Sed const ArgList &Args, 5407198092Srdivacky const char *LinkingOutput) const { 5408195341Sed ArgStringList CmdArgs; 5409193326Sed 5410263508Sdim // When building 32-bit code on OpenBSD/amd64, we have to explicitly 5411263508Sdim // instruct as in the base system to assemble 32-bit code. 5412263508Sdim if (getToolChain().getArch() == llvm::Triple::x86) 5413263508Sdim CmdArgs.push_back("--32"); 5414263508Sdim else if (getToolChain().getArch() == llvm::Triple::ppc) { 5415263508Sdim CmdArgs.push_back("-mppc"); 5416263508Sdim CmdArgs.push_back("-many"); 5417263508Sdim } else if (getToolChain().getArch() == llvm::Triple::mips64 || 5418263508Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 5419263508Sdim StringRef CPUName; 5420263508Sdim StringRef ABIName; 5421263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 5422263508Sdim 5423263508Sdim CmdArgs.push_back("-mabi"); 5424263508Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 5425263508Sdim 5426263508Sdim if (getToolChain().getArch() == llvm::Triple::mips64) 5427263508Sdim CmdArgs.push_back("-EB"); 5428263508Sdim else 5429263508Sdim CmdArgs.push_back("-EL"); 5430263508Sdim 5431263508Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5432263508Sdim options::OPT_fpic, options::OPT_fno_pic, 5433263508Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5434263508Sdim options::OPT_fpie, options::OPT_fno_pie); 5435263508Sdim if (LastPICArg && 5436263508Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5437263508Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5438263508Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5439263508Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5440263508Sdim CmdArgs.push_back("-KPIC"); 5441263508Sdim } 5442263508Sdim } 5443263508Sdim 5444195341Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5445195341Sed options::OPT_Xassembler); 5446195341Sed 5447195341Sed CmdArgs.push_back("-o"); 5448212904Sdim CmdArgs.push_back(Output.getFilename()); 5449195341Sed 5450195341Sed for (InputInfoList::const_iterator 5451195341Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5452195341Sed const InputInfo &II = *it; 5453212904Sdim CmdArgs.push_back(II.getFilename()); 5454195341Sed } 5455195341Sed 5456195341Sed const char *Exec = 5457210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 5458212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5459195341Sed} 5460195341Sed 5461195341Sedvoid openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 5462212904Sdim const InputInfo &Output, 5463195341Sed const InputInfoList &Inputs, 5464195341Sed const ArgList &Args, 5465195341Sed const char *LinkingOutput) const { 5466201361Srdivacky const Driver &D = getToolChain().getDriver(); 5467195341Sed ArgStringList CmdArgs; 5468195341Sed 5469249423Sdim // Silence warning for "clang -g foo.o -o foo" 5470249423Sdim Args.ClaimAllArgs(options::OPT_g_Group); 5471249423Sdim // and "clang -emit-llvm foo.o -o foo" 5472249423Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 5473249423Sdim // and for "clang -w foo.o -o foo". Other warning options are already 5474249423Sdim // handled somewhere else. 5475249423Sdim Args.ClaimAllArgs(options::OPT_w); 5476249423Sdim 5477263508Sdim if (getToolChain().getArch() == llvm::Triple::mips64) 5478263508Sdim CmdArgs.push_back("-EB"); 5479263508Sdim else if (getToolChain().getArch() == llvm::Triple::mips64el) 5480263508Sdim CmdArgs.push_back("-EL"); 5481263508Sdim 5482198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 5483198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 5484198092Srdivacky CmdArgs.push_back("-e"); 5485198092Srdivacky CmdArgs.push_back("__start"); 5486198092Srdivacky } 5487198092Srdivacky 5488195341Sed if (Args.hasArg(options::OPT_static)) { 5489195341Sed CmdArgs.push_back("-Bstatic"); 5490195341Sed } else { 5491218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 5492218893Sdim CmdArgs.push_back("-export-dynamic"); 5493195341Sed CmdArgs.push_back("--eh-frame-hdr"); 5494198092Srdivacky CmdArgs.push_back("-Bdynamic"); 5495195341Sed if (Args.hasArg(options::OPT_shared)) { 5496198092Srdivacky CmdArgs.push_back("-shared"); 5497195341Sed } else { 5498195341Sed CmdArgs.push_back("-dynamic-linker"); 5499195341Sed CmdArgs.push_back("/usr/libexec/ld.so"); 5500195341Sed } 5501195341Sed } 5502195341Sed 5503263508Sdim if (Args.hasArg(options::OPT_nopie)) 5504263508Sdim CmdArgs.push_back("-nopie"); 5505263508Sdim 5506212904Sdim if (Output.isFilename()) { 5507195341Sed CmdArgs.push_back("-o"); 5508195341Sed CmdArgs.push_back(Output.getFilename()); 5509195341Sed } else { 5510195341Sed assert(Output.isNothing() && "Invalid output."); 5511195341Sed } 5512195341Sed 5513195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5514195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 5515195341Sed if (!Args.hasArg(options::OPT_shared)) { 5516234353Sdim if (Args.hasArg(options::OPT_pg)) 5517234353Sdim CmdArgs.push_back(Args.MakeArgString( 5518234353Sdim getToolChain().GetFilePath("gcrt0.o"))); 5519234353Sdim else 5520234353Sdim CmdArgs.push_back(Args.MakeArgString( 5521234353Sdim getToolChain().GetFilePath("crt0.o"))); 5522210299Sed CmdArgs.push_back(Args.MakeArgString( 5523210299Sed getToolChain().GetFilePath("crtbegin.o"))); 5524195341Sed } else { 5525210299Sed CmdArgs.push_back(Args.MakeArgString( 5526210299Sed getToolChain().GetFilePath("crtbeginS.o"))); 5527195341Sed } 5528195341Sed } 5529195341Sed 5530198893Srdivacky std::string Triple = getToolChain().getTripleString(); 5531198893Srdivacky if (Triple.substr(0, 6) == "x86_64") 5532198893Srdivacky Triple.replace(0, 6, "amd64"); 5533198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + 5534212904Sdim "/4.2.1")); 5535198092Srdivacky 5536195341Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5537195341Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5538195341Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 5539249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 5540249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 5541249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 5542249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5543195341Sed 5544218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5545195341Sed 5546195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5547195341Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 5548263508Sdim if (D.CCCIsCXX()) { 5549218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5550234353Sdim if (Args.hasArg(options::OPT_pg)) 5551234353Sdim CmdArgs.push_back("-lm_p"); 5552234353Sdim else 5553234353Sdim CmdArgs.push_back("-lm"); 5554212904Sdim } 5555212904Sdim 5556198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 5557198092Srdivacky // the default system libraries. Just mimic this for now. 5558198092Srdivacky CmdArgs.push_back("-lgcc"); 5559195341Sed 5560243830Sdim if (Args.hasArg(options::OPT_pthread)) { 5561243830Sdim if (!Args.hasArg(options::OPT_shared) && 5562243830Sdim Args.hasArg(options::OPT_pg)) 5563243830Sdim CmdArgs.push_back("-lpthread_p"); 5564243830Sdim else 5565243830Sdim CmdArgs.push_back("-lpthread"); 5566243830Sdim } 5567243830Sdim 5568234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5569243830Sdim if (Args.hasArg(options::OPT_pg)) 5570234353Sdim CmdArgs.push_back("-lc_p"); 5571234353Sdim else 5572234353Sdim CmdArgs.push_back("-lc"); 5573234353Sdim } 5574243830Sdim 5575198092Srdivacky CmdArgs.push_back("-lgcc"); 5576195341Sed } 5577195341Sed 5578195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5579195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 5580195341Sed if (!Args.hasArg(options::OPT_shared)) 5581210299Sed CmdArgs.push_back(Args.MakeArgString( 5582210299Sed getToolChain().GetFilePath("crtend.o"))); 5583195341Sed else 5584210299Sed CmdArgs.push_back(Args.MakeArgString( 5585210299Sed getToolChain().GetFilePath("crtendS.o"))); 5586195341Sed } 5587195341Sed 5588195341Sed const char *Exec = 5589210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5590212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5591195341Sed} 5592195341Sed 5593239462Sdimvoid bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5594239462Sdim const InputInfo &Output, 5595239462Sdim const InputInfoList &Inputs, 5596239462Sdim const ArgList &Args, 5597239462Sdim const char *LinkingOutput) const { 5598239462Sdim ArgStringList CmdArgs; 5599239462Sdim 5600239462Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5601239462Sdim options::OPT_Xassembler); 5602239462Sdim 5603239462Sdim CmdArgs.push_back("-o"); 5604239462Sdim CmdArgs.push_back(Output.getFilename()); 5605239462Sdim 5606239462Sdim for (InputInfoList::const_iterator 5607239462Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5608239462Sdim const InputInfo &II = *it; 5609239462Sdim CmdArgs.push_back(II.getFilename()); 5610239462Sdim } 5611239462Sdim 5612239462Sdim const char *Exec = 5613239462Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 5614239462Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5615239462Sdim} 5616239462Sdim 5617239462Sdimvoid bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, 5618239462Sdim const InputInfo &Output, 5619239462Sdim const InputInfoList &Inputs, 5620239462Sdim const ArgList &Args, 5621239462Sdim const char *LinkingOutput) const { 5622239462Sdim const Driver &D = getToolChain().getDriver(); 5623239462Sdim ArgStringList CmdArgs; 5624239462Sdim 5625239462Sdim if ((!Args.hasArg(options::OPT_nostdlib)) && 5626239462Sdim (!Args.hasArg(options::OPT_shared))) { 5627239462Sdim CmdArgs.push_back("-e"); 5628239462Sdim CmdArgs.push_back("__start"); 5629239462Sdim } 5630239462Sdim 5631239462Sdim if (Args.hasArg(options::OPT_static)) { 5632239462Sdim CmdArgs.push_back("-Bstatic"); 5633239462Sdim } else { 5634239462Sdim if (Args.hasArg(options::OPT_rdynamic)) 5635239462Sdim CmdArgs.push_back("-export-dynamic"); 5636239462Sdim CmdArgs.push_back("--eh-frame-hdr"); 5637239462Sdim CmdArgs.push_back("-Bdynamic"); 5638239462Sdim if (Args.hasArg(options::OPT_shared)) { 5639239462Sdim CmdArgs.push_back("-shared"); 5640239462Sdim } else { 5641239462Sdim CmdArgs.push_back("-dynamic-linker"); 5642239462Sdim CmdArgs.push_back("/usr/libexec/ld.so"); 5643239462Sdim } 5644239462Sdim } 5645239462Sdim 5646239462Sdim if (Output.isFilename()) { 5647239462Sdim CmdArgs.push_back("-o"); 5648239462Sdim CmdArgs.push_back(Output.getFilename()); 5649239462Sdim } else { 5650239462Sdim assert(Output.isNothing() && "Invalid output."); 5651239462Sdim } 5652239462Sdim 5653239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5654239462Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5655239462Sdim if (!Args.hasArg(options::OPT_shared)) { 5656239462Sdim if (Args.hasArg(options::OPT_pg)) 5657239462Sdim CmdArgs.push_back(Args.MakeArgString( 5658239462Sdim getToolChain().GetFilePath("gcrt0.o"))); 5659239462Sdim else 5660239462Sdim CmdArgs.push_back(Args.MakeArgString( 5661239462Sdim getToolChain().GetFilePath("crt0.o"))); 5662239462Sdim CmdArgs.push_back(Args.MakeArgString( 5663239462Sdim getToolChain().GetFilePath("crtbegin.o"))); 5664239462Sdim } else { 5665239462Sdim CmdArgs.push_back(Args.MakeArgString( 5666239462Sdim getToolChain().GetFilePath("crtbeginS.o"))); 5667239462Sdim } 5668239462Sdim } 5669239462Sdim 5670239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 5671239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5672239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 5673239462Sdim 5674239462Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5675239462Sdim 5676239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5677239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5678263508Sdim if (D.CCCIsCXX()) { 5679239462Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5680239462Sdim if (Args.hasArg(options::OPT_pg)) 5681239462Sdim CmdArgs.push_back("-lm_p"); 5682239462Sdim else 5683239462Sdim CmdArgs.push_back("-lm"); 5684239462Sdim } 5685239462Sdim 5686243830Sdim if (Args.hasArg(options::OPT_pthread)) { 5687243830Sdim if (!Args.hasArg(options::OPT_shared) && 5688243830Sdim Args.hasArg(options::OPT_pg)) 5689243830Sdim CmdArgs.push_back("-lpthread_p"); 5690243830Sdim else 5691243830Sdim CmdArgs.push_back("-lpthread"); 5692243830Sdim } 5693243830Sdim 5694239462Sdim if (!Args.hasArg(options::OPT_shared)) { 5695239462Sdim if (Args.hasArg(options::OPT_pg)) 5696239462Sdim CmdArgs.push_back("-lc_p"); 5697239462Sdim else 5698239462Sdim CmdArgs.push_back("-lc"); 5699239462Sdim } 5700239462Sdim 5701263508Sdim StringRef MyArch; 5702263508Sdim switch (getToolChain().getTriple().getArch()) { 5703263508Sdim case llvm::Triple::arm: 5704263508Sdim MyArch = "arm"; 5705263508Sdim break; 5706263508Sdim case llvm::Triple::x86: 5707263508Sdim MyArch = "i386"; 5708263508Sdim break; 5709263508Sdim case llvm::Triple::x86_64: 5710263508Sdim MyArch = "amd64"; 5711263508Sdim break; 5712263508Sdim default: 5713263508Sdim llvm_unreachable("Unsupported architecture"); 5714263508Sdim } 5715263508Sdim CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch)); 5716239462Sdim } 5717239462Sdim 5718239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5719239462Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5720239462Sdim if (!Args.hasArg(options::OPT_shared)) 5721239462Sdim CmdArgs.push_back(Args.MakeArgString( 5722239462Sdim getToolChain().GetFilePath("crtend.o"))); 5723239462Sdim else 5724239462Sdim CmdArgs.push_back(Args.MakeArgString( 5725239462Sdim getToolChain().GetFilePath("crtendS.o"))); 5726239462Sdim } 5727239462Sdim 5728239462Sdim const char *Exec = 5729239462Sdim Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5730239462Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5731239462Sdim} 5732239462Sdim 5733193326Sedvoid freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5734212904Sdim const InputInfo &Output, 5735193326Sed const InputInfoList &Inputs, 5736193326Sed const ArgList &Args, 5737198092Srdivacky const char *LinkingOutput) const { 5738193326Sed ArgStringList CmdArgs; 5739193326Sed 5740193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 5741193326Sed // instruct as in the base system to assemble 32-bit code. 5742243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) 5743193326Sed CmdArgs.push_back("--32"); 5744243830Sdim else if (getToolChain().getArch() == llvm::Triple::ppc) 5745223017Sdim CmdArgs.push_back("-a32"); 5746243830Sdim else if (getToolChain().getArch() == llvm::Triple::mips || 5747243830Sdim getToolChain().getArch() == llvm::Triple::mipsel || 5748243830Sdim getToolChain().getArch() == llvm::Triple::mips64 || 5749243830Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 5750243830Sdim StringRef CPUName; 5751243830Sdim StringRef ABIName; 5752263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 5753218893Sdim 5754243830Sdim CmdArgs.push_back("-march"); 5755243830Sdim CmdArgs.push_back(CPUName.data()); 5756204643Srdivacky 5757243830Sdim CmdArgs.push_back("-mabi"); 5758249423Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 5759243830Sdim 5760243830Sdim if (getToolChain().getArch() == llvm::Triple::mips || 5761243830Sdim getToolChain().getArch() == llvm::Triple::mips64) 5762243830Sdim CmdArgs.push_back("-EB"); 5763243830Sdim else 5764243830Sdim CmdArgs.push_back("-EL"); 5765243830Sdim 5766243830Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5767243830Sdim options::OPT_fpic, options::OPT_fno_pic, 5768243830Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5769243830Sdim options::OPT_fpie, options::OPT_fno_pie); 5770243830Sdim if (LastPICArg && 5771243830Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5772243830Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5773243830Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5774243830Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5775243830Sdim CmdArgs.push_back("-KPIC"); 5776243830Sdim } 5777244640Sandrew } else if (getToolChain().getArch() == llvm::Triple::arm || 5778244640Sandrew getToolChain().getArch() == llvm::Triple::thumb) { 5779244640Sandrew CmdArgs.push_back("-mfpu=softvfp"); 5780244640Sandrew switch(getToolChain().getTriple().getEnvironment()) { 5781244640Sandrew case llvm::Triple::GNUEABI: 5782244640Sandrew case llvm::Triple::EABI: 5783248548Sandrew CmdArgs.push_back("-meabi=5"); 5784244640Sandrew break; 5785244640Sandrew 5786244640Sandrew default: 5787244640Sandrew CmdArgs.push_back("-matpcs"); 5788244640Sandrew } 5789263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparc || 5790263763Sdim getToolChain().getArch() == llvm::Triple::sparcv9) { 5791263763Sdim if (getToolChain().getArch() == llvm::Triple::sparc) 5792263763Sdim CmdArgs.push_back("-Av8plusa"); 5793263763Sdim else 5794263763Sdim CmdArgs.push_back("-Av9a"); 5795263763Sdim 5796263763Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5797263763Sdim options::OPT_fpic, options::OPT_fno_pic, 5798263763Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5799263763Sdim options::OPT_fpie, options::OPT_fno_pie); 5800263763Sdim if (LastPICArg && 5801263763Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5802263763Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5803263763Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5804263763Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5805263763Sdim CmdArgs.push_back("-KPIC"); 5806263763Sdim } 5807243830Sdim } 5808243830Sdim 5809193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5810193326Sed options::OPT_Xassembler); 5811193326Sed 5812193326Sed CmdArgs.push_back("-o"); 5813212904Sdim CmdArgs.push_back(Output.getFilename()); 5814193326Sed 5815193326Sed for (InputInfoList::const_iterator 5816193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5817193326Sed const InputInfo &II = *it; 5818212904Sdim CmdArgs.push_back(II.getFilename()); 5819193326Sed } 5820193326Sed 5821193326Sed const char *Exec = 5822210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 5823212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5824193326Sed} 5825193326Sed 5826193326Sedvoid freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 5827212904Sdim const InputInfo &Output, 5828193326Sed const InputInfoList &Inputs, 5829193326Sed const ArgList &Args, 5830193326Sed const char *LinkingOutput) const { 5831243830Sdim const toolchains::FreeBSD& ToolChain = 5832243830Sdim static_cast<const toolchains::FreeBSD&>(getToolChain()); 5833243830Sdim const Driver &D = ToolChain.getDriver(); 5834193326Sed ArgStringList CmdArgs; 5835193326Sed 5836238864Sdim // Silence warning for "clang -g foo.o -o foo" 5837238864Sdim Args.ClaimAllArgs(options::OPT_g_Group); 5838238864Sdim // and "clang -emit-llvm foo.o -o foo" 5839238864Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 5840238864Sdim // and for "clang -w foo.o -o foo". Other warning options are already 5841238864Sdim // handled somewhere else. 5842238864Sdim Args.ClaimAllArgs(options::OPT_w); 5843238864Sdim 5844221345Sdim if (!D.SysRoot.empty()) 5845221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 5846221345Sdim 5847243830Sdim if (Args.hasArg(options::OPT_pie)) 5848243830Sdim CmdArgs.push_back("-pie"); 5849243830Sdim 5850193326Sed if (Args.hasArg(options::OPT_static)) { 5851193326Sed CmdArgs.push_back("-Bstatic"); 5852193326Sed } else { 5853218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 5854218893Sdim CmdArgs.push_back("-export-dynamic"); 5855193326Sed CmdArgs.push_back("--eh-frame-hdr"); 5856193326Sed if (Args.hasArg(options::OPT_shared)) { 5857193326Sed CmdArgs.push_back("-Bshareable"); 5858193326Sed } else { 5859193326Sed CmdArgs.push_back("-dynamic-linker"); 5860193326Sed CmdArgs.push_back("/libexec/ld-elf.so.1"); 5861193326Sed } 5862243830Sdim if (ToolChain.getTriple().getOSMajorVersion() >= 9) { 5863243830Sdim llvm::Triple::ArchType Arch = ToolChain.getArch(); 5864239462Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc || 5865239462Sdim Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { 5866239462Sdim CmdArgs.push_back("--hash-style=both"); 5867239462Sdim } 5868239462Sdim } 5869238863Sdim CmdArgs.push_back("--enable-new-dtags"); 5870193326Sed } 5871193326Sed 5872193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 5873193326Sed // instruct ld in the base system to link 32-bit code. 5874243830Sdim if (ToolChain.getArch() == llvm::Triple::x86) { 5875193326Sed CmdArgs.push_back("-m"); 5876193326Sed CmdArgs.push_back("elf_i386_fbsd"); 5877193326Sed } 5878193326Sed 5879243830Sdim if (ToolChain.getArch() == llvm::Triple::ppc) { 5880223017Sdim CmdArgs.push_back("-m"); 5881227739Sandreast CmdArgs.push_back("elf32ppc_fbsd"); 5882223017Sdim } 5883223017Sdim 5884212904Sdim if (Output.isFilename()) { 5885193326Sed CmdArgs.push_back("-o"); 5886193326Sed CmdArgs.push_back(Output.getFilename()); 5887193326Sed } else { 5888193326Sed assert(Output.isNothing() && "Invalid output."); 5889193326Sed } 5890193326Sed 5891193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 5892193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 5893243830Sdim const char *crt1 = NULL; 5894193326Sed if (!Args.hasArg(options::OPT_shared)) { 5895218893Sdim if (Args.hasArg(options::OPT_pg)) 5896243830Sdim crt1 = "gcrt1.o"; 5897243830Sdim else if (Args.hasArg(options::OPT_pie)) 5898243830Sdim crt1 = "Scrt1.o"; 5899243830Sdim else 5900243830Sdim crt1 = "crt1.o"; 5901193326Sed } 5902243830Sdim if (crt1) 5903243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); 5904243830Sdim 5905243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 5906243830Sdim 5907243830Sdim const char *crtbegin = NULL; 5908243830Sdim if (Args.hasArg(options::OPT_static)) 5909243830Sdim crtbegin = "crtbeginT.o"; 5910243830Sdim else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 5911243830Sdim crtbegin = "crtbeginS.o"; 5912243830Sdim else 5913243830Sdim crtbegin = "crtbegin.o"; 5914243830Sdim 5915243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 5916193326Sed } 5917193326Sed 5918193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5919243830Sdim const ToolChain::path_list Paths = ToolChain.getFilePaths(); 5920219011Sdim for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); 5921219011Sdim i != e; ++i) 5922226633Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 5923193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5924193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 5925212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 5926212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 5927212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 5928212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5929193326Sed 5930263508Sdim // Tell the linker to load the plugin. This has to come before AddLinkerInputs 5931263508Sdim // as gold requires -plugin to come before any -plugin-opt that -Wl might 5932263508Sdim // forward. 5933263508Sdim if (D.IsUsingLTO(Args)) { 5934263508Sdim CmdArgs.push_back("-plugin"); 5935263508Sdim std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; 5936263508Sdim CmdArgs.push_back(Args.MakeArgString(Plugin)); 5937263508Sdim 5938263508Sdim // Try to pass driver level flags relevant to LTO code generation down to 5939263508Sdim // the plugin. 5940263508Sdim 5941263508Sdim // Handle flags for selecting CPU variants. 5942263508Sdim std::string CPU = getCPUName(Args, ToolChain.getTriple()); 5943263508Sdim if (!CPU.empty()) { 5944263508Sdim CmdArgs.push_back( 5945263508Sdim Args.MakeArgString(Twine("-plugin-opt=mcpu=") + 5946263508Sdim CPU)); 5947263508Sdim } 5948263508Sdim } 5949263508Sdim 5950243830Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 5951218893Sdim 5952218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5953218893Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5954263508Sdim if (D.CCCIsCXX()) { 5955243830Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 5956218893Sdim if (Args.hasArg(options::OPT_pg)) 5957218893Sdim CmdArgs.push_back("-lm_p"); 5958218893Sdim else 5959218893Sdim CmdArgs.push_back("-lm"); 5960218893Sdim } 5961218893Sdim // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding 5962218893Sdim // the default system libraries. Just mimic this for now. 5963218893Sdim if (Args.hasArg(options::OPT_pg)) 5964218893Sdim CmdArgs.push_back("-lgcc_p"); 5965218893Sdim else 5966218893Sdim CmdArgs.push_back("-lgcc"); 5967218893Sdim if (Args.hasArg(options::OPT_static)) { 5968218893Sdim CmdArgs.push_back("-lgcc_eh"); 5969218893Sdim } else if (Args.hasArg(options::OPT_pg)) { 5970218893Sdim CmdArgs.push_back("-lgcc_eh_p"); 5971218893Sdim } else { 5972218893Sdim CmdArgs.push_back("--as-needed"); 5973218893Sdim CmdArgs.push_back("-lgcc_s"); 5974218893Sdim CmdArgs.push_back("--no-as-needed"); 5975218893Sdim } 5976218893Sdim 5977218893Sdim if (Args.hasArg(options::OPT_pthread)) { 5978218893Sdim if (Args.hasArg(options::OPT_pg)) 5979218893Sdim CmdArgs.push_back("-lpthread_p"); 5980218893Sdim else 5981218893Sdim CmdArgs.push_back("-lpthread"); 5982218893Sdim } 5983218893Sdim 5984218893Sdim if (Args.hasArg(options::OPT_pg)) { 5985218893Sdim if (Args.hasArg(options::OPT_shared)) 5986218893Sdim CmdArgs.push_back("-lc"); 5987218893Sdim else 5988218893Sdim CmdArgs.push_back("-lc_p"); 5989218893Sdim CmdArgs.push_back("-lgcc_p"); 5990218893Sdim } else { 5991218893Sdim CmdArgs.push_back("-lc"); 5992218893Sdim CmdArgs.push_back("-lgcc"); 5993218893Sdim } 5994218893Sdim 5995218893Sdim if (Args.hasArg(options::OPT_static)) { 5996218893Sdim CmdArgs.push_back("-lgcc_eh"); 5997218893Sdim } else if (Args.hasArg(options::OPT_pg)) { 5998218893Sdim CmdArgs.push_back("-lgcc_eh_p"); 5999218893Sdim } else { 6000218893Sdim CmdArgs.push_back("--as-needed"); 6001218893Sdim CmdArgs.push_back("-lgcc_s"); 6002218893Sdim CmdArgs.push_back("--no-as-needed"); 6003218893Sdim } 6004218893Sdim } 6005218893Sdim 6006218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6007218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6008243830Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6009243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); 6010218893Sdim else 6011243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 6012243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 6013218893Sdim } 6014218893Sdim 6015243830Sdim addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple()); 6016223017Sdim 6017218893Sdim const char *Exec = 6018243830Sdim Args.MakeArgString(ToolChain.GetProgramPath("ld")); 6019218893Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6020218893Sdim} 6021218893Sdim 6022218893Sdimvoid netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6023218893Sdim const InputInfo &Output, 6024218893Sdim const InputInfoList &Inputs, 6025218893Sdim const ArgList &Args, 6026218893Sdim const char *LinkingOutput) const { 6027218893Sdim ArgStringList CmdArgs; 6028218893Sdim 6029218893Sdim // When building 32-bit code on NetBSD/amd64, we have to explicitly 6030218893Sdim // instruct as in the base system to assemble 32-bit code. 6031234353Sdim if (getToolChain().getArch() == llvm::Triple::x86) 6032218893Sdim CmdArgs.push_back("--32"); 6033218893Sdim 6034263508Sdim // Pass the target CPU to GNU as for ARM, since the source code might 6035263508Sdim // not have the correct .cpu annotation. 6036263508Sdim if (getToolChain().getArch() == llvm::Triple::arm) { 6037263508Sdim std::string MArch(getARMTargetCPU(Args, getToolChain().getTriple())); 6038263508Sdim CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch)); 6039263508Sdim } 6040218893Sdim 6041263508Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6042263508Sdim getToolChain().getArch() == llvm::Triple::mipsel || 6043263508Sdim getToolChain().getArch() == llvm::Triple::mips64 || 6044263508Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 6045263508Sdim StringRef CPUName; 6046263508Sdim StringRef ABIName; 6047263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 6048263508Sdim 6049263508Sdim CmdArgs.push_back("-march"); 6050263508Sdim CmdArgs.push_back(CPUName.data()); 6051263508Sdim 6052263508Sdim CmdArgs.push_back("-mabi"); 6053263508Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 6054263508Sdim 6055263508Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6056263508Sdim getToolChain().getArch() == llvm::Triple::mips64) 6057263508Sdim CmdArgs.push_back("-EB"); 6058263508Sdim else 6059263508Sdim CmdArgs.push_back("-EL"); 6060263508Sdim 6061263508Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 6062263508Sdim options::OPT_fpic, options::OPT_fno_pic, 6063263508Sdim options::OPT_fPIE, options::OPT_fno_PIE, 6064263508Sdim options::OPT_fpie, options::OPT_fno_pie); 6065263508Sdim if (LastPICArg && 6066263508Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 6067263508Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 6068263508Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 6069263508Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 6070263508Sdim CmdArgs.push_back("-KPIC"); 6071263508Sdim } 6072263508Sdim } 6073263508Sdim 6074218893Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6075218893Sdim options::OPT_Xassembler); 6076218893Sdim 6077218893Sdim CmdArgs.push_back("-o"); 6078218893Sdim CmdArgs.push_back(Output.getFilename()); 6079218893Sdim 6080193326Sed for (InputInfoList::const_iterator 6081193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6082193326Sed const InputInfo &II = *it; 6083218893Sdim CmdArgs.push_back(II.getFilename()); 6084218893Sdim } 6085193326Sed 6086226633Sdim const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as"))); 6087218893Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6088218893Sdim} 6089193326Sed 6090218893Sdimvoid netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 6091218893Sdim const InputInfo &Output, 6092218893Sdim const InputInfoList &Inputs, 6093218893Sdim const ArgList &Args, 6094218893Sdim const char *LinkingOutput) const { 6095218893Sdim const Driver &D = getToolChain().getDriver(); 6096218893Sdim ArgStringList CmdArgs; 6097218893Sdim 6098221345Sdim if (!D.SysRoot.empty()) 6099221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6100221345Sdim 6101218893Sdim if (Args.hasArg(options::OPT_static)) { 6102218893Sdim CmdArgs.push_back("-Bstatic"); 6103218893Sdim } else { 6104218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 6105218893Sdim CmdArgs.push_back("-export-dynamic"); 6106218893Sdim CmdArgs.push_back("--eh-frame-hdr"); 6107218893Sdim if (Args.hasArg(options::OPT_shared)) { 6108218893Sdim CmdArgs.push_back("-Bshareable"); 6109218893Sdim } else { 6110218893Sdim CmdArgs.push_back("-dynamic-linker"); 6111218893Sdim CmdArgs.push_back("/libexec/ld.elf_so"); 6112218893Sdim } 6113193326Sed } 6114193326Sed 6115218893Sdim // When building 32-bit code on NetBSD/amd64, we have to explicitly 6116218893Sdim // instruct ld in the base system to link 32-bit code. 6117234353Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6118218893Sdim CmdArgs.push_back("-m"); 6119218893Sdim CmdArgs.push_back("elf_i386"); 6120218893Sdim } 6121218893Sdim 6122218893Sdim if (Output.isFilename()) { 6123218893Sdim CmdArgs.push_back("-o"); 6124218893Sdim CmdArgs.push_back(Output.getFilename()); 6125218893Sdim } else { 6126218893Sdim assert(Output.isNothing() && "Invalid output."); 6127218893Sdim } 6128218893Sdim 6129193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6130218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6131218893Sdim if (!Args.hasArg(options::OPT_shared)) { 6132218893Sdim CmdArgs.push_back(Args.MakeArgString( 6133218893Sdim getToolChain().GetFilePath("crt0.o"))); 6134218893Sdim CmdArgs.push_back(Args.MakeArgString( 6135218893Sdim getToolChain().GetFilePath("crti.o"))); 6136218893Sdim CmdArgs.push_back(Args.MakeArgString( 6137218893Sdim getToolChain().GetFilePath("crtbegin.o"))); 6138218893Sdim } else { 6139218893Sdim CmdArgs.push_back(Args.MakeArgString( 6140218893Sdim getToolChain().GetFilePath("crti.o"))); 6141218893Sdim CmdArgs.push_back(Args.MakeArgString( 6142218893Sdim getToolChain().GetFilePath("crtbeginS.o"))); 6143218893Sdim } 6144218893Sdim } 6145218893Sdim 6146218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 6147218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6148218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 6149218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 6150218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 6151218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 6152218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 6153218893Sdim 6154218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6155218893Sdim 6156263508Sdim unsigned Major, Minor, Micro; 6157263508Sdim getToolChain().getTriple().getOSVersion(Major, Minor, Micro); 6158263508Sdim bool useLibgcc = true; 6159263508Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 6160263508Sdim if (getToolChain().getArch() == llvm::Triple::x86 || 6161263508Sdim getToolChain().getArch() == llvm::Triple::x86_64) 6162263508Sdim useLibgcc = false; 6163263508Sdim } 6164263508Sdim 6165218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6166193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6167263508Sdim if (D.CCCIsCXX()) { 6168218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6169204643Srdivacky CmdArgs.push_back("-lm"); 6170204643Srdivacky } 6171193326Sed if (Args.hasArg(options::OPT_pthread)) 6172193326Sed CmdArgs.push_back("-lpthread"); 6173193326Sed CmdArgs.push_back("-lc"); 6174193326Sed 6175263508Sdim if (useLibgcc) { 6176263508Sdim if (Args.hasArg(options::OPT_static)) { 6177263508Sdim // libgcc_eh depends on libc, so resolve as much as possible, 6178263508Sdim // pull in any new requirements from libc and then get the rest 6179263508Sdim // of libgcc. 6180263508Sdim CmdArgs.push_back("-lgcc_eh"); 6181263508Sdim CmdArgs.push_back("-lc"); 6182263508Sdim CmdArgs.push_back("-lgcc"); 6183263508Sdim } else { 6184263508Sdim CmdArgs.push_back("-lgcc"); 6185263508Sdim CmdArgs.push_back("--as-needed"); 6186263508Sdim CmdArgs.push_back("-lgcc_s"); 6187263508Sdim CmdArgs.push_back("--no-as-needed"); 6188263508Sdim } 6189193326Sed } 6190193326Sed } 6191193326Sed 6192193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6193193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6194193326Sed if (!Args.hasArg(options::OPT_shared)) 6195210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6196210299Sed "crtend.o"))); 6197193326Sed else 6198210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6199210299Sed "crtendS.o"))); 6200210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6201210299Sed "crtn.o"))); 6202193326Sed } 6203193326Sed 6204224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6205223017Sdim 6206226633Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6207212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6208193326Sed} 6209193326Sed 6210249423Sdimvoid gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6211249423Sdim const InputInfo &Output, 6212249423Sdim const InputInfoList &Inputs, 6213249423Sdim const ArgList &Args, 6214249423Sdim const char *LinkingOutput) const { 6215212904Sdim ArgStringList CmdArgs; 6216263763Sdim bool NeedsKPIC = false; 6217212904Sdim 6218212904Sdim // Add --32/--64 to make sure we get the format we want. 6219212904Sdim // This is incomplete 6220212904Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6221212904Sdim CmdArgs.push_back("--32"); 6222212904Sdim } else if (getToolChain().getArch() == llvm::Triple::x86_64) { 6223212904Sdim CmdArgs.push_back("--64"); 6224234353Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc) { 6225234353Sdim CmdArgs.push_back("-a32"); 6226234353Sdim CmdArgs.push_back("-mppc"); 6227234353Sdim CmdArgs.push_back("-many"); 6228234353Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc64) { 6229234353Sdim CmdArgs.push_back("-a64"); 6230234353Sdim CmdArgs.push_back("-mppc64"); 6231234353Sdim CmdArgs.push_back("-many"); 6232263508Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc64le) { 6233263508Sdim CmdArgs.push_back("-a64"); 6234263508Sdim CmdArgs.push_back("-mppc64le"); 6235263508Sdim CmdArgs.push_back("-many"); 6236263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparc) { 6237263763Sdim CmdArgs.push_back("-32"); 6238263763Sdim CmdArgs.push_back("-Av8plusa"); 6239263763Sdim NeedsKPIC = true; 6240263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparcv9) { 6241263763Sdim CmdArgs.push_back("-64"); 6242263763Sdim CmdArgs.push_back("-Av9a"); 6243263763Sdim NeedsKPIC = true; 6244212904Sdim } else if (getToolChain().getArch() == llvm::Triple::arm) { 6245226633Sdim StringRef MArch = getToolChain().getArchName(); 6246212904Sdim if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") 6247212904Sdim CmdArgs.push_back("-mfpu=neon"); 6248263508Sdim if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a") 6249263508Sdim CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8"); 6250239462Sdim 6251239462Sdim StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args, 6252239462Sdim getToolChain().getTriple()); 6253239462Sdim CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI)); 6254239462Sdim 6255239462Sdim Args.AddLastArg(CmdArgs, options::OPT_march_EQ); 6256239462Sdim Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); 6257239462Sdim Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); 6258234353Sdim } else if (getToolChain().getArch() == llvm::Triple::mips || 6259234353Sdim getToolChain().getArch() == llvm::Triple::mipsel || 6260234353Sdim getToolChain().getArch() == llvm::Triple::mips64 || 6261234353Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 6262234353Sdim StringRef CPUName; 6263234353Sdim StringRef ABIName; 6264263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 6265234353Sdim 6266234353Sdim CmdArgs.push_back("-march"); 6267234353Sdim CmdArgs.push_back(CPUName.data()); 6268234353Sdim 6269234353Sdim CmdArgs.push_back("-mabi"); 6270249423Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 6271234353Sdim 6272234353Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6273234353Sdim getToolChain().getArch() == llvm::Triple::mips64) 6274234353Sdim CmdArgs.push_back("-EB"); 6275234353Sdim else 6276234353Sdim CmdArgs.push_back("-EL"); 6277239462Sdim 6278263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 6279263508Sdim if (StringRef(A->getValue()) == "2008") 6280263508Sdim CmdArgs.push_back(Args.MakeArgString("-mnan=2008")); 6281263508Sdim } 6282263508Sdim 6283263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfp64)) { 6284263508Sdim if (A->getOption().matches(options::OPT_mfp32)) 6285263508Sdim CmdArgs.push_back(Args.MakeArgString("-mfp32")); 6286263508Sdim else 6287263508Sdim CmdArgs.push_back(Args.MakeArgString("-mfp64")); 6288263508Sdim } 6289263508Sdim 6290251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16); 6291251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mmicromips, 6292251662Sdim options::OPT_mno_micromips); 6293251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp); 6294251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2); 6295251662Sdim 6296263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) { 6297263508Sdim // Do not use AddLastArg because not all versions of MIPS assembler 6298263508Sdim // support -mmsa / -mno-msa options. 6299263508Sdim if (A->getOption().matches(options::OPT_mmsa)) 6300263508Sdim CmdArgs.push_back(Args.MakeArgString("-mmsa")); 6301263508Sdim } 6302263508Sdim 6303263763Sdim NeedsKPIC = true; 6304263763Sdim } else if (getToolChain().getArch() == llvm::Triple::systemz) { 6305263763Sdim // Always pass an -march option, since our default of z10 is later 6306263763Sdim // than the GNU assembler's default. 6307263763Sdim StringRef CPUName = getSystemZTargetCPU(Args); 6308263763Sdim CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); 6309263763Sdim } 6310263763Sdim 6311263763Sdim if (NeedsKPIC) { 6312239462Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 6313239462Sdim options::OPT_fpic, options::OPT_fno_pic, 6314239462Sdim options::OPT_fPIE, options::OPT_fno_PIE, 6315239462Sdim options::OPT_fpie, options::OPT_fno_pie); 6316239462Sdim if (LastPICArg && 6317239462Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 6318239462Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 6319239462Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 6320239462Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 6321239462Sdim CmdArgs.push_back("-KPIC"); 6322239462Sdim } 6323212904Sdim } 6324212904Sdim 6325212904Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6326212904Sdim options::OPT_Xassembler); 6327212904Sdim 6328212904Sdim CmdArgs.push_back("-o"); 6329212904Sdim CmdArgs.push_back(Output.getFilename()); 6330212904Sdim 6331212904Sdim for (InputInfoList::const_iterator 6332212904Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6333212904Sdim const InputInfo &II = *it; 6334212904Sdim CmdArgs.push_back(II.getFilename()); 6335212904Sdim } 6336212904Sdim 6337212904Sdim const char *Exec = 6338212904Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 6339212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6340263508Sdim 6341263508Sdim // Handle the debug info splitting at object creation time if we're 6342263508Sdim // creating an object. 6343263508Sdim // TODO: Currently only works on linux with newer objcopy. 6344263508Sdim if (Args.hasArg(options::OPT_gsplit_dwarf) && 6345263508Sdim getToolChain().getTriple().isOSLinux()) 6346263508Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, 6347263508Sdim SplitDebugName(Args, Inputs)); 6348212904Sdim} 6349212904Sdim 6350239462Sdimstatic void AddLibgcc(llvm::Triple Triple, const Driver &D, 6351239462Sdim ArgStringList &CmdArgs, const ArgList &Args) { 6352243830Sdim bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android; 6353249423Sdim bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) || 6354249423Sdim Args.hasArg(options::OPT_static); 6355263508Sdim if (!D.CCCIsCXX()) 6356234353Sdim CmdArgs.push_back("-lgcc"); 6357234353Sdim 6358249423Sdim if (StaticLibgcc || isAndroid) { 6359263508Sdim if (D.CCCIsCXX()) 6360234353Sdim CmdArgs.push_back("-lgcc"); 6361234353Sdim } else { 6362263508Sdim if (!D.CCCIsCXX()) 6363234353Sdim CmdArgs.push_back("--as-needed"); 6364234353Sdim CmdArgs.push_back("-lgcc_s"); 6365263508Sdim if (!D.CCCIsCXX()) 6366234353Sdim CmdArgs.push_back("--no-as-needed"); 6367234353Sdim } 6368234353Sdim 6369239462Sdim if (StaticLibgcc && !isAndroid) 6370234353Sdim CmdArgs.push_back("-lgcc_eh"); 6371263508Sdim else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX()) 6372234353Sdim CmdArgs.push_back("-lgcc"); 6373249423Sdim 6374249423Sdim // According to Android ABI, we have to link with libdl if we are 6375249423Sdim // linking with non-static libgcc. 6376249423Sdim // 6377249423Sdim // NOTE: This fixes a link error on Android MIPS as well. The non-static 6378249423Sdim // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl. 6379249423Sdim if (isAndroid && !StaticLibgcc) 6380249423Sdim CmdArgs.push_back("-ldl"); 6381234353Sdim} 6382234353Sdim 6383243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 6384243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 6385243830Sdim return A && (A->getValue() == StringRef("n32")); 6386243830Sdim} 6387243830Sdim 6388263508Sdimstatic StringRef getLinuxDynamicLinker(const ArgList &Args, 6389263508Sdim const toolchains::Linux &ToolChain) { 6390263508Sdim if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) 6391263508Sdim return "/system/bin/linker"; 6392263763Sdim else if (ToolChain.getArch() == llvm::Triple::x86 || 6393263763Sdim ToolChain.getArch() == llvm::Triple::sparc) 6394263508Sdim return "/lib/ld-linux.so.2"; 6395263508Sdim else if (ToolChain.getArch() == llvm::Triple::aarch64) 6396263508Sdim return "/lib/ld-linux-aarch64.so.1"; 6397263508Sdim else if (ToolChain.getArch() == llvm::Triple::arm || 6398263508Sdim ToolChain.getArch() == llvm::Triple::thumb) { 6399263508Sdim if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 6400263508Sdim return "/lib/ld-linux-armhf.so.3"; 6401263508Sdim else 6402263508Sdim return "/lib/ld-linux.so.3"; 6403263508Sdim } else if (ToolChain.getArch() == llvm::Triple::mips || 6404263508Sdim ToolChain.getArch() == llvm::Triple::mipsel) 6405263508Sdim return "/lib/ld.so.1"; 6406263508Sdim else if (ToolChain.getArch() == llvm::Triple::mips64 || 6407263508Sdim ToolChain.getArch() == llvm::Triple::mips64el) { 6408263508Sdim if (hasMipsN32ABIArg(Args)) 6409263508Sdim return "/lib32/ld.so.1"; 6410263508Sdim else 6411263508Sdim return "/lib64/ld.so.1"; 6412263508Sdim } else if (ToolChain.getArch() == llvm::Triple::ppc) 6413263508Sdim return "/lib/ld.so.1"; 6414263508Sdim else if (ToolChain.getArch() == llvm::Triple::ppc64 || 6415263508Sdim ToolChain.getArch() == llvm::Triple::ppc64le || 6416263508Sdim ToolChain.getArch() == llvm::Triple::systemz) 6417263508Sdim return "/lib64/ld64.so.1"; 6418263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparcv9) 6419263763Sdim return "/lib64/ld-linux.so.2"; 6420263508Sdim else 6421263508Sdim return "/lib64/ld-linux-x86-64.so.2"; 6422263508Sdim} 6423263508Sdim 6424249423Sdimvoid gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, 6425249423Sdim const InputInfo &Output, 6426249423Sdim const InputInfoList &Inputs, 6427249423Sdim const ArgList &Args, 6428249423Sdim const char *LinkingOutput) const { 6429218893Sdim const toolchains::Linux& ToolChain = 6430218893Sdim static_cast<const toolchains::Linux&>(getToolChain()); 6431218893Sdim const Driver &D = ToolChain.getDriver(); 6432243830Sdim const bool isAndroid = 6433243830Sdim ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; 6434263508Sdim const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs(); 6435251662Sdim const bool IsPIE = 6436251662Sdim !Args.hasArg(options::OPT_shared) && 6437251662Sdim (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow()); 6438239462Sdim 6439218893Sdim ArgStringList CmdArgs; 6440212904Sdim 6441218893Sdim // Silence warning for "clang -g foo.o -o foo" 6442218893Sdim Args.ClaimAllArgs(options::OPT_g_Group); 6443221345Sdim // and "clang -emit-llvm foo.o -o foo" 6444221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 6445239462Sdim // and for "clang -w foo.o -o foo". Other warning options are already 6446218893Sdim // handled somewhere else. 6447218893Sdim Args.ClaimAllArgs(options::OPT_w); 6448218893Sdim 6449221345Sdim if (!D.SysRoot.empty()) 6450221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6451218893Sdim 6452251662Sdim if (IsPIE) 6453218893Sdim CmdArgs.push_back("-pie"); 6454218893Sdim 6455218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 6456218893Sdim CmdArgs.push_back("-export-dynamic"); 6457218893Sdim 6458218893Sdim if (Args.hasArg(options::OPT_s)) 6459218893Sdim CmdArgs.push_back("-s"); 6460218893Sdim 6461218893Sdim for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), 6462218893Sdim e = ToolChain.ExtraOpts.end(); 6463218893Sdim i != e; ++i) 6464218893Sdim CmdArgs.push_back(i->c_str()); 6465218893Sdim 6466218893Sdim if (!Args.hasArg(options::OPT_static)) { 6467218893Sdim CmdArgs.push_back("--eh-frame-hdr"); 6468218893Sdim } 6469218893Sdim 6470218893Sdim CmdArgs.push_back("-m"); 6471218893Sdim if (ToolChain.getArch() == llvm::Triple::x86) 6472218893Sdim CmdArgs.push_back("elf_i386"); 6473249423Sdim else if (ToolChain.getArch() == llvm::Triple::aarch64) 6474249423Sdim CmdArgs.push_back("aarch64linux"); 6475226633Sdim else if (ToolChain.getArch() == llvm::Triple::arm 6476221345Sdim || ToolChain.getArch() == llvm::Triple::thumb) 6477218893Sdim CmdArgs.push_back("armelf_linux_eabi"); 6478221345Sdim else if (ToolChain.getArch() == llvm::Triple::ppc) 6479221345Sdim CmdArgs.push_back("elf32ppclinux"); 6480221345Sdim else if (ToolChain.getArch() == llvm::Triple::ppc64) 6481221345Sdim CmdArgs.push_back("elf64ppc"); 6482263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparc) 6483263763Sdim CmdArgs.push_back("elf32_sparc"); 6484263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparcv9) 6485263763Sdim CmdArgs.push_back("elf64_sparc"); 6486234353Sdim else if (ToolChain.getArch() == llvm::Triple::mips) 6487234353Sdim CmdArgs.push_back("elf32btsmip"); 6488234353Sdim else if (ToolChain.getArch() == llvm::Triple::mipsel) 6489234353Sdim CmdArgs.push_back("elf32ltsmip"); 6490243830Sdim else if (ToolChain.getArch() == llvm::Triple::mips64) { 6491243830Sdim if (hasMipsN32ABIArg(Args)) 6492243830Sdim CmdArgs.push_back("elf32btsmipn32"); 6493243830Sdim else 6494243830Sdim CmdArgs.push_back("elf64btsmip"); 6495243830Sdim } 6496243830Sdim else if (ToolChain.getArch() == llvm::Triple::mips64el) { 6497243830Sdim if (hasMipsN32ABIArg(Args)) 6498243830Sdim CmdArgs.push_back("elf32ltsmipn32"); 6499243830Sdim else 6500243830Sdim CmdArgs.push_back("elf64ltsmip"); 6501243830Sdim } 6502251662Sdim else if (ToolChain.getArch() == llvm::Triple::systemz) 6503251662Sdim CmdArgs.push_back("elf64_s390"); 6504218893Sdim else 6505218893Sdim CmdArgs.push_back("elf_x86_64"); 6506218893Sdim 6507218893Sdim if (Args.hasArg(options::OPT_static)) { 6508221345Sdim if (ToolChain.getArch() == llvm::Triple::arm 6509221345Sdim || ToolChain.getArch() == llvm::Triple::thumb) 6510218893Sdim CmdArgs.push_back("-Bstatic"); 6511218893Sdim else 6512218893Sdim CmdArgs.push_back("-static"); 6513218893Sdim } else if (Args.hasArg(options::OPT_shared)) { 6514218893Sdim CmdArgs.push_back("-shared"); 6515243830Sdim if (isAndroid) { 6516239462Sdim CmdArgs.push_back("-Bsymbolic"); 6517239462Sdim } 6518218893Sdim } 6519218893Sdim 6520218893Sdim if (ToolChain.getArch() == llvm::Triple::arm || 6521221345Sdim ToolChain.getArch() == llvm::Triple::thumb || 6522218893Sdim (!Args.hasArg(options::OPT_static) && 6523218893Sdim !Args.hasArg(options::OPT_shared))) { 6524218893Sdim CmdArgs.push_back("-dynamic-linker"); 6525263508Sdim CmdArgs.push_back(Args.MakeArgString( 6526263508Sdim D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain))); 6527218893Sdim } 6528218893Sdim 6529218893Sdim CmdArgs.push_back("-o"); 6530218893Sdim CmdArgs.push_back(Output.getFilename()); 6531218893Sdim 6532218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6533218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6534239462Sdim if (!isAndroid) { 6535239462Sdim const char *crt1 = NULL; 6536239462Sdim if (!Args.hasArg(options::OPT_shared)){ 6537263508Sdim if (Args.hasArg(options::OPT_pg)) 6538263508Sdim crt1 = "gcrt1.o"; 6539263508Sdim else if (IsPIE) 6540239462Sdim crt1 = "Scrt1.o"; 6541239462Sdim else 6542239462Sdim crt1 = "crt1.o"; 6543239462Sdim } 6544239462Sdim if (crt1) 6545239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); 6546239462Sdim 6547239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 6548218893Sdim } 6549218893Sdim 6550218893Sdim const char *crtbegin; 6551218893Sdim if (Args.hasArg(options::OPT_static)) 6552239462Sdim crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; 6553243830Sdim else if (Args.hasArg(options::OPT_shared)) 6554239462Sdim crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; 6555251662Sdim else if (IsPIE) 6556243830Sdim crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; 6557218893Sdim else 6558239462Sdim crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; 6559218893Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 6560243830Sdim 6561243830Sdim // Add crtfastmath.o if available and fast math is enabled. 6562243830Sdim ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs); 6563218893Sdim } 6564218893Sdim 6565218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 6566218893Sdim 6567218893Sdim const ToolChain::path_list Paths = ToolChain.getFilePaths(); 6568221345Sdim 6569219011Sdim for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); 6570219011Sdim i != e; ++i) 6571226633Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 6572218893Sdim 6573234353Sdim // Tell the linker to load the plugin. This has to come before AddLinkerInputs 6574234353Sdim // as gold requires -plugin to come before any -plugin-opt that -Wl might 6575234353Sdim // forward. 6576263508Sdim if (D.IsUsingLTO(Args)) { 6577234353Sdim CmdArgs.push_back("-plugin"); 6578234353Sdim std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; 6579234353Sdim CmdArgs.push_back(Args.MakeArgString(Plugin)); 6580247166Sdim 6581247166Sdim // Try to pass driver level flags relevant to LTO code generation down to 6582247166Sdim // the plugin. 6583247166Sdim 6584263508Sdim // Handle flags for selecting CPU variants. 6585263508Sdim std::string CPU = getCPUName(Args, ToolChain.getTriple()); 6586263508Sdim if (!CPU.empty()) { 6587247166Sdim CmdArgs.push_back( 6588263508Sdim Args.MakeArgString(Twine("-plugin-opt=mcpu=") + 6589263508Sdim CPU)); 6590263508Sdim } 6591234353Sdim } 6592234353Sdim 6593247166Sdim 6594239462Sdim if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 6595239462Sdim CmdArgs.push_back("--no-demangle"); 6596239462Sdim 6597218893Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 6598218893Sdim 6599249423Sdim // Call these before we add the C++ ABI library. 6600243830Sdim if (Sanitize.needsUbsanRt()) 6601263508Sdim addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(), 6602249423Sdim Sanitize.needsAsanRt() || Sanitize.needsTsanRt() || 6603263508Sdim Sanitize.needsMsanRt() || Sanitize.needsLsanRt()); 6604249423Sdim if (Sanitize.needsAsanRt()) 6605249423Sdim addAsanRTLinux(getToolChain(), Args, CmdArgs); 6606249423Sdim if (Sanitize.needsTsanRt()) 6607249423Sdim addTsanRTLinux(getToolChain(), Args, CmdArgs); 6608249423Sdim if (Sanitize.needsMsanRt()) 6609249423Sdim addMsanRTLinux(getToolChain(), Args, CmdArgs); 6610263508Sdim if (Sanitize.needsLsanRt()) 6611263508Sdim addLsanRTLinux(getToolChain(), Args, CmdArgs); 6612263508Sdim if (Sanitize.needsDfsanRt()) 6613263508Sdim addDfsanRTLinux(getToolChain(), Args, CmdArgs); 6614243830Sdim 6615263508Sdim // The profile runtime also needs access to system libraries. 6616263508Sdim addProfileRTLinux(getToolChain(), Args, CmdArgs); 6617263508Sdim 6618263508Sdim if (D.CCCIsCXX() && 6619239462Sdim !Args.hasArg(options::OPT_nostdlib) && 6620239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 6621234353Sdim bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && 6622234353Sdim !Args.hasArg(options::OPT_static); 6623234353Sdim if (OnlyLibstdcxxStatic) 6624234353Sdim CmdArgs.push_back("-Bstatic"); 6625218893Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 6626234353Sdim if (OnlyLibstdcxxStatic) 6627234353Sdim CmdArgs.push_back("-Bdynamic"); 6628218893Sdim CmdArgs.push_back("-lm"); 6629218893Sdim } 6630218893Sdim 6631223017Sdim if (!Args.hasArg(options::OPT_nostdlib)) { 6632239462Sdim if (!Args.hasArg(options::OPT_nodefaultlibs)) { 6633239462Sdim if (Args.hasArg(options::OPT_static)) 6634239462Sdim CmdArgs.push_back("--start-group"); 6635218893Sdim 6636249423Sdim bool OpenMP = Args.hasArg(options::OPT_fopenmp); 6637249423Sdim if (OpenMP) { 6638249423Sdim CmdArgs.push_back("-lgomp"); 6639249423Sdim 6640249423Sdim // FIXME: Exclude this for platforms whith libgomp that doesn't require 6641249423Sdim // librt. Most modern Linux platfroms require it, but some may not. 6642249423Sdim CmdArgs.push_back("-lrt"); 6643249423Sdim } 6644249423Sdim 6645239462Sdim AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args); 6646218893Sdim 6647239462Sdim if (Args.hasArg(options::OPT_pthread) || 6648249423Sdim Args.hasArg(options::OPT_pthreads) || OpenMP) 6649239462Sdim CmdArgs.push_back("-lpthread"); 6650218893Sdim 6651239462Sdim CmdArgs.push_back("-lc"); 6652218893Sdim 6653239462Sdim if (Args.hasArg(options::OPT_static)) 6654239462Sdim CmdArgs.push_back("--end-group"); 6655239462Sdim else 6656239462Sdim AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args); 6657239462Sdim } 6658218893Sdim 6659218893Sdim if (!Args.hasArg(options::OPT_nostartfiles)) { 6660218893Sdim const char *crtend; 6661243830Sdim if (Args.hasArg(options::OPT_shared)) 6662239462Sdim crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; 6663251662Sdim else if (IsPIE) 6664243830Sdim crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; 6665218893Sdim else 6666239462Sdim crtend = isAndroid ? "crtend_android.o" : "crtend.o"; 6667218893Sdim 6668218893Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); 6669239462Sdim if (!isAndroid) 6670239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 6671218893Sdim } 6672218893Sdim } 6673218893Sdim 6674218893Sdim C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); 6675218893Sdim} 6676218893Sdim 6677210299Sedvoid minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6678212904Sdim const InputInfo &Output, 6679212904Sdim const InputInfoList &Inputs, 6680212904Sdim const ArgList &Args, 6681212904Sdim const char *LinkingOutput) const { 6682210299Sed ArgStringList CmdArgs; 6683210299Sed 6684210299Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6685210299Sed options::OPT_Xassembler); 6686210299Sed 6687210299Sed CmdArgs.push_back("-o"); 6688212904Sdim CmdArgs.push_back(Output.getFilename()); 6689210299Sed 6690210299Sed for (InputInfoList::const_iterator 6691210299Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6692210299Sed const InputInfo &II = *it; 6693212904Sdim CmdArgs.push_back(II.getFilename()); 6694210299Sed } 6695210299Sed 6696210299Sed const char *Exec = 6697234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 6698212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6699210299Sed} 6700210299Sed 6701210299Sedvoid minix::Link::ConstructJob(Compilation &C, const JobAction &JA, 6702212904Sdim const InputInfo &Output, 6703212904Sdim const InputInfoList &Inputs, 6704212904Sdim const ArgList &Args, 6705212904Sdim const char *LinkingOutput) const { 6706210299Sed const Driver &D = getToolChain().getDriver(); 6707210299Sed ArgStringList CmdArgs; 6708210299Sed 6709212904Sdim if (Output.isFilename()) { 6710210299Sed CmdArgs.push_back("-o"); 6711210299Sed CmdArgs.push_back(Output.getFilename()); 6712210299Sed } else { 6713210299Sed assert(Output.isNothing() && "Invalid output."); 6714210299Sed } 6715210299Sed 6716210299Sed if (!Args.hasArg(options::OPT_nostdlib) && 6717234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6718234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); 6719234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); 6720234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); 6721234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); 6722234353Sdim } 6723210299Sed 6724210299Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 6725210299Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6726210299Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 6727210299Sed 6728218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6729210299Sed 6730234353Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6731234353Sdim 6732210299Sed if (!Args.hasArg(options::OPT_nostdlib) && 6733210299Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6734263508Sdim if (D.CCCIsCXX()) { 6735218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6736210299Sed CmdArgs.push_back("-lm"); 6737210299Sed } 6738234353Sdim } 6739210299Sed 6740234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6741234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6742210299Sed if (Args.hasArg(options::OPT_pthread)) 6743210299Sed CmdArgs.push_back("-lpthread"); 6744210299Sed CmdArgs.push_back("-lc"); 6745234353Sdim CmdArgs.push_back("-lCompilerRT-Generic"); 6746234353Sdim CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib"); 6747234353Sdim CmdArgs.push_back( 6748249423Sdim Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); 6749210299Sed } 6750210299Sed 6751234353Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6752212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6753210299Sed} 6754210299Sed 6755193326Sed/// DragonFly Tools 6756193326Sed 6757193326Sed// For now, DragonFly Assemble does just about the same as for 6758193326Sed// FreeBSD, but this may change soon. 6759193326Sedvoid dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6760212904Sdim const InputInfo &Output, 6761198893Srdivacky const InputInfoList &Inputs, 6762198893Srdivacky const ArgList &Args, 6763198893Srdivacky const char *LinkingOutput) const { 6764193326Sed ArgStringList CmdArgs; 6765193326Sed 6766193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 6767193326Sed // instruct as in the base system to assemble 32-bit code. 6768243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) 6769193326Sed CmdArgs.push_back("--32"); 6770193326Sed 6771193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6772193326Sed options::OPT_Xassembler); 6773193326Sed 6774193326Sed CmdArgs.push_back("-o"); 6775212904Sdim CmdArgs.push_back(Output.getFilename()); 6776193326Sed 6777193326Sed for (InputInfoList::const_iterator 6778193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6779193326Sed const InputInfo &II = *it; 6780212904Sdim CmdArgs.push_back(II.getFilename()); 6781193326Sed } 6782193326Sed 6783193326Sed const char *Exec = 6784210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 6785212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6786193326Sed} 6787193326Sed 6788193326Sedvoid dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, 6789212904Sdim const InputInfo &Output, 6790212904Sdim const InputInfoList &Inputs, 6791212904Sdim const ArgList &Args, 6792212904Sdim const char *LinkingOutput) const { 6793251662Sdim bool UseGCC47 = false; 6794201361Srdivacky const Driver &D = getToolChain().getDriver(); 6795193326Sed ArgStringList CmdArgs; 6796193326Sed 6797251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47)) 6798251662Sdim UseGCC47 = false; 6799251662Sdim 6800221345Sdim if (!D.SysRoot.empty()) 6801221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6802221345Sdim 6803251662Sdim CmdArgs.push_back("--eh-frame-hdr"); 6804193326Sed if (Args.hasArg(options::OPT_static)) { 6805193326Sed CmdArgs.push_back("-Bstatic"); 6806193326Sed } else { 6807251662Sdim if (Args.hasArg(options::OPT_rdynamic)) 6808251662Sdim CmdArgs.push_back("-export-dynamic"); 6809193326Sed if (Args.hasArg(options::OPT_shared)) 6810193326Sed CmdArgs.push_back("-Bshareable"); 6811193326Sed else { 6812193326Sed CmdArgs.push_back("-dynamic-linker"); 6813193326Sed CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); 6814193326Sed } 6815251662Sdim CmdArgs.push_back("--hash-style=both"); 6816193326Sed } 6817193326Sed 6818193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 6819193326Sed // instruct ld in the base system to link 32-bit code. 6820243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6821193326Sed CmdArgs.push_back("-m"); 6822193326Sed CmdArgs.push_back("elf_i386"); 6823193326Sed } 6824193326Sed 6825212904Sdim if (Output.isFilename()) { 6826193326Sed CmdArgs.push_back("-o"); 6827193326Sed CmdArgs.push_back(Output.getFilename()); 6828193326Sed } else { 6829193326Sed assert(Output.isNothing() && "Invalid output."); 6830193326Sed } 6831193326Sed 6832193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6833193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6834193326Sed if (!Args.hasArg(options::OPT_shared)) { 6835251662Sdim if (Args.hasArg(options::OPT_pg)) 6836251662Sdim CmdArgs.push_back(Args.MakeArgString( 6837251662Sdim getToolChain().GetFilePath("gcrt1.o"))); 6838251662Sdim else { 6839251662Sdim if (Args.hasArg(options::OPT_pie)) 6840251662Sdim CmdArgs.push_back(Args.MakeArgString( 6841251662Sdim getToolChain().GetFilePath("Scrt1.o"))); 6842251662Sdim else 6843251662Sdim CmdArgs.push_back(Args.MakeArgString( 6844251662Sdim getToolChain().GetFilePath("crt1.o"))); 6845251662Sdim } 6846193326Sed } 6847251662Sdim CmdArgs.push_back(Args.MakeArgString( 6848251662Sdim getToolChain().GetFilePath("crti.o"))); 6849251662Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6850251662Sdim CmdArgs.push_back(Args.MakeArgString( 6851251662Sdim getToolChain().GetFilePath("crtbeginS.o"))); 6852251662Sdim else 6853251662Sdim CmdArgs.push_back(Args.MakeArgString( 6854251662Sdim getToolChain().GetFilePath("crtbegin.o"))); 6855193326Sed } 6856193326Sed 6857193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 6858193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6859193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 6860193326Sed 6861218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6862193326Sed 6863193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6864193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6865193326Sed // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of 6866193326Sed // rpaths 6867251662Sdim if (UseGCC47) 6868251662Sdim CmdArgs.push_back("-L/usr/lib/gcc47"); 6869251662Sdim else 6870251662Sdim CmdArgs.push_back("-L/usr/lib/gcc44"); 6871193326Sed 6872193326Sed if (!Args.hasArg(options::OPT_static)) { 6873251662Sdim if (UseGCC47) { 6874251662Sdim CmdArgs.push_back("-rpath"); 6875251662Sdim CmdArgs.push_back("/usr/lib/gcc47"); 6876251662Sdim } else { 6877251662Sdim CmdArgs.push_back("-rpath"); 6878251662Sdim CmdArgs.push_back("/usr/lib/gcc44"); 6879251662Sdim } 6880193326Sed } 6881193326Sed 6882263508Sdim if (D.CCCIsCXX()) { 6883218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6884212904Sdim CmdArgs.push_back("-lm"); 6885212904Sdim } 6886212904Sdim 6887193326Sed if (Args.hasArg(options::OPT_pthread)) 6888198893Srdivacky CmdArgs.push_back("-lpthread"); 6889193326Sed 6890193326Sed if (!Args.hasArg(options::OPT_nolibc)) { 6891193326Sed CmdArgs.push_back("-lc"); 6892193326Sed } 6893193326Sed 6894251662Sdim if (UseGCC47) { 6895251662Sdim if (Args.hasArg(options::OPT_static) || 6896251662Sdim Args.hasArg(options::OPT_static_libgcc)) { 6897251662Sdim CmdArgs.push_back("-lgcc"); 6898251662Sdim CmdArgs.push_back("-lgcc_eh"); 6899251662Sdim } else { 6900251662Sdim if (Args.hasArg(options::OPT_shared_libgcc)) { 6901251662Sdim CmdArgs.push_back("-lgcc_pic"); 6902251662Sdim if (!Args.hasArg(options::OPT_shared)) 6903251662Sdim CmdArgs.push_back("-lgcc"); 6904251662Sdim } else { 6905251662Sdim CmdArgs.push_back("-lgcc"); 6906251662Sdim CmdArgs.push_back("--as-needed"); 6907251662Sdim CmdArgs.push_back("-lgcc_pic"); 6908251662Sdim CmdArgs.push_back("--no-as-needed"); 6909251662Sdim } 6910251662Sdim } 6911193326Sed } else { 6912251662Sdim if (Args.hasArg(options::OPT_shared)) { 6913251662Sdim CmdArgs.push_back("-lgcc_pic"); 6914251662Sdim } else { 6915251662Sdim CmdArgs.push_back("-lgcc"); 6916251662Sdim } 6917193326Sed } 6918193326Sed } 6919193326Sed 6920193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6921193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6922251662Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6923210299Sed CmdArgs.push_back(Args.MakeArgString( 6924251662Sdim getToolChain().GetFilePath("crtendS.o"))); 6925193326Sed else 6926210299Sed CmdArgs.push_back(Args.MakeArgString( 6927251662Sdim getToolChain().GetFilePath("crtend.o"))); 6928210299Sed CmdArgs.push_back(Args.MakeArgString( 6929251662Sdim getToolChain().GetFilePath("crtn.o"))); 6930193326Sed } 6931193326Sed 6932224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6933223017Sdim 6934193326Sed const char *Exec = 6935210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6936212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6937193326Sed} 6938212904Sdim 6939212904Sdimvoid visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, 6940212904Sdim const InputInfo &Output, 6941212904Sdim const InputInfoList &Inputs, 6942212904Sdim const ArgList &Args, 6943212904Sdim const char *LinkingOutput) const { 6944212904Sdim ArgStringList CmdArgs; 6945212904Sdim 6946212904Sdim if (Output.isFilename()) { 6947218893Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + 6948218893Sdim Output.getFilename())); 6949212904Sdim } else { 6950212904Sdim assert(Output.isNothing() && "Invalid output."); 6951212904Sdim } 6952212904Sdim 6953212904Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6954263508Sdim !Args.hasArg(options::OPT_nostartfiles) && 6955263508Sdim !C.getDriver().IsCLMode()) { 6956212904Sdim CmdArgs.push_back("-defaultlib:libcmt"); 6957212904Sdim } 6958212904Sdim 6959212904Sdim CmdArgs.push_back("-nologo"); 6960212904Sdim 6961263508Sdim bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd); 6962263508Sdim 6963263508Sdim if (DLL) { 6964263508Sdim CmdArgs.push_back(Args.MakeArgString("-dll")); 6965263508Sdim 6966263508Sdim SmallString<128> ImplibName(Output.getFilename()); 6967263508Sdim llvm::sys::path::replace_extension(ImplibName, "lib"); 6968263508Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + 6969263508Sdim ImplibName.str())); 6970263508Sdim } 6971263508Sdim 6972263508Sdim if (getToolChain().getSanitizerArgs().needsAsanRt()) { 6973263508Sdim CmdArgs.push_back(Args.MakeArgString("-debug")); 6974263508Sdim CmdArgs.push_back(Args.MakeArgString("-incremental:no")); 6975263508Sdim SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir); 6976263508Sdim llvm::sys::path::append(LibSanitizer, "lib", "windows"); 6977263508Sdim if (DLL) { 6978263508Sdim llvm::sys::path::append(LibSanitizer, "clang_rt.asan_dll_thunk-i386.lib"); 6979263508Sdim } else { 6980263508Sdim llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib"); 6981263508Sdim } 6982263508Sdim // FIXME: Handle 64-bit. 6983263508Sdim CmdArgs.push_back(Args.MakeArgString(LibSanitizer)); 6984263508Sdim } 6985263508Sdim 6986239462Sdim Args.AddAllArgValues(CmdArgs, options::OPT_l); 6987263508Sdim Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link); 6988212904Sdim 6989239462Sdim // Add filenames immediately. 6990239462Sdim for (InputInfoList::const_iterator 6991239462Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6992239462Sdim if (it->isFilename()) 6993239462Sdim CmdArgs.push_back(it->getFilename()); 6994263508Sdim else 6995263508Sdim it->getInputArg().renderAsInput(Args, CmdArgs); 6996239462Sdim } 6997239462Sdim 6998212904Sdim const char *Exec = 6999218893Sdim Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); 7000212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7001212904Sdim} 7002263508Sdim 7003263508Sdimvoid visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA, 7004263508Sdim const InputInfo &Output, 7005263508Sdim const InputInfoList &Inputs, 7006263508Sdim const ArgList &Args, 7007263508Sdim const char *LinkingOutput) const { 7008263508Sdim C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput)); 7009263508Sdim} 7010263508Sdim 7011263508Sdim// Try to find FallbackName on PATH that is not identical to ClangProgramPath. 7012263508Sdim// If one cannot be found, return FallbackName. 7013263508Sdim// We do this special search to prevent clang-cl from falling back onto itself 7014263508Sdim// if it's available as cl.exe on the path. 7015263508Sdimstatic std::string FindFallback(const char *FallbackName, 7016263508Sdim const char *ClangProgramPath) { 7017263508Sdim llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH"); 7018263508Sdim if (!OptPath.hasValue()) 7019263508Sdim return FallbackName; 7020263508Sdim 7021263508Sdim#ifdef LLVM_ON_WIN32 7022263508Sdim const StringRef PathSeparators = ";"; 7023263508Sdim#else 7024263508Sdim const StringRef PathSeparators = ":"; 7025263508Sdim#endif 7026263508Sdim 7027263508Sdim SmallVector<StringRef, 8> PathSegments; 7028263508Sdim llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators); 7029263508Sdim 7030263508Sdim for (size_t i = 0, e = PathSegments.size(); i != e; ++i) { 7031263508Sdim const StringRef &PathSegment = PathSegments[i]; 7032263508Sdim if (PathSegment.empty()) 7033263508Sdim continue; 7034263508Sdim 7035263508Sdim SmallString<128> FilePath(PathSegment); 7036263508Sdim llvm::sys::path::append(FilePath, FallbackName); 7037263508Sdim if (llvm::sys::fs::can_execute(Twine(FilePath)) && 7038263508Sdim !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath)) 7039263508Sdim return FilePath.str(); 7040263508Sdim } 7041263508Sdim 7042263508Sdim return FallbackName; 7043263508Sdim} 7044263508Sdim 7045263508SdimCommand *visualstudio::Compile::GetCommand(Compilation &C, const JobAction &JA, 7046263508Sdim const InputInfo &Output, 7047263508Sdim const InputInfoList &Inputs, 7048263508Sdim const ArgList &Args, 7049263508Sdim const char *LinkingOutput) const { 7050263508Sdim ArgStringList CmdArgs; 7051263508Sdim CmdArgs.push_back("/nologo"); 7052263508Sdim CmdArgs.push_back("/c"); // Compile only. 7053263508Sdim CmdArgs.push_back("/W0"); // No warnings. 7054263508Sdim 7055263508Sdim // The goal is to be able to invoke this tool correctly based on 7056263508Sdim // any flag accepted by clang-cl. 7057263508Sdim 7058263508Sdim // These are spelled the same way in clang and cl.exe,. 7059263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); 7060263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_I); 7061263508Sdim 7062263508Sdim // Optimization level. 7063263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) { 7064263508Sdim if (A->getOption().getID() == options::OPT_O0) { 7065263508Sdim CmdArgs.push_back("/Od"); 7066263508Sdim } else { 7067263508Sdim StringRef OptLevel = A->getValue(); 7068263508Sdim if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s") 7069263508Sdim A->render(Args, CmdArgs); 7070263508Sdim else if (OptLevel == "3") 7071263508Sdim CmdArgs.push_back("/Ox"); 7072263508Sdim } 7073263508Sdim } 7074263508Sdim 7075263508Sdim // Flags for which clang-cl have an alias. 7076263508Sdim // FIXME: How can we ensure this stays in sync with relevant clang-cl options? 7077263508Sdim 7078263508Sdim if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti)) 7079263508Sdim CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR" 7080263508Sdim : "/GR-"); 7081263508Sdim if (Args.hasArg(options::OPT_fsyntax_only)) 7082263508Sdim CmdArgs.push_back("/Zs"); 7083263508Sdim 7084263508Sdim std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include); 7085263508Sdim for (size_t I = 0, E = Includes.size(); I != E; ++I) 7086263508Sdim CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I])); 7087263508Sdim 7088263508Sdim // Flags that can simply be passed through. 7089263508Sdim Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD); 7090263508Sdim Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd); 7091263508Sdim 7092263508Sdim // The order of these flags is relevant, so pick the last one. 7093263508Sdim if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd, 7094263508Sdim options::OPT__SLASH_MT, options::OPT__SLASH_MTd)) 7095263508Sdim A->render(Args, CmdArgs); 7096263508Sdim 7097263508Sdim 7098263508Sdim // Input filename. 7099263508Sdim assert(Inputs.size() == 1); 7100263508Sdim const InputInfo &II = Inputs[0]; 7101263508Sdim assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX); 7102263508Sdim CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp"); 7103263508Sdim if (II.isFilename()) 7104263508Sdim CmdArgs.push_back(II.getFilename()); 7105263508Sdim else 7106263508Sdim II.getInputArg().renderAsInput(Args, CmdArgs); 7107263508Sdim 7108263508Sdim // Output filename. 7109263508Sdim assert(Output.getType() == types::TY_Object); 7110263508Sdim const char *Fo = Args.MakeArgString(std::string("/Fo") + 7111263508Sdim Output.getFilename()); 7112263508Sdim CmdArgs.push_back(Fo); 7113263508Sdim 7114263508Sdim const Driver &D = getToolChain().getDriver(); 7115263508Sdim std::string Exec = FindFallback("cl.exe", D.getClangProgramPath()); 7116263508Sdim 7117263508Sdim return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs); 7118263508Sdim} 7119263508Sdim 7120263508Sdim 7121263508Sdim/// XCore Tools 7122263508Sdim// We pass assemble and link construction to the xcc tool. 7123263508Sdim 7124263508Sdimvoid XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 7125263508Sdim const InputInfo &Output, 7126263508Sdim const InputInfoList &Inputs, 7127263508Sdim const ArgList &Args, 7128263508Sdim const char *LinkingOutput) const { 7129263508Sdim ArgStringList CmdArgs; 7130263508Sdim 7131263508Sdim CmdArgs.push_back("-o"); 7132263508Sdim CmdArgs.push_back(Output.getFilename()); 7133263508Sdim 7134263508Sdim CmdArgs.push_back("-c"); 7135263508Sdim 7136263508Sdim if (Args.hasArg(options::OPT_g_Group)) { 7137263508Sdim CmdArgs.push_back("-g"); 7138263508Sdim } 7139263508Sdim 7140263508Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 7141263508Sdim options::OPT_Xassembler); 7142263508Sdim 7143263508Sdim for (InputInfoList::const_iterator 7144263508Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 7145263508Sdim const InputInfo &II = *it; 7146263508Sdim CmdArgs.push_back(II.getFilename()); 7147263508Sdim } 7148263508Sdim 7149263508Sdim const char *Exec = 7150263508Sdim Args.MakeArgString(getToolChain().GetProgramPath("xcc")); 7151263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7152263508Sdim} 7153263508Sdim 7154263508Sdimvoid XCore::Link::ConstructJob(Compilation &C, const JobAction &JA, 7155263508Sdim const InputInfo &Output, 7156263508Sdim const InputInfoList &Inputs, 7157263508Sdim const ArgList &Args, 7158263508Sdim const char *LinkingOutput) const { 7159263508Sdim ArgStringList CmdArgs; 7160263508Sdim 7161263508Sdim if (Output.isFilename()) { 7162263508Sdim CmdArgs.push_back("-o"); 7163263508Sdim CmdArgs.push_back(Output.getFilename()); 7164263508Sdim } else { 7165263508Sdim assert(Output.isNothing() && "Invalid output."); 7166263508Sdim } 7167263508Sdim 7168263508Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 7169263508Sdim 7170263508Sdim const char *Exec = 7171263508Sdim Args.MakeArgString(getToolChain().GetProgramPath("xcc")); 7172263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7173263508Sdim} 7174