Tools.cpp revision ff8857a9e6f533765f63b2934902645baa7ddd09
1//===--- Tools.cpp - Tools Implementations ------------------------------*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "Tools.h" 11 12#include "clang/Driver/Action.h" 13#include "clang/Driver/Arg.h" 14#include "clang/Driver/ArgList.h" 15#include "clang/Driver/Driver.h" // FIXME: Remove? 16#include "clang/Driver/DriverDiagnostic.h" // FIXME: Remove? 17#include "clang/Driver/Compilation.h" 18#include "clang/Driver/Job.h" 19#include "clang/Driver/HostInfo.h" 20#include "clang/Driver/Option.h" 21#include "clang/Driver/ToolChain.h" 22#include "clang/Driver/Util.h" 23 24#include "llvm/ADT/SmallVector.h" 25#include "llvm/Support/Format.h" 26#include "llvm/Support/raw_ostream.h" 27 28#include "InputInfo.h" 29#include "ToolChains.h" 30 31using namespace clang::driver; 32using namespace clang::driver::tools; 33 34void Clang::AddPreprocessingOptions(const ArgList &Args, 35 ArgStringList &CmdArgs, 36 const InputInfo &Output, 37 const InputInfoList &Inputs) const { 38 // Handle dependency file generation. 39 Arg *A; 40 if ((A = Args.getLastArg(options::OPT_M)) || 41 (A = Args.getLastArg(options::OPT_MM)) || 42 (A = Args.getLastArg(options::OPT_MD)) || 43 (A = Args.getLastArg(options::OPT_MMD))) { 44 // Determine the output location. 45 const char *DepFile; 46 if (Output.getType() == types::TY_Dependencies) { 47 if (Output.isPipe()) 48 DepFile = "-"; 49 else 50 DepFile = Output.getFilename(); 51 } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) { 52 DepFile = MF->getValue(Args); 53 } else if (A->getOption().getId() == options::OPT_M || 54 A->getOption().getId() == options::OPT_MM) { 55 DepFile = "-"; 56 } else { 57 DepFile = darwin::CC1::getDependencyFileName(Args, Inputs); 58 } 59 CmdArgs.push_back("-dependency-file"); 60 CmdArgs.push_back(DepFile); 61 62 // Add an -MT option if the user didn't specify their own. 63 // FIXME: This should use -MQ, when we support it. 64 if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) { 65 const char *DepTarget; 66 67 // If user provided -o, that is the dependency target, except 68 // when we are only generating a dependency file. 69 Arg *OutputOpt = Args.getLastArg(options::OPT_o); 70 if (OutputOpt && Output.getType() != types::TY_Dependencies) { 71 DepTarget = OutputOpt->getValue(Args); 72 } else { 73 // Otherwise derive from the base input. 74 // 75 // FIXME: This should use the computed output file location. 76 llvm::sys::Path P(Inputs[0].getBaseInput()); 77 78 P.eraseSuffix(); 79 P.appendSuffix("o"); 80 DepTarget = Args.MakeArgString(P.getLast().c_str()); 81 } 82 83 CmdArgs.push_back("-MT"); 84 CmdArgs.push_back(DepTarget); 85 } 86 87 if (A->getOption().getId() == options::OPT_M || 88 A->getOption().getId() == options::OPT_MD) 89 CmdArgs.push_back("-sys-header-deps"); 90 } 91 92 Args.AddLastArg(CmdArgs, options::OPT_MP); 93 Args.AddAllArgs(CmdArgs, options::OPT_MT); 94 95 // FIXME: Use iterator. 96 97 // Add -i* options, and automatically translate to -include-pth for 98 // transparent PCH support. It's wonky, but we include looking for 99 // .gch so we can support seamless replacement into a build system 100 // already set up to be generating .gch files. 101 for (ArgList::const_iterator 102 it = Args.begin(), ie = Args.end(); it != ie; ++it) { 103 const Arg *A = *it; 104 if (!A->getOption().matches(options::OPT_clang_i_Group)) 105 continue; 106 107 if (A->getOption().matches(options::OPT_include)) { 108 bool FoundPTH = false; 109 llvm::sys::Path P(A->getValue(Args)); 110 P.appendSuffix("pth"); 111 if (P.exists()) { 112 FoundPTH = true; 113 } else { 114 P.eraseSuffix(); 115 P.appendSuffix("gch"); 116 if (P.exists()) 117 FoundPTH = true; 118 } 119 120 if (FoundPTH) { 121 A->claim(); 122 CmdArgs.push_back("-include-pth"); 123 CmdArgs.push_back(Args.MakeArgString(P.c_str())); 124 continue; 125 } 126 } 127 128 // Not translated, render as usual. 129 A->claim(); 130 A->render(Args, CmdArgs); 131 } 132 133 Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); 134 Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F); 135 136 // Add -Wp, and -Xassembler if using the preprocessor. 137 138 // FIXME: There is a very unfortunate problem here, some troubled 139 // souls abuse -Wp, to pass preprocessor options in gcc syntax. To 140 // really support that we would have to parse and then translate 141 // those options. :( 142 Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, 143 options::OPT_Xpreprocessor); 144} 145 146void Clang::ConstructJob(Compilation &C, const JobAction &JA, 147 Job &Dest, 148 const InputInfo &Output, 149 const InputInfoList &Inputs, 150 const ArgList &Args, 151 const char *LinkingOutput) const { 152 const Driver &D = getToolChain().getHost().getDriver(); 153 ArgStringList CmdArgs; 154 155 assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 156 157 CmdArgs.push_back("-triple"); 158 const char *TripleStr = 159 Args.MakeArgString(getToolChain().getTripleString().c_str()); 160 CmdArgs.push_back(TripleStr); 161 162 if (isa<AnalyzeJobAction>(JA)) { 163 assert(JA.getType() == types::TY_Plist && "Invalid output type."); 164 CmdArgs.push_back("-analyze"); 165 } else if (isa<PreprocessJobAction>(JA)) { 166 if (Output.getType() == types::TY_Dependencies) 167 CmdArgs.push_back("-Eonly"); 168 else 169 CmdArgs.push_back("-E"); 170 } else if (isa<PrecompileJobAction>(JA)) { 171 CmdArgs.push_back("-emit-pth"); 172 } else { 173 assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool."); 174 175 if (JA.getType() == types::TY_Nothing) { 176 CmdArgs.push_back("-fsyntax-only"); 177 } else if (JA.getType() == types::TY_LLVMAsm) { 178 CmdArgs.push_back("-emit-llvm"); 179 } else if (JA.getType() == types::TY_LLVMBC) { 180 CmdArgs.push_back("-emit-llvm-bc"); 181 } else if (JA.getType() == types::TY_PP_Asm) { 182 CmdArgs.push_back("-S"); 183 } 184 } 185 186 // The make clang go fast button. 187 CmdArgs.push_back("-disable-free"); 188 189 // Set the main file name, so that debug info works even with 190 // -save-temps. 191 CmdArgs.push_back("-main-file-name"); 192 CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs)); 193 194 // Some flags which affect the language (via preprocessor 195 // defines). See darwin::CC1::AddCPPArgs. 196 if (Args.hasArg(options::OPT_static)) 197 CmdArgs.push_back("-static-define"); 198 199 if (isa<AnalyzeJobAction>(JA)) { 200 // Add default argument set. 201 // 202 // FIXME: Move into clang? 203 CmdArgs.push_back("-warn-dead-stores"); 204 CmdArgs.push_back("-checker-cfref"); 205 CmdArgs.push_back("-analyzer-eagerly-assume"); 206 CmdArgs.push_back("-warn-objc-methodsigs"); 207 // Do not enable the missing -dealloc check. 208 // '-warn-objc-missing-dealloc', 209 CmdArgs.push_back("-warn-objc-unused-ivars"); 210 211 CmdArgs.push_back("-analyzer-output=plist"); 212 213 // Add -Xanalyzer arguments when running as analyzer. 214 Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer); 215 } else { 216 // Perform argument translation for LLVM backend. This 217 // takes some care in reconciling with llvm-gcc. The 218 // issue is that llvm-gcc translates these options based on 219 // the values in cc1, whereas we are processing based on 220 // the driver arguments. 221 // 222 // FIXME: This is currently broken for -f flags when -fno 223 // variants are present. 224 225 // This comes from the default translation the driver + cc1 226 // would do to enable flag_pic. 227 // 228 // FIXME: Centralize this code. 229 bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || 230 Args.hasArg(options::OPT_fpic) || 231 Args.hasArg(options::OPT_fPIE) || 232 Args.hasArg(options::OPT_fpie)); 233 bool PICDisabled = (Args.hasArg(options::OPT_mkernel) || 234 Args.hasArg(options::OPT_static)); 235 const char *Model = getToolChain().GetForcedPicModel(); 236 if (!Model) { 237 if (Args.hasArg(options::OPT_mdynamic_no_pic)) 238 Model = "dynamic-no-pic"; 239 else if (PICDisabled) 240 Model = "static"; 241 else if (PICEnabled) 242 Model = "pic"; 243 else 244 Model = getToolChain().GetDefaultRelocationModel(); 245 } 246 CmdArgs.push_back("--relocation-model"); 247 CmdArgs.push_back(Model); 248 249 // Infer the __PIC__ value. 250 // 251 // FIXME: This isn't quite right on Darwin, which always sets 252 // __PIC__=2. 253 if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) { 254 if (Args.hasArg(options::OPT_fPIC)) 255 CmdArgs.push_back("-pic-level=2"); 256 else 257 CmdArgs.push_back("-pic-level=1"); 258 } 259 260 if (Args.hasArg(options::OPT_ftime_report)) 261 CmdArgs.push_back("--time-passes"); 262 // FIXME: Set --enable-unsafe-fp-math. 263 if (!Args.hasArg(options::OPT_fomit_frame_pointer)) 264 CmdArgs.push_back("--disable-fp-elim"); 265 if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, 266 options::OPT_fno_zero_initialized_in_bss, 267 true)) 268 CmdArgs.push_back("--nozero-initialized-in-bss"); 269 if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm)) 270 CmdArgs.push_back("--asm-verbose"); 271 if (Args.hasArg(options::OPT_fdebug_pass_structure)) 272 CmdArgs.push_back("--debug-pass=Structure"); 273 if (Args.hasArg(options::OPT_fdebug_pass_arguments)) 274 CmdArgs.push_back("--debug-pass=Arguments"); 275 // FIXME: set --inline-threshhold=50 if (optimize_size || optimize 276 // < 3) 277 if (Args.hasFlag(options::OPT_funwind_tables, 278 options::OPT_fno_unwind_tables, 279 getToolChain().IsUnwindTablesDefault())) 280 CmdArgs.push_back("--unwind-tables=1"); 281 else 282 CmdArgs.push_back("--unwind-tables=0"); 283 if (!Args.hasFlag(options::OPT_mred_zone, 284 options::OPT_mno_red_zone, 285 true)) 286 CmdArgs.push_back("--disable-red-zone"); 287 if (Args.hasFlag(options::OPT_msoft_float, 288 options::OPT_mno_soft_float, 289 false)) 290 CmdArgs.push_back("--soft-float"); 291 292 // FIXME: Need target hooks. 293 if (memcmp(getToolChain().getPlatform().c_str(), "darwin", 6) == 0) { 294 if (getToolChain().getArchName() == "x86_64") 295 CmdArgs.push_back("--mcpu=core2"); 296 else if (getToolChain().getArchName() == "i386") 297 CmdArgs.push_back("--mcpu=yonah"); 298 } 299 300 // FIXME: Ignores ordering. Also, we need to find a realistic 301 // solution for this. 302 static const struct { 303 options::ID Pos, Neg; 304 const char *Name; 305 } FeatureOptions[] = { 306 { options::OPT_mmmx, options::OPT_mno_mmx, "mmx" }, 307 { options::OPT_msse, options::OPT_mno_sse, "sse" }, 308 { options::OPT_msse2, options::OPT_mno_sse2, "sse2" }, 309 { options::OPT_msse3, options::OPT_mno_sse3, "sse3" }, 310 { options::OPT_mssse3, options::OPT_mno_ssse3, "ssse3" }, 311 { options::OPT_msse41, options::OPT_mno_sse41, "sse41" }, 312 { options::OPT_msse42, options::OPT_mno_sse42, "sse42" }, 313 { options::OPT_msse4a, options::OPT_mno_sse4a, "sse4a" }, 314 { options::OPT_m3dnow, options::OPT_mno_3dnow, "3dnow" }, 315 { options::OPT_m3dnowa, options::OPT_mno_3dnowa, "3dnowa" } 316 }; 317 const unsigned NumFeatureOptions = 318 sizeof(FeatureOptions)/sizeof(FeatureOptions[0]); 319 320 // FIXME: Avoid std::string 321 std::string Attrs; 322 for (unsigned i=0; i < NumFeatureOptions; ++i) { 323 if (Args.hasArg(FeatureOptions[i].Pos)) { 324 if (!Attrs.empty()) 325 Attrs += ','; 326 Attrs += '+'; 327 Attrs += FeatureOptions[i].Name; 328 } else if (Args.hasArg(FeatureOptions[i].Neg)) { 329 if (!Attrs.empty()) 330 Attrs += ','; 331 Attrs += '-'; 332 Attrs += FeatureOptions[i].Name; 333 } 334 } 335 if (!Attrs.empty()) { 336 CmdArgs.push_back("--mattr"); 337 CmdArgs.push_back(Args.MakeArgString(Attrs.c_str())); 338 } 339 340 if (Args.hasFlag(options::OPT_fmath_errno, 341 options::OPT_fno_math_errno, 342 getToolChain().IsMathErrnoDefault())) 343 CmdArgs.push_back("--fmath-errno=1"); 344 else 345 CmdArgs.push_back("--fmath-errno=0"); 346 347 if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { 348 CmdArgs.push_back("--limit-float-precision"); 349 CmdArgs.push_back(A->getValue(Args)); 350 } 351 352 // FIXME: Add --stack-protector-buffer-size=<xxx> on 353 // -fstack-protect. 354 355 Arg *Unsupported; 356 if ((Unsupported = Args.getLastArg(options::OPT_MG)) || 357 (Unsupported = Args.getLastArg(options::OPT_MQ))) 358 D.Diag(clang::diag::err_drv_unsupported_opt) 359 << Unsupported->getOption().getName(); 360 } 361 362 Args.AddAllArgs(CmdArgs, options::OPT_v); 363 Args.AddLastArg(CmdArgs, options::OPT_P); 364 Args.AddLastArg(CmdArgs, options::OPT_mmacosx_version_min_EQ); 365 Args.AddLastArg(CmdArgs, options::OPT_miphoneos_version_min_EQ); 366 367 // Special case debug options to only pass -g to clang. This is 368 // wrong. 369 if (Args.hasArg(options::OPT_g_Group)) 370 CmdArgs.push_back("-g"); 371 372 Args.AddLastArg(CmdArgs, options::OPT_nostdinc); 373 374 Args.AddLastArg(CmdArgs, options::OPT_isysroot); 375 376 // Add preprocessing options like -I, -D, etc. if we are using the 377 // preprocessor. 378 // 379 // FIXME: Support -fpreprocessed 380 types::ID InputType = Inputs[0].getType(); 381 if (types::getPreprocessedType(InputType) != types::TY_INVALID) 382 AddPreprocessingOptions(Args, CmdArgs, Output, Inputs); 383 384 // Manually translate -O to -O1 and -O4 to -O3; let clang reject 385 // others. 386 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 387 if (A->getOption().getId() == options::OPT_O4) 388 CmdArgs.push_back("-O3"); 389 else if (A->getValue(Args)[0] == '\0') 390 CmdArgs.push_back("-O1"); 391 else 392 A->render(Args, CmdArgs); 393 } 394 395 Args.AddAllArgs(CmdArgs, options::OPT_clang_W_Group, 396 options::OPT_pedantic_Group); 397 Args.AddLastArg(CmdArgs, options::OPT_w); 398 399 // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi} 400 // (-ansi is equivalent to -std=c89). 401 // 402 // If a std is supplied, only add -trigraphs if it follows the 403 // option. 404 if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { 405 if (Std->getOption().matches(options::OPT_ansi)) 406 CmdArgs.push_back("-std=c89"); 407 else 408 Std->render(Args, CmdArgs); 409 410 if (Arg *A = Args.getLastArg(options::OPT_trigraphs)) 411 if (A->getIndex() > Std->getIndex()) 412 A->render(Args, CmdArgs); 413 } else 414 Args.AddLastArg(CmdArgs, options::OPT_trigraphs); 415 416 if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) { 417 CmdArgs.push_back("-ftemplate-depth"); 418 CmdArgs.push_back(A->getValue(Args)); 419 } 420 421 // Forward -f options which we can pass directly. 422 Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); 423 Args.AddLastArg(CmdArgs, options::OPT_fexceptions); 424 Args.AddLastArg(CmdArgs, options::OPT_ffreestanding); 425 Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); 426 Args.AddLastArg(CmdArgs, options::OPT_fgnu_runtime); 427 Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions); 428 Args.AddLastArg(CmdArgs, options::OPT_fms_extensions); 429 Args.AddLastArg(CmdArgs, options::OPT_fnext_runtime); 430 Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics); 431 Args.AddLastArg(CmdArgs, options::OPT_fno_show_column); 432 Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only); 433 Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc); 434 // FIXME: Should we remove this? 435 Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi); 436 Args.AddLastArg(CmdArgs, options::OPT_fprint_source_range_info); 437 Args.AddLastArg(CmdArgs, options::OPT_ftime_report); 438 Args.AddLastArg(CmdArgs, options::OPT_ftrapv); 439 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ); 440 Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); 441 442 // Forward -f options with positive and negative forms; we translate 443 // these by hand. 444 445 // -fbuiltin is default, only pass non-default. 446 if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin)) 447 CmdArgs.push_back("-fbuiltin=0"); 448 449 // -fblocks default varies depending on platform and language; 450 // -always pass if specified. 451 if (Arg *A = Args.getLastArg(options::OPT_fblocks, options::OPT_fno_blocks)) { 452 if (A->getOption().matches(options::OPT_fblocks)) 453 CmdArgs.push_back("-fblocks"); 454 else 455 CmdArgs.push_back("-fblocks=0"); 456 } 457 458 // -fno-pascal-strings is default, only pass non-default. If the 459 // -tool chain happened to translate to -mpascal-strings, we want to 460 // -back translate here. 461 // 462 // FIXME: This is gross; that translation should be pulled from the 463 // tool chain. 464 if (Args.hasFlag(options::OPT_fpascal_strings, 465 options::OPT_fno_pascal_strings, 466 false) || 467 Args.hasFlag(options::OPT_mpascal_strings, 468 options::OPT_mno_pascal_strings, 469 false)) 470 CmdArgs.push_back("-fpascal-strings"); 471 472 // -fcommon is default, only pass non-default. 473 if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common)) 474 CmdArgs.push_back("-fno-common"); 475 476 Args.AddLastArg(CmdArgs, options::OPT_dM); 477 478 Args.AddAllArgValues(CmdArgs, options::OPT_Xclang); 479 480 if (Output.getType() == types::TY_Dependencies) { 481 // Handled with other dependency code. 482 } else if (Output.isPipe()) { 483 CmdArgs.push_back("-o"); 484 CmdArgs.push_back("-"); 485 } else if (Output.isFilename()) { 486 CmdArgs.push_back("-o"); 487 CmdArgs.push_back(Output.getFilename()); 488 } else { 489 assert(Output.isNothing() && "Invalid output."); 490 } 491 492 for (InputInfoList::const_iterator 493 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 494 const InputInfo &II = *it; 495 CmdArgs.push_back("-x"); 496 CmdArgs.push_back(types::getTypeName(II.getType())); 497 if (II.isPipe()) 498 CmdArgs.push_back("-"); 499 else if (II.isFilename()) 500 CmdArgs.push_back(II.getFilename()); 501 else 502 II.getInputArg().renderAsInput(Args, CmdArgs); 503 } 504 505 const char *Exec = 506 Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc").c_str()); 507 Dest.addCommand(new Command(Exec, CmdArgs)); 508 509 // Explicitly warn that these options are unsupported, even though 510 // we are allowing compilation to continue. 511 // FIXME: Use iterator. 512 for (ArgList::const_iterator 513 it = Args.begin(), ie = Args.end(); it != ie; ++it) { 514 const Arg *A = *it; 515 if (A->getOption().matches(options::OPT_pg)) { 516 A->claim(); 517 D.Diag(clang::diag::warn_drv_clang_unsupported) 518 << A->getAsString(Args); 519 } 520 } 521 522 // Claim some arguments which clang supports automatically. 523 524 // -fpch-preprocess is used with gcc to add a special marker in the 525 // -output to include the PCH file. Clang's PTH solution is 526 // -completely transparent, so we do not need to deal with it at 527 // -all. 528 Args.ClaimAllArgs(options::OPT_fpch_preprocess); 529 530 // Claim some arguments which clang doesn't support, but we don't 531 // care to warn the user about. 532 533 // FIXME: Use iterator. 534 for (ArgList::const_iterator 535 it = Args.begin(), ie = Args.end(); it != ie; ++it) { 536 const Arg *A = *it; 537 if (A->getOption().matches(options::OPT_clang_ignored_W_Group) || 538 A->getOption().matches(options::OPT_clang_ignored_f_Group) || 539 A->getOption().matches(options::OPT_clang_ignored_m_Group)) 540 A->claim(); 541 } 542} 543 544void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, 545 Job &Dest, 546 const InputInfo &Output, 547 const InputInfoList &Inputs, 548 const ArgList &Args, 549 const char *LinkingOutput) const { 550 ArgStringList CmdArgs; 551 552 for (ArgList::const_iterator 553 it = Args.begin(), ie = Args.end(); it != ie; ++it) { 554 Arg *A = *it; 555 if (A->getOption().hasForwardToGCC()) { 556 // It is unfortunate that we have to claim here, as this means 557 // we will basically never report anything interesting for 558 // platforms using a generic gcc. 559 A->claim(); 560 A->render(Args, CmdArgs); 561 } 562 } 563 564 RenderExtraToolArgs(CmdArgs); 565 566 // If using a driver driver, force the arch. 567 if (getToolChain().getHost().useDriverDriver()) { 568 CmdArgs.push_back("-arch"); 569 570 // FIXME: Remove these special cases. 571 const char *Str = getToolChain().getArchName().c_str(); 572 if (strcmp(Str, "powerpc") == 0) 573 Str = "ppc"; 574 else if (strcmp(Str, "powerpc64") == 0) 575 Str = "ppc64"; 576 CmdArgs.push_back(Str); 577 } 578 579 if (Output.isPipe()) { 580 CmdArgs.push_back("-o"); 581 CmdArgs.push_back("-"); 582 } else if (Output.isFilename()) { 583 CmdArgs.push_back("-o"); 584 CmdArgs.push_back(Output.getFilename()); 585 } else { 586 assert(Output.isNothing() && "Unexpected output"); 587 CmdArgs.push_back("-fsyntax-only"); 588 } 589 590 591 // Only pass -x if gcc will understand it; otherwise hope gcc 592 // understands the suffix correctly. The main use case this would go 593 // wrong in is for linker inputs if they happened to have an odd 594 // suffix; really the only way to get this to happen is a command 595 // like '-x foobar a.c' which will treat a.c like a linker input. 596 // 597 // FIXME: For the linker case specifically, can we safely convert 598 // inputs into '-Wl,' options? 599 for (InputInfoList::const_iterator 600 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 601 const InputInfo &II = *it; 602 if (types::canTypeBeUserSpecified(II.getType())) { 603 CmdArgs.push_back("-x"); 604 CmdArgs.push_back(types::getTypeName(II.getType())); 605 } 606 607 if (II.isPipe()) 608 CmdArgs.push_back("-"); 609 else if (II.isFilename()) 610 CmdArgs.push_back(II.getFilename()); 611 else 612 // Don't render as input, we need gcc to do the translations. 613 II.getInputArg().render(Args, CmdArgs); 614 } 615 616 const char *GCCName = 617 getToolChain().getHost().getDriver().CCCGenericGCCName.c_str(); 618 const char *Exec = 619 Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName).c_str()); 620 Dest.addCommand(new Command(Exec, CmdArgs)); 621} 622 623void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const { 624 CmdArgs.push_back("-E"); 625} 626 627void gcc::Precompile::RenderExtraToolArgs(ArgStringList &CmdArgs) const { 628 // The type is good enough. 629} 630 631void gcc::Compile::RenderExtraToolArgs(ArgStringList &CmdArgs) const { 632 CmdArgs.push_back("-S"); 633} 634 635void gcc::Assemble::RenderExtraToolArgs(ArgStringList &CmdArgs) const { 636 CmdArgs.push_back("-c"); 637} 638 639void gcc::Link::RenderExtraToolArgs(ArgStringList &CmdArgs) const { 640 // The types are (hopefully) good enough. 641} 642 643const char *darwin::CC1::getCC1Name(types::ID Type) const { 644 switch (Type) { 645 default: 646 assert(0 && "Unexpected type for Darwin CC1 tool."); 647 case types::TY_Asm: 648 case types::TY_C: case types::TY_CHeader: 649 case types::TY_PP_C: case types::TY_PP_CHeader: 650 return "cc1"; 651 case types::TY_ObjC: case types::TY_ObjCHeader: 652 case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader: 653 return "cc1obj"; 654 case types::TY_CXX: case types::TY_CXXHeader: 655 case types::TY_PP_CXX: case types::TY_PP_CXXHeader: 656 return "cc1plus"; 657 case types::TY_ObjCXX: case types::TY_ObjCXXHeader: 658 case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader: 659 return "cc1objplus"; 660 } 661} 662 663const char *darwin::CC1::getBaseInputName(const ArgList &Args, 664 const InputInfoList &Inputs) { 665 llvm::sys::Path P(Inputs[0].getBaseInput()); 666 return Args.MakeArgString(P.getLast().c_str()); 667} 668 669const char *darwin::CC1::getBaseInputStem(const ArgList &Args, 670 const InputInfoList &Inputs) { 671 const char *Str = getBaseInputName(Args, Inputs); 672 673 if (const char *End = strchr(Str, '.')) 674 return Args.MakeArgString(std::string(Str, End).c_str()); 675 676 return Str; 677} 678 679const char * 680darwin::CC1::getDependencyFileName(const ArgList &Args, 681 const InputInfoList &Inputs) { 682 // FIXME: Think about this more. 683 std::string Res; 684 685 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 686 std::string Str(OutputOpt->getValue(Args)); 687 688 Res = Str.substr(0, Str.rfind('.')); 689 } else 690 Res = darwin::CC1::getBaseInputStem(Args, Inputs); 691 692 return Args.MakeArgString((Res + ".d").c_str()); 693} 694 695void darwin::CC1::AddCC1Args(const ArgList &Args, 696 ArgStringList &CmdArgs) const { 697 // Derived from cc1 spec. 698 699 // FIXME: -fapple-kext seems to disable this too. Investigate. 700 if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) && 701 !Args.hasArg(options::OPT_mdynamic_no_pic)) 702 CmdArgs.push_back("-fPIC"); 703 704 // gcc has some code here to deal with when no -mmacosx-version-min 705 // and no -miphoneos-version-min is present, but this never happens 706 // due to tool chain specific argument translation. 707 708 // FIXME: Remove mthumb 709 // FIXME: Remove mno-thumb 710 // FIXME: Remove faltivec 711 // FIXME: Remove mno-fused-madd 712 // FIXME: Remove mlong-branch 713 // FIXME: Remove mlongcall 714 // FIXME: Remove mcpu=G4 715 // FIXME: Remove mcpu=G5 716 717 if (Args.hasArg(options::OPT_g_Flag) && 718 !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols)) 719 CmdArgs.push_back("-feliminate-unused-debug-symbols"); 720} 721 722void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, 723 const InputInfoList &Inputs, 724 const ArgStringList &OutputArgs) const { 725 const Driver &D = getToolChain().getHost().getDriver(); 726 727 // Derived from cc1_options spec. 728 if (Args.hasArg(options::OPT_fast) || 729 Args.hasArg(options::OPT_fastf) || 730 Args.hasArg(options::OPT_fastcp)) 731 CmdArgs.push_back("-O3"); 732 733 if (Arg *A = Args.getLastArg(options::OPT_pg)) 734 if (Args.hasArg(options::OPT_fomit_frame_pointer)) 735 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 736 << A->getAsString(Args) << "-fomit-frame-pointer"; 737 738 AddCC1Args(Args, CmdArgs); 739 740 if (!Args.hasArg(options::OPT_Q)) 741 CmdArgs.push_back("-quiet"); 742 743 CmdArgs.push_back("-dumpbase"); 744 CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs)); 745 746 Args.AddAllArgs(CmdArgs, options::OPT_d_Group); 747 748 Args.AddAllArgs(CmdArgs, options::OPT_m_Group); 749 Args.AddAllArgs(CmdArgs, options::OPT_a_Group); 750 751 // FIXME: The goal is to use the user provided -o if that is our 752 // final output, otherwise to drive from the original input 753 // name. Find a clean way to go about this. 754 if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) && 755 Args.hasArg(options::OPT_o)) { 756 Arg *OutputOpt = Args.getLastArg(options::OPT_o); 757 CmdArgs.push_back("-auxbase-strip"); 758 CmdArgs.push_back(OutputOpt->getValue(Args)); 759 } else { 760 CmdArgs.push_back("-auxbase"); 761 CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs)); 762 } 763 764 Args.AddAllArgs(CmdArgs, options::OPT_g_Group); 765 766 Args.AddAllArgs(CmdArgs, options::OPT_O); 767 // FIXME: -Wall is getting some special treatment. Investigate. 768 Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group); 769 Args.AddLastArg(CmdArgs, options::OPT_w); 770 Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi, 771 options::OPT_trigraphs); 772 if (Args.hasArg(options::OPT_v)) 773 CmdArgs.push_back("-version"); 774 if (Args.hasArg(options::OPT_pg)) 775 CmdArgs.push_back("-p"); 776 Args.AddLastArg(CmdArgs, options::OPT_p); 777 778 // The driver treats -fsyntax-only specially. 779 Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); 780 781 Args.AddAllArgs(CmdArgs, options::OPT_undef); 782 if (Args.hasArg(options::OPT_Qn)) 783 CmdArgs.push_back("-fno-ident"); 784 785 // FIXME: This isn't correct. 786 //Args.AddLastArg(CmdArgs, options::OPT__help) 787 //Args.AddLastArg(CmdArgs, options::OPT__targetHelp) 788 789 CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 790 791 // FIXME: Still don't get what is happening here. Investigate. 792 Args.AddAllArgs(CmdArgs, options::OPT__param); 793 794 if (Args.hasArg(options::OPT_fmudflap) || 795 Args.hasArg(options::OPT_fmudflapth)) { 796 CmdArgs.push_back("-fno-builtin"); 797 CmdArgs.push_back("-fno-merge-constants"); 798 } 799 800 if (Args.hasArg(options::OPT_coverage)) { 801 CmdArgs.push_back("-fprofile-arcs"); 802 CmdArgs.push_back("-ftest-coverage"); 803 } 804 805 if (types::isCXX(Inputs[0].getType())) 806 CmdArgs.push_back("-D__private_extern__=extern"); 807} 808 809void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, 810 const InputInfoList &Inputs, 811 const ArgStringList &OutputArgs) const { 812 // Derived from cpp_options 813 AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs); 814 815 CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 816 817 AddCC1Args(Args, CmdArgs); 818 819 // NOTE: The code below has some commonality with cpp_options, but 820 // in classic gcc style ends up sending things in different 821 // orders. This may be a good merge candidate once we drop pedantic 822 // compatibility. 823 824 Args.AddAllArgs(CmdArgs, options::OPT_m_Group); 825 Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi, 826 options::OPT_trigraphs); 827 Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group); 828 Args.AddLastArg(CmdArgs, options::OPT_w); 829 830 // The driver treats -fsyntax-only specially. 831 Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); 832 833 if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) && 834 !Args.hasArg(options::OPT_fno_working_directory)) 835 CmdArgs.push_back("-fworking-directory"); 836 837 Args.AddAllArgs(CmdArgs, options::OPT_O); 838 Args.AddAllArgs(CmdArgs, options::OPT_undef); 839 if (Args.hasArg(options::OPT_save_temps)) 840 CmdArgs.push_back("-fpch-preprocess"); 841} 842 843void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args, 844 ArgStringList &CmdArgs, 845 const InputInfoList &Inputs) const 846{ 847 const Driver &D = getToolChain().getHost().getDriver(); 848 849 // Derived from cpp_unique_options. 850 Arg *A; 851 if ((A = Args.getLastArg(options::OPT_C)) || 852 (A = Args.getLastArg(options::OPT_CC))) { 853 if (!Args.hasArg(options::OPT_E)) 854 D.Diag(clang::diag::err_drv_argument_only_allowed_with) 855 << A->getAsString(Args) << "-E"; 856 } 857 if (!Args.hasArg(options::OPT_Q)) 858 CmdArgs.push_back("-quiet"); 859 Args.AddAllArgs(CmdArgs, options::OPT_nostdinc); 860 Args.AddLastArg(CmdArgs, options::OPT_v); 861 Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F); 862 Args.AddLastArg(CmdArgs, options::OPT_P); 863 864 // FIXME: Handle %I properly. 865 if (getToolChain().getArchName() == "x86_64") { 866 CmdArgs.push_back("-imultilib"); 867 CmdArgs.push_back("x86_64"); 868 } 869 870 if (Args.hasArg(options::OPT_MD)) { 871 CmdArgs.push_back("-MD"); 872 CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs)); 873 } 874 875 if (Args.hasArg(options::OPT_MMD)) { 876 CmdArgs.push_back("-MMD"); 877 CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs)); 878 } 879 880 Args.AddLastArg(CmdArgs, options::OPT_M); 881 Args.AddLastArg(CmdArgs, options::OPT_MM); 882 Args.AddAllArgs(CmdArgs, options::OPT_MF); 883 Args.AddLastArg(CmdArgs, options::OPT_MG); 884 Args.AddLastArg(CmdArgs, options::OPT_MP); 885 Args.AddAllArgs(CmdArgs, options::OPT_MQ); 886 Args.AddAllArgs(CmdArgs, options::OPT_MT); 887 if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) && 888 (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) { 889 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) { 890 CmdArgs.push_back("-MQ"); 891 CmdArgs.push_back(OutputOpt->getValue(Args)); 892 } 893 } 894 895 Args.AddLastArg(CmdArgs, options::OPT_remap); 896 if (Args.hasArg(options::OPT_g3)) 897 CmdArgs.push_back("-dD"); 898 Args.AddLastArg(CmdArgs, options::OPT_H); 899 900 AddCPPArgs(Args, CmdArgs); 901 902 Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A); 903 Args.AddAllArgs(CmdArgs, options::OPT_i_Group); 904 905 for (InputInfoList::const_iterator 906 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 907 const InputInfo &II = *it; 908 909 if (II.isPipe()) 910 CmdArgs.push_back("-"); 911 else 912 CmdArgs.push_back(II.getFilename()); 913 } 914 915 Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, 916 options::OPT_Xpreprocessor); 917 918 if (Args.hasArg(options::OPT_fmudflap)) { 919 CmdArgs.push_back("-D_MUDFLAP"); 920 CmdArgs.push_back("-include"); 921 CmdArgs.push_back("mf-runtime.h"); 922 } 923 924 if (Args.hasArg(options::OPT_fmudflapth)) { 925 CmdArgs.push_back("-D_MUDFLAP"); 926 CmdArgs.push_back("-D_MUDFLAPTH"); 927 CmdArgs.push_back("-include"); 928 CmdArgs.push_back("mf-runtime.h"); 929 } 930} 931 932void darwin::CC1::AddCPPArgs(const ArgList &Args, 933 ArgStringList &CmdArgs) const { 934 // Derived from cpp spec. 935 936 if (Args.hasArg(options::OPT_static)) { 937 // The gcc spec is broken here, it refers to dynamic but 938 // that has been translated. Start by being bug compatible. 939 940 // if (!Args.hasArg(arglist.parser.dynamicOption)) 941 CmdArgs.push_back("-D__STATIC__"); 942 } else 943 CmdArgs.push_back("-D__DYNAMIC__"); 944 945 if (Args.hasArg(options::OPT_pthread)) 946 CmdArgs.push_back("-D_REENTRANT"); 947} 948 949void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, 950 Job &Dest, const InputInfo &Output, 951 const InputInfoList &Inputs, 952 const ArgList &Args, 953 const char *LinkingOutput) const { 954 ArgStringList CmdArgs; 955 956 assert(Inputs.size() == 1 && "Unexpected number of inputs!"); 957 958 CmdArgs.push_back("-E"); 959 960 if (Args.hasArg(options::OPT_traditional) || 961 Args.hasArg(options::OPT_ftraditional) || 962 Args.hasArg(options::OPT_traditional_cpp)) 963 CmdArgs.push_back("-traditional-cpp"); 964 965 ArgStringList OutputArgs; 966 if (Output.isFilename()) { 967 OutputArgs.push_back("-o"); 968 OutputArgs.push_back(Output.getFilename()); 969 } else { 970 assert(Output.isPipe() && "Unexpected CC1 output."); 971 } 972 973 if (Args.hasArg(options::OPT_E)) { 974 AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 975 } else { 976 AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 977 CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 978 } 979 980 Args.AddAllArgs(CmdArgs, options::OPT_d_Group); 981 982 const char *CC1Name = getCC1Name(Inputs[0].getType()); 983 const char *Exec = 984 Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str()); 985 Dest.addCommand(new Command(Exec, CmdArgs)); 986} 987 988void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA, 989 Job &Dest, const InputInfo &Output, 990 const InputInfoList &Inputs, 991 const ArgList &Args, 992 const char *LinkingOutput) const { 993 const Driver &D = getToolChain().getHost().getDriver(); 994 ArgStringList CmdArgs; 995 996 assert(Inputs.size() == 1 && "Unexpected number of inputs!"); 997 998 types::ID InputType = Inputs[0].getType(); 999 const Arg *A; 1000 if ((A = Args.getLastArg(options::OPT_traditional)) || 1001 (A = Args.getLastArg(options::OPT_ftraditional))) 1002 D.Diag(clang::diag::err_drv_argument_only_allowed_with) 1003 << A->getAsString(Args) << "-E"; 1004 1005 if (Output.getType() == types::TY_LLVMAsm) 1006 CmdArgs.push_back("-emit-llvm"); 1007 else if (Output.getType() == types::TY_LLVMBC) 1008 CmdArgs.push_back("-emit-llvm-bc"); 1009 1010 ArgStringList OutputArgs; 1011 if (Output.getType() != types::TY_PCH) { 1012 OutputArgs.push_back("-o"); 1013 if (Output.isPipe()) 1014 OutputArgs.push_back("-"); 1015 else if (Output.isNothing()) 1016 OutputArgs.push_back("/dev/null"); 1017 else 1018 OutputArgs.push_back(Output.getFilename()); 1019 } 1020 1021 // There is no need for this level of compatibility, but it makes 1022 // diffing easier. 1023 bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) || 1024 Args.hasArg(options::OPT_S)); 1025 1026 if (types::getPreprocessedType(InputType) != types::TY_INVALID) { 1027 AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs); 1028 if (OutputArgsEarly) { 1029 AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 1030 } else { 1031 AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 1032 CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 1033 } 1034 } else { 1035 CmdArgs.push_back("-fpreprocessed"); 1036 1037 // FIXME: There is a spec command to remove 1038 // -fpredictive-compilation args here. Investigate. 1039 1040 for (InputInfoList::const_iterator 1041 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1042 const InputInfo &II = *it; 1043 1044 if (II.isPipe()) 1045 CmdArgs.push_back("-"); 1046 else 1047 CmdArgs.push_back(II.getFilename()); 1048 } 1049 1050 if (OutputArgsEarly) { 1051 AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs); 1052 } else { 1053 AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); 1054 CmdArgs.append(OutputArgs.begin(), OutputArgs.end()); 1055 } 1056 } 1057 1058 if (Output.getType() == types::TY_PCH) { 1059 assert(Output.isFilename() && "Invalid PCH output."); 1060 1061 CmdArgs.push_back("-o"); 1062 // NOTE: gcc uses a temp .s file for this, but there doesn't seem 1063 // to be a good reason. 1064 CmdArgs.push_back("/dev/null"); 1065 1066 CmdArgs.push_back("--output-pch="); 1067 CmdArgs.push_back(Output.getFilename()); 1068 } 1069 1070 const char *CC1Name = getCC1Name(Inputs[0].getType()); 1071 const char *Exec = 1072 Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str()); 1073 Dest.addCommand(new Command(Exec, CmdArgs)); 1074} 1075 1076void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 1077 Job &Dest, const InputInfo &Output, 1078 const InputInfoList &Inputs, 1079 const ArgList &Args, 1080 const char *LinkingOutput) const { 1081 ArgStringList CmdArgs; 1082 1083 assert(Inputs.size() == 1 && "Unexpected number of inputs."); 1084 const InputInfo &Input = Inputs[0]; 1085 1086 // Bit of a hack, this is only used for original inputs. 1087 // 1088 // FIXME: This is broken for preprocessed .s inputs. 1089 if (Input.isFilename() && 1090 strcmp(Input.getFilename(), Input.getBaseInput()) == 0) { 1091 if (Args.hasArg(options::OPT_gstabs)) 1092 CmdArgs.push_back("--gstabs"); 1093 else if (Args.hasArg(options::OPT_g_Group)) 1094 CmdArgs.push_back("--gdwarf2"); 1095 } 1096 1097 // Derived from asm spec. 1098 CmdArgs.push_back("-arch"); 1099 CmdArgs.push_back(getToolChain().getArchName().c_str()); 1100 1101 CmdArgs.push_back("-force_cpusubtype_ALL"); 1102 if ((Args.hasArg(options::OPT_mkernel) || 1103 Args.hasArg(options::OPT_static) || 1104 Args.hasArg(options::OPT_fapple_kext)) && 1105 !Args.hasArg(options::OPT_dynamic)) 1106 CmdArgs.push_back("-static"); 1107 1108 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 1109 options::OPT_Xassembler); 1110 1111 assert(Output.isFilename() && "Unexpected lipo output."); 1112 CmdArgs.push_back("-o"); 1113 CmdArgs.push_back(Output.getFilename()); 1114 1115 if (Input.isPipe()) { 1116 CmdArgs.push_back("-"); 1117 } else { 1118 assert(Input.isFilename() && "Invalid input."); 1119 CmdArgs.push_back(Input.getFilename()); 1120 } 1121 1122 // asm_final spec is empty. 1123 1124 const char *Exec = 1125 Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str()); 1126 Dest.addCommand(new Command(Exec, CmdArgs)); 1127} 1128 1129static const char *MakeFormattedString(const ArgList &Args, 1130 const llvm::format_object_base &Fmt) { 1131 std::string Str; 1132 llvm::raw_string_ostream(Str) << Fmt; 1133 return Args.MakeArgString(Str.c_str()); 1134} 1135 1136/// Helper routine for seeing if we should use dsymutil; this is a 1137/// gcc compatible hack, we should remove it and use the input 1138/// type information. 1139static bool isSourceSuffix(const char *Str) { 1140 // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm', 1141 // 'mm'. 1142 switch (strlen(Str)) { 1143 default: 1144 return false; 1145 case 1: 1146 return (memcmp(Str, "C", 1) == 0 || 1147 memcmp(Str, "c", 1) == 0 || 1148 memcmp(Str, "m", 1) == 0); 1149 case 2: 1150 return (memcmp(Str, "cc", 2) == 0 || 1151 memcmp(Str, "cp", 2) == 0 || 1152 memcmp(Str, "mm", 2) == 0); 1153 case 3: 1154 return (memcmp(Str, "CPP", 3) == 0 || 1155 memcmp(Str, "c++", 3) == 0 || 1156 memcmp(Str, "cpp", 3) == 0 || 1157 memcmp(Str, "cxx", 3) == 0); 1158 } 1159} 1160 1161static bool isMacosxVersionLT(unsigned (&A)[3], unsigned (&B)[3]) { 1162 for (unsigned i=0; i < 3; ++i) { 1163 if (A[i] > B[i]) return false; 1164 if (A[i] < B[i]) return true; 1165 } 1166 return false; 1167} 1168 1169static bool isMacosxVersionLT(unsigned (&A)[3], 1170 unsigned V0, unsigned V1=0, unsigned V2=0) { 1171 unsigned B[3] = { V0, V1, V2 }; 1172 return isMacosxVersionLT(A, B); 1173} 1174 1175const toolchains::Darwin_X86 &darwin::Link::getDarwinToolChain() const { 1176 return reinterpret_cast<const toolchains::Darwin_X86&>(getToolChain()); 1177} 1178 1179void darwin::Link::AddDarwinArch(const ArgList &Args, 1180 ArgStringList &CmdArgs) const { 1181 // Derived from darwin_arch spec. 1182 CmdArgs.push_back("-arch"); 1183 CmdArgs.push_back(getToolChain().getArchName().c_str()); 1184} 1185 1186void darwin::Link::AddDarwinSubArch(const ArgList &Args, 1187 ArgStringList &CmdArgs) const { 1188 // Derived from darwin_subarch spec, not sure what the distinction 1189 // exists for but at least for this chain it is the same. 1190 AddDarwinArch(Args, CmdArgs); 1191} 1192 1193void darwin::Link::AddLinkArgs(const ArgList &Args, 1194 ArgStringList &CmdArgs) const { 1195 const Driver &D = getToolChain().getHost().getDriver(); 1196 1197 // Derived from the "link" spec. 1198 Args.AddAllArgs(CmdArgs, options::OPT_static); 1199 if (!Args.hasArg(options::OPT_static)) 1200 CmdArgs.push_back("-dynamic"); 1201 if (Args.hasArg(options::OPT_fgnu_runtime)) { 1202 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 1203 // here. How do we wish to handle such things? 1204 } 1205 1206 if (!Args.hasArg(options::OPT_dynamiclib)) { 1207 if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) { 1208 AddDarwinArch(Args, CmdArgs); 1209 CmdArgs.push_back("-force_cpusubtype_ALL"); 1210 } else 1211 AddDarwinSubArch(Args, CmdArgs); 1212 1213 Args.AddLastArg(CmdArgs, options::OPT_bundle); 1214 Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 1215 Args.AddAllArgs(CmdArgs, options::OPT_client__name); 1216 1217 Arg *A; 1218 if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 1219 (A = Args.getLastArg(options::OPT_current__version)) || 1220 (A = Args.getLastArg(options::OPT_install__name))) 1221 D.Diag(clang::diag::err_drv_argument_only_allowed_with) 1222 << A->getAsString(Args) << "-dynamiclib"; 1223 1224 Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 1225 Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 1226 Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 1227 } else { 1228 CmdArgs.push_back("-dylib"); 1229 1230 Arg *A; 1231 if ((A = Args.getLastArg(options::OPT_bundle)) || 1232 (A = Args.getLastArg(options::OPT_bundle__loader)) || 1233 (A = Args.getLastArg(options::OPT_client__name)) || 1234 (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 1235 (A = Args.getLastArg(options::OPT_keep__private__externs)) || 1236 (A = Args.getLastArg(options::OPT_private__bundle))) 1237 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 1238 << A->getAsString(Args) << "-dynamiclib"; 1239 1240 Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 1241 "-dylib_compatibility_version"); 1242 Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 1243 "-dylib_current_version"); 1244 1245 if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) { 1246 AddDarwinArch(Args, CmdArgs); 1247 // NOTE: We don't add -force_cpusubtype_ALL on this path. Ok. 1248 } else 1249 AddDarwinSubArch(Args, CmdArgs); 1250 1251 Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 1252 "-dylib_install_name"); 1253 } 1254 1255 Args.AddLastArg(CmdArgs, options::OPT_all__load); 1256 Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 1257 Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 1258 Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 1259 Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 1260 Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 1261 Args.AddLastArg(CmdArgs, options::OPT_dynamic); 1262 Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 1263 Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 1264 Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 1265 Args.AddAllArgs(CmdArgs, options::OPT_image__base); 1266 Args.AddAllArgs(CmdArgs, options::OPT_init); 1267 1268 if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ)) { 1269 if (!Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { 1270 // FIXME: I don't understand what is going on here. This is 1271 // supposed to come from darwin_ld_minversion, but gcc doesn't 1272 // seem to be following that; it must be getting overridden 1273 // somewhere. 1274 CmdArgs.push_back("-macosx_version_min"); 1275 CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr()); 1276 } 1277 } else { 1278 // Adding all arguments doesn't make sense here but this is what 1279 // gcc does. 1280 Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ, 1281 "-macosx_version_min"); 1282 } 1283 1284 Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ, 1285 "-iphoneos_version_min"); 1286 Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 1287 Args.AddLastArg(CmdArgs, options::OPT_multi__module); 1288 Args.AddLastArg(CmdArgs, options::OPT_single__module); 1289 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 1290 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 1291 1292 if (Args.hasArg(options::OPT_fpie)) 1293 CmdArgs.push_back("-pie"); 1294 1295 Args.AddLastArg(CmdArgs, options::OPT_prebind); 1296 Args.AddLastArg(CmdArgs, options::OPT_noprebind); 1297 Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 1298 Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 1299 Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 1300 Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 1301 Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 1302 Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 1303 Args.AddAllArgs(CmdArgs, options::OPT_segprot); 1304 Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 1305 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 1306 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 1307 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 1308 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 1309 Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 1310 Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 1311 Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot"); 1312 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 1313 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 1314 Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 1315 Args.AddAllArgs(CmdArgs, options::OPT_undefined); 1316 Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 1317 Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 1318 1319 if (!Args.hasArg(options::OPT_weak__reference__mismatches)) { 1320 CmdArgs.push_back("-weak_reference_mismatches"); 1321 CmdArgs.push_back("non-weak"); 1322 } 1323 1324 Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 1325 Args.AddAllArgs(CmdArgs, options::OPT_y); 1326 Args.AddLastArg(CmdArgs, options::OPT_w); 1327 Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 1328 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 1329 Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 1330 Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 1331 Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 1332 Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 1333 Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 1334 Args.AddLastArg(CmdArgs, options::OPT_whyload); 1335 Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 1336 Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 1337 Args.AddLastArg(CmdArgs, options::OPT_dylinker); 1338 Args.AddLastArg(CmdArgs, options::OPT_Mach); 1339} 1340 1341void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, 1342 Job &Dest, const InputInfo &Output, 1343 const InputInfoList &Inputs, 1344 const ArgList &Args, 1345 const char *LinkingOutput) const { 1346 assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 1347 // The logic here is derived from gcc's behavior; most of which 1348 // comes from specs (starting with link_command). Consult gcc for 1349 // more information. 1350 1351 // FIXME: The spec references -fdump= which seems to have 1352 // disappeared? 1353 1354 ArgStringList CmdArgs; 1355 1356 // I'm not sure why this particular decomposition exists in gcc, but 1357 // we follow suite for ease of comparison. 1358 AddLinkArgs(Args, CmdArgs); 1359 1360 // FIXME: gcc has %{x} in here. How could this ever happen? Cruft? 1361 Args.AddAllArgs(CmdArgs, options::OPT_d_Flag); 1362 Args.AddAllArgs(CmdArgs, options::OPT_s); 1363 Args.AddAllArgs(CmdArgs, options::OPT_t); 1364 Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); 1365 Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 1366 Args.AddAllArgs(CmdArgs, options::OPT_A); 1367 Args.AddLastArg(CmdArgs, options::OPT_e); 1368 Args.AddAllArgs(CmdArgs, options::OPT_m_Separate); 1369 Args.AddAllArgs(CmdArgs, options::OPT_r); 1370 1371 // FIXME: This is just being pedantically bug compatible, gcc 1372 // doesn't *mean* to forward this, it just does (yay for pattern 1373 // matching). It doesn't work, of course. 1374 Args.AddAllArgs(CmdArgs, options::OPT_object); 1375 1376 CmdArgs.push_back("-o"); 1377 CmdArgs.push_back(Output.getFilename()); 1378 1379 unsigned MacosxVersion[3]; 1380 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) { 1381 bool HadExtra; 1382 if (!Driver::GetReleaseVersion(A->getValue(Args), MacosxVersion[0], 1383 MacosxVersion[1], MacosxVersion[2], 1384 HadExtra) || 1385 HadExtra) { 1386 const Driver &D = getToolChain().getHost().getDriver(); 1387 D.Diag(clang::diag::err_drv_invalid_version_number) 1388 << A->getAsString(Args); 1389 } 1390 } else { 1391 getDarwinToolChain().getMacosxVersion(MacosxVersion); 1392 } 1393 1394 if (!Args.hasArg(options::OPT_A) && 1395 !Args.hasArg(options::OPT_nostdlib) && 1396 !Args.hasArg(options::OPT_nostartfiles)) { 1397 // Derived from startfile spec. 1398 if (Args.hasArg(options::OPT_dynamiclib)) { 1399 // Derived from darwin_dylib1 spec. 1400 if (isMacosxVersionLT(MacosxVersion, 10, 5)) 1401 CmdArgs.push_back("-ldylib1.o"); 1402 else if (isMacosxVersionLT(MacosxVersion, 10, 6)) 1403 CmdArgs.push_back("-ldylib1.10.5.o"); 1404 } else { 1405 if (Args.hasArg(options::OPT_bundle)) { 1406 if (!Args.hasArg(options::OPT_static)) { 1407 // Derived from darwin_bundle1 spec. 1408 if (isMacosxVersionLT(MacosxVersion, 10, 6)) 1409 CmdArgs.push_back("-lbundle1.o"); 1410 } 1411 } else { 1412 if (Args.hasArg(options::OPT_pg)) { 1413 if (Args.hasArg(options::OPT_static) || 1414 Args.hasArg(options::OPT_object) || 1415 Args.hasArg(options::OPT_preload)) { 1416 CmdArgs.push_back("-lgcrt0.o"); 1417 } else { 1418 CmdArgs.push_back("-lgcrt1.o"); 1419 1420 // darwin_crt2 spec is empty. 1421 } 1422 } else { 1423 if (Args.hasArg(options::OPT_static) || 1424 Args.hasArg(options::OPT_object) || 1425 Args.hasArg(options::OPT_preload)) { 1426 CmdArgs.push_back("-lcrt0.o"); 1427 } else { 1428 // Derived from darwin_crt1 spec. 1429 if (isMacosxVersionLT(MacosxVersion, 10, 5)) 1430 CmdArgs.push_back("-lcrt1.o"); 1431 else if (isMacosxVersionLT(MacosxVersion, 10, 6)) 1432 CmdArgs.push_back("-lcrt1.10.5.o"); 1433 else 1434 CmdArgs.push_back("-lcrt1.10.6.o"); 1435 1436 // darwin_crt2 spec is empty. 1437 } 1438 } 1439 } 1440 } 1441 1442 if (Args.hasArg(options::OPT_shared_libgcc) && 1443 !Args.hasArg(options::OPT_miphoneos_version_min_EQ) && 1444 isMacosxVersionLT(MacosxVersion, 10, 5)) { 1445 const char *Str = getToolChain().GetFilePath(C, "crt3.o").c_str(); 1446 CmdArgs.push_back(Args.MakeArgString(Str)); 1447 } 1448 } 1449 1450 Args.AddAllArgs(CmdArgs, options::OPT_L); 1451 1452 if (Args.hasArg(options::OPT_fopenmp)) 1453 // This is more complicated in gcc... 1454 CmdArgs.push_back("-lgomp"); 1455 1456 // FIXME: Derive these correctly. 1457 const char *TCDir = getDarwinToolChain().getToolChainDir().c_str(); 1458 if (getToolChain().getArchName() == "x86_64") { 1459 CmdArgs.push_back(MakeFormattedString(Args, 1460 llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir))); 1461 // Intentionally duplicated for (temporary) gcc bug compatibility. 1462 CmdArgs.push_back(MakeFormattedString(Args, 1463 llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir))); 1464 } 1465 CmdArgs.push_back(MakeFormattedString(Args, 1466 llvm::format("-L/usr/lib/%s", TCDir))); 1467 CmdArgs.push_back(MakeFormattedString(Args, 1468 llvm::format("-L/usr/lib/gcc/%s", TCDir))); 1469 // Intentionally duplicated for (temporary) gcc bug compatibility. 1470 CmdArgs.push_back(MakeFormattedString(Args, 1471 llvm::format("-L/usr/lib/gcc/%s", TCDir))); 1472 CmdArgs.push_back(MakeFormattedString(Args, 1473 llvm::format("-L/usr/lib/gcc/%s/../../../%s", TCDir, TCDir))); 1474 CmdArgs.push_back(MakeFormattedString(Args, 1475 llvm::format("-L/usr/lib/gcc/%s/../../..", TCDir))); 1476 1477 for (InputInfoList::const_iterator 1478 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1479 const InputInfo &II = *it; 1480 if (II.isFilename()) 1481 CmdArgs.push_back(II.getFilename()); 1482 else 1483 II.getInputArg().renderAsInput(Args, CmdArgs); 1484 } 1485 1486 if (LinkingOutput) { 1487 CmdArgs.push_back("-arch_multiple"); 1488 CmdArgs.push_back("-final_output"); 1489 CmdArgs.push_back(LinkingOutput); 1490 } 1491 1492 if (Args.hasArg(options::OPT_fprofile_arcs) || 1493 Args.hasArg(options::OPT_fprofile_generate) || 1494 Args.hasArg(options::OPT_fcreate_profile) || 1495 Args.hasArg(options::OPT_coverage)) 1496 CmdArgs.push_back("-lgcov"); 1497 1498 if (Args.hasArg(options::OPT_fnested_functions)) 1499 CmdArgs.push_back("-allow_stack_execute"); 1500 1501 if (!Args.hasArg(options::OPT_nostdlib) && 1502 !Args.hasArg(options::OPT_nodefaultlibs)) { 1503 // FIXME: g++ is more complicated here, it tries to put -lstdc++ 1504 // before -lm, for example. 1505 if (getToolChain().getHost().getDriver().CCCIsCXX) 1506 CmdArgs.push_back("-lstdc++"); 1507 1508 // link_ssp spec is empty. 1509 1510 // Derived from libgcc and lib specs but refactored. 1511 if (Args.hasArg(options::OPT_static)) { 1512 CmdArgs.push_back("-lgcc_static"); 1513 } else { 1514 if (Args.hasArg(options::OPT_static_libgcc)) { 1515 CmdArgs.push_back("-lgcc_eh"); 1516 } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { 1517 // Derived from darwin_iphoneos_libgcc spec. 1518 CmdArgs.push_back("-lgcc_s.10.5"); 1519 } else if (Args.hasArg(options::OPT_shared_libgcc) || 1520 Args.hasArg(options::OPT_fexceptions) || 1521 Args.hasArg(options::OPT_fgnu_runtime)) { 1522 // FIXME: This is probably broken on 10.3? 1523 if (isMacosxVersionLT(MacosxVersion, 10, 5)) 1524 CmdArgs.push_back("-lgcc_s.10.4"); 1525 else if (isMacosxVersionLT(MacosxVersion, 10, 6)) 1526 CmdArgs.push_back("-lgcc_s.10.5"); 1527 } else { 1528 if (isMacosxVersionLT(MacosxVersion, 10, 3, 9)) 1529 ; // Do nothing. 1530 else if (isMacosxVersionLT(MacosxVersion, 10, 5)) 1531 CmdArgs.push_back("-lgcc_s.10.4"); 1532 else if (isMacosxVersionLT(MacosxVersion, 10, 6)) 1533 CmdArgs.push_back("-lgcc_s.10.5"); 1534 } 1535 1536 if (isMacosxVersionLT(MacosxVersion, 10, 6)) { 1537 CmdArgs.push_back("-lgcc"); 1538 CmdArgs.push_back("-lSystem"); 1539 } else { 1540 CmdArgs.push_back("-lSystem"); 1541 CmdArgs.push_back("-lgcc"); 1542 } 1543 } 1544 } 1545 1546 if (!Args.hasArg(options::OPT_A) && 1547 !Args.hasArg(options::OPT_nostdlib) && 1548 !Args.hasArg(options::OPT_nostartfiles)) { 1549 // endfile_spec is empty. 1550 } 1551 1552 Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 1553 Args.AddAllArgs(CmdArgs, options::OPT_F); 1554 1555 const char *Exec = 1556 Args.MakeArgString(getToolChain().GetProgramPath(C, "collect2").c_str()); 1557 Dest.addCommand(new Command(Exec, CmdArgs)); 1558 1559 // Find the first non-empty base input (we want to ignore linker 1560 // inputs). 1561 const char *BaseInput = ""; 1562 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) { 1563 if (Inputs[i].getBaseInput()[0] != '\0') { 1564 BaseInput = Inputs[i].getBaseInput(); 1565 break; 1566 } 1567 } 1568 1569 if (Args.getLastArg(options::OPT_g_Group) && 1570 !Args.getLastArg(options::OPT_gstabs) && 1571 !Args.getLastArg(options::OPT_g0)) { 1572 // FIXME: This is gross, but matches gcc. The test only considers 1573 // the suffix (not the -x type), and then only of the first 1574 // source input. Awesome. 1575 const char *Suffix = strrchr(BaseInput, '.'); 1576 if (Suffix && isSourceSuffix(Suffix + 1)) { 1577 const char *Exec = 1578 Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str()); 1579 ArgStringList CmdArgs; 1580 CmdArgs.push_back(Output.getFilename()); 1581 C.getJobs().addCommand(new Command(Exec, CmdArgs)); 1582 } 1583 } 1584} 1585 1586void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 1587 Job &Dest, const InputInfo &Output, 1588 const InputInfoList &Inputs, 1589 const ArgList &Args, 1590 const char *LinkingOutput) const { 1591 ArgStringList CmdArgs; 1592 1593 CmdArgs.push_back("-create"); 1594 assert(Output.isFilename() && "Unexpected lipo output."); 1595 1596 CmdArgs.push_back("-output"); 1597 CmdArgs.push_back(Output.getFilename()); 1598 1599 for (InputInfoList::const_iterator 1600 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1601 const InputInfo &II = *it; 1602 assert(II.isFilename() && "Unexpected lipo input."); 1603 CmdArgs.push_back(II.getFilename()); 1604 } 1605 const char *Exec = 1606 Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo").c_str()); 1607 Dest.addCommand(new Command(Exec, CmdArgs)); 1608} 1609 1610 1611void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, 1612 Job &Dest, const InputInfo &Output, 1613 const InputInfoList &Inputs, 1614 const ArgList &Args, 1615 const char *LinkingOutput) const 1616{ 1617 ArgStringList CmdArgs; 1618 1619 // When building 32-bit code on FreeBSD/amd64, we have to explicitly 1620 // instruct as in the base system to assemble 32-bit code. 1621 if (getToolChain().getArchName() == "i386") 1622 CmdArgs.push_back("--32"); 1623 1624 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, 1625 options::OPT_Xassembler); 1626 1627 CmdArgs.push_back("-o"); 1628 if (Output.isPipe()) 1629 CmdArgs.push_back("-"); 1630 else 1631 CmdArgs.push_back(Output.getFilename()); 1632 1633 for (InputInfoList::const_iterator 1634 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1635 const InputInfo &II = *it; 1636 if (II.isPipe()) 1637 CmdArgs.push_back("-"); 1638 else 1639 CmdArgs.push_back(II.getFilename()); 1640 } 1641 1642 const char *Exec = 1643 Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str()); 1644 Dest.addCommand(new Command(Exec, CmdArgs)); 1645} 1646 1647void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, 1648 Job &Dest, const InputInfo &Output, 1649 const InputInfoList &Inputs, 1650 const ArgList &Args, 1651 const char *LinkingOutput) const 1652{ 1653 ArgStringList CmdArgs; 1654 1655 if (Args.hasArg(options::OPT_static)) { 1656 CmdArgs.push_back("-Bstatic"); 1657 } else { 1658 CmdArgs.push_back("--eh-frame-hdr"); 1659 if (Args.hasArg(options::OPT_shared)) { 1660 CmdArgs.push_back("-Bshareable"); 1661 } else { 1662 CmdArgs.push_back("-dynamic-linker"); 1663 CmdArgs.push_back("/libexec/ld-elf.so.1"); 1664 } 1665 } 1666 1667 // When building 32-bit code on FreeBSD/amd64, we have to explicitly 1668 // instruct ld in the base system to link 32-bit code. 1669 if (getToolChain().getArchName() == "i386") { 1670 CmdArgs.push_back("-m"); 1671 CmdArgs.push_back("elf_i386_fbsd"); 1672 } 1673 1674 if (Output.isPipe()) { 1675 CmdArgs.push_back("-o"); 1676 CmdArgs.push_back("-"); 1677 } else if (Output.isFilename()) { 1678 CmdArgs.push_back("-o"); 1679 CmdArgs.push_back(Output.getFilename()); 1680 } else { 1681 assert(Output.isNothing() && "Invalid output."); 1682 } 1683 1684 if (!Args.hasArg(options::OPT_nostdlib) && 1685 !Args.hasArg(options::OPT_nostartfiles)) { 1686 if (!Args.hasArg(options::OPT_shared)) { 1687 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o").c_str())); 1688 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o").c_str())); 1689 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str())); 1690 } else { 1691 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o").c_str())); 1692 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str())); 1693 } 1694 } 1695 1696 Args.AddAllArgs(CmdArgs, options::OPT_L); 1697 Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 1698 Args.AddAllArgs(CmdArgs, options::OPT_e); 1699 1700 for (InputInfoList::const_iterator 1701 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { 1702 const InputInfo &II = *it; 1703 if (II.isPipe()) 1704 CmdArgs.push_back("-"); 1705 else if (II.isFilename()) 1706 CmdArgs.push_back(II.getFilename()); 1707 else 1708 II.getInputArg().renderAsInput(Args, CmdArgs); 1709 } 1710 1711 if (!Args.hasArg(options::OPT_nostdlib) && 1712 !Args.hasArg(options::OPT_nodefaultlibs)) { 1713 // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding 1714 // the default system libraries. Just mimic this for now. 1715 CmdArgs.push_back("-lgcc"); 1716 if (Args.hasArg(options::OPT_static)) { 1717 CmdArgs.push_back("-lgcc_eh"); 1718 } else { 1719 CmdArgs.push_back("--as-needed"); 1720 CmdArgs.push_back("-lgcc_s"); 1721 CmdArgs.push_back("--no-as-needed"); 1722 } 1723 1724 if (Args.hasArg(options::OPT_pthread)) 1725 CmdArgs.push_back("-lpthread"); 1726 CmdArgs.push_back("-lc"); 1727 1728 CmdArgs.push_back("-lgcc"); 1729 if (Args.hasArg(options::OPT_static)) { 1730 CmdArgs.push_back("-lgcc_eh"); 1731 } else { 1732 CmdArgs.push_back("--as-needed"); 1733 CmdArgs.push_back("-lgcc_s"); 1734 CmdArgs.push_back("--no-as-needed"); 1735 } 1736 } 1737 1738 if (!Args.hasArg(options::OPT_nostdlib) && 1739 !Args.hasArg(options::OPT_nostartfiles)) { 1740 if (!Args.hasArg(options::OPT_shared)) 1741 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str())); 1742 else 1743 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str())); 1744 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o").c_str())); 1745 } 1746 1747 const char *Exec = 1748 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str()); 1749 Dest.addCommand(new Command(Exec, CmdArgs)); 1750} 1751