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 502270072Sian if (Triple.getOS() == llvm::Triple::NetBSD || 503270072Sian Triple.getOS() == llvm::Triple::FreeBSD) { 504263508Sdim if (MArch == "armv6") 505263508Sdim return "arm1176jzf-s"; 506263508Sdim } 507263508Sdim 508239462Sdim // Handle -march=native. 509239462Sdim std::string NativeMArch; 510239462Sdim if (MArch == "native") { 511239462Sdim std::string CPU = llvm::sys::getHostCPUName(); 512239462Sdim if (CPU != "generic") { 513239462Sdim // Translate the native cpu into the architecture. The switch below will 514239462Sdim // then chose the minimum cpu for that arch. 515239462Sdim NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU); 516239462Sdim MArch = NativeMArch; 517239462Sdim } 518239462Sdim } 519239462Sdim 520226633Sdim return llvm::StringSwitch<const char *>(MArch) 521226633Sdim .Cases("armv2", "armv2a","arm2") 522226633Sdim .Case("armv3", "arm6") 523226633Sdim .Case("armv3m", "arm7m") 524263508Sdim .Case("armv4", "strongarm") 525263508Sdim .Case("armv4t", "arm7tdmi") 526226633Sdim .Cases("armv5", "armv5t", "arm10tdmi") 527239462Sdim .Cases("armv5e", "armv5te", "arm1022e") 528226633Sdim .Case("armv5tej", "arm926ej-s") 529226633Sdim .Cases("armv6", "armv6k", "arm1136jf-s") 530226633Sdim .Case("armv6j", "arm1136j-s") 531226633Sdim .Cases("armv6z", "armv6zk", "arm1176jzf-s") 532226633Sdim .Case("armv6t2", "arm1156t2-s") 533249423Sdim .Cases("armv6m", "armv6-m", "cortex-m0") 534226633Sdim .Cases("armv7", "armv7a", "armv7-a", "cortex-a8") 535249423Sdim .Cases("armv7em", "armv7e-m", "cortex-m4") 536243830Sdim .Cases("armv7f", "armv7-f", "cortex-a9-mp") 537243830Sdim .Cases("armv7s", "armv7-s", "swift") 538226633Sdim .Cases("armv7r", "armv7-r", "cortex-r4") 539226633Sdim .Cases("armv7m", "armv7-m", "cortex-m3") 540263508Sdim .Cases("armv8", "armv8a", "armv8-a", "cortex-a53") 541226633Sdim .Case("ep9312", "ep9312") 542226633Sdim .Case("iwmmxt", "iwmmxt") 543226633Sdim .Case("xscale", "xscale") 544263508Sdim // If all else failed, return the most base CPU with thumb interworking 545263508Sdim // supported by LLVM. 546226633Sdim .Default("arm7tdmi"); 547198092Srdivacky} 548198092Srdivacky 549263508Sdim/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are targeting. 550263508Sdim// 551263508Sdim// FIXME: tblgen this. 552263508Sdimstatic std::string getAArch64TargetCPU(const ArgList &Args, 553263508Sdim const llvm::Triple &Triple) { 554263508Sdim // FIXME: Warn on inconsistent use of -mcpu and -march. 555263508Sdim 556263508Sdim // If we have -mcpu=, use that. 557263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 558263508Sdim StringRef MCPU = A->getValue(); 559263508Sdim // Handle -mcpu=native. 560263508Sdim if (MCPU == "native") 561263508Sdim return llvm::sys::getHostCPUName(); 562263508Sdim else 563263508Sdim return MCPU; 564263508Sdim } 565263508Sdim 566263508Sdim return "generic"; 567263508Sdim} 568263508Sdim 569199482Srdivacky// FIXME: Move to target hook. 570199482Srdivackystatic bool isSignedCharDefault(const llvm::Triple &Triple) { 571199482Srdivacky switch (Triple.getArch()) { 572199482Srdivacky default: 573199482Srdivacky return true; 574199482Srdivacky 575249423Sdim case llvm::Triple::aarch64: 576223017Sdim case llvm::Triple::arm: 577199482Srdivacky case llvm::Triple::ppc: 578199482Srdivacky case llvm::Triple::ppc64: 579226633Sdim if (Triple.isOSDarwin()) 580199482Srdivacky return true; 581199482Srdivacky return false; 582251662Sdim 583263508Sdim case llvm::Triple::ppc64le: 584251662Sdim case llvm::Triple::systemz: 585263508Sdim case llvm::Triple::xcore: 586251662Sdim return false; 587199482Srdivacky } 588199482Srdivacky} 589199482Srdivacky 590263508Sdimstatic bool isNoCommonDefault(const llvm::Triple &Triple) { 591263508Sdim switch (Triple.getArch()) { 592263508Sdim default: 593263508Sdim return false; 594263508Sdim 595263508Sdim case llvm::Triple::xcore: 596263508Sdim return true; 597263508Sdim } 598263508Sdim} 599263508Sdim 600234353Sdim// Handle -mfpu=. 601234353Sdim// 602234353Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the 603234353Sdim// frontend target. 604263508Sdimstatic void getAArch64FPUFeatures(const Driver &D, const Arg *A, 605263508Sdim const ArgList &Args, 606263508Sdim std::vector<const char *> &Features) { 607243830Sdim StringRef FPU = A->getValue(); 608263508Sdim if (FPU == "fp-armv8") { 609263508Sdim Features.push_back("+fp-armv8"); 610263508Sdim } else if (FPU == "neon-fp-armv8") { 611263508Sdim Features.push_back("+fp-armv8"); 612263508Sdim Features.push_back("+neon"); 613263508Sdim } else if (FPU == "crypto-neon-fp-armv8") { 614263508Sdim Features.push_back("+fp-armv8"); 615263508Sdim Features.push_back("+neon"); 616263508Sdim Features.push_back("+crypto"); 617263508Sdim } else if (FPU == "neon") { 618263508Sdim Features.push_back("+neon"); 619263508Sdim } else if (FPU == "none") { 620263508Sdim Features.push_back("-fp-armv8"); 621263508Sdim Features.push_back("-crypto"); 622263508Sdim Features.push_back("-neon"); 623263508Sdim } else 624263508Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 625263508Sdim} 626198092Srdivacky 627263508Sdim// Handle -mhwdiv=. 628263508Sdimstatic void getARMHWDivFeatures(const Driver &D, const Arg *A, 629263508Sdim const ArgList &Args, 630263508Sdim std::vector<const char *> &Features) { 631263508Sdim StringRef HWDiv = A->getValue(); 632263508Sdim if (HWDiv == "arm") { 633263508Sdim Features.push_back("+hwdiv-arm"); 634263508Sdim Features.push_back("-hwdiv"); 635263508Sdim } else if (HWDiv == "thumb") { 636263508Sdim Features.push_back("-hwdiv-arm"); 637263508Sdim Features.push_back("+hwdiv"); 638263508Sdim } else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") { 639263508Sdim Features.push_back("+hwdiv-arm"); 640263508Sdim Features.push_back("+hwdiv"); 641263508Sdim } else if (HWDiv == "none") { 642263508Sdim Features.push_back("-hwdiv-arm"); 643263508Sdim Features.push_back("-hwdiv"); 644263508Sdim } else 645263508Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 646263508Sdim} 647263508Sdim 648263508Sdim// Handle -mfpu=. 649263508Sdim// 650263508Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the 651263508Sdim// frontend target. 652263508Sdimstatic void getARMFPUFeatures(const Driver &D, const Arg *A, 653263508Sdim const ArgList &Args, 654263508Sdim std::vector<const char *> &Features) { 655263508Sdim StringRef FPU = A->getValue(); 656263508Sdim 657234353Sdim // Set the target features based on the FPU. 658234353Sdim if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") { 659234353Sdim // Disable any default FPU support. 660263508Sdim Features.push_back("-vfp2"); 661263508Sdim Features.push_back("-vfp3"); 662263508Sdim Features.push_back("-neon"); 663234353Sdim } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") { 664263508Sdim Features.push_back("+vfp3"); 665263508Sdim Features.push_back("+d16"); 666263508Sdim Features.push_back("-neon"); 667234353Sdim } else if (FPU == "vfp") { 668263508Sdim Features.push_back("+vfp2"); 669263508Sdim Features.push_back("-neon"); 670234353Sdim } else if (FPU == "vfp3" || FPU == "vfpv3") { 671263508Sdim Features.push_back("+vfp3"); 672263508Sdim Features.push_back("-neon"); 673263508Sdim } else if (FPU == "fp-armv8") { 674263508Sdim Features.push_back("+fp-armv8"); 675263508Sdim Features.push_back("-neon"); 676263508Sdim Features.push_back("-crypto"); 677263508Sdim } else if (FPU == "neon-fp-armv8") { 678263508Sdim Features.push_back("+fp-armv8"); 679263508Sdim Features.push_back("+neon"); 680263508Sdim Features.push_back("-crypto"); 681263508Sdim } else if (FPU == "crypto-neon-fp-armv8") { 682263508Sdim Features.push_back("+fp-armv8"); 683263508Sdim Features.push_back("+neon"); 684263508Sdim Features.push_back("+crypto"); 685234353Sdim } else if (FPU == "neon") { 686263508Sdim Features.push_back("+neon"); 687263508Sdim } else if (FPU == "none") { 688263508Sdim Features.push_back("-vfp2"); 689263508Sdim Features.push_back("-vfp3"); 690263508Sdim Features.push_back("-vfp4"); 691263508Sdim Features.push_back("-fp-armv8"); 692263508Sdim Features.push_back("-crypto"); 693263508Sdim Features.push_back("-neon"); 694234353Sdim } else 695234353Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 696234353Sdim} 697198092Srdivacky 698234353Sdim// Select the float ABI as determined by -msoft-float, -mhard-float, and 699234353Sdim// -mfloat-abi=. 700234353Sdimstatic StringRef getARMFloatABI(const Driver &D, 701234353Sdim const ArgList &Args, 702234353Sdim const llvm::Triple &Triple) { 703226633Sdim StringRef FloatABI; 704198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 705198092Srdivacky options::OPT_mhard_float, 706198092Srdivacky options::OPT_mfloat_abi_EQ)) { 707198092Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 708198092Srdivacky FloatABI = "soft"; 709198092Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 710198092Srdivacky FloatABI = "hard"; 711198092Srdivacky else { 712243830Sdim FloatABI = A->getValue(); 713198092Srdivacky if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") { 714226633Sdim D.Diag(diag::err_drv_invalid_mfloat_abi) 715198092Srdivacky << A->getAsString(Args); 716198092Srdivacky FloatABI = "soft"; 717198092Srdivacky } 718198092Srdivacky } 719198092Srdivacky } 720198092Srdivacky 721198092Srdivacky // If unspecified, choose the default based on the platform. 722198092Srdivacky if (FloatABI.empty()) { 723210299Sed switch (Triple.getOS()) { 724226633Sdim case llvm::Triple::Darwin: 725226633Sdim case llvm::Triple::MacOSX: 726226633Sdim case llvm::Triple::IOS: { 727198092Srdivacky // Darwin defaults to "softfp" for v6 and v7. 728198092Srdivacky // 729198092Srdivacky // FIXME: Factor out an ARM class so we can cache the arch somewhere. 730239462Sdim std::string ArchName = 731210299Sed getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 732239462Sdim if (StringRef(ArchName).startswith("v6") || 733239462Sdim StringRef(ArchName).startswith("v7")) 734198092Srdivacky FloatABI = "softfp"; 735198092Srdivacky else 736198092Srdivacky FloatABI = "soft"; 737198092Srdivacky break; 738198092Srdivacky } 739198092Srdivacky 740244640Sandrew case llvm::Triple::FreeBSD: 741244640Sandrew // FreeBSD defaults to soft float 742244640Sandrew FloatABI = "soft"; 743244640Sandrew break; 744244640Sandrew 745198092Srdivacky default: 746218893Sdim switch(Triple.getEnvironment()) { 747239462Sdim case llvm::Triple::GNUEABIHF: 748239462Sdim FloatABI = "hard"; 749239462Sdim break; 750218893Sdim case llvm::Triple::GNUEABI: 751218893Sdim FloatABI = "softfp"; 752218893Sdim break; 753218893Sdim case llvm::Triple::EABI: 754218893Sdim // EABI is always AAPCS, and if it was not marked 'hard', it's softfp 755218893Sdim FloatABI = "softfp"; 756218893Sdim break; 757243830Sdim case llvm::Triple::Android: { 758239462Sdim std::string ArchName = 759234353Sdim getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 760239462Sdim if (StringRef(ArchName).startswith("v7")) 761234353Sdim FloatABI = "softfp"; 762234353Sdim else 763234353Sdim FloatABI = "soft"; 764234353Sdim break; 765234353Sdim } 766218893Sdim default: 767218893Sdim // Assume "soft", but warn the user we are guessing. 768218893Sdim FloatABI = "soft"; 769226633Sdim D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 770218893Sdim break; 771218893Sdim } 772198092Srdivacky } 773198092Srdivacky } 774198092Srdivacky 775234353Sdim return FloatABI; 776234353Sdim} 777234353Sdim 778263508Sdimstatic void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, 779263508Sdim const ArgList &Args, 780263508Sdim std::vector<const char *> &Features) { 781263508Sdim StringRef FloatABI = getARMFloatABI(D, Args, Triple); 782263508Sdim // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these 783263508Sdim // yet (it uses the -mfloat-abi and -msoft-float options), and it is 784263508Sdim // stripped out by the ARM target. 785263508Sdim // Use software floating point operations? 786263508Sdim if (FloatABI == "soft") 787263508Sdim Features.push_back("+soft-float"); 788234353Sdim 789263508Sdim // Use software floating point argument passing? 790263508Sdim if (FloatABI != "hard") 791263508Sdim Features.push_back("+soft-float-abi"); 792263508Sdim 793263508Sdim // Honor -mfpu=. 794263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 795263508Sdim getARMFPUFeatures(D, A, Args, Features); 796263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ)) 797263508Sdim getARMHWDivFeatures(D, A, Args, Features); 798263508Sdim 799263508Sdim // Setting -msoft-float effectively disables NEON because of the GCC 800263508Sdim // implementation, although the same isn't true of VFP or VFP3. 801263508Sdim if (FloatABI == "soft") 802263508Sdim Features.push_back("-neon"); 803263508Sdim 804263508Sdim // En/disable crc 805263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcrc, 806263508Sdim options::OPT_mnocrc)) { 807263508Sdim if (A->getOption().matches(options::OPT_mcrc)) 808263508Sdim Features.push_back("+crc"); 809263508Sdim else 810263508Sdim Features.push_back("-crc"); 811263508Sdim } 812263508Sdim} 813263508Sdim 814234353Sdimvoid Clang::AddARMTargetArgs(const ArgList &Args, 815234353Sdim ArgStringList &CmdArgs, 816234353Sdim bool KernelOrKext) const { 817234353Sdim const Driver &D = getToolChain().getDriver(); 818243830Sdim // Get the effective triple, which takes into account the deployment target. 819243830Sdim std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 820243830Sdim llvm::Triple Triple(TripleStr); 821243830Sdim std::string CPUName = getARMTargetCPU(Args, Triple); 822234353Sdim 823234353Sdim // Select the ABI to use. 824234353Sdim // 825234353Sdim // FIXME: Support -meabi. 826234353Sdim const char *ABIName = 0; 827234353Sdim if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 828243830Sdim ABIName = A->getValue(); 829243830Sdim } else if (Triple.isOSDarwin()) { 830243830Sdim // The backend is hardwired to assume AAPCS for M-class processors, ensure 831243830Sdim // the frontend matches that. 832263508Sdim if (Triple.getEnvironment() == llvm::Triple::EABI || 833263508Sdim StringRef(CPUName).startswith("cortex-m")) { 834243830Sdim ABIName = "aapcs"; 835243830Sdim } else { 836243830Sdim ABIName = "apcs-gnu"; 837243830Sdim } 838234353Sdim } else { 839234353Sdim // Select the default based on the platform. 840234353Sdim switch(Triple.getEnvironment()) { 841243830Sdim case llvm::Triple::Android: 842234353Sdim case llvm::Triple::GNUEABI: 843239462Sdim case llvm::Triple::GNUEABIHF: 844234353Sdim ABIName = "aapcs-linux"; 845234353Sdim break; 846234353Sdim case llvm::Triple::EABI: 847234353Sdim ABIName = "aapcs"; 848234353Sdim break; 849234353Sdim default: 850234353Sdim ABIName = "apcs-gnu"; 851234353Sdim } 852234353Sdim } 853234353Sdim CmdArgs.push_back("-target-abi"); 854234353Sdim CmdArgs.push_back(ABIName); 855234353Sdim 856234353Sdim // Determine floating point ABI from the options & target defaults. 857234353Sdim StringRef FloatABI = getARMFloatABI(D, Args, Triple); 858198092Srdivacky if (FloatABI == "soft") { 859198092Srdivacky // Floating point operations and argument passing are soft. 860198092Srdivacky // 861198092Srdivacky // FIXME: This changes CPP defines, we need -target-soft-float. 862199990Srdivacky CmdArgs.push_back("-msoft-float"); 863200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 864200583Srdivacky CmdArgs.push_back("soft"); 865198092Srdivacky } else if (FloatABI == "softfp") { 866198092Srdivacky // Floating point operations are hard, but argument passing is soft. 867200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 868200583Srdivacky CmdArgs.push_back("soft"); 869198092Srdivacky } else { 870198092Srdivacky // Floating point operations and argument passing are hard. 871198092Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 872200583Srdivacky CmdArgs.push_back("-mfloat-abi"); 873200583Srdivacky CmdArgs.push_back("hard"); 874198092Srdivacky } 875201361Srdivacky 876221345Sdim // Kernel code has more strict alignment requirements. 877221345Sdim if (KernelOrKext) { 878263508Sdim if (!Triple.isiOS() || Triple.isOSVersionLT(6)) { 879243830Sdim CmdArgs.push_back("-backend-option"); 880243830Sdim CmdArgs.push_back("-arm-long-calls"); 881243830Sdim } 882221345Sdim 883221345Sdim CmdArgs.push_back("-backend-option"); 884221345Sdim CmdArgs.push_back("-arm-strict-align"); 885221345Sdim 886221345Sdim // The kext linker doesn't know how to deal with movw/movt. 887221345Sdim CmdArgs.push_back("-backend-option"); 888263508Sdim CmdArgs.push_back("-arm-use-movt=0"); 889221345Sdim } 890226633Sdim 891226633Sdim // Setting -mno-global-merge disables the codegen global merge pass. Setting 892226633Sdim // -mglobal-merge has no effect as the pass is enabled by default. 893226633Sdim if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, 894226633Sdim options::OPT_mno_global_merge)) { 895226633Sdim if (A->getOption().matches(options::OPT_mno_global_merge)) 896226633Sdim CmdArgs.push_back("-mno-global-merge"); 897226633Sdim } 898239462Sdim 899251662Sdim if (!Args.hasFlag(options::OPT_mimplicit_float, 900251662Sdim options::OPT_mno_implicit_float, 901251662Sdim true)) 902239462Sdim CmdArgs.push_back("-no-implicit-float"); 903198092Srdivacky 904263508Sdim // llvm does not support reserving registers in general. There is support 905263508Sdim // for reserving r9 on ARM though (defined as a platform-specific register 906263508Sdim // in ARM EABI). 907263508Sdim if (Args.hasArg(options::OPT_ffixed_r9)) { 908263508Sdim CmdArgs.push_back("-backend-option"); 909263508Sdim CmdArgs.push_back("-arm-reserve-r9"); 910263508Sdim } 911226633Sdim} 912226633Sdim 913234353Sdim// Get CPU and ABI names. They are not independent 914234353Sdim// so we have to calculate them together. 915234353Sdimstatic void getMipsCPUAndABI(const ArgList &Args, 916263508Sdim const llvm::Triple &Triple, 917234353Sdim StringRef &CPUName, 918234353Sdim StringRef &ABIName) { 919243830Sdim const char *DefMips32CPU = "mips32"; 920243830Sdim const char *DefMips64CPU = "mips64"; 921226633Sdim 922243830Sdim if (Arg *A = Args.getLastArg(options::OPT_march_EQ, 923263508Sdim options::OPT_mcpu_EQ)) 924263508Sdim CPUName = A->getValue(); 925243830Sdim 926251662Sdim if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 927243830Sdim ABIName = A->getValue(); 928251662Sdim // Convert a GNU style Mips ABI name to the name 929251662Sdim // accepted by LLVM Mips backend. 930251662Sdim ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) 931251662Sdim .Case("32", "o32") 932251662Sdim .Case("64", "n64") 933251662Sdim .Default(ABIName); 934251662Sdim } 935243830Sdim 936243830Sdim // Setup default CPU and ABI names. 937243830Sdim if (CPUName.empty() && ABIName.empty()) { 938263508Sdim switch (Triple.getArch()) { 939243830Sdim default: 940243830Sdim llvm_unreachable("Unexpected triple arch name"); 941243830Sdim case llvm::Triple::mips: 942243830Sdim case llvm::Triple::mipsel: 943243830Sdim CPUName = DefMips32CPU; 944243830Sdim break; 945243830Sdim case llvm::Triple::mips64: 946243830Sdim case llvm::Triple::mips64el: 947243830Sdim CPUName = DefMips64CPU; 948243830Sdim break; 949243830Sdim } 950243830Sdim } 951243830Sdim 952243830Sdim if (!ABIName.empty()) { 953243830Sdim // Deduce CPU name from ABI name. 954243830Sdim CPUName = llvm::StringSwitch<const char *>(ABIName) 955249423Sdim .Cases("32", "o32", "eabi", DefMips32CPU) 956249423Sdim .Cases("n32", "n64", "64", DefMips64CPU) 957243830Sdim .Default(""); 958243830Sdim } 959243830Sdim else if (!CPUName.empty()) { 960243830Sdim // Deduce ABI name from CPU name. 961243830Sdim ABIName = llvm::StringSwitch<const char *>(CPUName) 962243830Sdim .Cases("mips32", "mips32r2", "o32") 963243830Sdim .Cases("mips64", "mips64r2", "n64") 964243830Sdim .Default(""); 965243830Sdim } 966243830Sdim 967243830Sdim // FIXME: Warn on inconsistent cpu and abi usage. 968234353Sdim} 969204643Srdivacky 970249423Sdim// Convert ABI name to the GNU tools acceptable variant. 971249423Sdimstatic StringRef getGnuCompatibleMipsABIName(StringRef ABI) { 972249423Sdim return llvm::StringSwitch<llvm::StringRef>(ABI) 973249423Sdim .Case("o32", "32") 974249423Sdim .Case("n64", "64") 975249423Sdim .Default(ABI); 976249423Sdim} 977249423Sdim 978239462Sdim// Select the MIPS float ABI as determined by -msoft-float, -mhard-float, 979239462Sdim// and -mfloat-abi=. 980239462Sdimstatic StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) { 981226633Sdim StringRef FloatABI; 982204643Srdivacky if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 983234353Sdim options::OPT_mhard_float, 984234353Sdim options::OPT_mfloat_abi_EQ)) { 985204643Srdivacky if (A->getOption().matches(options::OPT_msoft_float)) 986204643Srdivacky FloatABI = "soft"; 987204643Srdivacky else if (A->getOption().matches(options::OPT_mhard_float)) 988204643Srdivacky FloatABI = "hard"; 989234353Sdim else { 990243830Sdim FloatABI = A->getValue(); 991251662Sdim if (FloatABI != "soft" && FloatABI != "hard") { 992239462Sdim D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 993234353Sdim FloatABI = "hard"; 994234353Sdim } 995234353Sdim } 996204643Srdivacky } 997204643Srdivacky 998204643Srdivacky // If unspecified, choose the default based on the platform. 999204643Srdivacky if (FloatABI.empty()) { 1000234353Sdim // Assume "hard", because it's a default value used by gcc. 1001234353Sdim // When we start to recognize specific target MIPS processors, 1002234353Sdim // we will be able to select the default more correctly. 1003234353Sdim FloatABI = "hard"; 1004204643Srdivacky } 1005204643Srdivacky 1006239462Sdim return FloatABI; 1007239462Sdim} 1008239462Sdim 1009239462Sdimstatic void AddTargetFeature(const ArgList &Args, 1010263508Sdim std::vector<const char *> &Features, 1011263508Sdim OptSpecifier OnOpt, OptSpecifier OffOpt, 1012239462Sdim StringRef FeatureName) { 1013239462Sdim if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) { 1014239462Sdim if (A->getOption().matches(OnOpt)) 1015263508Sdim Features.push_back(Args.MakeArgString("+" + FeatureName)); 1016239462Sdim else 1017263508Sdim Features.push_back(Args.MakeArgString("-" + FeatureName)); 1018239462Sdim } 1019239462Sdim} 1020239462Sdim 1021263508Sdimstatic void getMIPSTargetFeatures(const Driver &D, const ArgList &Args, 1022263508Sdim std::vector<const char *> &Features) { 1023263508Sdim StringRef FloatABI = getMipsFloatABI(D, Args); 1024263508Sdim bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL; 1025263508Sdim if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) { 1026263508Sdim // FIXME: Note, this is a hack. We need to pass the selected float 1027263508Sdim // mode to the MipsTargetInfoBase to define appropriate macros there. 1028263508Sdim // Now it is the only method. 1029263508Sdim Features.push_back("+soft-float"); 1030263508Sdim } 1031263508Sdim 1032263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 1033263508Sdim if (StringRef(A->getValue()) == "2008") 1034263508Sdim Features.push_back("+nan2008"); 1035263508Sdim } 1036263508Sdim 1037263508Sdim AddTargetFeature(Args, Features, options::OPT_msingle_float, 1038263508Sdim options::OPT_mdouble_float, "single-float"); 1039263508Sdim AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, 1040263508Sdim "mips16"); 1041263508Sdim AddTargetFeature(Args, Features, options::OPT_mmicromips, 1042263508Sdim options::OPT_mno_micromips, "micromips"); 1043263508Sdim AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, 1044263508Sdim "dsp"); 1045263508Sdim AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, 1046263508Sdim "dspr2"); 1047263508Sdim AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, 1048263508Sdim "msa"); 1049263508Sdim AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32, 1050263508Sdim "fp64"); 1051263508Sdim} 1052263508Sdim 1053239462Sdimvoid Clang::AddMIPSTargetArgs(const ArgList &Args, 1054251662Sdim ArgStringList &CmdArgs) const { 1055239462Sdim const Driver &D = getToolChain().getDriver(); 1056239462Sdim StringRef CPUName; 1057239462Sdim StringRef ABIName; 1058263508Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 1059263508Sdim getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 1060239462Sdim 1061239462Sdim CmdArgs.push_back("-target-abi"); 1062239462Sdim CmdArgs.push_back(ABIName.data()); 1063239462Sdim 1064239462Sdim StringRef FloatABI = getMipsFloatABI(D, Args); 1065239462Sdim 1066249423Sdim bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL; 1067249423Sdim 1068249423Sdim if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) { 1069204643Srdivacky // Floating point operations and argument passing are soft. 1070204643Srdivacky CmdArgs.push_back("-msoft-float"); 1071234353Sdim CmdArgs.push_back("-mfloat-abi"); 1072234353Sdim CmdArgs.push_back("soft"); 1073234353Sdim 1074249423Sdim if (FloatABI == "hard" && IsMips16) { 1075249423Sdim CmdArgs.push_back("-mllvm"); 1076249423Sdim CmdArgs.push_back("-mips16-hard-float"); 1077249423Sdim } 1078234353Sdim } 1079234353Sdim else { 1080234353Sdim // Floating point operations and argument passing are hard. 1081204643Srdivacky assert(FloatABI == "hard" && "Invalid float abi!"); 1082234353Sdim CmdArgs.push_back("-mfloat-abi"); 1083234353Sdim CmdArgs.push_back("hard"); 1084204643Srdivacky } 1085239462Sdim 1086249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) { 1087249423Sdim if (A->getOption().matches(options::OPT_mxgot)) { 1088249423Sdim CmdArgs.push_back("-mllvm"); 1089249423Sdim CmdArgs.push_back("-mxgot"); 1090249423Sdim } 1091249423Sdim } 1092249423Sdim 1093263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1, 1094263508Sdim options::OPT_mno_ldc1_sdc1)) { 1095263508Sdim if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) { 1096263508Sdim CmdArgs.push_back("-mllvm"); 1097263508Sdim CmdArgs.push_back("-mno-ldc1-sdc1"); 1098263508Sdim } 1099263508Sdim } 1100263508Sdim 1101263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division, 1102263508Sdim options::OPT_mno_check_zero_division)) { 1103263508Sdim if (A->getOption().matches(options::OPT_mno_check_zero_division)) { 1104263508Sdim CmdArgs.push_back("-mllvm"); 1105263508Sdim CmdArgs.push_back("-mno-check-zero-division"); 1106263508Sdim } 1107263508Sdim } 1108263508Sdim 1109243830Sdim if (Arg *A = Args.getLastArg(options::OPT_G)) { 1110243830Sdim StringRef v = A->getValue(); 1111243830Sdim CmdArgs.push_back("-mllvm"); 1112243830Sdim CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v)); 1113243830Sdim A->claim(); 1114243830Sdim } 1115204643Srdivacky} 1116204643Srdivacky 1117239462Sdim/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. 1118239462Sdimstatic std::string getPPCTargetCPU(const ArgList &Args) { 1119239462Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 1120243830Sdim StringRef CPUName = A->getValue(); 1121239462Sdim 1122239462Sdim if (CPUName == "native") { 1123239462Sdim std::string CPU = llvm::sys::getHostCPUName(); 1124239462Sdim if (!CPU.empty() && CPU != "generic") 1125239462Sdim return CPU; 1126239462Sdim else 1127239462Sdim return ""; 1128239462Sdim } 1129239462Sdim 1130239462Sdim return llvm::StringSwitch<const char *>(CPUName) 1131239462Sdim .Case("common", "generic") 1132239462Sdim .Case("440", "440") 1133239462Sdim .Case("440fp", "440") 1134239462Sdim .Case("450", "450") 1135239462Sdim .Case("601", "601") 1136239462Sdim .Case("602", "602") 1137239462Sdim .Case("603", "603") 1138239462Sdim .Case("603e", "603e") 1139239462Sdim .Case("603ev", "603ev") 1140239462Sdim .Case("604", "604") 1141239462Sdim .Case("604e", "604e") 1142239462Sdim .Case("620", "620") 1143249423Sdim .Case("630", "pwr3") 1144239462Sdim .Case("G3", "g3") 1145239462Sdim .Case("7400", "7400") 1146239462Sdim .Case("G4", "g4") 1147239462Sdim .Case("7450", "7450") 1148239462Sdim .Case("G4+", "g4+") 1149239462Sdim .Case("750", "750") 1150239462Sdim .Case("970", "970") 1151239462Sdim .Case("G5", "g5") 1152239462Sdim .Case("a2", "a2") 1153249423Sdim .Case("a2q", "a2q") 1154243830Sdim .Case("e500mc", "e500mc") 1155243830Sdim .Case("e5500", "e5500") 1156249423Sdim .Case("power3", "pwr3") 1157249423Sdim .Case("power4", "pwr4") 1158249423Sdim .Case("power5", "pwr5") 1159249423Sdim .Case("power5x", "pwr5x") 1160239462Sdim .Case("power6", "pwr6") 1161249423Sdim .Case("power6x", "pwr6x") 1162239462Sdim .Case("power7", "pwr7") 1163249423Sdim .Case("pwr3", "pwr3") 1164249423Sdim .Case("pwr4", "pwr4") 1165249423Sdim .Case("pwr5", "pwr5") 1166249423Sdim .Case("pwr5x", "pwr5x") 1167249423Sdim .Case("pwr6", "pwr6") 1168249423Sdim .Case("pwr6x", "pwr6x") 1169249423Sdim .Case("pwr7", "pwr7") 1170239462Sdim .Case("powerpc", "ppc") 1171239462Sdim .Case("powerpc64", "ppc64") 1172263508Sdim .Case("powerpc64le", "ppc64le") 1173239462Sdim .Default(""); 1174239462Sdim } 1175239462Sdim 1176239462Sdim return ""; 1177239462Sdim} 1178239462Sdim 1179263508Sdimstatic void getPPCTargetFeatures(const ArgList &Args, 1180263508Sdim std::vector<const char *> &Features) { 1181263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_m_ppc_Features_Group), 1182263508Sdim ie = Args.filtered_end(); 1183263508Sdim it != ie; ++it) { 1184263508Sdim StringRef Name = (*it)->getOption().getName(); 1185263508Sdim (*it)->claim(); 1186239462Sdim 1187263508Sdim // Skip over "-m". 1188263508Sdim assert(Name.startswith("m") && "Invalid feature name."); 1189263508Sdim Name = Name.substr(1); 1190239462Sdim 1191263508Sdim bool IsNegative = Name.startswith("no-"); 1192263508Sdim if (IsNegative) 1193263508Sdim Name = Name.substr(3); 1194249423Sdim 1195263508Sdim // Note that gcc calls this mfcrf and LLVM calls this mfocrf so we 1196263508Sdim // pass the correct option to the backend while calling the frontend 1197263508Sdim // option the same. 1198263508Sdim // TODO: Change the LLVM backend option maybe? 1199263508Sdim if (Name == "mfcrf") 1200263508Sdim Name = "mfocrf"; 1201249423Sdim 1202263508Sdim Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); 1203263508Sdim } 1204249423Sdim 1205263508Sdim // Altivec is a bit weird, allow overriding of the Altivec feature here. 1206263508Sdim AddTargetFeature(Args, Features, options::OPT_faltivec, 1207263508Sdim options::OPT_fno_altivec, "altivec"); 1208239462Sdim} 1209239462Sdim 1210249423Sdim/// Get the (LLVM) name of the R600 gpu we are targeting. 1211249423Sdimstatic std::string getR600TargetGPU(const ArgList &Args) { 1212249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 1213263508Sdim const char *GPUName = A->getValue(); 1214249423Sdim return llvm::StringSwitch<const char *>(GPUName) 1215251662Sdim .Cases("rv630", "rv635", "r600") 1216251662Sdim .Cases("rv610", "rv620", "rs780", "rs880") 1217249423Sdim .Case("rv740", "rv770") 1218249423Sdim .Case("palm", "cedar") 1219251662Sdim .Cases("sumo", "sumo2", "sumo") 1220249423Sdim .Case("hemlock", "cypress") 1221249423Sdim .Case("aruba", "cayman") 1222263508Sdim .Default(GPUName); 1223249423Sdim } 1224249423Sdim return ""; 1225249423Sdim} 1226249423Sdim 1227263508Sdimstatic void getSparcTargetFeatures(const ArgList &Args, 1228263508Sdim std::vector<const char *> Features) { 1229263508Sdim bool SoftFloatABI = true; 1230263508Sdim if (Arg *A = 1231263508Sdim Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { 1232263508Sdim if (A->getOption().matches(options::OPT_mhard_float)) 1233263508Sdim SoftFloatABI = false; 1234263508Sdim } 1235263508Sdim if (SoftFloatABI) 1236263508Sdim Features.push_back("+soft-float"); 1237249423Sdim} 1238249423Sdim 1239218893Sdimvoid Clang::AddSparcTargetArgs(const ArgList &Args, 1240218893Sdim ArgStringList &CmdArgs) const { 1241218893Sdim const Driver &D = getToolChain().getDriver(); 1242218893Sdim 1243218893Sdim // Select the float ABI as determined by -msoft-float, -mhard-float, and 1244226633Sdim StringRef FloatABI; 1245218893Sdim if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 1246218893Sdim options::OPT_mhard_float)) { 1247218893Sdim if (A->getOption().matches(options::OPT_msoft_float)) 1248218893Sdim FloatABI = "soft"; 1249218893Sdim else if (A->getOption().matches(options::OPT_mhard_float)) 1250218893Sdim FloatABI = "hard"; 1251218893Sdim } 1252218893Sdim 1253218893Sdim // If unspecified, choose the default based on the platform. 1254218893Sdim if (FloatABI.empty()) { 1255263508Sdim // Assume "soft", but warn the user we are guessing. 1256263508Sdim FloatABI = "soft"; 1257263508Sdim D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 1258218893Sdim } 1259218893Sdim 1260218893Sdim if (FloatABI == "soft") { 1261218893Sdim // Floating point operations and argument passing are soft. 1262218893Sdim // 1263218893Sdim // FIXME: This changes CPP defines, we need -target-soft-float. 1264218893Sdim CmdArgs.push_back("-msoft-float"); 1265218893Sdim } else { 1266218893Sdim assert(FloatABI == "hard" && "Invalid float abi!"); 1267218893Sdim CmdArgs.push_back("-mhard-float"); 1268218893Sdim } 1269218893Sdim} 1270218893Sdim 1271263508Sdimstatic const char *getSystemZTargetCPU(const ArgList &Args) { 1272263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 1273263508Sdim return A->getValue(); 1274263508Sdim return "z10"; 1275263508Sdim} 1276263508Sdim 1277247166Sdimstatic const char *getX86TargetCPU(const ArgList &Args, 1278247166Sdim const llvm::Triple &Triple) { 1279247166Sdim if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 1280263508Sdim if (StringRef(A->getValue()) != "native") { 1281263508Sdim if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h") 1282263508Sdim return "core-avx2"; 1283263508Sdim 1284247166Sdim return A->getValue(); 1285263508Sdim } 1286247166Sdim 1287247166Sdim // FIXME: Reject attempts to use -march=native unless the target matches 1288247166Sdim // the host. 1289247166Sdim // 1290247166Sdim // FIXME: We should also incorporate the detected target features for use 1291247166Sdim // with -native. 1292247166Sdim std::string CPU = llvm::sys::getHostCPUName(); 1293247166Sdim if (!CPU.empty() && CPU != "generic") 1294247166Sdim return Args.MakeArgString(CPU); 1295247166Sdim } 1296247166Sdim 1297247166Sdim // Select the default CPU if none was given (or detection failed). 1298247166Sdim 1299247166Sdim if (Triple.getArch() != llvm::Triple::x86_64 && 1300247166Sdim Triple.getArch() != llvm::Triple::x86) 1301247166Sdim return 0; // This routine is only handling x86 targets. 1302247166Sdim 1303247166Sdim bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; 1304247166Sdim 1305247166Sdim // FIXME: Need target hooks. 1306263508Sdim if (Triple.isOSDarwin()) { 1307263508Sdim if (Triple.getArchName() == "x86_64h") 1308263508Sdim return "core-avx2"; 1309247166Sdim return Is64Bit ? "core2" : "yonah"; 1310263508Sdim } 1311247166Sdim 1312263508Sdim // All x86 devices running Android have core2 as their common 1313263508Sdim // denominator. This makes a better choice than pentium4. 1314263508Sdim if (Triple.getEnvironment() == llvm::Triple::Android) 1315263508Sdim return "core2"; 1316263508Sdim 1317247166Sdim // Everything else goes to x86-64 in 64-bit mode. 1318247166Sdim if (Is64Bit) 1319247166Sdim return "x86-64"; 1320247166Sdim 1321263508Sdim switch (Triple.getOS()) { 1322263508Sdim case llvm::Triple::FreeBSD: 1323263508Sdim case llvm::Triple::NetBSD: 1324263508Sdim case llvm::Triple::OpenBSD: 1325263508Sdim return "i486"; 1326263508Sdim case llvm::Triple::Haiku: 1327247166Sdim return "i586"; 1328263508Sdim case llvm::Triple::Bitrig: 1329247166Sdim return "i686"; 1330263508Sdim default: 1331263508Sdim // Fallback to p4. 1332263508Sdim return "pentium4"; 1333263508Sdim } 1334263508Sdim} 1335247166Sdim 1336263508Sdimstatic std::string getCPUName(const ArgList &Args, const llvm::Triple &T) { 1337263508Sdim switch(T.getArch()) { 1338263508Sdim default: 1339263508Sdim return ""; 1340263508Sdim 1341263508Sdim case llvm::Triple::aarch64: 1342263508Sdim return getAArch64TargetCPU(Args, T); 1343263508Sdim 1344263508Sdim case llvm::Triple::arm: 1345263508Sdim case llvm::Triple::thumb: 1346263508Sdim return getARMTargetCPU(Args, T); 1347263508Sdim 1348263508Sdim case llvm::Triple::mips: 1349263508Sdim case llvm::Triple::mipsel: 1350263508Sdim case llvm::Triple::mips64: 1351263508Sdim case llvm::Triple::mips64el: { 1352263508Sdim StringRef CPUName; 1353263508Sdim StringRef ABIName; 1354263508Sdim getMipsCPUAndABI(Args, T, CPUName, ABIName); 1355263508Sdim return CPUName; 1356263508Sdim } 1357263508Sdim 1358263508Sdim case llvm::Triple::ppc: 1359263508Sdim case llvm::Triple::ppc64: 1360263508Sdim case llvm::Triple::ppc64le: { 1361263508Sdim std::string TargetCPUName = getPPCTargetCPU(Args); 1362263508Sdim // LLVM may default to generating code for the native CPU, 1363263508Sdim // but, like gcc, we default to a more generic option for 1364263508Sdim // each architecture. (except on Darwin) 1365263508Sdim if (TargetCPUName.empty() && !T.isOSDarwin()) { 1366263508Sdim if (T.getArch() == llvm::Triple::ppc64) 1367263508Sdim TargetCPUName = "ppc64"; 1368263508Sdim else if (T.getArch() == llvm::Triple::ppc64le) 1369263508Sdim TargetCPUName = "ppc64le"; 1370263508Sdim else 1371263508Sdim TargetCPUName = "ppc"; 1372263508Sdim } 1373263508Sdim return TargetCPUName; 1374263508Sdim } 1375263508Sdim 1376263508Sdim case llvm::Triple::sparc: 1377263763Sdim case llvm::Triple::sparcv9: 1378263763Sdim if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 1379263508Sdim return A->getValue(); 1380263508Sdim return ""; 1381263508Sdim 1382263508Sdim case llvm::Triple::x86: 1383263508Sdim case llvm::Triple::x86_64: 1384263508Sdim return getX86TargetCPU(Args, T); 1385263508Sdim 1386263508Sdim case llvm::Triple::hexagon: 1387263508Sdim return "hexagon" + toolchains::Hexagon_TC::GetTargetCPU(Args).str(); 1388263508Sdim 1389263508Sdim case llvm::Triple::systemz: 1390263508Sdim return getSystemZTargetCPU(Args); 1391263508Sdim 1392263508Sdim case llvm::Triple::r600: 1393263508Sdim return getR600TargetGPU(Args); 1394263508Sdim } 1395247166Sdim} 1396247166Sdim 1397263508Sdimstatic void getX86TargetFeatures(const llvm::Triple &Triple, 1398263508Sdim const ArgList &Args, 1399263508Sdim std::vector<const char *> &Features) { 1400263508Sdim if (Triple.getArchName() == "x86_64h") { 1401263508Sdim // x86_64h implies quite a few of the more modern subtarget features 1402263508Sdim // for Haswell class CPUs, but not all of them. Opt-out of a few. 1403263508Sdim Features.push_back("-rdrnd"); 1404263508Sdim Features.push_back("-aes"); 1405263508Sdim Features.push_back("-pclmul"); 1406263508Sdim Features.push_back("-rtm"); 1407263508Sdim Features.push_back("-hle"); 1408263508Sdim Features.push_back("-fsgsbase"); 1409263508Sdim } 1410263508Sdim 1411263508Sdim // Now add any that the user explicitly requested on the command line, 1412263508Sdim // which may override the defaults. 1413263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group), 1414263508Sdim ie = Args.filtered_end(); 1415263508Sdim it != ie; ++it) { 1416263508Sdim StringRef Name = (*it)->getOption().getName(); 1417263508Sdim (*it)->claim(); 1418263508Sdim 1419263508Sdim // Skip over "-m". 1420263508Sdim assert(Name.startswith("m") && "Invalid feature name."); 1421263508Sdim Name = Name.substr(1); 1422263508Sdim 1423263508Sdim bool IsNegative = Name.startswith("no-"); 1424263508Sdim if (IsNegative) 1425263508Sdim Name = Name.substr(3); 1426263508Sdim 1427263508Sdim Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); 1428263508Sdim } 1429263508Sdim} 1430263508Sdim 1431198092Srdivackyvoid Clang::AddX86TargetArgs(const ArgList &Args, 1432198092Srdivacky ArgStringList &CmdArgs) const { 1433198092Srdivacky if (!Args.hasFlag(options::OPT_mred_zone, 1434198092Srdivacky options::OPT_mno_red_zone, 1435198092Srdivacky true) || 1436198092Srdivacky Args.hasArg(options::OPT_mkernel) || 1437198092Srdivacky Args.hasArg(options::OPT_fapple_kext)) 1438199990Srdivacky CmdArgs.push_back("-disable-red-zone"); 1439198092Srdivacky 1440249423Sdim // Default to avoid implicit floating-point for kernel/kext code, but allow 1441249423Sdim // that to be overridden with -mno-soft-float. 1442249423Sdim bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) || 1443249423Sdim Args.hasArg(options::OPT_fapple_kext)); 1444249423Sdim if (Arg *A = Args.getLastArg(options::OPT_msoft_float, 1445249423Sdim options::OPT_mno_soft_float, 1446251662Sdim options::OPT_mimplicit_float, 1447249423Sdim options::OPT_mno_implicit_float)) { 1448249423Sdim const Option &O = A->getOption(); 1449249423Sdim NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) || 1450249423Sdim O.matches(options::OPT_msoft_float)); 1451249423Sdim } 1452249423Sdim if (NoImplicitFloat) 1453199990Srdivacky CmdArgs.push_back("-no-implicit-float"); 1454198092Srdivacky} 1455198092Srdivacky 1456249423Sdimstatic inline bool HasPICArg(const ArgList &Args) { 1457249423Sdim return Args.hasArg(options::OPT_fPIC) 1458249423Sdim || Args.hasArg(options::OPT_fpic); 1459249423Sdim} 1460234353Sdim 1461249423Sdimstatic Arg *GetLastSmallDataThresholdArg(const ArgList &Args) { 1462249423Sdim return Args.getLastArg(options::OPT_G, 1463249423Sdim options::OPT_G_EQ, 1464249423Sdim options::OPT_msmall_data_threshold_EQ); 1465234353Sdim} 1466234353Sdim 1467249423Sdimstatic std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) { 1468249423Sdim std::string value; 1469249423Sdim if (HasPICArg(Args)) 1470249423Sdim value = "0"; 1471249423Sdim else if (Arg *A = GetLastSmallDataThresholdArg(Args)) { 1472249423Sdim value = A->getValue(); 1473249423Sdim A->claim(); 1474234353Sdim } 1475249423Sdim return value; 1476234353Sdim} 1477234353Sdim 1478234353Sdimvoid Clang::AddHexagonTargetArgs(const ArgList &Args, 1479234353Sdim ArgStringList &CmdArgs) const { 1480234353Sdim CmdArgs.push_back("-fno-signed-char"); 1481249423Sdim CmdArgs.push_back("-mqdsp6-compat"); 1482249423Sdim CmdArgs.push_back("-Wreturn-type"); 1483234353Sdim 1484249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 1485249423Sdim if (!SmallDataThreshold.empty()) { 1486234353Sdim CmdArgs.push_back ("-mllvm"); 1487249423Sdim CmdArgs.push_back(Args.MakeArgString( 1488249423Sdim "-hexagon-small-data-threshold=" + SmallDataThreshold)); 1489234353Sdim } 1490234353Sdim 1491239462Sdim if (!Args.hasArg(options::OPT_fno_short_enums)) 1492239462Sdim CmdArgs.push_back("-fshort-enums"); 1493239462Sdim if (Args.getLastArg(options::OPT_mieee_rnd_near)) { 1494239462Sdim CmdArgs.push_back ("-mllvm"); 1495239462Sdim CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near"); 1496239462Sdim } 1497234353Sdim CmdArgs.push_back ("-mllvm"); 1498234353Sdim CmdArgs.push_back ("-machine-sink-split=0"); 1499234353Sdim} 1500234353Sdim 1501263508Sdimstatic void getAArch64TargetFeatures(const Driver &D, const ArgList &Args, 1502263508Sdim std::vector<const char *> &Features) { 1503263508Sdim // Honor -mfpu=. 1504263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) 1505263508Sdim getAArch64FPUFeatures(D, A, Args, Features); 1506263508Sdim} 1507263508Sdim 1508263508Sdimstatic void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, 1509263508Sdim const ArgList &Args, ArgStringList &CmdArgs) { 1510263508Sdim std::vector<const char *> Features; 1511263508Sdim switch (Triple.getArch()) { 1512263508Sdim default: 1513263508Sdim break; 1514263508Sdim case llvm::Triple::mips: 1515263508Sdim case llvm::Triple::mipsel: 1516263508Sdim case llvm::Triple::mips64: 1517263508Sdim case llvm::Triple::mips64el: 1518263508Sdim getMIPSTargetFeatures(D, Args, Features); 1519263508Sdim break; 1520263508Sdim 1521263508Sdim case llvm::Triple::arm: 1522263508Sdim case llvm::Triple::thumb: 1523263508Sdim getARMTargetFeatures(D, Triple, Args, Features); 1524263508Sdim break; 1525263508Sdim 1526263508Sdim case llvm::Triple::ppc: 1527263508Sdim case llvm::Triple::ppc64: 1528263508Sdim case llvm::Triple::ppc64le: 1529263508Sdim getPPCTargetFeatures(Args, Features); 1530263508Sdim break; 1531263508Sdim case llvm::Triple::sparc: 1532263508Sdim getSparcTargetFeatures(Args, Features); 1533263508Sdim break; 1534263508Sdim case llvm::Triple::aarch64: 1535263508Sdim getAArch64TargetFeatures(D, Args, Features); 1536263508Sdim break; 1537263508Sdim case llvm::Triple::x86: 1538263508Sdim case llvm::Triple::x86_64: 1539263508Sdim getX86TargetFeatures(Triple, Args, Features); 1540263508Sdim break; 1541263508Sdim } 1542263508Sdim 1543263508Sdim // Find the last of each feature. 1544263508Sdim llvm::StringMap<unsigned> LastOpt; 1545263508Sdim for (unsigned I = 0, N = Features.size(); I < N; ++I) { 1546263508Sdim const char *Name = Features[I]; 1547263508Sdim assert(Name[0] == '-' || Name[0] == '+'); 1548263508Sdim LastOpt[Name + 1] = I; 1549263508Sdim } 1550263508Sdim 1551263508Sdim for (unsigned I = 0, N = Features.size(); I < N; ++I) { 1552263508Sdim // If this feature was overridden, ignore it. 1553263508Sdim const char *Name = Features[I]; 1554263508Sdim llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1); 1555263508Sdim assert(LastI != LastOpt.end()); 1556263508Sdim unsigned Last = LastI->second; 1557263508Sdim if (Last != I) 1558263508Sdim continue; 1559263508Sdim 1560263508Sdim CmdArgs.push_back("-target-feature"); 1561263508Sdim CmdArgs.push_back(Name); 1562263508Sdim } 1563263508Sdim} 1564263508Sdim 1565226633Sdimstatic bool 1566239462SdimshouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, 1567221345Sdim const llvm::Triple &Triple) { 1568221345Sdim // We use the zero-cost exception tables for Objective-C if the non-fragile 1569221345Sdim // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and 1570221345Sdim // later. 1571239462Sdim if (runtime.isNonFragile()) 1572221345Sdim return true; 1573221345Sdim 1574226633Sdim if (!Triple.isOSDarwin()) 1575221345Sdim return false; 1576221345Sdim 1577224145Sdim return (!Triple.isMacOSXVersionLT(10,5) && 1578221345Sdim (Triple.getArch() == llvm::Triple::x86_64 || 1579226633Sdim Triple.getArch() == llvm::Triple::arm)); 1580221345Sdim} 1581221345Sdim 1582221345Sdim/// addExceptionArgs - Adds exception related arguments to the driver command 1583221345Sdim/// arguments. There's a master flag, -fexceptions and also language specific 1584221345Sdim/// flags to enable/disable C++ and Objective-C exceptions. 1585221345Sdim/// This makes it possible to for example disable C++ exceptions but enable 1586221345Sdim/// Objective-C exceptions. 1587221345Sdimstatic void addExceptionArgs(const ArgList &Args, types::ID InputType, 1588221345Sdim const llvm::Triple &Triple, 1589234353Sdim bool KernelOrKext, 1590239462Sdim const ObjCRuntime &objcRuntime, 1591221345Sdim ArgStringList &CmdArgs) { 1592234353Sdim if (KernelOrKext) { 1593234353Sdim // -mkernel and -fapple-kext imply no exceptions, so claim exception related 1594234353Sdim // arguments now to avoid warnings about unused arguments. 1595234353Sdim Args.ClaimAllArgs(options::OPT_fexceptions); 1596234353Sdim Args.ClaimAllArgs(options::OPT_fno_exceptions); 1597234353Sdim Args.ClaimAllArgs(options::OPT_fobjc_exceptions); 1598234353Sdim Args.ClaimAllArgs(options::OPT_fno_objc_exceptions); 1599234353Sdim Args.ClaimAllArgs(options::OPT_fcxx_exceptions); 1600234353Sdim Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions); 1601221345Sdim return; 1602234353Sdim } 1603221345Sdim 1604221345Sdim // Exceptions are enabled by default. 1605221345Sdim bool ExceptionsEnabled = true; 1606221345Sdim 1607221345Sdim // This keeps track of whether exceptions were explicitly turned on or off. 1608221345Sdim bool DidHaveExplicitExceptionFlag = false; 1609221345Sdim 1610198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fexceptions, 1611198092Srdivacky options::OPT_fno_exceptions)) { 1612198092Srdivacky if (A->getOption().matches(options::OPT_fexceptions)) 1613221345Sdim ExceptionsEnabled = true; 1614226633Sdim else 1615221345Sdim ExceptionsEnabled = false; 1616221345Sdim 1617221345Sdim DidHaveExplicitExceptionFlag = true; 1618198092Srdivacky } 1619218893Sdim 1620221345Sdim bool ShouldUseExceptionTables = false; 1621198092Srdivacky 1622221345Sdim // Exception tables and cleanups can be enabled with -fexceptions even if the 1623221345Sdim // language itself doesn't support exceptions. 1624221345Sdim if (ExceptionsEnabled && DidHaveExplicitExceptionFlag) 1625221345Sdim ShouldUseExceptionTables = true; 1626221345Sdim 1627221345Sdim // Obj-C exceptions are enabled by default, regardless of -fexceptions. This 1628221345Sdim // is not necessarily sensible, but follows GCC. 1629221345Sdim if (types::isObjC(InputType) && 1630226633Sdim Args.hasFlag(options::OPT_fobjc_exceptions, 1631221345Sdim options::OPT_fno_objc_exceptions, 1632221345Sdim true)) { 1633221345Sdim CmdArgs.push_back("-fobjc-exceptions"); 1634221345Sdim 1635226633Sdim ShouldUseExceptionTables |= 1636239462Sdim shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple); 1637218893Sdim } 1638198092Srdivacky 1639221345Sdim if (types::isCXX(InputType)) { 1640221345Sdim bool CXXExceptionsEnabled = ExceptionsEnabled; 1641221345Sdim 1642226633Sdim if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions, 1643226633Sdim options::OPT_fno_cxx_exceptions, 1644221345Sdim options::OPT_fexceptions, 1645221345Sdim options::OPT_fno_exceptions)) { 1646221345Sdim if (A->getOption().matches(options::OPT_fcxx_exceptions)) 1647221345Sdim CXXExceptionsEnabled = true; 1648221345Sdim else if (A->getOption().matches(options::OPT_fno_cxx_exceptions)) 1649221345Sdim CXXExceptionsEnabled = false; 1650221345Sdim } 1651221345Sdim 1652221345Sdim if (CXXExceptionsEnabled) { 1653221345Sdim CmdArgs.push_back("-fcxx-exceptions"); 1654221345Sdim 1655221345Sdim ShouldUseExceptionTables = true; 1656221345Sdim } 1657221345Sdim } 1658221345Sdim 1659221345Sdim if (ShouldUseExceptionTables) 1660221345Sdim CmdArgs.push_back("-fexceptions"); 1661198092Srdivacky} 1662198092Srdivacky 1663251662Sdimstatic bool ShouldDisableAutolink(const ArgList &Args, 1664251662Sdim const ToolChain &TC) { 1665251662Sdim bool Default = true; 1666251662Sdim if (TC.getTriple().isOSDarwin()) { 1667251662Sdim // The native darwin assembler doesn't support the linker_option directives, 1668251662Sdim // so we disable them if we think the .s file will be passed to it. 1669251662Sdim Default = TC.useIntegratedAs(); 1670251662Sdim } 1671251662Sdim return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink, 1672251662Sdim Default); 1673251662Sdim} 1674251662Sdim 1675221345Sdimstatic bool ShouldDisableCFI(const ArgList &Args, 1676221345Sdim const ToolChain &TC) { 1677234353Sdim bool Default = true; 1678226633Sdim if (TC.getTriple().isOSDarwin()) { 1679223017Sdim // The native darwin assembler doesn't support cfi directives, so 1680223017Sdim // we disable them if we think the .s file will be passed to it. 1681249423Sdim Default = TC.useIntegratedAs(); 1682223017Sdim } 1683234353Sdim return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm, 1684249423Sdim options::OPT_fno_dwarf2_cfi_asm, 1685249423Sdim Default); 1686234353Sdim} 1687223017Sdim 1688234353Sdimstatic bool ShouldDisableDwarfDirectory(const ArgList &Args, 1689234353Sdim const ToolChain &TC) { 1690234353Sdim bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm, 1691234353Sdim options::OPT_fno_dwarf_directory_asm, 1692249423Sdim TC.useIntegratedAs()); 1693234353Sdim return !UseDwarfDirectory; 1694221345Sdim} 1695221345Sdim 1696223017Sdim/// \brief Check whether the given input tree contains any compilation actions. 1697223017Sdimstatic bool ContainsCompileAction(const Action *A) { 1698223017Sdim if (isa<CompileJobAction>(A)) 1699223017Sdim return true; 1700223017Sdim 1701223017Sdim for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it) 1702223017Sdim if (ContainsCompileAction(*it)) 1703223017Sdim return true; 1704223017Sdim 1705223017Sdim return false; 1706223017Sdim} 1707223017Sdim 1708223017Sdim/// \brief Check if -relax-all should be passed to the internal assembler. 1709223017Sdim/// This is done by default when compiling non-assembler source with -O0. 1710223017Sdimstatic bool UseRelaxAll(Compilation &C, const ArgList &Args) { 1711223017Sdim bool RelaxDefault = true; 1712223017Sdim 1713223017Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 1714223017Sdim RelaxDefault = A->getOption().matches(options::OPT_O0); 1715223017Sdim 1716223017Sdim if (RelaxDefault) { 1717223017Sdim RelaxDefault = false; 1718223017Sdim for (ActionList::const_iterator it = C.getActions().begin(), 1719223017Sdim ie = C.getActions().end(); it != ie; ++it) { 1720223017Sdim if (ContainsCompileAction(*it)) { 1721223017Sdim RelaxDefault = true; 1722223017Sdim break; 1723223017Sdim } 1724223017Sdim } 1725223017Sdim } 1726223017Sdim 1727223017Sdim return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all, 1728223017Sdim RelaxDefault); 1729223017Sdim} 1730223017Sdim 1731263508Sdimstatic void CollectArgsForIntegratedAssembler(Compilation &C, 1732263508Sdim const ArgList &Args, 1733263508Sdim ArgStringList &CmdArgs, 1734263508Sdim const Driver &D) { 1735263508Sdim if (UseRelaxAll(C, Args)) 1736263508Sdim CmdArgs.push_back("-mrelax-all"); 1737243830Sdim 1738263508Sdim // When passing -I arguments to the assembler we sometimes need to 1739263508Sdim // unconditionally take the next argument. For example, when parsing 1740263508Sdim // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the 1741263508Sdim // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo' 1742263508Sdim // arg after parsing the '-I' arg. 1743263508Sdim bool TakeNextArg = false; 1744243830Sdim 1745263508Sdim // When using an integrated assembler, translate -Wa, and -Xassembler 1746263508Sdim // options. 1747263508Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA, 1748263508Sdim options::OPT_Xassembler), 1749263508Sdim ie = Args.filtered_end(); it != ie; ++it) { 1750263508Sdim const Arg *A = *it; 1751263508Sdim A->claim(); 1752243830Sdim 1753263508Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 1754263508Sdim StringRef Value = A->getValue(i); 1755263508Sdim if (TakeNextArg) { 1756263508Sdim CmdArgs.push_back(Value.data()); 1757263508Sdim TakeNextArg = false; 1758263508Sdim continue; 1759263508Sdim } 1760249423Sdim 1761263508Sdim if (Value == "-force_cpusubtype_ALL") { 1762263508Sdim // Do nothing, this is the default and we don't support anything else. 1763263508Sdim } else if (Value == "-L") { 1764263508Sdim CmdArgs.push_back("-msave-temp-labels"); 1765263508Sdim } else if (Value == "--fatal-warnings") { 1766263508Sdim CmdArgs.push_back("-mllvm"); 1767263508Sdim CmdArgs.push_back("-fatal-assembler-warnings"); 1768263508Sdim } else if (Value == "--noexecstack") { 1769263508Sdim CmdArgs.push_back("-mnoexecstack"); 1770263508Sdim } else if (Value.startswith("-I")) { 1771263508Sdim CmdArgs.push_back(Value.data()); 1772263508Sdim // We need to consume the next argument if the current arg is a plain 1773263508Sdim // -I. The next arg will be the include directory. 1774263508Sdim if (Value == "-I") 1775263508Sdim TakeNextArg = true; 1776263508Sdim } else { 1777263508Sdim D.Diag(diag::err_drv_unsupported_option_argument) 1778263508Sdim << A->getOption().getName() << Value; 1779263508Sdim } 1780263508Sdim } 1781263508Sdim } 1782263508Sdim} 1783249423Sdim 1784263508Sdimstatic void addProfileRTLinux( 1785263508Sdim const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { 1786263508Sdim if (!(Args.hasArg(options::OPT_fprofile_arcs) || 1787263508Sdim Args.hasArg(options::OPT_fprofile_generate) || 1788263508Sdim Args.hasArg(options::OPT_fcreate_profile) || 1789263508Sdim Args.hasArg(options::OPT_coverage))) 1790263508Sdim return; 1791249423Sdim 1792263508Sdim // The profile runtime is located in the Linux library directory and has name 1793263508Sdim // "libclang_rt.profile-<ArchName>.a". 1794263508Sdim SmallString<128> LibProfile(TC.getDriver().ResourceDir); 1795263508Sdim llvm::sys::path::append( 1796263508Sdim LibProfile, "lib", "linux", 1797263508Sdim Twine("libclang_rt.profile-") + TC.getArchName() + ".a"); 1798249423Sdim 1799263508Sdim CmdArgs.push_back(Args.MakeArgString(LibProfile)); 1800243830Sdim} 1801243830Sdim 1802249423Sdimstatic void addSanitizerRTLinkFlagsLinux( 1803249423Sdim const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, 1804249423Sdim const StringRef Sanitizer, bool BeforeLibStdCXX, 1805249423Sdim bool ExportSymbols = true) { 1806249423Sdim // Sanitizer runtime is located in the Linux library directory and 1807249423Sdim // has name "libclang_rt.<Sanitizer>-<ArchName>.a". 1808249423Sdim SmallString<128> LibSanitizer(TC.getDriver().ResourceDir); 1809249423Sdim llvm::sys::path::append( 1810249423Sdim LibSanitizer, "lib", "linux", 1811249423Sdim (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a")); 1812249423Sdim 1813249423Sdim // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a, 1814249423Sdim // etc.) so that the linker picks custom versions of the global 'operator 1815249423Sdim // new' and 'operator delete' symbols. We take the extreme (but simple) 1816249423Sdim // strategy of inserting it at the front of the link command. It also 1817249423Sdim // needs to be forced to end up in the executable, so wrap it in 1818249423Sdim // whole-archive. 1819249423Sdim SmallVector<const char *, 3> LibSanitizerArgs; 1820249423Sdim LibSanitizerArgs.push_back("-whole-archive"); 1821249423Sdim LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer)); 1822249423Sdim LibSanitizerArgs.push_back("-no-whole-archive"); 1823249423Sdim 1824249423Sdim CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(), 1825249423Sdim LibSanitizerArgs.begin(), LibSanitizerArgs.end()); 1826249423Sdim 1827249423Sdim CmdArgs.push_back("-lpthread"); 1828251662Sdim CmdArgs.push_back("-lrt"); 1829249423Sdim CmdArgs.push_back("-ldl"); 1830263508Sdim CmdArgs.push_back("-lm"); 1831249423Sdim 1832249423Sdim // If possible, use a dynamic symbols file to export the symbols from the 1833249423Sdim // runtime library. If we can't do so, use -export-dynamic instead to export 1834249423Sdim // all symbols from the binary. 1835249423Sdim if (ExportSymbols) { 1836249423Sdim if (llvm::sys::fs::exists(LibSanitizer + ".syms")) 1837249423Sdim CmdArgs.push_back( 1838249423Sdim Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms")); 1839249423Sdim else 1840249423Sdim CmdArgs.push_back("-export-dynamic"); 1841249423Sdim } 1842249423Sdim} 1843249423Sdim 1844234353Sdim/// If AddressSanitizer is enabled, add appropriate linker flags (Linux). 1845234353Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1846234353Sdimstatic void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, 1847234353Sdim ArgStringList &CmdArgs) { 1848263508Sdim if (TC.getTriple().getEnvironment() == llvm::Triple::Android) { 1849243830Sdim SmallString<128> LibAsan(TC.getDriver().ResourceDir); 1850243830Sdim llvm::sys::path::append(LibAsan, "lib", "linux", 1851243830Sdim (Twine("libclang_rt.asan-") + 1852243830Sdim TC.getArchName() + "-android.so")); 1853249423Sdim CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan)); 1854239462Sdim } else { 1855263508Sdim if (!Args.hasArg(options::OPT_shared)) 1856249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true); 1857239462Sdim } 1858234353Sdim} 1859234353Sdim 1860239462Sdim/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux). 1861239462Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1862239462Sdimstatic void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, 1863239462Sdim ArgStringList &CmdArgs) { 1864263508Sdim if (!Args.hasArg(options::OPT_shared)) 1865249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true); 1866239462Sdim} 1867239462Sdim 1868249423Sdim/// If MemorySanitizer is enabled, add appropriate linker flags (Linux). 1869249423Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1870249423Sdimstatic void addMsanRTLinux(const ToolChain &TC, const ArgList &Args, 1871249423Sdim ArgStringList &CmdArgs) { 1872263508Sdim if (!Args.hasArg(options::OPT_shared)) 1873249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true); 1874249423Sdim} 1875249423Sdim 1876263508Sdim/// If LeakSanitizer is enabled, add appropriate linker flags (Linux). 1877263508Sdim/// This needs to be called before we add the C run-time (malloc, etc). 1878263508Sdimstatic void addLsanRTLinux(const ToolChain &TC, const ArgList &Args, 1879263508Sdim ArgStringList &CmdArgs) { 1880263508Sdim if (!Args.hasArg(options::OPT_shared)) 1881263508Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true); 1882263508Sdim} 1883263508Sdim 1884243830Sdim/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags 1885243830Sdim/// (Linux). 1886243830Sdimstatic void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args, 1887249423Sdim ArgStringList &CmdArgs, bool IsCXX, 1888249423Sdim bool HasOtherSanitizerRt) { 1889249423Sdim // Need a copy of sanitizer_common. This could come from another sanitizer 1890249423Sdim // runtime; if we're not including one, include our own copy. 1891249423Sdim if (!HasOtherSanitizerRt) 1892249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false); 1893249423Sdim 1894249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false); 1895249423Sdim 1896249423Sdim // Only include the bits of the runtime which need a C++ ABI library if 1897249423Sdim // we're linking in C++ mode. 1898249423Sdim if (IsCXX) 1899249423Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false); 1900243830Sdim} 1901243830Sdim 1902263508Sdimstatic void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args, 1903263508Sdim ArgStringList &CmdArgs) { 1904263508Sdim if (!Args.hasArg(options::OPT_shared)) 1905263508Sdim addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true); 1906263508Sdim} 1907263508Sdim 1908263508Sdimstatic bool shouldUseFramePointerForTarget(const ArgList &Args, 1909263508Sdim const llvm::Triple &Triple) { 1910263508Sdim switch (Triple.getArch()) { 1911263508Sdim // Don't use a frame pointer on linux if optimizing for certain targets. 1912263508Sdim case llvm::Triple::mips64: 1913263508Sdim case llvm::Triple::mips64el: 1914263508Sdim case llvm::Triple::mips: 1915263508Sdim case llvm::Triple::mipsel: 1916263508Sdim case llvm::Triple::systemz: 1917263508Sdim case llvm::Triple::x86: 1918263508Sdim case llvm::Triple::x86_64: 1919263508Sdim if (Triple.isOSLinux()) 1920263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) 1921263508Sdim if (!A->getOption().matches(options::OPT_O0)) 1922263508Sdim return false; 1923263508Sdim return true; 1924263508Sdim case llvm::Triple::xcore: 1925263508Sdim return false; 1926263508Sdim default: 1927263508Sdim return true; 1928263508Sdim } 1929263508Sdim} 1930263508Sdim 1931234353Sdimstatic bool shouldUseFramePointer(const ArgList &Args, 1932234353Sdim const llvm::Triple &Triple) { 1933234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer, 1934234353Sdim options::OPT_fomit_frame_pointer)) 1935234353Sdim return A->getOption().matches(options::OPT_fno_omit_frame_pointer); 1936234353Sdim 1937263508Sdim return shouldUseFramePointerForTarget(Args, Triple); 1938234353Sdim} 1939234353Sdim 1940249423Sdimstatic bool shouldUseLeafFramePointer(const ArgList &Args, 1941249423Sdim const llvm::Triple &Triple) { 1942249423Sdim if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer, 1943249423Sdim options::OPT_momit_leaf_frame_pointer)) 1944249423Sdim return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer); 1945249423Sdim 1946263508Sdim return shouldUseFramePointerForTarget(Args, Triple); 1947249423Sdim} 1948249423Sdim 1949263508Sdim/// Add a CC1 option to specify the debug compilation directory. 1950249423Sdimstatic void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { 1951251662Sdim SmallString<128> cwd; 1952251662Sdim if (!llvm::sys::fs::current_path(cwd)) { 1953251662Sdim CmdArgs.push_back("-fdebug-compilation-dir"); 1954251662Sdim CmdArgs.push_back(Args.MakeArgString(cwd)); 1955251662Sdim } 1956249423Sdim} 1957249423Sdim 1958249423Sdimstatic const char *SplitDebugName(const ArgList &Args, 1959249423Sdim const InputInfoList &Inputs) { 1960249423Sdim Arg *FinalOutput = Args.getLastArg(options::OPT_o); 1961249423Sdim if (FinalOutput && Args.hasArg(options::OPT_c)) { 1962249423Sdim SmallString<128> T(FinalOutput->getValue()); 1963249423Sdim llvm::sys::path::replace_extension(T, "dwo"); 1964249423Sdim return Args.MakeArgString(T); 1965249423Sdim } else { 1966249423Sdim // Use the compilation dir. 1967249423Sdim SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir)); 1968249423Sdim SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput())); 1969249423Sdim llvm::sys::path::replace_extension(F, "dwo"); 1970249423Sdim T += F; 1971249423Sdim return Args.MakeArgString(F); 1972249423Sdim } 1973249423Sdim} 1974249423Sdim 1975249423Sdimstatic void SplitDebugInfo(const ToolChain &TC, Compilation &C, 1976249423Sdim const Tool &T, const JobAction &JA, 1977249423Sdim const ArgList &Args, const InputInfo &Output, 1978249423Sdim const char *OutFile) { 1979249423Sdim ArgStringList ExtractArgs; 1980249423Sdim ExtractArgs.push_back("--extract-dwo"); 1981249423Sdim 1982249423Sdim ArgStringList StripArgs; 1983249423Sdim StripArgs.push_back("--strip-dwo"); 1984249423Sdim 1985249423Sdim // Grabbing the output of the earlier compile step. 1986249423Sdim StripArgs.push_back(Output.getFilename()); 1987249423Sdim ExtractArgs.push_back(Output.getFilename()); 1988249423Sdim ExtractArgs.push_back(OutFile); 1989249423Sdim 1990249423Sdim const char *Exec = 1991249423Sdim Args.MakeArgString(TC.GetProgramPath("objcopy")); 1992249423Sdim 1993249423Sdim // First extract the dwo sections. 1994249423Sdim C.addCommand(new Command(JA, T, Exec, ExtractArgs)); 1995249423Sdim 1996249423Sdim // Then remove them from the original .o file. 1997249423Sdim C.addCommand(new Command(JA, T, Exec, StripArgs)); 1998249423Sdim} 1999249423Sdim 2000263508Sdim/// \brief Vectorize at all optimization levels greater than 1 except for -Oz. 2001263508Sdimstatic bool shouldEnableVectorizerAtOLevel(const ArgList &Args) { 2002263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 2003263508Sdim if (A->getOption().matches(options::OPT_O4) || 2004263508Sdim A->getOption().matches(options::OPT_Ofast)) 2005263508Sdim return true; 2006263508Sdim 2007263508Sdim if (A->getOption().matches(options::OPT_O0)) 2008263508Sdim return false; 2009263508Sdim 2010263508Sdim assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag"); 2011263508Sdim 2012263508Sdim // Vectorize -Os. 2013263508Sdim StringRef S(A->getValue()); 2014263508Sdim if (S == "s") 2015263508Sdim return true; 2016263508Sdim 2017263508Sdim // Don't vectorize -Oz. 2018263508Sdim if (S == "z") 2019263508Sdim return false; 2020263508Sdim 2021263508Sdim unsigned OptLevel = 0; 2022263508Sdim if (S.getAsInteger(10, OptLevel)) 2023263508Sdim return false; 2024263508Sdim 2025263508Sdim return OptLevel > 1; 2026263508Sdim } 2027263508Sdim 2028263508Sdim return false; 2029263508Sdim} 2030263508Sdim 2031193326Sedvoid Clang::ConstructJob(Compilation &C, const JobAction &JA, 2032193326Sed const InputInfo &Output, 2033193326Sed const InputInfoList &Inputs, 2034193326Sed const ArgList &Args, 2035193326Sed const char *LinkingOutput) const { 2036205408Srdivacky bool KernelOrKext = Args.hasArg(options::OPT_mkernel, 2037205408Srdivacky options::OPT_fapple_kext); 2038201361Srdivacky const Driver &D = getToolChain().getDriver(); 2039193326Sed ArgStringList CmdArgs; 2040193326Sed 2041193326Sed assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 2042193326Sed 2043200583Srdivacky // Invoke ourselves in -cc1 mode. 2044200583Srdivacky // 2045200583Srdivacky // FIXME: Implement custom jobs for internal actions. 2046200583Srdivacky CmdArgs.push_back("-cc1"); 2047200583Srdivacky 2048198893Srdivacky // Add the "effective" target triple. 2049193326Sed CmdArgs.push_back("-triple"); 2050212904Sdim std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 2051198893Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 2052198092Srdivacky 2053198893Srdivacky // Select the appropriate action. 2054239462Sdim RewriteKind rewriteKind = RK_None; 2055234353Sdim 2056193326Sed if (isa<AnalyzeJobAction>(JA)) { 2057193326Sed assert(JA.getType() == types::TY_Plist && "Invalid output type."); 2058193326Sed CmdArgs.push_back("-analyze"); 2059234353Sdim } else if (isa<MigrateJobAction>(JA)) { 2060234353Sdim CmdArgs.push_back("-migrate"); 2061193326Sed } else if (isa<PreprocessJobAction>(JA)) { 2062193326Sed if (Output.getType() == types::TY_Dependencies) 2063193326Sed CmdArgs.push_back("-Eonly"); 2064249423Sdim else { 2065193326Sed CmdArgs.push_back("-E"); 2066249423Sdim if (Args.hasArg(options::OPT_rewrite_objc) && 2067249423Sdim !Args.hasArg(options::OPT_g_Group)) 2068249423Sdim CmdArgs.push_back("-P"); 2069249423Sdim } 2070203955Srdivacky } else if (isa<AssembleJobAction>(JA)) { 2071203955Srdivacky CmdArgs.push_back("-emit-obj"); 2072208600Srdivacky 2073263508Sdim CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D); 2074212904Sdim 2075218893Sdim // Also ignore explicit -force_cpusubtype_ALL option. 2076218893Sdim (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); 2077193326Sed } else if (isa<PrecompileJobAction>(JA)) { 2078212904Sdim // Use PCH if the user requested it. 2079198398Srdivacky bool UsePCH = D.CCCUsePCH; 2080198398Srdivacky 2081239462Sdim if (JA.getType() == types::TY_Nothing) 2082239462Sdim CmdArgs.push_back("-fsyntax-only"); 2083239462Sdim else if (UsePCH) 2084193326Sed CmdArgs.push_back("-emit-pch"); 2085193326Sed else 2086193326Sed CmdArgs.push_back("-emit-pth"); 2087193326Sed } else { 2088193326Sed assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool."); 2089193326Sed 2090193326Sed if (JA.getType() == types::TY_Nothing) { 2091193326Sed CmdArgs.push_back("-fsyntax-only"); 2092210299Sed } else if (JA.getType() == types::TY_LLVM_IR || 2093210299Sed JA.getType() == types::TY_LTO_IR) { 2094193326Sed CmdArgs.push_back("-emit-llvm"); 2095210299Sed } else if (JA.getType() == types::TY_LLVM_BC || 2096210299Sed JA.getType() == types::TY_LTO_BC) { 2097193326Sed CmdArgs.push_back("-emit-llvm-bc"); 2098193326Sed } else if (JA.getType() == types::TY_PP_Asm) { 2099193326Sed CmdArgs.push_back("-S"); 2100198092Srdivacky } else if (JA.getType() == types::TY_AST) { 2101198092Srdivacky CmdArgs.push_back("-emit-pch"); 2102249423Sdim } else if (JA.getType() == types::TY_ModuleFile) { 2103249423Sdim CmdArgs.push_back("-module-file-info"); 2104203955Srdivacky } else if (JA.getType() == types::TY_RewrittenObjC) { 2105203955Srdivacky CmdArgs.push_back("-rewrite-objc"); 2106239462Sdim rewriteKind = RK_NonFragile; 2107234353Sdim } else if (JA.getType() == types::TY_RewrittenLegacyObjC) { 2108234353Sdim CmdArgs.push_back("-rewrite-objc"); 2109239462Sdim rewriteKind = RK_Fragile; 2110203955Srdivacky } else { 2111203955Srdivacky assert(JA.getType() == types::TY_PP_Asm && 2112203955Srdivacky "Unexpected output type!"); 2113193326Sed } 2114193326Sed } 2115193326Sed 2116193326Sed // The make clang go fast button. 2117193326Sed CmdArgs.push_back("-disable-free"); 2118193326Sed 2119203955Srdivacky // Disable the verification pass in -asserts builds. 2120203955Srdivacky#ifdef NDEBUG 2121203955Srdivacky CmdArgs.push_back("-disable-llvm-verifier"); 2122203955Srdivacky#endif 2123203955Srdivacky 2124193326Sed // Set the main file name, so that debug info works even with 2125193326Sed // -save-temps. 2126193326Sed CmdArgs.push_back("-main-file-name"); 2127249423Sdim CmdArgs.push_back(getBaseInputName(Args, Inputs)); 2128193326Sed 2129193326Sed // Some flags which affect the language (via preprocessor 2130249423Sdim // defines). 2131193326Sed if (Args.hasArg(options::OPT_static)) 2132193326Sed CmdArgs.push_back("-static-define"); 2133193326Sed 2134193326Sed if (isa<AnalyzeJobAction>(JA)) { 2135198092Srdivacky // Enable region store model by default. 2136198092Srdivacky CmdArgs.push_back("-analyzer-store=region"); 2137198092Srdivacky 2138200583Srdivacky // Treat blocks as analysis entry points. 2139200583Srdivacky CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks"); 2140200583Srdivacky 2141221345Sdim CmdArgs.push_back("-analyzer-eagerly-assume"); 2142221345Sdim 2143193326Sed // Add default argument set. 2144193326Sed if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) { 2145221345Sdim CmdArgs.push_back("-analyzer-checker=core"); 2146218893Sdim 2147218893Sdim if (getToolChain().getTriple().getOS() != llvm::Triple::Win32) 2148218893Sdim CmdArgs.push_back("-analyzer-checker=unix"); 2149221345Sdim 2150218893Sdim if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple) 2151221345Sdim CmdArgs.push_back("-analyzer-checker=osx"); 2152234353Sdim 2153234353Sdim CmdArgs.push_back("-analyzer-checker=deadcode"); 2154234353Sdim 2155251662Sdim if (types::isCXX(Inputs[0].getType())) 2156251662Sdim CmdArgs.push_back("-analyzer-checker=cplusplus"); 2157251662Sdim 2158234353Sdim // Enable the following experimental checkers for testing. 2159234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn"); 2160234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw"); 2161234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets"); 2162234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp"); 2163234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp"); 2164234353Sdim CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork"); 2165193326Sed } 2166193326Sed 2167193326Sed // Set the output format. The default is plist, for (lame) historical 2168193326Sed // reasons. 2169193326Sed CmdArgs.push_back("-analyzer-output"); 2170193326Sed if (Arg *A = Args.getLastArg(options::OPT__analyzer_output)) 2171243830Sdim CmdArgs.push_back(A->getValue()); 2172193326Sed else 2173193326Sed CmdArgs.push_back("plist"); 2174193326Sed 2175206084Srdivacky // Disable the presentation of standard compiler warnings when 2176206084Srdivacky // using --analyze. We only want to show static analyzer diagnostics 2177206084Srdivacky // or frontend errors. 2178206084Srdivacky CmdArgs.push_back("-w"); 2179206084Srdivacky 2180193326Sed // Add -Xanalyzer arguments when running as analyzer. 2181193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer); 2182198092Srdivacky } 2183198092Srdivacky 2184198092Srdivacky CheckCodeGenerationOptions(D, Args); 2185198092Srdivacky 2186251662Sdim bool PIE = getToolChain().isPIEDefault(); 2187251662Sdim bool PIC = PIE || getToolChain().isPICDefault(); 2188243830Sdim bool IsPICLevelTwo = PIC; 2189251662Sdim 2190251662Sdim // For the PIC and PIE flag options, this logic is different from the 2191251662Sdim // legacy logic in very old versions of GCC, as that logic was just 2192251662Sdim // a bug no one had ever fixed. This logic is both more rational and 2193251662Sdim // consistent with GCC's new logic now that the bugs are fixed. The last 2194251662Sdim // argument relating to either PIC or PIE wins, and no other argument is 2195251662Sdim // used. If the last argument is any flavor of the '-fno-...' arguments, 2196251662Sdim // both PIC and PIE are disabled. Any PIE option implicitly enables PIC 2197251662Sdim // at the same level. 2198251662Sdim Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 2199251662Sdim options::OPT_fpic, options::OPT_fno_pic, 2200251662Sdim options::OPT_fPIE, options::OPT_fno_PIE, 2201251662Sdim options::OPT_fpie, options::OPT_fno_pie); 2202243830Sdim // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness 2203243830Sdim // is forced, then neither PIC nor PIE flags will have no effect. 2204251662Sdim if (!getToolChain().isPICDefaultForced()) { 2205251662Sdim if (LastPICArg) { 2206251662Sdim Option O = LastPICArg->getOption(); 2207251662Sdim if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || 2208251662Sdim O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { 2209251662Sdim PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); 2210251662Sdim PIC = PIE || O.matches(options::OPT_fPIC) || 2211251662Sdim O.matches(options::OPT_fpic); 2212251662Sdim IsPICLevelTwo = O.matches(options::OPT_fPIE) || 2213251662Sdim O.matches(options::OPT_fPIC); 2214251662Sdim } else { 2215251662Sdim PIE = PIC = false; 2216251662Sdim } 2217251662Sdim } 2218243830Sdim } 2219193326Sed 2220263508Sdim // Introduce a Darwin-specific hack. If the default is PIC but the flags 2221243830Sdim // specified while enabling PIC enabled level 1 PIC, just force it back to 2222243830Sdim // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my 2223243830Sdim // informal testing). 2224243830Sdim if (PIC && getToolChain().getTriple().isOSDarwin()) 2225243830Sdim IsPICLevelTwo |= getToolChain().isPICDefault(); 2226239462Sdim 2227234353Sdim // Note that these flags are trump-cards. Regardless of the order w.r.t. the 2228234353Sdim // PIC or PIE options above, if these show up, PIC is disabled. 2229243830Sdim llvm::Triple Triple(TripleStr); 2230249423Sdim if (KernelOrKext && 2231263508Sdim (!Triple.isiOS() || Triple.isOSVersionLT(6))) 2232243830Sdim PIC = PIE = false; 2233234353Sdim if (Args.hasArg(options::OPT_static)) 2234243830Sdim PIC = PIE = false; 2235234353Sdim 2236243830Sdim if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) { 2237243830Sdim // This is a very special mode. It trumps the other modes, almost no one 2238243830Sdim // uses it, and it isn't even valid on any OS but Darwin. 2239243830Sdim if (!getToolChain().getTriple().isOSDarwin()) 2240243830Sdim D.Diag(diag::err_drv_unsupported_opt_for_target) 2241243830Sdim << A->getSpelling() << getToolChain().getTriple().str(); 2242243830Sdim 2243243830Sdim // FIXME: Warn when this flag trumps some other PIC or PIE flag. 2244243830Sdim 2245199990Srdivacky CmdArgs.push_back("-mrelocation-model"); 2246243830Sdim CmdArgs.push_back("dynamic-no-pic"); 2247193326Sed 2248243830Sdim // Only a forced PIC mode can cause the actual compile to have PIC defines 2249243830Sdim // etc., no flags are sufficient. This behavior was selected to closely 2250243830Sdim // match that of llvm-gcc and Apple GCC before that. 2251243830Sdim if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) { 2252243830Sdim CmdArgs.push_back("-pic-level"); 2253243830Sdim CmdArgs.push_back("2"); 2254243830Sdim } 2255243830Sdim } else { 2256243830Sdim // Currently, LLVM only knows about PIC vs. static; the PIE differences are 2257243830Sdim // handled in Clang's IRGen by the -pie-level flag. 2258243830Sdim CmdArgs.push_back("-mrelocation-model"); 2259243830Sdim CmdArgs.push_back(PIC ? "pic" : "static"); 2260243830Sdim 2261243830Sdim if (PIC) { 2262243830Sdim CmdArgs.push_back("-pic-level"); 2263243830Sdim CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); 2264243830Sdim if (PIE) { 2265243830Sdim CmdArgs.push_back("-pie-level"); 2266243830Sdim CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); 2267243830Sdim } 2268243830Sdim } 2269193326Sed } 2270234353Sdim 2271199990Srdivacky if (!Args.hasFlag(options::OPT_fmerge_all_constants, 2272199990Srdivacky options::OPT_fno_merge_all_constants)) 2273221345Sdim CmdArgs.push_back("-fno-merge-all-constants"); 2274193326Sed 2275199990Srdivacky // LLVM Code Generator Options. 2276199990Srdivacky 2277218893Sdim if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) { 2278218893Sdim CmdArgs.push_back("-mregparm"); 2279243830Sdim CmdArgs.push_back(A->getValue()); 2280218893Sdim } 2281218893Sdim 2282263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return, 2283263508Sdim options::OPT_freg_struct_return)) { 2284263508Sdim if (getToolChain().getArch() != llvm::Triple::x86) { 2285263508Sdim D.Diag(diag::err_drv_unsupported_opt_for_target) 2286263508Sdim << A->getSpelling() << getToolChain().getTriple().str(); 2287263508Sdim } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) { 2288263508Sdim CmdArgs.push_back("-fpcc-struct-return"); 2289263508Sdim } else { 2290263508Sdim assert(A->getOption().matches(options::OPT_freg_struct_return)); 2291263508Sdim CmdArgs.push_back("-freg-struct-return"); 2292263508Sdim } 2293263508Sdim } 2294263508Sdim 2295221345Sdim if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) 2296221345Sdim CmdArgs.push_back("-mrtd"); 2297221345Sdim 2298234353Sdim if (shouldUseFramePointer(Args, getToolChain().getTriple())) 2299199990Srdivacky CmdArgs.push_back("-mdisable-fp-elim"); 2300193326Sed if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, 2301199990Srdivacky options::OPT_fno_zero_initialized_in_bss)) 2302199990Srdivacky CmdArgs.push_back("-mno-zero-initialized-in-bss"); 2303251662Sdim 2304251662Sdim bool OFastEnabled = isOptimizationLevelFast(Args); 2305251662Sdim // If -Ofast is the optimization level, then -fstrict-aliasing should be 2306251662Sdim // enabled. This alias option is being used to simplify the hasFlag logic. 2307251662Sdim OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : 2308251662Sdim options::OPT_fstrict_aliasing; 2309251662Sdim if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, 2310263508Sdim options::OPT_fno_strict_aliasing, true)) 2311218893Sdim CmdArgs.push_back("-relaxed-aliasing"); 2312263508Sdim if (!Args.hasFlag(options::OPT_fstruct_path_tbaa, 2313263508Sdim options::OPT_fno_struct_path_tbaa)) 2314263508Sdim CmdArgs.push_back("-no-struct-path-tbaa"); 2315234353Sdim if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums, 2316234353Sdim false)) 2317234353Sdim CmdArgs.push_back("-fstrict-enums"); 2318234353Sdim if (!Args.hasFlag(options::OPT_foptimize_sibling_calls, 2319234353Sdim options::OPT_fno_optimize_sibling_calls)) 2320234353Sdim CmdArgs.push_back("-mdisable-tail-calls"); 2321208600Srdivacky 2322249423Sdim // Handle segmented stacks. 2323249423Sdim if (Args.hasArg(options::OPT_fsplit_stack)) 2324249423Sdim CmdArgs.push_back("-split-stacks"); 2325251662Sdim 2326251662Sdim // If -Ofast is the optimization level, then -ffast-math should be enabled. 2327251662Sdim // This alias option is being used to simplify the getLastArg logic. 2328251662Sdim OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast : 2329251662Sdim options::OPT_ffast_math; 2330249423Sdim 2331234353Sdim // Handle various floating point optimization flags, mapping them to the 2332234353Sdim // appropriate LLVM code generation flags. The pattern for all of these is to 2333234353Sdim // default off the codegen optimizations, and if any flag enables them and no 2334234353Sdim // flag disables them after the flag enabling them, enable the codegen 2335234353Sdim // optimization. This is complicated by several "umbrella" flags. 2336251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2337243830Sdim options::OPT_fno_fast_math, 2338234353Sdim options::OPT_ffinite_math_only, 2339234353Sdim options::OPT_fno_finite_math_only, 2340234353Sdim options::OPT_fhonor_infinities, 2341234353Sdim options::OPT_fno_honor_infinities)) 2342243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2343243830Sdim A->getOption().getID() != options::OPT_fno_finite_math_only && 2344234353Sdim A->getOption().getID() != options::OPT_fhonor_infinities) 2345234353Sdim CmdArgs.push_back("-menable-no-infs"); 2346251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2347243830Sdim options::OPT_fno_fast_math, 2348234353Sdim options::OPT_ffinite_math_only, 2349234353Sdim options::OPT_fno_finite_math_only, 2350234353Sdim options::OPT_fhonor_nans, 2351234353Sdim options::OPT_fno_honor_nans)) 2352243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2353243830Sdim A->getOption().getID() != options::OPT_fno_finite_math_only && 2354234353Sdim A->getOption().getID() != options::OPT_fhonor_nans) 2355234353Sdim CmdArgs.push_back("-menable-no-nans"); 2356234353Sdim 2357239462Sdim // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. 2358239462Sdim bool MathErrno = getToolChain().IsMathErrnoDefault(); 2359251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2360243830Sdim options::OPT_fno_fast_math, 2361234353Sdim options::OPT_fmath_errno, 2362263508Sdim options::OPT_fno_math_errno)) { 2363263508Sdim // Turning on -ffast_math (with either flag) removes the need for MathErrno. 2364263508Sdim // However, turning *off* -ffast_math merely restores the toolchain default 2365263508Sdim // (which may be false). 2366263508Sdim if (A->getOption().getID() == options::OPT_fno_math_errno || 2367263508Sdim A->getOption().getID() == options::OPT_ffast_math || 2368263508Sdim A->getOption().getID() == options::OPT_Ofast) 2369263508Sdim MathErrno = false; 2370263508Sdim else if (A->getOption().getID() == options::OPT_fmath_errno) 2371263508Sdim MathErrno = true; 2372263508Sdim } 2373239462Sdim if (MathErrno) 2374239462Sdim CmdArgs.push_back("-fmath-errno"); 2375234353Sdim 2376234353Sdim // There are several flags which require disabling very specific 2377234353Sdim // optimizations. Any of these being disabled forces us to turn off the 2378234353Sdim // entire set of LLVM optimizations, so collect them through all the flag 2379234353Sdim // madness. 2380234353Sdim bool AssociativeMath = false; 2381251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2382243830Sdim options::OPT_fno_fast_math, 2383234353Sdim options::OPT_funsafe_math_optimizations, 2384234353Sdim options::OPT_fno_unsafe_math_optimizations, 2385234353Sdim options::OPT_fassociative_math, 2386234353Sdim options::OPT_fno_associative_math)) 2387243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2388243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2389234353Sdim A->getOption().getID() != options::OPT_fno_associative_math) 2390234353Sdim AssociativeMath = true; 2391234353Sdim bool ReciprocalMath = false; 2392251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2393243830Sdim options::OPT_fno_fast_math, 2394234353Sdim options::OPT_funsafe_math_optimizations, 2395234353Sdim options::OPT_fno_unsafe_math_optimizations, 2396234353Sdim options::OPT_freciprocal_math, 2397234353Sdim options::OPT_fno_reciprocal_math)) 2398243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2399243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2400234353Sdim A->getOption().getID() != options::OPT_fno_reciprocal_math) 2401234353Sdim ReciprocalMath = true; 2402234353Sdim bool SignedZeros = true; 2403251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2404243830Sdim options::OPT_fno_fast_math, 2405234353Sdim options::OPT_funsafe_math_optimizations, 2406234353Sdim options::OPT_fno_unsafe_math_optimizations, 2407234353Sdim options::OPT_fsigned_zeros, 2408234353Sdim options::OPT_fno_signed_zeros)) 2409243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2410243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2411234353Sdim A->getOption().getID() != options::OPT_fsigned_zeros) 2412234353Sdim SignedZeros = false; 2413234353Sdim bool TrappingMath = true; 2414251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2415243830Sdim options::OPT_fno_fast_math, 2416234353Sdim options::OPT_funsafe_math_optimizations, 2417234353Sdim options::OPT_fno_unsafe_math_optimizations, 2418234353Sdim options::OPT_ftrapping_math, 2419234353Sdim options::OPT_fno_trapping_math)) 2420243830Sdim if (A->getOption().getID() != options::OPT_fno_fast_math && 2421243830Sdim A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && 2422234353Sdim A->getOption().getID() != options::OPT_ftrapping_math) 2423234353Sdim TrappingMath = false; 2424234353Sdim if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros && 2425234353Sdim !TrappingMath) 2426234353Sdim CmdArgs.push_back("-menable-unsafe-fp-math"); 2427234353Sdim 2428239462Sdim 2429239462Sdim // Validate and pass through -fp-contract option. 2430251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2431243830Sdim options::OPT_fno_fast_math, 2432239462Sdim options::OPT_ffp_contract)) { 2433239462Sdim if (A->getOption().getID() == options::OPT_ffp_contract) { 2434243830Sdim StringRef Val = A->getValue(); 2435239462Sdim if (Val == "fast" || Val == "on" || Val == "off") { 2436239462Sdim CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val)); 2437239462Sdim } else { 2438239462Sdim D.Diag(diag::err_drv_unsupported_option_argument) 2439239462Sdim << A->getOption().getName() << Val; 2440239462Sdim } 2441251662Sdim } else if (A->getOption().matches(options::OPT_ffast_math) || 2442251662Sdim (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) { 2443239462Sdim // If fast-math is set then set the fp-contract mode to fast. 2444239462Sdim CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); 2445239462Sdim } 2446239462Sdim } 2447239462Sdim 2448239462Sdim // We separately look for the '-ffast-math' and '-ffinite-math-only' flags, 2449239462Sdim // and if we find them, tell the frontend to provide the appropriate 2450239462Sdim // preprocessor macros. This is distinct from enabling any optimizations as 2451239462Sdim // these options induce language changes which must survive serialization 2452239462Sdim // and deserialization, etc. 2453251662Sdim if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, 2454251662Sdim options::OPT_fno_fast_math)) 2455251662Sdim if (!A->getOption().matches(options::OPT_fno_fast_math)) 2456251662Sdim CmdArgs.push_back("-ffast-math"); 2457243830Sdim if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math)) 2458243830Sdim if (A->getOption().matches(options::OPT_ffinite_math_only)) 2459243830Sdim CmdArgs.push_back("-ffinite-math-only"); 2460234353Sdim 2461208600Srdivacky // Decide whether to use verbose asm. Verbose assembly is the default on 2462208600Srdivacky // toolchains which have the integrated assembler on by default. 2463208600Srdivacky bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault(); 2464208600Srdivacky if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, 2465218893Sdim IsVerboseAsmDefault) || 2466208600Srdivacky Args.hasArg(options::OPT_dA)) 2467199990Srdivacky CmdArgs.push_back("-masm-verbose"); 2468208600Srdivacky 2469199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_structure)) { 2470199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 2471199990Srdivacky CmdArgs.push_back("Structure"); 2472199990Srdivacky } 2473199990Srdivacky if (Args.hasArg(options::OPT_fdebug_pass_arguments)) { 2474199990Srdivacky CmdArgs.push_back("-mdebug-pass"); 2475199990Srdivacky CmdArgs.push_back("Arguments"); 2476199990Srdivacky } 2477198092Srdivacky 2478204643Srdivacky // Enable -mconstructor-aliases except on darwin, where we have to 2479204643Srdivacky // work around a linker bug; see <rdar://problem/7651567>. 2480226633Sdim if (!getToolChain().getTriple().isOSDarwin()) 2481204643Srdivacky CmdArgs.push_back("-mconstructor-aliases"); 2482204643Srdivacky 2483221345Sdim // Darwin's kernel doesn't support guard variables; just die if we 2484221345Sdim // try to use them. 2485226633Sdim if (KernelOrKext && getToolChain().getTriple().isOSDarwin()) 2486221345Sdim CmdArgs.push_back("-fforbid-guard-variables"); 2487221345Sdim 2488218893Sdim if (Args.hasArg(options::OPT_mms_bitfields)) { 2489218893Sdim CmdArgs.push_back("-mms-bitfields"); 2490218893Sdim } 2491218893Sdim 2492198092Srdivacky // This is a coarse approximation of what llvm-gcc actually does, both 2493198092Srdivacky // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more 2494198092Srdivacky // complicated ways. 2495198092Srdivacky bool AsynchronousUnwindTables = 2496198092Srdivacky Args.hasFlag(options::OPT_fasynchronous_unwind_tables, 2497198092Srdivacky options::OPT_fno_asynchronous_unwind_tables, 2498198092Srdivacky getToolChain().IsUnwindTablesDefault() && 2499205408Srdivacky !KernelOrKext); 2500198092Srdivacky if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, 2501198092Srdivacky AsynchronousUnwindTables)) 2502199990Srdivacky CmdArgs.push_back("-munwind-tables"); 2503193326Sed 2504249423Sdim getToolChain().addClangTargetOptions(Args, CmdArgs); 2505239462Sdim 2506199990Srdivacky if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { 2507199990Srdivacky CmdArgs.push_back("-mlimit-float-precision"); 2508243830Sdim CmdArgs.push_back(A->getValue()); 2509199990Srdivacky } 2510199990Srdivacky 2511193326Sed // FIXME: Handle -mtune=. 2512193326Sed (void) Args.hasArg(options::OPT_mtune_EQ); 2513193326Sed 2514198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) { 2515199990Srdivacky CmdArgs.push_back("-mcode-model"); 2516243830Sdim CmdArgs.push_back(A->getValue()); 2517193326Sed } 2518193326Sed 2519263508Sdim // Add the target cpu 2520263508Sdim std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args); 2521263508Sdim llvm::Triple ETriple(ETripleStr); 2522263508Sdim std::string CPU = getCPUName(Args, ETriple); 2523263508Sdim if (!CPU.empty()) { 2524263508Sdim CmdArgs.push_back("-target-cpu"); 2525263508Sdim CmdArgs.push_back(Args.MakeArgString(CPU)); 2526263508Sdim } 2527263508Sdim 2528263508Sdim if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) { 2529263508Sdim CmdArgs.push_back("-mfpmath"); 2530263508Sdim CmdArgs.push_back(A->getValue()); 2531263508Sdim } 2532263508Sdim 2533263508Sdim // Add the target features 2534263508Sdim getTargetFeatures(D, ETriple, Args, CmdArgs); 2535263508Sdim 2536263508Sdim // Add target specific flags. 2537263508Sdim switch(getToolChain().getArch()) { 2538198092Srdivacky default: 2539198092Srdivacky break; 2540193326Sed 2541198092Srdivacky case llvm::Triple::arm: 2542198092Srdivacky case llvm::Triple::thumb: 2543221345Sdim AddARMTargetArgs(Args, CmdArgs, KernelOrKext); 2544198092Srdivacky break; 2545193326Sed 2546204643Srdivacky case llvm::Triple::mips: 2547204643Srdivacky case llvm::Triple::mipsel: 2548226633Sdim case llvm::Triple::mips64: 2549226633Sdim case llvm::Triple::mips64el: 2550204643Srdivacky AddMIPSTargetArgs(Args, CmdArgs); 2551204643Srdivacky break; 2552204643Srdivacky 2553218893Sdim case llvm::Triple::sparc: 2554218893Sdim AddSparcTargetArgs(Args, CmdArgs); 2555218893Sdim break; 2556218893Sdim 2557198092Srdivacky case llvm::Triple::x86: 2558198092Srdivacky case llvm::Triple::x86_64: 2559198092Srdivacky AddX86TargetArgs(Args, CmdArgs); 2560198092Srdivacky break; 2561234353Sdim 2562234353Sdim case llvm::Triple::hexagon: 2563234353Sdim AddHexagonTargetArgs(Args, CmdArgs); 2564234353Sdim break; 2565193326Sed } 2566193326Sed 2567263508Sdim // Add clang-cl arguments. 2568263508Sdim if (getToolChain().getDriver().IsCLMode()) 2569263508Sdim AddClangCLArgs(Args, CmdArgs); 2570234353Sdim 2571212904Sdim // Pass the linker version in use. 2572212904Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 2573212904Sdim CmdArgs.push_back("-target-linker-version"); 2574243830Sdim CmdArgs.push_back(A->getValue()); 2575212904Sdim } 2576212904Sdim 2577249423Sdim if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple())) 2578210299Sed CmdArgs.push_back("-momit-leaf-frame-pointer"); 2579210299Sed 2580208600Srdivacky // Explicitly error on some things we know we don't support and can't just 2581208600Srdivacky // ignore. 2582208600Srdivacky types::ID InputType = Inputs[0].getType(); 2583218893Sdim if (!Args.hasArg(options::OPT_fallow_unsupported)) { 2584218893Sdim Arg *Unsupported; 2585218893Sdim if (types::isCXX(InputType) && 2586226633Sdim getToolChain().getTriple().isOSDarwin() && 2587263508Sdim getToolChain().getArch() == llvm::Triple::x86) { 2588226633Sdim if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) || 2589226633Sdim (Unsupported = Args.getLastArg(options::OPT_mkernel))) 2590226633Sdim D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386) 2591218893Sdim << Unsupported->getOption().getName(); 2592218893Sdim } 2593208600Srdivacky } 2594208600Srdivacky 2595193326Sed Args.AddAllArgs(CmdArgs, options::OPT_v); 2596212904Sdim Args.AddLastArg(CmdArgs, options::OPT_H); 2597226633Sdim if (D.CCPrintHeaders && !D.CCGenDiagnostics) { 2598218893Sdim CmdArgs.push_back("-header-include-file"); 2599218893Sdim CmdArgs.push_back(D.CCPrintHeadersFilename ? 2600218893Sdim D.CCPrintHeadersFilename : "-"); 2601218893Sdim } 2602193326Sed Args.AddLastArg(CmdArgs, options::OPT_P); 2603198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); 2604193326Sed 2605226633Sdim if (D.CCLogDiagnostics && !D.CCGenDiagnostics) { 2606221345Sdim CmdArgs.push_back("-diagnostic-log-file"); 2607221345Sdim CmdArgs.push_back(D.CCLogDiagnosticsFilename ? 2608221345Sdim D.CCLogDiagnosticsFilename : "-"); 2609221345Sdim } 2610221345Sdim 2611249423Sdim // Use the last option from "-g" group. "-gline-tables-only" 2612249423Sdim // is preserved, all other debug options are substituted with "-g". 2613204962Srdivacky Args.ClaimAllArgs(options::OPT_g_Group); 2614239462Sdim if (Arg *A = Args.getLastArg(options::OPT_g_Group)) { 2615249423Sdim if (A->getOption().matches(options::OPT_gline_tables_only)) 2616239462Sdim CmdArgs.push_back("-gline-tables-only"); 2617263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_2)) 2618263508Sdim CmdArgs.push_back("-gdwarf-2"); 2619263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_3)) 2620263508Sdim CmdArgs.push_back("-gdwarf-3"); 2621263508Sdim else if (A->getOption().matches(options::OPT_gdwarf_4)) 2622263508Sdim CmdArgs.push_back("-gdwarf-4"); 2623249423Sdim else if (!A->getOption().matches(options::OPT_g0) && 2624263508Sdim !A->getOption().matches(options::OPT_ggdb0)) { 2625264464Sdim // Default is dwarf-2 for darwin and FreeBSD. 2626263984Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 2627264464Sdim if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::FreeBSD) 2628263508Sdim CmdArgs.push_back("-gdwarf-2"); 2629263508Sdim else 2630263508Sdim CmdArgs.push_back("-g"); 2631263508Sdim } 2632239462Sdim } 2633193326Sed 2634239462Sdim // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now. 2635239462Sdim Args.ClaimAllArgs(options::OPT_g_flags_Group); 2636243830Sdim if (Args.hasArg(options::OPT_gcolumn_info)) 2637243830Sdim CmdArgs.push_back("-dwarf-column-info"); 2638239462Sdim 2639263508Sdim // FIXME: Move backend command line options to the module. 2640249423Sdim // -gsplit-dwarf should turn on -g and enable the backend dwarf 2641249423Sdim // splitting and extraction. 2642249423Sdim // FIXME: Currently only works on Linux. 2643263508Sdim if (getToolChain().getTriple().isOSLinux() && 2644249423Sdim Args.hasArg(options::OPT_gsplit_dwarf)) { 2645249423Sdim CmdArgs.push_back("-g"); 2646249423Sdim CmdArgs.push_back("-backend-option"); 2647249423Sdim CmdArgs.push_back("-split-dwarf=Enable"); 2648249423Sdim } 2649249423Sdim 2650263508Sdim // -ggnu-pubnames turns on gnu style pubnames in the backend. 2651263508Sdim if (Args.hasArg(options::OPT_ggnu_pubnames)) { 2652263508Sdim CmdArgs.push_back("-backend-option"); 2653263508Sdim CmdArgs.push_back("-generate-gnu-dwarf-pub-sections"); 2654263508Sdim } 2655263508Sdim 2656263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_fdebug_types_section); 2657263508Sdim 2658208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections); 2659208600Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections); 2660208600Srdivacky 2661210299Sed Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions); 2662210299Sed 2663221345Sdim if (Args.hasArg(options::OPT_ftest_coverage) || 2664221345Sdim Args.hasArg(options::OPT_coverage)) 2665221345Sdim CmdArgs.push_back("-femit-coverage-notes"); 2666221345Sdim if (Args.hasArg(options::OPT_fprofile_arcs) || 2667221345Sdim Args.hasArg(options::OPT_coverage)) 2668221345Sdim CmdArgs.push_back("-femit-coverage-data"); 2669221345Sdim 2670223017Sdim if (C.getArgs().hasArg(options::OPT_c) || 2671223017Sdim C.getArgs().hasArg(options::OPT_S)) { 2672223017Sdim if (Output.isFilename()) { 2673223017Sdim CmdArgs.push_back("-coverage-file"); 2674249423Sdim SmallString<128> CoverageFilename(Output.getFilename()); 2675249423Sdim if (llvm::sys::path::is_relative(CoverageFilename.str())) { 2676263508Sdim SmallString<128> Pwd; 2677263508Sdim if (!llvm::sys::fs::current_path(Pwd)) { 2678263508Sdim llvm::sys::path::append(Pwd, CoverageFilename.str()); 2679263508Sdim CoverageFilename.swap(Pwd); 2680249423Sdim } 2681249423Sdim } 2682249423Sdim CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); 2683223017Sdim } 2684223017Sdim } 2685223017Sdim 2686226633Sdim // Pass options for controlling the default header search paths. 2687226633Sdim if (Args.hasArg(options::OPT_nostdinc)) { 2688226633Sdim CmdArgs.push_back("-nostdsysteminc"); 2689226633Sdim CmdArgs.push_back("-nobuiltininc"); 2690226633Sdim } else { 2691226633Sdim if (Args.hasArg(options::OPT_nostdlibinc)) 2692226633Sdim CmdArgs.push_back("-nostdsysteminc"); 2693226633Sdim Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); 2694226633Sdim Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); 2695226633Sdim } 2696193326Sed 2697200583Srdivacky // Pass the path to compiler resource files. 2698200583Srdivacky CmdArgs.push_back("-resource-dir"); 2699202879Srdivacky CmdArgs.push_back(D.ResourceDir.c_str()); 2700193326Sed 2701218893Sdim Args.AddLastArg(CmdArgs, options::OPT_working_directory); 2702218893Sdim 2703234353Sdim bool ARCMTEnabled = false; 2704263508Sdim if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) { 2705224145Sdim if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check, 2706224145Sdim options::OPT_ccc_arcmt_modify, 2707224145Sdim options::OPT_ccc_arcmt_migrate)) { 2708234353Sdim ARCMTEnabled = true; 2709224145Sdim switch (A->getOption().getID()) { 2710224145Sdim default: 2711224145Sdim llvm_unreachable("missed a case"); 2712224145Sdim case options::OPT_ccc_arcmt_check: 2713224145Sdim CmdArgs.push_back("-arcmt-check"); 2714224145Sdim break; 2715224145Sdim case options::OPT_ccc_arcmt_modify: 2716224145Sdim CmdArgs.push_back("-arcmt-modify"); 2717224145Sdim break; 2718224145Sdim case options::OPT_ccc_arcmt_migrate: 2719224145Sdim CmdArgs.push_back("-arcmt-migrate"); 2720234353Sdim CmdArgs.push_back("-mt-migrate-directory"); 2721243830Sdim CmdArgs.push_back(A->getValue()); 2722226633Sdim 2723226633Sdim Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output); 2724226633Sdim Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors); 2725224145Sdim break; 2726224145Sdim } 2727224145Sdim } 2728263508Sdim } else { 2729263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_check); 2730263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify); 2731263508Sdim Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate); 2732224145Sdim } 2733226633Sdim 2734234353Sdim if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) { 2735234353Sdim if (ARCMTEnabled) { 2736234353Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 2737234353Sdim << A->getAsString(Args) << "-ccc-arcmt-migrate"; 2738234353Sdim } 2739234353Sdim CmdArgs.push_back("-mt-migrate-directory"); 2740243830Sdim CmdArgs.push_back(A->getValue()); 2741234353Sdim 2742234353Sdim if (!Args.hasArg(options::OPT_objcmt_migrate_literals, 2743263508Sdim options::OPT_objcmt_migrate_subscripting, 2744263508Sdim options::OPT_objcmt_migrate_property)) { 2745234353Sdim // None specified, means enable them all. 2746234353Sdim CmdArgs.push_back("-objcmt-migrate-literals"); 2747234353Sdim CmdArgs.push_back("-objcmt-migrate-subscripting"); 2748263508Sdim CmdArgs.push_back("-objcmt-migrate-property"); 2749234353Sdim } else { 2750234353Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); 2751234353Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); 2752263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); 2753234353Sdim } 2754263508Sdim } else { 2755263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); 2756263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); 2757263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); 2758263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all); 2759263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property); 2760263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property); 2761263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation); 2762263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype); 2763263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros); 2764263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance); 2765263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property); 2766263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property); 2767263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly); 2768263508Sdim Args.AddLastArg(CmdArgs, options::OPT_objcmt_white_list_dir_path); 2769234353Sdim } 2770234353Sdim 2771193326Sed // Add preprocessing options like -I, -D, etc. if we are using the 2772193326Sed // preprocessor. 2773193326Sed // 2774193326Sed // FIXME: Support -fpreprocessed 2775193326Sed if (types::getPreprocessedType(InputType) != types::TY_INVALID) 2776249423Sdim AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs); 2777193326Sed 2778226633Sdim // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes 2779226633Sdim // that "The compiler can only warn and ignore the option if not recognized". 2780226633Sdim // When building with ccache, it will pass -D options to clang even on 2781226633Sdim // preprocessed inputs and configure concludes that -fPIC is not supported. 2782226633Sdim Args.ClaimAllArgs(options::OPT_D); 2783226633Sdim 2784263508Sdim // Manually translate -O4 to -O3; let clang reject others. 2785193326Sed if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 2786263508Sdim if (A->getOption().matches(options::OPT_O4)) { 2787193326Sed CmdArgs.push_back("-O3"); 2788263508Sdim D.Diag(diag::warn_O4_is_O3); 2789263508Sdim } else { 2790193326Sed A->render(Args, CmdArgs); 2791263508Sdim } 2792193326Sed } 2793193326Sed 2794249423Sdim // Don't warn about unused -flto. This can happen when we're preprocessing or 2795249423Sdim // precompiling. 2796249423Sdim Args.ClaimAllArgs(options::OPT_flto); 2797249423Sdim 2798198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_W_Group); 2799239462Sdim if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false)) 2800239462Sdim CmdArgs.push_back("-pedantic"); 2801198893Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors); 2802193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 2803193326Sed 2804193326Sed // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi} 2805263508Sdim // (-ansi is equivalent to -std=c89 or -std=c++98). 2806193326Sed // 2807193326Sed // If a std is supplied, only add -trigraphs if it follows the 2808193326Sed // option. 2809193326Sed if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 2810193326Sed if (Std->getOption().matches(options::OPT_ansi)) 2811198398Srdivacky if (types::isCXX(InputType)) 2812198893Srdivacky CmdArgs.push_back("-std=c++98"); 2813198398Srdivacky else 2814198893Srdivacky CmdArgs.push_back("-std=c89"); 2815193326Sed else 2816193326Sed Std->render(Args, CmdArgs); 2817193326Sed 2818210299Sed if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi, 2819210299Sed options::OPT_trigraphs)) 2820210299Sed if (A != Std) 2821193326Sed A->render(Args, CmdArgs); 2822193326Sed } else { 2823193326Sed // Honor -std-default. 2824203955Srdivacky // 2825203955Srdivacky // FIXME: Clang doesn't correctly handle -std= when the input language 2826203955Srdivacky // doesn't match. For the time being just ignore this for C++ inputs; 2827203955Srdivacky // eventually we want to do all the standard defaulting here instead of 2828203955Srdivacky // splitting it between the driver and clang -cc1. 2829203955Srdivacky if (!types::isCXX(InputType)) 2830243830Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, 2831243830Sdim "-std=", /*Joined=*/true); 2832243830Sdim else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32) 2833243830Sdim CmdArgs.push_back("-std=c++11"); 2834243830Sdim 2835193326Sed Args.AddLastArg(CmdArgs, options::OPT_trigraphs); 2836193326Sed } 2837193326Sed 2838263508Sdim // GCC's behavior for -Wwrite-strings is a bit strange: 2839263508Sdim // * In C, this "warning flag" changes the types of string literals from 2840263508Sdim // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning 2841263508Sdim // for the discarded qualifier. 2842263508Sdim // * In C++, this is just a normal warning flag. 2843263508Sdim // 2844263508Sdim // Implementing this warning correctly in C is hard, so we follow GCC's 2845263508Sdim // behavior for now. FIXME: Directly diagnose uses of a string literal as 2846263508Sdim // a non-const char* in C, rather than using this crude hack. 2847263508Sdim if (!types::isCXX(InputType)) { 2848263508Sdim DiagnosticsEngine::Level DiagLevel = D.getDiags().getDiagnosticLevel( 2849263508Sdim diag::warn_deprecated_string_literal_conversion_c, SourceLocation()); 2850263508Sdim if (DiagLevel > DiagnosticsEngine::Ignored) 2851263508Sdim CmdArgs.push_back("-fconst-strings"); 2852221345Sdim } 2853221345Sdim 2854221345Sdim // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active 2855221345Sdim // during C++ compilation, which it is by default. GCC keeps this define even 2856221345Sdim // in the presence of '-w', match this behavior bug-for-bug. 2857221345Sdim if (types::isCXX(InputType) && 2858221345Sdim Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated, 2859221345Sdim true)) { 2860221345Sdim CmdArgs.push_back("-fdeprecated-macro"); 2861221345Sdim } 2862221345Sdim 2863208600Srdivacky // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'. 2864208600Srdivacky if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) { 2865208600Srdivacky if (Asm->getOption().matches(options::OPT_fasm)) 2866208600Srdivacky CmdArgs.push_back("-fgnu-keywords"); 2867208600Srdivacky else 2868208600Srdivacky CmdArgs.push_back("-fno-gnu-keywords"); 2869208600Srdivacky } 2870208600Srdivacky 2871221345Sdim if (ShouldDisableCFI(Args, getToolChain())) 2872221345Sdim CmdArgs.push_back("-fno-dwarf2-cfi-asm"); 2873221345Sdim 2874234353Sdim if (ShouldDisableDwarfDirectory(Args, getToolChain())) 2875234353Sdim CmdArgs.push_back("-fno-dwarf-directory-asm"); 2876234353Sdim 2877251662Sdim if (ShouldDisableAutolink(Args, getToolChain())) 2878251662Sdim CmdArgs.push_back("-fno-autolink"); 2879251662Sdim 2880249423Sdim // Add in -fdebug-compilation-dir if necessary. 2881249423Sdim addDebugCompDirArg(Args, CmdArgs); 2882234353Sdim 2883234353Sdim if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_, 2884234353Sdim options::OPT_ftemplate_depth_EQ)) { 2885193326Sed CmdArgs.push_back("-ftemplate-depth"); 2886243830Sdim CmdArgs.push_back(A->getValue()); 2887193326Sed } 2888193326Sed 2889263508Sdim if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) { 2890263508Sdim CmdArgs.push_back("-foperator-arrow-depth"); 2891263508Sdim CmdArgs.push_back(A->getValue()); 2892263508Sdim } 2893263508Sdim 2894234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) { 2895234353Sdim CmdArgs.push_back("-fconstexpr-depth"); 2896243830Sdim CmdArgs.push_back(A->getValue()); 2897234353Sdim } 2898234353Sdim 2899263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) { 2900263508Sdim CmdArgs.push_back("-fconstexpr-steps"); 2901263508Sdim CmdArgs.push_back(A->getValue()); 2902263508Sdim } 2903263508Sdim 2904249423Sdim if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) { 2905249423Sdim CmdArgs.push_back("-fbracket-depth"); 2906249423Sdim CmdArgs.push_back(A->getValue()); 2907249423Sdim } 2908249423Sdim 2909218893Sdim if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ, 2910218893Sdim options::OPT_Wlarge_by_value_copy_def)) { 2911239462Sdim if (A->getNumValues()) { 2912243830Sdim StringRef bytes = A->getValue(); 2913239462Sdim CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes)); 2914239462Sdim } else 2915239462Sdim CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value 2916218893Sdim } 2917218893Sdim 2918239462Sdim 2919243830Sdim if (Args.hasArg(options::OPT_relocatable_pch)) 2920199990Srdivacky CmdArgs.push_back("-relocatable-pch"); 2921198092Srdivacky 2922198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { 2923198893Srdivacky CmdArgs.push_back("-fconstant-string-class"); 2924243830Sdim CmdArgs.push_back(A->getValue()); 2925198893Srdivacky } 2926198092Srdivacky 2927202379Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) { 2928202379Srdivacky CmdArgs.push_back("-ftabstop"); 2929243830Sdim CmdArgs.push_back(A->getValue()); 2930202379Srdivacky } 2931202379Srdivacky 2932207619Srdivacky CmdArgs.push_back("-ferror-limit"); 2933207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ)) 2934243830Sdim CmdArgs.push_back(A->getValue()); 2935207619Srdivacky else 2936207619Srdivacky CmdArgs.push_back("19"); 2937207619Srdivacky 2938208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) { 2939208600Srdivacky CmdArgs.push_back("-fmacro-backtrace-limit"); 2940243830Sdim CmdArgs.push_back(A->getValue()); 2941208600Srdivacky } 2942208600Srdivacky 2943208600Srdivacky if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) { 2944208600Srdivacky CmdArgs.push_back("-ftemplate-backtrace-limit"); 2945243830Sdim CmdArgs.push_back(A->getValue()); 2946208600Srdivacky } 2947208600Srdivacky 2948234353Sdim if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) { 2949234353Sdim CmdArgs.push_back("-fconstexpr-backtrace-limit"); 2950243830Sdim CmdArgs.push_back(A->getValue()); 2951234353Sdim } 2952234353Sdim 2953198893Srdivacky // Pass -fmessage-length=. 2954199990Srdivacky CmdArgs.push_back("-fmessage-length"); 2955198893Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { 2956243830Sdim CmdArgs.push_back(A->getValue()); 2957198893Srdivacky } else { 2958198893Srdivacky // If -fmessage-length=N was not specified, determine whether this is a 2959198893Srdivacky // terminal and, if so, implicitly define -fmessage-length appropriately. 2960198893Srdivacky unsigned N = llvm::sys::Process::StandardErrColumns(); 2961226633Sdim CmdArgs.push_back(Args.MakeArgString(Twine(N))); 2962198893Srdivacky } 2963198893Srdivacky 2964249423Sdim // -fvisibility= and -fvisibility-ms-compat are of a piece. 2965249423Sdim if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ, 2966249423Sdim options::OPT_fvisibility_ms_compat)) { 2967249423Sdim if (A->getOption().matches(options::OPT_fvisibility_EQ)) { 2968249423Sdim CmdArgs.push_back("-fvisibility"); 2969249423Sdim CmdArgs.push_back(A->getValue()); 2970249423Sdim } else { 2971249423Sdim assert(A->getOption().matches(options::OPT_fvisibility_ms_compat)); 2972249423Sdim CmdArgs.push_back("-fvisibility"); 2973249423Sdim CmdArgs.push_back("hidden"); 2974249423Sdim CmdArgs.push_back("-ftype-visibility"); 2975249423Sdim CmdArgs.push_back("default"); 2976249423Sdim } 2977200583Srdivacky } 2978200583Srdivacky 2979210299Sed Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); 2980218893Sdim 2981239462Sdim Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); 2982239462Sdim 2983205408Srdivacky // -fhosted is default. 2984234353Sdim if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) || 2985234353Sdim KernelOrKext) 2986205408Srdivacky CmdArgs.push_back("-ffreestanding"); 2987205408Srdivacky 2988200583Srdivacky // Forward -f (flag) options which we can pass directly. 2989193326Sed Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); 2990218893Sdim Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions); 2991193326Sed Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); 2992269011Semaste Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug); 2993269011Semaste Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug); 2994234353Sdim Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); 2995263508Sdim // AltiVec language extensions aren't relevant for assembling. 2996263508Sdim if (!isa<PreprocessJobAction>(JA) || 2997263508Sdim Output.getType() != types::TY_PP_Asm) 2998263508Sdim Args.AddLastArg(CmdArgs, options::OPT_faltivec); 2999239462Sdim Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); 3000239462Sdim Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); 3001234353Sdim 3002263508Sdim const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs(); 3003243830Sdim Sanitize.addArgs(Args, CmdArgs); 3004243830Sdim 3005249423Sdim if (!Args.hasFlag(options::OPT_fsanitize_recover, 3006249423Sdim options::OPT_fno_sanitize_recover, 3007249423Sdim true)) 3008249423Sdim CmdArgs.push_back("-fno-sanitize-recover"); 3009249423Sdim 3010249423Sdim if (Args.hasArg(options::OPT_fcatch_undefined_behavior) || 3011249423Sdim Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, 3012249423Sdim options::OPT_fno_sanitize_undefined_trap_on_error, false)) 3013249423Sdim CmdArgs.push_back("-fsanitize-undefined-trap-on-error"); 3014249423Sdim 3015249423Sdim // Report an error for -faltivec on anything other than PowerPC. 3016234353Sdim if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) 3017263508Sdim if (!(getToolChain().getArch() == llvm::Triple::ppc || 3018263508Sdim getToolChain().getArch() == llvm::Triple::ppc64 || 3019263508Sdim getToolChain().getArch() == llvm::Triple::ppc64le)) 3020234353Sdim D.Diag(diag::err_drv_argument_only_allowed_with) 3021263508Sdim << A->getAsString(Args) << "ppc/ppc64/ppc64le"; 3022234353Sdim 3023221345Sdim if (getToolChain().SupportsProfiling()) 3024221345Sdim Args.AddLastArg(CmdArgs, options::OPT_pg); 3025205408Srdivacky 3026205408Srdivacky // -flax-vector-conversions is default. 3027205408Srdivacky if (!Args.hasFlag(options::OPT_flax_vector_conversions, 3028205408Srdivacky options::OPT_fno_lax_vector_conversions)) 3029205408Srdivacky CmdArgs.push_back("-fno-lax-vector-conversions"); 3030205408Srdivacky 3031218893Sdim if (Args.getLastArg(options::OPT_fapple_kext)) 3032218893Sdim CmdArgs.push_back("-fapple-kext"); 3033218893Sdim 3034239462Sdim if (Args.hasFlag(options::OPT_frewrite_includes, 3035239462Sdim options::OPT_fno_rewrite_includes, false)) 3036239462Sdim CmdArgs.push_back("-frewrite-includes"); 3037239462Sdim 3038193326Sed Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch); 3039193326Sed Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); 3040212904Sdim Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits); 3041193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftime_report); 3042193326Sed Args.AddLastArg(CmdArgs, options::OPT_ftrapv); 3043218893Sdim 3044218893Sdim if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { 3045218893Sdim CmdArgs.push_back("-ftrapv-handler"); 3046243830Sdim CmdArgs.push_back(A->getValue()); 3047218893Sdim } 3048218893Sdim 3049234353Sdim Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ); 3050221345Sdim 3051221345Sdim // -fno-strict-overflow implies -fwrapv if it isn't disabled, but 3052221345Sdim // -fstrict-overflow won't turn off an explicitly enabled -fwrapv. 3053221345Sdim if (Arg *A = Args.getLastArg(options::OPT_fwrapv, 3054221345Sdim options::OPT_fno_wrapv)) { 3055221345Sdim if (A->getOption().matches(options::OPT_fwrapv)) 3056221345Sdim CmdArgs.push_back("-fwrapv"); 3057221345Sdim } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow, 3058221345Sdim options::OPT_fno_strict_overflow)) { 3059221345Sdim if (A->getOption().matches(options::OPT_fno_strict_overflow)) 3060221345Sdim CmdArgs.push_back("-fwrapv"); 3061221345Sdim } 3062263508Sdim 3063263508Sdim if (Arg *A = Args.getLastArg(options::OPT_freroll_loops, 3064263508Sdim options::OPT_fno_reroll_loops)) 3065263508Sdim if (A->getOption().matches(options::OPT_freroll_loops)) 3066263508Sdim CmdArgs.push_back("-freroll-loops"); 3067263508Sdim 3068193326Sed Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); 3069263508Sdim Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, 3070263508Sdim options::OPT_fno_unroll_loops); 3071193326Sed 3072198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_pthread); 3073198092Srdivacky 3074243830Sdim 3075199482Srdivacky // -stack-protector=0 is default. 3076199482Srdivacky unsigned StackProtectorLevel = 0; 3077195341Sed if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, 3078195341Sed options::OPT_fstack_protector_all, 3079195341Sed options::OPT_fstack_protector)) { 3080199482Srdivacky if (A->getOption().matches(options::OPT_fstack_protector)) 3081199482Srdivacky StackProtectorLevel = 1; 3082199482Srdivacky else if (A->getOption().matches(options::OPT_fstack_protector_all)) 3083199482Srdivacky StackProtectorLevel = 2; 3084226633Sdim } else { 3085226633Sdim StackProtectorLevel = 3086226633Sdim getToolChain().GetDefaultStackProtectorLevel(KernelOrKext); 3087226633Sdim } 3088199482Srdivacky if (StackProtectorLevel) { 3089199482Srdivacky CmdArgs.push_back("-stack-protector"); 3090226633Sdim CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel))); 3091195341Sed } 3092195341Sed 3093243830Sdim // --param ssp-buffer-size= 3094243830Sdim for (arg_iterator it = Args.filtered_begin(options::OPT__param), 3095243830Sdim ie = Args.filtered_end(); it != ie; ++it) { 3096243830Sdim StringRef Str((*it)->getValue()); 3097243830Sdim if (Str.startswith("ssp-buffer-size=")) { 3098243830Sdim if (StackProtectorLevel) { 3099243830Sdim CmdArgs.push_back("-stack-protector-buffer-size"); 3100243830Sdim // FIXME: Verify the argument is a valid integer. 3101243830Sdim CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16))); 3102243830Sdim } 3103243830Sdim (*it)->claim(); 3104243830Sdim } 3105243830Sdim } 3106243830Sdim 3107223017Sdim // Translate -mstackrealign 3108234353Sdim if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign, 3109234353Sdim false)) { 3110223017Sdim CmdArgs.push_back("-backend-option"); 3111223017Sdim CmdArgs.push_back("-force-align-stack"); 3112223017Sdim } 3113234353Sdim if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign, 3114234353Sdim false)) { 3115234353Sdim CmdArgs.push_back(Args.MakeArgString("-mstackrealign")); 3116234353Sdim } 3117226633Sdim 3118234353Sdim if (Args.hasArg(options::OPT_mstack_alignment)) { 3119234353Sdim StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment); 3120234353Sdim CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment)); 3121234353Sdim } 3122249423Sdim // -mkernel implies -mstrict-align; don't add the redundant option. 3123263508Sdim if (!KernelOrKext) { 3124263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, 3125263508Sdim options::OPT_munaligned_access)) { 3126263508Sdim if (A->getOption().matches(options::OPT_mno_unaligned_access)) { 3127263508Sdim CmdArgs.push_back("-backend-option"); 3128263508Sdim CmdArgs.push_back("-arm-strict-align"); 3129263508Sdim } else { 3130263508Sdim CmdArgs.push_back("-backend-option"); 3131263508Sdim CmdArgs.push_back("-arm-no-strict-align"); 3132263508Sdim } 3133263508Sdim } 3134243830Sdim } 3135234353Sdim 3136263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it, 3137263508Sdim options::OPT_mno_restrict_it)) { 3138263508Sdim if (A->getOption().matches(options::OPT_mrestrict_it)) { 3139263508Sdim CmdArgs.push_back("-backend-option"); 3140263508Sdim CmdArgs.push_back("-arm-restrict-it"); 3141263508Sdim } else { 3142263508Sdim CmdArgs.push_back("-backend-option"); 3143263508Sdim CmdArgs.push_back("-arm-no-restrict-it"); 3144263508Sdim } 3145263508Sdim } 3146263508Sdim 3147193326Sed // Forward -f options with positive and negative forms; we translate 3148193326Sed // these by hand. 3149263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) { 3150263508Sdim StringRef fname = A->getValue(); 3151263508Sdim if (!llvm::sys::fs::exists(fname)) 3152263508Sdim D.Diag(diag::err_drv_no_such_file) << fname; 3153263508Sdim else 3154263508Sdim A->render(Args, CmdArgs); 3155263508Sdim } 3156193326Sed 3157218893Sdim if (Args.hasArg(options::OPT_mkernel)) { 3158218893Sdim if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType)) 3159218893Sdim CmdArgs.push_back("-fapple-kext"); 3160218893Sdim if (!Args.hasArg(options::OPT_fbuiltin)) 3161218893Sdim CmdArgs.push_back("-fno-builtin"); 3162234353Sdim Args.ClaimAllArgs(options::OPT_fno_builtin); 3163218893Sdim } 3164199482Srdivacky // -fbuiltin is default. 3165218893Sdim else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin)) 3166199512Srdivacky CmdArgs.push_back("-fno-builtin"); 3167193326Sed 3168201361Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 3169201361Srdivacky options::OPT_fno_assume_sane_operator_new)) 3170201361Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 3171201361Srdivacky 3172199482Srdivacky // -fblocks=0 is default. 3173199482Srdivacky if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks, 3174221345Sdim getToolChain().IsBlocksDefault()) || 3175221345Sdim (Args.hasArg(options::OPT_fgnu_runtime) && 3176221345Sdim Args.hasArg(options::OPT_fobjc_nonfragile_abi) && 3177221345Sdim !Args.hasArg(options::OPT_fno_blocks))) { 3178199482Srdivacky CmdArgs.push_back("-fblocks"); 3179226633Sdim 3180226633Sdim if (!Args.hasArg(options::OPT_fgnu_runtime) && 3181226633Sdim !getToolChain().hasBlocksRuntime()) 3182226633Sdim CmdArgs.push_back("-fblocks-runtime-optional"); 3183193326Sed } 3184193326Sed 3185234353Sdim // -fmodules enables modules (off by default). However, for C++/Objective-C++, 3186234353Sdim // users must also pass -fcxx-modules. The latter flag will disappear once the 3187234353Sdim // modules implementation is solid for C++/Objective-C++ programs as well. 3188249423Sdim bool HaveModules = false; 3189234353Sdim if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) { 3190234353Sdim bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, 3191234353Sdim options::OPT_fno_cxx_modules, 3192234353Sdim false); 3193249423Sdim if (AllowedInCXX || !types::isCXX(InputType)) { 3194234353Sdim CmdArgs.push_back("-fmodules"); 3195249423Sdim HaveModules = true; 3196249423Sdim } 3197234353Sdim } 3198234353Sdim 3199263508Sdim // -fmodule-maps enables module map processing (off by default) for header 3200263508Sdim // checking. It is implied by -fmodules. 3201263508Sdim if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps, 3202263508Sdim false)) { 3203263508Sdim CmdArgs.push_back("-fmodule-maps"); 3204263508Sdim } 3205263508Sdim 3206263508Sdim // -fmodules-decluse checks that modules used are declared so (off by 3207263508Sdim // default). 3208263508Sdim if (Args.hasFlag(options::OPT_fmodules_decluse, 3209263508Sdim options::OPT_fno_modules_decluse, 3210263508Sdim false)) { 3211263508Sdim CmdArgs.push_back("-fmodules-decluse"); 3212263508Sdim } 3213263508Sdim 3214263508Sdim // -fmodule-name specifies the module that is currently being built (or 3215263508Sdim // used for header checking by -fmodule-maps). 3216263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) { 3217263508Sdim A->claim(); 3218263508Sdim A->render(Args, CmdArgs); 3219263508Sdim } 3220263508Sdim 3221263508Sdim // -fmodule-map-file can be used to specify a file containing module 3222263508Sdim // definitions. 3223263508Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) { 3224263508Sdim A->claim(); 3225263508Sdim A->render(Args, CmdArgs); 3226263508Sdim } 3227263508Sdim 3228249423Sdim // If a module path was provided, pass it along. Otherwise, use a temporary 3229249423Sdim // directory. 3230249423Sdim if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) { 3231249423Sdim A->claim(); 3232249423Sdim if (HaveModules) { 3233249423Sdim A->render(Args, CmdArgs); 3234249423Sdim } 3235249423Sdim } else if (HaveModules) { 3236249423Sdim SmallString<128> DefaultModuleCache; 3237249423Sdim llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, 3238249423Sdim DefaultModuleCache); 3239249423Sdim llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang"); 3240249423Sdim llvm::sys::path::append(DefaultModuleCache, "ModuleCache"); 3241249423Sdim const char Arg[] = "-fmodules-cache-path="; 3242249423Sdim DefaultModuleCache.insert(DefaultModuleCache.begin(), 3243249423Sdim Arg, Arg + strlen(Arg)); 3244249423Sdim CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache)); 3245249423Sdim } 3246249423Sdim 3247249423Sdim // Pass through all -fmodules-ignore-macro arguments. 3248249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro); 3249249423Sdim Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval); 3250249423Sdim Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after); 3251249423Sdim 3252207619Srdivacky // -faccess-control is default. 3253207619Srdivacky if (Args.hasFlag(options::OPT_fno_access_control, 3254207619Srdivacky options::OPT_faccess_control, 3255205408Srdivacky false)) 3256207619Srdivacky CmdArgs.push_back("-fno-access-control"); 3257205408Srdivacky 3258218893Sdim // -felide-constructors is the default. 3259218893Sdim if (Args.hasFlag(options::OPT_fno_elide_constructors, 3260218893Sdim options::OPT_felide_constructors, 3261218893Sdim false)) 3262218893Sdim CmdArgs.push_back("-fno-elide-constructors"); 3263218893Sdim 3264199482Srdivacky // -frtti is default. 3265234353Sdim if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) || 3266243830Sdim KernelOrKext) { 3267199512Srdivacky CmdArgs.push_back("-fno-rtti"); 3268198092Srdivacky 3269243830Sdim // -fno-rtti cannot usefully be combined with -fsanitize=vptr. 3270243830Sdim if (Sanitize.sanitizesVptr()) { 3271243830Sdim std::string NoRttiArg = 3272243830Sdim Args.getLastArg(options::OPT_mkernel, 3273243830Sdim options::OPT_fapple_kext, 3274243830Sdim options::OPT_fno_rtti)->getAsString(Args); 3275243830Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 3276243830Sdim << "-fsanitize=vptr" << NoRttiArg; 3277243830Sdim } 3278243830Sdim } 3279243830Sdim 3280234353Sdim // -fshort-enums=0 is default for all architectures except Hexagon. 3281218893Sdim if (Args.hasFlag(options::OPT_fshort_enums, 3282234353Sdim options::OPT_fno_short_enums, 3283263508Sdim getToolChain().getArch() == 3284234353Sdim llvm::Triple::hexagon)) 3285218893Sdim CmdArgs.push_back("-fshort-enums"); 3286218893Sdim 3287199482Srdivacky // -fsigned-char is default. 3288199990Srdivacky if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char, 3289199482Srdivacky isSignedCharDefault(getToolChain().getTriple()))) 3290199990Srdivacky CmdArgs.push_back("-fno-signed-char"); 3291199482Srdivacky 3292203955Srdivacky // -fthreadsafe-static is default. 3293218893Sdim if (!Args.hasFlag(options::OPT_fthreadsafe_statics, 3294203955Srdivacky options::OPT_fno_threadsafe_statics)) 3295203955Srdivacky CmdArgs.push_back("-fno-threadsafe-statics"); 3296203955Srdivacky 3297205408Srdivacky // -fuse-cxa-atexit is default. 3298263508Sdim if (!Args.hasFlag( 3299263508Sdim options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, 3300263508Sdim getToolChain().getTriple().getOS() != llvm::Triple::Cygwin && 3301263508Sdim getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 && 3302263508Sdim getToolChain().getArch() != llvm::Triple::hexagon && 3303263508Sdim getToolChain().getArch() != llvm::Triple::xcore) || 3304234353Sdim KernelOrKext) 3305205408Srdivacky CmdArgs.push_back("-fno-use-cxa-atexit"); 3306205408Srdivacky 3307199482Srdivacky // -fms-extensions=0 is default. 3308199990Srdivacky if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 3309199482Srdivacky getToolChain().getTriple().getOS() == llvm::Triple::Win32)) 3310199482Srdivacky CmdArgs.push_back("-fms-extensions"); 3311199482Srdivacky 3312226633Sdim // -fms-compatibility=0 is default. 3313234353Sdim if (Args.hasFlag(options::OPT_fms_compatibility, 3314234353Sdim options::OPT_fno_ms_compatibility, 3315234353Sdim (getToolChain().getTriple().getOS() == llvm::Triple::Win32 && 3316234353Sdim Args.hasFlag(options::OPT_fms_extensions, 3317234353Sdim options::OPT_fno_ms_extensions, 3318234353Sdim true)))) 3319226633Sdim CmdArgs.push_back("-fms-compatibility"); 3320226633Sdim 3321263508Sdim // -fmsc-version=1700 is default. 3322218893Sdim if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 3323218893Sdim getToolChain().getTriple().getOS() == llvm::Triple::Win32) || 3324218893Sdim Args.hasArg(options::OPT_fmsc_version)) { 3325226633Sdim StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version); 3326218893Sdim if (msc_ver.empty()) 3327263508Sdim CmdArgs.push_back("-fmsc-version=1700"); 3328218893Sdim else 3329218893Sdim CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver)); 3330218893Sdim } 3331218893Sdim 3332218893Sdim 3333249423Sdim // -fno-borland-extensions is default. 3334212904Sdim if (Args.hasFlag(options::OPT_fborland_extensions, 3335212904Sdim options::OPT_fno_borland_extensions, false)) 3336212904Sdim CmdArgs.push_back("-fborland-extensions"); 3337212904Sdim 3338226633Sdim // -fno-delayed-template-parsing is default, except for Windows where MSVC STL 3339226633Sdim // needs it. 3340221345Sdim if (Args.hasFlag(options::OPT_fdelayed_template_parsing, 3341221345Sdim options::OPT_fno_delayed_template_parsing, 3342226633Sdim getToolChain().getTriple().getOS() == llvm::Triple::Win32)) 3343221345Sdim CmdArgs.push_back("-fdelayed-template-parsing"); 3344221345Sdim 3345207619Srdivacky // -fgnu-keywords default varies depending on language; only pass if 3346207619Srdivacky // specified. 3347207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, 3348207619Srdivacky options::OPT_fno_gnu_keywords)) 3349207619Srdivacky A->render(Args, CmdArgs); 3350207619Srdivacky 3351223017Sdim if (Args.hasFlag(options::OPT_fgnu89_inline, 3352223017Sdim options::OPT_fno_gnu89_inline, 3353223017Sdim false)) 3354223017Sdim CmdArgs.push_back("-fgnu89-inline"); 3355223017Sdim 3356234353Sdim if (Args.hasArg(options::OPT_fno_inline)) 3357234353Sdim CmdArgs.push_back("-fno-inline"); 3358234353Sdim 3359234353Sdim if (Args.hasArg(options::OPT_fno_inline_functions)) 3360234353Sdim CmdArgs.push_back("-fno-inline-functions"); 3361234353Sdim 3362239462Sdim ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind); 3363224145Sdim 3364239462Sdim // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and 3365263508Sdim // legacy is the default. Next runtime is always legacy dispatch and 3366263508Sdim // -fno-objc-legacy-dispatch gets ignored silently. 3367263508Sdim if (objcRuntime.isNonFragile() && !objcRuntime.isNeXTFamily()) { 3368226633Sdim if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch, 3369226633Sdim options::OPT_fno_objc_legacy_dispatch, 3370239462Sdim objcRuntime.isLegacyDispatchDefaultForArch( 3371263508Sdim getToolChain().getArch()))) { 3372226633Sdim if (getToolChain().UseObjCMixedDispatch()) 3373226633Sdim CmdArgs.push_back("-fobjc-dispatch-method=mixed"); 3374226633Sdim else 3375226633Sdim CmdArgs.push_back("-fobjc-dispatch-method=non-legacy"); 3376218893Sdim } 3377199482Srdivacky } 3378199482Srdivacky 3379263508Sdim // When ObjectiveC legacy runtime is in effect on MacOSX, 3380263508Sdim // turn on the option to do Array/Dictionary subscripting 3381263508Sdim // by default. 3382263508Sdim if (getToolChain().getTriple().getArch() == llvm::Triple::x86 && 3383263508Sdim getToolChain().getTriple().isMacOSX() && 3384263508Sdim !getToolChain().getTriple().isMacOSXVersionLT(10, 7) && 3385263508Sdim objcRuntime.getKind() == ObjCRuntime::FragileMacOSX && 3386263508Sdim objcRuntime.isNeXTFamily()) 3387263508Sdim CmdArgs.push_back("-fobjc-subscripting-legacy-runtime"); 3388263508Sdim 3389243830Sdim // -fencode-extended-block-signature=1 is default. 3390243830Sdim if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) { 3391243830Sdim CmdArgs.push_back("-fencode-extended-block-signature"); 3392243830Sdim } 3393243830Sdim 3394224145Sdim // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc. 3395224145Sdim // NOTE: This logic is duplicated in ToolChains.cpp. 3396224145Sdim bool ARC = isObjCAutoRefCount(Args); 3397224145Sdim if (ARC) { 3398243830Sdim getToolChain().CheckObjCARC(); 3399234353Sdim 3400224145Sdim CmdArgs.push_back("-fobjc-arc"); 3401224145Sdim 3402228379Sdim // FIXME: It seems like this entire block, and several around it should be 3403228379Sdim // wrapped in isObjC, but for now we just use it here as this is where it 3404228379Sdim // was being used previously. 3405228379Sdim if (types::isCXX(InputType) && types::isObjC(InputType)) { 3406228379Sdim if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) 3407228379Sdim CmdArgs.push_back("-fobjc-arc-cxxlib=libc++"); 3408228379Sdim else 3409228379Sdim CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++"); 3410228379Sdim } 3411228379Sdim 3412224145Sdim // Allow the user to enable full exceptions code emission. 3413224145Sdim // We define off for Objective-CC, on for Objective-C++. 3414224145Sdim if (Args.hasFlag(options::OPT_fobjc_arc_exceptions, 3415224145Sdim options::OPT_fno_objc_arc_exceptions, 3416224145Sdim /*default*/ types::isCXX(InputType))) 3417224145Sdim CmdArgs.push_back("-fobjc-arc-exceptions"); 3418224145Sdim } 3419224145Sdim 3420224145Sdim // -fobjc-infer-related-result-type is the default, except in the Objective-C 3421224145Sdim // rewriter. 3422239462Sdim if (rewriteKind != RK_None) 3423224145Sdim CmdArgs.push_back("-fno-objc-infer-related-result-type"); 3424226633Sdim 3425224145Sdim // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only 3426224145Sdim // takes precedence. 3427224145Sdim const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only); 3428224145Sdim if (!GCArg) 3429224145Sdim GCArg = Args.getLastArg(options::OPT_fobjc_gc); 3430224145Sdim if (GCArg) { 3431224145Sdim if (ARC) { 3432226633Sdim D.Diag(diag::err_drv_objc_gc_arr) 3433224145Sdim << GCArg->getAsString(Args); 3434224145Sdim } else if (getToolChain().SupportsObjCGC()) { 3435224145Sdim GCArg->render(Args, CmdArgs); 3436224145Sdim } else { 3437224145Sdim // FIXME: We should move this to a hard error. 3438226633Sdim D.Diag(diag::warn_drv_objc_gc_unsupported) 3439224145Sdim << GCArg->getAsString(Args); 3440224145Sdim } 3441224145Sdim } 3442224145Sdim 3443224145Sdim // Add exception args. 3444224145Sdim addExceptionArgs(Args, InputType, getToolChain().getTriple(), 3445239462Sdim KernelOrKext, objcRuntime, CmdArgs); 3446224145Sdim 3447224145Sdim if (getToolChain().UseSjLjExceptions()) 3448224145Sdim CmdArgs.push_back("-fsjlj-exceptions"); 3449224145Sdim 3450224145Sdim // C++ "sane" operator new. 3451203955Srdivacky if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, 3452203955Srdivacky options::OPT_fno_assume_sane_operator_new)) 3453203955Srdivacky CmdArgs.push_back("-fno-assume-sane-operator-new"); 3454203955Srdivacky 3455207619Srdivacky // -fconstant-cfstrings is default, and may be subject to argument translation 3456207619Srdivacky // on Darwin. 3457207619Srdivacky if (!Args.hasFlag(options::OPT_fconstant_cfstrings, 3458207619Srdivacky options::OPT_fno_constant_cfstrings) || 3459207619Srdivacky !Args.hasFlag(options::OPT_mconstant_cfstrings, 3460207619Srdivacky options::OPT_mno_constant_cfstrings)) 3461207619Srdivacky CmdArgs.push_back("-fno-constant-cfstrings"); 3462207619Srdivacky 3463199482Srdivacky // -fshort-wchar default varies depending on platform; only 3464193576Sed // pass if specified. 3465207619Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) 3466207619Srdivacky A->render(Args, CmdArgs); 3467193576Sed 3468263508Sdim // -fno-pascal-strings is default, only pass non-default. 3469193326Sed if (Args.hasFlag(options::OPT_fpascal_strings, 3470193326Sed options::OPT_fno_pascal_strings, 3471193326Sed false)) 3472193326Sed CmdArgs.push_back("-fpascal-strings"); 3473193326Sed 3474226633Sdim // Honor -fpack-struct= and -fpack-struct, if given. Note that 3475226633Sdim // -fno-pack-struct doesn't apply to -fpack-struct=. 3476226633Sdim if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) { 3477239462Sdim std::string PackStructStr = "-fpack-struct="; 3478243830Sdim PackStructStr += A->getValue(); 3479239462Sdim CmdArgs.push_back(Args.MakeArgString(PackStructStr)); 3480226633Sdim } else if (Args.hasFlag(options::OPT_fpack_struct, 3481226633Sdim options::OPT_fno_pack_struct, false)) { 3482239462Sdim CmdArgs.push_back("-fpack-struct=1"); 3483226633Sdim } 3484226633Sdim 3485263508Sdim if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) { 3486218893Sdim if (!Args.hasArg(options::OPT_fcommon)) 3487218893Sdim CmdArgs.push_back("-fno-common"); 3488234353Sdim Args.ClaimAllArgs(options::OPT_fno_common); 3489218893Sdim } 3490226633Sdim 3491193326Sed // -fcommon is default, only pass non-default. 3492218893Sdim else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common)) 3493193326Sed CmdArgs.push_back("-fno-common"); 3494193326Sed 3495193326Sed // -fsigned-bitfields is default, and clang doesn't yet support 3496218893Sdim // -funsigned-bitfields. 3497198092Srdivacky if (!Args.hasFlag(options::OPT_fsigned_bitfields, 3498193326Sed options::OPT_funsigned_bitfields)) 3499226633Sdim D.Diag(diag::warn_drv_clang_unsupported) 3500193326Sed << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args); 3501193326Sed 3502218893Sdim // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope. 3503218893Sdim if (!Args.hasFlag(options::OPT_ffor_scope, 3504218893Sdim options::OPT_fno_for_scope)) 3505226633Sdim D.Diag(diag::err_drv_clang_unsupported) 3506218893Sdim << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args); 3507218893Sdim 3508210299Sed // -fcaret-diagnostics is default. 3509210299Sed if (!Args.hasFlag(options::OPT_fcaret_diagnostics, 3510210299Sed options::OPT_fno_caret_diagnostics, true)) 3511210299Sed CmdArgs.push_back("-fno-caret-diagnostics"); 3512210299Sed 3513193326Sed // -fdiagnostics-fixit-info is default, only pass non-default. 3514198092Srdivacky if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info, 3515193326Sed options::OPT_fno_diagnostics_fixit_info)) 3516193326Sed CmdArgs.push_back("-fno-diagnostics-fixit-info"); 3517226633Sdim 3518193326Sed // Enable -fdiagnostics-show-option by default. 3519198092Srdivacky if (Args.hasFlag(options::OPT_fdiagnostics_show_option, 3520193326Sed options::OPT_fno_diagnostics_show_option)) 3521193326Sed CmdArgs.push_back("-fdiagnostics-show-option"); 3522198893Srdivacky 3523208600Srdivacky if (const Arg *A = 3524208600Srdivacky Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { 3525208600Srdivacky CmdArgs.push_back("-fdiagnostics-show-category"); 3526243830Sdim CmdArgs.push_back(A->getValue()); 3527208600Srdivacky } 3528212904Sdim 3529223017Sdim if (const Arg *A = 3530223017Sdim Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { 3531223017Sdim CmdArgs.push_back("-fdiagnostics-format"); 3532243830Sdim CmdArgs.push_back(A->getValue()); 3533223017Sdim } 3534223017Sdim 3535221345Sdim if (Arg *A = Args.getLastArg( 3536221345Sdim options::OPT_fdiagnostics_show_note_include_stack, 3537221345Sdim options::OPT_fno_diagnostics_show_note_include_stack)) { 3538221345Sdim if (A->getOption().matches( 3539221345Sdim options::OPT_fdiagnostics_show_note_include_stack)) 3540221345Sdim CmdArgs.push_back("-fdiagnostics-show-note-include-stack"); 3541221345Sdim else 3542221345Sdim CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); 3543221345Sdim } 3544221345Sdim 3545198893Srdivacky // Color diagnostics are the default, unless the terminal doesn't support 3546198893Srdivacky // them. 3547251662Sdim // Support both clang's -f[no-]color-diagnostics and gcc's 3548251662Sdim // -f[no-]diagnostics-colors[=never|always|auto]. 3549251662Sdim enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto; 3550251662Sdim for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 3551251662Sdim it != ie; ++it) { 3552251662Sdim const Option &O = (*it)->getOption(); 3553251662Sdim if (!O.matches(options::OPT_fcolor_diagnostics) && 3554251662Sdim !O.matches(options::OPT_fdiagnostics_color) && 3555251662Sdim !O.matches(options::OPT_fno_color_diagnostics) && 3556251662Sdim !O.matches(options::OPT_fno_diagnostics_color) && 3557251662Sdim !O.matches(options::OPT_fdiagnostics_color_EQ)) 3558251662Sdim continue; 3559251662Sdim 3560251662Sdim (*it)->claim(); 3561251662Sdim if (O.matches(options::OPT_fcolor_diagnostics) || 3562251662Sdim O.matches(options::OPT_fdiagnostics_color)) { 3563251662Sdim ShowColors = Colors_On; 3564251662Sdim } else if (O.matches(options::OPT_fno_color_diagnostics) || 3565251662Sdim O.matches(options::OPT_fno_diagnostics_color)) { 3566251662Sdim ShowColors = Colors_Off; 3567251662Sdim } else { 3568251662Sdim assert(O.matches(options::OPT_fdiagnostics_color_EQ)); 3569251662Sdim StringRef value((*it)->getValue()); 3570251662Sdim if (value == "always") 3571251662Sdim ShowColors = Colors_On; 3572251662Sdim else if (value == "never") 3573251662Sdim ShowColors = Colors_Off; 3574251662Sdim else if (value == "auto") 3575251662Sdim ShowColors = Colors_Auto; 3576251662Sdim else 3577251662Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3578251662Sdim << ("-fdiagnostics-color=" + value).str(); 3579251662Sdim } 3580251662Sdim } 3581251662Sdim if (ShowColors == Colors_On || 3582251662Sdim (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) 3583198893Srdivacky CmdArgs.push_back("-fcolor-diagnostics"); 3584198893Srdivacky 3585263508Sdim if (Args.hasArg(options::OPT_fansi_escape_codes)) 3586263508Sdim CmdArgs.push_back("-fansi-escape-codes"); 3587263508Sdim 3588194179Sed if (!Args.hasFlag(options::OPT_fshow_source_location, 3589194179Sed options::OPT_fno_show_source_location)) 3590194179Sed CmdArgs.push_back("-fno-show-source-location"); 3591193326Sed 3592223017Sdim if (!Args.hasFlag(options::OPT_fshow_column, 3593223017Sdim options::OPT_fno_show_column, 3594223017Sdim true)) 3595223017Sdim CmdArgs.push_back("-fno-show-column"); 3596223017Sdim 3597210299Sed if (!Args.hasFlag(options::OPT_fspell_checking, 3598210299Sed options::OPT_fno_spell_checking)) 3599210299Sed CmdArgs.push_back("-fno-spell-checking"); 3600212904Sdim 3601218893Sdim 3602249423Sdim // -fno-asm-blocks is default. 3603249423Sdim if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks, 3604249423Sdim false)) 3605249423Sdim CmdArgs.push_back("-fasm-blocks"); 3606218893Sdim 3607263508Sdim // Enable vectorization per default according to the optimization level 3608263508Sdim // selected. For optimization levels that want vectorization we use the alias 3609263508Sdim // option to simplify the hasFlag logic. 3610263508Sdim bool EnableVec = shouldEnableVectorizerAtOLevel(Args); 3611263508Sdim OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group : 3612251662Sdim options::OPT_fvectorize; 3613251662Sdim if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption, 3614263508Sdim options::OPT_fno_vectorize, EnableVec)) 3615249423Sdim CmdArgs.push_back("-vectorize-loops"); 3616249423Sdim 3617263508Sdim // -fslp-vectorize is default. 3618249423Sdim if (Args.hasFlag(options::OPT_fslp_vectorize, 3619263508Sdim options::OPT_fno_slp_vectorize, true)) 3620251662Sdim CmdArgs.push_back("-vectorize-slp"); 3621249423Sdim 3622251662Sdim // -fno-slp-vectorize-aggressive is default. 3623251662Sdim if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive, 3624263508Sdim options::OPT_fno_slp_vectorize_aggressive, false)) 3625251662Sdim CmdArgs.push_back("-vectorize-slp-aggressive"); 3626251662Sdim 3627210299Sed if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ)) 3628210299Sed A->render(Args, CmdArgs); 3629210299Sed 3630193326Sed // -fdollars-in-identifiers default varies depending on platform and 3631193326Sed // language; only pass if specified. 3632198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers, 3633193326Sed options::OPT_fno_dollars_in_identifiers)) { 3634193326Sed if (A->getOption().matches(options::OPT_fdollars_in_identifiers)) 3635201361Srdivacky CmdArgs.push_back("-fdollars-in-identifiers"); 3636193326Sed else 3637201361Srdivacky CmdArgs.push_back("-fno-dollars-in-identifiers"); 3638193326Sed } 3639193326Sed 3640193326Sed // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for 3641193326Sed // practical purposes. 3642198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time, 3643193326Sed options::OPT_fno_unit_at_a_time)) { 3644193326Sed if (A->getOption().matches(options::OPT_fno_unit_at_a_time)) 3645226633Sdim D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); 3646193326Sed } 3647198092Srdivacky 3648234353Sdim if (Args.hasFlag(options::OPT_fapple_pragma_pack, 3649234353Sdim options::OPT_fno_apple_pragma_pack, false)) 3650234353Sdim CmdArgs.push_back("-fapple-pragma-pack"); 3651234353Sdim 3652263508Sdim // le32-specific flags: 3653263508Sdim // -fno-math-builtin: clang should not convert math builtins to intrinsics 3654263508Sdim // by default. 3655263508Sdim if (getToolChain().getArch() == llvm::Triple::le32) { 3656263508Sdim CmdArgs.push_back("-fno-math-builtin"); 3657263508Sdim } 3658263508Sdim 3659198092Srdivacky // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM. 3660198092Srdivacky // 3661200583Srdivacky // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941. 3662198092Srdivacky#if 0 3663226633Sdim if (getToolChain().getTriple().isOSDarwin() && 3664263508Sdim (getToolChain().getArch() == llvm::Triple::arm || 3665263508Sdim getToolChain().getArch() == llvm::Triple::thumb)) { 3666198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcat)) 3667198092Srdivacky CmdArgs.push_back("-fno-builtin-strcat"); 3668198092Srdivacky if (!Args.hasArg(options::OPT_fbuiltin_strcpy)) 3669198092Srdivacky CmdArgs.push_back("-fno-builtin-strcpy"); 3670198092Srdivacky } 3671198092Srdivacky#endif 3672198092Srdivacky 3673221345Sdim // Only allow -traditional or -traditional-cpp outside in preprocessing modes. 3674198092Srdivacky if (Arg *A = Args.getLastArg(options::OPT_traditional, 3675221345Sdim options::OPT_traditional_cpp)) { 3676221345Sdim if (isa<PreprocessJobAction>(JA)) 3677221345Sdim CmdArgs.push_back("-traditional-cpp"); 3678226633Sdim else 3679226633Sdim D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); 3680221345Sdim } 3681198092Srdivacky 3682193326Sed Args.AddLastArg(CmdArgs, options::OPT_dM); 3683193326Sed Args.AddLastArg(CmdArgs, options::OPT_dD); 3684234353Sdim 3685234353Sdim // Handle serialized diagnostics. 3686234353Sdim if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) { 3687234353Sdim CmdArgs.push_back("-serialize-diagnostic-file"); 3688243830Sdim CmdArgs.push_back(Args.MakeArgString(A->getValue())); 3689234353Sdim } 3690193326Sed 3691243830Sdim if (Args.hasArg(options::OPT_fretain_comments_from_system_headers)) 3692243830Sdim CmdArgs.push_back("-fretain-comments-from-system-headers"); 3693243830Sdim 3694249423Sdim // Forward -fcomment-block-commands to -cc1. 3695249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); 3696251662Sdim // Forward -fparse-all-comments to -cc1. 3697251662Sdim Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments); 3698249423Sdim 3699207619Srdivacky // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option 3700207619Srdivacky // parser. 3701193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Xclang); 3702207619Srdivacky for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm), 3703207619Srdivacky ie = Args.filtered_end(); it != ie; ++it) { 3704210299Sed (*it)->claim(); 3705193326Sed 3706207619Srdivacky // We translate this by hand to the -cc1 argument, since nightly test uses 3707207619Srdivacky // it and developers have been trained to spell it with -mllvm. 3708243830Sdim if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns") 3709207619Srdivacky CmdArgs.push_back("-disable-llvm-optzns"); 3710207619Srdivacky else 3711210299Sed (*it)->render(Args, CmdArgs); 3712207619Srdivacky } 3713207619Srdivacky 3714193326Sed if (Output.getType() == types::TY_Dependencies) { 3715193326Sed // Handled with other dependency code. 3716193326Sed } else if (Output.isFilename()) { 3717193326Sed CmdArgs.push_back("-o"); 3718193326Sed CmdArgs.push_back(Output.getFilename()); 3719193326Sed } else { 3720193326Sed assert(Output.isNothing() && "Invalid output."); 3721193326Sed } 3722193326Sed 3723193326Sed for (InputInfoList::const_iterator 3724193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 3725193326Sed const InputInfo &II = *it; 3726193326Sed CmdArgs.push_back("-x"); 3727243830Sdim if (Args.hasArg(options::OPT_rewrite_objc)) 3728243830Sdim CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX)); 3729243830Sdim else 3730243830Sdim CmdArgs.push_back(types::getTypeName(II.getType())); 3731212904Sdim if (II.isFilename()) 3732193326Sed CmdArgs.push_back(II.getFilename()); 3733193326Sed else 3734193326Sed II.getInputArg().renderAsInput(Args, CmdArgs); 3735193326Sed } 3736193326Sed 3737198893Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_undef); 3738198893Srdivacky 3739212904Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 3740201361Srdivacky 3741201361Srdivacky // Optionally embed the -cc1 level arguments into the debug info, for build 3742201361Srdivacky // analysis. 3743201361Srdivacky if (getToolChain().UseDwarfDebugFlags()) { 3744210299Sed ArgStringList OriginalArgs; 3745210299Sed for (ArgList::const_iterator it = Args.begin(), 3746210299Sed ie = Args.end(); it != ie; ++it) 3747210299Sed (*it)->render(Args, OriginalArgs); 3748212904Sdim 3749234353Sdim SmallString<256> Flags; 3750201361Srdivacky Flags += Exec; 3751210299Sed for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { 3752201361Srdivacky Flags += " "; 3753210299Sed Flags += OriginalArgs[i]; 3754201361Srdivacky } 3755201361Srdivacky CmdArgs.push_back("-dwarf-debug-flags"); 3756201361Srdivacky CmdArgs.push_back(Args.MakeArgString(Flags.str())); 3757201361Srdivacky } 3758201361Srdivacky 3759249423Sdim // Add the split debug info name to the command lines here so we 3760249423Sdim // can propagate it to the backend. 3761249423Sdim bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) && 3762263508Sdim getToolChain().getTriple().isOSLinux() && 3763249423Sdim (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA)); 3764249423Sdim const char *SplitDwarfOut; 3765249423Sdim if (SplitDwarf) { 3766249423Sdim CmdArgs.push_back("-split-dwarf-file"); 3767249423Sdim SplitDwarfOut = SplitDebugName(Args, Inputs); 3768249423Sdim CmdArgs.push_back(SplitDwarfOut); 3769249423Sdim } 3770249423Sdim 3771249423Sdim // Finally add the compile command to the compilation. 3772263508Sdim if (Args.hasArg(options::OPT__SLASH_fallback)) { 3773263508Sdim tools::visualstudio::Compile CL(getToolChain()); 3774263508Sdim Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args, 3775263508Sdim LinkingOutput); 3776263508Sdim C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand)); 3777263508Sdim } else { 3778263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 3779263508Sdim } 3780193326Sed 3781263508Sdim 3782249423Sdim // Handle the debug info splitting at object creation time if we're 3783249423Sdim // creating an object. 3784249423Sdim // TODO: Currently only works on linux with newer objcopy. 3785249423Sdim if (SplitDwarf && !isa<CompileJobAction>(JA)) 3786249423Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut); 3787249423Sdim 3788218893Sdim if (Arg *A = Args.getLastArg(options::OPT_pg)) 3789218893Sdim if (Args.hasArg(options::OPT_fomit_frame_pointer)) 3790226633Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 3791218893Sdim << "-fomit-frame-pointer" << A->getAsString(Args); 3792193326Sed 3793193326Sed // Claim some arguments which clang supports automatically. 3794193326Sed 3795207619Srdivacky // -fpch-preprocess is used with gcc to add a special marker in the output to 3796207619Srdivacky // include the PCH file. Clang's PTH solution is completely transparent, so we 3797207619Srdivacky // do not need to deal with it at all. 3798193326Sed Args.ClaimAllArgs(options::OPT_fpch_preprocess); 3799193326Sed 3800193326Sed // Claim some arguments which clang doesn't support, but we don't 3801193326Sed // care to warn the user about. 3802199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group); 3803199990Srdivacky Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group); 3804221345Sdim 3805263508Sdim // Disable warnings for clang -E -emit-llvm foo.c 3806221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 3807193326Sed} 3808193326Sed 3809239462Sdim/// Add options related to the Objective-C runtime/ABI. 3810239462Sdim/// 3811239462Sdim/// Returns true if the runtime is non-fragile. 3812239462SdimObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, 3813239462Sdim ArgStringList &cmdArgs, 3814239462Sdim RewriteKind rewriteKind) const { 3815239462Sdim // Look for the controlling runtime option. 3816239462Sdim Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime, 3817239462Sdim options::OPT_fgnu_runtime, 3818239462Sdim options::OPT_fobjc_runtime_EQ); 3819239462Sdim 3820239462Sdim // Just forward -fobjc-runtime= to the frontend. This supercedes 3821239462Sdim // options about fragility. 3822239462Sdim if (runtimeArg && 3823239462Sdim runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) { 3824239462Sdim ObjCRuntime runtime; 3825243830Sdim StringRef value = runtimeArg->getValue(); 3826239462Sdim if (runtime.tryParse(value)) { 3827239462Sdim getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime) 3828239462Sdim << value; 3829239462Sdim } 3830239462Sdim 3831239462Sdim runtimeArg->render(args, cmdArgs); 3832239462Sdim return runtime; 3833239462Sdim } 3834239462Sdim 3835239462Sdim // Otherwise, we'll need the ABI "version". Version numbers are 3836239462Sdim // slightly confusing for historical reasons: 3837239462Sdim // 1 - Traditional "fragile" ABI 3838239462Sdim // 2 - Non-fragile ABI, version 1 3839239462Sdim // 3 - Non-fragile ABI, version 2 3840239462Sdim unsigned objcABIVersion = 1; 3841239462Sdim // If -fobjc-abi-version= is present, use that to set the version. 3842239462Sdim if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) { 3843243830Sdim StringRef value = abiArg->getValue(); 3844239462Sdim if (value == "1") 3845239462Sdim objcABIVersion = 1; 3846239462Sdim else if (value == "2") 3847239462Sdim objcABIVersion = 2; 3848239462Sdim else if (value == "3") 3849239462Sdim objcABIVersion = 3; 3850239462Sdim else 3851239462Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3852239462Sdim << value; 3853239462Sdim } else { 3854239462Sdim // Otherwise, determine if we are using the non-fragile ABI. 3855239462Sdim bool nonFragileABIIsDefault = 3856239462Sdim (rewriteKind == RK_NonFragile || 3857239462Sdim (rewriteKind == RK_None && 3858239462Sdim getToolChain().IsObjCNonFragileABIDefault())); 3859239462Sdim if (args.hasFlag(options::OPT_fobjc_nonfragile_abi, 3860239462Sdim options::OPT_fno_objc_nonfragile_abi, 3861239462Sdim nonFragileABIIsDefault)) { 3862239462Sdim // Determine the non-fragile ABI version to use. 3863239462Sdim#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO 3864239462Sdim unsigned nonFragileABIVersion = 1; 3865239462Sdim#else 3866239462Sdim unsigned nonFragileABIVersion = 2; 3867239462Sdim#endif 3868239462Sdim 3869239462Sdim if (Arg *abiArg = args.getLastArg( 3870239462Sdim options::OPT_fobjc_nonfragile_abi_version_EQ)) { 3871243830Sdim StringRef value = abiArg->getValue(); 3872239462Sdim if (value == "1") 3873239462Sdim nonFragileABIVersion = 1; 3874239462Sdim else if (value == "2") 3875239462Sdim nonFragileABIVersion = 2; 3876239462Sdim else 3877239462Sdim getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) 3878239462Sdim << value; 3879239462Sdim } 3880239462Sdim 3881239462Sdim objcABIVersion = 1 + nonFragileABIVersion; 3882239462Sdim } else { 3883239462Sdim objcABIVersion = 1; 3884239462Sdim } 3885239462Sdim } 3886239462Sdim 3887239462Sdim // We don't actually care about the ABI version other than whether 3888239462Sdim // it's non-fragile. 3889239462Sdim bool isNonFragile = objcABIVersion != 1; 3890239462Sdim 3891239462Sdim // If we have no runtime argument, ask the toolchain for its default runtime. 3892239462Sdim // However, the rewriter only really supports the Mac runtime, so assume that. 3893239462Sdim ObjCRuntime runtime; 3894239462Sdim if (!runtimeArg) { 3895239462Sdim switch (rewriteKind) { 3896239462Sdim case RK_None: 3897239462Sdim runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); 3898239462Sdim break; 3899239462Sdim case RK_Fragile: 3900239462Sdim runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple()); 3901239462Sdim break; 3902239462Sdim case RK_NonFragile: 3903239462Sdim runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple()); 3904239462Sdim break; 3905239462Sdim } 3906239462Sdim 3907239462Sdim // -fnext-runtime 3908239462Sdim } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) { 3909239462Sdim // On Darwin, make this use the default behavior for the toolchain. 3910239462Sdim if (getToolChain().getTriple().isOSDarwin()) { 3911239462Sdim runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); 3912239462Sdim 3913239462Sdim // Otherwise, build for a generic macosx port. 3914239462Sdim } else { 3915239462Sdim runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple()); 3916239462Sdim } 3917239462Sdim 3918239462Sdim // -fgnu-runtime 3919239462Sdim } else { 3920239462Sdim assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime)); 3921239462Sdim // Legacy behaviour is to target the gnustep runtime if we are i 3922239462Sdim // non-fragile mode or the GCC runtime in fragile mode. 3923239462Sdim if (isNonFragile) 3924243830Sdim runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6)); 3925239462Sdim else 3926239462Sdim runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple()); 3927239462Sdim } 3928239462Sdim 3929239462Sdim cmdArgs.push_back(args.MakeArgString( 3930239462Sdim "-fobjc-runtime=" + runtime.getAsString())); 3931239462Sdim return runtime; 3932239462Sdim} 3933239462Sdim 3934263508Sdimvoid Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const { 3935263508Sdim unsigned RTOptionID = options::OPT__SLASH_MT; 3936263508Sdim 3937263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3938263508Sdim // The /LDd option implies /MTd. The dependent lib part can be overridden, 3939263508Sdim // but defining _DEBUG is sticky. 3940263508Sdim RTOptionID = options::OPT__SLASH_MTd; 3941263508Sdim 3942263508Sdim if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) 3943263508Sdim RTOptionID = A->getOption().getID(); 3944263508Sdim 3945263508Sdim switch(RTOptionID) { 3946263508Sdim case options::OPT__SLASH_MD: 3947263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3948263508Sdim CmdArgs.push_back("-D_DEBUG"); 3949263508Sdim CmdArgs.push_back("-D_MT"); 3950263508Sdim CmdArgs.push_back("-D_DLL"); 3951263508Sdim CmdArgs.push_back("--dependent-lib=msvcrt"); 3952263508Sdim break; 3953263508Sdim case options::OPT__SLASH_MDd: 3954263508Sdim CmdArgs.push_back("-D_DEBUG"); 3955263508Sdim CmdArgs.push_back("-D_MT"); 3956263508Sdim CmdArgs.push_back("-D_DLL"); 3957263508Sdim CmdArgs.push_back("--dependent-lib=msvcrtd"); 3958263508Sdim break; 3959263508Sdim case options::OPT__SLASH_MT: 3960263508Sdim if (Args.hasArg(options::OPT__SLASH_LDd)) 3961263508Sdim CmdArgs.push_back("-D_DEBUG"); 3962263508Sdim CmdArgs.push_back("-D_MT"); 3963263508Sdim CmdArgs.push_back("--dependent-lib=libcmt"); 3964263508Sdim break; 3965263508Sdim case options::OPT__SLASH_MTd: 3966263508Sdim CmdArgs.push_back("-D_DEBUG"); 3967263508Sdim CmdArgs.push_back("-D_MT"); 3968263508Sdim CmdArgs.push_back("--dependent-lib=libcmtd"); 3969263508Sdim break; 3970263508Sdim default: 3971263508Sdim llvm_unreachable("Unexpected option ID."); 3972263508Sdim } 3973263508Sdim 3974263508Sdim // This provides POSIX compatibility (maps 'open' to '_open'), which most 3975263508Sdim // users want. The /Za flag to cl.exe turns this off, but it's not 3976263508Sdim // implemented in clang. 3977263508Sdim CmdArgs.push_back("--dependent-lib=oldnames"); 3978263508Sdim 3979263508Sdim // FIXME: Make this default for the win32 triple. 3980263508Sdim CmdArgs.push_back("-cxx-abi"); 3981263508Sdim CmdArgs.push_back("microsoft"); 3982263508Sdim 3983263508Sdim if (Arg *A = Args.getLastArg(options::OPT_show_includes)) 3984263508Sdim A->render(Args, CmdArgs); 3985263508Sdim 3986263508Sdim if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) { 3987263508Sdim CmdArgs.push_back("-fdiagnostics-format"); 3988263508Sdim if (Args.hasArg(options::OPT__SLASH_fallback)) 3989263508Sdim CmdArgs.push_back("msvc-fallback"); 3990263508Sdim else 3991263508Sdim CmdArgs.push_back("msvc"); 3992263508Sdim } 3993263508Sdim} 3994263508Sdim 3995208600Srdivackyvoid ClangAs::ConstructJob(Compilation &C, const JobAction &JA, 3996208600Srdivacky const InputInfo &Output, 3997208600Srdivacky const InputInfoList &Inputs, 3998208600Srdivacky const ArgList &Args, 3999208600Srdivacky const char *LinkingOutput) const { 4000208600Srdivacky ArgStringList CmdArgs; 4001208600Srdivacky 4002208600Srdivacky assert(Inputs.size() == 1 && "Unexpected number of inputs."); 4003208600Srdivacky const InputInfo &Input = Inputs[0]; 4004208600Srdivacky 4005218893Sdim // Don't warn about "clang -w -c foo.s" 4006218893Sdim Args.ClaimAllArgs(options::OPT_w); 4007221345Sdim // and "clang -emit-llvm -c foo.s" 4008221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 4009218893Sdim 4010208600Srdivacky // Invoke ourselves in -cc1as mode. 4011208600Srdivacky // 4012208600Srdivacky // FIXME: Implement custom jobs for internal actions. 4013208600Srdivacky CmdArgs.push_back("-cc1as"); 4014208600Srdivacky 4015208600Srdivacky // Add the "effective" target triple. 4016208600Srdivacky CmdArgs.push_back("-triple"); 4017226633Sdim std::string TripleStr = 4018226633Sdim getToolChain().ComputeEffectiveClangTriple(Args, Input.getType()); 4019208600Srdivacky CmdArgs.push_back(Args.MakeArgString(TripleStr)); 4020208600Srdivacky 4021208600Srdivacky // Set the output mode, we currently only expect to be used as a real 4022208600Srdivacky // assembler. 4023208600Srdivacky CmdArgs.push_back("-filetype"); 4024208600Srdivacky CmdArgs.push_back("obj"); 4025208600Srdivacky 4026249423Sdim // Set the main file name, so that debug info works even with 4027249423Sdim // -save-temps or preprocessed assembly. 4028249423Sdim CmdArgs.push_back("-main-file-name"); 4029249423Sdim CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs)); 4030249423Sdim 4031263508Sdim // Add the target cpu 4032263508Sdim const llvm::Triple &Triple = getToolChain().getTriple(); 4033263508Sdim std::string CPU = getCPUName(Args, Triple); 4034263508Sdim if (!CPU.empty()) { 4035263508Sdim CmdArgs.push_back("-target-cpu"); 4036263508Sdim CmdArgs.push_back(Args.MakeArgString(CPU)); 4037263508Sdim } 4038208600Srdivacky 4039263508Sdim // Add the target features 4040263508Sdim const Driver &D = getToolChain().getDriver(); 4041263508Sdim getTargetFeatures(D, Triple, Args, CmdArgs); 4042234353Sdim 4043221345Sdim // Ignore explicit -force_cpusubtype_ALL option. 4044221345Sdim (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); 4045208600Srdivacky 4046234353Sdim // Determine the original source input. 4047234353Sdim const Action *SourceAction = &JA; 4048234353Sdim while (SourceAction->getKind() != Action::InputClass) { 4049234353Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 4050234353Sdim SourceAction = SourceAction->getInputs()[0]; 4051234353Sdim } 4052208600Srdivacky 4053249423Sdim // Forward -g and handle debug info related flags, assuming we are dealing 4054249423Sdim // with an actual assembly file. 4055234353Sdim if (SourceAction->getType() == types::TY_Asm || 4056234353Sdim SourceAction->getType() == types::TY_PP_Asm) { 4057234353Sdim Args.ClaimAllArgs(options::OPT_g_Group); 4058234353Sdim if (Arg *A = Args.getLastArg(options::OPT_g_Group)) 4059234353Sdim if (!A->getOption().matches(options::OPT_g0)) 4060234353Sdim CmdArgs.push_back("-g"); 4061249423Sdim 4062249423Sdim // Add the -fdebug-compilation-dir flag if needed. 4063249423Sdim addDebugCompDirArg(Args, CmdArgs); 4064249423Sdim 4065249423Sdim // Set the AT_producer to the clang version when using the integrated 4066249423Sdim // assembler on assembly source files. 4067249423Sdim CmdArgs.push_back("-dwarf-debug-producer"); 4068249423Sdim CmdArgs.push_back(Args.MakeArgString(getClangFullVersion())); 4069234353Sdim } 4070234353Sdim 4071234353Sdim // Optionally embed the -cc1as level arguments into the debug info, for build 4072234353Sdim // analysis. 4073234353Sdim if (getToolChain().UseDwarfDebugFlags()) { 4074234353Sdim ArgStringList OriginalArgs; 4075234353Sdim for (ArgList::const_iterator it = Args.begin(), 4076234353Sdim ie = Args.end(); it != ie; ++it) 4077234353Sdim (*it)->render(Args, OriginalArgs); 4078234353Sdim 4079234353Sdim SmallString<256> Flags; 4080234353Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 4081234353Sdim Flags += Exec; 4082234353Sdim for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { 4083234353Sdim Flags += " "; 4084234353Sdim Flags += OriginalArgs[i]; 4085234353Sdim } 4086234353Sdim CmdArgs.push_back("-dwarf-debug-flags"); 4087234353Sdim CmdArgs.push_back(Args.MakeArgString(Flags.str())); 4088234353Sdim } 4089234353Sdim 4090208600Srdivacky // FIXME: Add -static support, once we have it. 4091208600Srdivacky 4092263508Sdim CollectArgsForIntegratedAssembler(C, Args, CmdArgs, 4093263508Sdim getToolChain().getDriver()); 4094263508Sdim 4095221345Sdim Args.AddAllArgs(CmdArgs, options::OPT_mllvm); 4096208600Srdivacky 4097208600Srdivacky assert(Output.isFilename() && "Unexpected lipo output."); 4098208600Srdivacky CmdArgs.push_back("-o"); 4099208600Srdivacky CmdArgs.push_back(Output.getFilename()); 4100208600Srdivacky 4101212904Sdim assert(Input.isFilename() && "Invalid input."); 4102212904Sdim CmdArgs.push_back(Input.getFilename()); 4103208600Srdivacky 4104212904Sdim const char *Exec = getToolChain().getDriver().getClangProgramPath(); 4105212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4106251662Sdim 4107251662Sdim // Handle the debug info splitting at object creation time if we're 4108251662Sdim // creating an object. 4109251662Sdim // TODO: Currently only works on linux with newer objcopy. 4110251662Sdim if (Args.hasArg(options::OPT_gsplit_dwarf) && 4111263508Sdim getToolChain().getTriple().isOSLinux()) 4112251662Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, 4113251662Sdim SplitDebugName(Args, Inputs)); 4114208600Srdivacky} 4115208600Srdivacky 4116193326Sedvoid gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, 4117193326Sed const InputInfo &Output, 4118193326Sed const InputInfoList &Inputs, 4119193326Sed const ArgList &Args, 4120193326Sed const char *LinkingOutput) const { 4121201361Srdivacky const Driver &D = getToolChain().getDriver(); 4122193326Sed ArgStringList CmdArgs; 4123193326Sed 4124193326Sed for (ArgList::const_iterator 4125193326Sed it = Args.begin(), ie = Args.end(); it != ie; ++it) { 4126193326Sed Arg *A = *it; 4127243830Sdim if (forwardToGCC(A->getOption())) { 4128212904Sdim // Don't forward any -g arguments to assembly steps. 4129212904Sdim if (isa<AssembleJobAction>(JA) && 4130212904Sdim A->getOption().matches(options::OPT_g_Group)) 4131212904Sdim continue; 4132212904Sdim 4133263508Sdim // Don't forward any -W arguments to assembly and link steps. 4134263508Sdim if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) && 4135263508Sdim A->getOption().matches(options::OPT_W_Group)) 4136263508Sdim continue; 4137263508Sdim 4138193326Sed // It is unfortunate that we have to claim here, as this means 4139193326Sed // we will basically never report anything interesting for 4140193326Sed // platforms using a generic gcc, even if we are just using gcc 4141193326Sed // to get to the assembler. 4142193326Sed A->claim(); 4143193326Sed A->render(Args, CmdArgs); 4144193326Sed } 4145193326Sed } 4146193326Sed 4147203955Srdivacky RenderExtraToolArgs(JA, CmdArgs); 4148193326Sed 4149193326Sed // If using a driver driver, force the arch. 4150243830Sdim llvm::Triple::ArchType Arch = getToolChain().getArch(); 4151226633Sdim if (getToolChain().getTriple().isOSDarwin()) { 4152193326Sed CmdArgs.push_back("-arch"); 4153193326Sed 4154193326Sed // FIXME: Remove these special cases. 4155243830Sdim if (Arch == llvm::Triple::ppc) 4156193326Sed CmdArgs.push_back("ppc"); 4157243830Sdim else if (Arch == llvm::Triple::ppc64) 4158193326Sed CmdArgs.push_back("ppc64"); 4159263508Sdim else if (Arch == llvm::Triple::ppc64le) 4160263508Sdim CmdArgs.push_back("ppc64le"); 4161193326Sed else 4162243830Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName())); 4163193326Sed } 4164193326Sed 4165193326Sed // Try to force gcc to match the tool chain we want, if we recognize 4166193326Sed // the arch. 4167193326Sed // 4168193326Sed // FIXME: The triple class should directly provide the information we want 4169193326Sed // here. 4170243830Sdim if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) 4171193326Sed CmdArgs.push_back("-m32"); 4172263508Sdim else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 || 4173263508Sdim Arch == llvm::Triple::ppc64le) 4174193326Sed CmdArgs.push_back("-m64"); 4175193326Sed 4176212904Sdim if (Output.isFilename()) { 4177193326Sed CmdArgs.push_back("-o"); 4178193326Sed CmdArgs.push_back(Output.getFilename()); 4179193326Sed } else { 4180193326Sed assert(Output.isNothing() && "Unexpected output"); 4181193326Sed CmdArgs.push_back("-fsyntax-only"); 4182193326Sed } 4183193326Sed 4184234353Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4185234353Sdim options::OPT_Xassembler); 4186193326Sed 4187193326Sed // Only pass -x if gcc will understand it; otherwise hope gcc 4188193326Sed // understands the suffix correctly. The main use case this would go 4189193326Sed // wrong in is for linker inputs if they happened to have an odd 4190193326Sed // suffix; really the only way to get this to happen is a command 4191193326Sed // like '-x foobar a.c' which will treat a.c like a linker input. 4192193326Sed // 4193193326Sed // FIXME: For the linker case specifically, can we safely convert 4194193326Sed // inputs into '-Wl,' options? 4195193326Sed for (InputInfoList::const_iterator 4196193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 4197193326Sed const InputInfo &II = *it; 4198193326Sed 4199198092Srdivacky // Don't try to pass LLVM or AST inputs to a generic gcc. 4200210299Sed if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || 4201210299Sed II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) 4202226633Sdim D.Diag(diag::err_drv_no_linker_llvm_support) 4203198092Srdivacky << getToolChain().getTripleString(); 4204198092Srdivacky else if (II.getType() == types::TY_AST) 4205226633Sdim D.Diag(diag::err_drv_no_ast_support) 4206198092Srdivacky << getToolChain().getTripleString(); 4207249423Sdim else if (II.getType() == types::TY_ModuleFile) 4208249423Sdim D.Diag(diag::err_drv_no_module_support) 4209249423Sdim << getToolChain().getTripleString(); 4210193326Sed 4211193326Sed if (types::canTypeBeUserSpecified(II.getType())) { 4212193326Sed CmdArgs.push_back("-x"); 4213193326Sed CmdArgs.push_back(types::getTypeName(II.getType())); 4214193326Sed } 4215193326Sed 4216212904Sdim if (II.isFilename()) 4217193326Sed CmdArgs.push_back(II.getFilename()); 4218218893Sdim else { 4219218893Sdim const Arg &A = II.getInputArg(); 4220218893Sdim 4221218893Sdim // Reverse translate some rewritten options. 4222218893Sdim if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) { 4223218893Sdim CmdArgs.push_back("-lstdc++"); 4224218893Sdim continue; 4225218893Sdim } 4226218893Sdim 4227193326Sed // Don't render as input, we need gcc to do the translations. 4228218893Sdim A.render(Args, CmdArgs); 4229218893Sdim } 4230193326Sed } 4231193326Sed 4232221345Sdim const std::string customGCCName = D.getCCCGenericGCCName(); 4233221345Sdim const char *GCCName; 4234221345Sdim if (!customGCCName.empty()) 4235221345Sdim GCCName = customGCCName.c_str(); 4236263508Sdim else if (D.CCCIsCXX()) { 4237221345Sdim GCCName = "g++"; 4238221345Sdim } else 4239221345Sdim GCCName = "gcc"; 4240221345Sdim 4241193326Sed const char *Exec = 4242210299Sed Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); 4243212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4244193326Sed} 4245193326Sed 4246203955Srdivackyvoid gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA, 4247203955Srdivacky ArgStringList &CmdArgs) const { 4248193326Sed CmdArgs.push_back("-E"); 4249193326Sed} 4250193326Sed 4251203955Srdivackyvoid gcc::Precompile::RenderExtraToolArgs(const JobAction &JA, 4252203955Srdivacky ArgStringList &CmdArgs) const { 4253193326Sed // The type is good enough. 4254193326Sed} 4255193326Sed 4256203955Srdivackyvoid gcc::Compile::RenderExtraToolArgs(const JobAction &JA, 4257203955Srdivacky ArgStringList &CmdArgs) const { 4258203955Srdivacky const Driver &D = getToolChain().getDriver(); 4259203955Srdivacky 4260203955Srdivacky // If -flto, etc. are present then make sure not to force assembly output. 4261210299Sed if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR || 4262210299Sed JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC) 4263203955Srdivacky CmdArgs.push_back("-c"); 4264203955Srdivacky else { 4265203955Srdivacky if (JA.getType() != types::TY_PP_Asm) 4266226633Sdim D.Diag(diag::err_drv_invalid_gcc_output_type) 4267203955Srdivacky << getTypeName(JA.getType()); 4268218893Sdim 4269203955Srdivacky CmdArgs.push_back("-S"); 4270203955Srdivacky } 4271193326Sed} 4272193326Sed 4273203955Srdivackyvoid gcc::Assemble::RenderExtraToolArgs(const JobAction &JA, 4274203955Srdivacky ArgStringList &CmdArgs) const { 4275193326Sed CmdArgs.push_back("-c"); 4276193326Sed} 4277193326Sed 4278203955Srdivackyvoid gcc::Link::RenderExtraToolArgs(const JobAction &JA, 4279203955Srdivacky ArgStringList &CmdArgs) const { 4280193326Sed // The types are (hopefully) good enough. 4281193326Sed} 4282193326Sed 4283234353Sdim// Hexagon tools start. 4284234353Sdimvoid hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA, 4285234353Sdim ArgStringList &CmdArgs) const { 4286234353Sdim 4287234353Sdim} 4288234353Sdimvoid hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 4289234353Sdim const InputInfo &Output, 4290234353Sdim const InputInfoList &Inputs, 4291234353Sdim const ArgList &Args, 4292234353Sdim const char *LinkingOutput) const { 4293234353Sdim 4294234353Sdim const Driver &D = getToolChain().getDriver(); 4295234353Sdim ArgStringList CmdArgs; 4296234353Sdim 4297234353Sdim std::string MarchString = "-march="; 4298249423Sdim MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args); 4299234353Sdim CmdArgs.push_back(Args.MakeArgString(MarchString)); 4300234353Sdim 4301234353Sdim RenderExtraToolArgs(JA, CmdArgs); 4302234353Sdim 4303234353Sdim if (Output.isFilename()) { 4304234353Sdim CmdArgs.push_back("-o"); 4305234353Sdim CmdArgs.push_back(Output.getFilename()); 4306234353Sdim } else { 4307234353Sdim assert(Output.isNothing() && "Unexpected output"); 4308234353Sdim CmdArgs.push_back("-fsyntax-only"); 4309234353Sdim } 4310234353Sdim 4311249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 4312249423Sdim if (!SmallDataThreshold.empty()) 4313249423Sdim CmdArgs.push_back( 4314249423Sdim Args.MakeArgString(std::string("-G") + SmallDataThreshold)); 4315234353Sdim 4316249423Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4317249423Sdim options::OPT_Xassembler); 4318249423Sdim 4319234353Sdim // Only pass -x if gcc will understand it; otherwise hope gcc 4320234353Sdim // understands the suffix correctly. The main use case this would go 4321234353Sdim // wrong in is for linker inputs if they happened to have an odd 4322234353Sdim // suffix; really the only way to get this to happen is a command 4323234353Sdim // like '-x foobar a.c' which will treat a.c like a linker input. 4324234353Sdim // 4325234353Sdim // FIXME: For the linker case specifically, can we safely convert 4326234353Sdim // inputs into '-Wl,' options? 4327234353Sdim for (InputInfoList::const_iterator 4328234353Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 4329234353Sdim const InputInfo &II = *it; 4330234353Sdim 4331234353Sdim // Don't try to pass LLVM or AST inputs to a generic gcc. 4332234353Sdim if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || 4333234353Sdim II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) 4334234353Sdim D.Diag(clang::diag::err_drv_no_linker_llvm_support) 4335234353Sdim << getToolChain().getTripleString(); 4336234353Sdim else if (II.getType() == types::TY_AST) 4337234353Sdim D.Diag(clang::diag::err_drv_no_ast_support) 4338234353Sdim << getToolChain().getTripleString(); 4339249423Sdim else if (II.getType() == types::TY_ModuleFile) 4340249423Sdim D.Diag(diag::err_drv_no_module_support) 4341249423Sdim << getToolChain().getTripleString(); 4342234353Sdim 4343234353Sdim if (II.isFilename()) 4344234353Sdim CmdArgs.push_back(II.getFilename()); 4345234353Sdim else 4346234353Sdim // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? 4347234353Sdim II.getInputArg().render(Args, CmdArgs); 4348234353Sdim } 4349234353Sdim 4350234353Sdim const char *GCCName = "hexagon-as"; 4351234353Sdim const char *Exec = 4352234353Sdim Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); 4353234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4354234353Sdim 4355234353Sdim} 4356234353Sdimvoid hexagon::Link::RenderExtraToolArgs(const JobAction &JA, 4357234353Sdim ArgStringList &CmdArgs) const { 4358234353Sdim // The types are (hopefully) good enough. 4359234353Sdim} 4360234353Sdim 4361234353Sdimvoid hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, 4362234353Sdim const InputInfo &Output, 4363234353Sdim const InputInfoList &Inputs, 4364234353Sdim const ArgList &Args, 4365234353Sdim const char *LinkingOutput) const { 4366234353Sdim 4367249423Sdim const toolchains::Hexagon_TC& ToolChain = 4368249423Sdim static_cast<const toolchains::Hexagon_TC&>(getToolChain()); 4369249423Sdim const Driver &D = ToolChain.getDriver(); 4370249423Sdim 4371234353Sdim ArgStringList CmdArgs; 4372234353Sdim 4373249423Sdim //---------------------------------------------------------------------------- 4374249423Sdim // 4375249423Sdim //---------------------------------------------------------------------------- 4376249423Sdim bool hasStaticArg = Args.hasArg(options::OPT_static); 4377249423Sdim bool buildingLib = Args.hasArg(options::OPT_shared); 4378249423Sdim bool buildPIE = Args.hasArg(options::OPT_pie); 4379249423Sdim bool incStdLib = !Args.hasArg(options::OPT_nostdlib); 4380249423Sdim bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles); 4381249423Sdim bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs); 4382249423Sdim bool useShared = buildingLib && !hasStaticArg; 4383234353Sdim 4384249423Sdim //---------------------------------------------------------------------------- 4385249423Sdim // Silence warnings for various options 4386249423Sdim //---------------------------------------------------------------------------- 4387249423Sdim 4388249423Sdim Args.ClaimAllArgs(options::OPT_g_Group); 4389249423Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 4390249423Sdim Args.ClaimAllArgs(options::OPT_w); // Other warning options are already 4391249423Sdim // handled somewhere else. 4392249423Sdim Args.ClaimAllArgs(options::OPT_static_libgcc); 4393249423Sdim 4394249423Sdim //---------------------------------------------------------------------------- 4395249423Sdim // 4396249423Sdim //---------------------------------------------------------------------------- 4397249423Sdim for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), 4398249423Sdim e = ToolChain.ExtraOpts.end(); 4399249423Sdim i != e; ++i) 4400249423Sdim CmdArgs.push_back(i->c_str()); 4401249423Sdim 4402249423Sdim std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args); 4403249423Sdim CmdArgs.push_back(Args.MakeArgString("-m" + MarchString)); 4404249423Sdim 4405249423Sdim if (buildingLib) { 4406249423Sdim CmdArgs.push_back("-shared"); 4407249423Sdim CmdArgs.push_back("-call_shared"); // should be the default, but doing as 4408249423Sdim // hexagon-gcc does 4409234353Sdim } 4410234353Sdim 4411249423Sdim if (hasStaticArg) 4412249423Sdim CmdArgs.push_back("-static"); 4413234353Sdim 4414249423Sdim if (buildPIE && !buildingLib) 4415249423Sdim CmdArgs.push_back("-pie"); 4416249423Sdim 4417249423Sdim std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args); 4418249423Sdim if (!SmallDataThreshold.empty()) { 4419249423Sdim CmdArgs.push_back( 4420249423Sdim Args.MakeArgString(std::string("-G") + SmallDataThreshold)); 4421234353Sdim } 4422234353Sdim 4423249423Sdim //---------------------------------------------------------------------------- 4424249423Sdim // 4425249423Sdim //---------------------------------------------------------------------------- 4426249423Sdim CmdArgs.push_back("-o"); 4427249423Sdim CmdArgs.push_back(Output.getFilename()); 4428234353Sdim 4429249423Sdim const std::string MarchSuffix = "/" + MarchString; 4430249423Sdim const std::string G0Suffix = "/G0"; 4431249423Sdim const std::string MarchG0Suffix = MarchSuffix + G0Suffix; 4432249423Sdim const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir) 4433249423Sdim + "/"; 4434249423Sdim const std::string StartFilesDir = RootDir 4435249423Sdim + "hexagon/lib" 4436249423Sdim + (buildingLib 4437249423Sdim ? MarchG0Suffix : MarchSuffix); 4438234353Sdim 4439249423Sdim //---------------------------------------------------------------------------- 4440249423Sdim // moslib 4441249423Sdim //---------------------------------------------------------------------------- 4442249423Sdim std::vector<std::string> oslibs; 4443249423Sdim bool hasStandalone= false; 4444249423Sdim 4445249423Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ), 4446249423Sdim ie = Args.filtered_end(); it != ie; ++it) { 4447249423Sdim (*it)->claim(); 4448249423Sdim oslibs.push_back((*it)->getValue()); 4449249423Sdim hasStandalone = hasStandalone || (oslibs.back() == "standalone"); 4450234353Sdim } 4451249423Sdim if (oslibs.empty()) { 4452249423Sdim oslibs.push_back("standalone"); 4453249423Sdim hasStandalone = true; 4454249423Sdim } 4455234353Sdim 4456249423Sdim //---------------------------------------------------------------------------- 4457249423Sdim // Start Files 4458249423Sdim //---------------------------------------------------------------------------- 4459249423Sdim if (incStdLib && incStartFiles) { 4460234353Sdim 4461249423Sdim if (!buildingLib) { 4462249423Sdim if (hasStandalone) { 4463249423Sdim CmdArgs.push_back( 4464249423Sdim Args.MakeArgString(StartFilesDir + "/crt0_standalone.o")); 4465249423Sdim } 4466249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o")); 4467249423Sdim } 4468249423Sdim std::string initObj = useShared ? "/initS.o" : "/init.o"; 4469249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj)); 4470249423Sdim } 4471234353Sdim 4472249423Sdim //---------------------------------------------------------------------------- 4473249423Sdim // Library Search Paths 4474249423Sdim //---------------------------------------------------------------------------- 4475249423Sdim const ToolChain::path_list &LibPaths = ToolChain.getFilePaths(); 4476249423Sdim for (ToolChain::path_list::const_iterator 4477249423Sdim i = LibPaths.begin(), 4478249423Sdim e = LibPaths.end(); 4479249423Sdim i != e; 4480249423Sdim ++i) 4481249423Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 4482249423Sdim 4483249423Sdim //---------------------------------------------------------------------------- 4484249423Sdim // 4485249423Sdim //---------------------------------------------------------------------------- 4486249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 4487249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 4488249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 4489249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 4490249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 4491249423Sdim 4492249423Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 4493249423Sdim 4494249423Sdim //---------------------------------------------------------------------------- 4495249423Sdim // Libraries 4496249423Sdim //---------------------------------------------------------------------------- 4497249423Sdim if (incStdLib && incDefLibs) { 4498263508Sdim if (D.CCCIsCXX()) { 4499249423Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 4500249423Sdim CmdArgs.push_back("-lm"); 4501249423Sdim } 4502249423Sdim 4503249423Sdim CmdArgs.push_back("--start-group"); 4504249423Sdim 4505249423Sdim if (!buildingLib) { 4506249423Sdim for(std::vector<std::string>::iterator i = oslibs.begin(), 4507249423Sdim e = oslibs.end(); i != e; ++i) 4508249423Sdim CmdArgs.push_back(Args.MakeArgString("-l" + *i)); 4509249423Sdim CmdArgs.push_back("-lc"); 4510249423Sdim } 4511249423Sdim CmdArgs.push_back("-lgcc"); 4512249423Sdim 4513249423Sdim CmdArgs.push_back("--end-group"); 4514234353Sdim } 4515234353Sdim 4516249423Sdim //---------------------------------------------------------------------------- 4517249423Sdim // End files 4518249423Sdim //---------------------------------------------------------------------------- 4519249423Sdim if (incStdLib && incStartFiles) { 4520249423Sdim std::string finiObj = useShared ? "/finiS.o" : "/fini.o"; 4521249423Sdim CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj)); 4522249423Sdim } 4523249423Sdim 4524249423Sdim std::string Linker = ToolChain.GetProgramPath("hexagon-ld"); 4525263508Sdim C.addCommand(new Command(JA, *this, Args.MakeArgString(Linker), CmdArgs)); 4526234353Sdim} 4527234353Sdim// Hexagon tools end. 4528234353Sdim 4529243830Sdimllvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) { 4530243830Sdim // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 4531243830Sdim // archs which Darwin doesn't use. 4532234353Sdim 4533243830Sdim // The matching this routine does is fairly pointless, since it is neither the 4534243830Sdim // complete architecture list, nor a reasonable subset. The problem is that 4535243830Sdim // historically the driver driver accepts this and also ties its -march= 4536243830Sdim // handling to the architecture name, so we need to be careful before removing 4537243830Sdim // support for it. 4538243830Sdim 4539243830Sdim // This code must be kept in sync with Clang's Darwin specific argument 4540243830Sdim // translation. 4541243830Sdim 4542243830Sdim return llvm::StringSwitch<llvm::Triple::ArchType>(Str) 4543243830Sdim .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) 4544243830Sdim .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) 4545243830Sdim .Case("ppc64", llvm::Triple::ppc64) 4546243830Sdim .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) 4547243830Sdim .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 4548243830Sdim llvm::Triple::x86) 4549263508Sdim .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) 4550243830Sdim // This is derived from the driver driver. 4551249423Sdim .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) 4552249423Sdim .Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm) 4553249423Sdim .Cases("armv7s", "xscale", llvm::Triple::arm) 4554243830Sdim .Case("r600", llvm::Triple::r600) 4555243830Sdim .Case("nvptx", llvm::Triple::nvptx) 4556243830Sdim .Case("nvptx64", llvm::Triple::nvptx64) 4557243830Sdim .Case("amdil", llvm::Triple::amdil) 4558243830Sdim .Case("spir", llvm::Triple::spir) 4559243830Sdim .Default(llvm::Triple::UnknownArch); 4560243830Sdim} 4561243830Sdim 4562249423Sdimconst char *Clang::getBaseInputName(const ArgList &Args, 4563249423Sdim const InputInfoList &Inputs) { 4564218893Sdim return Args.MakeArgString( 4565218893Sdim llvm::sys::path::filename(Inputs[0].getBaseInput())); 4566193326Sed} 4567193326Sed 4568249423Sdimconst char *Clang::getBaseInputStem(const ArgList &Args, 4569249423Sdim const InputInfoList &Inputs) { 4570193326Sed const char *Str = getBaseInputName(Args, Inputs); 4571193326Sed 4572218893Sdim if (const char *End = strrchr(Str, '.')) 4573198092Srdivacky return Args.MakeArgString(std::string(Str, End)); 4574193326Sed 4575193326Sed return Str; 4576193326Sed} 4577193326Sed 4578249423Sdimconst char *Clang::getDependencyFileName(const ArgList &Args, 4579249423Sdim const InputInfoList &Inputs) { 4580193326Sed // FIXME: Think about this more. 4581193326Sed std::string Res; 4582193326Sed 4583193326Sed if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 4584243830Sdim std::string Str(OutputOpt->getValue()); 4585193326Sed Res = Str.substr(0, Str.rfind('.')); 4586226633Sdim } else { 4587249423Sdim Res = getBaseInputStem(Args, Inputs); 4588226633Sdim } 4589198092Srdivacky return Args.MakeArgString(Res + ".d"); 4590193326Sed} 4591193326Sed 4592193326Sedvoid darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 4593212904Sdim const InputInfo &Output, 4594193326Sed const InputInfoList &Inputs, 4595193326Sed const ArgList &Args, 4596193326Sed const char *LinkingOutput) const { 4597193326Sed ArgStringList CmdArgs; 4598193326Sed 4599193326Sed assert(Inputs.size() == 1 && "Unexpected number of inputs."); 4600193326Sed const InputInfo &Input = Inputs[0]; 4601193326Sed 4602221345Sdim // Determine the original source input. 4603221345Sdim const Action *SourceAction = &JA; 4604221345Sdim while (SourceAction->getKind() != Action::InputClass) { 4605221345Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 4606221345Sdim SourceAction = SourceAction->getInputs()[0]; 4607221345Sdim } 4608221345Sdim 4609263508Sdim // If -no_integrated_as is used add -Q to the darwin assember driver to make 4610263508Sdim // sure it runs its system assembler not clang's integrated assembler. 4611266715Sdim // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as. 4612266715Sdim // FIXME: at run-time detect assembler capabilities or rely on version 4613266715Sdim // information forwarded by -target-assembler-version (future) 4614266715Sdim if (Args.hasArg(options::OPT_no_integrated_as)) { 4615266715Sdim const llvm::Triple& t(getToolChain().getTriple()); 4616266715Sdim if (!(t.isMacOSX() && t.isMacOSXVersionLT(10, 7))) 4617266715Sdim CmdArgs.push_back("-Q"); 4618266715Sdim } 4619263508Sdim 4620221345Sdim // Forward -g, assuming we are dealing with an actual assembly file. 4621226633Sdim if (SourceAction->getType() == types::TY_Asm || 4622221345Sdim SourceAction->getType() == types::TY_PP_Asm) { 4623193326Sed if (Args.hasArg(options::OPT_gstabs)) 4624193326Sed CmdArgs.push_back("--gstabs"); 4625193326Sed else if (Args.hasArg(options::OPT_g_Group)) 4626234353Sdim CmdArgs.push_back("-g"); 4627193326Sed } 4628193326Sed 4629193326Sed // Derived from asm spec. 4630198092Srdivacky AddDarwinArch(Args, CmdArgs); 4631193326Sed 4632212904Sdim // Use -force_cpusubtype_ALL on x86 by default. 4633263508Sdim if (getToolChain().getArch() == llvm::Triple::x86 || 4634263508Sdim getToolChain().getArch() == llvm::Triple::x86_64 || 4635198092Srdivacky Args.hasArg(options::OPT_force__cpusubtype__ALL)) 4636198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 4637198092Srdivacky 4638263508Sdim if (getToolChain().getArch() != llvm::Triple::x86_64 && 4639243830Sdim (((Args.hasArg(options::OPT_mkernel) || 4640243830Sdim Args.hasArg(options::OPT_fapple_kext)) && 4641243830Sdim (!getDarwinToolChain().isTargetIPhoneOS() || 4642243830Sdim getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) || 4643243830Sdim Args.hasArg(options::OPT_static))) 4644193326Sed CmdArgs.push_back("-static"); 4645193326Sed 4646193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 4647193326Sed options::OPT_Xassembler); 4648193326Sed 4649193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 4650193326Sed CmdArgs.push_back("-o"); 4651193326Sed CmdArgs.push_back(Output.getFilename()); 4652193326Sed 4653212904Sdim assert(Input.isFilename() && "Invalid input."); 4654212904Sdim CmdArgs.push_back(Input.getFilename()); 4655193326Sed 4656193326Sed // asm_final spec is empty. 4657193326Sed 4658193326Sed const char *Exec = 4659210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 4660212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4661193326Sed} 4662193326Sed 4663234353Sdimvoid darwin::DarwinTool::anchor() {} 4664234353Sdim 4665198092Srdivackyvoid darwin::DarwinTool::AddDarwinArch(const ArgList &Args, 4666198092Srdivacky ArgStringList &CmdArgs) const { 4667226633Sdim StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args); 4668202879Srdivacky 4669193326Sed // Derived from darwin_arch spec. 4670193326Sed CmdArgs.push_back("-arch"); 4671202879Srdivacky CmdArgs.push_back(Args.MakeArgString(ArchName)); 4672198092Srdivacky 4673202879Srdivacky // FIXME: Is this needed anymore? 4674202879Srdivacky if (ArchName == "arm") 4675198092Srdivacky CmdArgs.push_back("-force_cpusubtype_ALL"); 4676193326Sed} 4677193326Sed 4678243830Sdimbool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const { 4679243830Sdim // We only need to generate a temp path for LTO if we aren't compiling object 4680243830Sdim // files. When compiling source files, we run 'dsymutil' after linking. We 4681243830Sdim // don't run 'dsymutil' when compiling object files. 4682243830Sdim for (InputInfoList::const_iterator 4683243830Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) 4684243830Sdim if (it->getType() != types::TY_Object) 4685243830Sdim return true; 4686243830Sdim 4687243830Sdim return false; 4688243830Sdim} 4689243830Sdim 4690218893Sdimvoid darwin::Link::AddLinkArgs(Compilation &C, 4691218893Sdim const ArgList &Args, 4692243830Sdim ArgStringList &CmdArgs, 4693243830Sdim const InputInfoList &Inputs) const { 4694201361Srdivacky const Driver &D = getToolChain().getDriver(); 4695221345Sdim const toolchains::Darwin &DarwinTC = getDarwinToolChain(); 4696193326Sed 4697212904Sdim unsigned Version[3] = { 0, 0, 0 }; 4698212904Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 4699212904Sdim bool HadExtra; 4700243830Sdim if (!Driver::GetReleaseVersion(A->getValue(), Version[0], 4701212904Sdim Version[1], Version[2], HadExtra) || 4702212904Sdim HadExtra) 4703226633Sdim D.Diag(diag::err_drv_invalid_version_number) 4704212904Sdim << A->getAsString(Args); 4705212904Sdim } 4706212904Sdim 4707212904Sdim // Newer linkers support -demangle, pass it if supported and not disabled by 4708212904Sdim // the user. 4709234353Sdim if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) { 4710218893Sdim // Don't pass -demangle to ld_classic. 4711218893Sdim // 4712218893Sdim // FIXME: This is a temporary workaround, ld should be handling this. 4713218893Sdim bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 && 4714218893Sdim Args.hasArg(options::OPT_static)); 4715218893Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 4716218893Sdim for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker, 4717218893Sdim options::OPT_Wl_COMMA), 4718218893Sdim ie = Args.filtered_end(); it != ie; ++it) { 4719218893Sdim const Arg *A = *it; 4720218893Sdim for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) 4721243830Sdim if (StringRef(A->getValue(i)) == "-kext") 4722218893Sdim UsesLdClassic = true; 4723218893Sdim } 4724218893Sdim } 4725218893Sdim if (!UsesLdClassic) 4726218893Sdim CmdArgs.push_back("-demangle"); 4727212904Sdim } 4728212904Sdim 4729263508Sdim if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137) 4730263508Sdim CmdArgs.push_back("-export_dynamic"); 4731263508Sdim 4732224145Sdim // If we are using LTO, then automatically create a temporary file path for 4733224145Sdim // the linker to use, so that it's lifetime will extend past a possible 4734224145Sdim // dsymutil step. 4735243830Sdim if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) { 4736224145Sdim const char *TmpPath = C.getArgs().MakeArgString( 4737226633Sdim D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object))); 4738224145Sdim C.addTempFile(TmpPath); 4739224145Sdim CmdArgs.push_back("-object_path_lto"); 4740224145Sdim CmdArgs.push_back(TmpPath); 4741224145Sdim } 4742224145Sdim 4743193326Sed // Derived from the "link" spec. 4744193326Sed Args.AddAllArgs(CmdArgs, options::OPT_static); 4745193326Sed if (!Args.hasArg(options::OPT_static)) 4746193326Sed CmdArgs.push_back("-dynamic"); 4747193326Sed if (Args.hasArg(options::OPT_fgnu_runtime)) { 4748193326Sed // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 4749193326Sed // here. How do we wish to handle such things? 4750193326Sed } 4751193326Sed 4752193326Sed if (!Args.hasArg(options::OPT_dynamiclib)) { 4753202879Srdivacky AddDarwinArch(Args, CmdArgs); 4754202879Srdivacky // FIXME: Why do this only on this path? 4755202879Srdivacky Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 4756193326Sed 4757193326Sed Args.AddLastArg(CmdArgs, options::OPT_bundle); 4758193326Sed Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 4759193326Sed Args.AddAllArgs(CmdArgs, options::OPT_client__name); 4760193326Sed 4761193326Sed Arg *A; 4762193326Sed if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 4763193326Sed (A = Args.getLastArg(options::OPT_current__version)) || 4764193326Sed (A = Args.getLastArg(options::OPT_install__name))) 4765226633Sdim D.Diag(diag::err_drv_argument_only_allowed_with) 4766193326Sed << A->getAsString(Args) << "-dynamiclib"; 4767193326Sed 4768193326Sed Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 4769193326Sed Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 4770193326Sed Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 4771193326Sed } else { 4772193326Sed CmdArgs.push_back("-dylib"); 4773193326Sed 4774193326Sed Arg *A; 4775193326Sed if ((A = Args.getLastArg(options::OPT_bundle)) || 4776193326Sed (A = Args.getLastArg(options::OPT_bundle__loader)) || 4777193326Sed (A = Args.getLastArg(options::OPT_client__name)) || 4778193326Sed (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 4779193326Sed (A = Args.getLastArg(options::OPT_keep__private__externs)) || 4780193326Sed (A = Args.getLastArg(options::OPT_private__bundle))) 4781226633Sdim D.Diag(diag::err_drv_argument_not_allowed_with) 4782193326Sed << A->getAsString(Args) << "-dynamiclib"; 4783193326Sed 4784193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 4785193326Sed "-dylib_compatibility_version"); 4786193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 4787193326Sed "-dylib_current_version"); 4788193326Sed 4789202879Srdivacky AddDarwinArch(Args, CmdArgs); 4790193326Sed 4791193326Sed Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 4792193326Sed "-dylib_install_name"); 4793193326Sed } 4794193326Sed 4795193326Sed Args.AddLastArg(CmdArgs, options::OPT_all__load); 4796193326Sed Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 4797193326Sed Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 4798221345Sdim if (DarwinTC.isTargetIPhoneOS()) 4799198092Srdivacky Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 4800193326Sed Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 4801193326Sed Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 4802193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 4803193326Sed Args.AddLastArg(CmdArgs, options::OPT_dynamic); 4804193326Sed Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 4805193326Sed Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 4806224145Sdim Args.AddAllArgs(CmdArgs, options::OPT_force__load); 4807193326Sed Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 4808193326Sed Args.AddAllArgs(CmdArgs, options::OPT_image__base); 4809193326Sed Args.AddAllArgs(CmdArgs, options::OPT_init); 4810193326Sed 4811221345Sdim // Add the deployment target. 4812234353Sdim VersionTuple TargetVersion = DarwinTC.getTargetVersion(); 4813221345Sdim 4814221345Sdim // If we had an explicit -mios-simulator-version-min argument, honor that, 4815221345Sdim // otherwise use the traditional deployment targets. We can't just check the 4816221345Sdim // is-sim attribute because existing code follows this path, and the linker 4817221345Sdim // may not handle the argument. 4818221345Sdim // 4819221345Sdim // FIXME: We may be able to remove this, once we can verify no one depends on 4820221345Sdim // it. 4821221345Sdim if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) 4822221345Sdim CmdArgs.push_back("-ios_simulator_version_min"); 4823221345Sdim else if (DarwinTC.isTargetIPhoneOS()) 4824221345Sdim CmdArgs.push_back("-iphoneos_version_min"); 4825221345Sdim else 4826221345Sdim CmdArgs.push_back("-macosx_version_min"); 4827234353Sdim CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 4828221345Sdim 4829193326Sed Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 4830193326Sed Args.AddLastArg(CmdArgs, options::OPT_multi__module); 4831193326Sed Args.AddLastArg(CmdArgs, options::OPT_single__module); 4832193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 4833193326Sed Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 4834193326Sed 4835210299Sed if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, 4836210299Sed options::OPT_fno_pie, 4837210299Sed options::OPT_fno_PIE)) { 4838210299Sed if (A->getOption().matches(options::OPT_fpie) || 4839210299Sed A->getOption().matches(options::OPT_fPIE)) 4840210299Sed CmdArgs.push_back("-pie"); 4841210299Sed else 4842210299Sed CmdArgs.push_back("-no_pie"); 4843210299Sed } 4844193326Sed 4845193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind); 4846193326Sed Args.AddLastArg(CmdArgs, options::OPT_noprebind); 4847193326Sed Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 4848193326Sed Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 4849193326Sed Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 4850193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 4851193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 4852193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 4853193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segprot); 4854193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 4855193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 4856193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 4857193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 4858193326Sed Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 4859193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 4860193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 4861198092Srdivacky 4862223017Sdim // Give --sysroot= preference, over the Apple specific behavior to also use 4863223017Sdim // --isysroot as the syslibroot. 4864234982Sdim StringRef sysroot = C.getSysRoot(); 4865234982Sdim if (sysroot != "") { 4866223017Sdim CmdArgs.push_back("-syslibroot"); 4867234982Sdim CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 4868223017Sdim } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 4869223017Sdim CmdArgs.push_back("-syslibroot"); 4870243830Sdim CmdArgs.push_back(A->getValue()); 4871198092Srdivacky } 4872198092Srdivacky 4873193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 4874193326Sed Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 4875193326Sed Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 4876193326Sed Args.AddAllArgs(CmdArgs, options::OPT_undefined); 4877193326Sed Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 4878193326Sed Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 4879193326Sed Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 4880193326Sed Args.AddAllArgs(CmdArgs, options::OPT_y); 4881193326Sed Args.AddLastArg(CmdArgs, options::OPT_w); 4882193326Sed Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 4883193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 4884193326Sed Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 4885193326Sed Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 4886193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 4887193326Sed Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 4888193326Sed Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 4889193326Sed Args.AddLastArg(CmdArgs, options::OPT_whyload); 4890193326Sed Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 4891193326Sed Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 4892193326Sed Args.AddLastArg(CmdArgs, options::OPT_dylinker); 4893193326Sed Args.AddLastArg(CmdArgs, options::OPT_Mach); 4894193326Sed} 4895193326Sed 4896193326Sedvoid darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, 4897212904Sdim const InputInfo &Output, 4898193326Sed const InputInfoList &Inputs, 4899193326Sed const ArgList &Args, 4900193326Sed const char *LinkingOutput) const { 4901193326Sed assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 4902198092Srdivacky 4903193326Sed // The logic here is derived from gcc's behavior; most of which 4904193326Sed // comes from specs (starting with link_command). Consult gcc for 4905193326Sed // more information. 4906193326Sed ArgStringList CmdArgs; 4907193326Sed 4908226633Sdim /// Hack(tm) to ignore linking errors when we are doing ARC migration. 4909226633Sdim if (Args.hasArg(options::OPT_ccc_arcmt_check, 4910226633Sdim options::OPT_ccc_arcmt_migrate)) { 4911226633Sdim for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) 4912226633Sdim (*I)->claim(); 4913226633Sdim const char *Exec = 4914226633Sdim Args.MakeArgString(getToolChain().GetProgramPath("touch")); 4915226633Sdim CmdArgs.push_back(Output.getFilename()); 4916226633Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 4917226633Sdim return; 4918226633Sdim } 4919226633Sdim 4920193326Sed // I'm not sure why this particular decomposition exists in gcc, but 4921193326Sed // we follow suite for ease of comparison. 4922243830Sdim AddLinkArgs(C, Args, CmdArgs, Inputs); 4923193326Sed 4924193326Sed Args.AddAllArgs(CmdArgs, options::OPT_d_Flag); 4925193326Sed Args.AddAllArgs(CmdArgs, options::OPT_s); 4926193326Sed Args.AddAllArgs(CmdArgs, options::OPT_t); 4927193326Sed Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 4928193326Sed Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 4929193326Sed Args.AddLastArg(CmdArgs, options::OPT_e); 4930193326Sed Args.AddAllArgs(CmdArgs, options::OPT_r); 4931193326Sed 4932218893Sdim // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading 4933218893Sdim // members of static archive libraries which implement Objective-C classes or 4934218893Sdim // categories. 4935218893Sdim if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX)) 4936218893Sdim CmdArgs.push_back("-ObjC"); 4937218893Sdim 4938193326Sed CmdArgs.push_back("-o"); 4939193326Sed CmdArgs.push_back(Output.getFilename()); 4940193326Sed 4941239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 4942193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 4943193326Sed // Derived from startfile spec. 4944193326Sed if (Args.hasArg(options::OPT_dynamiclib)) { 4945193326Sed // Derived from darwin_dylib1 spec. 4946221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 4947221345Sdim // The simulator doesn't have a versioned crt1 file. 4948221345Sdim CmdArgs.push_back("-ldylib1.o"); 4949221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 4950203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 4951203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 4952203955Srdivacky } else { 4953203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 4954203955Srdivacky CmdArgs.push_back("-ldylib1.o"); 4955203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 4956203955Srdivacky CmdArgs.push_back("-ldylib1.10.5.o"); 4957203955Srdivacky } 4958193326Sed } else { 4959193326Sed if (Args.hasArg(options::OPT_bundle)) { 4960193326Sed if (!Args.hasArg(options::OPT_static)) { 4961193326Sed // Derived from darwin_bundle1 spec. 4962221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 4963221345Sdim // The simulator doesn't have a versioned crt1 file. 4964221345Sdim CmdArgs.push_back("-lbundle1.o"); 4965221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 4966203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 4967203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 4968203955Srdivacky } else { 4969203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 4970203955Srdivacky CmdArgs.push_back("-lbundle1.o"); 4971203955Srdivacky } 4972193326Sed } 4973193326Sed } else { 4974221345Sdim if (Args.hasArg(options::OPT_pg) && 4975221345Sdim getToolChain().SupportsProfiling()) { 4976193326Sed if (Args.hasArg(options::OPT_static) || 4977193326Sed Args.hasArg(options::OPT_object) || 4978193326Sed Args.hasArg(options::OPT_preload)) { 4979193326Sed CmdArgs.push_back("-lgcrt0.o"); 4980193326Sed } else { 4981193326Sed CmdArgs.push_back("-lgcrt1.o"); 4982193326Sed 4983193326Sed // darwin_crt2 spec is empty. 4984193326Sed } 4985239462Sdim // By default on OS X 10.8 and later, we don't link with a crt1.o 4986239462Sdim // file and the linker knows to use _main as the entry point. But, 4987239462Sdim // when compiling with -pg, we need to link with the gcrt1.o file, 4988239462Sdim // so pass the -no_new_main option to tell the linker to use the 4989239462Sdim // "start" symbol as the entry point. 4990239462Sdim if (getDarwinToolChain().isTargetMacOS() && 4991239462Sdim !getDarwinToolChain().isMacosxVersionLT(10, 8)) 4992239462Sdim CmdArgs.push_back("-no_new_main"); 4993193326Sed } else { 4994193326Sed if (Args.hasArg(options::OPT_static) || 4995193326Sed Args.hasArg(options::OPT_object) || 4996193326Sed Args.hasArg(options::OPT_preload)) { 4997193326Sed CmdArgs.push_back("-lcrt0.o"); 4998193326Sed } else { 4999193326Sed // Derived from darwin_crt1 spec. 5000221345Sdim if (getDarwinToolChain().isTargetIOSSimulator()) { 5001221345Sdim // The simulator doesn't have a versioned crt1 file. 5002221345Sdim CmdArgs.push_back("-lcrt1.o"); 5003221345Sdim } else if (getDarwinToolChain().isTargetIPhoneOS()) { 5004203955Srdivacky if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) 5005203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 5006243830Sdim else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0)) 5007203955Srdivacky CmdArgs.push_back("-lcrt1.3.1.o"); 5008203955Srdivacky } else { 5009203955Srdivacky if (getDarwinToolChain().isMacosxVersionLT(10, 5)) 5010203955Srdivacky CmdArgs.push_back("-lcrt1.o"); 5011203955Srdivacky else if (getDarwinToolChain().isMacosxVersionLT(10, 6)) 5012203955Srdivacky CmdArgs.push_back("-lcrt1.10.5.o"); 5013234353Sdim else if (getDarwinToolChain().isMacosxVersionLT(10, 8)) 5014203955Srdivacky CmdArgs.push_back("-lcrt1.10.6.o"); 5015193326Sed 5016203955Srdivacky // darwin_crt2 spec is empty. 5017203955Srdivacky } 5018193326Sed } 5019193326Sed } 5020193326Sed } 5021193326Sed } 5022193326Sed 5023203955Srdivacky if (!getDarwinToolChain().isTargetIPhoneOS() && 5024203955Srdivacky Args.hasArg(options::OPT_shared_libgcc) && 5025203955Srdivacky getDarwinToolChain().isMacosxVersionLT(10, 5)) { 5026198092Srdivacky const char *Str = 5027210299Sed Args.MakeArgString(getToolChain().GetFilePath("crt3.o")); 5028198092Srdivacky CmdArgs.push_back(Str); 5029193326Sed } 5030193326Sed } 5031193326Sed 5032193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5033193326Sed 5034193326Sed if (Args.hasArg(options::OPT_fopenmp)) 5035193326Sed // This is more complicated in gcc... 5036193326Sed CmdArgs.push_back("-lgomp"); 5037193326Sed 5038239462Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5039239462Sdim 5040239462Sdim if (isObjCRuntimeLinked(Args) && 5041239462Sdim !Args.hasArg(options::OPT_nostdlib) && 5042239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5043234353Sdim // Avoid linking compatibility stubs on i386 mac. 5044234353Sdim if (!getDarwinToolChain().isTargetMacOS() || 5045243830Sdim getDarwinToolChain().getArch() != llvm::Triple::x86) { 5046234353Sdim // If we don't have ARC or subscripting runtime support, link in the 5047234353Sdim // runtime stubs. We have to do this *before* adding any of the normal 5048234353Sdim // linker inputs so that its initializer gets run first. 5049239462Sdim ObjCRuntime runtime = 5050239462Sdim getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true); 5051234353Sdim // We use arclite library for both ARC and subscripting support. 5052243830Sdim if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) || 5053239462Sdim !runtime.hasSubscripting()) 5054234353Sdim getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs); 5055234353Sdim } 5056239462Sdim CmdArgs.push_back("-framework"); 5057239462Sdim CmdArgs.push_back("Foundation"); 5058234353Sdim // Link libobj. 5059234353Sdim CmdArgs.push_back("-lobjc"); 5060224145Sdim } 5061224145Sdim 5062193326Sed if (LinkingOutput) { 5063193326Sed CmdArgs.push_back("-arch_multiple"); 5064193326Sed CmdArgs.push_back("-final_output"); 5065193326Sed CmdArgs.push_back(LinkingOutput); 5066193326Sed } 5067193326Sed 5068193326Sed if (Args.hasArg(options::OPT_fnested_functions)) 5069193326Sed CmdArgs.push_back("-allow_stack_execute"); 5070193326Sed 5071193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 5072193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 5073263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5074218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5075193326Sed 5076193326Sed // link_ssp spec is empty. 5077193326Sed 5078198092Srdivacky // Let the tool chain choose which runtime library to link. 5079198092Srdivacky getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); 5080193326Sed } 5081193326Sed 5082239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5083193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 5084193326Sed // endfile_spec is empty. 5085193326Sed } 5086193326Sed 5087193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5088193326Sed Args.AddAllArgs(CmdArgs, options::OPT_F); 5089193326Sed 5090193326Sed const char *Exec = 5091210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5092212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5093193326Sed} 5094193326Sed 5095193326Sedvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 5096212904Sdim const InputInfo &Output, 5097193326Sed const InputInfoList &Inputs, 5098193326Sed const ArgList &Args, 5099193326Sed const char *LinkingOutput) const { 5100193326Sed ArgStringList CmdArgs; 5101193326Sed 5102193326Sed CmdArgs.push_back("-create"); 5103193326Sed assert(Output.isFilename() && "Unexpected lipo output."); 5104193326Sed 5105193326Sed CmdArgs.push_back("-output"); 5106193326Sed CmdArgs.push_back(Output.getFilename()); 5107193326Sed 5108193326Sed for (InputInfoList::const_iterator 5109193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5110193326Sed const InputInfo &II = *it; 5111193326Sed assert(II.isFilename() && "Unexpected lipo input."); 5112193326Sed CmdArgs.push_back(II.getFilename()); 5113193326Sed } 5114193326Sed const char *Exec = 5115210299Sed Args.MakeArgString(getToolChain().GetProgramPath("lipo")); 5116212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5117193326Sed} 5118193326Sed 5119210299Sedvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, 5120212904Sdim const InputInfo &Output, 5121210299Sed const InputInfoList &Inputs, 5122210299Sed const ArgList &Args, 5123210299Sed const char *LinkingOutput) const { 5124210299Sed ArgStringList CmdArgs; 5125210299Sed 5126223017Sdim CmdArgs.push_back("-o"); 5127223017Sdim CmdArgs.push_back(Output.getFilename()); 5128223017Sdim 5129210299Sed assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 5130210299Sed const InputInfo &Input = Inputs[0]; 5131210299Sed assert(Input.isFilename() && "Unexpected dsymutil input."); 5132210299Sed CmdArgs.push_back(Input.getFilename()); 5133210299Sed 5134210299Sed const char *Exec = 5135210299Sed Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); 5136212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5137210299Sed} 5138210299Sed 5139226633Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, 5140249423Sdim const InputInfo &Output, 5141249423Sdim const InputInfoList &Inputs, 5142249423Sdim const ArgList &Args, 5143249423Sdim const char *LinkingOutput) const { 5144226633Sdim ArgStringList CmdArgs; 5145226633Sdim CmdArgs.push_back("--verify"); 5146234353Sdim CmdArgs.push_back("--debug-info"); 5147234353Sdim CmdArgs.push_back("--eh-frame"); 5148234353Sdim CmdArgs.push_back("--quiet"); 5149226633Sdim 5150226633Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 5151226633Sdim const InputInfo &Input = Inputs[0]; 5152226633Sdim assert(Input.isFilename() && "Unexpected verify input"); 5153226633Sdim 5154226633Sdim // Grabbing the output of the earlier dsymutil run. 5155226633Sdim CmdArgs.push_back(Input.getFilename()); 5156226633Sdim 5157226633Sdim const char *Exec = 5158226633Sdim Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); 5159226633Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5160226633Sdim} 5161226633Sdim 5162234353Sdimvoid solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5163234353Sdim const InputInfo &Output, 5164234353Sdim const InputInfoList &Inputs, 5165234353Sdim const ArgList &Args, 5166234353Sdim const char *LinkingOutput) const { 5167234353Sdim ArgStringList CmdArgs; 5168234353Sdim 5169234353Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5170234353Sdim options::OPT_Xassembler); 5171234353Sdim 5172234353Sdim CmdArgs.push_back("-o"); 5173234353Sdim CmdArgs.push_back(Output.getFilename()); 5174234353Sdim 5175234353Sdim for (InputInfoList::const_iterator 5176234353Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5177234353Sdim const InputInfo &II = *it; 5178234353Sdim CmdArgs.push_back(II.getFilename()); 5179234353Sdim } 5180234353Sdim 5181234353Sdim const char *Exec = 5182234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 5183234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5184234353Sdim} 5185234353Sdim 5186234353Sdim 5187234353Sdimvoid solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, 5188234353Sdim const InputInfo &Output, 5189234353Sdim const InputInfoList &Inputs, 5190234353Sdim const ArgList &Args, 5191234353Sdim const char *LinkingOutput) const { 5192234353Sdim // FIXME: Find a real GCC, don't hard-code versions here 5193234353Sdim std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/"; 5194234353Sdim const llvm::Triple &T = getToolChain().getTriple(); 5195234353Sdim std::string LibPath = "/usr/lib/"; 5196234353Sdim llvm::Triple::ArchType Arch = T.getArch(); 5197234353Sdim switch (Arch) { 5198263508Sdim case llvm::Triple::x86: 5199263508Sdim GCCLibPath += 5200263508Sdim ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/"; 5201263508Sdim break; 5202263508Sdim case llvm::Triple::x86_64: 5203263508Sdim GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str(); 5204263508Sdim GCCLibPath += "/4.5.2/amd64/"; 5205263508Sdim LibPath += "amd64/"; 5206263508Sdim break; 5207263508Sdim default: 5208263508Sdim llvm_unreachable("Unsupported architecture"); 5209234353Sdim } 5210234353Sdim 5211234353Sdim ArgStringList CmdArgs; 5212234353Sdim 5213234353Sdim // Demangle C++ names in errors 5214234353Sdim CmdArgs.push_back("-C"); 5215234353Sdim 5216234353Sdim if ((!Args.hasArg(options::OPT_nostdlib)) && 5217234353Sdim (!Args.hasArg(options::OPT_shared))) { 5218234353Sdim CmdArgs.push_back("-e"); 5219234353Sdim CmdArgs.push_back("_start"); 5220234353Sdim } 5221234353Sdim 5222234353Sdim if (Args.hasArg(options::OPT_static)) { 5223234353Sdim CmdArgs.push_back("-Bstatic"); 5224234353Sdim CmdArgs.push_back("-dn"); 5225234353Sdim } else { 5226234353Sdim CmdArgs.push_back("-Bdynamic"); 5227234353Sdim if (Args.hasArg(options::OPT_shared)) { 5228234353Sdim CmdArgs.push_back("-shared"); 5229234353Sdim } else { 5230234353Sdim CmdArgs.push_back("--dynamic-linker"); 5231234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1")); 5232234353Sdim } 5233234353Sdim } 5234234353Sdim 5235234353Sdim if (Output.isFilename()) { 5236234353Sdim CmdArgs.push_back("-o"); 5237234353Sdim CmdArgs.push_back(Output.getFilename()); 5238234353Sdim } else { 5239234353Sdim assert(Output.isNothing() && "Invalid output."); 5240234353Sdim } 5241234353Sdim 5242234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5243234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5244234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5245234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o")); 5246234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); 5247234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); 5248234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); 5249234353Sdim } else { 5250234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o")); 5251234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o")); 5252234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o")); 5253234353Sdim } 5254263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5255234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o")); 5256234353Sdim } 5257234353Sdim 5258234353Sdim CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath)); 5259234353Sdim 5260234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 5261234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5262234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 5263234353Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5264234353Sdim 5265234353Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5266234353Sdim 5267234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5268234353Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5269263508Sdim if (getToolChain().getDriver().CCCIsCXX()) 5270234353Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5271234353Sdim CmdArgs.push_back("-lgcc_s"); 5272234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5273234353Sdim CmdArgs.push_back("-lgcc"); 5274234353Sdim CmdArgs.push_back("-lc"); 5275234353Sdim CmdArgs.push_back("-lm"); 5276234353Sdim } 5277234353Sdim } 5278234353Sdim 5279234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5280234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5281234353Sdim CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o")); 5282234353Sdim } 5283234353Sdim CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o")); 5284234353Sdim 5285234353Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 5286234353Sdim 5287234353Sdim const char *Exec = 5288234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5289234353Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5290234353Sdim} 5291234353Sdim 5292198092Srdivackyvoid auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5293212904Sdim const InputInfo &Output, 5294198893Srdivacky const InputInfoList &Inputs, 5295198893Srdivacky const ArgList &Args, 5296198893Srdivacky const char *LinkingOutput) const { 5297198092Srdivacky ArgStringList CmdArgs; 5298198092Srdivacky 5299198092Srdivacky Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5300198092Srdivacky options::OPT_Xassembler); 5301198092Srdivacky 5302198092Srdivacky CmdArgs.push_back("-o"); 5303212904Sdim CmdArgs.push_back(Output.getFilename()); 5304198092Srdivacky 5305198092Srdivacky for (InputInfoList::const_iterator 5306198092Srdivacky it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5307198092Srdivacky const InputInfo &II = *it; 5308212904Sdim CmdArgs.push_back(II.getFilename()); 5309198092Srdivacky } 5310198092Srdivacky 5311198092Srdivacky const char *Exec = 5312210299Sed Args.MakeArgString(getToolChain().GetProgramPath("gas")); 5313212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5314198092Srdivacky} 5315198092Srdivacky 5316198092Srdivackyvoid auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, 5317212904Sdim const InputInfo &Output, 5318198893Srdivacky const InputInfoList &Inputs, 5319198893Srdivacky const ArgList &Args, 5320198893Srdivacky const char *LinkingOutput) const { 5321198092Srdivacky ArgStringList CmdArgs; 5322198092Srdivacky 5323198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 5324198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 5325198092Srdivacky CmdArgs.push_back("-e"); 5326198398Srdivacky CmdArgs.push_back("_start"); 5327198092Srdivacky } 5328198092Srdivacky 5329198092Srdivacky if (Args.hasArg(options::OPT_static)) { 5330198092Srdivacky CmdArgs.push_back("-Bstatic"); 5331198398Srdivacky CmdArgs.push_back("-dn"); 5332198092Srdivacky } else { 5333198398Srdivacky// CmdArgs.push_back("--eh-frame-hdr"); 5334198092Srdivacky CmdArgs.push_back("-Bdynamic"); 5335198092Srdivacky if (Args.hasArg(options::OPT_shared)) { 5336198092Srdivacky CmdArgs.push_back("-shared"); 5337198092Srdivacky } else { 5338198398Srdivacky CmdArgs.push_back("--dynamic-linker"); 5339198092Srdivacky CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1 5340198092Srdivacky } 5341198092Srdivacky } 5342198092Srdivacky 5343212904Sdim if (Output.isFilename()) { 5344198092Srdivacky CmdArgs.push_back("-o"); 5345198092Srdivacky CmdArgs.push_back(Output.getFilename()); 5346198092Srdivacky } else { 5347198092Srdivacky assert(Output.isNothing() && "Invalid output."); 5348198092Srdivacky } 5349198092Srdivacky 5350198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5351198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 5352198092Srdivacky if (!Args.hasArg(options::OPT_shared)) { 5353210299Sed CmdArgs.push_back(Args.MakeArgString( 5354210299Sed getToolChain().GetFilePath("crt1.o"))); 5355210299Sed CmdArgs.push_back(Args.MakeArgString( 5356210299Sed getToolChain().GetFilePath("crti.o"))); 5357210299Sed CmdArgs.push_back(Args.MakeArgString( 5358210299Sed getToolChain().GetFilePath("crtbegin.o"))); 5359198092Srdivacky } else { 5360210299Sed CmdArgs.push_back(Args.MakeArgString( 5361210299Sed getToolChain().GetFilePath("crti.o"))); 5362198092Srdivacky } 5363210299Sed CmdArgs.push_back(Args.MakeArgString( 5364210299Sed getToolChain().GetFilePath("crtn.o"))); 5365198092Srdivacky } 5366198092Srdivacky 5367198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/" 5368198893Srdivacky + getToolChain().getTripleString() 5369198893Srdivacky + "/4.2.4")); 5370198092Srdivacky 5371198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_L); 5372198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5373198092Srdivacky Args.AddAllArgs(CmdArgs, options::OPT_e); 5374198092Srdivacky 5375218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5376198092Srdivacky 5377198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5378198092Srdivacky !Args.hasArg(options::OPT_nodefaultlibs)) { 5379198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 5380198092Srdivacky // the default system libraries. Just mimic this for now. 5381198092Srdivacky CmdArgs.push_back("-lgcc"); 5382198092Srdivacky 5383198092Srdivacky if (Args.hasArg(options::OPT_pthread)) 5384198092Srdivacky CmdArgs.push_back("-pthread"); 5385198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 5386198092Srdivacky CmdArgs.push_back("-lc"); 5387198092Srdivacky CmdArgs.push_back("-lgcc"); 5388198092Srdivacky } 5389198092Srdivacky 5390198092Srdivacky if (!Args.hasArg(options::OPT_nostdlib) && 5391198092Srdivacky !Args.hasArg(options::OPT_nostartfiles)) { 5392198092Srdivacky if (!Args.hasArg(options::OPT_shared)) 5393210299Sed CmdArgs.push_back(Args.MakeArgString( 5394210299Sed getToolChain().GetFilePath("crtend.o"))); 5395198092Srdivacky } 5396198092Srdivacky 5397224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 5398223017Sdim 5399198092Srdivacky const char *Exec = 5400210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5401212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5402198092Srdivacky} 5403198092Srdivacky 5404195341Sedvoid openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5405212904Sdim const InputInfo &Output, 5406195341Sed const InputInfoList &Inputs, 5407195341Sed const ArgList &Args, 5408198092Srdivacky const char *LinkingOutput) const { 5409195341Sed ArgStringList CmdArgs; 5410193326Sed 5411263508Sdim // When building 32-bit code on OpenBSD/amd64, we have to explicitly 5412263508Sdim // instruct as in the base system to assemble 32-bit code. 5413263508Sdim if (getToolChain().getArch() == llvm::Triple::x86) 5414263508Sdim CmdArgs.push_back("--32"); 5415263508Sdim else if (getToolChain().getArch() == llvm::Triple::ppc) { 5416263508Sdim CmdArgs.push_back("-mppc"); 5417263508Sdim CmdArgs.push_back("-many"); 5418263508Sdim } else if (getToolChain().getArch() == llvm::Triple::mips64 || 5419263508Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 5420263508Sdim StringRef CPUName; 5421263508Sdim StringRef ABIName; 5422263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 5423263508Sdim 5424263508Sdim CmdArgs.push_back("-mabi"); 5425263508Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 5426263508Sdim 5427263508Sdim if (getToolChain().getArch() == llvm::Triple::mips64) 5428263508Sdim CmdArgs.push_back("-EB"); 5429263508Sdim else 5430263508Sdim CmdArgs.push_back("-EL"); 5431263508Sdim 5432263508Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5433263508Sdim options::OPT_fpic, options::OPT_fno_pic, 5434263508Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5435263508Sdim options::OPT_fpie, options::OPT_fno_pie); 5436263508Sdim if (LastPICArg && 5437263508Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5438263508Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5439263508Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5440263508Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5441263508Sdim CmdArgs.push_back("-KPIC"); 5442263508Sdim } 5443263508Sdim } 5444263508Sdim 5445195341Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5446195341Sed options::OPT_Xassembler); 5447195341Sed 5448195341Sed CmdArgs.push_back("-o"); 5449212904Sdim CmdArgs.push_back(Output.getFilename()); 5450195341Sed 5451195341Sed for (InputInfoList::const_iterator 5452195341Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5453195341Sed const InputInfo &II = *it; 5454212904Sdim CmdArgs.push_back(II.getFilename()); 5455195341Sed } 5456195341Sed 5457195341Sed const char *Exec = 5458210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 5459212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5460195341Sed} 5461195341Sed 5462195341Sedvoid openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 5463212904Sdim const InputInfo &Output, 5464195341Sed const InputInfoList &Inputs, 5465195341Sed const ArgList &Args, 5466195341Sed const char *LinkingOutput) const { 5467201361Srdivacky const Driver &D = getToolChain().getDriver(); 5468195341Sed ArgStringList CmdArgs; 5469195341Sed 5470249423Sdim // Silence warning for "clang -g foo.o -o foo" 5471249423Sdim Args.ClaimAllArgs(options::OPT_g_Group); 5472249423Sdim // and "clang -emit-llvm foo.o -o foo" 5473249423Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 5474249423Sdim // and for "clang -w foo.o -o foo". Other warning options are already 5475249423Sdim // handled somewhere else. 5476249423Sdim Args.ClaimAllArgs(options::OPT_w); 5477249423Sdim 5478263508Sdim if (getToolChain().getArch() == llvm::Triple::mips64) 5479263508Sdim CmdArgs.push_back("-EB"); 5480263508Sdim else if (getToolChain().getArch() == llvm::Triple::mips64el) 5481263508Sdim CmdArgs.push_back("-EL"); 5482263508Sdim 5483198092Srdivacky if ((!Args.hasArg(options::OPT_nostdlib)) && 5484198893Srdivacky (!Args.hasArg(options::OPT_shared))) { 5485198092Srdivacky CmdArgs.push_back("-e"); 5486198092Srdivacky CmdArgs.push_back("__start"); 5487198092Srdivacky } 5488198092Srdivacky 5489195341Sed if (Args.hasArg(options::OPT_static)) { 5490195341Sed CmdArgs.push_back("-Bstatic"); 5491195341Sed } else { 5492218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 5493218893Sdim CmdArgs.push_back("-export-dynamic"); 5494195341Sed CmdArgs.push_back("--eh-frame-hdr"); 5495198092Srdivacky CmdArgs.push_back("-Bdynamic"); 5496195341Sed if (Args.hasArg(options::OPT_shared)) { 5497198092Srdivacky CmdArgs.push_back("-shared"); 5498195341Sed } else { 5499195341Sed CmdArgs.push_back("-dynamic-linker"); 5500195341Sed CmdArgs.push_back("/usr/libexec/ld.so"); 5501195341Sed } 5502195341Sed } 5503195341Sed 5504263508Sdim if (Args.hasArg(options::OPT_nopie)) 5505263508Sdim CmdArgs.push_back("-nopie"); 5506263508Sdim 5507212904Sdim if (Output.isFilename()) { 5508195341Sed CmdArgs.push_back("-o"); 5509195341Sed CmdArgs.push_back(Output.getFilename()); 5510195341Sed } else { 5511195341Sed assert(Output.isNothing() && "Invalid output."); 5512195341Sed } 5513195341Sed 5514195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5515195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 5516195341Sed if (!Args.hasArg(options::OPT_shared)) { 5517234353Sdim if (Args.hasArg(options::OPT_pg)) 5518234353Sdim CmdArgs.push_back(Args.MakeArgString( 5519234353Sdim getToolChain().GetFilePath("gcrt0.o"))); 5520234353Sdim else 5521234353Sdim CmdArgs.push_back(Args.MakeArgString( 5522234353Sdim getToolChain().GetFilePath("crt0.o"))); 5523210299Sed CmdArgs.push_back(Args.MakeArgString( 5524210299Sed getToolChain().GetFilePath("crtbegin.o"))); 5525195341Sed } else { 5526210299Sed CmdArgs.push_back(Args.MakeArgString( 5527210299Sed getToolChain().GetFilePath("crtbeginS.o"))); 5528195341Sed } 5529195341Sed } 5530195341Sed 5531198893Srdivacky std::string Triple = getToolChain().getTripleString(); 5532198893Srdivacky if (Triple.substr(0, 6) == "x86_64") 5533198893Srdivacky Triple.replace(0, 6, "amd64"); 5534198893Srdivacky CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + 5535212904Sdim "/4.2.1")); 5536198092Srdivacky 5537195341Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5538195341Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5539195341Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 5540249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 5541249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 5542249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 5543249423Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5544195341Sed 5545218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5546195341Sed 5547195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5548195341Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 5549263508Sdim if (D.CCCIsCXX()) { 5550218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5551234353Sdim if (Args.hasArg(options::OPT_pg)) 5552234353Sdim CmdArgs.push_back("-lm_p"); 5553234353Sdim else 5554234353Sdim CmdArgs.push_back("-lm"); 5555212904Sdim } 5556212904Sdim 5557198092Srdivacky // FIXME: For some reason GCC passes -lgcc before adding 5558198092Srdivacky // the default system libraries. Just mimic this for now. 5559198092Srdivacky CmdArgs.push_back("-lgcc"); 5560195341Sed 5561243830Sdim if (Args.hasArg(options::OPT_pthread)) { 5562243830Sdim if (!Args.hasArg(options::OPT_shared) && 5563243830Sdim Args.hasArg(options::OPT_pg)) 5564243830Sdim CmdArgs.push_back("-lpthread_p"); 5565243830Sdim else 5566243830Sdim CmdArgs.push_back("-lpthread"); 5567243830Sdim } 5568243830Sdim 5569234353Sdim if (!Args.hasArg(options::OPT_shared)) { 5570243830Sdim if (Args.hasArg(options::OPT_pg)) 5571234353Sdim CmdArgs.push_back("-lc_p"); 5572234353Sdim else 5573234353Sdim CmdArgs.push_back("-lc"); 5574234353Sdim } 5575243830Sdim 5576198092Srdivacky CmdArgs.push_back("-lgcc"); 5577195341Sed } 5578195341Sed 5579195341Sed if (!Args.hasArg(options::OPT_nostdlib) && 5580195341Sed !Args.hasArg(options::OPT_nostartfiles)) { 5581195341Sed if (!Args.hasArg(options::OPT_shared)) 5582210299Sed CmdArgs.push_back(Args.MakeArgString( 5583210299Sed getToolChain().GetFilePath("crtend.o"))); 5584195341Sed else 5585210299Sed CmdArgs.push_back(Args.MakeArgString( 5586210299Sed getToolChain().GetFilePath("crtendS.o"))); 5587195341Sed } 5588195341Sed 5589195341Sed const char *Exec = 5590210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5591212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5592195341Sed} 5593195341Sed 5594239462Sdimvoid bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5595239462Sdim const InputInfo &Output, 5596239462Sdim const InputInfoList &Inputs, 5597239462Sdim const ArgList &Args, 5598239462Sdim const char *LinkingOutput) const { 5599239462Sdim ArgStringList CmdArgs; 5600239462Sdim 5601239462Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5602239462Sdim options::OPT_Xassembler); 5603239462Sdim 5604239462Sdim CmdArgs.push_back("-o"); 5605239462Sdim CmdArgs.push_back(Output.getFilename()); 5606239462Sdim 5607239462Sdim for (InputInfoList::const_iterator 5608239462Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5609239462Sdim const InputInfo &II = *it; 5610239462Sdim CmdArgs.push_back(II.getFilename()); 5611239462Sdim } 5612239462Sdim 5613239462Sdim const char *Exec = 5614239462Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 5615239462Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5616239462Sdim} 5617239462Sdim 5618239462Sdimvoid bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, 5619239462Sdim const InputInfo &Output, 5620239462Sdim const InputInfoList &Inputs, 5621239462Sdim const ArgList &Args, 5622239462Sdim const char *LinkingOutput) const { 5623239462Sdim const Driver &D = getToolChain().getDriver(); 5624239462Sdim ArgStringList CmdArgs; 5625239462Sdim 5626239462Sdim if ((!Args.hasArg(options::OPT_nostdlib)) && 5627239462Sdim (!Args.hasArg(options::OPT_shared))) { 5628239462Sdim CmdArgs.push_back("-e"); 5629239462Sdim CmdArgs.push_back("__start"); 5630239462Sdim } 5631239462Sdim 5632239462Sdim if (Args.hasArg(options::OPT_static)) { 5633239462Sdim CmdArgs.push_back("-Bstatic"); 5634239462Sdim } else { 5635239462Sdim if (Args.hasArg(options::OPT_rdynamic)) 5636239462Sdim CmdArgs.push_back("-export-dynamic"); 5637239462Sdim CmdArgs.push_back("--eh-frame-hdr"); 5638239462Sdim CmdArgs.push_back("-Bdynamic"); 5639239462Sdim if (Args.hasArg(options::OPT_shared)) { 5640239462Sdim CmdArgs.push_back("-shared"); 5641239462Sdim } else { 5642239462Sdim CmdArgs.push_back("-dynamic-linker"); 5643239462Sdim CmdArgs.push_back("/usr/libexec/ld.so"); 5644239462Sdim } 5645239462Sdim } 5646239462Sdim 5647239462Sdim if (Output.isFilename()) { 5648239462Sdim CmdArgs.push_back("-o"); 5649239462Sdim CmdArgs.push_back(Output.getFilename()); 5650239462Sdim } else { 5651239462Sdim assert(Output.isNothing() && "Invalid output."); 5652239462Sdim } 5653239462Sdim 5654239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5655239462Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5656239462Sdim if (!Args.hasArg(options::OPT_shared)) { 5657239462Sdim if (Args.hasArg(options::OPT_pg)) 5658239462Sdim CmdArgs.push_back(Args.MakeArgString( 5659239462Sdim getToolChain().GetFilePath("gcrt0.o"))); 5660239462Sdim else 5661239462Sdim CmdArgs.push_back(Args.MakeArgString( 5662239462Sdim getToolChain().GetFilePath("crt0.o"))); 5663239462Sdim CmdArgs.push_back(Args.MakeArgString( 5664239462Sdim getToolChain().GetFilePath("crtbegin.o"))); 5665239462Sdim } else { 5666239462Sdim CmdArgs.push_back(Args.MakeArgString( 5667239462Sdim getToolChain().GetFilePath("crtbeginS.o"))); 5668239462Sdim } 5669239462Sdim } 5670239462Sdim 5671239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 5672239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5673239462Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 5674239462Sdim 5675239462Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 5676239462Sdim 5677239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5678239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5679263508Sdim if (D.CCCIsCXX()) { 5680239462Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 5681239462Sdim if (Args.hasArg(options::OPT_pg)) 5682239462Sdim CmdArgs.push_back("-lm_p"); 5683239462Sdim else 5684239462Sdim CmdArgs.push_back("-lm"); 5685239462Sdim } 5686239462Sdim 5687243830Sdim if (Args.hasArg(options::OPT_pthread)) { 5688243830Sdim if (!Args.hasArg(options::OPT_shared) && 5689243830Sdim Args.hasArg(options::OPT_pg)) 5690243830Sdim CmdArgs.push_back("-lpthread_p"); 5691243830Sdim else 5692243830Sdim CmdArgs.push_back("-lpthread"); 5693243830Sdim } 5694243830Sdim 5695239462Sdim if (!Args.hasArg(options::OPT_shared)) { 5696239462Sdim if (Args.hasArg(options::OPT_pg)) 5697239462Sdim CmdArgs.push_back("-lc_p"); 5698239462Sdim else 5699239462Sdim CmdArgs.push_back("-lc"); 5700239462Sdim } 5701239462Sdim 5702263508Sdim StringRef MyArch; 5703263508Sdim switch (getToolChain().getTriple().getArch()) { 5704263508Sdim case llvm::Triple::arm: 5705263508Sdim MyArch = "arm"; 5706263508Sdim break; 5707263508Sdim case llvm::Triple::x86: 5708263508Sdim MyArch = "i386"; 5709263508Sdim break; 5710263508Sdim case llvm::Triple::x86_64: 5711263508Sdim MyArch = "amd64"; 5712263508Sdim break; 5713263508Sdim default: 5714263508Sdim llvm_unreachable("Unsupported architecture"); 5715263508Sdim } 5716263508Sdim CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch)); 5717239462Sdim } 5718239462Sdim 5719239462Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5720239462Sdim !Args.hasArg(options::OPT_nostartfiles)) { 5721239462Sdim if (!Args.hasArg(options::OPT_shared)) 5722239462Sdim CmdArgs.push_back(Args.MakeArgString( 5723239462Sdim getToolChain().GetFilePath("crtend.o"))); 5724239462Sdim else 5725239462Sdim CmdArgs.push_back(Args.MakeArgString( 5726239462Sdim getToolChain().GetFilePath("crtendS.o"))); 5727239462Sdim } 5728239462Sdim 5729239462Sdim const char *Exec = 5730239462Sdim Args.MakeArgString(getToolChain().GetProgramPath("ld")); 5731239462Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5732239462Sdim} 5733239462Sdim 5734193326Sedvoid freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 5735212904Sdim const InputInfo &Output, 5736193326Sed const InputInfoList &Inputs, 5737193326Sed const ArgList &Args, 5738198092Srdivacky const char *LinkingOutput) const { 5739193326Sed ArgStringList CmdArgs; 5740193326Sed 5741193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 5742193326Sed // instruct as in the base system to assemble 32-bit code. 5743243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) 5744193326Sed CmdArgs.push_back("--32"); 5745243830Sdim else if (getToolChain().getArch() == llvm::Triple::ppc) 5746223017Sdim CmdArgs.push_back("-a32"); 5747243830Sdim else if (getToolChain().getArch() == llvm::Triple::mips || 5748243830Sdim getToolChain().getArch() == llvm::Triple::mipsel || 5749243830Sdim getToolChain().getArch() == llvm::Triple::mips64 || 5750243830Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 5751243830Sdim StringRef CPUName; 5752243830Sdim StringRef ABIName; 5753263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 5754218893Sdim 5755243830Sdim CmdArgs.push_back("-march"); 5756243830Sdim CmdArgs.push_back(CPUName.data()); 5757204643Srdivacky 5758243830Sdim CmdArgs.push_back("-mabi"); 5759249423Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 5760243830Sdim 5761243830Sdim if (getToolChain().getArch() == llvm::Triple::mips || 5762243830Sdim getToolChain().getArch() == llvm::Triple::mips64) 5763243830Sdim CmdArgs.push_back("-EB"); 5764243830Sdim else 5765243830Sdim CmdArgs.push_back("-EL"); 5766243830Sdim 5767243830Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5768243830Sdim options::OPT_fpic, options::OPT_fno_pic, 5769243830Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5770243830Sdim options::OPT_fpie, options::OPT_fno_pie); 5771243830Sdim if (LastPICArg && 5772243830Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5773243830Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5774243830Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5775243830Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5776243830Sdim CmdArgs.push_back("-KPIC"); 5777243830Sdim } 5778244640Sandrew } else if (getToolChain().getArch() == llvm::Triple::arm || 5779244640Sandrew getToolChain().getArch() == llvm::Triple::thumb) { 5780244640Sandrew CmdArgs.push_back("-mfpu=softvfp"); 5781244640Sandrew switch(getToolChain().getTriple().getEnvironment()) { 5782244640Sandrew case llvm::Triple::GNUEABI: 5783244640Sandrew case llvm::Triple::EABI: 5784248548Sandrew CmdArgs.push_back("-meabi=5"); 5785244640Sandrew break; 5786244640Sandrew 5787244640Sandrew default: 5788244640Sandrew CmdArgs.push_back("-matpcs"); 5789244640Sandrew } 5790263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparc || 5791263763Sdim getToolChain().getArch() == llvm::Triple::sparcv9) { 5792263763Sdim if (getToolChain().getArch() == llvm::Triple::sparc) 5793263763Sdim CmdArgs.push_back("-Av8plusa"); 5794263763Sdim else 5795263763Sdim CmdArgs.push_back("-Av9a"); 5796263763Sdim 5797263763Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 5798263763Sdim options::OPT_fpic, options::OPT_fno_pic, 5799263763Sdim options::OPT_fPIE, options::OPT_fno_PIE, 5800263763Sdim options::OPT_fpie, options::OPT_fno_pie); 5801263763Sdim if (LastPICArg && 5802263763Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 5803263763Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 5804263763Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 5805263763Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 5806263763Sdim CmdArgs.push_back("-KPIC"); 5807263763Sdim } 5808243830Sdim } 5809243830Sdim 5810193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 5811193326Sed options::OPT_Xassembler); 5812193326Sed 5813193326Sed CmdArgs.push_back("-o"); 5814212904Sdim CmdArgs.push_back(Output.getFilename()); 5815193326Sed 5816193326Sed for (InputInfoList::const_iterator 5817193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 5818193326Sed const InputInfo &II = *it; 5819212904Sdim CmdArgs.push_back(II.getFilename()); 5820193326Sed } 5821193326Sed 5822193326Sed const char *Exec = 5823210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 5824212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 5825193326Sed} 5826193326Sed 5827193326Sedvoid freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 5828212904Sdim const InputInfo &Output, 5829193326Sed const InputInfoList &Inputs, 5830193326Sed const ArgList &Args, 5831193326Sed const char *LinkingOutput) const { 5832243830Sdim const toolchains::FreeBSD& ToolChain = 5833243830Sdim static_cast<const toolchains::FreeBSD&>(getToolChain()); 5834243830Sdim const Driver &D = ToolChain.getDriver(); 5835193326Sed ArgStringList CmdArgs; 5836193326Sed 5837238864Sdim // Silence warning for "clang -g foo.o -o foo" 5838238864Sdim Args.ClaimAllArgs(options::OPT_g_Group); 5839238864Sdim // and "clang -emit-llvm foo.o -o foo" 5840238864Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 5841238864Sdim // and for "clang -w foo.o -o foo". Other warning options are already 5842238864Sdim // handled somewhere else. 5843238864Sdim Args.ClaimAllArgs(options::OPT_w); 5844238864Sdim 5845221345Sdim if (!D.SysRoot.empty()) 5846221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 5847221345Sdim 5848243830Sdim if (Args.hasArg(options::OPT_pie)) 5849243830Sdim CmdArgs.push_back("-pie"); 5850243830Sdim 5851193326Sed if (Args.hasArg(options::OPT_static)) { 5852193326Sed CmdArgs.push_back("-Bstatic"); 5853193326Sed } else { 5854218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 5855218893Sdim CmdArgs.push_back("-export-dynamic"); 5856193326Sed CmdArgs.push_back("--eh-frame-hdr"); 5857193326Sed if (Args.hasArg(options::OPT_shared)) { 5858193326Sed CmdArgs.push_back("-Bshareable"); 5859193326Sed } else { 5860193326Sed CmdArgs.push_back("-dynamic-linker"); 5861193326Sed CmdArgs.push_back("/libexec/ld-elf.so.1"); 5862193326Sed } 5863243830Sdim if (ToolChain.getTriple().getOSMajorVersion() >= 9) { 5864243830Sdim llvm::Triple::ArchType Arch = ToolChain.getArch(); 5865239462Sdim if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc || 5866239462Sdim Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { 5867239462Sdim CmdArgs.push_back("--hash-style=both"); 5868239462Sdim } 5869239462Sdim } 5870238863Sdim CmdArgs.push_back("--enable-new-dtags"); 5871193326Sed } 5872193326Sed 5873193326Sed // When building 32-bit code on FreeBSD/amd64, we have to explicitly 5874193326Sed // instruct ld in the base system to link 32-bit code. 5875243830Sdim if (ToolChain.getArch() == llvm::Triple::x86) { 5876193326Sed CmdArgs.push_back("-m"); 5877193326Sed CmdArgs.push_back("elf_i386_fbsd"); 5878193326Sed } 5879193326Sed 5880243830Sdim if (ToolChain.getArch() == llvm::Triple::ppc) { 5881223017Sdim CmdArgs.push_back("-m"); 5882227739Sandreast CmdArgs.push_back("elf32ppc_fbsd"); 5883223017Sdim } 5884223017Sdim 5885212904Sdim if (Output.isFilename()) { 5886193326Sed CmdArgs.push_back("-o"); 5887193326Sed CmdArgs.push_back(Output.getFilename()); 5888193326Sed } else { 5889193326Sed assert(Output.isNothing() && "Invalid output."); 5890193326Sed } 5891193326Sed 5892193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 5893193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 5894243830Sdim const char *crt1 = NULL; 5895193326Sed if (!Args.hasArg(options::OPT_shared)) { 5896218893Sdim if (Args.hasArg(options::OPT_pg)) 5897243830Sdim crt1 = "gcrt1.o"; 5898243830Sdim else if (Args.hasArg(options::OPT_pie)) 5899243830Sdim crt1 = "Scrt1.o"; 5900243830Sdim else 5901243830Sdim crt1 = "crt1.o"; 5902193326Sed } 5903243830Sdim if (crt1) 5904243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); 5905243830Sdim 5906243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 5907243830Sdim 5908243830Sdim const char *crtbegin = NULL; 5909243830Sdim if (Args.hasArg(options::OPT_static)) 5910243830Sdim crtbegin = "crtbeginT.o"; 5911243830Sdim else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 5912243830Sdim crtbegin = "crtbeginS.o"; 5913243830Sdim else 5914243830Sdim crtbegin = "crtbegin.o"; 5915243830Sdim 5916243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 5917193326Sed } 5918193326Sed 5919193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 5920243830Sdim const ToolChain::path_list Paths = ToolChain.getFilePaths(); 5921219011Sdim for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); 5922219011Sdim i != e; ++i) 5923226633Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 5924193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 5925193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 5926212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 5927212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 5928212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 5929212904Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 5930193326Sed 5931263508Sdim // Tell the linker to load the plugin. This has to come before AddLinkerInputs 5932263508Sdim // as gold requires -plugin to come before any -plugin-opt that -Wl might 5933263508Sdim // forward. 5934263508Sdim if (D.IsUsingLTO(Args)) { 5935263508Sdim CmdArgs.push_back("-plugin"); 5936263508Sdim std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; 5937263508Sdim CmdArgs.push_back(Args.MakeArgString(Plugin)); 5938263508Sdim 5939263508Sdim // Try to pass driver level flags relevant to LTO code generation down to 5940263508Sdim // the plugin. 5941263508Sdim 5942263508Sdim // Handle flags for selecting CPU variants. 5943263508Sdim std::string CPU = getCPUName(Args, ToolChain.getTriple()); 5944263508Sdim if (!CPU.empty()) { 5945263508Sdim CmdArgs.push_back( 5946263508Sdim Args.MakeArgString(Twine("-plugin-opt=mcpu=") + 5947263508Sdim CPU)); 5948263508Sdim } 5949263508Sdim } 5950263508Sdim 5951243830Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 5952218893Sdim 5953218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 5954218893Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 5955263508Sdim if (D.CCCIsCXX()) { 5956243830Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 5957218893Sdim if (Args.hasArg(options::OPT_pg)) 5958218893Sdim CmdArgs.push_back("-lm_p"); 5959218893Sdim else 5960218893Sdim CmdArgs.push_back("-lm"); 5961218893Sdim } 5962218893Sdim // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding 5963218893Sdim // the default system libraries. Just mimic this for now. 5964218893Sdim if (Args.hasArg(options::OPT_pg)) 5965218893Sdim CmdArgs.push_back("-lgcc_p"); 5966218893Sdim else 5967218893Sdim CmdArgs.push_back("-lgcc"); 5968218893Sdim if (Args.hasArg(options::OPT_static)) { 5969218893Sdim CmdArgs.push_back("-lgcc_eh"); 5970218893Sdim } else if (Args.hasArg(options::OPT_pg)) { 5971218893Sdim CmdArgs.push_back("-lgcc_eh_p"); 5972218893Sdim } else { 5973218893Sdim CmdArgs.push_back("--as-needed"); 5974218893Sdim CmdArgs.push_back("-lgcc_s"); 5975218893Sdim CmdArgs.push_back("--no-as-needed"); 5976218893Sdim } 5977218893Sdim 5978218893Sdim if (Args.hasArg(options::OPT_pthread)) { 5979218893Sdim if (Args.hasArg(options::OPT_pg)) 5980218893Sdim CmdArgs.push_back("-lpthread_p"); 5981218893Sdim else 5982218893Sdim CmdArgs.push_back("-lpthread"); 5983218893Sdim } 5984218893Sdim 5985218893Sdim if (Args.hasArg(options::OPT_pg)) { 5986218893Sdim if (Args.hasArg(options::OPT_shared)) 5987218893Sdim CmdArgs.push_back("-lc"); 5988218893Sdim else 5989218893Sdim CmdArgs.push_back("-lc_p"); 5990218893Sdim CmdArgs.push_back("-lgcc_p"); 5991218893Sdim } else { 5992218893Sdim CmdArgs.push_back("-lc"); 5993218893Sdim CmdArgs.push_back("-lgcc"); 5994218893Sdim } 5995218893Sdim 5996218893Sdim if (Args.hasArg(options::OPT_static)) { 5997218893Sdim CmdArgs.push_back("-lgcc_eh"); 5998218893Sdim } else if (Args.hasArg(options::OPT_pg)) { 5999218893Sdim CmdArgs.push_back("-lgcc_eh_p"); 6000218893Sdim } else { 6001218893Sdim CmdArgs.push_back("--as-needed"); 6002218893Sdim CmdArgs.push_back("-lgcc_s"); 6003218893Sdim CmdArgs.push_back("--no-as-needed"); 6004218893Sdim } 6005218893Sdim } 6006218893Sdim 6007218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6008218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6009243830Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6010243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); 6011218893Sdim else 6012243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 6013243830Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 6014218893Sdim } 6015218893Sdim 6016243830Sdim addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple()); 6017223017Sdim 6018218893Sdim const char *Exec = 6019243830Sdim Args.MakeArgString(ToolChain.GetProgramPath("ld")); 6020218893Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6021218893Sdim} 6022218893Sdim 6023218893Sdimvoid netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6024218893Sdim const InputInfo &Output, 6025218893Sdim const InputInfoList &Inputs, 6026218893Sdim const ArgList &Args, 6027218893Sdim const char *LinkingOutput) const { 6028218893Sdim ArgStringList CmdArgs; 6029218893Sdim 6030218893Sdim // When building 32-bit code on NetBSD/amd64, we have to explicitly 6031218893Sdim // instruct as in the base system to assemble 32-bit code. 6032234353Sdim if (getToolChain().getArch() == llvm::Triple::x86) 6033218893Sdim CmdArgs.push_back("--32"); 6034218893Sdim 6035263508Sdim // Pass the target CPU to GNU as for ARM, since the source code might 6036263508Sdim // not have the correct .cpu annotation. 6037263508Sdim if (getToolChain().getArch() == llvm::Triple::arm) { 6038263508Sdim std::string MArch(getARMTargetCPU(Args, getToolChain().getTriple())); 6039263508Sdim CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch)); 6040263508Sdim } 6041218893Sdim 6042263508Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6043263508Sdim getToolChain().getArch() == llvm::Triple::mipsel || 6044263508Sdim getToolChain().getArch() == llvm::Triple::mips64 || 6045263508Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 6046263508Sdim StringRef CPUName; 6047263508Sdim StringRef ABIName; 6048263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 6049263508Sdim 6050263508Sdim CmdArgs.push_back("-march"); 6051263508Sdim CmdArgs.push_back(CPUName.data()); 6052263508Sdim 6053263508Sdim CmdArgs.push_back("-mabi"); 6054263508Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 6055263508Sdim 6056263508Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6057263508Sdim getToolChain().getArch() == llvm::Triple::mips64) 6058263508Sdim CmdArgs.push_back("-EB"); 6059263508Sdim else 6060263508Sdim CmdArgs.push_back("-EL"); 6061263508Sdim 6062263508Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 6063263508Sdim options::OPT_fpic, options::OPT_fno_pic, 6064263508Sdim options::OPT_fPIE, options::OPT_fno_PIE, 6065263508Sdim options::OPT_fpie, options::OPT_fno_pie); 6066263508Sdim if (LastPICArg && 6067263508Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 6068263508Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 6069263508Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 6070263508Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 6071263508Sdim CmdArgs.push_back("-KPIC"); 6072263508Sdim } 6073263508Sdim } 6074263508Sdim 6075218893Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6076218893Sdim options::OPT_Xassembler); 6077218893Sdim 6078218893Sdim CmdArgs.push_back("-o"); 6079218893Sdim CmdArgs.push_back(Output.getFilename()); 6080218893Sdim 6081193326Sed for (InputInfoList::const_iterator 6082193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6083193326Sed const InputInfo &II = *it; 6084218893Sdim CmdArgs.push_back(II.getFilename()); 6085218893Sdim } 6086193326Sed 6087226633Sdim const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as"))); 6088218893Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6089218893Sdim} 6090193326Sed 6091218893Sdimvoid netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 6092218893Sdim const InputInfo &Output, 6093218893Sdim const InputInfoList &Inputs, 6094218893Sdim const ArgList &Args, 6095218893Sdim const char *LinkingOutput) const { 6096218893Sdim const Driver &D = getToolChain().getDriver(); 6097218893Sdim ArgStringList CmdArgs; 6098218893Sdim 6099221345Sdim if (!D.SysRoot.empty()) 6100221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6101221345Sdim 6102218893Sdim if (Args.hasArg(options::OPT_static)) { 6103218893Sdim CmdArgs.push_back("-Bstatic"); 6104218893Sdim } else { 6105218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 6106218893Sdim CmdArgs.push_back("-export-dynamic"); 6107218893Sdim CmdArgs.push_back("--eh-frame-hdr"); 6108218893Sdim if (Args.hasArg(options::OPT_shared)) { 6109218893Sdim CmdArgs.push_back("-Bshareable"); 6110218893Sdim } else { 6111218893Sdim CmdArgs.push_back("-dynamic-linker"); 6112218893Sdim CmdArgs.push_back("/libexec/ld.elf_so"); 6113218893Sdim } 6114193326Sed } 6115193326Sed 6116218893Sdim // When building 32-bit code on NetBSD/amd64, we have to explicitly 6117218893Sdim // instruct ld in the base system to link 32-bit code. 6118234353Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6119218893Sdim CmdArgs.push_back("-m"); 6120218893Sdim CmdArgs.push_back("elf_i386"); 6121218893Sdim } 6122218893Sdim 6123218893Sdim if (Output.isFilename()) { 6124218893Sdim CmdArgs.push_back("-o"); 6125218893Sdim CmdArgs.push_back(Output.getFilename()); 6126218893Sdim } else { 6127218893Sdim assert(Output.isNothing() && "Invalid output."); 6128218893Sdim } 6129218893Sdim 6130193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6131218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6132218893Sdim if (!Args.hasArg(options::OPT_shared)) { 6133218893Sdim CmdArgs.push_back(Args.MakeArgString( 6134218893Sdim getToolChain().GetFilePath("crt0.o"))); 6135218893Sdim CmdArgs.push_back(Args.MakeArgString( 6136218893Sdim getToolChain().GetFilePath("crti.o"))); 6137218893Sdim CmdArgs.push_back(Args.MakeArgString( 6138218893Sdim getToolChain().GetFilePath("crtbegin.o"))); 6139218893Sdim } else { 6140218893Sdim CmdArgs.push_back(Args.MakeArgString( 6141218893Sdim getToolChain().GetFilePath("crti.o"))); 6142218893Sdim CmdArgs.push_back(Args.MakeArgString( 6143218893Sdim getToolChain().GetFilePath("crtbeginS.o"))); 6144218893Sdim } 6145218893Sdim } 6146218893Sdim 6147218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 6148218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6149218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_e); 6150218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_s); 6151218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_t); 6152218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 6153218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_r); 6154218893Sdim 6155218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6156218893Sdim 6157263508Sdim unsigned Major, Minor, Micro; 6158263508Sdim getToolChain().getTriple().getOSVersion(Major, Minor, Micro); 6159263508Sdim bool useLibgcc = true; 6160263508Sdim if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) { 6161263508Sdim if (getToolChain().getArch() == llvm::Triple::x86 || 6162263508Sdim getToolChain().getArch() == llvm::Triple::x86_64) 6163263508Sdim useLibgcc = false; 6164263508Sdim } 6165263508Sdim 6166218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6167193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6168263508Sdim if (D.CCCIsCXX()) { 6169218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6170204643Srdivacky CmdArgs.push_back("-lm"); 6171204643Srdivacky } 6172193326Sed if (Args.hasArg(options::OPT_pthread)) 6173193326Sed CmdArgs.push_back("-lpthread"); 6174193326Sed CmdArgs.push_back("-lc"); 6175193326Sed 6176263508Sdim if (useLibgcc) { 6177263508Sdim if (Args.hasArg(options::OPT_static)) { 6178263508Sdim // libgcc_eh depends on libc, so resolve as much as possible, 6179263508Sdim // pull in any new requirements from libc and then get the rest 6180263508Sdim // of libgcc. 6181263508Sdim CmdArgs.push_back("-lgcc_eh"); 6182263508Sdim CmdArgs.push_back("-lc"); 6183263508Sdim CmdArgs.push_back("-lgcc"); 6184263508Sdim } else { 6185263508Sdim CmdArgs.push_back("-lgcc"); 6186263508Sdim CmdArgs.push_back("--as-needed"); 6187263508Sdim CmdArgs.push_back("-lgcc_s"); 6188263508Sdim CmdArgs.push_back("--no-as-needed"); 6189263508Sdim } 6190193326Sed } 6191193326Sed } 6192193326Sed 6193193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6194193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6195193326Sed if (!Args.hasArg(options::OPT_shared)) 6196210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6197210299Sed "crtend.o"))); 6198193326Sed else 6199210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6200210299Sed "crtendS.o"))); 6201210299Sed CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( 6202210299Sed "crtn.o"))); 6203193326Sed } 6204193326Sed 6205224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6206223017Sdim 6207226633Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6208212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6209193326Sed} 6210193326Sed 6211249423Sdimvoid gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6212249423Sdim const InputInfo &Output, 6213249423Sdim const InputInfoList &Inputs, 6214249423Sdim const ArgList &Args, 6215249423Sdim const char *LinkingOutput) const { 6216212904Sdim ArgStringList CmdArgs; 6217263763Sdim bool NeedsKPIC = false; 6218212904Sdim 6219212904Sdim // Add --32/--64 to make sure we get the format we want. 6220212904Sdim // This is incomplete 6221212904Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6222212904Sdim CmdArgs.push_back("--32"); 6223212904Sdim } else if (getToolChain().getArch() == llvm::Triple::x86_64) { 6224212904Sdim CmdArgs.push_back("--64"); 6225234353Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc) { 6226234353Sdim CmdArgs.push_back("-a32"); 6227234353Sdim CmdArgs.push_back("-mppc"); 6228234353Sdim CmdArgs.push_back("-many"); 6229234353Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc64) { 6230234353Sdim CmdArgs.push_back("-a64"); 6231234353Sdim CmdArgs.push_back("-mppc64"); 6232234353Sdim CmdArgs.push_back("-many"); 6233263508Sdim } else if (getToolChain().getArch() == llvm::Triple::ppc64le) { 6234263508Sdim CmdArgs.push_back("-a64"); 6235263508Sdim CmdArgs.push_back("-mppc64le"); 6236263508Sdim CmdArgs.push_back("-many"); 6237263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparc) { 6238263763Sdim CmdArgs.push_back("-32"); 6239263763Sdim CmdArgs.push_back("-Av8plusa"); 6240263763Sdim NeedsKPIC = true; 6241263763Sdim } else if (getToolChain().getArch() == llvm::Triple::sparcv9) { 6242263763Sdim CmdArgs.push_back("-64"); 6243263763Sdim CmdArgs.push_back("-Av9a"); 6244263763Sdim NeedsKPIC = true; 6245212904Sdim } else if (getToolChain().getArch() == llvm::Triple::arm) { 6246226633Sdim StringRef MArch = getToolChain().getArchName(); 6247212904Sdim if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") 6248212904Sdim CmdArgs.push_back("-mfpu=neon"); 6249263508Sdim if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a") 6250263508Sdim CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8"); 6251239462Sdim 6252239462Sdim StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args, 6253239462Sdim getToolChain().getTriple()); 6254239462Sdim CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI)); 6255239462Sdim 6256239462Sdim Args.AddLastArg(CmdArgs, options::OPT_march_EQ); 6257239462Sdim Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); 6258239462Sdim Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); 6259234353Sdim } else if (getToolChain().getArch() == llvm::Triple::mips || 6260234353Sdim getToolChain().getArch() == llvm::Triple::mipsel || 6261234353Sdim getToolChain().getArch() == llvm::Triple::mips64 || 6262234353Sdim getToolChain().getArch() == llvm::Triple::mips64el) { 6263234353Sdim StringRef CPUName; 6264234353Sdim StringRef ABIName; 6265263508Sdim getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 6266234353Sdim 6267234353Sdim CmdArgs.push_back("-march"); 6268234353Sdim CmdArgs.push_back(CPUName.data()); 6269234353Sdim 6270234353Sdim CmdArgs.push_back("-mabi"); 6271249423Sdim CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data()); 6272234353Sdim 6273234353Sdim if (getToolChain().getArch() == llvm::Triple::mips || 6274234353Sdim getToolChain().getArch() == llvm::Triple::mips64) 6275234353Sdim CmdArgs.push_back("-EB"); 6276234353Sdim else 6277234353Sdim CmdArgs.push_back("-EL"); 6278239462Sdim 6279263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 6280263508Sdim if (StringRef(A->getValue()) == "2008") 6281263508Sdim CmdArgs.push_back(Args.MakeArgString("-mnan=2008")); 6282263508Sdim } 6283263508Sdim 6284263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfp64)) { 6285263508Sdim if (A->getOption().matches(options::OPT_mfp32)) 6286263508Sdim CmdArgs.push_back(Args.MakeArgString("-mfp32")); 6287263508Sdim else 6288263508Sdim CmdArgs.push_back(Args.MakeArgString("-mfp64")); 6289263508Sdim } 6290263508Sdim 6291251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16); 6292251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mmicromips, 6293251662Sdim options::OPT_mno_micromips); 6294251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp); 6295251662Sdim Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2); 6296251662Sdim 6297263508Sdim if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) { 6298263508Sdim // Do not use AddLastArg because not all versions of MIPS assembler 6299263508Sdim // support -mmsa / -mno-msa options. 6300263508Sdim if (A->getOption().matches(options::OPT_mmsa)) 6301263508Sdim CmdArgs.push_back(Args.MakeArgString("-mmsa")); 6302263508Sdim } 6303263508Sdim 6304263763Sdim NeedsKPIC = true; 6305263763Sdim } else if (getToolChain().getArch() == llvm::Triple::systemz) { 6306263763Sdim // Always pass an -march option, since our default of z10 is later 6307263763Sdim // than the GNU assembler's default. 6308263763Sdim StringRef CPUName = getSystemZTargetCPU(Args); 6309263763Sdim CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); 6310263763Sdim } 6311263763Sdim 6312263763Sdim if (NeedsKPIC) { 6313239462Sdim Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 6314239462Sdim options::OPT_fpic, options::OPT_fno_pic, 6315239462Sdim options::OPT_fPIE, options::OPT_fno_PIE, 6316239462Sdim options::OPT_fpie, options::OPT_fno_pie); 6317239462Sdim if (LastPICArg && 6318239462Sdim (LastPICArg->getOption().matches(options::OPT_fPIC) || 6319239462Sdim LastPICArg->getOption().matches(options::OPT_fpic) || 6320239462Sdim LastPICArg->getOption().matches(options::OPT_fPIE) || 6321239462Sdim LastPICArg->getOption().matches(options::OPT_fpie))) { 6322239462Sdim CmdArgs.push_back("-KPIC"); 6323239462Sdim } 6324212904Sdim } 6325212904Sdim 6326212904Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6327212904Sdim options::OPT_Xassembler); 6328212904Sdim 6329212904Sdim CmdArgs.push_back("-o"); 6330212904Sdim CmdArgs.push_back(Output.getFilename()); 6331212904Sdim 6332212904Sdim for (InputInfoList::const_iterator 6333212904Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6334212904Sdim const InputInfo &II = *it; 6335212904Sdim CmdArgs.push_back(II.getFilename()); 6336212904Sdim } 6337212904Sdim 6338212904Sdim const char *Exec = 6339212904Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 6340212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6341263508Sdim 6342263508Sdim // Handle the debug info splitting at object creation time if we're 6343263508Sdim // creating an object. 6344263508Sdim // TODO: Currently only works on linux with newer objcopy. 6345263508Sdim if (Args.hasArg(options::OPT_gsplit_dwarf) && 6346263508Sdim getToolChain().getTriple().isOSLinux()) 6347263508Sdim SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, 6348263508Sdim SplitDebugName(Args, Inputs)); 6349212904Sdim} 6350212904Sdim 6351239462Sdimstatic void AddLibgcc(llvm::Triple Triple, const Driver &D, 6352239462Sdim ArgStringList &CmdArgs, const ArgList &Args) { 6353243830Sdim bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android; 6354249423Sdim bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) || 6355249423Sdim Args.hasArg(options::OPT_static); 6356263508Sdim if (!D.CCCIsCXX()) 6357234353Sdim CmdArgs.push_back("-lgcc"); 6358234353Sdim 6359249423Sdim if (StaticLibgcc || isAndroid) { 6360263508Sdim if (D.CCCIsCXX()) 6361234353Sdim CmdArgs.push_back("-lgcc"); 6362234353Sdim } else { 6363263508Sdim if (!D.CCCIsCXX()) 6364234353Sdim CmdArgs.push_back("--as-needed"); 6365234353Sdim CmdArgs.push_back("-lgcc_s"); 6366263508Sdim if (!D.CCCIsCXX()) 6367234353Sdim CmdArgs.push_back("--no-as-needed"); 6368234353Sdim } 6369234353Sdim 6370239462Sdim if (StaticLibgcc && !isAndroid) 6371234353Sdim CmdArgs.push_back("-lgcc_eh"); 6372263508Sdim else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX()) 6373234353Sdim CmdArgs.push_back("-lgcc"); 6374249423Sdim 6375249423Sdim // According to Android ABI, we have to link with libdl if we are 6376249423Sdim // linking with non-static libgcc. 6377249423Sdim // 6378249423Sdim // NOTE: This fixes a link error on Android MIPS as well. The non-static 6379249423Sdim // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl. 6380249423Sdim if (isAndroid && !StaticLibgcc) 6381249423Sdim CmdArgs.push_back("-ldl"); 6382234353Sdim} 6383234353Sdim 6384243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) { 6385243830Sdim Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 6386243830Sdim return A && (A->getValue() == StringRef("n32")); 6387243830Sdim} 6388243830Sdim 6389263508Sdimstatic StringRef getLinuxDynamicLinker(const ArgList &Args, 6390263508Sdim const toolchains::Linux &ToolChain) { 6391263508Sdim if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) 6392263508Sdim return "/system/bin/linker"; 6393263763Sdim else if (ToolChain.getArch() == llvm::Triple::x86 || 6394263763Sdim ToolChain.getArch() == llvm::Triple::sparc) 6395263508Sdim return "/lib/ld-linux.so.2"; 6396263508Sdim else if (ToolChain.getArch() == llvm::Triple::aarch64) 6397263508Sdim return "/lib/ld-linux-aarch64.so.1"; 6398263508Sdim else if (ToolChain.getArch() == llvm::Triple::arm || 6399263508Sdim ToolChain.getArch() == llvm::Triple::thumb) { 6400263508Sdim if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) 6401263508Sdim return "/lib/ld-linux-armhf.so.3"; 6402263508Sdim else 6403263508Sdim return "/lib/ld-linux.so.3"; 6404263508Sdim } else if (ToolChain.getArch() == llvm::Triple::mips || 6405263508Sdim ToolChain.getArch() == llvm::Triple::mipsel) 6406263508Sdim return "/lib/ld.so.1"; 6407263508Sdim else if (ToolChain.getArch() == llvm::Triple::mips64 || 6408263508Sdim ToolChain.getArch() == llvm::Triple::mips64el) { 6409263508Sdim if (hasMipsN32ABIArg(Args)) 6410263508Sdim return "/lib32/ld.so.1"; 6411263508Sdim else 6412263508Sdim return "/lib64/ld.so.1"; 6413263508Sdim } else if (ToolChain.getArch() == llvm::Triple::ppc) 6414263508Sdim return "/lib/ld.so.1"; 6415263508Sdim else if (ToolChain.getArch() == llvm::Triple::ppc64 || 6416263508Sdim ToolChain.getArch() == llvm::Triple::ppc64le || 6417263508Sdim ToolChain.getArch() == llvm::Triple::systemz) 6418263508Sdim return "/lib64/ld64.so.1"; 6419263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparcv9) 6420263763Sdim return "/lib64/ld-linux.so.2"; 6421263508Sdim else 6422263508Sdim return "/lib64/ld-linux-x86-64.so.2"; 6423263508Sdim} 6424263508Sdim 6425249423Sdimvoid gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, 6426249423Sdim const InputInfo &Output, 6427249423Sdim const InputInfoList &Inputs, 6428249423Sdim const ArgList &Args, 6429249423Sdim const char *LinkingOutput) const { 6430218893Sdim const toolchains::Linux& ToolChain = 6431218893Sdim static_cast<const toolchains::Linux&>(getToolChain()); 6432218893Sdim const Driver &D = ToolChain.getDriver(); 6433243830Sdim const bool isAndroid = 6434243830Sdim ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; 6435263508Sdim const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs(); 6436251662Sdim const bool IsPIE = 6437251662Sdim !Args.hasArg(options::OPT_shared) && 6438251662Sdim (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow()); 6439239462Sdim 6440218893Sdim ArgStringList CmdArgs; 6441212904Sdim 6442218893Sdim // Silence warning for "clang -g foo.o -o foo" 6443218893Sdim Args.ClaimAllArgs(options::OPT_g_Group); 6444221345Sdim // and "clang -emit-llvm foo.o -o foo" 6445221345Sdim Args.ClaimAllArgs(options::OPT_emit_llvm); 6446239462Sdim // and for "clang -w foo.o -o foo". Other warning options are already 6447218893Sdim // handled somewhere else. 6448218893Sdim Args.ClaimAllArgs(options::OPT_w); 6449218893Sdim 6450221345Sdim if (!D.SysRoot.empty()) 6451221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6452218893Sdim 6453251662Sdim if (IsPIE) 6454218893Sdim CmdArgs.push_back("-pie"); 6455218893Sdim 6456218893Sdim if (Args.hasArg(options::OPT_rdynamic)) 6457218893Sdim CmdArgs.push_back("-export-dynamic"); 6458218893Sdim 6459218893Sdim if (Args.hasArg(options::OPT_s)) 6460218893Sdim CmdArgs.push_back("-s"); 6461218893Sdim 6462218893Sdim for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(), 6463218893Sdim e = ToolChain.ExtraOpts.end(); 6464218893Sdim i != e; ++i) 6465218893Sdim CmdArgs.push_back(i->c_str()); 6466218893Sdim 6467218893Sdim if (!Args.hasArg(options::OPT_static)) { 6468218893Sdim CmdArgs.push_back("--eh-frame-hdr"); 6469218893Sdim } 6470218893Sdim 6471218893Sdim CmdArgs.push_back("-m"); 6472218893Sdim if (ToolChain.getArch() == llvm::Triple::x86) 6473218893Sdim CmdArgs.push_back("elf_i386"); 6474249423Sdim else if (ToolChain.getArch() == llvm::Triple::aarch64) 6475249423Sdim CmdArgs.push_back("aarch64linux"); 6476226633Sdim else if (ToolChain.getArch() == llvm::Triple::arm 6477221345Sdim || ToolChain.getArch() == llvm::Triple::thumb) 6478218893Sdim CmdArgs.push_back("armelf_linux_eabi"); 6479221345Sdim else if (ToolChain.getArch() == llvm::Triple::ppc) 6480221345Sdim CmdArgs.push_back("elf32ppclinux"); 6481221345Sdim else if (ToolChain.getArch() == llvm::Triple::ppc64) 6482221345Sdim CmdArgs.push_back("elf64ppc"); 6483263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparc) 6484263763Sdim CmdArgs.push_back("elf32_sparc"); 6485263763Sdim else if (ToolChain.getArch() == llvm::Triple::sparcv9) 6486263763Sdim CmdArgs.push_back("elf64_sparc"); 6487234353Sdim else if (ToolChain.getArch() == llvm::Triple::mips) 6488234353Sdim CmdArgs.push_back("elf32btsmip"); 6489234353Sdim else if (ToolChain.getArch() == llvm::Triple::mipsel) 6490234353Sdim CmdArgs.push_back("elf32ltsmip"); 6491243830Sdim else if (ToolChain.getArch() == llvm::Triple::mips64) { 6492243830Sdim if (hasMipsN32ABIArg(Args)) 6493243830Sdim CmdArgs.push_back("elf32btsmipn32"); 6494243830Sdim else 6495243830Sdim CmdArgs.push_back("elf64btsmip"); 6496243830Sdim } 6497243830Sdim else if (ToolChain.getArch() == llvm::Triple::mips64el) { 6498243830Sdim if (hasMipsN32ABIArg(Args)) 6499243830Sdim CmdArgs.push_back("elf32ltsmipn32"); 6500243830Sdim else 6501243830Sdim CmdArgs.push_back("elf64ltsmip"); 6502243830Sdim } 6503251662Sdim else if (ToolChain.getArch() == llvm::Triple::systemz) 6504251662Sdim CmdArgs.push_back("elf64_s390"); 6505218893Sdim else 6506218893Sdim CmdArgs.push_back("elf_x86_64"); 6507218893Sdim 6508218893Sdim if (Args.hasArg(options::OPT_static)) { 6509221345Sdim if (ToolChain.getArch() == llvm::Triple::arm 6510221345Sdim || ToolChain.getArch() == llvm::Triple::thumb) 6511218893Sdim CmdArgs.push_back("-Bstatic"); 6512218893Sdim else 6513218893Sdim CmdArgs.push_back("-static"); 6514218893Sdim } else if (Args.hasArg(options::OPT_shared)) { 6515218893Sdim CmdArgs.push_back("-shared"); 6516243830Sdim if (isAndroid) { 6517239462Sdim CmdArgs.push_back("-Bsymbolic"); 6518239462Sdim } 6519218893Sdim } 6520218893Sdim 6521218893Sdim if (ToolChain.getArch() == llvm::Triple::arm || 6522221345Sdim ToolChain.getArch() == llvm::Triple::thumb || 6523218893Sdim (!Args.hasArg(options::OPT_static) && 6524218893Sdim !Args.hasArg(options::OPT_shared))) { 6525218893Sdim CmdArgs.push_back("-dynamic-linker"); 6526263508Sdim CmdArgs.push_back(Args.MakeArgString( 6527263508Sdim D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain))); 6528218893Sdim } 6529218893Sdim 6530218893Sdim CmdArgs.push_back("-o"); 6531218893Sdim CmdArgs.push_back(Output.getFilename()); 6532218893Sdim 6533218893Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6534218893Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6535239462Sdim if (!isAndroid) { 6536239462Sdim const char *crt1 = NULL; 6537239462Sdim if (!Args.hasArg(options::OPT_shared)){ 6538263508Sdim if (Args.hasArg(options::OPT_pg)) 6539263508Sdim crt1 = "gcrt1.o"; 6540263508Sdim else if (IsPIE) 6541239462Sdim crt1 = "Scrt1.o"; 6542239462Sdim else 6543239462Sdim crt1 = "crt1.o"; 6544239462Sdim } 6545239462Sdim if (crt1) 6546239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); 6547239462Sdim 6548239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 6549218893Sdim } 6550218893Sdim 6551218893Sdim const char *crtbegin; 6552218893Sdim if (Args.hasArg(options::OPT_static)) 6553239462Sdim crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; 6554243830Sdim else if (Args.hasArg(options::OPT_shared)) 6555239462Sdim crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; 6556251662Sdim else if (IsPIE) 6557243830Sdim crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; 6558218893Sdim else 6559239462Sdim crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; 6560218893Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 6561243830Sdim 6562243830Sdim // Add crtfastmath.o if available and fast math is enabled. 6563243830Sdim ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs); 6564218893Sdim } 6565218893Sdim 6566218893Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 6567218893Sdim 6568218893Sdim const ToolChain::path_list Paths = ToolChain.getFilePaths(); 6569221345Sdim 6570219011Sdim for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); 6571219011Sdim i != e; ++i) 6572226633Sdim CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i)); 6573218893Sdim 6574234353Sdim // Tell the linker to load the plugin. This has to come before AddLinkerInputs 6575234353Sdim // as gold requires -plugin to come before any -plugin-opt that -Wl might 6576234353Sdim // forward. 6577263508Sdim if (D.IsUsingLTO(Args)) { 6578234353Sdim CmdArgs.push_back("-plugin"); 6579234353Sdim std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; 6580234353Sdim CmdArgs.push_back(Args.MakeArgString(Plugin)); 6581247166Sdim 6582247166Sdim // Try to pass driver level flags relevant to LTO code generation down to 6583247166Sdim // the plugin. 6584247166Sdim 6585263508Sdim // Handle flags for selecting CPU variants. 6586263508Sdim std::string CPU = getCPUName(Args, ToolChain.getTriple()); 6587263508Sdim if (!CPU.empty()) { 6588247166Sdim CmdArgs.push_back( 6589263508Sdim Args.MakeArgString(Twine("-plugin-opt=mcpu=") + 6590263508Sdim CPU)); 6591263508Sdim } 6592234353Sdim } 6593234353Sdim 6594247166Sdim 6595239462Sdim if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 6596239462Sdim CmdArgs.push_back("--no-demangle"); 6597239462Sdim 6598218893Sdim AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); 6599218893Sdim 6600249423Sdim // Call these before we add the C++ ABI library. 6601243830Sdim if (Sanitize.needsUbsanRt()) 6602263508Sdim addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(), 6603249423Sdim Sanitize.needsAsanRt() || Sanitize.needsTsanRt() || 6604263508Sdim Sanitize.needsMsanRt() || Sanitize.needsLsanRt()); 6605249423Sdim if (Sanitize.needsAsanRt()) 6606249423Sdim addAsanRTLinux(getToolChain(), Args, CmdArgs); 6607249423Sdim if (Sanitize.needsTsanRt()) 6608249423Sdim addTsanRTLinux(getToolChain(), Args, CmdArgs); 6609249423Sdim if (Sanitize.needsMsanRt()) 6610249423Sdim addMsanRTLinux(getToolChain(), Args, CmdArgs); 6611263508Sdim if (Sanitize.needsLsanRt()) 6612263508Sdim addLsanRTLinux(getToolChain(), Args, CmdArgs); 6613263508Sdim if (Sanitize.needsDfsanRt()) 6614263508Sdim addDfsanRTLinux(getToolChain(), Args, CmdArgs); 6615243830Sdim 6616263508Sdim // The profile runtime also needs access to system libraries. 6617263508Sdim addProfileRTLinux(getToolChain(), Args, CmdArgs); 6618263508Sdim 6619263508Sdim if (D.CCCIsCXX() && 6620239462Sdim !Args.hasArg(options::OPT_nostdlib) && 6621239462Sdim !Args.hasArg(options::OPT_nodefaultlibs)) { 6622234353Sdim bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && 6623234353Sdim !Args.hasArg(options::OPT_static); 6624234353Sdim if (OnlyLibstdcxxStatic) 6625234353Sdim CmdArgs.push_back("-Bstatic"); 6626218893Sdim ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 6627234353Sdim if (OnlyLibstdcxxStatic) 6628234353Sdim CmdArgs.push_back("-Bdynamic"); 6629218893Sdim CmdArgs.push_back("-lm"); 6630218893Sdim } 6631218893Sdim 6632223017Sdim if (!Args.hasArg(options::OPT_nostdlib)) { 6633239462Sdim if (!Args.hasArg(options::OPT_nodefaultlibs)) { 6634239462Sdim if (Args.hasArg(options::OPT_static)) 6635239462Sdim CmdArgs.push_back("--start-group"); 6636218893Sdim 6637249423Sdim bool OpenMP = Args.hasArg(options::OPT_fopenmp); 6638249423Sdim if (OpenMP) { 6639249423Sdim CmdArgs.push_back("-lgomp"); 6640249423Sdim 6641249423Sdim // FIXME: Exclude this for platforms whith libgomp that doesn't require 6642249423Sdim // librt. Most modern Linux platfroms require it, but some may not. 6643249423Sdim CmdArgs.push_back("-lrt"); 6644249423Sdim } 6645249423Sdim 6646239462Sdim AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args); 6647218893Sdim 6648239462Sdim if (Args.hasArg(options::OPT_pthread) || 6649249423Sdim Args.hasArg(options::OPT_pthreads) || OpenMP) 6650239462Sdim CmdArgs.push_back("-lpthread"); 6651218893Sdim 6652239462Sdim CmdArgs.push_back("-lc"); 6653218893Sdim 6654239462Sdim if (Args.hasArg(options::OPT_static)) 6655239462Sdim CmdArgs.push_back("--end-group"); 6656239462Sdim else 6657239462Sdim AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args); 6658239462Sdim } 6659218893Sdim 6660218893Sdim if (!Args.hasArg(options::OPT_nostartfiles)) { 6661218893Sdim const char *crtend; 6662243830Sdim if (Args.hasArg(options::OPT_shared)) 6663239462Sdim crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; 6664251662Sdim else if (IsPIE) 6665243830Sdim crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; 6666218893Sdim else 6667239462Sdim crtend = isAndroid ? "crtend_android.o" : "crtend.o"; 6668218893Sdim 6669218893Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); 6670239462Sdim if (!isAndroid) 6671239462Sdim CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 6672218893Sdim } 6673218893Sdim } 6674218893Sdim 6675218893Sdim C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); 6676218893Sdim} 6677218893Sdim 6678210299Sedvoid minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6679212904Sdim const InputInfo &Output, 6680212904Sdim const InputInfoList &Inputs, 6681212904Sdim const ArgList &Args, 6682212904Sdim const char *LinkingOutput) const { 6683210299Sed ArgStringList CmdArgs; 6684210299Sed 6685210299Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6686210299Sed options::OPT_Xassembler); 6687210299Sed 6688210299Sed CmdArgs.push_back("-o"); 6689212904Sdim CmdArgs.push_back(Output.getFilename()); 6690210299Sed 6691210299Sed for (InputInfoList::const_iterator 6692210299Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6693210299Sed const InputInfo &II = *it; 6694212904Sdim CmdArgs.push_back(II.getFilename()); 6695210299Sed } 6696210299Sed 6697210299Sed const char *Exec = 6698234353Sdim Args.MakeArgString(getToolChain().GetProgramPath("as")); 6699212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6700210299Sed} 6701210299Sed 6702210299Sedvoid minix::Link::ConstructJob(Compilation &C, const JobAction &JA, 6703212904Sdim const InputInfo &Output, 6704212904Sdim const InputInfoList &Inputs, 6705212904Sdim const ArgList &Args, 6706212904Sdim const char *LinkingOutput) const { 6707210299Sed const Driver &D = getToolChain().getDriver(); 6708210299Sed ArgStringList CmdArgs; 6709210299Sed 6710212904Sdim if (Output.isFilename()) { 6711210299Sed CmdArgs.push_back("-o"); 6712210299Sed CmdArgs.push_back(Output.getFilename()); 6713210299Sed } else { 6714210299Sed assert(Output.isNothing() && "Invalid output."); 6715210299Sed } 6716210299Sed 6717210299Sed if (!Args.hasArg(options::OPT_nostdlib) && 6718234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6719234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); 6720234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); 6721234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); 6722234353Sdim CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); 6723234353Sdim } 6724210299Sed 6725210299Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 6726210299Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6727210299Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 6728210299Sed 6729218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6730210299Sed 6731234353Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6732234353Sdim 6733210299Sed if (!Args.hasArg(options::OPT_nostdlib) && 6734210299Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6735263508Sdim if (D.CCCIsCXX()) { 6736218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6737210299Sed CmdArgs.push_back("-lm"); 6738210299Sed } 6739234353Sdim } 6740210299Sed 6741234353Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6742234353Sdim !Args.hasArg(options::OPT_nostartfiles)) { 6743210299Sed if (Args.hasArg(options::OPT_pthread)) 6744210299Sed CmdArgs.push_back("-lpthread"); 6745210299Sed CmdArgs.push_back("-lc"); 6746234353Sdim CmdArgs.push_back("-lCompilerRT-Generic"); 6747234353Sdim CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib"); 6748234353Sdim CmdArgs.push_back( 6749249423Sdim Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); 6750210299Sed } 6751210299Sed 6752234353Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6753212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6754210299Sed} 6755210299Sed 6756193326Sed/// DragonFly Tools 6757193326Sed 6758193326Sed// For now, DragonFly Assemble does just about the same as for 6759193326Sed// FreeBSD, but this may change soon. 6760193326Sedvoid dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 6761212904Sdim const InputInfo &Output, 6762198893Srdivacky const InputInfoList &Inputs, 6763198893Srdivacky const ArgList &Args, 6764198893Srdivacky const char *LinkingOutput) const { 6765193326Sed ArgStringList CmdArgs; 6766193326Sed 6767193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 6768193326Sed // instruct as in the base system to assemble 32-bit code. 6769243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) 6770193326Sed CmdArgs.push_back("--32"); 6771193326Sed 6772193326Sed Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 6773193326Sed options::OPT_Xassembler); 6774193326Sed 6775193326Sed CmdArgs.push_back("-o"); 6776212904Sdim CmdArgs.push_back(Output.getFilename()); 6777193326Sed 6778193326Sed for (InputInfoList::const_iterator 6779193326Sed it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6780193326Sed const InputInfo &II = *it; 6781212904Sdim CmdArgs.push_back(II.getFilename()); 6782193326Sed } 6783193326Sed 6784193326Sed const char *Exec = 6785210299Sed Args.MakeArgString(getToolChain().GetProgramPath("as")); 6786212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6787193326Sed} 6788193326Sed 6789193326Sedvoid dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, 6790212904Sdim const InputInfo &Output, 6791212904Sdim const InputInfoList &Inputs, 6792212904Sdim const ArgList &Args, 6793212904Sdim const char *LinkingOutput) const { 6794251662Sdim bool UseGCC47 = false; 6795201361Srdivacky const Driver &D = getToolChain().getDriver(); 6796193326Sed ArgStringList CmdArgs; 6797193326Sed 6798251662Sdim if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47)) 6799251662Sdim UseGCC47 = false; 6800251662Sdim 6801221345Sdim if (!D.SysRoot.empty()) 6802221345Sdim CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 6803221345Sdim 6804251662Sdim CmdArgs.push_back("--eh-frame-hdr"); 6805193326Sed if (Args.hasArg(options::OPT_static)) { 6806193326Sed CmdArgs.push_back("-Bstatic"); 6807193326Sed } else { 6808251662Sdim if (Args.hasArg(options::OPT_rdynamic)) 6809251662Sdim CmdArgs.push_back("-export-dynamic"); 6810193326Sed if (Args.hasArg(options::OPT_shared)) 6811193326Sed CmdArgs.push_back("-Bshareable"); 6812193326Sed else { 6813193326Sed CmdArgs.push_back("-dynamic-linker"); 6814193326Sed CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); 6815193326Sed } 6816251662Sdim CmdArgs.push_back("--hash-style=both"); 6817193326Sed } 6818193326Sed 6819193326Sed // When building 32-bit code on DragonFly/pc64, we have to explicitly 6820193326Sed // instruct ld in the base system to link 32-bit code. 6821243830Sdim if (getToolChain().getArch() == llvm::Triple::x86) { 6822193326Sed CmdArgs.push_back("-m"); 6823193326Sed CmdArgs.push_back("elf_i386"); 6824193326Sed } 6825193326Sed 6826212904Sdim if (Output.isFilename()) { 6827193326Sed CmdArgs.push_back("-o"); 6828193326Sed CmdArgs.push_back(Output.getFilename()); 6829193326Sed } else { 6830193326Sed assert(Output.isNothing() && "Invalid output."); 6831193326Sed } 6832193326Sed 6833193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6834193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6835193326Sed if (!Args.hasArg(options::OPT_shared)) { 6836251662Sdim if (Args.hasArg(options::OPT_pg)) 6837251662Sdim CmdArgs.push_back(Args.MakeArgString( 6838251662Sdim getToolChain().GetFilePath("gcrt1.o"))); 6839251662Sdim else { 6840251662Sdim if (Args.hasArg(options::OPT_pie)) 6841251662Sdim CmdArgs.push_back(Args.MakeArgString( 6842251662Sdim getToolChain().GetFilePath("Scrt1.o"))); 6843251662Sdim else 6844251662Sdim CmdArgs.push_back(Args.MakeArgString( 6845251662Sdim getToolChain().GetFilePath("crt1.o"))); 6846251662Sdim } 6847193326Sed } 6848251662Sdim CmdArgs.push_back(Args.MakeArgString( 6849251662Sdim getToolChain().GetFilePath("crti.o"))); 6850251662Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6851251662Sdim CmdArgs.push_back(Args.MakeArgString( 6852251662Sdim getToolChain().GetFilePath("crtbeginS.o"))); 6853251662Sdim else 6854251662Sdim CmdArgs.push_back(Args.MakeArgString( 6855251662Sdim getToolChain().GetFilePath("crtbegin.o"))); 6856193326Sed } 6857193326Sed 6858193326Sed Args.AddAllArgs(CmdArgs, options::OPT_L); 6859193326Sed Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 6860193326Sed Args.AddAllArgs(CmdArgs, options::OPT_e); 6861193326Sed 6862218893Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 6863193326Sed 6864193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6865193326Sed !Args.hasArg(options::OPT_nodefaultlibs)) { 6866193326Sed // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of 6867193326Sed // rpaths 6868251662Sdim if (UseGCC47) 6869251662Sdim CmdArgs.push_back("-L/usr/lib/gcc47"); 6870251662Sdim else 6871251662Sdim CmdArgs.push_back("-L/usr/lib/gcc44"); 6872193326Sed 6873193326Sed if (!Args.hasArg(options::OPT_static)) { 6874251662Sdim if (UseGCC47) { 6875251662Sdim CmdArgs.push_back("-rpath"); 6876251662Sdim CmdArgs.push_back("/usr/lib/gcc47"); 6877251662Sdim } else { 6878251662Sdim CmdArgs.push_back("-rpath"); 6879251662Sdim CmdArgs.push_back("/usr/lib/gcc44"); 6880251662Sdim } 6881193326Sed } 6882193326Sed 6883263508Sdim if (D.CCCIsCXX()) { 6884218893Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 6885212904Sdim CmdArgs.push_back("-lm"); 6886212904Sdim } 6887212904Sdim 6888193326Sed if (Args.hasArg(options::OPT_pthread)) 6889198893Srdivacky CmdArgs.push_back("-lpthread"); 6890193326Sed 6891193326Sed if (!Args.hasArg(options::OPT_nolibc)) { 6892193326Sed CmdArgs.push_back("-lc"); 6893193326Sed } 6894193326Sed 6895251662Sdim if (UseGCC47) { 6896251662Sdim if (Args.hasArg(options::OPT_static) || 6897251662Sdim Args.hasArg(options::OPT_static_libgcc)) { 6898251662Sdim CmdArgs.push_back("-lgcc"); 6899251662Sdim CmdArgs.push_back("-lgcc_eh"); 6900251662Sdim } else { 6901251662Sdim if (Args.hasArg(options::OPT_shared_libgcc)) { 6902251662Sdim CmdArgs.push_back("-lgcc_pic"); 6903251662Sdim if (!Args.hasArg(options::OPT_shared)) 6904251662Sdim CmdArgs.push_back("-lgcc"); 6905251662Sdim } else { 6906251662Sdim CmdArgs.push_back("-lgcc"); 6907251662Sdim CmdArgs.push_back("--as-needed"); 6908251662Sdim CmdArgs.push_back("-lgcc_pic"); 6909251662Sdim CmdArgs.push_back("--no-as-needed"); 6910251662Sdim } 6911251662Sdim } 6912193326Sed } else { 6913251662Sdim if (Args.hasArg(options::OPT_shared)) { 6914251662Sdim CmdArgs.push_back("-lgcc_pic"); 6915251662Sdim } else { 6916251662Sdim CmdArgs.push_back("-lgcc"); 6917251662Sdim } 6918193326Sed } 6919193326Sed } 6920193326Sed 6921193326Sed if (!Args.hasArg(options::OPT_nostdlib) && 6922193326Sed !Args.hasArg(options::OPT_nostartfiles)) { 6923251662Sdim if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 6924210299Sed CmdArgs.push_back(Args.MakeArgString( 6925251662Sdim getToolChain().GetFilePath("crtendS.o"))); 6926193326Sed else 6927210299Sed CmdArgs.push_back(Args.MakeArgString( 6928251662Sdim getToolChain().GetFilePath("crtend.o"))); 6929210299Sed CmdArgs.push_back(Args.MakeArgString( 6930251662Sdim getToolChain().GetFilePath("crtn.o"))); 6931193326Sed } 6932193326Sed 6933224145Sdim addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); 6934223017Sdim 6935193326Sed const char *Exec = 6936210299Sed Args.MakeArgString(getToolChain().GetProgramPath("ld")); 6937212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 6938193326Sed} 6939212904Sdim 6940212904Sdimvoid visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, 6941212904Sdim const InputInfo &Output, 6942212904Sdim const InputInfoList &Inputs, 6943212904Sdim const ArgList &Args, 6944212904Sdim const char *LinkingOutput) const { 6945212904Sdim ArgStringList CmdArgs; 6946212904Sdim 6947212904Sdim if (Output.isFilename()) { 6948218893Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + 6949218893Sdim Output.getFilename())); 6950212904Sdim } else { 6951212904Sdim assert(Output.isNothing() && "Invalid output."); 6952212904Sdim } 6953212904Sdim 6954212904Sdim if (!Args.hasArg(options::OPT_nostdlib) && 6955263508Sdim !Args.hasArg(options::OPT_nostartfiles) && 6956263508Sdim !C.getDriver().IsCLMode()) { 6957212904Sdim CmdArgs.push_back("-defaultlib:libcmt"); 6958212904Sdim } 6959212904Sdim 6960212904Sdim CmdArgs.push_back("-nologo"); 6961212904Sdim 6962263508Sdim bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd); 6963263508Sdim 6964263508Sdim if (DLL) { 6965263508Sdim CmdArgs.push_back(Args.MakeArgString("-dll")); 6966263508Sdim 6967263508Sdim SmallString<128> ImplibName(Output.getFilename()); 6968263508Sdim llvm::sys::path::replace_extension(ImplibName, "lib"); 6969263508Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + 6970263508Sdim ImplibName.str())); 6971263508Sdim } 6972263508Sdim 6973263508Sdim if (getToolChain().getSanitizerArgs().needsAsanRt()) { 6974263508Sdim CmdArgs.push_back(Args.MakeArgString("-debug")); 6975263508Sdim CmdArgs.push_back(Args.MakeArgString("-incremental:no")); 6976263508Sdim SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir); 6977263508Sdim llvm::sys::path::append(LibSanitizer, "lib", "windows"); 6978263508Sdim if (DLL) { 6979263508Sdim llvm::sys::path::append(LibSanitizer, "clang_rt.asan_dll_thunk-i386.lib"); 6980263508Sdim } else { 6981263508Sdim llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib"); 6982263508Sdim } 6983263508Sdim // FIXME: Handle 64-bit. 6984263508Sdim CmdArgs.push_back(Args.MakeArgString(LibSanitizer)); 6985263508Sdim } 6986263508Sdim 6987239462Sdim Args.AddAllArgValues(CmdArgs, options::OPT_l); 6988263508Sdim Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link); 6989212904Sdim 6990239462Sdim // Add filenames immediately. 6991239462Sdim for (InputInfoList::const_iterator 6992239462Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 6993239462Sdim if (it->isFilename()) 6994239462Sdim CmdArgs.push_back(it->getFilename()); 6995263508Sdim else 6996263508Sdim it->getInputArg().renderAsInput(Args, CmdArgs); 6997239462Sdim } 6998239462Sdim 6999212904Sdim const char *Exec = 7000218893Sdim Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); 7001212904Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7002212904Sdim} 7003263508Sdim 7004263508Sdimvoid visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA, 7005263508Sdim const InputInfo &Output, 7006263508Sdim const InputInfoList &Inputs, 7007263508Sdim const ArgList &Args, 7008263508Sdim const char *LinkingOutput) const { 7009263508Sdim C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput)); 7010263508Sdim} 7011263508Sdim 7012263508Sdim// Try to find FallbackName on PATH that is not identical to ClangProgramPath. 7013263508Sdim// If one cannot be found, return FallbackName. 7014263508Sdim// We do this special search to prevent clang-cl from falling back onto itself 7015263508Sdim// if it's available as cl.exe on the path. 7016263508Sdimstatic std::string FindFallback(const char *FallbackName, 7017263508Sdim const char *ClangProgramPath) { 7018263508Sdim llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH"); 7019263508Sdim if (!OptPath.hasValue()) 7020263508Sdim return FallbackName; 7021263508Sdim 7022263508Sdim#ifdef LLVM_ON_WIN32 7023263508Sdim const StringRef PathSeparators = ";"; 7024263508Sdim#else 7025263508Sdim const StringRef PathSeparators = ":"; 7026263508Sdim#endif 7027263508Sdim 7028263508Sdim SmallVector<StringRef, 8> PathSegments; 7029263508Sdim llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators); 7030263508Sdim 7031263508Sdim for (size_t i = 0, e = PathSegments.size(); i != e; ++i) { 7032263508Sdim const StringRef &PathSegment = PathSegments[i]; 7033263508Sdim if (PathSegment.empty()) 7034263508Sdim continue; 7035263508Sdim 7036263508Sdim SmallString<128> FilePath(PathSegment); 7037263508Sdim llvm::sys::path::append(FilePath, FallbackName); 7038263508Sdim if (llvm::sys::fs::can_execute(Twine(FilePath)) && 7039263508Sdim !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath)) 7040263508Sdim return FilePath.str(); 7041263508Sdim } 7042263508Sdim 7043263508Sdim return FallbackName; 7044263508Sdim} 7045263508Sdim 7046263508SdimCommand *visualstudio::Compile::GetCommand(Compilation &C, const JobAction &JA, 7047263508Sdim const InputInfo &Output, 7048263508Sdim const InputInfoList &Inputs, 7049263508Sdim const ArgList &Args, 7050263508Sdim const char *LinkingOutput) const { 7051263508Sdim ArgStringList CmdArgs; 7052263508Sdim CmdArgs.push_back("/nologo"); 7053263508Sdim CmdArgs.push_back("/c"); // Compile only. 7054263508Sdim CmdArgs.push_back("/W0"); // No warnings. 7055263508Sdim 7056263508Sdim // The goal is to be able to invoke this tool correctly based on 7057263508Sdim // any flag accepted by clang-cl. 7058263508Sdim 7059263508Sdim // These are spelled the same way in clang and cl.exe,. 7060263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); 7061263508Sdim Args.AddAllArgs(CmdArgs, options::OPT_I); 7062263508Sdim 7063263508Sdim // Optimization level. 7064263508Sdim if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) { 7065263508Sdim if (A->getOption().getID() == options::OPT_O0) { 7066263508Sdim CmdArgs.push_back("/Od"); 7067263508Sdim } else { 7068263508Sdim StringRef OptLevel = A->getValue(); 7069263508Sdim if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s") 7070263508Sdim A->render(Args, CmdArgs); 7071263508Sdim else if (OptLevel == "3") 7072263508Sdim CmdArgs.push_back("/Ox"); 7073263508Sdim } 7074263508Sdim } 7075263508Sdim 7076263508Sdim // Flags for which clang-cl have an alias. 7077263508Sdim // FIXME: How can we ensure this stays in sync with relevant clang-cl options? 7078263508Sdim 7079263508Sdim if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti)) 7080263508Sdim CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR" 7081263508Sdim : "/GR-"); 7082263508Sdim if (Args.hasArg(options::OPT_fsyntax_only)) 7083263508Sdim CmdArgs.push_back("/Zs"); 7084263508Sdim 7085263508Sdim std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include); 7086263508Sdim for (size_t I = 0, E = Includes.size(); I != E; ++I) 7087263508Sdim CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I])); 7088263508Sdim 7089263508Sdim // Flags that can simply be passed through. 7090263508Sdim Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD); 7091263508Sdim Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd); 7092263508Sdim 7093263508Sdim // The order of these flags is relevant, so pick the last one. 7094263508Sdim if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd, 7095263508Sdim options::OPT__SLASH_MT, options::OPT__SLASH_MTd)) 7096263508Sdim A->render(Args, CmdArgs); 7097263508Sdim 7098263508Sdim 7099263508Sdim // Input filename. 7100263508Sdim assert(Inputs.size() == 1); 7101263508Sdim const InputInfo &II = Inputs[0]; 7102263508Sdim assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX); 7103263508Sdim CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp"); 7104263508Sdim if (II.isFilename()) 7105263508Sdim CmdArgs.push_back(II.getFilename()); 7106263508Sdim else 7107263508Sdim II.getInputArg().renderAsInput(Args, CmdArgs); 7108263508Sdim 7109263508Sdim // Output filename. 7110263508Sdim assert(Output.getType() == types::TY_Object); 7111263508Sdim const char *Fo = Args.MakeArgString(std::string("/Fo") + 7112263508Sdim Output.getFilename()); 7113263508Sdim CmdArgs.push_back(Fo); 7114263508Sdim 7115263508Sdim const Driver &D = getToolChain().getDriver(); 7116263508Sdim std::string Exec = FindFallback("cl.exe", D.getClangProgramPath()); 7117263508Sdim 7118263508Sdim return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs); 7119263508Sdim} 7120263508Sdim 7121263508Sdim 7122263508Sdim/// XCore Tools 7123263508Sdim// We pass assemble and link construction to the xcc tool. 7124263508Sdim 7125263508Sdimvoid XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 7126263508Sdim const InputInfo &Output, 7127263508Sdim const InputInfoList &Inputs, 7128263508Sdim const ArgList &Args, 7129263508Sdim const char *LinkingOutput) const { 7130263508Sdim ArgStringList CmdArgs; 7131263508Sdim 7132263508Sdim CmdArgs.push_back("-o"); 7133263508Sdim CmdArgs.push_back(Output.getFilename()); 7134263508Sdim 7135263508Sdim CmdArgs.push_back("-c"); 7136263508Sdim 7137263508Sdim if (Args.hasArg(options::OPT_g_Group)) { 7138263508Sdim CmdArgs.push_back("-g"); 7139263508Sdim } 7140263508Sdim 7141263508Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 7142263508Sdim options::OPT_Xassembler); 7143263508Sdim 7144263508Sdim for (InputInfoList::const_iterator 7145263508Sdim it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 7146263508Sdim const InputInfo &II = *it; 7147263508Sdim CmdArgs.push_back(II.getFilename()); 7148263508Sdim } 7149263508Sdim 7150263508Sdim const char *Exec = 7151263508Sdim Args.MakeArgString(getToolChain().GetProgramPath("xcc")); 7152263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7153263508Sdim} 7154263508Sdim 7155263508Sdimvoid XCore::Link::ConstructJob(Compilation &C, const JobAction &JA, 7156263508Sdim const InputInfo &Output, 7157263508Sdim const InputInfoList &Inputs, 7158263508Sdim const ArgList &Args, 7159263508Sdim const char *LinkingOutput) const { 7160263508Sdim ArgStringList CmdArgs; 7161263508Sdim 7162263508Sdim if (Output.isFilename()) { 7163263508Sdim CmdArgs.push_back("-o"); 7164263508Sdim CmdArgs.push_back(Output.getFilename()); 7165263508Sdim } else { 7166263508Sdim assert(Output.isNothing() && "Invalid output."); 7167263508Sdim } 7168263508Sdim 7169263508Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); 7170263508Sdim 7171263508Sdim const char *Exec = 7172263508Sdim Args.MakeArgString(getToolChain().GetProgramPath("xcc")); 7173263508Sdim C.addCommand(new Command(JA, *this, Exec, CmdArgs)); 7174263508Sdim} 7175