zcov: / lib/Driver/Tools.cpp


Files: 1 Branches Taken: 60.2% 756 / 1255
Generated: 2010-02-10 01:31 Branches Executed: 87.4% 1097 / 1255
Line Coverage: 77.5% 1103 / 1424


Programs: 2 Runs 3018


       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"
      16                 : #include "clang/Driver/DriverDiagnostic.h"
      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/Options.h"
      22                 : #include "clang/Driver/ToolChain.h"
      23                 : #include "clang/Driver/Util.h"
      24                 : 
      25                 : #include "llvm/ADT/SmallString.h"
      26                 : #include "llvm/ADT/StringSwitch.h"
      27                 : #include "llvm/ADT/Twine.h"
      28                 : #include "llvm/Support/Format.h"
      29                 : #include "llvm/Support/raw_ostream.h"
      30                 : #include "llvm/System/Host.h"
      31                 : #include "llvm/System/Process.h"
      32                 : 
      33                 : #include "InputInfo.h"
      34                 : #include "ToolChains.h"
      35                 : 
      36                 : using namespace clang::driver;
      37                 : using namespace clang::driver::tools;
      38                 : 
      39                 : /// CheckPreprocessingOptions - Perform some validation of preprocessing
      40                 : /// arguments that is shared with gcc.
      41              185: static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
                        3: branch 3 taken
                      182: branch 4 taken
      42              185:   if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
                        0: branch 2 not taken
                        3: branch 3 taken
      43                3:     if (!Args.hasArg(options::OPT_E))
      44                 :       D.Diag(clang::diag::err_drv_argument_only_allowed_with)
      45                0:         << A->getAsString(Args) << "-E";
      46              185: }
      47                 : 
      48                 : /// CheckCodeGenerationOptions - Perform some validation of code generation
      49                 : /// arguments that is shared with gcc.
      50              191: static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
      51                 :   // In gcc, only ARM checks this, but it seems reasonable to check universally.
                        3: branch 2 taken
                      188: branch 3 taken
      52              191:   if (Args.hasArg(options::OPT_static))
                        0: branch 0 not taken
                        3: branch 1 taken
      53                3:     if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
      54                3:                                        options::OPT_mdynamic_no_pic))
      55                 :       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
      56                0:         << A->getAsString(Args) << "-static";
      57              191: }
      58                 : 
      59                 : void Clang::AddPreprocessingOptions(const Driver &D,
      60                 :                                     const ArgList &Args,
      61                 :                                     ArgStringList &CmdArgs,
      62                 :                                     const InputInfo &Output,
      63              183:                                     const InputInfoList &Inputs) const {
      64                 :   Arg *A;
      65                 : 
      66              183:   CheckPreprocessingOptions(D, Args);
      67                 : 
      68              183:   Args.AddLastArg(CmdArgs, options::OPT_C);
      69              183:   Args.AddLastArg(CmdArgs, options::OPT_CC);
      70                 : 
      71                 :   // Handle dependency file generation.
                      182: branch 2 taken
                        1: branch 3 taken
                      182: branch 6 taken
                        0: branch 7 not taken
                      180: branch 10 taken
                        2: branch 11 taken
                        0: branch 14 not taken
                      180: branch 15 taken
                        3: branch 16 taken
                      180: branch 17 taken
      72              183:   if ((A = Args.getLastArg(options::OPT_M)) ||
      73                 :       (A = Args.getLastArg(options::OPT_MM)) ||
      74                 :       (A = Args.getLastArg(options::OPT_MD)) ||
      75                 :       (A = Args.getLastArg(options::OPT_MMD))) {
      76                 :     // Determine the output location.
      77                 :     const char *DepFile;
                        1: branch 1 taken
                        2: branch 2 taken
      78                3:     if (Output.getType() == types::TY_Dependencies) {
                        0: branch 1 not taken
                        1: branch 2 taken
      79                1:       if (Output.isPipe())
      80                0:         DepFile = "-";
      81                 :       else
      82                1:         DepFile = Output.getFilename();
                        2: branch 2 taken
                        0: branch 3 not taken
      83                2:     } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
      84                2:       DepFile = MF->getValue(Args);
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
      85                0:     } else if (A->getOption().matches(options::OPT_M) ||
      86                 :                A->getOption().matches(options::OPT_MM)) {
      87                0:       DepFile = "-";
      88                 :     } else {
      89                0:       DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
      90                 :     }
      91                3:     CmdArgs.push_back("-dependency-file");
      92                3:     CmdArgs.push_back(DepFile);
      93                 : 
      94                 :     // Add an -MT option if the user didn't specify their own.
      95                 :     //
      96                 :     // FIXME: This should use -MQ, when we support it.
                        2: branch 2 taken
                        1: branch 3 taken
                        2: branch 6 taken
                        0: branch 7 not taken
                        2: branch 8 taken
                        1: branch 9 taken
      97                3:     if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
      98                 :       const char *DepTarget;
      99                 : 
     100                 :       // If user provided -o, that is the dependency target, except
     101                 :       // when we are only generating a dependency file.
     102                2:       Arg *OutputOpt = Args.getLastArg(options::OPT_o);
                        2: branch 0 taken
                        0: branch 1 not taken
                        1: branch 3 taken
                        1: branch 4 taken
                        1: branch 5 taken
                        1: branch 6 taken
     103                2:       if (OutputOpt && Output.getType() != types::TY_Dependencies) {
     104                1:         DepTarget = OutputOpt->getValue(Args);
     105                 :       } else {
     106                 :         // Otherwise derive from the base input.
     107                 :         //
     108                 :         // FIXME: This should use the computed output file location.
     109                1:         llvm::sys::Path P(Inputs[0].getBaseInput());
     110                 : 
     111                1:         P.eraseSuffix();
     112                1:         P.appendSuffix("o");
     113                1:         DepTarget = Args.MakeArgString(P.getLast());
     114                 :       }
     115                 : 
     116                2:       CmdArgs.push_back("-MT");
     117                2:       CmdArgs.push_back(DepTarget);
     118                 :     }
     119                 : 
                        2: branch 3 taken
                        1: branch 4 taken
                        2: branch 8 taken
                        0: branch 9 not taken
                        3: branch 10 taken
                        0: branch 11 not taken
     120                3:     if (A->getOption().matches(options::OPT_M) ||
     121                 :         A->getOption().matches(options::OPT_MD))
     122                3:       CmdArgs.push_back("-sys-header-deps");
     123                 :   }
     124                 : 
     125              183:   Args.AddLastArg(CmdArgs, options::OPT_MP);
     126              183:   Args.AddAllArgs(CmdArgs, options::OPT_MT);
     127                 : 
     128                 :   // Add -i* options, and automatically translate to
     129                 :   // -include-pch/-include-pth for transparent PCH support. It's
     130                 :   // wonky, but we include looking for .gch so we can support seamless
     131                 :   // replacement into a build system already set up to be generating
     132                 :   // .gch files.
                        6: branch 6 taken
                      183: branch 7 taken
     133              372:   for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
     134              183:          ie = Args.filtered_end(); it != ie; ++it) {
     135                6:     const Arg *A = it;
     136                 : 
                        6: branch 3 taken
                        0: branch 4 not taken
     137                6:     if (A->getOption().matches(options::OPT_include)) {
     138                 :       // Use PCH if the user requested it, except for C++ (for now).
     139                6:       bool UsePCH = D.CCCUsePCH;
                        1: branch 3 taken
                        5: branch 4 taken
     140                6:       if (types::isCXX(Inputs[0].getType()))
     141                1:         UsePCH = false;
     142                 : 
     143                6:       bool FoundPTH = false;
     144                6:       bool FoundPCH = false;
     145                6:       llvm::sys::Path P(A->getValue(Args));
                        4: branch 0 taken
                        2: branch 1 taken
     146                6:       if (UsePCH) {
     147                4:         P.appendSuffix("pch");
                        1: branch 1 taken
                        3: branch 2 taken
     148                4:         if (P.exists())
     149                1:           FoundPCH = true;
     150                 :         else
     151                3:           P.eraseSuffix();
     152                 :       }
     153                 : 
                        5: branch 0 taken
                        1: branch 1 taken
     154                6:       if (!FoundPCH) {
     155                5:         P.appendSuffix("pth");
                        1: branch 1 taken
                        4: branch 2 taken
     156                5:         if (P.exists())
     157                1:           FoundPTH = true;
     158                 :         else
     159                4:           P.eraseSuffix();
     160                 :       }
     161                 : 
                        5: branch 0 taken
                        1: branch 1 taken
                        4: branch 2 taken
                        1: branch 3 taken
     162                6:       if (!FoundPCH && !FoundPTH) {
     163                4:         P.appendSuffix("gch");
                        2: branch 1 taken
                        2: branch 2 taken
     164                4:         if (P.exists()) {
     165                2:           FoundPCH = UsePCH;
     166                2:           FoundPTH = !UsePCH;
     167                 :         }
     168                 :         else
     169                2:           P.eraseSuffix();
     170                 :       }
     171                 : 
                        4: branch 0 taken
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
     172                6:       if (FoundPCH || FoundPTH) {
     173                4:         A->claim();
                        2: branch 0 taken
                        2: branch 1 taken
     174                4:         if (UsePCH)
     175                2:           CmdArgs.push_back("-include-pch");
     176                 :         else
     177                2:           CmdArgs.push_back("-include-pth");
     178                4:         CmdArgs.push_back(Args.MakeArgString(P.str()));
     179                4:         continue;
                        2: branch 1 taken
                        4: branch 2 taken
     180                6:       }
     181                 :     }
     182                 : 
     183                 :     // Not translated, render as usual.
     184                2:     A->claim();
     185                2:     A->render(Args, CmdArgs);
     186                 :   }
     187                 : 
     188              183:   Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
     189              183:   Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
     190                 : 
     191                 :   // Add -Wp, and -Xassembler if using the preprocessor.
     192                 : 
     193                 :   // FIXME: There is a very unfortunate problem here, some troubled
     194                 :   // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
     195                 :   // really support that we would have to parse and then translate
     196                 :   // those options. :(
     197                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
     198              183:                        options::OPT_Xpreprocessor);
     199                 : 
     200                 :   // -I- is a deprecated GCC feature, reject it.
                        0: branch 2 not taken
                      183: branch 3 taken
     201              183:   if (Arg *A = Args.getLastArg(options::OPT_I_))
     202                0:     D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
     203              183: }
     204                 : 
     205                 : /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
     206                 : //
     207                 : // FIXME: tblgen this.
     208               19: static const char *getARMTargetCPU(const ArgList &Args) {
     209                 :   // FIXME: Warn on inconsistent use of -mcpu and -march.
     210                 : 
     211                 :   // If we have -mcpu=, use that.
                        0: branch 2 not taken
                       19: branch 3 taken
     212               19:   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
     213                0:     return A->getValue(Args);
     214                 : 
     215                 :   // Otherwise, if we have -march= choose the base CPU for that arch.
                       10: branch 2 taken
                        9: branch 3 taken
     216               19:   if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
     217               10:     llvm::StringRef MArch = A->getValue(Args);
     218                 : 
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     219               10:     if (MArch == "armv2" || MArch == "armv2a")
     220                0:       return "arm2";
                        0: branch 2 not taken
                       10: branch 3 taken
     221               10:     if (MArch == "armv3")
     222                0:       return "arm6";
                        0: branch 2 not taken
                       10: branch 3 taken
     223               10:     if (MArch == "armv3m")
     224                0:       return "arm7m";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     225               10:     if (MArch == "armv4" || MArch == "armv4t")
     226                0:       return "arm7tdmi";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     227               10:     if (MArch == "armv5" || MArch == "armv5t")
     228                0:       return "arm10tdmi";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     229               10:     if (MArch == "armv5e" || MArch == "armv5te")
     230                0:       return "arm1026ejs";
                        0: branch 2 not taken
                       10: branch 3 taken
     231               10:     if (MArch == "armv5tej")
     232                0:       return "arm926ej-s";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     233               10:     if (MArch == "armv6" || MArch == "armv6k")
     234                0:       return "arm1136jf-s";
                        0: branch 2 not taken
                       10: branch 3 taken
     235               10:     if (MArch == "armv6j")
     236                0:       return "arm1136j-s";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 8 not taken
                       10: branch 9 taken
     237               10:     if (MArch == "armv6z" || MArch == "armv6zk")
     238                0:       return "arm1176jzf-s";
                        0: branch 2 not taken
                       10: branch 3 taken
     239               10:     if (MArch == "armv6t2")
     240                0:       return "arm1156t2-s";
                       10: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       10: branch 7 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                       10: branch 12 taken
                        0: branch 13 not taken
     241               10:     if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
     242               10:       return "cortex-a8";
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
     243                0:     if (MArch == "armv7r" || MArch == "armv7-r")
     244                0:       return "cortex-r4";
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
     245                0:     if (MArch == "armv7m" || MArch == "armv7-m")
     246                0:       return "cortex-m3";
                        0: branch 2 not taken
                        0: branch 3 not taken
     247                0:     if (MArch == "ep9312")
     248                0:       return "ep9312";
                        0: branch 2 not taken
                        0: branch 3 not taken
     249                0:     if (MArch == "iwmmxt")
     250                0:       return "iwmmxt";
                        0: branch 2 not taken
                        0: branch 3 not taken
     251                0:     if (MArch == "xscale")
     252                0:       return "xscale";
     253                 :   }
     254                 : 
     255                 :   // Otherwise return the most base CPU LLVM supports.
     256                9:   return "arm7tdmi";
     257                 : }
     258                 : 
     259                 : /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
     260                 : /// CPU.
     261                 : //
     262                 : // FIXME: This is redundant with -mcpu, why does LLVM use this.
     263                 : // FIXME: tblgen this, or kill it!
     264               12: static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
                        6: branch 2 taken
                        6: branch 3 taken
                        6: branch 6 taken
                        0: branch 7 not taken
                        6: branch 10 taken
                        0: branch 11 not taken
                        6: branch 14 taken
                        0: branch 15 not taken
                        6: branch 18 taken
                        0: branch 19 not taken
                        6: branch 22 taken
                        0: branch 23 not taken
                        6: branch 26 taken
                        0: branch 27 not taken
                        6: branch 30 taken
                        0: branch 31 not taken
                        6: branch 34 taken
                        0: branch 35 not taken
                        6: branch 38 taken
                        0: branch 39 not taken
                        0: branch 42 not taken
                        6: branch 43 taken
                        6: branch 44 taken
                        6: branch 45 taken
     265               12:   if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" ||
     266                 :       CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" ||
     267                 :       CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" ||
     268                 :       CPU == "arm940t" || CPU == "ep9312")
     269                6:     return "v4t";
     270                 : 
                        6: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        6: branch 7 taken
                        0: branch 8 not taken
                        6: branch 9 taken
     271                6:   if (CPU == "arm10tdmi" || CPU == "arm1020t")
     272                0:     return "v5";
     273                 : 
                        6: branch 2 taken
                        0: branch 3 not taken
                        6: branch 6 taken
                        0: branch 7 not taken
                        6: branch 10 taken
                        0: branch 11 not taken
                        6: branch 14 taken
                        0: branch 15 not taken
                        6: branch 18 taken
                        0: branch 19 not taken
                        6: branch 22 taken
                        0: branch 23 not taken
                        6: branch 26 taken
                        0: branch 27 not taken
                        6: branch 30 taken
                        0: branch 31 not taken
                        6: branch 34 taken
                        0: branch 35 not taken
                        0: branch 38 not taken
                        6: branch 39 taken
                        0: branch 40 not taken
                        6: branch 41 taken
     274                6:   if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" ||
     275                 :       CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" ||
     276                 :       CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" ||
     277                 :       CPU == "iwmmxt")
     278                0:     return "v5e";
     279                 : 
                        6: branch 2 taken
                        0: branch 3 not taken
                        6: branch 6 taken
                        0: branch 7 not taken
                        6: branch 10 taken
                        0: branch 11 not taken
                        6: branch 14 taken
                        0: branch 15 not taken
                        6: branch 18 taken
                        0: branch 19 not taken
                        0: branch 22 not taken
                        6: branch 23 taken
                        0: branch 24 not taken
                        6: branch 25 taken
     280                6:   if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
     281                 :       CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
     282                0:     return "v6";
     283                 : 
                        6: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        6: branch 7 taken
                        0: branch 8 not taken
                        6: branch 9 taken
     284                6:   if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
     285                0:     return "v6t2";
     286                 : 
                        0: branch 2 not taken
                        6: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        6: branch 8 taken
                        0: branch 9 not taken
     287                6:   if (CPU == "cortex-a8" || CPU == "cortex-a9")
     288                6:     return "v7";
     289                 : 
     290                0:   return "";
     291                 : }
     292                 : 
     293                 : /// getLLVMTriple - Get the LLVM triple to use for a particular toolchain, which
     294                 : /// may depend on command line arguments.
     295              188: static std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) {
                      181: branch 2 taken
                        7: branch 3 taken
     296              188:   switch (TC.getTriple().getArch()) {
     297                 :   default:
     298              181:     return TC.getTripleString();
     299                 : 
     300                 :   case llvm::Triple::arm:
     301                 :   case llvm::Triple::thumb: {
     302                 :     // FIXME: Factor into subclasses.
     303                7:     llvm::Triple Triple = TC.getTriple();
     304                 : 
     305                 :     // Thumb2 is the default for V7 on Darwin.
     306                 :     //
     307                 :     // FIXME: Thumb should just be another -target-feaure, not in the triple.
     308                7:     llvm::StringRef Suffix = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
     309                 :     bool ThumbDefault =
                        4: branch 2 taken
                        3: branch 3 taken
                        4: branch 6 taken
                        0: branch 7 not taken
     310                7:       (Suffix == "v7" && TC.getTriple().getOS() == llvm::Triple::Darwin);
     311                7:     std::string ArchName = "arm";
                        4: branch 3 taken
                        3: branch 4 taken
     312                7:     if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
     313                4:       ArchName = "thumb";
     314                7:     Triple.setArchName(ArchName + Suffix.str());
     315                 : 
     316                7:     return Triple.getTriple();
     317                 :   }
     318                 :   }
     319                 : }
     320                 : 
     321                 : // FIXME: Move to target hook.
     322              188: static bool isSignedCharDefault(const llvm::Triple &Triple) {
                      187: branch 1 taken
                        1: branch 2 taken
                        0: branch 3 not taken
     323              188:   switch (Triple.getArch()) {
     324                 :   default:
     325              187:     return true;
     326                 : 
     327                 :   case llvm::Triple::ppc:
     328                 :   case llvm::Triple::ppc64:
                        0: branch 1 not taken
                        1: branch 2 taken
     329                1:     if (Triple.getOS() == llvm::Triple::Darwin)
     330                0:       return true;
     331                1:     return false;
     332                 : 
     333                 :   case llvm::Triple::systemz:
     334                0:     return false;
     335                 :   }
     336                 : }
     337                 : 
     338                 : void Clang::AddARMTargetArgs(const ArgList &Args,
     339                7:                              ArgStringList &CmdArgs) const {
     340                7:   const Driver &D = getToolChain().getDriver();
     341                 : 
     342                 :   // Select the ABI to use.
     343                 :   //
     344                 :   // FIXME: Support -meabi.
     345                7:   const char *ABIName = 0;
                        0: branch 2 not taken
                        7: branch 3 taken
     346                7:   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
     347                0:     ABIName = A->getValue(Args);
     348                 :   } else {
     349                 :     // Select the default based on the platform.
                        0: branch 3 not taken
                        7: branch 4 taken
                        0: branch 5 not taken
     350                7:     switch (getToolChain().getTriple().getOS()) {
     351                 :       // FIXME: Is this right for non-Darwin and non-Linux?
     352                 :     default:
     353                0:       ABIName = "aapcs";
     354                0:       break;
     355                 : 
     356                 :     case llvm::Triple::Darwin:
     357                7:       ABIName = "apcs-gnu";
     358                7:       break;
     359                 : 
     360                 :     case llvm::Triple::Linux:
     361                0:       ABIName = "aapcs-linux";
     362                 :       break;
     363                 :     }
     364                 :   }
     365                7:   CmdArgs.push_back("-target-abi");
     366                7:   CmdArgs.push_back(ABIName);
     367                 : 
     368                 :   // Set the CPU based on -march= and -mcpu=.
     369                7:   CmdArgs.push_back("-target-cpu");
     370                7:   CmdArgs.push_back(getARMTargetCPU(Args));
     371                 : 
     372                 :   // Select the float ABI as determined by -msoft-float, -mhard-float, and
     373                 :   // -mfloat-abi=.
     374                7:   llvm::StringRef FloatABI;
                        2: branch 0 taken
                        5: branch 1 taken
     375                7:   if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
     376                 :                                options::OPT_mhard_float,
     377                7:                                options::OPT_mfloat_abi_EQ)) {
                        1: branch 3 taken
                        1: branch 4 taken
     378                2:     if (A->getOption().matches(options::OPT_msoft_float))
     379                1:       FloatABI = "soft";
                        1: branch 3 taken
                        0: branch 4 not taken
     380                1:     else if (A->getOption().matches(options::OPT_mhard_float))
     381                1:       FloatABI = "hard";
     382                 :     else {
     383                0:       FloatABI = A->getValue(Args);
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
     384                0:       if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
     385                 :         D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
     386                0:           << A->getAsString(Args);
     387                0:         FloatABI = "soft";
     388                 :       }
     389                 :     }
     390                 :   }
     391                 : 
     392                 :   // If unspecified, choose the default based on the platform.
                        5: branch 1 taken
                        2: branch 2 taken
     393                7:   if (FloatABI.empty()) {
     394                 :     // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for
     395                 :     // distinguishing things like linux-eabi vs linux-elf.
                        5: branch 3 taken
                        0: branch 4 not taken
     396                5:     switch (getToolChain().getTriple().getOS()) {
     397                 :     case llvm::Triple::Darwin: {
     398                 :       // Darwin defaults to "softfp" for v6 and v7.
     399                 :       //
     400                 :       // FIXME: Factor out an ARM class so we can cache the arch somewhere.
     401                5:       llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
                        5: branch 2 taken
                        0: branch 3 not taken
                        2: branch 6 taken
                        3: branch 7 taken
                        2: branch 8 taken
                        3: branch 9 taken
     402                5:       if (ArchName.startswith("v6") || ArchName.startswith("v7"))
     403                2:         FloatABI = "softfp";
     404                 :       else
     405                3:         FloatABI = "soft";
     406                5:       break;
     407                 :     }
     408                 : 
     409                 :     default:
     410                 :       // Assume "soft", but warn the user we are guessing.
     411                0:       FloatABI = "soft";
     412                0:       D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
     413                 :       break;
     414                 :     }
     415                 :   }
     416                 : 
                        4: branch 2 taken
                        3: branch 3 taken
     417                7:   if (FloatABI == "soft") {
     418                 :     // Floating point operations and argument passing are soft.
     419                 :     //
     420                 :     // FIXME: This changes CPP defines, we need -target-soft-float.
     421                4:     CmdArgs.push_back("-msoft-float");
     422                4:     CmdArgs.push_back("-mfloat-abi");
     423                4:     CmdArgs.push_back("soft");
                        2: branch 2 taken
                        1: branch 3 taken
     424                3:   } else if (FloatABI == "softfp") {
     425                 :     // Floating point operations are hard, but argument passing is soft.
     426                2:     CmdArgs.push_back("-mfloat-abi");
     427                2:     CmdArgs.push_back("soft");
     428                 :   } else {
     429                 :     // Floating point operations and argument passing are hard.
                        1: branch 2 taken
                        0: branch 3 not taken
     430                1:     assert(FloatABI == "hard" && "Invalid float abi!");
     431                1:     CmdArgs.push_back("-mfloat-abi");
     432                1:     CmdArgs.push_back("hard");
     433                 :   }
     434                 : 
     435                 :   // Set appropriate target features for floating point mode.
     436                 :   //
     437                 :   // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
     438                 :   // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
     439                 :   // stripped out by the ARM target.
     440                 : 
     441                 :   // Use software floating point operations?
                        4: branch 2 taken
                        3: branch 3 taken
     442                7:   if (FloatABI == "soft") {
     443                4:     CmdArgs.push_back("-target-feature");
     444                4:     CmdArgs.push_back("+soft-float");
     445                 :   }
     446                 : 
     447                 :   // Use software floating point argument passing?
                        6: branch 2 taken
                        1: branch 3 taken
     448                7:   if (FloatABI != "hard") {
     449                6:     CmdArgs.push_back("-target-feature");
     450                6:     CmdArgs.push_back("+soft-float-abi");
     451                 :   }
     452                 : 
     453                 :   // Honor -mfpu=.
     454                 :   //
     455                 :   // FIXME: Centralize feature selection, defaulting shouldn't be also in the
     456                 :   // frontend target.
                        0: branch 2 not taken
                        7: branch 3 taken
     457                7:   if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
     458                0:     llvm::StringRef FPU = A->getValue(Args);
     459                 : 
     460                 :     // Set the target features based on the FPU.
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 14 not taken
                        0: branch 15 not taken
                        0: branch 16 not taken
                        0: branch 17 not taken
     461                0:     if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
     462                 :       // Disable any default FPU support.
     463                0:       CmdArgs.push_back("-target-feature");
     464                0:       CmdArgs.push_back("-vfp2");
     465                0:       CmdArgs.push_back("-target-feature");
     466                0:       CmdArgs.push_back("-vfp3");
     467                0:       CmdArgs.push_back("-target-feature");
     468                0:       CmdArgs.push_back("-neon");
                        0: branch 2 not taken
                        0: branch 3 not taken
     469                0:     } else if (FPU == "vfp") {
     470                0:       CmdArgs.push_back("-target-feature");
     471                0:       CmdArgs.push_back("+vfp2");
                        0: branch 2 not taken
                        0: branch 3 not taken
     472                0:     } else if (FPU == "vfp3") {
     473                0:       CmdArgs.push_back("-target-feature");
     474                0:       CmdArgs.push_back("+vfp3");
                        0: branch 2 not taken
                        0: branch 3 not taken
     475                0:     } else if (FPU == "neon") {
     476                0:       CmdArgs.push_back("-target-feature");
     477                0:       CmdArgs.push_back("+neon");
     478                 :     } else
     479                0:       D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
     480                 :   }
     481                7: }
     482                 : 
     483                 : void Clang::AddX86TargetArgs(const ArgList &Args,
     484              180:                              ArgStringList &CmdArgs) const {
                      179: branch 3 taken
                        1: branch 4 taken
                      179: branch 7 taken
                        0: branch 8 not taken
                        0: branch 11 not taken
                      179: branch 12 taken
                        1: branch 13 taken
                      179: branch 14 taken
     485              180:   if (!Args.hasFlag(options::OPT_mred_zone,
     486                 :                     options::OPT_mno_red_zone,
     487                 :                     true) ||
     488                 :       Args.hasArg(options::OPT_mkernel) ||
     489                 :       Args.hasArg(options::OPT_fapple_kext))
     490                1:     CmdArgs.push_back("-disable-red-zone");
     491                 : 
                        2: branch 3 taken
                      178: branch 4 taken
     492              180:   if (Args.hasFlag(options::OPT_msoft_float,
     493                 :                    options::OPT_mno_soft_float,
     494                 :                    false))
     495                2:     CmdArgs.push_back("-no-implicit-float");
     496                 : 
     497              180:   const char *CPUName = 0;
                        3: branch 2 taken
                      177: branch 3 taken
     498              180:   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
                        0: branch 4 not taken
                        3: branch 5 taken
     499                3:     if (llvm::StringRef(A->getValue(Args)) == "native") {
     500                 :       // FIXME: Reject attempts to use -march=native unless the target matches
     501                 :       // the host.
     502                 :       //
     503                 :       // FIXME: We should also incorporate the detected target features for use
     504                 :       // with -native.
     505                0:       std::string CPU = llvm::sys::getHostCPUName();
                        0: branch 1 not taken
                        0: branch 2 not taken
     506                0:       if (!CPU.empty())
     507                0:         CPUName = Args.MakeArgString(CPU);
     508                 :     } else
     509                3:       CPUName = A->getValue(Args);
     510                 :   }
     511                 : 
     512                 :   // Select the default CPU if none was given (or detection failed).
                      177: branch 0 taken
                        3: branch 1 taken
     513              180:   if (!CPUName) {
     514                 :     // FIXME: Need target hooks.
                       27: branch 4 taken
                      150: branch 5 taken
     515              177:     if (getToolChain().getOS().startswith("darwin")) {
                        5: branch 4 taken
                       22: branch 5 taken
     516               27:       if (getToolChain().getArchName() == "x86_64")
     517                5:         CPUName = "core2";
                       22: branch 4 taken
                        0: branch 5 not taken
     518               22:       else if (getToolChain().getArchName() == "i386")
     519               22:         CPUName = "yonah";
     520                 :     } else {
                        1: branch 4 taken
                      149: branch 5 taken
     521              150:       if (getToolChain().getArchName() == "x86_64")
     522                1:         CPUName = "x86-64";
                      147: branch 4 taken
                        2: branch 5 taken
     523              149:       else if (getToolChain().getArchName() == "i386")
     524              147:         CPUName = "pentium4";
     525                 :     }
     526                 :   }
     527                 : 
                      178: branch 0 taken
                        2: branch 1 taken
     528              180:   if (CPUName) {
     529              178:     CmdArgs.push_back("-target-cpu");
     530              178:     CmdArgs.push_back(CPUName);
     531                 :   }
     532                 : 
                        9: branch 6 taken
                      180: branch 7 taken
     533              369:   for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
     534              180:          ie = Args.filtered_end(); it != ie; ++it) {
     535                9:     llvm::StringRef Name = it->getOption().getName();
     536                9:     it->claim();
     537                 : 
     538                 :     // Skip over "-m".
                        9: branch 2 taken
                        0: branch 3 not taken
     539                9:     assert(Name.startswith("-m") && "Invalid feature name.");
     540                9:     Name = Name.substr(2);
     541                 : 
     542                9:     bool IsNegative = Name.startswith("no-");
                        3: branch 0 taken
                        6: branch 1 taken
     543                9:     if (IsNegative)
     544                3:       Name = Name.substr(3);
     545                 : 
     546                9:     CmdArgs.push_back("-target-feature");
                        3: branch 0 taken
                        6: branch 1 taken
     547                9:     CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
     548                 :   }
     549              180: }
     550                 : 
     551                 : static bool needsExceptions(const ArgList &Args,  types::ID InputType,
     552              188:                             const llvm::Triple &Triple) {
                        2: branch 0 taken
                      186: branch 1 taken
     553              188:   if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
     554              188:                                options::OPT_fno_exceptions)) {
                        1: branch 3 taken
                        1: branch 4 taken
     555                2:     if (A->getOption().matches(options::OPT_fexceptions))
     556                1:       return true;
     557                 :     else
     558                1:       return false;
     559                 :   }
                       15: branch 0 taken
                       52: branch 1 taken
                      119: branch 2 taken
     560              186:   switch (InputType) {
     561                 :   case types::TY_CXX: case types::TY_CXXHeader:
     562                 :   case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
     563                 :   case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
     564                 :   case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
     565               15:     return true;
     566                 : 
     567                 :   case types::TY_ObjC: case types::TY_ObjCHeader:
     568                 :   case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
                        0: branch 2 not taken
                       52: branch 3 taken
     569               52:     if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
     570                0:       return true;
                       51: branch 1 taken
                        1: branch 2 taken
     571               52:     if (Triple.getOS() != llvm::Triple::Darwin)
     572               51:       return false;
     573                 :     return (Triple.getDarwinMajorNumber() >= 9 &&
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        1: branch 5 taken
     574                1:             Triple.getArch() == llvm::Triple::x86_64);
     575                 : 
     576                 :   default:
     577              119:     return false;
     578                 :   }
     579                 : }
     580                 : 
     581                 : /// getEffectiveClangTriple - Get the "effective" target triple, which is the
     582                 : /// triple for the target but with the OS version potentially modified for
     583                 : /// Darwin's -mmacosx-version-min.
     584                 : static std::string getEffectiveClangTriple(const Driver &D,
     585                 :                                            const ToolChain &TC,
     586              188:                                            const ArgList &Args) {
     587              188:   llvm::Triple Triple(getLLVMTriple(TC, Args));
     588                 : 
     589                 :   // Handle -mmacosx-version-min and -miphoneos-version-min.
                      154: branch 1 taken
                       34: branch 2 taken
     590              188:   if (Triple.getOS() != llvm::Triple::Darwin) {
     591                 :     // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on
     592                 :     // non-Darwin.
                        0: branch 0 not taken
                      154: branch 1 taken
     593              154:     if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
     594              154:                                  options::OPT_miphoneos_version_min_EQ))
     595                0:       D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
     596                 :   } else {
     597                 :     const toolchains::Darwin &DarwinTC(
     598               34:       reinterpret_cast<const toolchains::Darwin&>(TC));
     599                 :     unsigned Version[3];
     600               34:     DarwinTC.getTargetVersion(Version);
     601                 : 
     602                 :     // Mangle the target version into the OS triple component.  For historical
     603                 :     // reasons that make little sense, the version passed here is the "darwin"
     604                 :     // version, which drops the 10 and offsets by 4. See inverse code when
     605                 :     // setting the OS version preprocessor define.
                       25: branch 1 taken
                        9: branch 2 taken
     606               34:     if (!DarwinTC.isTargetIPhoneOS()) {
     607               25:       Version[0] = Version[1] + 4;
     608               25:       Version[1] = Version[2];
     609               25:       Version[2] = 0;
     610                 :     } else {
     611                 :       // Use the environment to communicate that we are targetting iPhoneOS.
     612                9:       Triple.setEnvironmentName("iphoneos");
     613                 :     }
     614                 : 
     615               34:     llvm::SmallString<16> Str;
     616                 :     llvm::raw_svector_ostream(Str) << "darwin" << Version[0]
     617               34:                                    << "." << Version[1] << "." << Version[2];
     618               34:     Triple.setOSName(Str.str());
     619                 :   }
     620                 : 
     621              188:   return Triple.getTriple();
     622                 : }
     623                 : 
     624                 : void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     625                 :                          Job &Dest,
     626                 :                          const InputInfo &Output,
     627                 :                          const InputInfoList &Inputs,
     628                 :                          const ArgList &Args,
     629              188:                          const char *LinkingOutput) const {
     630              188:   const Driver &D = getToolChain().getDriver();
     631              188:   ArgStringList CmdArgs;
     632                 : 
                      188: branch 1 taken
                        0: branch 2 not taken
     633              188:   assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
     634                 : 
     635                 :   // Invoke ourselves in -cc1 mode.
     636                 :   //
     637                 :   // FIXME: Implement custom jobs for internal actions.
     638              188:   CmdArgs.push_back("-cc1");
     639                 : 
     640                 :   // Add the "effective" target triple.
     641              188:   CmdArgs.push_back("-triple");
     642              188:   std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args);
     643              188:   CmdArgs.push_back(Args.MakeArgString(TripleStr));
     644                 : 
     645                 :   // Select the appropriate action.
                        1: branch 1 taken
                      187: branch 2 taken
     646              188:   if (isa<AnalyzeJobAction>(JA)) {
                        1: branch 1 taken
                        0: branch 2 not taken
     647                1:     assert(JA.getType() == types::TY_Plist && "Invalid output type.");
     648                1:     CmdArgs.push_back("-analyze");
                       44: branch 1 taken
                      143: branch 2 taken
     649              187:   } else if (isa<PreprocessJobAction>(JA)) {
                        1: branch 1 taken
                       43: branch 2 taken
     650               44:     if (Output.getType() == types::TY_Dependencies)
     651                1:       CmdArgs.push_back("-Eonly");
     652                 :     else
     653               43:       CmdArgs.push_back("-E");
                        0: branch 1 not taken
                      143: branch 2 taken
     654              143:   } else if (isa<AssembleJobAction>(JA)) {
     655                0:     CmdArgs.push_back("-emit-obj");
                        4: branch 1 taken
                      139: branch 2 taken
     656              143:   } else if (isa<PrecompileJobAction>(JA)) {
     657                 :     // Use PCH if the user requested it, except for C++ (for now).
     658                4:     bool UsePCH = D.CCCUsePCH;
                        1: branch 3 taken
                        3: branch 4 taken
     659                4:     if (types::isCXX(Inputs[0].getType()))
     660                1:       UsePCH = false;
     661                 : 
                        2: branch 0 taken
                        2: branch 1 taken
     662                4:     if (UsePCH)
     663                2:       CmdArgs.push_back("-emit-pch");
     664                 :     else
     665                2:       CmdArgs.push_back("-emit-pth");
     666                 :   } else {
                      139: branch 1 taken
                        0: branch 2 not taken
     667              139:     assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
     668                 : 
                       80: branch 1 taken
                       59: branch 2 taken
     669              139:     if (JA.getType() == types::TY_Nothing) {
     670               80:       CmdArgs.push_back("-fsyntax-only");
                       23: branch 1 taken
                       36: branch 2 taken
     671               59:     } else if (JA.getType() == types::TY_LLVMAsm) {
     672               23:       CmdArgs.push_back("-emit-llvm");
                        2: branch 1 taken
                       34: branch 2 taken
     673               36:     } else if (JA.getType() == types::TY_LLVMBC) {
     674                2:       CmdArgs.push_back("-emit-llvm-bc");
                       31: branch 1 taken
                        3: branch 2 taken
     675               34:     } else if (JA.getType() == types::TY_PP_Asm) {
     676               31:       CmdArgs.push_back("-S");
                        3: branch 1 taken
                        0: branch 2 not taken
     677                3:     } else if (JA.getType() == types::TY_AST) {
     678                3:       CmdArgs.push_back("-emit-pch");
     679                 :     }
     680                 :   }
     681                 : 
     682                 :   // The make clang go fast button.
     683              188:   CmdArgs.push_back("-disable-free");
     684                 : 
     685                 :   // Set the main file name, so that debug info works even with
     686                 :   // -save-temps.
     687              188:   CmdArgs.push_back("-main-file-name");
     688              188:   CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
     689                 : 
     690                 :   // Some flags which affect the language (via preprocessor
     691                 :   // defines). See darwin::CC1::AddCPPArgs.
                        1: branch 2 taken
                      187: branch 3 taken
     692              188:   if (Args.hasArg(options::OPT_static))
     693                1:     CmdArgs.push_back("-static-define");
     694                 : 
                        1: branch 1 taken
                      187: branch 2 taken
     695              188:   if (isa<AnalyzeJobAction>(JA)) {
     696                 :     // Enable region store model by default.
     697                1:     CmdArgs.push_back("-analyzer-store=region");
     698                 : 
     699                 :     // Treat blocks as analysis entry points.
     700                1:     CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
     701                 : 
     702                 :     // Add default argument set.
                        1: branch 2 taken
                        0: branch 3 not taken
     703                1:     if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
     704                1:       CmdArgs.push_back("-analyzer-check-dead-stores");
     705                1:       CmdArgs.push_back("-analyzer-check-security-syntactic");
     706                1:       CmdArgs.push_back("-analyzer-check-objc-mem");
     707                1:       CmdArgs.push_back("-analyzer-eagerly-assume");
     708                1:       CmdArgs.push_back("-analyzer-check-objc-methodsigs");
     709                 :       // Do not enable the missing -dealloc check.
     710                 :       // '-analyzer-check-objc-missing-dealloc',
     711                1:       CmdArgs.push_back("-analyzer-check-objc-unused-ivars");
     712                 :     }
     713                 : 
     714                 :     // Set the output format. The default is plist, for (lame) historical
     715                 :     // reasons.
     716                1:     CmdArgs.push_back("-analyzer-output");
                        0: branch 2 not taken
                        1: branch 3 taken
     717                1:     if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
     718                0:       CmdArgs.push_back(A->getValue(Args));
     719                 :     else
     720                1:       CmdArgs.push_back("plist");
     721                 : 
     722                 :     // Add -Xanalyzer arguments when running as analyzer.
     723                1:     Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
     724                 :   }
     725                 : 
     726              188:   CheckCodeGenerationOptions(D, Args);
     727                 : 
     728                 :   // Perform argument translation for LLVM backend. This
     729                 :   // takes some care in reconciling with llvm-gcc. The
     730                 :   // issue is that llvm-gcc translates these options based on
     731                 :   // the values in cc1, whereas we are processing based on
     732                 :   // the driver arguments.
     733                 : 
     734                 :   // This comes from the default translation the driver + cc1
     735                 :   // would do to enable flag_pic.
     736                 :   //
     737                 :   // FIXME: Centralize this code.
     738                 :   bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
     739                 :                      Args.hasArg(options::OPT_fpic) ||
     740                 :                      Args.hasArg(options::OPT_fPIE) ||
                      187: branch 2 taken
                        1: branch 3 taken
                      186: branch 6 taken
                        1: branch 7 taken
                      186: branch 10 taken
                        0: branch 11 not taken
                        0: branch 14 not taken
                      186: branch 15 taken
     741              188:                      Args.hasArg(options::OPT_fpie));
     742                 :   bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
                      188: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                      187: branch 7 taken
     743              188:                       Args.hasArg(options::OPT_static));
     744              188:   const char *Model = getToolChain().GetForcedPicModel();
                      183: branch 0 taken
                        5: branch 1 taken
     745              188:   if (!Model) {
                        0: branch 2 not taken
                      183: branch 3 taken
     746              183:     if (Args.hasArg(options::OPT_mdynamic_no_pic))
     747                0:       Model = "dynamic-no-pic";
                        1: branch 0 taken
                      182: branch 1 taken
     748              183:     else if (PICDisabled)
     749                1:       Model = "static";
                        2: branch 0 taken
                      180: branch 1 taken
     750              182:     else if (PICEnabled)
     751                2:       Model = "pic";
     752                 :     else
     753              180:       Model = getToolChain().GetDefaultRelocationModel();
     754                 :   }
                      152: branch 3 taken
                       36: branch 4 taken
     755              188:   if (llvm::StringRef(Model) != "pic") {
     756              152:     CmdArgs.push_back("-mrelocation-model");
     757              152:     CmdArgs.push_back(Model);
     758                 :   }
     759                 : 
     760                 :   // Infer the __PIC__ value.
     761                 :   //
     762                 :   // FIXME:  This isn't quite right on Darwin, which always sets
     763                 :   // __PIC__=2.
                      152: branch 1 taken
                       36: branch 2 taken
                        0: branch 4 not taken
                      152: branch 5 taken
     764              188:   if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
     765               36:     CmdArgs.push_back("-pic-level");
                        1: branch 2 taken
                       35: branch 3 taken
     766               36:     CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1");
     767                 :   }
                        0: branch 3 not taken
                      188: branch 4 taken
     768              188:   if (!Args.hasFlag(options::OPT_fmerge_all_constants,
     769                 :                     options::OPT_fno_merge_all_constants))
     770                0:     CmdArgs.push_back("-no-merge-all-constants");
     771                 : 
     772                 :   // LLVM Code Generator Options.
     773                 : 
     774                 :   // FIXME: Set --enable-unsafe-fp-math.
                      188: branch 3 taken
                        0: branch 4 not taken
     775              188:   if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
     776                 :                    options::OPT_fomit_frame_pointer))
     777              188:     CmdArgs.push_back("-mdisable-fp-elim");
                        0: branch 3 not taken
                      188: branch 4 taken
     778              188:   if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
     779                 :                     options::OPT_fno_zero_initialized_in_bss))
     780                0:     CmdArgs.push_back("-mno-zero-initialized-in-bss");
                      187: branch 2 taken
                        1: branch 3 taken
                        1: branch 6 taken
                      186: branch 7 taken
                        2: branch 8 taken
                      186: branch 9 taken
     781              188:   if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm))
     782                2:     CmdArgs.push_back("-masm-verbose");
                        0: branch 2 not taken
                      188: branch 3 taken
     783              188:   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
     784                0:     CmdArgs.push_back("-mdebug-pass");
     785                0:     CmdArgs.push_back("Structure");
     786                 :   }
                        0: branch 2 not taken
                      188: branch 3 taken
     787              188:   if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
     788                0:     CmdArgs.push_back("-mdebug-pass");
     789                0:     CmdArgs.push_back("Arguments");
     790                 :   }
     791                 : 
     792                 :   // This is a coarse approximation of what llvm-gcc actually does, both
     793                 :   // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
     794                 :   // complicated ways.
     795                 :   bool AsynchronousUnwindTables =
     796                 :     Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
     797                 :                  options::OPT_fno_asynchronous_unwind_tables,
     798                 :                  getToolChain().IsUnwindTablesDefault() &&
                        6: branch 2 taken
                      182: branch 3 taken
                        6: branch 6 taken
                        0: branch 7 not taken
     799              188:                  !Args.hasArg(options::OPT_mkernel));
                        7: branch 3 taken
                      181: branch 4 taken
     800              188:   if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
     801                 :                    AsynchronousUnwindTables))
     802                7:     CmdArgs.push_back("-munwind-tables");
     803                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     804              188:   if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
     805                0:     CmdArgs.push_back("-mlimit-float-precision");
     806                0:     CmdArgs.push_back(A->getValue(Args));
     807                 :   }
     808                 : 
     809                 :   // FIXME: Handle -mtune=.
     810              188:   (void) Args.hasArg(options::OPT_mtune_EQ);
     811                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     812              188:   if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
     813                0:     CmdArgs.push_back("-mcode-model");
     814                0:     CmdArgs.push_back(A->getValue(Args));
     815                 :   }
     816                 : 
     817                 :   // Add target specific cpu and features flags.
                        1: branch 3 taken
                        7: branch 4 taken
                      180: branch 5 taken
     818              188:   switch(getToolChain().getTriple().getArch()) {
     819                 :   default:
     820                1:     break;
     821                 : 
     822                 :   case llvm::Triple::arm:
     823                 :   case llvm::Triple::thumb:
     824                7:     AddARMTargetArgs(Args, CmdArgs);
     825                7:     break;
     826                 : 
     827                 :   case llvm::Triple::x86:
     828                 :   case llvm::Triple::x86_64:
     829              180:     AddX86TargetArgs(Args, CmdArgs);
     830                 :     break;
     831                 :   }
     832                 : 
     833                 :   // -fno-math-errno is default.
                        2: branch 3 taken
                      186: branch 4 taken
     834              188:   if (Args.hasFlag(options::OPT_fmath_errno,
     835                 :                    options::OPT_fno_math_errno,
     836                 :                    false))
     837                2:     CmdArgs.push_back("-fmath-errno");
     838                 : 
     839                 :   Arg *Unsupported;
                      188: branch 2 taken
                        0: branch 3 not taken
                      188: branch 6 taken
                        0: branch 7 not taken
                      188: branch 10 taken
                        0: branch 11 not taken
                        1: branch 14 taken
                      187: branch 15 taken
                        1: branch 16 taken
                      187: branch 17 taken
     840              188:   if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
     841                 :       (Unsupported = Args.getLastArg(options::OPT_MQ)) ||
     842                 :       (Unsupported = Args.getLastArg(options::OPT_iframework)) ||
     843                 :       (Unsupported = Args.getLastArg(options::OPT_fshort_enums)))
     844                 :     D.Diag(clang::diag::err_drv_clang_unsupported)
     845                1:       << Unsupported->getOption().getName();
     846                 : 
     847              188:   Args.AddAllArgs(CmdArgs, options::OPT_v);
     848              188:   Args.AddLastArg(CmdArgs, options::OPT_P);
     849              188:   Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
     850                 : 
     851                 :   // Special case debug options to only pass -g to clang. This is
     852                 :   // wrong.
                        8: branch 2 taken
                      180: branch 3 taken
     853              188:   if (Args.hasArg(options::OPT_g_Group))
     854                8:     CmdArgs.push_back("-g");
     855                 : 
     856              188:   Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
     857              188:   Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
     858                 : 
     859                 :   // Pass the path to compiler resource files.
     860              188:   CmdArgs.push_back("-resource-dir");
     861              188:   CmdArgs.push_back(D.ResourceDir.c_str());
     862                 : 
     863                 :   // Add preprocessing options like -I, -D, etc. if we are using the
     864                 :   // preprocessor.
     865                 :   //
     866                 :   // FIXME: Support -fpreprocessed
     867              188:   types::ID InputType = Inputs[0].getType();
                      183: branch 1 taken
                        5: branch 2 taken
     868              188:   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
     869              183:     AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
     870                 : 
     871                 :   // Manually translate -O to -O2 and -O4 to -O3; let clang reject
     872                 :   // others.
                        5: branch 2 taken
                      183: branch 3 taken
     873              188:   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
                        0: branch 3 not taken
                        5: branch 4 taken
     874                5:     if (A->getOption().matches(options::OPT_O4))
     875                0:       CmdArgs.push_back("-O3");
                        0: branch 1 not taken
                        5: branch 2 taken
     876                5:     else if (A->getValue(Args)[0] == '\0')
     877                0:       CmdArgs.push_back("-O2");
     878                 :     else
     879                5:       A->render(Args, CmdArgs);
     880                 :   }
     881                 : 
     882              188:   Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
     883              188:   Args.AddLastArg(CmdArgs, options::OPT_pedantic);
     884              188:   Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
     885              188:   Args.AddLastArg(CmdArgs, options::OPT_w);
     886                 : 
     887                 :   // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
     888                 :   // (-ansi is equivalent to -std=c89).
     889                 :   //
     890                 :   // If a std is supplied, only add -trigraphs if it follows the
     891                 :   // option.
                        7: branch 3 taken
                      181: branch 4 taken
     892              188:   if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
                        1: branch 3 taken
                        6: branch 4 taken
     893                7:     if (Std->getOption().matches(options::OPT_ansi))
                        0: branch 1 not taken
                        1: branch 2 taken
     894                1:       if (types::isCXX(InputType))
     895                0:         CmdArgs.push_back("-std=c++98");
     896                 :       else
     897                1:         CmdArgs.push_back("-std=c89");
     898                 :     else
     899                6:       Std->render(Args, CmdArgs);
     900                 : 
                        2: branch 2 taken
                        5: branch 3 taken
     901                7:     if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
                        1: branch 2 taken
                        1: branch 3 taken
     902                2:       if (A->getIndex() > Std->getIndex())
     903                1:         A->render(Args, CmdArgs);
     904                 :   } else {
     905                 :     // Honor -std-default.
     906                 :     //
     907                 :     // FIXME: Clang doesn't correctly handle -std= when the input language
     908                 :     // doesn't match. For the time being just ignore this for C++ inputs;
     909                 :     // eventually we want to do all the standard defaulting here instead of
     910                 :     // splitting it between the driver and clang -cc1.
                      165: branch 1 taken
                       16: branch 2 taken
     911              181:     if (!types::isCXX(InputType))
     912                 :         Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
     913              165:                                   "-std=", /*Joined=*/true);
     914              181:     Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
     915                 :   }
     916                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     917              188:   if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
     918                0:     CmdArgs.push_back("-ftemplate-depth");
     919                0:     CmdArgs.push_back(A->getValue(Args));
     920                 :   }
     921                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     922              188:   if (Args.hasArg(options::OPT__relocatable_pch))
     923                0:     CmdArgs.push_back("-relocatable-pch");
     924                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     925              188:   if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
     926                0:     CmdArgs.push_back("-fconstant-string-class");
     927                0:     CmdArgs.push_back(A->getValue(Args));
     928                 :   }
     929                 : 
                        0: branch 2 not taken
                      188: branch 3 taken
     930              188:   if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
     931                0:     CmdArgs.push_back("-ftabstop");
     932                0:     CmdArgs.push_back(A->getValue(Args));
     933                 :   }
     934                 : 
     935                 :   // Pass -fmessage-length=.
     936              188:   CmdArgs.push_back("-fmessage-length");
                        0: branch 2 not taken
                      188: branch 3 taken
     937              188:   if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
     938                0:     CmdArgs.push_back(A->getValue(Args));
     939                 :   } else {
     940                 :     // If -fmessage-length=N was not specified, determine whether this is a
     941                 :     // terminal and, if so, implicitly define -fmessage-length appropriately.
     942              188:     unsigned N = llvm::sys::Process::StandardErrColumns();
     943              188:     CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N)));
     944                 :   }
     945                 : 
                        1: branch 2 taken
                      187: branch 3 taken
     946              188:   if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
     947                1:     CmdArgs.push_back("-fvisibility");
     948                1:     CmdArgs.push_back(A->getValue(Args));
     949                 :   }
     950                 : 
     951                 :   // Forward -f (flag) options which we can pass directly.
     952              188:   Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
     953              188:   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
     954              188:   Args.AddLastArg(CmdArgs, options::OPT_ffreestanding);
     955              188:   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
     956              188:   Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions);
     957              188:   Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics);
     958              188:   Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
     959              188:   Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
     960              188:   Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
     961              188:   Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
     962              188:   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
     963              188:   Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
     964              188:   Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
     965              188:   Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
     966                 : 
     967              188:   Args.AddLastArg(CmdArgs, options::OPT_pthread);
     968                 : 
     969                 :   // -stack-protector=0 is default.
     970              188:   unsigned StackProtectorLevel = 0;
                        0: branch 0 not taken
                      188: branch 1 taken
     971              188:   if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
     972                 :                                options::OPT_fstack_protector_all,
     973              188:                                options::OPT_fstack_protector)) {
                        0: branch 3 not taken
                        0: branch 4 not taken
     974                0:     if (A->getOption().matches(options::OPT_fstack_protector))
     975                0:       StackProtectorLevel = 1;
                        0: branch 3 not taken
                        0: branch 4 not taken
     976                0:     else if (A->getOption().matches(options::OPT_fstack_protector_all))
     977                0:       StackProtectorLevel = 2;
     978                 :   } else
     979              188:     StackProtectorLevel = getToolChain().GetDefaultStackProtectorLevel();
                        3: branch 0 taken
                      185: branch 1 taken
     980              188:   if (StackProtectorLevel) {
     981                3:     CmdArgs.push_back("-stack-protector");
     982                3:     CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel)));
     983                 :   }
     984                 : 
     985                 :   // Forward -f options with positive and negative forms; we translate
     986                 :   // these by hand.
     987                 : 
     988                 :   // -fbuiltin is default.
                        1: branch 3 taken
                      187: branch 4 taken
     989              188:   if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
     990                1:     CmdArgs.push_back("-fno-builtin");
     991                 : 
                        0: branch 3 not taken
                      188: branch 4 taken
     992              188:   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
     993                 :                     options::OPT_fno_assume_sane_operator_new))
     994                0:     CmdArgs.push_back("-fno-assume-sane-operator-new");
     995                 : 
     996                 :   // -fblocks=0 is default.
                       13: branch 5 taken
                      175: branch 6 taken
     997              188:   if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
     998                 :                    getToolChain().IsBlocksDefault())) {
     999               13:     Args.AddLastArg(CmdArgs, options::OPT_fblock_introspection);
    1000               13:     CmdArgs.push_back("-fblocks");
    1001                 :   }
    1002                 : 
    1003                 :   // -fexceptions=0 is default.
                       16: branch 3 taken
                      172: branch 4 taken
    1004              188:   if (needsExceptions(Args, InputType, getToolChain().getTriple()))
    1005               16:     CmdArgs.push_back("-fexceptions");
    1006                 : 
    1007                 :   // -frtti is default.
                        1: branch 3 taken
                      187: branch 4 taken
    1008              188:   if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
    1009                1:     CmdArgs.push_back("-fno-rtti");
    1010                 : 
    1011                 :   // -fsigned-char is default.
                        1: branch 6 taken
                      187: branch 7 taken
    1012              188:   if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
    1013                 :                     isSignedCharDefault(getToolChain().getTriple())))
    1014                1:     CmdArgs.push_back("-fno-signed-char");
    1015                 : 
    1016                 :   // -fthreadsafe-static is default.
                        0: branch 3 not taken
                      188: branch 4 taken
    1017              188:   if (!Args.hasFlag(options::OPT_fthreadsafe_statics, 
    1018                 :                     options::OPT_fno_threadsafe_statics))
    1019                0:     CmdArgs.push_back("-fno-threadsafe-statics");
    1020                 : 
    1021                 :   // -fms-extensions=0 is default.
                        0: branch 6 not taken
                      188: branch 7 taken
    1022              188:   if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
    1023                 :                    getToolChain().getTriple().getOS() == llvm::Triple::Win32))
    1024                0:     CmdArgs.push_back("-fms-extensions");
    1025                 : 
    1026                 :   // -fnext-runtime is default.
                      154: branch 6 taken
                       34: branch 7 taken
    1027              188:   if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
    1028                 :                     getToolChain().getTriple().getOS() == llvm::Triple::Darwin))
    1029              154:     CmdArgs.push_back("-fgnu-runtime");
    1030                 : 
    1031                 :   // -fobjc-nonfragile-abi=0 is default.
                       52: branch 1 taken
                      136: branch 2 taken
    1032              188:   if (types::isObjC(InputType)) {
                       52: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                       51: branch 7 taken
                        1: branch 8 taken
                       51: branch 9 taken
    1033               52:     if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) ||
    1034                 :         getToolChain().IsObjCNonFragileABIDefault()) {
    1035                1:       CmdArgs.push_back("-fobjc-nonfragile-abi");
    1036                 :       
    1037                 :       // -fobjc-legacy-dispatch is only relevant with the nonfragile-abi, and
    1038                 :       // defaults to off.
                        1: branch 5 taken
                        0: branch 6 not taken
    1039                1:       if (Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
    1040                 :                        options::OPT_fno_objc_legacy_dispatch,
    1041                 :                        getToolChain().IsObjCLegacyDispatchDefault()))
    1042                1:         CmdArgs.push_back("-fobjc-legacy-dispatch");
    1043                 :     }
    1044                 :   }
    1045                 : 
                        0: branch 3 not taken
                      188: branch 4 taken
    1046              188:   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
    1047                 :                     options::OPT_fno_assume_sane_operator_new))
    1048                0:     CmdArgs.push_back("-fno-assume-sane-operator-new");
    1049                 : 
    1050                 :   // -fshort-wchar default varies depending on platform; only
    1051                 :   // pass if specified.
                        2: branch 2 taken
                      186: branch 3 taken
    1052              188:   if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) {
                        2: branch 3 taken
                        0: branch 4 not taken
    1053                2:     if (A->getOption().matches(options::OPT_fshort_wchar))
    1054                2:       CmdArgs.push_back("-fshort-wchar");
    1055                 :   }
    1056                 : 
    1057                 :   // -fno-pascal-strings is default, only pass non-default. If the tool chain
    1058                 :   // happened to translate to -mpascal-strings, we want to back translate here.
    1059                 :   //
    1060                 :   // FIXME: This is gross; that translation should be pulled from the
    1061                 :   // tool chain.
                      186: branch 3 taken
                        2: branch 4 taken
                        0: branch 8 not taken
                      186: branch 9 taken
                        2: branch 10 taken
                      186: branch 11 taken
    1062              188:   if (Args.hasFlag(options::OPT_fpascal_strings,
    1063                 :                    options::OPT_fno_pascal_strings,
    1064                 :                    false) ||
    1065                 :       Args.hasFlag(options::OPT_mpascal_strings,
    1066                 :                    options::OPT_mno_pascal_strings,
    1067                 :                    false))
    1068                2:     CmdArgs.push_back("-fpascal-strings");
    1069                 : 
    1070                 :   // -fcommon is default, only pass non-default.
                        2: branch 3 taken
                      186: branch 4 taken
    1071              188:   if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
    1072                2:     CmdArgs.push_back("-fno-common");
    1073                 : 
    1074                 :   // -fsigned-bitfields is default, and clang doesn't yet support
    1075                 :   // --funsigned-bitfields.
                        0: branch 3 not taken
                      188: branch 4 taken
    1076              188:   if (!Args.hasFlag(options::OPT_fsigned_bitfields,
    1077                 :                     options::OPT_funsigned_bitfields))
    1078                 :     D.Diag(clang::diag::warn_drv_clang_unsupported)
    1079                0:       << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
    1080                 : 
    1081                 :   // -fdiagnostics-fixit-info is default, only pass non-default.
                        0: branch 3 not taken
                      188: branch 4 taken
    1082              188:   if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
    1083                 :                     options::OPT_fno_diagnostics_fixit_info))
    1084                0:     CmdArgs.push_back("-fno-diagnostics-fixit-info");
    1085                 : 
    1086              188:   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_binary);
    1087                 : 
    1088                 :   // Enable -fdiagnostics-show-option by default.
                      188: branch 3 taken
                        0: branch 4 not taken
    1089              188:   if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
    1090                 :                    options::OPT_fno_diagnostics_show_option))
    1091              188:     CmdArgs.push_back("-fdiagnostics-show-option");
    1092                 : 
    1093                 :   // Color diagnostics are the default, unless the terminal doesn't support
    1094                 :   // them.
                      188: branch 3 taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                      188: branch 7 taken
                        0: branch 8 not taken
                      188: branch 9 taken
    1095              188:   if (Args.hasFlag(options::OPT_fcolor_diagnostics,
    1096                 :                    options::OPT_fno_color_diagnostics) &&
    1097                 :       llvm::sys::Process::StandardErrHasColors())
    1098                0:     CmdArgs.push_back("-fcolor-diagnostics");
    1099                 : 
                        1: branch 3 taken
                      187: branch 4 taken
    1100              188:   if (!Args.hasFlag(options::OPT_fshow_source_location,
    1101                 :                     options::OPT_fno_show_source_location))
    1102                1:     CmdArgs.push_back("-fno-show-source-location");
    1103                 : 
    1104                 :   // -fdollars-in-identifiers default varies depending on platform and
    1105                 :   // language; only pass if specified.
                        0: branch 0 not taken
                      188: branch 1 taken
    1106              188:   if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
    1107              188:                                options::OPT_fno_dollars_in_identifiers)) {
                        0: branch 3 not taken
                        0: branch 4 not taken
    1108                0:     if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
    1109                0:       CmdArgs.push_back("-fdollars-in-identifiers");
    1110                 :     else
    1111                0:       CmdArgs.push_back("-fno-dollars-in-identifiers");
    1112                 :   }
    1113                 : 
    1114                 :   // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
    1115                 :   // practical purposes.
                        0: branch 0 not taken
                      188: branch 1 taken
    1116              188:   if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
    1117              188:                                options::OPT_fno_unit_at_a_time)) {
                        0: branch 3 not taken
                        0: branch 4 not taken
    1118                0:     if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
    1119                0:       D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args);
    1120                 :   }
    1121                 : 
    1122                 :   // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
    1123                 :   //
    1124                 :   // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
    1125                 : #if 0
    1126                 :   if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
    1127                 :       (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
    1128                 :        getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
    1129                 :     if (!Args.hasArg(options::OPT_fbuiltin_strcat))
    1130                 :       CmdArgs.push_back("-fno-builtin-strcat");
    1131                 :     if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
    1132                 :       CmdArgs.push_back("-fno-builtin-strcpy");
    1133                 :   }
    1134                 : #endif
    1135                 : 
                        0: branch 0 not taken
                      188: branch 1 taken
    1136              188:   if (Arg *A = Args.getLastArg(options::OPT_traditional,
    1137              188:                                options::OPT_traditional_cpp))
    1138                0:     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
    1139                 : 
    1140              188:   Args.AddLastArg(CmdArgs, options::OPT_dM);
    1141              188:   Args.AddLastArg(CmdArgs, options::OPT_dD);
    1142                 : 
    1143              188:   Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
    1144              188:   Args.AddAllArgValues(CmdArgs, options::OPT_mllvm);
    1145                 : 
                      187: branch 1 taken
                        1: branch 2 taken
    1146              188:   if (Output.getType() == types::TY_Dependencies) {
    1147                 :     // Handled with other dependency code.
                       12: branch 1 taken
                      175: branch 2 taken
    1148              187:   } else if (Output.isPipe()) {
    1149               12:     CmdArgs.push_back("-o");
    1150               12:     CmdArgs.push_back("-");
                       95: branch 1 taken
                       80: branch 2 taken
    1151              175:   } else if (Output.isFilename()) {
    1152               95:     CmdArgs.push_back("-o");
    1153               95:     CmdArgs.push_back(Output.getFilename());
    1154                 :   } else {
                       80: branch 1 taken
                        0: branch 2 not taken
    1155               80:     assert(Output.isNothing() && "Invalid output.");
    1156                 :   }
    1157                 : 
                      188: branch 0 taken
                      188: branch 1 taken
    1158              376:   for (InputInfoList::const_iterator
    1159              188:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    1160              188:     const InputInfo &II = *it;
    1161              188:     CmdArgs.push_back("-x");
    1162              188:     CmdArgs.push_back(types::getTypeName(II.getType()));
                        0: branch 1 not taken
                      188: branch 2 taken
    1163              188:     if (II.isPipe())
    1164                0:       CmdArgs.push_back("-");
                      188: branch 1 taken
                        0: branch 2 not taken
    1165              188:     else if (II.isFilename())
    1166              188:       CmdArgs.push_back(II.getFilename());
    1167                 :     else
    1168                0:       II.getInputArg().renderAsInput(Args, CmdArgs);
    1169                 :   }
    1170                 : 
    1171              188:   Args.AddAllArgs(CmdArgs, options::OPT_undef);
    1172                 : 
    1173                 :   const char *Exec =
    1174              188:     Args.MakeArgString(getToolChain().GetProgramPath(C, "clang"));
    1175                 : 
    1176                 :   // Optionally embed the -cc1 level arguments into the debug info, for build
    1177                 :   // analysis.
                        1: branch 2 taken
                      187: branch 3 taken
    1178              188:   if (getToolChain().UseDwarfDebugFlags()) {
    1179                1:     llvm::SmallString<256> Flags;
    1180                1:     Flags += Exec;
                       24: branch 1 taken
                        1: branch 2 taken
    1181               25:     for (unsigned i = 0, e = CmdArgs.size(); i != e; ++i) {
    1182               24:       Flags += " ";
    1183               24:       Flags += CmdArgs[i];
    1184                 :     }
    1185                1:     CmdArgs.push_back("-dwarf-debug-flags");
    1186                1:     CmdArgs.push_back(Args.MakeArgString(Flags.str()));
    1187                 :   }
    1188                 : 
    1189              188:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    1190                 : 
    1191                 :   // Explicitly warn that these options are unsupported, even though
    1192                 :   // we are allowing compilation to continue.
                        0: branch 6 not taken
                      188: branch 7 taken
    1193              376:   for (arg_iterator it = Args.filtered_begin(options::OPT_pg),
    1194              188:          ie = Args.filtered_end(); it != ie; ++it) {
    1195                0:     it->claim();
    1196                0:     D.Diag(clang::diag::warn_drv_clang_unsupported) << it->getAsString(Args);
    1197                 :   }
    1198                 : 
    1199                 :   // Claim some arguments which clang supports automatically.
    1200                 : 
    1201                 :   // -fpch-preprocess is used with gcc to add a special marker in the
    1202                 :   // -output to include the PCH file. Clang's PTH solution is
    1203                 :   // -completely transparent, so we do not need to deal with it at
    1204                 :   // -all.
    1205              188:   Args.ClaimAllArgs(options::OPT_fpch_preprocess);
    1206                 : 
    1207                 :   // Claim some arguments which clang doesn't support, but we don't
    1208                 :   // care to warn the user about.
    1209              188:   Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
    1210              188:   Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
    1211              188: }
    1212                 : 
    1213                 : void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
    1214                 :                                Job &Dest,
    1215                 :                                const InputInfo &Output,
    1216                 :                                const InputInfoList &Inputs,
    1217                 :                                const ArgList &Args,
    1218               10:                                const char *LinkingOutput) const {
    1219               10:   const Driver &D = getToolChain().getDriver();
    1220               10:   ArgStringList CmdArgs;
    1221                 : 
                       42: branch 0 taken
                       10: branch 1 taken
    1222               52:   for (ArgList::const_iterator
    1223               10:          it = Args.begin(), ie = Args.end(); it != ie; ++it) {
    1224               42:     Arg *A = *it;
                        4: branch 2 taken
                       38: branch 3 taken
    1225               42:     if (A->getOption().hasForwardToGCC()) {
    1226                 :       // It is unfortunate that we have to claim here, as this means
    1227                 :       // we will basically never report anything interesting for
    1228                 :       // platforms using a generic gcc, even if we are just using gcc
    1229                 :       // to get to the assembler.
    1230                4:       A->claim();
    1231                4:       A->render(Args, CmdArgs);
    1232                 :     }
    1233                 :   }
    1234                 : 
    1235               10:   RenderExtraToolArgs(JA, CmdArgs);
    1236                 : 
    1237                 :   // If using a driver driver, force the arch.
    1238               10:   const std::string &Arch = getToolChain().getArchName();
                        0: branch 3 not taken
                       10: branch 4 taken
    1239               10:   if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin) {
    1240                0:     CmdArgs.push_back("-arch");
    1241                 : 
    1242                 :     // FIXME: Remove these special cases.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1243                0:     if (Arch == "powerpc")
    1244                0:       CmdArgs.push_back("ppc");
                        0: branch 1 not taken
                        0: branch 2 not taken
    1245                0:     else if (Arch == "powerpc64")
    1246                0:       CmdArgs.push_back("ppc64");
    1247                 :     else
    1248                0:       CmdArgs.push_back(Args.MakeArgString(Arch));
    1249                 :   }
    1250                 : 
    1251                 :   // Try to force gcc to match the tool chain we want, if we recognize
    1252                 :   // the arch.
    1253                 :   //
    1254                 :   // FIXME: The triple class should directly provide the information we want
    1255                 :   // here.
                        2: branch 1 taken
                        8: branch 2 taken
                        0: branch 4 not taken
                        2: branch 5 taken
                        8: branch 6 taken
                        2: branch 7 taken
    1256               10:   if (Arch == "i386" || Arch == "powerpc")
    1257                8:     CmdArgs.push_back("-m32");
                        0: branch 1 not taken
                        2: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        2: branch 6 taken
                        0: branch 7 not taken
    1258                2:   else if (Arch == "x86_64" || Arch == "powerpc64")
    1259                2:     CmdArgs.push_back("-m64");
    1260                 : 
                        0: branch 1 not taken
                       10: branch 2 taken
    1261               10:   if (Output.isPipe()) {
    1262                0:     CmdArgs.push_back("-o");
    1263                0:     CmdArgs.push_back("-");
                       10: branch 1 taken
                        0: branch 2 not taken
    1264               10:   } else if (Output.isFilename()) {
    1265               10:     CmdArgs.push_back("-o");
    1266               10:     CmdArgs.push_back(Output.getFilename());
    1267                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1268                0:     assert(Output.isNothing() && "Unexpected output");
    1269                0:     CmdArgs.push_back("-fsyntax-only");
    1270                 :   }
    1271                 : 
    1272                 : 
    1273                 :   // Only pass -x if gcc will understand it; otherwise hope gcc
    1274                 :   // understands the suffix correctly. The main use case this would go
    1275                 :   // wrong in is for linker inputs if they happened to have an odd
    1276                 :   // suffix; really the only way to get this to happen is a command
    1277                 :   // like '-x foobar a.c' which will treat a.c like a linker input.
    1278                 :   //
    1279                 :   // FIXME: For the linker case specifically, can we safely convert
    1280                 :   // inputs into '-Wl,' options?
                       10: branch 0 taken
                       10: branch 1 taken
    1281               20:   for (InputInfoList::const_iterator
    1282               10:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    1283               10:     const InputInfo &II = *it;
    1284                 : 
    1285                 :     // Don't try to pass LLVM or AST inputs to a generic gcc.
                        2: branch 1 taken
                        8: branch 2 taken
    1286               10:     if (II.getType() == types::TY_LLVMBC)
    1287                 :       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
    1288                2:         << getToolChain().getTripleString();
                        0: branch 1 not taken
                        8: branch 2 taken
    1289                8:     else if (II.getType() == types::TY_AST)
    1290                 :       D.Diag(clang::diag::err_drv_no_ast_support)
    1291                0:         << getToolChain().getTripleString();
    1292                 : 
                        6: branch 2 taken
                        4: branch 3 taken
    1293               10:     if (types::canTypeBeUserSpecified(II.getType())) {
    1294                6:       CmdArgs.push_back("-x");
    1295                6:       CmdArgs.push_back(types::getTypeName(II.getType()));
    1296                 :     }
    1297                 : 
                        0: branch 1 not taken
                       10: branch 2 taken
    1298               10:     if (II.isPipe())
    1299                0:       CmdArgs.push_back("-");
                       10: branch 1 taken
                        0: branch 2 not taken
    1300               10:     else if (II.isFilename())
    1301               10:       CmdArgs.push_back(II.getFilename());
    1302                 :     else
    1303                 :       // Don't render as input, we need gcc to do the translations.
    1304                0:       II.getInputArg().render(Args, CmdArgs);
    1305                 :   }
    1306                 : 
    1307               10:   const char *GCCName = getToolChain().getDriver().CCCGenericGCCName.c_str();
    1308                 :   const char *Exec =
    1309               10:     Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName));
    1310               10:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    1311               10: }
    1312                 : 
    1313                 : void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
    1314                0:                                           ArgStringList &CmdArgs) const {
    1315                0:   CmdArgs.push_back("-E");
    1316                0: }
    1317                 : 
    1318                 : void gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
    1319                0:                                           ArgStringList &CmdArgs) const {
    1320                 :   // The type is good enough.
    1321                0: }
    1322                 : 
    1323                 : void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
    1324                0:                                        ArgStringList &CmdArgs) const {
    1325                 :   // If -flto, etc. are present then make sure not to force assembly output.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1326                0:   if (JA.getType() == types::TY_LLVMBC)
    1327                0:     CmdArgs.push_back("-c");
    1328                 :   else
    1329                0:     CmdArgs.push_back("-S");
    1330                0: }
    1331                 : 
    1332                 : void gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
    1333                6:                                         ArgStringList &CmdArgs) const {
    1334                6:   CmdArgs.push_back("-c");
    1335                6: }
    1336                 : 
    1337                 : void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
    1338                4:                                     ArgStringList &CmdArgs) const {
    1339                 :   // The types are (hopefully) good enough.
    1340                4: }
    1341                 : 
    1342                3: const char *darwin::CC1::getCC1Name(types::ID Type) const {
                        0: branch 0 not taken
                        3: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
    1343                3:   switch (Type) {
    1344                 :   default:
    1345                0:     assert(0 && "Unexpected type for Darwin CC1 tool.");
    1346                 :   case types::TY_Asm:
    1347                 :   case types::TY_C: case types::TY_CHeader:
    1348                 :   case types::TY_PP_C: case types::TY_PP_CHeader:
    1349                3:     return "cc1";
    1350                 :   case types::TY_ObjC: case types::TY_ObjCHeader:
    1351                 :   case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
    1352                0:     return "cc1obj";
    1353                 :   case types::TY_CXX: case types::TY_CXXHeader:
    1354                 :   case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
    1355                0:     return "cc1plus";
    1356                 :   case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
    1357                 :   case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
    1358                0:     return "cc1objplus";
    1359                 :   }
    1360                 : }
    1361                 : 
    1362                 : const char *darwin::CC1::getBaseInputName(const ArgList &Args,
    1363              191:                                           const InputInfoList &Inputs) {
    1364              191:   llvm::sys::Path P(Inputs[0].getBaseInput());
    1365              191:   return Args.MakeArgString(P.getLast());
    1366                 : }
    1367                 : 
    1368                 : const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
    1369                1:                                           const InputInfoList &Inputs) {
    1370                1:   const char *Str = getBaseInputName(Args, Inputs);
    1371                 : 
                        1: branch 1 taken
                        0: branch 2 not taken
    1372                1:   if (const char *End = strchr(Str, '.'))
    1373                1:     return Args.MakeArgString(std::string(Str, End));
    1374                 : 
    1375                0:   return Str;
    1376                 : }
    1377                 : 
    1378                 : const char *
    1379                 : darwin::CC1::getDependencyFileName(const ArgList &Args,
    1380                1:                                    const InputInfoList &Inputs) {
    1381                 :   // FIXME: Think about this more.
    1382                1:   std::string Res;
    1383                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
    1384                1:   if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
    1385                1:     std::string Str(OutputOpt->getValue(Args));
    1386                 : 
    1387                1:     Res = Str.substr(0, Str.rfind('.'));
    1388                 :   } else
    1389                0:     Res = darwin::CC1::getBaseInputStem(Args, Inputs);
    1390                 : 
    1391                1:   return Args.MakeArgString(Res + ".d");
    1392                 : }
    1393                 : 
    1394                 : void darwin::CC1::AddCC1Args(const ArgList &Args,
    1395                3:                              ArgStringList &CmdArgs) const {
    1396                3:   const Driver &D = getToolChain().getDriver();
    1397                 : 
    1398                3:   CheckCodeGenerationOptions(D, Args);
    1399                 : 
    1400                 :   // Derived from cc1 spec.
                        1: branch 2 taken
                        2: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 10 taken
                        0: branch 11 not taken
                        1: branch 12 taken
                        2: branch 13 taken
    1401                3:   if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
    1402                 :       !Args.hasArg(options::OPT_mdynamic_no_pic))
    1403                1:     CmdArgs.push_back("-fPIC");
    1404                 : 
                        2: branch 3 taken
                        1: branch 4 taken
                        0: branch 8 not taken
                        2: branch 9 taken
                        1: branch 10 taken
                        2: branch 11 taken
    1405                3:   if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
    1406                 :       getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
                        0: branch 2 not taken
                        1: branch 3 taken
    1407                1:     if (!Args.hasArg(options::OPT_fbuiltin_strcat))
    1408                0:       CmdArgs.push_back("-fno-builtin-strcat");
                        0: branch 2 not taken
                        1: branch 3 taken
    1409                1:     if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
    1410                0:       CmdArgs.push_back("-fno-builtin-strcpy");
    1411                 :   }
    1412                 : 
    1413                 :   // gcc has some code here to deal with when no -mmacosx-version-min
    1414                 :   // and no -miphoneos-version-min is present, but this never happens
    1415                 :   // due to tool chain specific argument translation.
    1416                 : 
                        2: branch 2 taken
                        1: branch 3 taken
                        0: branch 6 not taken
                        2: branch 7 taken
                        0: branch 8 not taken
                        3: branch 9 taken
    1417                3:   if (Args.hasArg(options::OPT_g_Flag) &&
    1418                 :       !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
    1419                0:     CmdArgs.push_back("-feliminate-unused-debug-symbols");
    1420                3: }
    1421                 : 
    1422                 : void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
    1423                 :                                     const InputInfoList &Inputs,
    1424                2:                                     const ArgStringList &OutputArgs) const {
    1425                2:   const Driver &D = getToolChain().getDriver();
    1426                 : 
    1427                 :   // Derived from cc1_options spec.
                        1: branch 2 taken
                        1: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                        1: branch 11 taken
                        1: branch 12 taken
                        1: branch 13 taken
    1428                2:   if (Args.hasArg(options::OPT_fast) ||
    1429                 :       Args.hasArg(options::OPT_fastf) ||
    1430                 :       Args.hasArg(options::OPT_fastcp))
    1431                1:     CmdArgs.push_back("-O3");
    1432                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1433                2:   if (Arg *A = Args.getLastArg(options::OPT_pg))
                        0: branch 2 not taken
                        1: branch 3 taken
    1434                1:     if (Args.hasArg(options::OPT_fomit_frame_pointer))
    1435                 :       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    1436                0:         << A->getAsString(Args) << "-fomit-frame-pointer";
    1437                 : 
    1438                2:   AddCC1Args(Args, CmdArgs);
    1439                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1440                2:   if (!Args.hasArg(options::OPT_Q))
    1441                1:     CmdArgs.push_back("-quiet");
    1442                 : 
    1443                2:   CmdArgs.push_back("-dumpbase");
    1444                2:   CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
    1445                 : 
    1446                2:   Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
    1447                 : 
    1448                2:   Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
    1449                2:   Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
    1450                 : 
    1451                 :   // FIXME: The goal is to use the user provided -o if that is our
    1452                 :   // final output, otherwise to drive from the original input
    1453                 :   // name. Find a clean way to go about this.
                        2: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        1: branch 7 taken
                        1: branch 10 taken
                        0: branch 11 not taken
                        1: branch 12 taken
                        1: branch 13 taken
    1454                2:   if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
    1455                 :       Args.hasArg(options::OPT_o)) {
    1456                1:     Arg *OutputOpt = Args.getLastArg(options::OPT_o);
    1457                1:     CmdArgs.push_back("-auxbase-strip");
    1458                1:     CmdArgs.push_back(OutputOpt->getValue(Args));
    1459                 :   } else {
    1460                1:     CmdArgs.push_back("-auxbase");
    1461                1:     CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
    1462                 :   }
    1463                 : 
    1464                2:   Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
    1465                 : 
    1466                2:   Args.AddAllArgs(CmdArgs, options::OPT_O);
    1467                 :   // FIXME: -Wall is getting some special treatment. Investigate.
    1468                2:   Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
    1469                2:   Args.AddLastArg(CmdArgs, options::OPT_w);
    1470                 :   Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
    1471                2:                   options::OPT_trigraphs);
                        1: branch 3 taken
                        1: branch 4 taken
    1472                2:   if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
    1473                 :     // Honor -std-default.
    1474                 :     Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
    1475                1:                               "-std=", /*Joined=*/true);
    1476                 :   }
    1477                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1478                2:   if (Args.hasArg(options::OPT_v))
    1479                1:     CmdArgs.push_back("-version");
                        1: branch 2 taken
                        1: branch 3 taken
    1480                2:   if (Args.hasArg(options::OPT_pg))
    1481                1:     CmdArgs.push_back("-p");
    1482                2:   Args.AddLastArg(CmdArgs, options::OPT_p);
    1483                 : 
    1484                 :   // The driver treats -fsyntax-only specially.
                        1: branch 3 taken
                        1: branch 4 taken
                        0: branch 8 not taken
                        1: branch 9 taken
                        1: branch 10 taken
                        1: branch 11 taken
    1485                2:   if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
    1486                 :       getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
    1487                 :     // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
    1488                 :     // used to inhibit the default -fno-builtin-str{cat,cpy}.
    1489                 :     //
    1490                 :     // FIXME: Should we grow a better way to deal with "removing" args?
                        3: branch 2 taken
                        1: branch 3 taken
    1491                4:     for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
    1492                1:                                                options::OPT_fsyntax_only),
    1493                1:            ie = Args.filtered_end(); it != ie; ++it) {
                        2: branch 4 taken
                        1: branch 5 taken
                        1: branch 10 taken
                        1: branch 11 taken
                        1: branch 12 taken
                        2: branch 13 taken
    1494                3:       if (!it->getOption().matches(options::OPT_fbuiltin_strcat) &&
    1495                 :           !it->getOption().matches(options::OPT_fbuiltin_strcpy)) {
    1496                1:         it->claim();
    1497                1:         it->render(Args, CmdArgs);
    1498                 :       }
    1499                 :     }
    1500                 :   } else
    1501                1:     Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
    1502                 : 
    1503                2:   Args.AddAllArgs(CmdArgs, options::OPT_undef);
                        1: branch 2 taken
                        1: branch 3 taken
    1504                2:   if (Args.hasArg(options::OPT_Qn))
    1505                1:     CmdArgs.push_back("-fno-ident");
    1506                 : 
    1507                 :   // FIXME: This isn't correct.
    1508                 :   //Args.AddLastArg(CmdArgs, options::OPT__help)
    1509                 :   //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
    1510                 : 
    1511                2:   CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
    1512                 : 
    1513                 :   // FIXME: Still don't get what is happening here. Investigate.
    1514                2:   Args.AddAllArgs(CmdArgs, options::OPT__param);
    1515                 : 
                        1: branch 2 taken
                        1: branch 3 taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        1: branch 8 taken
                        1: branch 9 taken
    1516                2:   if (Args.hasArg(options::OPT_fmudflap) ||
    1517                 :       Args.hasArg(options::OPT_fmudflapth)) {
    1518                1:     CmdArgs.push_back("-fno-builtin");
    1519                1:     CmdArgs.push_back("-fno-merge-constants");
    1520                 :   }
    1521                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1522                2:   if (Args.hasArg(options::OPT_coverage)) {
    1523                1:     CmdArgs.push_back("-fprofile-arcs");
    1524                1:     CmdArgs.push_back("-ftest-coverage");
    1525                 :   }
    1526                 : 
                        0: branch 3 not taken
                        2: branch 4 taken
    1527                2:   if (types::isCXX(Inputs[0].getType()))
    1528                0:     CmdArgs.push_back("-D__private_extern__=extern");
    1529                2: }
    1530                 : 
    1531                 : void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
    1532                 :                                     const InputInfoList &Inputs,
    1533                1:                                     const ArgStringList &OutputArgs) const {
    1534                 :   // Derived from cpp_options
    1535                1:   AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
    1536                 : 
    1537                1:   CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
    1538                 : 
    1539                1:   AddCC1Args(Args, CmdArgs);
    1540                 : 
    1541                 :   // NOTE: The code below has some commonality with cpp_options, but
    1542                 :   // in classic gcc style ends up sending things in different
    1543                 :   // orders. This may be a good merge candidate once we drop pedantic
    1544                 :   // compatibility.
    1545                 : 
    1546                1:   Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
    1547                 :   Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
    1548                1:                   options::OPT_trigraphs);
                        0: branch 3 not taken
                        1: branch 4 taken
    1549                1:   if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
    1550                 :     // Honor -std-default.
    1551                 :     Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
    1552                0:                               "-std=", /*Joined=*/true);
    1553                 :   }
    1554                1:   Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
    1555                1:   Args.AddLastArg(CmdArgs, options::OPT_w);
    1556                 : 
    1557                 :   // The driver treats -fsyntax-only specially.
    1558                1:   Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
    1559                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        1: branch 13 taken
    1560                1:   if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
    1561                 :       !Args.hasArg(options::OPT_fno_working_directory))
    1562                0:     CmdArgs.push_back("-fworking-directory");
    1563                 : 
    1564                1:   Args.AddAllArgs(CmdArgs, options::OPT_O);
    1565                1:   Args.AddAllArgs(CmdArgs, options::OPT_undef);
                        1: branch 2 taken
                        0: branch 3 not taken
    1566                1:   if (Args.hasArg(options::OPT_save_temps))
    1567                1:     CmdArgs.push_back("-fpch-preprocess");
    1568                1: }
    1569                 : 
    1570                 : void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
    1571                 :                                           ArgStringList &CmdArgs,
    1572                2:                                           const InputInfoList &Inputs) const {
    1573                2:   const Driver &D = getToolChain().getDriver();
    1574                 : 
    1575                2:   CheckPreprocessingOptions(D, Args);
    1576                 : 
    1577                 :   // Derived from cpp_unique_options.
    1578                 :   // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
    1579                2:   Args.AddLastArg(CmdArgs, options::OPT_C);
    1580                2:   Args.AddLastArg(CmdArgs, options::OPT_CC);
                        1: branch 2 taken
                        1: branch 3 taken
    1581                2:   if (!Args.hasArg(options::OPT_Q))
    1582                1:     CmdArgs.push_back("-quiet");
    1583                2:   Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
    1584                2:   Args.AddLastArg(CmdArgs, options::OPT_v);
    1585                2:   Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
    1586                2:   Args.AddLastArg(CmdArgs, options::OPT_P);
    1587                 : 
    1588                 :   // FIXME: Handle %I properly.
                        0: branch 4 not taken
                        2: branch 5 taken
    1589                2:   if (getToolChain().getArchName() == "x86_64") {
    1590                0:     CmdArgs.push_back("-imultilib");
    1591                0:     CmdArgs.push_back("x86_64");
    1592                 :   }
    1593                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1594                2:   if (Args.hasArg(options::OPT_MD)) {
    1595                1:     CmdArgs.push_back("-MD");
    1596                1:     CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
    1597                 :   }
    1598                 : 
                        0: branch 2 not taken
                        2: branch 3 taken
    1599                2:   if (Args.hasArg(options::OPT_MMD)) {
    1600                0:     CmdArgs.push_back("-MMD");
    1601                0:     CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
    1602                 :   }
    1603                 : 
    1604                2:   Args.AddLastArg(CmdArgs, options::OPT_M);
    1605                2:   Args.AddLastArg(CmdArgs, options::OPT_MM);
    1606                2:   Args.AddAllArgs(CmdArgs, options::OPT_MF);
    1607                2:   Args.AddLastArg(CmdArgs, options::OPT_MG);
    1608                2:   Args.AddLastArg(CmdArgs, options::OPT_MP);
    1609                2:   Args.AddAllArgs(CmdArgs, options::OPT_MQ);
    1610                2:   Args.AddAllArgs(CmdArgs, options::OPT_MT);
                        2: branch 2 taken
                        0: branch 3 not taken
                        2: branch 6 taken
                        0: branch 7 not taken
                        1: branch 10 taken
                        1: branch 11 taken
                        0: branch 14 not taken
                        1: branch 15 taken
                        1: branch 16 taken
                        1: branch 17 taken
    1611                2:   if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
    1612                 :       (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
                        1: branch 2 taken
                        0: branch 3 not taken
    1613                1:     if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
    1614                1:       CmdArgs.push_back("-MQ");
    1615                1:       CmdArgs.push_back(OutputOpt->getValue(Args));
    1616                 :     }
    1617                 :   }
    1618                 : 
    1619                2:   Args.AddLastArg(CmdArgs, options::OPT_remap);
                        1: branch 2 taken
                        1: branch 3 taken
    1620                2:   if (Args.hasArg(options::OPT_g3))
    1621                1:     CmdArgs.push_back("-dD");
    1622                2:   Args.AddLastArg(CmdArgs, options::OPT_H);
    1623                 : 
    1624                2:   AddCPPArgs(Args, CmdArgs);
    1625                 : 
    1626                2:   Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
    1627                2:   Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
    1628                 : 
                        2: branch 0 taken
                        2: branch 1 taken
    1629                4:   for (InputInfoList::const_iterator
    1630                2:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    1631                2:     const InputInfo &II = *it;
    1632                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
    1633                2:     if (II.isPipe())
    1634                0:       CmdArgs.push_back("-");
    1635                 :     else
    1636                2:       CmdArgs.push_back(II.getFilename());
    1637                 :   }
    1638                 : 
    1639                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
    1640                2:                        options::OPT_Xpreprocessor);
    1641                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1642                2:   if (Args.hasArg(options::OPT_fmudflap)) {
    1643                1:     CmdArgs.push_back("-D_MUDFLAP");
    1644                1:     CmdArgs.push_back("-include");
    1645                1:     CmdArgs.push_back("mf-runtime.h");
    1646                 :   }
    1647                 : 
                        0: branch 2 not taken
                        2: branch 3 taken
    1648                2:   if (Args.hasArg(options::OPT_fmudflapth)) {
    1649                0:     CmdArgs.push_back("-D_MUDFLAP");
    1650                0:     CmdArgs.push_back("-D_MUDFLAPTH");
    1651                0:     CmdArgs.push_back("-include");
    1652                0:     CmdArgs.push_back("mf-runtime.h");
    1653                 :   }
    1654                2: }
    1655                 : 
    1656                 : void darwin::CC1::AddCPPArgs(const ArgList &Args,
    1657                2:                              ArgStringList &CmdArgs) const {
    1658                 :   // Derived from cpp spec.
    1659                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1660                2:   if (Args.hasArg(options::OPT_static)) {
    1661                 :     // The gcc spec is broken here, it refers to dynamic but
    1662                 :     // that has been translated. Start by being bug compatible.
    1663                 : 
    1664                 :     // if (!Args.hasArg(arglist.parser.dynamicOption))
    1665                1:     CmdArgs.push_back("-D__STATIC__");
    1666                 :   } else
    1667                1:     CmdArgs.push_back("-D__DYNAMIC__");
    1668                 : 
                        1: branch 2 taken
                        1: branch 3 taken
    1669                2:   if (Args.hasArg(options::OPT_pthread))
    1670                1:     CmdArgs.push_back("-D_REENTRANT");
    1671                2: }
    1672                 : 
    1673                 : void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
    1674                 :                                       Job &Dest, const InputInfo &Output,
    1675                 :                                       const InputInfoList &Inputs,
    1676                 :                                       const ArgList &Args,
    1677                1:                                       const char *LinkingOutput) const {
    1678                1:   ArgStringList CmdArgs;
    1679                 : 
                        1: branch 1 taken
                        0: branch 2 not taken
    1680                1:   assert(Inputs.size() == 1 && "Unexpected number of inputs!");
    1681                 : 
    1682                1:   CmdArgs.push_back("-E");
    1683                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
    1684                2:   if (Args.hasArg(options::OPT_traditional) ||
    1685                 :       Args.hasArg(options::OPT_traditional_cpp))
    1686                0:     CmdArgs.push_back("-traditional-cpp");
    1687                 : 
    1688                1:   ArgStringList OutputArgs;
                        1: branch 1 taken
                        0: branch 2 not taken
    1689                1:   if (Output.isFilename()) {
    1690                1:     OutputArgs.push_back("-o");
    1691                1:     OutputArgs.push_back(Output.getFilename());
    1692                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1693                0:     assert(Output.isPipe() && "Unexpected CC1 output.");
    1694                 :   }
    1695                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    1696                1:   if (Args.hasArg(options::OPT_E)) {
    1697                0:     AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
    1698                 :   } else {
    1699                1:     AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
    1700                1:     CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
    1701                 :   }
    1702                 : 
    1703                1:   Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
    1704                 : 
    1705                1:   const char *CC1Name = getCC1Name(Inputs[0].getType());
    1706                 :   const char *Exec =
    1707                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
    1708                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    1709                1: }
    1710                 : 
    1711                 : void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
    1712                 :                                    Job &Dest, const InputInfo &Output,
    1713                 :                                    const InputInfoList &Inputs,
    1714                 :                                    const ArgList &Args,
    1715                2:                                    const char *LinkingOutput) const {
    1716                2:   const Driver &D = getToolChain().getDriver();
    1717                2:   ArgStringList CmdArgs;
    1718                 : 
                        2: branch 1 taken
                        0: branch 2 not taken
    1719                2:   assert(Inputs.size() == 1 && "Unexpected number of inputs!");
    1720                 : 
    1721                2:   types::ID InputType = Inputs[0].getType();
    1722                 :   const Arg *A;
                        0: branch 2 not taken
                        2: branch 3 taken
    1723                2:   if ((A = Args.getLastArg(options::OPT_traditional)))
    1724                 :     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    1725                0:       << A->getAsString(Args) << "-E";
    1726                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
    1727                2:   if (Output.getType() == types::TY_LLVMAsm)
    1728                0:     CmdArgs.push_back("-emit-llvm");
                        0: branch 1 not taken
                        2: branch 2 taken
    1729                2:   else if (Output.getType() == types::TY_LLVMBC)
    1730                0:     CmdArgs.push_back("-emit-llvm-bc");
                        0: branch 1 not taken
                        2: branch 2 taken
    1731                2:   else if (Output.getType() == types::TY_AST)
    1732                 :     D.Diag(clang::diag::err_drv_no_ast_support)
    1733                0:       << getToolChain().getTripleString();
    1734                 : 
    1735                2:   ArgStringList OutputArgs;
                        2: branch 1 taken
                        0: branch 2 not taken
    1736                2:   if (Output.getType() != types::TY_PCH) {
    1737                2:     OutputArgs.push_back("-o");
                        0: branch 1 not taken
                        2: branch 2 taken
    1738                2:     if (Output.isPipe())
    1739                0:       OutputArgs.push_back("-");
                        1: branch 1 taken
                        1: branch 2 taken
    1740                2:     else if (Output.isNothing())
    1741                1:       OutputArgs.push_back("/dev/null");
    1742                 :     else
    1743                1:       OutputArgs.push_back(Output.getFilename());
    1744                 :   }
    1745                 : 
    1746                 :   // There is no need for this level of compatibility, but it makes
    1747                 :   // diffing easier.
    1748                 :   bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
                        1: branch 2 taken
                        1: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
    1749                2:                           Args.hasArg(options::OPT_S));
    1750                 : 
                        1: branch 1 taken
                        1: branch 2 taken
    1751                2:   if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
    1752                1:     AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
                        1: branch 0 taken
                        0: branch 1 not taken
    1753                1:     if (OutputArgsEarly) {
    1754                1:       AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
    1755                 :     } else {
    1756                0:       AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
    1757                0:       CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
    1758                 :     }
    1759                 :   } else {
    1760                1:     CmdArgs.push_back("-fpreprocessed");
    1761                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    1762                2:     for (InputInfoList::const_iterator
    1763                1:            it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    1764                1:       const InputInfo &II = *it;
    1765                 : 
    1766                 :       // Reject AST inputs.
                        0: branch 1 not taken
                        1: branch 2 taken
    1767                1:       if (II.getType() == types::TY_AST) {
    1768                 :         D.Diag(clang::diag::err_drv_no_ast_support)
    1769                0:           << getToolChain().getTripleString();
    1770                0:         return;
    1771                 :       }
    1772                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    1773                1:       if (II.isPipe())
    1774                0:         CmdArgs.push_back("-");
    1775                 :       else
    1776                1:         CmdArgs.push_back(II.getFilename());
    1777                 :     }
    1778                 : 
                        1: branch 0 taken
                        0: branch 1 not taken
    1779                1:     if (OutputArgsEarly) {
    1780                1:       AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
    1781                 :     } else {
    1782                0:       AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
    1783                0:       CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
    1784                 :     }
    1785                 :   }
    1786                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
    1787                2:   if (Output.getType() == types::TY_PCH) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1788                0:     assert(Output.isFilename() && "Invalid PCH output.");
    1789                 : 
    1790                0:     CmdArgs.push_back("-o");
    1791                 :     // NOTE: gcc uses a temp .s file for this, but there doesn't seem
    1792                 :     // to be a good reason.
    1793                0:     CmdArgs.push_back("/dev/null");
    1794                 : 
    1795                0:     CmdArgs.push_back("--output-pch=");
    1796                0:     CmdArgs.push_back(Output.getFilename());
    1797                 :   }
    1798                 : 
    1799                2:   const char *CC1Name = getCC1Name(Inputs[0].getType());
    1800                 :   const char *Exec =
    1801                2:     Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
                        2: branch 4 taken
                        0: branch 5 not taken
                        2: branch 7 taken
                        0: branch 8 not taken
    1802                2:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    1803                 : }
    1804                 : 
    1805                 : void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
    1806                 :                                     Job &Dest, const InputInfo &Output,
    1807                 :                                     const InputInfoList &Inputs,
    1808                 :                                     const ArgList &Args,
    1809                8:                                     const char *LinkingOutput) const {
    1810                8:   ArgStringList CmdArgs;
    1811                 : 
                        8: branch 1 taken
                        0: branch 2 not taken
    1812                8:   assert(Inputs.size() == 1 && "Unexpected number of inputs.");
    1813                8:   const InputInfo &Input = Inputs[0];
    1814                 : 
    1815                 :   // Bit of a hack, this is only used for original inputs.
    1816                 :   //
    1817                 :   // FIXME: This is broken for preprocessed .s inputs.
                        8: branch 1 taken
                        0: branch 2 not taken
                        2: branch 6 taken
                        6: branch 7 taken
                        2: branch 8 taken
                        6: branch 9 taken
    1818               16:   if (Input.isFilename() &&
    1819                 :       strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
                        0: branch 2 not taken
                        2: branch 3 taken
    1820                2:     if (Args.hasArg(options::OPT_gstabs))
    1821                0:       CmdArgs.push_back("--gstabs");
                        0: branch 2 not taken
                        2: branch 3 taken
    1822                2:     else if (Args.hasArg(options::OPT_g_Group))
    1823                0:       CmdArgs.push_back("--gdwarf2");
    1824                 :   }
    1825                 : 
    1826                 :   // Derived from asm spec.
    1827                8:   AddDarwinArch(Args, CmdArgs);
    1828                 : 
                        0: branch 2 not taken
                        8: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        8: branch 8 taken
                        0: branch 9 not taken
    1829                8:   if (!getDarwinToolChain().isTargetIPhoneOS() ||
    1830                 :       Args.hasArg(options::OPT_force__cpusubtype__ALL))
    1831                8:     CmdArgs.push_back("-force_cpusubtype_ALL");
    1832                 : 
                        5: branch 3 taken
                        3: branch 4 taken
                        5: branch 7 taken
                        0: branch 8 not taken
                        4: branch 11 taken
                        1: branch 12 taken
                        0: branch 15 not taken
                        4: branch 16 taken
                        1: branch 17 taken
                        7: branch 18 taken
    1833                8:   if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
    1834                 :       (Args.hasArg(options::OPT_mkernel) ||
    1835                 :        Args.hasArg(options::OPT_static) ||
    1836                 :        Args.hasArg(options::OPT_fapple_kext)))
    1837                1:     CmdArgs.push_back("-static");
    1838                 : 
    1839                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
    1840                8:                        options::OPT_Xassembler);
    1841                 : 
                        8: branch 1 taken
                        0: branch 2 not taken
    1842                8:   assert(Output.isFilename() && "Unexpected lipo output.");
    1843                8:   CmdArgs.push_back("-o");
    1844                8:   CmdArgs.push_back(Output.getFilename());
    1845                 : 
                        0: branch 1 not taken
                        8: branch 2 taken
    1846                8:   if (Input.isPipe()) {
    1847                0:     CmdArgs.push_back("-");
    1848                 :   } else {
                        8: branch 1 taken
                        0: branch 2 not taken
    1849                8:     assert(Input.isFilename() && "Invalid input.");
    1850                8:     CmdArgs.push_back(Input.getFilename());
    1851                 :   }
    1852                 : 
    1853                 :   // asm_final spec is empty.
    1854                 : 
    1855                 :   const char *Exec =
    1856                8:     Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
    1857                8:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    1858                8: }
    1859                 : 
    1860                 : /// Helper routine for seeing if we should use dsymutil; this is a
    1861                 : /// gcc compatible hack, we should remove it and use the input
    1862                 : /// type information.
    1863                2: static bool isSourceSuffix(const char *Str) {
    1864                 :   // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
    1865                 :   // 'mm'.
    1866                 :   return llvm::StringSwitch<bool>(Str)
    1867                 :            .Case("C", true)
    1868                 :            .Case("c", true)
    1869                 :            .Case("m", true)
    1870                 :            .Case("cc", true)
    1871                 :            .Case("cp", true)
    1872                 :            .Case("mm", true)
    1873                 :            .Case("CPP", true)
    1874                 :            .Case("c++", true)
    1875                 :            .Case("cpp", true)
    1876                 :            .Case("cxx", true)
    1877                2:            .Default(false);
    1878                 : }
    1879                 : 
    1880                 : void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
    1881               26:                                        ArgStringList &CmdArgs) const {
    1882               26:   llvm::StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
    1883                 : 
    1884                 :   // Derived from darwin_arch spec.
    1885               26:   CmdArgs.push_back("-arch");
    1886               26:   CmdArgs.push_back(Args.MakeArgString(ArchName));
    1887                 : 
    1888                 :   // FIXME: Is this needed anymore?
                        0: branch 2 not taken
                       26: branch 3 taken
    1889               26:   if (ArchName == "arm")
    1890                0:     CmdArgs.push_back("-force_cpusubtype_ALL");
    1891               26: }
    1892                 : 
    1893                 : void darwin::Link::AddLinkArgs(const ArgList &Args,
    1894               18:                                ArgStringList &CmdArgs) const {
    1895               18:   const Driver &D = getToolChain().getDriver();
    1896                 : 
    1897                 :   // Derived from the "link" spec.
    1898               18:   Args.AddAllArgs(CmdArgs, options::OPT_static);
                       16: branch 2 taken
                        2: branch 3 taken
    1899               18:   if (!Args.hasArg(options::OPT_static))
    1900               16:     CmdArgs.push_back("-dynamic");
    1901               18:   if (Args.hasArg(options::OPT_fgnu_runtime)) {
    1902                 :     // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
    1903                 :     // here. How do we wish to handle such things?
    1904                 :   }
    1905                 : 
                       15: branch 2 taken
                        3: branch 3 taken
    1906               18:   if (!Args.hasArg(options::OPT_dynamiclib)) {
    1907               15:     AddDarwinArch(Args, CmdArgs);
    1908                 :     // FIXME: Why do this only on this path?
    1909               15:     Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
    1910                 : 
    1911               15:     Args.AddLastArg(CmdArgs, options::OPT_bundle);
    1912               15:     Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
    1913               15:     Args.AddAllArgs(CmdArgs, options::OPT_client__name);
    1914                 : 
    1915                 :     Arg *A;
                       15: branch 2 taken
                        0: branch 3 not taken
                       15: branch 6 taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                       15: branch 11 taken
                        0: branch 12 not taken
                       15: branch 13 taken
    1916               15:     if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
    1917                 :         (A = Args.getLastArg(options::OPT_current__version)) ||
    1918                 :         (A = Args.getLastArg(options::OPT_install__name)))
    1919                 :       D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    1920                0:         << A->getAsString(Args) << "-dynamiclib";
    1921                 : 
    1922               15:     Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
    1923               15:     Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
    1924               15:     Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
    1925                 :   } else {
    1926                3:     CmdArgs.push_back("-dylib");
    1927                 : 
    1928                 :     Arg *A;
                        3: branch 2 taken
                        0: branch 3 not taken
                        3: branch 6 taken
                        0: branch 7 not taken
                        3: branch 10 taken
                        0: branch 11 not taken
                        3: branch 14 taken
                        0: branch 15 not taken
                        3: branch 18 taken
                        0: branch 19 not taken
                        0: branch 22 not taken
                        3: branch 23 taken
                        0: branch 24 not taken
                        3: branch 25 taken
    1929                3:     if ((A = Args.getLastArg(options::OPT_bundle)) ||
    1930                 :         (A = Args.getLastArg(options::OPT_bundle__loader)) ||
    1931                 :         (A = Args.getLastArg(options::OPT_client__name)) ||
    1932                 :         (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
    1933                 :         (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
    1934                 :         (A = Args.getLastArg(options::OPT_private__bundle)))
    1935                 :       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    1936                0:         << A->getAsString(Args) << "-dynamiclib";
    1937                 : 
    1938                 :     Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
    1939                3:                               "-dylib_compatibility_version");
    1940                 :     Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
    1941                3:                               "-dylib_current_version");
    1942                 : 
    1943                3:     AddDarwinArch(Args, CmdArgs);
    1944                 : 
    1945                 :     Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
    1946                3:                               "-dylib_install_name");
    1947                 :   }
    1948                 : 
    1949               18:   Args.AddLastArg(CmdArgs, options::OPT_all__load);
    1950               18:   Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
    1951               18:   Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
                        6: branch 2 taken
                       12: branch 3 taken
    1952               18:   if (getDarwinToolChain().isTargetIPhoneOS())
    1953                6:     Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
    1954               18:   Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
    1955               18:   Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
    1956               18:   Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
    1957               18:   Args.AddLastArg(CmdArgs, options::OPT_dynamic);
    1958               18:   Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
    1959               18:   Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
    1960               18:   Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
    1961               18:   Args.AddAllArgs(CmdArgs, options::OPT_image__base);
    1962               18:   Args.AddAllArgs(CmdArgs, options::OPT_init);
    1963                 : 
    1964                 :   // Adding all arguments doesn't make sense here but this is what gcc does. One
    1965                 :   // of this should always be present thanks to argument translation.
    1966                 :   assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) ||
    1967                 :           Args.hasArg(options::OPT_miphoneos_version_min_EQ)) &&
                        6: branch 2 taken
                       12: branch 3 taken
                        6: branch 6 taken
                        0: branch 7 not taken
    1968               18:          "Missing version argument (lost in translation)?");
    1969                 :   Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
    1970               18:                             "-macosx_version_min");
    1971                 :   Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
    1972               18:                             "-iphoneos_version_min");
    1973               18:   Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
    1974               18:   Args.AddLastArg(CmdArgs, options::OPT_multi__module);
    1975               18:   Args.AddLastArg(CmdArgs, options::OPT_single__module);
    1976               18:   Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
    1977               18:   Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
    1978                 : 
                        1: branch 2 taken
                       17: branch 3 taken
    1979               18:   if (Args.hasArg(options::OPT_fpie))
    1980                1:     CmdArgs.push_back("-pie");
    1981                 : 
    1982               18:   Args.AddLastArg(CmdArgs, options::OPT_prebind);
    1983               18:   Args.AddLastArg(CmdArgs, options::OPT_noprebind);
    1984               18:   Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
    1985               18:   Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
    1986               18:   Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
    1987               18:   Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
    1988               18:   Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
    1989               18:   Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
    1990               18:   Args.AddAllArgs(CmdArgs, options::OPT_segprot);
    1991               18:   Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
    1992               18:   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
    1993               18:   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
    1994               18:   Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
    1995               18:   Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
    1996               18:   Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
    1997               18:   Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
    1998                 : 
    1999               18:   Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
                        6: branch 2 taken
                       12: branch 3 taken
    2000               18:   if (getDarwinToolChain().isTargetIPhoneOS()) {
                        6: branch 2 taken
                        0: branch 3 not taken
    2001                6:     if (!Args.hasArg(options::OPT_isysroot)) {
    2002                6:       CmdArgs.push_back("-syslibroot");
    2003                6:       CmdArgs.push_back("/Developer/SDKs/Extra");
    2004                 :     }
    2005                 :   }
    2006                 : 
    2007               18:   Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
    2008               18:   Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
    2009               18:   Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
    2010               18:   Args.AddAllArgs(CmdArgs, options::OPT_undefined);
    2011               18:   Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
    2012               18:   Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
    2013               18:   Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
    2014               18:   Args.AddAllArgs(CmdArgs, options::OPT_y);
    2015               18:   Args.AddLastArg(CmdArgs, options::OPT_w);
    2016               18:   Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
    2017               18:   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
    2018               18:   Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
    2019               18:   Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
    2020               18:   Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
    2021               18:   Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
    2022               18:   Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
    2023               18:   Args.AddLastArg(CmdArgs, options::OPT_whyload);
    2024               18:   Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
    2025               18:   Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
    2026               18:   Args.AddLastArg(CmdArgs, options::OPT_dylinker);
    2027               18:   Args.AddLastArg(CmdArgs, options::OPT_Mach);
    2028               18: }
    2029                 : 
    2030                 : void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
    2031                 :                                 Job &Dest, const InputInfo &Output,
    2032                 :                                 const InputInfoList &Inputs,
    2033                 :                                 const ArgList &Args,
    2034               18:                                 const char *LinkingOutput) const {
                       18: branch 1 taken
                        0: branch 2 not taken
    2035               18:   assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
    2036                 : 
    2037                 :   // The logic here is derived from gcc's behavior; most of which
    2038                 :   // comes from specs (starting with link_command). Consult gcc for
    2039                 :   // more information.
    2040               18:   ArgStringList CmdArgs;
    2041                 : 
    2042                 :   // I'm not sure why this particular decomposition exists in gcc, but
    2043                 :   // we follow suite for ease of comparison.
    2044               18:   AddLinkArgs(Args, CmdArgs);
    2045                 : 
    2046               18:   Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
    2047               18:   Args.AddAllArgs(CmdArgs, options::OPT_s);
    2048               18:   Args.AddAllArgs(CmdArgs, options::OPT_t);
    2049               18:   Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
    2050               18:   Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
    2051               18:   Args.AddAllArgs(CmdArgs, options::OPT_A);
    2052               18:   Args.AddLastArg(CmdArgs, options::OPT_e);
    2053               18:   Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
    2054               18:   Args.AddAllArgs(CmdArgs, options::OPT_r);
    2055                 : 
    2056               18:   CmdArgs.push_back("-o");
    2057               18:   CmdArgs.push_back(Output.getFilename());
    2058                 : 
                       17: branch 2 taken
                        1: branch 3 taken
                       17: branch 6 taken
                        0: branch 7 not taken
                       17: branch 10 taken
                        0: branch 11 not taken
                       17: branch 12 taken
                        1: branch 13 taken
    2059               35:   if (!Args.hasArg(options::OPT_A) &&
    2060                 :       !Args.hasArg(options::OPT_nostdlib) &&
    2061                 :       !Args.hasArg(options::OPT_nostartfiles)) {
    2062                 :     // Derived from startfile spec.
                        2: branch 2 taken
                       15: branch 3 taken
    2063               17:     if (Args.hasArg(options::OPT_dynamiclib)) {
    2064                 :       // Derived from darwin_dylib1 spec.
                        2: branch 2 taken
                        0: branch 3 not taken
    2065                2:       if (getDarwinToolChain().isTargetIPhoneOS()) {
                        1: branch 2 taken
                        1: branch 3 taken
    2066                2:         if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
    2067                1:           CmdArgs.push_back("-ldylib1.o");
    2068                 :       } else {
                        0: branch 2 not taken
                        0: branch 3 not taken
    2069                0:         if (getDarwinToolChain().isMacosxVersionLT(10, 5))
    2070                0:           CmdArgs.push_back("-ldylib1.o");
                        0: branch 2 not taken
                        0: branch 3 not taken
    2071                0:         else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
    2072                0:           CmdArgs.push_back("-ldylib1.10.5.o");
    2073                 :       }
    2074                 :     } else {
                        2: branch 2 taken
                       13: branch 3 taken
    2075               15:       if (Args.hasArg(options::OPT_bundle)) {
                        2: branch 2 taken
                        0: branch 3 not taken
    2076                2:         if (!Args.hasArg(options::OPT_static)) {
    2077                 :           // Derived from darwin_bundle1 spec.
                        2: branch 2 taken
                        0: branch 3 not taken
    2078                2:           if (getDarwinToolChain().isTargetIPhoneOS()) {
                        1: branch 2 taken
                        1: branch 3 taken
    2079                2:             if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
    2080                1:               CmdArgs.push_back("-lbundle1.o");
    2081                 :           } else {
                        0: branch 2 not taken
                        0: branch 3 not taken
    2082                0:             if (getDarwinToolChain().isMacosxVersionLT(10, 6))
    2083                0:               CmdArgs.push_back("-lbundle1.o");
    2084                 :           }
    2085                 :         }
    2086                 :       } else {
                        0: branch 2 not taken
                       13: branch 3 taken
    2087               13:         if (Args.hasArg(options::OPT_pg)) {
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
    2088                0:           if (Args.hasArg(options::OPT_static) ||
    2089                 :               Args.hasArg(options::OPT_object) ||
    2090                 :               Args.hasArg(options::OPT_preload)) {
    2091                0:             CmdArgs.push_back("-lgcrt0.o");
    2092                 :           } else {
    2093                0:             CmdArgs.push_back("-lgcrt1.o");
    2094                 : 
    2095                 :             // darwin_crt2 spec is empty.
    2096                 :           }
    2097                 :         } else {
                       12: branch 2 taken
                        1: branch 3 taken
                       12: branch 6 taken
                        0: branch 7 not taken
                        0: branch 10 not taken
                       12: branch 11 taken
                        1: branch 12 taken
                       12: branch 13 taken
    2098               13:           if (Args.hasArg(options::OPT_static) ||
    2099                 :               Args.hasArg(options::OPT_object) ||
    2100                 :               Args.hasArg(options::OPT_preload)) {
    2101                1:             CmdArgs.push_back("-lcrt0.o");
    2102                 :           } else {
    2103                 :             // Derived from darwin_crt1 spec.
                        2: branch 2 taken
                       10: branch 3 taken
    2104               12:             if (getDarwinToolChain().isTargetIPhoneOS()) {
                        1: branch 2 taken
                        1: branch 3 taken
    2105                2:               if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
    2106                1:                 CmdArgs.push_back("-lcrt1.o");
    2107                 :               else
    2108                1:                 CmdArgs.push_back("-lcrt1.3.1.o");
    2109                 :             } else {
                        2: branch 2 taken
                        8: branch 3 taken
    2110               10:               if (getDarwinToolChain().isMacosxVersionLT(10, 5))
    2111                2:                 CmdArgs.push_back("-lcrt1.o");
                        7: branch 2 taken
                        1: branch 3 taken
    2112                8:               else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
    2113                7:                 CmdArgs.push_back("-lcrt1.10.5.o");
    2114                 :               else
    2115                1:                 CmdArgs.push_back("-lcrt1.10.6.o");
    2116                 : 
    2117                 :               // darwin_crt2 spec is empty.
    2118                 :             }
    2119                 :           }
    2120                 :         }
    2121                 :       }
    2122                 :     }
    2123                 : 
                       11: branch 2 taken
                        6: branch 3 taken
                        0: branch 6 not taken
                       11: branch 7 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                       17: branch 13 taken
    2124               17:     if (!getDarwinToolChain().isTargetIPhoneOS() &&
    2125                 :         Args.hasArg(options::OPT_shared_libgcc) &&
    2126                 :         getDarwinToolChain().isMacosxVersionLT(10, 5)) {
    2127                 :       const char *Str =
    2128                0:         Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o"));
    2129                0:       CmdArgs.push_back(Str);
    2130                 :     }
    2131                 :   }
    2132                 : 
    2133               18:   Args.AddAllArgs(CmdArgs, options::OPT_L);
    2134                 : 
                        1: branch 2 taken
                       17: branch 3 taken
    2135               18:   if (Args.hasArg(options::OPT_fopenmp))
    2136                 :     // This is more complicated in gcc...
    2137                1:     CmdArgs.push_back("-lgomp");
    2138                 : 
    2139               18:   getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
    2140                 : 
                       19: branch 0 taken
                       18: branch 1 taken
    2141               37:   for (InputInfoList::const_iterator
    2142               18:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2143               19:     const InputInfo &II = *it;
                       12: branch 1 taken
                        7: branch 2 taken
    2144               19:     if (II.isFilename())
    2145               12:       CmdArgs.push_back(II.getFilename());
    2146                 :     else
    2147                7:       II.getInputArg().renderAsInput(Args, CmdArgs);
    2148                 :   }
    2149                 : 
                        4: branch 0 taken
                       14: branch 1 taken
    2150               18:   if (LinkingOutput) {
    2151                4:     CmdArgs.push_back("-arch_multiple");
    2152                4:     CmdArgs.push_back("-final_output");
    2153                4:     CmdArgs.push_back(LinkingOutput);
    2154                 :   }
    2155                 : 
                       17: branch 2 taken
                        1: branch 3 taken
                       17: branch 6 taken
                        0: branch 7 not taken
                       17: branch 10 taken
                        0: branch 11 not taken
                        0: branch 14 not taken
                       17: branch 15 taken
                        1: branch 16 taken
                       17: branch 17 taken
    2156               18:   if (Args.hasArg(options::OPT_fprofile_arcs) ||
    2157                 :       Args.hasArg(options::OPT_fprofile_generate) ||
    2158                 :       Args.hasArg(options::OPT_fcreate_profile) ||
    2159                 :       Args.hasArg(options::OPT_coverage))
    2160                1:     CmdArgs.push_back("-lgcov");
    2161                 : 
                        1: branch 2 taken
                       17: branch 3 taken
    2162               18:   if (Args.hasArg(options::OPT_fnested_functions))
    2163                1:     CmdArgs.push_back("-allow_stack_execute");
    2164                 : 
                       17: branch 2 taken
                        1: branch 3 taken
                       17: branch 6 taken
                        0: branch 7 not taken
                       17: branch 8 taken
                        1: branch 9 taken
    2165               18:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2166                 :       !Args.hasArg(options::OPT_nodefaultlibs)) {
    2167                 :     // FIXME: g++ is more complicated here, it tries to put -lstdc++
    2168                 :     // before -lm, for example.
                        0: branch 2 not taken
                       17: branch 3 taken
    2169               17:     if (getToolChain().getDriver().CCCIsCXX)
    2170                0:       CmdArgs.push_back("-lstdc++");
    2171                 : 
    2172                 :     // link_ssp spec is empty.
    2173                 : 
    2174                 :     // Let the tool chain choose which runtime library to link.
    2175               17:     getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
    2176                 :   }
    2177                 : 
                       17: branch 2 taken
                        1: branch 3 taken
                       17: branch 6 taken
                        0: branch 7 not taken
                       17: branch 10 taken
                        0: branch 11 not taken
    2178               18:   if (!Args.hasArg(options::OPT_A) &&
    2179                 :       !Args.hasArg(options::OPT_nostdlib) &&
    2180                 :       !Args.hasArg(options::OPT_nostartfiles)) {
    2181                 :     // endfile_spec is empty.
    2182                 :   }
    2183                 : 
    2184               18:   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
    2185               18:   Args.AddAllArgs(CmdArgs, options::OPT_F);
    2186                 : 
    2187                 :   const char *Exec =
    2188               18:     Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
    2189               18:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2190                 : 
    2191                 :   // Find the first non-empty base input (we want to ignore linker
    2192                 :   // inputs).
    2193               18:   const char *BaseInput = "";
                       19: branch 1 taken
                        6: branch 2 taken
    2194               25:   for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
                       12: branch 2 taken
                        7: branch 3 taken
    2195               19:     if (Inputs[i].getBaseInput()[0] != '\0') {
    2196               12:       BaseInput = Inputs[i].getBaseInput();
    2197               12:       break;
    2198                 :     }
    2199                 :   }
    2200                 : 
    2201                 :   // Run dsymutil if we are making an executable in a single step.
    2202                 :   //
    2203                 :   // FIXME: Currently we don't want to do this when we are part of a
    2204                 :   // universal build step, as this would end up creating stray temp
    2205                 :   // files.
                       14: branch 0 taken
                        4: branch 1 taken
                        2: branch 4 taken
                       12: branch 5 taken
                        2: branch 8 taken
                        0: branch 9 not taken
                        2: branch 12 taken
                        0: branch 13 not taken
                        2: branch 14 taken
                       16: branch 15 taken
    2206               18:   if (!LinkingOutput &&
    2207                 :       Args.getLastArg(options::OPT_g_Group) &&
    2208                 :       !Args.getLastArg(options::OPT_gstabs) &&
    2209                 :       !Args.getLastArg(options::OPT_g0)) {
    2210                 :     // FIXME: This is gross, but matches gcc. The test only considers
    2211                 :     // the suffix (not the -x type), and then only of the first
    2212                 :     // source input. Awesome.
    2213                2:     const char *Suffix = strrchr(BaseInput, '.');
                        2: branch 0 taken
                        0: branch 1 not taken
                        2: branch 3 taken
                        0: branch 4 not taken
                        2: branch 5 taken
                        0: branch 6 not taken
    2214                2:     if (Suffix && isSourceSuffix(Suffix + 1)) {
    2215                 :       const char *Exec =
    2216                2:         Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil"));
    2217                2:       ArgStringList CmdArgs;
    2218                2:       CmdArgs.push_back(Output.getFilename());
    2219                2:       C.getJobs().addCommand(new Command(JA, *this, Exec, CmdArgs));
    2220                 :     }
    2221               18:   }
    2222               18: }
    2223                 : 
    2224                 : void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
    2225                 :                                 Job &Dest, const InputInfo &Output,
    2226                 :                                 const InputInfoList &Inputs,
    2227                 :                                 const ArgList &Args,
    2228                2:                                 const char *LinkingOutput) const {
    2229                2:   ArgStringList CmdArgs;
    2230                 : 
    2231                2:   CmdArgs.push_back("-create");
                        2: branch 1 taken
                        0: branch 2 not taken
    2232                2:   assert(Output.isFilename() && "Unexpected lipo output.");
    2233                 : 
    2234                2:   CmdArgs.push_back("-output");
    2235                2:   CmdArgs.push_back(Output.getFilename());
    2236                 : 
                        4: branch 0 taken
                        2: branch 1 taken
    2237               12:   for (InputInfoList::const_iterator
    2238                2:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2239                4:     const InputInfo &II = *it;
                        4: branch 1 taken
                        0: branch 2 not taken
    2240                4:     assert(II.isFilename() && "Unexpected lipo input.");
    2241                4:     CmdArgs.push_back(II.getFilename());
    2242                 :   }
    2243                 :   const char *Exec =
    2244                2:     Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo"));
    2245                2:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2246                2: }
    2247                 : 
    2248                 : void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
    2249                 :                                       Job &Dest, const InputInfo &Output,
    2250                 :                                       const InputInfoList &Inputs,
    2251                 :                                       const ArgList &Args,
    2252                0:                                       const char *LinkingOutput) const {
    2253                0:   ArgStringList CmdArgs;
    2254                 : 
    2255                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
    2256                0:                        options::OPT_Xassembler);
    2257                 : 
    2258                0:   CmdArgs.push_back("-o");
                        0: branch 1 not taken
                        0: branch 2 not taken
    2259                0:   if (Output.isPipe())
    2260                0:     CmdArgs.push_back("-");
    2261                 :   else
    2262                0:     CmdArgs.push_back(Output.getFilename());
    2263                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
    2264                0:   for (InputInfoList::const_iterator
    2265                0:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2266                0:     const InputInfo &II = *it;
                        0: branch 1 not taken
                        0: branch 2 not taken
    2267                0:     if (II.isPipe())
    2268                0:       CmdArgs.push_back("-");
    2269                 :     else
    2270                0:       CmdArgs.push_back(II.getFilename());
    2271                 :   }
    2272                 : 
    2273                 :   const char *Exec =
    2274                0:     Args.MakeArgString(getToolChain().GetProgramPath(C, "gas"));
    2275                0:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2276                0: }
    2277                 : 
    2278                 : void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
    2279                 :                                   Job &Dest, const InputInfo &Output,
    2280                 :                                   const InputInfoList &Inputs,
    2281                 :                                   const ArgList &Args,
    2282                0:                                   const char *LinkingOutput) const {
    2283                0:   const Driver &D = getToolChain().getDriver();
    2284                0:   ArgStringList CmdArgs;
    2285                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2286                0:   if ((!Args.hasArg(options::OPT_nostdlib)) &&
    2287                 :       (!Args.hasArg(options::OPT_shared))) {
    2288                0:     CmdArgs.push_back("-e");
    2289                0:     CmdArgs.push_back("_start");
    2290                 :   }
    2291                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
    2292                0:   if (Args.hasArg(options::OPT_static)) {
    2293                0:     CmdArgs.push_back("-Bstatic");
    2294                0:     CmdArgs.push_back("-dn");
    2295                 :   } else {
    2296                 : //    CmdArgs.push_back("--eh-frame-hdr");
    2297                0:     CmdArgs.push_back("-Bdynamic");
                        0: branch 2 not taken
                        0: branch 3 not taken
    2298                0:     if (Args.hasArg(options::OPT_shared)) {
    2299                0:       CmdArgs.push_back("-shared");
    2300                 :     } else {
    2301                0:       CmdArgs.push_back("--dynamic-linker");
    2302                0:       CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
    2303                 :     }
    2304                 :   }
    2305                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
    2306                0:   if (Output.isPipe()) {
    2307                0:     CmdArgs.push_back("-o");
    2308                0:     CmdArgs.push_back("-");
                        0: branch 1 not taken
                        0: branch 2 not taken
    2309                0:   } else if (Output.isFilename()) {
    2310                0:     CmdArgs.push_back("-o");
    2311                0:     CmdArgs.push_back(Output.getFilename());
    2312                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    2313                0:     assert(Output.isNothing() && "Invalid output.");
    2314                 :   }
    2315                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2316                0:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2317                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    2318                0:     if (!Args.hasArg(options::OPT_shared)) {
    2319                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
    2320                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2321                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
    2322                 :     } else {
    2323                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2324                 :     }
    2325                0:     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
    2326                 :   }
    2327                 : 
    2328                 :   CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
    2329                 :                                        + getToolChain().getTripleString()
    2330                0:                                        + "/4.2.4"));
    2331                 : 
    2332                0:   Args.AddAllArgs(CmdArgs, options::OPT_L);
    2333                0:   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
    2334                0:   Args.AddAllArgs(CmdArgs, options::OPT_e);
    2335                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
    2336                0:   for (InputInfoList::const_iterator
    2337                0:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2338                0:     const InputInfo &II = *it;
    2339                 : 
    2340                 :     // Don't try to pass LLVM inputs to a generic gcc.
                        0: branch 1 not taken
                        0: branch 2 not taken
    2341                0:     if (II.getType() == types::TY_LLVMBC)
    2342                 :       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
    2343                0:         << getToolChain().getTripleString();
    2344                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
    2345                0:     if (II.isPipe())
    2346                0:       CmdArgs.push_back("-");
                        0: branch 1 not taken
                        0: branch 2 not taken
    2347                0:     else if (II.isFilename())
    2348                0:       CmdArgs.push_back(II.getFilename());
    2349                 :     else
    2350                0:       II.getInputArg().renderAsInput(Args, CmdArgs);
    2351                 :   }
    2352                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2353                0:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2354                 :       !Args.hasArg(options::OPT_nodefaultlibs)) {
    2355                 :     // FIXME: For some reason GCC passes -lgcc before adding
    2356                 :     // the default system libraries. Just mimic this for now.
    2357                0:     CmdArgs.push_back("-lgcc");
    2358                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
    2359                0:     if (Args.hasArg(options::OPT_pthread))
    2360                0:       CmdArgs.push_back("-pthread");
                        0: branch 2 not taken
                        0: branch 3 not taken
    2361                0:     if (!Args.hasArg(options::OPT_shared))
    2362                0:       CmdArgs.push_back("-lc");
    2363                0:     CmdArgs.push_back("-lgcc");
    2364                 :   }
    2365                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2366                0:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2367                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    2368                0:     if (!Args.hasArg(options::OPT_shared))
    2369                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
    2370                 : //    else
    2371                 : //      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
    2372                 :   }
    2373                 : 
    2374                 :   const char *Exec =
    2375                0:     Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
    2376                0:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2377                0: }
    2378                 : 
    2379                 : void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
    2380                 :                                      Job &Dest, const InputInfo &Output,
    2381                 :                                      const InputInfoList &Inputs,
    2382                 :                                      const ArgList &Args,
    2383                1:                                      const char *LinkingOutput) const {
    2384                1:   ArgStringList CmdArgs;
    2385                 : 
    2386                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
    2387                1:                        options::OPT_Xassembler);
    2388                 : 
    2389                1:   CmdArgs.push_back("-o");
                        0: branch 1 not taken
                        1: branch 2 taken
    2390                1:   if (Output.isPipe())
    2391                0:     CmdArgs.push_back("-");
    2392                 :   else
    2393                1:     CmdArgs.push_back(Output.getFilename());
    2394                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2395                2:   for (InputInfoList::const_iterator
    2396                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2397                1:     const InputInfo &II = *it;
                        0: branch 1 not taken
                        1: branch 2 taken
    2398                1:     if (II.isPipe())
    2399                0:       CmdArgs.push_back("-");
    2400                 :     else
    2401                1:       CmdArgs.push_back(II.getFilename());
    2402                 :   }
    2403                 : 
    2404                 :   const char *Exec =
    2405                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
    2406                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2407                1: }
    2408                 : 
    2409                 : void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
    2410                 :                                  Job &Dest, const InputInfo &Output,
    2411                 :                                  const InputInfoList &Inputs,
    2412                 :                                  const ArgList &Args,
    2413                1:                                  const char *LinkingOutput) const {
    2414                1:   const Driver &D = getToolChain().getDriver();
    2415                1:   ArgStringList CmdArgs;
    2416                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2417                1:   if ((!Args.hasArg(options::OPT_nostdlib)) &&
    2418                 :       (!Args.hasArg(options::OPT_shared))) {
    2419                1:     CmdArgs.push_back("-e");
    2420                1:     CmdArgs.push_back("__start");
    2421                 :   }
    2422                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    2423                1:   if (Args.hasArg(options::OPT_static)) {
    2424                0:     CmdArgs.push_back("-Bstatic");
    2425                 :   } else {
    2426                1:     CmdArgs.push_back("--eh-frame-hdr");
    2427                1:     CmdArgs.push_back("-Bdynamic");
                        0: branch 2 not taken
                        1: branch 3 taken
    2428                1:     if (Args.hasArg(options::OPT_shared)) {
    2429                0:       CmdArgs.push_back("-shared");
    2430                 :     } else {
    2431                1:       CmdArgs.push_back("-dynamic-linker");
    2432                1:       CmdArgs.push_back("/usr/libexec/ld.so");
    2433                 :     }
    2434                 :   }
    2435                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2436                1:   if (Output.isPipe()) {
    2437                0:     CmdArgs.push_back("-o");
    2438                0:     CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2439                1:   } else if (Output.isFilename()) {
    2440                1:     CmdArgs.push_back("-o");
    2441                1:     CmdArgs.push_back(Output.getFilename());
    2442                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    2443                0:     assert(Output.isNothing() && "Invalid output.");
    2444                 :   }
    2445                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2446                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2447                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        1: branch 2 taken
                        0: branch 3 not taken
    2448                1:     if (!Args.hasArg(options::OPT_shared)) {
    2449                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o")));
    2450                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
    2451                 :     } else {
    2452                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
    2453                 :     }
    2454                 :   }
    2455                 : 
    2456                1:   std::string Triple = getToolChain().getTripleString();
                        0: branch 3 not taken
                        1: branch 4 taken
    2457                1:   if (Triple.substr(0, 6) == "x86_64")
    2458                0:     Triple.replace(0, 6, "amd64");
    2459                 :   CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
    2460                1:                                        "/3.3.5"));
    2461                 : 
    2462                1:   Args.AddAllArgs(CmdArgs, options::OPT_L);
    2463                1:   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
    2464                1:   Args.AddAllArgs(CmdArgs, options::OPT_e);
    2465                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2466                2:   for (InputInfoList::const_iterator
    2467                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2468                1:     const InputInfo &II = *it;
    2469                 : 
    2470                 :     // Don't try to pass LLVM inputs to a generic gcc.
                        0: branch 1 not taken
                        1: branch 2 taken
    2471                1:     if (II.getType() == types::TY_LLVMBC)
    2472                 :       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
    2473                0:         << getToolChain().getTripleString();
    2474                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2475                1:     if (II.isPipe())
    2476                0:       CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2477                1:     else if (II.isFilename())
    2478                1:       CmdArgs.push_back(II.getFilename());
    2479                 :     else
    2480                0:       II.getInputArg().renderAsInput(Args, CmdArgs);
    2481                 :   }
    2482                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2483                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2484                 :       !Args.hasArg(options::OPT_nodefaultlibs)) {
    2485                 :     // FIXME: For some reason GCC passes -lgcc before adding
    2486                 :     // the default system libraries. Just mimic this for now.
    2487                1:     CmdArgs.push_back("-lgcc");
    2488                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    2489                1:     if (Args.hasArg(options::OPT_pthread))
    2490                0:       CmdArgs.push_back("-pthread");
                        1: branch 2 taken
                        0: branch 3 not taken
    2491                1:     if (!Args.hasArg(options::OPT_shared))
    2492                1:       CmdArgs.push_back("-lc");
    2493                1:     CmdArgs.push_back("-lgcc");
    2494                 :   }
    2495                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2496                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2497                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        1: branch 2 taken
                        0: branch 3 not taken
    2498                1:     if (!Args.hasArg(options::OPT_shared))
    2499                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
    2500                 :     else
    2501                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
    2502                 :   }
    2503                 : 
    2504                 :   const char *Exec =
    2505                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
    2506                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2507                1: }
    2508                 : 
    2509                 : void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
    2510                 :                                      Job &Dest, const InputInfo &Output,
    2511                 :                                      const InputInfoList &Inputs,
    2512                 :                                      const ArgList &Args,
    2513                1:                                      const char *LinkingOutput) const {
    2514                1:   ArgStringList CmdArgs;
    2515                 : 
    2516                 :   // When building 32-bit code on FreeBSD/amd64, we have to explicitly
    2517                 :   // instruct as in the base system to assemble 32-bit code.
                        0: branch 4 not taken
                        1: branch 5 taken
    2518                1:   if (getToolChain().getArchName() == "i386")
    2519                0:     CmdArgs.push_back("--32");
    2520                 : 
    2521                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
    2522                1:                        options::OPT_Xassembler);
    2523                 : 
    2524                1:   CmdArgs.push_back("-o");
                        0: branch 1 not taken
                        1: branch 2 taken
    2525                1:   if (Output.isPipe())
    2526                0:     CmdArgs.push_back("-");
    2527                 :   else
    2528                1:     CmdArgs.push_back(Output.getFilename());
    2529                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2530                2:   for (InputInfoList::const_iterator
    2531                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2532                1:     const InputInfo &II = *it;
                        0: branch 1 not taken
                        1: branch 2 taken
    2533                1:     if (II.isPipe())
    2534                0:       CmdArgs.push_back("-");
    2535                 :     else
    2536                1:       CmdArgs.push_back(II.getFilename());
    2537                 :   }
    2538                 : 
    2539                 :   const char *Exec =
    2540                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
    2541                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2542                1: }
    2543                 : 
    2544                 : void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
    2545                 :                                  Job &Dest, const InputInfo &Output,
    2546                 :                                  const InputInfoList &Inputs,
    2547                 :                                  const ArgList &Args,
    2548                1:                                  const char *LinkingOutput) const {
    2549                1:   const Driver &D = getToolChain().getDriver();
    2550                1:   ArgStringList CmdArgs;
    2551                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    2552                1:   if (Args.hasArg(options::OPT_static)) {
    2553                0:     CmdArgs.push_back("-Bstatic");
    2554                 :   } else {
    2555                1:     CmdArgs.push_back("--eh-frame-hdr");
                        0: branch 2 not taken
                        1: branch 3 taken
    2556                1:     if (Args.hasArg(options::OPT_shared)) {
    2557                0:       CmdArgs.push_back("-Bshareable");
    2558                 :     } else {
    2559                1:       CmdArgs.push_back("-dynamic-linker");
    2560                1:       CmdArgs.push_back("/libexec/ld-elf.so.1");
    2561                 :     }
    2562                 :   }
    2563                 : 
    2564                 :   // When building 32-bit code on FreeBSD/amd64, we have to explicitly
    2565                 :   // instruct ld in the base system to link 32-bit code.
                        0: branch 4 not taken
                        1: branch 5 taken
    2566                1:   if (getToolChain().getArchName() == "i386") {
    2567                0:     CmdArgs.push_back("-m");
    2568                0:     CmdArgs.push_back("elf_i386_fbsd");
    2569                 :   }
    2570                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2571                1:   if (Output.isPipe()) {
    2572                0:     CmdArgs.push_back("-o");
    2573                0:     CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2574                1:   } else if (Output.isFilename()) {
    2575                1:     CmdArgs.push_back("-o");
    2576                1:     CmdArgs.push_back(Output.getFilename());
    2577                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    2578                0:     assert(Output.isNothing() && "Invalid output.");
    2579                 :   }
    2580                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2581                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2582                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        1: branch 2 taken
                        0: branch 3 not taken
    2583                1:     if (!Args.hasArg(options::OPT_shared)) {
    2584                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
    2585                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2586                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
    2587                 :     } else {
    2588                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2589                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
    2590                 :     }
    2591                 :   }
    2592                 : 
    2593                1:   Args.AddAllArgs(CmdArgs, options::OPT_L);
    2594                1:   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
    2595                1:   Args.AddAllArgs(CmdArgs, options::OPT_e);
    2596                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2597                2:   for (InputInfoList::const_iterator
    2598                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2599                1:     const InputInfo &II = *it;
    2600                 : 
    2601                 :     // Don't try to pass LLVM inputs to a generic gcc.
                        0: branch 1 not taken
                        1: branch 2 taken
    2602                1:     if (II.getType() == types::TY_LLVMBC)
    2603                 :       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
    2604                0:         << getToolChain().getTripleString();
    2605                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2606                1:     if (II.isPipe())
    2607                0:       CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2608                1:     else if (II.isFilename())
    2609                1:       CmdArgs.push_back(II.getFilename());
    2610                 :     else
    2611                0:       II.getInputArg().renderAsInput(Args, CmdArgs);
    2612                 :   }
    2613                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2614                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2615                 :       !Args.hasArg(options::OPT_nodefaultlibs)) {
    2616                 :     // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
    2617                 :     // the default system libraries. Just mimic this for now.
    2618                1:     CmdArgs.push_back("-lgcc");
                        0: branch 0 not taken
                        1: branch 1 taken
    2619                1:     if (D.CCCIsCXX)
    2620                0:       CmdArgs.push_back("-lstdc++");
                        0: branch 2 not taken
                        1: branch 3 taken
    2621                1:     if (Args.hasArg(options::OPT_static)) {
    2622                0:       CmdArgs.push_back("-lgcc_eh");
    2623                 :     } else {
    2624                1:       CmdArgs.push_back("--as-needed");
    2625                1:       CmdArgs.push_back("-lgcc_s");
    2626                1:       CmdArgs.push_back("--no-as-needed");
    2627                 :     }
    2628                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    2629                1:     if (Args.hasArg(options::OPT_pthread))
    2630                0:       CmdArgs.push_back("-lpthread");
    2631                1:     CmdArgs.push_back("-lc");
    2632                 : 
    2633                1:     CmdArgs.push_back("-lgcc");
                        0: branch 2 not taken
                        1: branch 3 taken
    2634                1:     if (Args.hasArg(options::OPT_static)) {
    2635                0:       CmdArgs.push_back("-lgcc_eh");
    2636                 :     } else {
    2637                1:       CmdArgs.push_back("--as-needed");
    2638                1:       CmdArgs.push_back("-lgcc_s");
    2639                1:       CmdArgs.push_back("--no-as-needed");
    2640                 :     }
    2641                 :   }
    2642                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2643                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2644                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        1: branch 2 taken
                        0: branch 3 not taken
    2645                1:     if (!Args.hasArg(options::OPT_shared))
    2646                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
    2647                 :     else
    2648                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
    2649                1:     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
    2650                 :   }
    2651                 : 
    2652                 :   const char *Exec =
    2653                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
    2654                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2655                1: }
    2656                 : 
    2657                 : /// DragonFly Tools
    2658                 : 
    2659                 : // For now, DragonFly Assemble does just about the same as for
    2660                 : // FreeBSD, but this may change soon.
    2661                 : void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
    2662                 :                                        Job &Dest, const InputInfo &Output,
    2663                 :                                        const InputInfoList &Inputs,
    2664                 :                                        const ArgList &Args,
    2665                1:                                        const char *LinkingOutput) const {
    2666                1:   ArgStringList CmdArgs;
    2667                 : 
    2668                 :   // When building 32-bit code on DragonFly/pc64, we have to explicitly
    2669                 :   // instruct as in the base system to assemble 32-bit code.
                        0: branch 4 not taken
                        1: branch 5 taken
    2670                1:   if (getToolChain().getArchName() == "i386")
    2671                0:     CmdArgs.push_back("--32");
    2672                 : 
    2673                 :   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
    2674                1:                        options::OPT_Xassembler);
    2675                 : 
    2676                1:   CmdArgs.push_back("-o");
                        0: branch 1 not taken
                        1: branch 2 taken
    2677                1:   if (Output.isPipe())
    2678                0:     CmdArgs.push_back("-");
    2679                 :   else
    2680                1:     CmdArgs.push_back(Output.getFilename());
    2681                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2682                2:   for (InputInfoList::const_iterator
    2683                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2684                1:     const InputInfo &II = *it;
                        0: branch 1 not taken
                        1: branch 2 taken
    2685                1:     if (II.isPipe())
    2686                0:       CmdArgs.push_back("-");
    2687                 :     else
    2688                1:       CmdArgs.push_back(II.getFilename());
    2689                 :   }
    2690                 : 
    2691                 :   const char *Exec =
    2692                1:     Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
    2693                1:   Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
    2694                1: }
    2695                 : 
    2696                 : void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
    2697                 :                                  Job &Dest, const InputInfo &Output,
    2698                 :                                  const InputInfoList &Inputs,
    2699                 :                                  const ArgList &Args,
    2700                1:                                  const char *LinkingOutput) const {
    2701                1:   const Driver &D = getToolChain().getDriver();
    2702                1:   ArgStringList CmdArgs;
    2703                 : 
                        0: branch 2 not taken
                        1: branch 3 taken
    2704                1:   if (Args.hasArg(options::OPT_static)) {
    2705                0:     CmdArgs.push_back("-Bstatic");
    2706                 :   } else {
                        0: branch 2 not taken
                        1: branch 3 taken
    2707                1:     if (Args.hasArg(options::OPT_shared))
    2708                0:       CmdArgs.push_back("-Bshareable");
    2709                 :     else {
    2710                1:       CmdArgs.push_back("-dynamic-linker");
    2711                1:       CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
    2712                 :     }
    2713                 :   }
    2714                 : 
    2715                 :   // When building 32-bit code on DragonFly/pc64, we have to explicitly
    2716                 :   // instruct ld in the base system to link 32-bit code.
                        0: branch 4 not taken
                        1: branch 5 taken
    2717                1:   if (getToolChain().getArchName() == "i386") {
    2718                0:     CmdArgs.push_back("-m");
    2719                0:     CmdArgs.push_back("elf_i386");
    2720                 :   }
    2721                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2722                1:   if (Output.isPipe()) {
    2723                0:     CmdArgs.push_back("-o");
    2724                0:     CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2725                1:   } else if (Output.isFilename()) {
    2726                1:     CmdArgs.push_back("-o");
    2727                1:     CmdArgs.push_back(Output.getFilename());
    2728                 :   } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
    2729                0:     assert(Output.isNothing() && "Invalid output.");
    2730                 :   }
    2731                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2732                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2733                 :       !Args.hasArg(options::OPT_nostartfiles)) {
                        1: branch 2 taken
                        0: branch 3 not taken
    2734                1:     if (!Args.hasArg(options::OPT_shared)) {
    2735                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
    2736                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2737                1:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
    2738                 :     } else {
    2739                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
    2740                0:       CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
    2741                 :     }
    2742                 :   }
    2743                 : 
    2744                1:   Args.AddAllArgs(CmdArgs, options::OPT_L);
    2745                1:   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
    2746                1:   Args.AddAllArgs(CmdArgs, options::OPT_e);
    2747                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    2748                2:   for (InputInfoList::const_iterator
    2749                1:          it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
    2750                1:     const InputInfo &II = *it;
    2751                 : 
    2752                 :     // Don't try to pass LLVM inputs to a generic gcc.
                        0: branch 1 not taken
                        1: branch 2 taken
    2753                1:     if (II.getType() == types::TY_LLVMBC)
    2754                 :       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
    2755                0:         << getToolChain().getTripleString();
    2756                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    2757                1:     if (II.isPipe())
    2758                0:       CmdArgs.push_back("-");
                        1: branch 1 taken
                        0: branch 2 not taken
    2759                1:     else if (II.isFilename())
    2760                1:       CmdArgs.push_back(II.getFilename());
    2761                 :     else
    2762                0:       II.getInputArg().renderAsInput(Args, CmdArgs);
    2763                 :   }
    2764                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
    2765                1:   if (!Args.hasArg(options::OPT_nostdlib) &&
    2766                 :       !Args.hasArg(options::OPT_nodefaultlibs)) {