1 //===--- Tools.h - Tool Implementations -------------------------*- C++ -*-===// 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 #ifndef CLANG_LIB_DRIVER_TOOLS_H_ 11 #define CLANG_LIB_DRIVER_TOOLS_H_ 12 13 #include "clang/Driver/Tool.h" 14 #include "clang/Driver/Types.h" 15 #include "clang/Driver/Util.h" 16 #include "llvm/ADT/Triple.h" 17 #include "llvm/Option/Option.h" 18 #include "llvm/Support/Compiler.h" 19 20 namespace clang { 21 class ObjCRuntime; 22 23 namespace driver { 24 class Driver; 25 26 namespace toolchains { 27 class Darwin; 28 } 29 30 namespace tools { 31 using llvm::opt::ArgStringList; 32 33 /// \brief Clang compiler tool. 34 class LLVM_LIBRARY_VISIBILITY Clang : public Tool { 35 public: 36 static const char *getBaseInputName(const llvm::opt::ArgList &Args, 37 const InputInfoList &Inputs); 38 static const char *getBaseInputStem(const llvm::opt::ArgList &Args, 39 const InputInfoList &Inputs); 40 static const char *getDependencyFileName(const llvm::opt::ArgList &Args, 41 const InputInfoList &Inputs); 42 43 private: 44 void AddPreprocessingOptions(Compilation &C, const JobAction &JA, 45 const Driver &D, 46 const llvm::opt::ArgList &Args, 47 llvm::opt::ArgStringList &CmdArgs, 48 const InputInfo &Output, 49 const InputInfoList &Inputs) const; 50 51 void AddARMTargetArgs(const llvm::opt::ArgList &Args, 52 llvm::opt::ArgStringList &CmdArgs, 53 bool KernelOrKext) const; 54 void AddMIPSTargetArgs(const llvm::opt::ArgList &Args, 55 llvm::opt::ArgStringList &CmdArgs) const; 56 void AddPPCTargetArgs(const llvm::opt::ArgList &Args, 57 llvm::opt::ArgStringList &CmdArgs) const; 58 void AddR600TargetArgs(const llvm::opt::ArgList &Args, 59 llvm::opt::ArgStringList &CmdArgs) const; 60 void AddSparcTargetArgs(const llvm::opt::ArgList &Args, 61 llvm::opt::ArgStringList &CmdArgs) const; 62 void AddSystemZTargetArgs(const llvm::opt::ArgList &Args, 63 llvm::opt::ArgStringList &CmdArgs) const; 64 void AddX86TargetArgs(const llvm::opt::ArgList &Args, 65 llvm::opt::ArgStringList &CmdArgs) const; 66 void AddHexagonTargetArgs(const llvm::opt::ArgList &Args, 67 llvm::opt::ArgStringList &CmdArgs) const; 68 void AddAArch64TargetArgs(const llvm::opt::ArgList &Args, 69 llvm::opt::ArgStringList &CmdArgs) const; 70 71 enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile }; 72 73 ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args, 74 llvm::opt::ArgStringList &cmdArgs, 75 RewriteKind rewrite) const; 76 77 public: 78 Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {} 79 80 virtual bool hasGoodDiagnostics() const { return true; } 81 virtual bool hasIntegratedAssembler() const { return true; } 82 virtual bool hasIntegratedCPP() const { return true; } 83 84 virtual void ConstructJob(Compilation &C, const JobAction &JA, 85 const InputInfo &Output, 86 const InputInfoList &Inputs, 87 const llvm::opt::ArgList &TCArgs, 88 const char *LinkingOutput) const; 89 }; 90 91 /// \brief Clang integrated assembler tool. 92 class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { 93 void AddARMTargetArgs(const llvm::opt::ArgList &Args, 94 llvm::opt::ArgStringList &CmdArgs) const; 95 void AddX86TargetArgs(const llvm::opt::ArgList &Args, 96 llvm::opt::ArgStringList &CmdArgs) const; 97 98 public: 99 ClangAs(const ToolChain &TC) : Tool("clang::as", 100 "clang integrated assembler", TC) {} 101 102 virtual bool hasGoodDiagnostics() const { return true; } 103 virtual bool hasIntegratedAssembler() const { return false; } 104 virtual bool hasIntegratedCPP() const { return false; } 105 106 virtual void ConstructJob(Compilation &C, const JobAction &JA, 107 const InputInfo &Output, 108 const InputInfoList &Inputs, 109 const llvm::opt::ArgList &TCArgs, 110 const char *LinkingOutput) const; 111 }; 112 113 /// gcc - Generic GCC tool implementations. 114 namespace gcc { 115 class LLVM_LIBRARY_VISIBILITY Common : public Tool { 116 public: 117 Common(const char *Name, const char *ShortName, 118 const ToolChain &TC) : Tool(Name, ShortName, TC) {} 119 120 virtual void ConstructJob(Compilation &C, const JobAction &JA, 121 const InputInfo &Output, 122 const InputInfoList &Inputs, 123 const llvm::opt::ArgList &TCArgs, 124 const char *LinkingOutput) const; 125 126 /// RenderExtraToolArgs - Render any arguments necessary to force 127 /// the particular tool mode. 128 virtual void 129 RenderExtraToolArgs(const JobAction &JA, 130 llvm::opt::ArgStringList &CmdArgs) const = 0; 131 }; 132 133 class LLVM_LIBRARY_VISIBILITY Preprocess : public Common { 134 public: 135 Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", 136 "gcc preprocessor", TC) {} 137 138 virtual bool hasGoodDiagnostics() const { return true; } 139 virtual bool hasIntegratedCPP() const { return false; } 140 141 virtual void RenderExtraToolArgs(const JobAction &JA, 142 llvm::opt::ArgStringList &CmdArgs) const; 143 }; 144 145 class LLVM_LIBRARY_VISIBILITY Precompile : public Common { 146 public: 147 Precompile(const ToolChain &TC) : Common("gcc::Precompile", 148 "gcc precompile", TC) {} 149 150 virtual bool hasGoodDiagnostics() const { return true; } 151 virtual bool hasIntegratedCPP() const { return true; } 152 153 virtual void RenderExtraToolArgs(const JobAction &JA, 154 llvm::opt::ArgStringList &CmdArgs) const; 155 }; 156 157 class LLVM_LIBRARY_VISIBILITY Compile : public Common { 158 public: 159 Compile(const ToolChain &TC) : Common("gcc::Compile", 160 "gcc frontend", TC) {} 161 162 virtual bool hasGoodDiagnostics() const { return true; } 163 virtual bool hasIntegratedCPP() const { return true; } 164 165 virtual void RenderExtraToolArgs(const JobAction &JA, 166 llvm::opt::ArgStringList &CmdArgs) const; 167 }; 168 169 class LLVM_LIBRARY_VISIBILITY Assemble : public Common { 170 public: 171 Assemble(const ToolChain &TC) : Common("gcc::Assemble", 172 "assembler (via gcc)", TC) {} 173 174 virtual bool hasIntegratedCPP() const { return false; } 175 176 virtual void RenderExtraToolArgs(const JobAction &JA, 177 llvm::opt::ArgStringList &CmdArgs) const; 178 }; 179 180 class LLVM_LIBRARY_VISIBILITY Link : public Common { 181 public: 182 Link(const ToolChain &TC) : Common("gcc::Link", 183 "linker (via gcc)", TC) {} 184 185 virtual bool hasIntegratedCPP() const { return false; } 186 virtual bool isLinkJob() const { return true; } 187 188 virtual void RenderExtraToolArgs(const JobAction &JA, 189 llvm::opt::ArgStringList &CmdArgs) const; 190 }; 191 } // end namespace gcc 192 193 namespace hexagon { 194 // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile. 195 // We simply use "clang -cc1" for those actions. 196 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 197 public: 198 Assemble(const ToolChain &TC) : Tool("hexagon::Assemble", 199 "hexagon-as", TC) {} 200 201 virtual bool hasIntegratedCPP() const { return false; } 202 203 virtual void RenderExtraToolArgs(const JobAction &JA, 204 llvm::opt::ArgStringList &CmdArgs) const; 205 virtual void ConstructJob(Compilation &C, const JobAction &JA, 206 const InputInfo &Output, 207 const InputInfoList &Inputs, 208 const llvm::opt::ArgList &TCArgs, 209 const char *LinkingOutput) const; 210 }; 211 212 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 213 public: 214 Link(const ToolChain &TC) : Tool("hexagon::Link", 215 "hexagon-ld", TC) {} 216 217 virtual bool hasIntegratedCPP() const { return false; } 218 virtual bool isLinkJob() const { return true; } 219 220 virtual void RenderExtraToolArgs(const JobAction &JA, 221 llvm::opt::ArgStringList &CmdArgs) const; 222 virtual void ConstructJob(Compilation &C, const JobAction &JA, 223 const InputInfo &Output, 224 const InputInfoList &Inputs, 225 const llvm::opt::ArgList &TCArgs, 226 const char *LinkingOutput) const; 227 }; 228 } // end namespace hexagon. 229 230 231 namespace darwin { 232 llvm::Triple::ArchType getArchTypeForDarwinArchName(StringRef Str); 233 234 class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool { 235 virtual void anchor(); 236 protected: 237 void AddDarwinArch(const llvm::opt::ArgList &Args, 238 llvm::opt::ArgStringList &CmdArgs) const; 239 240 const toolchains::Darwin &getDarwinToolChain() const { 241 return reinterpret_cast<const toolchains::Darwin&>(getToolChain()); 242 } 243 244 public: 245 DarwinTool(const char *Name, const char *ShortName, 246 const ToolChain &TC) : Tool(Name, ShortName, TC) {} 247 }; 248 249 class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool { 250 public: 251 Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", 252 "assembler", TC) {} 253 254 virtual bool hasIntegratedCPP() const { return false; } 255 256 virtual void ConstructJob(Compilation &C, const JobAction &JA, 257 const InputInfo &Output, 258 const InputInfoList &Inputs, 259 const llvm::opt::ArgList &TCArgs, 260 const char *LinkingOutput) const; 261 }; 262 263 class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool { 264 bool NeedsTempPath(const InputInfoList &Inputs) const; 265 void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 266 llvm::opt::ArgStringList &CmdArgs, 267 const InputInfoList &Inputs) const; 268 269 public: 270 Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {} 271 272 virtual bool hasIntegratedCPP() const { return false; } 273 virtual bool isLinkJob() const { return true; } 274 275 virtual void ConstructJob(Compilation &C, const JobAction &JA, 276 const InputInfo &Output, 277 const InputInfoList &Inputs, 278 const llvm::opt::ArgList &TCArgs, 279 const char *LinkingOutput) const; 280 }; 281 282 class LLVM_LIBRARY_VISIBILITY Lipo : public DarwinTool { 283 public: 284 Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {} 285 286 virtual bool hasIntegratedCPP() const { return false; } 287 288 virtual void ConstructJob(Compilation &C, const JobAction &JA, 289 const InputInfo &Output, 290 const InputInfoList &Inputs, 291 const llvm::opt::ArgList &TCArgs, 292 const char *LinkingOutput) const; 293 }; 294 295 class LLVM_LIBRARY_VISIBILITY Dsymutil : public DarwinTool { 296 public: 297 Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil", 298 "dsymutil", TC) {} 299 300 virtual bool hasIntegratedCPP() const { return false; } 301 virtual bool isDsymutilJob() const { return true; } 302 303 virtual void ConstructJob(Compilation &C, const JobAction &JA, 304 const InputInfo &Output, 305 const InputInfoList &Inputs, 306 const llvm::opt::ArgList &TCArgs, 307 const char *LinkingOutput) const; 308 }; 309 310 class LLVM_LIBRARY_VISIBILITY VerifyDebug : public DarwinTool { 311 public: 312 VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug", 313 "dwarfdump", TC) {} 314 315 virtual bool hasIntegratedCPP() const { return false; } 316 317 virtual void ConstructJob(Compilation &C, const JobAction &JA, 318 const InputInfo &Output, 319 const InputInfoList &Inputs, 320 const llvm::opt::ArgList &TCArgs, 321 const char *LinkingOutput) const; 322 }; 323 324 } 325 326 /// openbsd -- Directly call GNU Binutils assembler and linker 327 namespace openbsd { 328 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 329 public: 330 Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler", 331 TC) {} 332 333 virtual bool hasIntegratedCPP() const { return false; } 334 335 virtual void ConstructJob(Compilation &C, const JobAction &JA, 336 const InputInfo &Output, 337 const InputInfoList &Inputs, 338 const llvm::opt::ArgList &TCArgs, 339 const char *LinkingOutput) const; 340 }; 341 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 342 public: 343 Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {} 344 345 virtual bool hasIntegratedCPP() const { return false; } 346 virtual bool isLinkJob() const { return true; } 347 348 virtual void ConstructJob(Compilation &C, const JobAction &JA, 349 const InputInfo &Output, 350 const InputInfoList &Inputs, 351 const llvm::opt::ArgList &TCArgs, 352 const char *LinkingOutput) const; 353 }; 354 } // end namespace openbsd 355 356 /// bitrig -- Directly call GNU Binutils assembler and linker 357 namespace bitrig { 358 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 359 public: 360 Assemble(const ToolChain &TC) : Tool("bitrig::Assemble", "assembler", 361 TC) {} 362 363 virtual bool hasIntegratedCPP() const { return false; } 364 365 virtual void ConstructJob(Compilation &C, const JobAction &JA, 366 const InputInfo &Output, 367 const InputInfoList &Inputs, 368 const llvm::opt::ArgList &TCArgs, 369 const char *LinkingOutput) const; 370 }; 371 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 372 public: 373 Link(const ToolChain &TC) : Tool("bitrig::Link", "linker", TC) {} 374 375 virtual bool hasIntegratedCPP() const { return false; } 376 virtual bool isLinkJob() const { return true; } 377 378 virtual void ConstructJob(Compilation &C, const JobAction &JA, 379 const InputInfo &Output, 380 const InputInfoList &Inputs, 381 const llvm::opt::ArgList &TCArgs, 382 const char *LinkingOutput) const; 383 }; 384 } // end namespace bitrig 385 386 /// freebsd -- Directly call GNU Binutils assembler and linker 387 namespace freebsd { 388 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 389 public: 390 Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler", 391 TC) {} 392 393 virtual bool hasIntegratedCPP() const { return false; } 394 395 virtual void ConstructJob(Compilation &C, const JobAction &JA, 396 const InputInfo &Output, 397 const InputInfoList &Inputs, 398 const llvm::opt::ArgList &TCArgs, 399 const char *LinkingOutput) const; 400 }; 401 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 402 public: 403 Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {} 404 405 virtual bool hasIntegratedCPP() const { return false; } 406 virtual bool isLinkJob() const { return true; } 407 408 virtual void ConstructJob(Compilation &C, const JobAction &JA, 409 const InputInfo &Output, 410 const InputInfoList &Inputs, 411 const llvm::opt::ArgList &TCArgs, 412 const char *LinkingOutput) const; 413 }; 414 } // end namespace freebsd 415 416 /// netbsd -- Directly call GNU Binutils assembler and linker 417 namespace netbsd { 418 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 419 420 public: 421 Assemble(const ToolChain &TC) 422 : Tool("netbsd::Assemble", "assembler", TC) {} 423 424 virtual bool hasIntegratedCPP() const { return false; } 425 426 virtual void ConstructJob(Compilation &C, const JobAction &JA, 427 const InputInfo &Output, 428 const InputInfoList &Inputs, 429 const llvm::opt::ArgList &TCArgs, 430 const char *LinkingOutput) const; 431 }; 432 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 433 434 public: 435 Link(const ToolChain &TC) 436 : Tool("netbsd::Link", "linker", TC) {} 437 438 virtual bool hasIntegratedCPP() const { return false; } 439 virtual bool isLinkJob() const { return true; } 440 441 virtual void ConstructJob(Compilation &C, const JobAction &JA, 442 const InputInfo &Output, 443 const InputInfoList &Inputs, 444 const llvm::opt::ArgList &TCArgs, 445 const char *LinkingOutput) const; 446 }; 447 } // end namespace netbsd 448 449 /// Directly call GNU Binutils' assembler and linker. 450 namespace gnutools { 451 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 452 public: 453 Assemble(const ToolChain &TC) : Tool("GNU::Assemble", "assembler", TC) {} 454 455 virtual bool hasIntegratedCPP() const { return false; } 456 457 virtual void ConstructJob(Compilation &C, const JobAction &JA, 458 const InputInfo &Output, 459 const InputInfoList &Inputs, 460 const llvm::opt::ArgList &TCArgs, 461 const char *LinkingOutput) const; 462 }; 463 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 464 public: 465 Link(const ToolChain &TC) : Tool("GNU::Link", "linker", TC) {} 466 467 virtual bool hasIntegratedCPP() const { return false; } 468 virtual bool isLinkJob() const { return true; } 469 470 virtual void ConstructJob(Compilation &C, const JobAction &JA, 471 const InputInfo &Output, 472 const InputInfoList &Inputs, 473 const llvm::opt::ArgList &TCArgs, 474 const char *LinkingOutput) const; 475 }; 476 } 477 /// minix -- Directly call GNU Binutils assembler and linker 478 namespace minix { 479 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 480 public: 481 Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler", 482 TC) {} 483 484 virtual bool hasIntegratedCPP() const { return false; } 485 486 virtual void ConstructJob(Compilation &C, const JobAction &JA, 487 const InputInfo &Output, 488 const InputInfoList &Inputs, 489 const llvm::opt::ArgList &TCArgs, 490 const char *LinkingOutput) const; 491 }; 492 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 493 public: 494 Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {} 495 496 virtual bool hasIntegratedCPP() const { return false; } 497 virtual bool isLinkJob() const { return true; } 498 499 virtual void ConstructJob(Compilation &C, const JobAction &JA, 500 const InputInfo &Output, 501 const InputInfoList &Inputs, 502 const llvm::opt::ArgList &TCArgs, 503 const char *LinkingOutput) const; 504 }; 505 } // end namespace minix 506 507 /// solaris -- Directly call Solaris assembler and linker 508 namespace solaris { 509 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 510 public: 511 Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler", 512 TC) {} 513 514 virtual bool hasIntegratedCPP() const { return false; } 515 516 virtual void ConstructJob(Compilation &C, const JobAction &JA, 517 const InputInfo &Output, 518 const InputInfoList &Inputs, 519 const llvm::opt::ArgList &TCArgs, 520 const char *LinkingOutput) const; 521 }; 522 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 523 public: 524 Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {} 525 526 virtual bool hasIntegratedCPP() const { return false; } 527 virtual bool isLinkJob() const { return true; } 528 529 virtual void ConstructJob(Compilation &C, const JobAction &JA, 530 const InputInfo &Output, 531 const InputInfoList &Inputs, 532 const llvm::opt::ArgList &TCArgs, 533 const char *LinkingOutput) const; 534 }; 535 } // end namespace solaris 536 537 /// auroraux -- Directly call GNU Binutils assembler and linker 538 namespace auroraux { 539 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 540 public: 541 Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler", 542 TC) {} 543 544 virtual bool hasIntegratedCPP() const { return false; } 545 546 virtual void ConstructJob(Compilation &C, const JobAction &JA, 547 const InputInfo &Output, 548 const InputInfoList &Inputs, 549 const llvm::opt::ArgList &TCArgs, 550 const char *LinkingOutput) const; 551 }; 552 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 553 public: 554 Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {} 555 556 virtual bool hasIntegratedCPP() const { return false; } 557 virtual bool isLinkJob() const { return true; } 558 559 virtual void ConstructJob(Compilation &C, const JobAction &JA, 560 const InputInfo &Output, 561 const InputInfoList &Inputs, 562 const llvm::opt::ArgList &TCArgs, 563 const char *LinkingOutput) const; 564 }; 565 } // end namespace auroraux 566 567 /// dragonfly -- Directly call GNU Binutils assembler and linker 568 namespace dragonfly { 569 class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { 570 public: 571 Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler", 572 TC) {} 573 574 virtual bool hasIntegratedCPP() const { return false; } 575 576 virtual void ConstructJob(Compilation &C, const JobAction &JA, 577 const InputInfo &Output, 578 const InputInfoList &Inputs, 579 const llvm::opt::ArgList &TCArgs, 580 const char *LinkingOutput) const; 581 }; 582 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 583 public: 584 Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {} 585 586 virtual bool hasIntegratedCPP() const { return false; } 587 virtual bool isLinkJob() const { return true; } 588 589 virtual void ConstructJob(Compilation &C, const JobAction &JA, 590 const InputInfo &Output, 591 const InputInfoList &Inputs, 592 const llvm::opt::ArgList &TCArgs, 593 const char *LinkingOutput) const; 594 }; 595 } // end namespace dragonfly 596 597 /// Visual studio tools. 598 namespace visualstudio { 599 class LLVM_LIBRARY_VISIBILITY Link : public Tool { 600 public: 601 Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {} 602 603 virtual bool hasIntegratedCPP() const { return false; } 604 virtual bool isLinkJob() const { return true; } 605 606 virtual void ConstructJob(Compilation &C, const JobAction &JA, 607 const InputInfo &Output, 608 const InputInfoList &Inputs, 609 const llvm::opt::ArgList &TCArgs, 610 const char *LinkingOutput) const; 611 }; 612 } // end namespace visualstudio 613 614 } // end namespace toolchains 615 } // end namespace driver 616 } // end namespace clang 617 618 #endif // CLANG_LIB_DRIVER_TOOLS_H_ 619