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