blob: 1013f24267eea55343d0fb38339e13d7982ccfcd [file] [log] [blame]
Daniel Dunbar39176082009-03-20 00:20:03 +00001//===--- 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
Daniel Dunbarf3cad362009-03-25 04:13:45 +000012#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000014#include "clang/Driver/Driver.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000015#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000016#include "clang/Driver/HostInfo.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000017#include "clang/Driver/Option.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000018
19#include "llvm/ADT/StringExtras.h"
Daniel Dunbar84ec96c2009-09-09 22:33:15 +000020#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000021#include "llvm/Support/raw_ostream.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000022#include "llvm/System/Path.h"
23
Daniel Dunbarf36a06a2009-04-10 21:00:07 +000024#include <cstdlib> // ::getenv
25
Daniel Dunbar39176082009-03-20 00:20:03 +000026using namespace clang::driver;
27using namespace clang::driver::toolchains;
28
Daniel Dunbarf3955282009-09-04 18:34:51 +000029/// Darwin - Darwin tool chain for i386 and x86_64.
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000030
Daniel Dunbarf3955282009-09-04 18:34:51 +000031Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
32 const unsigned (&_DarwinVersion)[3],
Daniel Dunbar30392de2009-09-04 18:35:21 +000033 const unsigned (&_GCCVersion)[3],
34 bool _IsIPhone)
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000035 : ToolChain(Host, Triple) {
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000036 DarwinVersion[0] = _DarwinVersion[0];
37 DarwinVersion[1] = _DarwinVersion[1];
38 DarwinVersion[2] = _DarwinVersion[2];
39 GCCVersion[0] = _GCCVersion[0];
40 GCCVersion[1] = _GCCVersion[1];
41 GCCVersion[2] = _GCCVersion[2];
Daniel Dunbar30392de2009-09-04 18:35:21 +000042 IsIPhone = _IsIPhone;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000043
Daniel Dunbar02633b52009-03-26 16:23:12 +000044 llvm::raw_string_ostream(MacosxVersionMin)
45 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
46
Daniel Dunbar30392de2009-09-04 18:35:21 +000047 // FIXME: Lift default up.
48 IPhoneOSVersionMin = "3.0";
49
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000050 ToolChainDir = "i686-apple-darwin";
51 ToolChainDir += llvm::utostr(DarwinVersion[0]);
52 ToolChainDir += "/";
53 ToolChainDir += llvm::utostr(GCCVersion[0]);
54 ToolChainDir += '.';
55 ToolChainDir += llvm::utostr(GCCVersion[1]);
56 ToolChainDir += '.';
57 ToolChainDir += llvm::utostr(GCCVersion[2]);
58
59 std::string Path;
60 if (getArchName() == "x86_64") {
61 Path = getHost().getDriver().Dir;
62 Path += "/../lib/gcc/";
63 Path += getToolChainDir();
64 Path += "/x86_64";
65 getFilePaths().push_back(Path);
66
67 Path = "/usr/lib/gcc/";
68 Path += getToolChainDir();
69 Path += "/x86_64";
70 getFilePaths().push_back(Path);
71 }
Mike Stump1eb44332009-09-09 15:08:12 +000072
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000073 Path = getHost().getDriver().Dir;
74 Path += "/../lib/gcc/";
75 Path += getToolChainDir();
76 getFilePaths().push_back(Path);
77
78 Path = "/usr/lib/gcc/";
79 Path += getToolChainDir();
80 getFilePaths().push_back(Path);
81
82 Path = getHost().getDriver().Dir;
83 Path += "/../libexec/gcc/";
84 Path += getToolChainDir();
85 getProgramPaths().push_back(Path);
86
87 Path = "/usr/libexec/gcc/";
88 Path += getToolChainDir();
89 getProgramPaths().push_back(Path);
90
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000091 Path = getHost().getDriver().Dir;
92 Path += "/../libexec";
93 getProgramPaths().push_back(Path);
94
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000095 getProgramPaths().push_back(getHost().getDriver().Dir);
96}
97
Daniel Dunbarf3955282009-09-04 18:34:51 +000098Darwin::~Darwin() {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000099 // Free tool implementations.
100 for (llvm::DenseMap<unsigned, Tool*>::iterator
101 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
102 delete it->second;
103}
104
Daniel Dunbarf3955282009-09-04 18:34:51 +0000105Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000106 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000107 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000108 Key = Action::AnalyzeJobClass;
109 else
110 Key = JA.getKind();
111
112 Tool *&T = Tools[Key];
113 if (!T) {
114 switch (Key) {
115 case Action::InputClass:
116 case Action::BindArchClass:
117 assert(0 && "Invalid tool kind.");
118 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000119 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000120 case Action::AnalyzeJobClass:
121 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000122 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000123 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000124 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000125 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000126 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000127 case Action::LinkJobClass:
Daniel Dunbar8f289622009-09-04 17:39:02 +0000128 T = new tools::darwin::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000129 case Action::LipoJobClass:
130 T = new tools::darwin::Lipo(*this); break;
131 }
132 }
133
134 return *T;
135}
136
Daniel Dunbar0dcb9a32009-09-09 18:36:12 +0000137DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
138 const char *BoundArch) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000139 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000140 const OptTable &Opts = getHost().getDriver().getOpts();
141
142 // FIXME: We really want to get out of the tool chain level argument
143 // translation business, as it makes the driver functionality much
144 // more opaque. For now, we follow gcc closely solely for the
145 // purpose of easily achieving feature parity & testability. Once we
146 // have something that works, we should reevaluate each translation
Mike Stump1eb44332009-09-09 15:08:12 +0000147 // and try to push it down into tool specific logic.
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000148
Mike Stump1eb44332009-09-09 15:08:12 +0000149 Arg *OSXVersion =
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000150 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
151 Arg *iPhoneVersion =
Mike Stump1eb44332009-09-09 15:08:12 +0000152 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000153 if (OSXVersion && iPhoneVersion) {
154 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
155 << OSXVersion->getAsString(Args)
Mike Stump1eb44332009-09-09 15:08:12 +0000156 << iPhoneVersion->getAsString(Args);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000157 } else if (!OSXVersion && !iPhoneVersion) {
158 // Chose the default version based on the arch.
159 //
Daniel Dunbar30392de2009-09-04 18:35:21 +0000160 // FIXME: Are there iPhone overrides for this?
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000161
Daniel Dunbar30392de2009-09-04 18:35:21 +0000162 if (!isIPhone()) {
163 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
164 // from the host.
165 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET");
166 if (!Version)
167 Version = MacosxVersionMin.c_str();
168 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
169 DAL->append(DAL->MakeJoinedArg(0, O, Version));
170 } else {
171 const char *Version = IPhoneOSVersionMin.c_str();
172 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
173 DAL->append(DAL->MakeJoinedArg(0, O, Version));
174 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000175 }
Mike Stump1eb44332009-09-09 15:08:12 +0000176
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000177 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
178 Arg *A = *it;
179
180 if (A->getOption().matches(options::OPT_Xarch__)) {
181 // FIXME: Canonicalize name.
182 if (getArchName() != A->getValue(Args, 0))
183 continue;
184
185 // FIXME: The arg is leaked here, and we should have a nicer
186 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000187 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000188 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Mike Stump1eb44332009-09-09 15:08:12 +0000189
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000190 // If the argument parsing failed or more than one argument was
191 // consumed, the -Xarch_ argument's parameter tried to consume
192 // extra arguments. Emit an error and ignore.
193 //
194 // We also want to disallow any options which would alter the
195 // driver behavior; that isn't going to work in our model. We
196 // use isDriverOption() as an approximation, although things
197 // like -O4 are going to slip through.
Mike Stump1eb44332009-09-09 15:08:12 +0000198 if (!XarchArg || Index > Prev + 1 ||
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000199 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000200 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000201 << A->getAsString(Args);
202 continue;
203 }
204
Daniel Dunbar478edc22009-03-29 22:29:05 +0000205 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000206 A = XarchArg;
Mike Stump1eb44332009-09-09 15:08:12 +0000207 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000208
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000209 // Sob. These is strictly gcc compatible for the time being. Apple
210 // gcc translates options twice, which means that self-expanding
211 // options add duplicates.
212 options::ID id = A->getOption().getId();
213 switch (id) {
214 default:
215 DAL->append(A);
216 break;
217
218 case options::OPT_mkernel:
219 case options::OPT_fapple_kext:
220 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000221 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
222 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000223 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000224
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000225 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000226 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000227 A->getValue(Args)));
228 break;
229
230 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000231 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
232 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000233 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
234 break;
235
236 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000237 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
238 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000239 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
240 break;
241
242 case options::OPT_fterminated_vtables:
243 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000244 DAL->append(DAL->MakeFlagArg(A,
245 Opts.getOption(options::OPT_fapple_kext)));
246 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000247 break;
248
249 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000250 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000251 break;
252
253 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000254 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000255 Opts.getOption(options::OPT_mconstant_cfstrings)));
256 break;
257
258 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000259 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000260 Opts.getOption(options::OPT_mno_constant_cfstrings)));
261 break;
262
263 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000264 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000265 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
266 break;
267
268 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000269 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000270 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
271 break;
272
273 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000274 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000275 Opts.getOption(options::OPT_mpascal_strings)));
276 break;
277
278 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000279 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000280 Opts.getOption(options::OPT_mno_pascal_strings)));
281 break;
282 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000283 }
284
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000285 if (getTriple().getArch() == llvm::Triple::x86 ||
286 getTriple().getArch() == llvm::Triple::x86_64)
287 if (!Args.hasArg(options::OPT_mtune_EQ, false))
288 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
289 "core2"));
290
291 // Add the arch options based on the particular spelling of -arch, to match
292 // how the driver driver works.
293 if (BoundArch) {
294 llvm::StringRef Name = BoundArch;
295 const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
296 const Option *MArch = Opts.getOption(options::OPT_march_EQ);
297
298 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
299 // which defines the list of which architectures we accept.
300 if (Name == "ppc")
301 ;
302 else if (Name == "ppc601")
303 DAL->append(DAL->MakeJoinedArg(0, MCpu, "601"));
304 else if (Name == "ppc603")
305 DAL->append(DAL->MakeJoinedArg(0, MCpu, "603"));
306 else if (Name == "ppc604")
307 DAL->append(DAL->MakeJoinedArg(0, MCpu, "604"));
308 else if (Name == "ppc604e")
309 DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e"));
310 else if (Name == "ppc750")
311 DAL->append(DAL->MakeJoinedArg(0, MCpu, "750"));
312 else if (Name == "ppc7400")
313 DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400"));
314 else if (Name == "ppc7450")
315 DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450"));
316 else if (Name == "ppc970")
317 DAL->append(DAL->MakeJoinedArg(0, MCpu, "970"));
318
319 else if (Name == "ppc64")
Daniel Dunbar478edc22009-03-29 22:29:05 +0000320 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000321
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000322 else if (Name == "i386")
323 ;
324 else if (Name == "i486")
325 DAL->append(DAL->MakeJoinedArg(0, MArch, "i486"));
326 else if (Name == "i586")
327 DAL->append(DAL->MakeJoinedArg(0, MArch, "i586"));
328 else if (Name == "i686")
329 DAL->append(DAL->MakeJoinedArg(0, MArch, "i686"));
330 else if (Name == "pentium")
331 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium"));
332 else if (Name == "pentium2")
333 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
334 else if (Name == "pentpro")
335 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro"));
336 else if (Name == "pentIIm3")
337 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
338
339 else if (Name == "x86_64")
340 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
341
342 else if (Name == "arm")
343 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
344 else if (Name == "armv4t")
345 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
346 else if (Name == "armv5")
347 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej"));
348 else if (Name == "xscale")
349 DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale"));
350 else if (Name == "armv6")
351 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k"));
352 else if (Name == "armv7")
353 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a"));
354
355 else
356 llvm::llvm_unreachable("invalid Darwin arch");
357 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000358
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000359 return DAL;
Mike Stump1eb44332009-09-09 15:08:12 +0000360}
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000361
Daniel Dunbarf3955282009-09-04 18:34:51 +0000362bool Darwin::IsMathErrnoDefault() const {
Mike Stump1eb44332009-09-09 15:08:12 +0000363 return false;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000364}
365
Daniel Dunbarf3955282009-09-04 18:34:51 +0000366bool Darwin::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000367 // FIXME: Gross; we should probably have some separate target
368 // definition, possibly even reusing the one in clang.
369 return getArchName() == "x86_64";
370}
371
Daniel Dunbarf3955282009-09-04 18:34:51 +0000372const char *Darwin::GetDefaultRelocationModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000373 return "pic";
374}
375
Daniel Dunbarf3955282009-09-04 18:34:51 +0000376const char *Darwin::GetForcedPicModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000377 if (getArchName() == "x86_64")
378 return "pic";
379 return 0;
380}
381
Daniel Dunbar39176082009-03-20 00:20:03 +0000382/// Generic_GCC - A tool chain using the 'gcc' command to perform
383/// all subcommands; this relies on gcc translating the majority of
384/// command line options.
385
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000386Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
Mike Stump1eb44332009-09-09 15:08:12 +0000387 : ToolChain(Host, Triple) {
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000388 std::string Path(getHost().getDriver().Dir);
389 Path += "/../libexec";
390 getProgramPaths().push_back(Path);
391
Mike Stump1eb44332009-09-09 15:08:12 +0000392 getProgramPaths().push_back(getHost().getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000393}
394
Daniel Dunbar39176082009-03-20 00:20:03 +0000395Generic_GCC::~Generic_GCC() {
396 // Free tool implementations.
397 for (llvm::DenseMap<unsigned, Tool*>::iterator
398 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
399 delete it->second;
400}
401
Mike Stump1eb44332009-09-09 15:08:12 +0000402Tool &Generic_GCC::SelectTool(const Compilation &C,
Daniel Dunbar39176082009-03-20 00:20:03 +0000403 const JobAction &JA) const {
404 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000405 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000406 Key = Action::AnalyzeJobClass;
407 else
408 Key = JA.getKind();
409
410 Tool *&T = Tools[Key];
411 if (!T) {
412 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000413 case Action::InputClass:
414 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000415 assert(0 && "Invalid tool kind.");
416 case Action::PreprocessJobClass:
417 T = new tools::gcc::Preprocess(*this); break;
418 case Action::PrecompileJobClass:
419 T = new tools::gcc::Precompile(*this); break;
420 case Action::AnalyzeJobClass:
421 T = new tools::Clang(*this); break;
422 case Action::CompileJobClass:
423 T = new tools::gcc::Compile(*this); break;
424 case Action::AssembleJobClass:
425 T = new tools::gcc::Assemble(*this); break;
426 case Action::LinkJobClass:
427 T = new tools::gcc::Link(*this); break;
Mike Stump1eb44332009-09-09 15:08:12 +0000428
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000429 // This is a bit ungeneric, but the only platform using a driver
430 // driver is Darwin.
431 case Action::LipoJobClass:
432 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000433 }
434 }
435
436 return *T;
437}
438
Daniel Dunbarf3955282009-09-04 18:34:51 +0000439bool Generic_GCC::IsMathErrnoDefault() const {
Mike Stump1eb44332009-09-09 15:08:12 +0000440 return true;
Daniel Dunbar39176082009-03-20 00:20:03 +0000441}
442
443bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000444 // FIXME: Gross; we should probably have some separate target
445 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000446 return getArchName() == "x86_64";
447}
448
449const char *Generic_GCC::GetDefaultRelocationModel() const {
450 return "static";
451}
452
453const char *Generic_GCC::GetForcedPicModel() const {
454 return 0;
455}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000456
Daniel Dunbar0dcb9a32009-09-09 18:36:12 +0000457DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
458 const char *BoundArch) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000459 return new DerivedArgList(Args, true);
460}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000461
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000462/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
463
464OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
465 : Generic_GCC(Host, Triple) {
466 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
467 getFilePaths().push_back("/usr/lib");
468}
469
470Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
471 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000472 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000473 Key = Action::AnalyzeJobClass;
474 else
475 Key = JA.getKind();
476
477 Tool *&T = Tools[Key];
478 if (!T) {
479 switch (Key) {
480 case Action::AssembleJobClass:
481 T = new tools::openbsd::Assemble(*this); break;
482 case Action::LinkJobClass:
483 T = new tools::openbsd::Link(*this); break;
484 default:
485 T = &Generic_GCC::SelectTool(C, JA);
486 }
487 }
488
489 return *T;
490}
491
Daniel Dunbar75358d22009-03-30 21:06:03 +0000492/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
493
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000494FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
495 : Generic_GCC(Host, Triple) {
Daniel Dunbarbc534662009-04-02 18:30:04 +0000496 if (Lib32) {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000497 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000498 getFilePaths().push_back("/usr/lib32");
499 } else {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000500 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000501 getFilePaths().push_back("/usr/lib");
502 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000503}
504
505Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
506 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000507 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar75358d22009-03-30 21:06:03 +0000508 Key = Action::AnalyzeJobClass;
509 else
510 Key = JA.getKind();
511
512 Tool *&T = Tools[Key];
513 if (!T) {
514 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000515 case Action::AssembleJobClass:
516 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000517 case Action::LinkJobClass:
518 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000519 default:
520 T = &Generic_GCC::SelectTool(C, JA);
521 }
522 }
523
524 return *T;
525}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000526
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000527/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
528
529AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
530 : Generic_GCC(Host, Triple) {
531
532 // Path mangling to find libexec
533 std::string Path(getHost().getDriver().Dir);
534
535 Path += "/../libexec";
536 getProgramPaths().push_back(Path);
Mike Stump1eb44332009-09-09 15:08:12 +0000537 getProgramPaths().push_back(getHost().getDriver().Dir);
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000538
539 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
540 getFilePaths().push_back("/usr/lib");
541 getFilePaths().push_back("/usr/sfw/lib");
542 getFilePaths().push_back("/opt/gcc4/lib");
543
544}
545
546Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
547 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000548 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000549 Key = Action::AnalyzeJobClass;
550 else
551 Key = JA.getKind();
552
553 Tool *&T = Tools[Key];
554 if (!T) {
555 switch (Key) {
556 case Action::AssembleJobClass:
557 T = new tools::auroraux::Assemble(*this); break;
558 case Action::LinkJobClass:
559 T = new tools::auroraux::Link(*this); break;
560 default:
561 T = &Generic_GCC::SelectTool(C, JA);
562 }
563 }
564
565 return *T;
566}
567
568
Eli Friedman6b3454a2009-05-26 07:52:18 +0000569/// Linux toolchain (very bare-bones at the moment).
570
571Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
572 : Generic_GCC(Host, Triple) {
573 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/");
574 getFilePaths().push_back("/lib/");
575 getFilePaths().push_back("/usr/lib/");
Daniel Dunbara9822de2009-08-06 01:47:11 +0000576
577 // Depending on the Linux distribution, any combination of lib{,32,64} is
578 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
579 // openSUSE uses lib and lib64 for the same purpose.
580 getFilePaths().push_back("/lib32/");
581 getFilePaths().push_back("/usr/lib32/");
582 getFilePaths().push_back("/lib64/");
583 getFilePaths().push_back("/usr/lib64/");
584
Eli Friedman6b3454a2009-05-26 07:52:18 +0000585 // FIXME: Figure out some way to get gcc's libdir
586 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
587 // crtbegin.o/crtend.o/etc., and want static versions of various
588 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
589 // get away with using shared versions in /usr/lib, though.
590 // We could fall back to the approach we used for includes (a massive
591 // list), but that's messy at best.
592}
593
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000594/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
595
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000596DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
597 : Generic_GCC(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000598
599 // Path mangling to find libexec
600 std::string Path(getHost().getDriver().Dir);
601
602 Path += "/../libexec";
603 getProgramPaths().push_back(Path);
Mike Stump1eb44332009-09-09 15:08:12 +0000604 getProgramPaths().push_back(getHost().getDriver().Dir);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000605
606 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
607 getFilePaths().push_back("/usr/lib");
608 getFilePaths().push_back("/usr/lib/gcc41");
609}
610
611Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
612 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000613 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000614 Key = Action::AnalyzeJobClass;
615 else
616 Key = JA.getKind();
617
618 Tool *&T = Tools[Key];
619 if (!T) {
620 switch (Key) {
621 case Action::AssembleJobClass:
622 T = new tools::dragonfly::Assemble(*this); break;
623 case Action::LinkJobClass:
624 T = new tools::dragonfly::Link(*this); break;
625 default:
626 T = &Generic_GCC::SelectTool(C, JA);
627 }
628 }
629
630 return *T;
631}