 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
50.5% |
198 / 392 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
72.7% |
285 / 392 |
| |
|
Line Coverage: |
75.1% |
335 / 446 |
| |
 |
|
 |
1 : //===--- ToolChains.cpp - ToolChain 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 "ToolChains.h"
11 :
12 : #include "clang/Driver/Arg.h"
13 : #include "clang/Driver/ArgList.h"
14 : #include "clang/Driver/Driver.h"
15 : #include "clang/Driver/DriverDiagnostic.h"
16 : #include "clang/Driver/HostInfo.h"
17 : #include "clang/Driver/OptTable.h"
18 : #include "clang/Driver/Option.h"
19 : #include "clang/Driver/Options.h"
20 :
21 : #include "llvm/ADT/StringExtras.h"
22 : #include "llvm/Support/ErrorHandling.h"
23 : #include "llvm/Support/raw_ostream.h"
24 : #include "llvm/System/Path.h"
25 :
26 : #include <cstdlib> // ::getenv
27 :
28 : using namespace clang::driver;
29 : using namespace clang::driver::toolchains;
30 :
31 : /// Darwin - Darwin tool chain for i386 and x86_64.
32 :
33 : Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
34 58: const unsigned (&_DarwinVersion)[3])
35 58: : ToolChain(Host, Triple), TargetInitialized(false)
36 : {
37 : llvm::raw_string_ostream(MacosxVersionMin)
38 : << "10." << std::max(0, (int)_DarwinVersion[0] - 4) << '.'
39 58: << _DarwinVersion[1];
40 58: }
41 :
42 : // FIXME: Can we tablegen this?
43 12: static const char *GetArmArchForMArch(llvm::StringRef Value) {
6: branch 2 taken
6: branch 3 taken
44 12: if (Value == "armv6k")
45 6: return "armv6";
46 :
0: branch 2 not taken
6: branch 3 taken
47 6: if (Value == "armv5tej")
48 0: return "armv5";
49 :
0: branch 2 not taken
6: branch 3 taken
50 6: if (Value == "xscale")
51 0: return "xscale";
52 :
0: branch 2 not taken
6: branch 3 taken
53 6: if (Value == "armv4t")
54 0: return "armv4t";
55 :
6: branch 2 taken
0: branch 3 not taken
6: branch 6 taken
0: branch 7 not taken
6: branch 10 taken
0: branch 11 not taken
6: branch 14 taken
0: branch 15 not taken
0: branch 18 not taken
6: branch 19 taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 26 not taken
0: branch 27 not taken
6: branch 28 taken
0: branch 29 not taken
56 6: if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
57 : Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
58 : Value == "armv7m")
59 6: return "armv7";
60 :
61 0: return 0;
62 : }
63 :
64 : // FIXME: Can we tablegen this?
65 0: static const char *GetArmArchForMCpu(llvm::StringRef Value) {
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 14 not taken
0: branch 15 not taken
0: branch 18 not taken
0: branch 19 not taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 26 not taken
0: branch 27 not taken
0: branch 30 not taken
0: branch 31 not taken
0: branch 34 not taken
0: branch 35 not taken
0: branch 38 not taken
0: branch 39 not taken
0: branch 42 not taken
0: branch 43 not taken
0: branch 44 not taken
0: branch 45 not taken
66 0: if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
67 : Value == "arm946e-s" || Value == "arm966e-s" ||
68 : Value == "arm968e-s" || Value == "arm10e" ||
69 : Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
70 : Value == "arm1026ej-s")
71 0: return "armv5";
72 :
0: branch 2 not taken
0: branch 3 not taken
73 0: if (Value == "xscale")
74 0: return "xscale";
75 :
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 14 not taken
0: branch 15 not taken
0: branch 16 not taken
0: branch 17 not taken
76 0: if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
77 : Value == "arm1176jz-s" || Value == "arm1176jzf-s")
78 0: return "armv6";
79 :
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
80 0: if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
81 0: return "armv7";
82 :
83 0: return 0;
84 : }
85 :
86 32: llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
20: branch 2 taken
12: branch 3 taken
87 32: switch (getTriple().getArch()) {
88 : default:
89 20: return getArchName();
90 :
91 : case llvm::Triple::arm: {
12: branch 2 taken
0: branch 3 not taken
92 12: if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
12: branch 3 taken
0: branch 4 not taken
93 12: if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
94 12: return Arch;
95 :
0: branch 2 not taken
0: branch 3 not taken
96 0: if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
0: branch 3 not taken
0: branch 4 not taken
97 0: if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
98 0: return Arch;
99 :
100 0: return "arm";
101 : }
102 : }
103 : }
104 :
105 : DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
106 : const unsigned (&DarwinVersion)[3],
107 44: const unsigned (&_GCCVersion)[3])
108 44: : Darwin(Host, Triple, DarwinVersion)
109 : {
110 44: GCCVersion[0] = _GCCVersion[0];
111 44: GCCVersion[1] = _GCCVersion[1];
112 44: GCCVersion[2] = _GCCVersion[2];
113 :
114 : // Set up the tool chain paths to match gcc.
115 44: ToolChainDir = "i686-apple-darwin";
116 44: ToolChainDir += llvm::utostr(DarwinVersion[0]);
117 44: ToolChainDir += "/";
118 44: ToolChainDir += llvm::utostr(GCCVersion[0]);
119 44: ToolChainDir += '.';
120 44: ToolChainDir += llvm::utostr(GCCVersion[1]);
121 44: ToolChainDir += '.';
122 44: ToolChainDir += llvm::utostr(GCCVersion[2]);
123 :
124 : // Try the next major version if that tool chain dir is invalid.
125 44: std::string Tmp = "/usr/lib/gcc/" + ToolChainDir;
44: branch 4 taken
0: branch 5 not taken
0: branch 10 not taken
0: branch 11 not taken
126 44: if (!llvm::sys::Path(Tmp).exists()) {
127 44: std::string Next = "i686-apple-darwin";
128 44: Next += llvm::utostr(DarwinVersion[0] + 1);
129 44: Next += "/";
130 44: Next += llvm::utostr(GCCVersion[0]);
131 44: Next += '.';
132 44: Next += llvm::utostr(GCCVersion[1]);
133 44: Next += '.';
134 44: Next += llvm::utostr(GCCVersion[2]);
135 :
136 : // Use that if it exists, otherwise hope the user isn't linking.
137 : //
138 : // FIXME: Drop dependency on gcc's tool chain.
139 44: Tmp = "/usr/lib/gcc/" + Next;
0: branch 4 not taken
44: branch 5 taken
0: branch 10 not taken
0: branch 11 not taken
140 44: if (llvm::sys::Path(Tmp).exists())
141 0: ToolChainDir = Next;
142 : }
143 :
144 44: std::string Path;
8: branch 3 taken
36: branch 4 taken
0: branch 8 not taken
0: branch 9 not taken
145 44: if (getArchName() == "x86_64") {
146 8: Path = getDriver().Dir;
147 8: Path += "/../lib/gcc/";
148 8: Path += ToolChainDir;
149 8: Path += "/x86_64";
150 8: getFilePaths().push_back(Path);
151 :
152 8: Path = "/usr/lib/gcc/";
153 8: Path += ToolChainDir;
154 8: Path += "/x86_64";
155 8: getFilePaths().push_back(Path);
156 : }
157 :
158 44: Path = getDriver().Dir;
159 44: Path += "/../lib/gcc/";
160 44: Path += ToolChainDir;
161 44: getFilePaths().push_back(Path);
162 :
163 44: Path = "/usr/lib/gcc/";
164 44: Path += ToolChainDir;
165 44: getFilePaths().push_back(Path);
166 :
167 44: Path = getDriver().Dir;
168 44: Path += "/../libexec/gcc/";
169 44: Path += ToolChainDir;
170 44: getProgramPaths().push_back(Path);
171 :
172 44: Path = "/usr/libexec/gcc/";
173 44: Path += ToolChainDir;
174 44: getProgramPaths().push_back(Path);
175 :
176 44: getProgramPaths().push_back(getDriver().Dir);
177 44: }
178 :
179 58: Darwin::~Darwin() {
180 : // Free tool implementations.
0: branch 3 not taken
0: branch 4 not taken
0: branch 8 not taken
0: branch 9 not taken
68: branch 13 taken
58: branch 14 taken
181 126: for (llvm::DenseMap<unsigned, Tool*>::iterator
182 58: it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
68: branch 9 taken
0: branch 10 not taken
183 68: delete it->second;
0: branch 3 not taken
0: branch 4 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 15 not taken
58: branch 16 taken
184 58: }
185 :
186 68: Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
187 : Action::ActionClass Key;
34: branch 3 taken
34: branch 4 taken
188 68: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
189 34: Key = Action::AnalyzeJobClass;
190 : else
191 34: Key = JA.getKind();
192 :
193 68: Tool *&T = Tools[Key];
68: branch 0 taken
0: branch 1 not taken
194 68: if (!T) {
0: branch 0 not taken
1: branch 1 taken
35: branch 2 taken
2: branch 3 taken
9: branch 4 taken
19: branch 5 taken
2: branch 6 taken
0: branch 7 not taken
195 68: switch (Key) {
196 : case Action::InputClass:
197 : case Action::BindArchClass:
198 0: assert(0 && "Invalid tool kind.");
199 : case Action::PreprocessJobClass:
200 1: T = new tools::darwin::Preprocess(*this); break;
201 : case Action::AnalyzeJobClass:
202 35: T = new tools::Clang(*this); break;
203 : case Action::PrecompileJobClass:
204 : case Action::CompileJobClass:
205 2: T = new tools::darwin::Compile(*this); break;
206 : case Action::AssembleJobClass:
207 9: T = new tools::darwin::Assemble(*this); break;
208 : case Action::LinkJobClass:
209 19: T = new tools::darwin::Link(*this); break;
210 : case Action::LipoJobClass:
211 2: T = new tools::darwin::Lipo(*this); break;
212 : }
213 : }
214 :
215 68: return *T;
216 : }
217 :
218 : void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args,
219 12: ArgStringList &CmdArgs) const {
220 : // FIXME: Derive these correctly.
2: branch 3 taken
10: branch 4 taken
221 12: if (getArchName() == "x86_64") {
222 : CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
223 2: "/x86_64"));
224 : // Intentionally duplicated for (temporary) gcc bug compatibility.
225 : CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
226 2: "/x86_64"));
227 : }
228 12: CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
229 12: CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
230 : // Intentionally duplicated for (temporary) gcc bug compatibility.
231 12: CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
232 : CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
233 12: "/../../../" + ToolChainDir));
234 : CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
235 12: "/../../.."));
236 12: }
237 :
238 : void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args,
239 11: ArgStringList &CmdArgs) const {
240 : // Note that this routine is only used for targetting OS X.
241 :
242 : // Derived from libgcc and lib specs but refactored.
1: branch 2 taken
10: branch 3 taken
243 11: if (Args.hasArg(options::OPT_static)) {
244 1: CmdArgs.push_back("-lgcc_static");
245 : } else {
0: branch 2 not taken
10: branch 3 taken
246 10: if (Args.hasArg(options::OPT_static_libgcc)) {
247 0: CmdArgs.push_back("-lgcc_eh");
0: branch 2 not taken
10: branch 3 taken
248 10: } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
249 : // Derived from darwin_iphoneos_libgcc spec.
0: branch 1 not taken
0: branch 2 not taken
250 0: if (isTargetIPhoneOS()) {
251 0: CmdArgs.push_back("-lgcc_s.1");
252 : } else {
253 0: CmdArgs.push_back("-lgcc_s.10.5");
254 : }
10: branch 2 taken
0: branch 3 not taken
0: branch 7 not taken
10: branch 8 taken
0: branch 11 not taken
0: branch 12 not taken
10: branch 13 taken
0: branch 14 not taken
255 10: } else if (Args.hasArg(options::OPT_shared_libgcc) ||
256 : Args.hasFlag(options::OPT_fexceptions,
257 : options::OPT_fno_exceptions) ||
258 : Args.hasArg(options::OPT_fgnu_runtime)) {
259 : // FIXME: This is probably broken on 10.3?
2: branch 1 taken
8: branch 2 taken
260 10: if (isMacosxVersionLT(10, 5))
261 2: CmdArgs.push_back("-lgcc_s.10.4");
7: branch 1 taken
1: branch 2 taken
262 8: else if (isMacosxVersionLT(10, 6))
263 7: CmdArgs.push_back("-lgcc_s.10.5");
264 : } else {
0: branch 1 not taken
0: branch 2 not taken
265 0: if (isMacosxVersionLT(10, 3, 9))
266 : ; // Do nothing.
0: branch 1 not taken
0: branch 2 not taken
267 0: else if (isMacosxVersionLT(10, 5))
268 0: CmdArgs.push_back("-lgcc_s.10.4");
0: branch 1 not taken
0: branch 2 not taken
269 0: else if (isMacosxVersionLT(10, 6))
270 0: CmdArgs.push_back("-lgcc_s.10.5");
271 : }
272 :
10: branch 1 taken
0: branch 2 not taken
9: branch 4 taken
1: branch 5 taken
9: branch 6 taken
1: branch 7 taken
273 10: if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) {
274 9: CmdArgs.push_back("-lgcc");
275 9: CmdArgs.push_back("-lSystem");
276 : } else {
277 1: CmdArgs.push_back("-lSystem");
278 1: CmdArgs.push_back("-lgcc");
279 : }
280 : }
281 11: }
282 :
283 : DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
284 14: const unsigned (&DarwinVersion)[3])
285 14: : Darwin(Host, Triple, DarwinVersion)
286 : {
287 : // We expect 'as', 'ld', etc. to be adjacent to our install dir.
288 14: getProgramPaths().push_back(getDriver().Dir);
289 14: }
290 :
291 : void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
292 6: ArgStringList &CmdArgs) const {
293 : // The Clang toolchain uses explicit paths for internal libraries.
294 6: }
295 :
296 : void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
297 6: ArgStringList &CmdArgs) const {
298 : // Darwin doesn't support real static executables, don't link any runtime
299 : // libraries with -static.
0: branch 2 not taken
6: branch 3 taken
300 6: if (Args.hasArg(options::OPT_static))
301 0: return;
302 :
303 : // Reject -static-libgcc for now, we can deal with this when and if someone
304 : // cares. This is useful in situations where someone wants to statically link
305 : // something like libstdc++, and needs its runtime support routines.
0: branch 2 not taken
6: branch 3 taken
306 6: if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
307 : getDriver().Diag(clang::diag::err_drv_unsupported_opt)
308 0: << A->getAsString(Args);
309 0: return;
310 : }
311 :
312 : // Otherwise link libSystem, then the dynamic runtime library, and finally any
313 : // target specific static runtime library.
314 6: CmdArgs.push_back("-lSystem");
315 :
316 : // Select the dynamic runtime library and the target specific static library.
317 6: const char *DarwinStaticLib = 0;
6: branch 1 taken
0: branch 2 not taken
318 6: if (isTargetIPhoneOS()) {
319 6: CmdArgs.push_back("-lgcc_s.1");
320 :
321 : // We may need some static functions for armv6/thumb which are required to
322 : // be in the same linkage unit as their caller.
3: branch 3 taken
3: branch 4 taken
323 6: if (getDarwinArchName(Args) == "armv6")
324 3: DarwinStaticLib = "libclang_rt.armv6.a";
325 : } else {
326 : // The dynamic runtime library was merged with libSystem for 10.6 and
327 : // beyond; only 10.4 and 10.5 need an additional runtime library.
0: branch 1 not taken
0: branch 2 not taken
328 0: if (isMacosxVersionLT(10, 5))
329 0: CmdArgs.push_back("-lgcc_s.10.4");
0: branch 1 not taken
0: branch 2 not taken
330 0: else if (isMacosxVersionLT(10, 6))
331 0: CmdArgs.push_back("-lgcc_s.10.5");
332 :
333 : // For OS X, we only need a static runtime library when targetting 10.4, to
334 : // provide versions of the static functions which were omitted from
335 : // 10.4.dylib.
0: branch 1 not taken
0: branch 2 not taken
336 0: if (isMacosxVersionLT(10, 5))
337 0: DarwinStaticLib = "libclang_rt.10.4.a";
338 : }
339 :
340 : /// Add the target specific static library, if needed.
3: branch 0 taken
3: branch 1 taken
341 6: if (DarwinStaticLib) {
342 3: llvm::sys::Path P(getDriver().ResourceDir);
343 3: P.appendComponent("lib");
344 3: P.appendComponent("darwin");
345 3: P.appendComponent(DarwinStaticLib);
346 :
347 : // For now, allow missing resource libraries to support developers who may
348 : // not have compiler-rt checked out or integrated into their build.
3: branch 1 taken
0: branch 2 not taken
349 3: if (!P.exists())
350 : getDriver().Diag(clang::diag::warn_drv_missing_resource_library)
351 3: << P.str();
352 : else
353 0: CmdArgs.push_back(Args.MakeArgString(P.str()));
354 : }
355 : }
356 :
357 : DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
358 52: const char *BoundArch) const {
359 52: DerivedArgList *DAL = new DerivedArgList(Args, false);
360 52: const OptTable &Opts = getDriver().getOpts();
361 :
362 : // FIXME: We really want to get out of the tool chain level argument
363 : // translation business, as it makes the driver functionality much
364 : // more opaque. For now, we follow gcc closely solely for the
365 : // purpose of easily achieving feature parity & testability. Once we
366 : // have something that works, we should reevaluate each translation
367 : // and try to push it down into tool specific logic.
368 :
369 52: Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
370 52: Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
5: branch 0 taken
47: branch 1 taken
1: branch 2 taken
4: branch 3 taken
371 53: if (OSXVersion && iPhoneVersion) {
372 : getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
373 : << OSXVersion->getAsString(Args)
374 1: << iPhoneVersion->getAsString(Args);
375 1: iPhoneVersion = 0;
47: branch 0 taken
4: branch 1 taken
39: branch 2 taken
8: branch 3 taken
376 51: } else if (!OSXVersion && !iPhoneVersion) {
377 : // If neither OS X nor iPhoneOS targets were specified, check for
378 : // environment defines.
379 39: const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET");
380 39: const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
381 :
382 : // Ignore empty strings.
2: branch 0 taken
37: branch 1 taken
0: branch 2 not taken
2: branch 3 taken
383 39: if (OSXTarget && OSXTarget[0] == '\0')
384 0: OSXTarget = 0;
2: branch 0 taken
37: branch 1 taken
0: branch 2 not taken
2: branch 3 taken
385 39: if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0')
386 0: iPhoneOSTarget = 0;
387 :
388 : // Diagnose conflicting deployment targets, and choose default platform
389 : // based on the tool chain.
390 : //
391 : // FIXME: Don't hardcode default here.
2: branch 0 taken
37: branch 1 taken
0: branch 2 not taken
2: branch 3 taken
392 39: if (OSXTarget && iPhoneOSTarget) {
393 : // FIXME: We should see if we can get away with warning or erroring on
394 : // this. Perhaps put under -pedantic?
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
395 0: if (getTriple().getArch() == llvm::Triple::arm ||
396 : getTriple().getArch() == llvm::Triple::thumb)
397 0: OSXVersion = 0;
398 : else
399 0: iPhoneVersion = 0;
400 : }
401 :
2: branch 0 taken
37: branch 1 taken
402 39: if (OSXTarget) {
403 2: const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
404 2: OSXVersion = DAL->MakeJoinedArg(0, O, OSXTarget);
405 2: DAL->append(OSXVersion);
2: branch 0 taken
35: branch 1 taken
406 37: } else if (iPhoneOSTarget) {
407 2: const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
408 2: iPhoneVersion = DAL->MakeJoinedArg(0, O, iPhoneOSTarget);
409 2: DAL->append(iPhoneVersion);
410 : } else {
411 : // Otherwise, choose a default platform based on the tool chain.
412 : //
413 : // FIXME: Don't hardcode default here.
29: branch 2 taken
6: branch 3 taken
0: branch 6 not taken
29: branch 7 taken
6: branch 8 taken
29: branch 9 taken
414 35: if (getTriple().getArch() == llvm::Triple::arm ||
415 : getTriple().getArch() == llvm::Triple::thumb) {
416 6: const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
417 6: iPhoneVersion = DAL->MakeJoinedArg(0, O, "3.0");
418 6: DAL->append(iPhoneVersion);
419 : } else {
420 29: const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
421 29: OSXVersion = DAL->MakeJoinedArg(0, O, MacosxVersionMin);
422 29: DAL->append(OSXVersion);
423 : }
424 : }
425 : }
426 :
427 : // Set the tool chain target information.
428 : unsigned Major, Minor, Micro;
429 : bool HadExtra;
36: branch 0 taken
16: branch 1 taken
430 52: if (OSXVersion) {
0: branch 0 not taken
36: branch 1 taken
431 36: assert(!iPhoneVersion && "Unknown target platform!");
36: branch 2 taken
0: branch 3 not taken
36: branch 4 taken
0: branch 5 not taken
36: branch 6 taken
0: branch 7 not taken
36: branch 8 taken
0: branch 9 not taken
0: branch 10 not taken
36: branch 11 taken
0: branch 12 not taken
36: branch 13 taken
432 36: if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
433 : Micro, HadExtra) || HadExtra ||
434 : Major != 10 || Minor >= 10 || Micro >= 10)
435 : getDriver().Diag(clang::diag::err_drv_invalid_version_number)
436 0: << OSXVersion->getAsString(Args);
437 : } else {
0: branch 0 not taken
16: branch 1 taken
438 16: assert(iPhoneVersion && "Unknown target platform!");
16: branch 2 taken
0: branch 3 not taken
16: branch 4 taken
0: branch 5 not taken
16: branch 6 taken
0: branch 7 not taken
16: branch 8 taken
0: branch 9 not taken
0: branch 10 not taken
16: branch 11 taken
0: branch 12 not taken
16: branch 13 taken
439 16: if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
440 : Micro, HadExtra) || HadExtra ||
441 : Major >= 10 || Minor >= 100 || Micro >= 100)
442 : getDriver().Diag(clang::diag::err_drv_invalid_version_number)
443 0: << iPhoneVersion->getAsString(Args);
444 : }
445 52: setTarget(iPhoneVersion, Major, Minor, Micro);
446 :
414: branch 2 taken
52: branch 3 taken
447 466: for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
448 414: Arg *A = *it;
449 :
5: branch 3 taken
409: branch 4 taken
450 414: if (A->getOption().matches(options::OPT_Xarch__)) {
451 : // FIXME: Canonicalize name.
1: branch 4 taken
4: branch 5 taken
452 5: if (getArchName() != A->getValue(Args, 0))
453 1: continue;
454 :
455 : // FIXME: The arg is leaked here, and we should have a nicer
456 : // interface for this.
457 4: unsigned Prev, Index = Prev = A->getIndex() + 1;
458 4: Arg *XarchArg = Opts.ParseOneArg(Args, Index);
459 :
460 : // If the argument parsing failed or more than one argument was
461 : // consumed, the -Xarch_ argument's parameter tried to consume
462 : // extra arguments. Emit an error and ignore.
463 : //
464 : // We also want to disallow any options which would alter the
465 : // driver behavior; that isn't going to work in our model. We
466 : // use isDriverOption() as an approximation, although things
467 : // like -O4 are going to slip through.
3: branch 0 taken
1: branch 1 taken
2: branch 2 taken
1: branch 3 taken
1: branch 6 taken
1: branch 7 taken
3: branch 8 taken
1: branch 9 taken
468 4: if (!XarchArg || Index > Prev + 1 ||
469 : XarchArg->getOption().isDriverOption()) {
470 : getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
471 3: << A->getAsString(Args);
472 3: continue;
473 : }
474 :
475 1: XarchArg->setBaseArg(A);
476 1: A = XarchArg;
477 : }
478 :
479 : // Sob. These is strictly gcc compatible for the time being. Apple
480 : // gcc translates options twice, which means that self-expanding
481 : // options add duplicates.
408: branch 2 taken
1: branch 3 taken
0: branch 4 not taken
1: branch 5 taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
482 410: switch ((options::ID) A->getOption().getID()) {
483 : default:
484 408: DAL->append(A);
485 408: break;
486 :
487 : case options::OPT_mkernel:
488 : case options::OPT_fapple_kext:
489 1: DAL->append(A);
490 1: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
491 1: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
492 1: break;
493 :
494 : case options::OPT_dependency_file:
495 : DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
496 0: A->getValue(Args)));
497 0: break;
498 :
499 : case options::OPT_gfull:
500 1: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
501 : DAL->append(DAL->MakeFlagArg(A,
502 1: Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
503 1: break;
504 :
505 : case options::OPT_gused:
506 0: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
507 : DAL->append(DAL->MakeFlagArg(A,
508 0: Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
509 0: break;
510 :
511 : case options::OPT_fterminated_vtables:
512 : case options::OPT_findirect_virtual_calls:
513 : DAL->append(DAL->MakeFlagArg(A,
514 0: Opts.getOption(options::OPT_fapple_kext)));
515 0: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
516 0: break;
517 :
518 : case options::OPT_shared:
519 0: DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
520 0: break;
521 :
522 : case options::OPT_fconstant_cfstrings:
523 : DAL->append(DAL->MakeFlagArg(A,
524 0: Opts.getOption(options::OPT_mconstant_cfstrings)));
525 0: break;
526 :
527 : case options::OPT_fno_constant_cfstrings:
528 : DAL->append(DAL->MakeFlagArg(A,
529 0: Opts.getOption(options::OPT_mno_constant_cfstrings)));
530 0: break;
531 :
532 : case options::OPT_Wnonportable_cfstrings:
533 : DAL->append(DAL->MakeFlagArg(A,
534 0: Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
535 0: break;
536 :
537 : case options::OPT_Wno_nonportable_cfstrings:
538 : DAL->append(DAL->MakeFlagArg(A,
539 0: Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
540 0: break;
541 :
542 : case options::OPT_fpascal_strings:
543 : DAL->append(DAL->MakeFlagArg(A,
544 0: Opts.getOption(options::OPT_mpascal_strings)));
545 0: break;
546 :
547 : case options::OPT_fno_pascal_strings:
548 : DAL->append(DAL->MakeFlagArg(A,
549 0: Opts.getOption(options::OPT_mno_pascal_strings)));
550 : break;
551 : }
552 : }
553 :
22: branch 2 taken
30: branch 3 taken
8: branch 6 taken
14: branch 7 taken
38: branch 8 taken
14: branch 9 taken
554 52: if (getTriple().getArch() == llvm::Triple::x86 ||
555 : getTriple().getArch() == llvm::Triple::x86_64)
38: branch 2 taken
0: branch 3 not taken
556 38: if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
557 : DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
558 38: "core2"));
559 :
560 : // Add the arch options based on the particular spelling of -arch, to match
561 : // how the driver driver works.
15: branch 0 taken
37: branch 1 taken
562 52: if (BoundArch) {
563 15: llvm::StringRef Name = BoundArch;
564 15: const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
565 15: const Option *MArch = Opts.getOption(options::OPT_march_EQ);
566 :
567 : // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
568 : // which defines the list of which architectures we accept.
15: branch 2 taken
0: branch 3 not taken
569 15: if (Name == "ppc")
570 : ;
0: branch 2 not taken
15: branch 3 taken
571 15: else if (Name == "ppc601")
572 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "601"));
0: branch 2 not taken
15: branch 3 taken
573 15: else if (Name == "ppc603")
574 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "603"));
0: branch 2 not taken
15: branch 3 taken
575 15: else if (Name == "ppc604")
576 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "604"));
0: branch 2 not taken
15: branch 3 taken
577 15: else if (Name == "ppc604e")
578 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e"));
0: branch 2 not taken
15: branch 3 taken
579 15: else if (Name == "ppc750")
580 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "750"));
0: branch 2 not taken
15: branch 3 taken
581 15: else if (Name == "ppc7400")
582 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400"));
0: branch 2 not taken
15: branch 3 taken
583 15: else if (Name == "ppc7450")
584 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450"));
0: branch 2 not taken
15: branch 3 taken
585 15: else if (Name == "ppc970")
586 0: DAL->append(DAL->MakeJoinedArg(0, MCpu, "970"));
587 :
0: branch 2 not taken
15: branch 3 taken
588 15: else if (Name == "ppc64")
589 0: DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
590 :
13: branch 2 taken
2: branch 3 taken
591 15: else if (Name == "i386")
592 : ;
0: branch 2 not taken
13: branch 3 taken
593 13: else if (Name == "i486")
594 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "i486"));
0: branch 2 not taken
13: branch 3 taken
595 13: else if (Name == "i586")
596 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "i586"));
0: branch 2 not taken
13: branch 3 taken
597 13: else if (Name == "i686")
598 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "i686"));
0: branch 2 not taken
13: branch 3 taken
599 13: else if (Name == "pentium")
600 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium"));
0: branch 2 not taken
13: branch 3 taken
601 13: else if (Name == "pentium2")
602 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
0: branch 2 not taken
13: branch 3 taken
603 13: else if (Name == "pentpro")
604 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro"));
0: branch 2 not taken
13: branch 3 taken
605 13: else if (Name == "pentIIm3")
606 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
607 :
2: branch 2 taken
11: branch 3 taken
608 13: else if (Name == "x86_64")
609 2: DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
610 :
1: branch 2 taken
10: branch 3 taken
611 11: else if (Name == "arm")
612 1: DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
0: branch 2 not taken
10: branch 3 taken
613 10: else if (Name == "armv4t")
614 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
0: branch 2 not taken
10: branch 3 taken
615 10: else if (Name == "armv5")
616 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej"));
0: branch 2 not taken
10: branch 3 taken
617 10: else if (Name == "xscale")
618 0: DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale"));
3: branch 2 taken
7: branch 3 taken
619 10: else if (Name == "armv6")
620 3: DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k"));
7: branch 2 taken
0: branch 3 not taken
621 7: else if (Name == "armv7")
622 7: DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a"));
623 :
624 : else
625 0: llvm_unreachable("invalid Darwin arch");
626 : }
627 :
628 52: return DAL;
629 : }
630 :
631 34: bool Darwin::IsUnwindTablesDefault() const {
632 : // FIXME: Gross; we should probably have some separate target
633 : // definition, possibly even reusing the one in clang.
634 34: return getArchName() == "x86_64";
635 : }
636 :
637 34: bool Darwin::UseDwarfDebugFlags() const {
1: branch 1 taken
33: branch 2 taken
638 34: if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
639 1: return S[0] != '\0';
640 33: return false;
641 : }
642 :
643 29: const char *Darwin::GetDefaultRelocationModel() const {
644 29: return "pic";
645 : }
646 :
647 34: const char *Darwin::GetForcedPicModel() const {
5: branch 3 taken
29: branch 4 taken
648 34: if (getArchName() == "x86_64")
649 5: return "pic";
650 29: return 0;
651 : }
652 :
653 : /// Generic_GCC - A tool chain using the 'gcc' command to perform
654 : /// all subcommands; this relies on gcc translating the majority of
655 : /// command line options.
656 :
657 192: Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
658 192: : ToolChain(Host, Triple) {
659 192: getProgramPaths().push_back(getDriver().Dir);
660 192: }
661 :
662 192: Generic_GCC::~Generic_GCC() {
663 : // Free tool implementations.
37: branch 3 taken
33: branch 4 taken
0: branch 8 not taken
0: branch 9 not taken
155: branch 13 taken
159: branch 14 taken
664 384: for (llvm::DenseMap<unsigned, Tool*>::iterator
665 192: it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
37: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
155: branch 9 taken
0: branch 10 not taken
666 192: delete it->second;
33: branch 2 taken
0: branch 3 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 12 not taken
159: branch 13 taken
667 192: }
668 :
669 : Tool &Generic_GCC::SelectTool(const Compilation &C,
670 189: const JobAction &JA) const {
671 : Action::ActionClass Key;
160: branch 3 taken
29: branch 4 taken
672 189: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
673 160: Key = Action::AnalyzeJobClass;
674 : else
675 29: Key = JA.getKind();
676 :
677 189: Tool *&T = Tools[Key];
186: branch 0 taken
3: branch 1 taken
678 189: if (!T) {
0: branch 0 not taken
3: branch 1 taken
1: branch 2 taken
157: branch 3 taken
7: branch 4 taken
10: branch 5 taken
8: branch 6 taken
0: branch 7 not taken
0: branch 8 not taken
679 186: switch (Key) {
680 : case Action::InputClass:
681 : case Action::BindArchClass:
682 0: assert(0 && "Invalid tool kind.");
683 : case Action::PreprocessJobClass:
684 3: T = new tools::gcc::Preprocess(*this); break;
685 : case Action::PrecompileJobClass:
686 1: T = new tools::gcc::Precompile(*this); break;
687 : case Action::AnalyzeJobClass:
688 157: T = new tools::Clang(*this); break;
689 : case Action::CompileJobClass:
690 7: T = new tools::gcc::Compile(*this); break;
691 : case Action::AssembleJobClass:
692 10: T = new tools::gcc::Assemble(*this); break;
693 : case Action::LinkJobClass:
694 8: T = new tools::gcc::Link(*this); break;
695 :
696 : // This is a bit ungeneric, but the only platform using a driver
697 : // driver is Darwin.
698 : case Action::LipoJobClass:
699 0: T = new tools::darwin::Lipo(*this); break;
700 : }
701 : }
702 :
703 189: return *T;
704 : }
705 :
706 154: bool Generic_GCC::IsUnwindTablesDefault() const {
707 : // FIXME: Gross; we should probably have some separate target
708 : // definition, possibly even reusing the one in clang.
709 154: return getArchName() == "x86_64";
710 : }
711 :
712 151: const char *Generic_GCC::GetDefaultRelocationModel() const {
713 151: return "static";
714 : }
715 :
716 154: const char *Generic_GCC::GetForcedPicModel() const {
717 154: return 0;
718 : }
719 :
720 : DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
721 155: const char *BoundArch) const {
722 155: return new DerivedArgList(Args, true);
723 : }
724 :
725 : /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
726 :
727 1: OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
728 1: : Generic_GCC(Host, Triple) {
729 1: getFilePaths().push_back(getDriver().Dir + "/../lib");
730 1: getFilePaths().push_back("/usr/lib");
731 1: }
732 :
733 3: Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
734 : Action::ActionClass Key;
1: branch 3 taken
2: branch 4 taken
735 3: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
736 1: Key = Action::AnalyzeJobClass;
737 : else
738 2: Key = JA.getKind();
739 :
740 3: Tool *&T = Tools[Key];
3: branch 0 taken
0: branch 1 not taken
741 3: if (!T) {
1: branch 0 taken
1: branch 1 taken
1: branch 2 taken
742 3: switch (Key) {
743 : case Action::AssembleJobClass:
744 1: T = new tools::openbsd::Assemble(*this); break;
745 : case Action::LinkJobClass:
746 1: T = new tools::openbsd::Link(*this); break;
747 : default:
748 1: T = &Generic_GCC::SelectTool(C, JA);
749 : }
750 : }
751 :
752 3: return *T;
753 : }
754 :
755 : /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
756 :
757 1: FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
758 1: : Generic_GCC(Host, Triple) {
0: branch 0 not taken
1: branch 1 taken
1: branch 2 taken
1: branch 3 taken
759 1: if (Lib32) {
760 0: getFilePaths().push_back(getDriver().Dir + "/../lib32");
761 0: getFilePaths().push_back("/usr/lib32");
762 : } else {
763 1: getFilePaths().push_back(getDriver().Dir + "/../lib");
764 1: getFilePaths().push_back("/usr/lib");
765 : }
766 1: }
767 :
768 3: Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
769 : Action::ActionClass Key;
1: branch 3 taken
2: branch 4 taken
770 3: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
771 1: Key = Action::AnalyzeJobClass;
772 : else
773 2: Key = JA.getKind();
774 :
775 3: Tool *&T = Tools[Key];
3: branch 0 taken
0: branch 1 not taken
776 3: if (!T) {
1: branch 0 taken
1: branch 1 taken
1: branch 2 taken
777 3: switch (Key) {
778 : case Action::AssembleJobClass:
779 1: T = new tools::freebsd::Assemble(*this); break;
780 : case Action::LinkJobClass:
781 1: T = new tools::freebsd::Link(*this); break;
782 : default:
783 1: T = &Generic_GCC::SelectTool(C, JA);
784 : }
785 : }
786 :
787 3: return *T;
788 : }
789 :
790 : /// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
791 :
792 0: AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
793 0: : Generic_GCC(Host, Triple) {
794 :
795 0: getProgramPaths().push_back(getDriver().Dir);
796 :
797 0: getFilePaths().push_back(getDriver().Dir + "/../lib");
798 0: getFilePaths().push_back("/usr/lib");
799 0: getFilePaths().push_back("/usr/sfw/lib");
800 0: getFilePaths().push_back("/opt/gcc4/lib");
801 0: getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
802 :
803 0: }
804 :
805 0: Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
806 : Action::ActionClass Key;
0: branch 3 not taken
0: branch 4 not taken
807 0: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
808 0: Key = Action::AnalyzeJobClass;
809 : else
810 0: Key = JA.getKind();
811 :
812 0: Tool *&T = Tools[Key];
0: branch 0 not taken
0: branch 1 not taken
813 0: if (!T) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
814 0: switch (Key) {
815 : case Action::AssembleJobClass:
816 0: T = new tools::auroraux::Assemble(*this); break;
817 : case Action::LinkJobClass:
818 0: T = new tools::auroraux::Link(*this); break;
819 : default:
820 0: T = &Generic_GCC::SelectTool(C, JA);
821 : }
822 : }
823 :
824 0: return *T;
825 : }
826 :
827 :
828 : /// Linux toolchain (very bare-bones at the moment).
829 :
830 152: Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
831 152: : Generic_GCC(Host, Triple) {
832 152: getFilePaths().push_back(getDriver().Dir + "/../lib/clang/1.0/");
833 152: getFilePaths().push_back("/lib/");
834 152: getFilePaths().push_back("/usr/lib/");
835 :
836 : // Depending on the Linux distribution, any combination of lib{,32,64} is
837 : // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
838 : // openSUSE uses lib and lib64 for the same purpose.
839 152: getFilePaths().push_back("/lib32/");
840 152: getFilePaths().push_back("/usr/lib32/");
841 152: getFilePaths().push_back("/lib64/");
842 152: getFilePaths().push_back("/usr/lib64/");
843 :
844 : // FIXME: Figure out some way to get gcc's libdir
845 : // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
846 : // crtbegin.o/crtend.o/etc., and want static versions of various
847 : // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
848 : // get away with using shared versions in /usr/lib, though.
849 : // We could fall back to the approach we used for includes (a massive
850 : // list), but that's messy at best.
851 152: }
852 :
853 : /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
854 :
855 1: DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
856 1: : Generic_GCC(Host, Triple) {
857 :
858 : // Path mangling to find libexec
859 1: getProgramPaths().push_back(getDriver().Dir);
860 :
861 1: getFilePaths().push_back(getDriver().Dir + "/../lib");
862 1: getFilePaths().push_back("/usr/lib");
863 1: getFilePaths().push_back("/usr/lib/gcc41");
864 1: }
865 :
866 3: Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
867 : Action::ActionClass Key;
1: branch 3 taken
2: branch 4 taken
868 3: if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
869 1: Key = Action::AnalyzeJobClass;
870 : else
871 2: Key = JA.getKind();
872 :
873 3: Tool *&T = Tools[Key];
3: branch 0 taken
0: branch 1 not taken
874 3: if (!T) {
1: branch 0 taken
1: branch 1 taken
1: branch 2 taken
875 3: switch (Key) {
876 : case Action::AssembleJobClass:
877 1: T = new tools::dragonfly::Assemble(*this); break;
878 : case Action::LinkJobClass:
879 1: T = new tools::dragonfly::Link(*this); break;
880 : default:
881 1: T = &Generic_GCC::SelectTool(C, JA);
882 : }
883 : }
884 :
885 3: return *T;
886 : }
Generated: 2010-02-10 01:31 by zcov