ToolChain.cpp revision 3ea9e33ea25e0c2b12db56418ba3f994eb662c04
1//===--- ToolChain.cpp - Collections of tools for one platform ------------===//
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#include "clang/Basic/ObjCRuntime.h"
12#include "clang/Driver/Action.h"
13#include "clang/Driver/Driver.h"
14#include "clang/Driver/DriverDiagnostic.h"
15#include "clang/Driver/Options.h"
16#include "clang/Driver/SanitizerArgs.h"
17#include "clang/Driver/ToolChain.h"
18#include "llvm/ADT/SmallString.h"
19#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Option/Arg.h"
21#include "llvm/Option/ArgList.h"
22#include "llvm/Option/Option.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/FileSystem.h"
25using namespace clang::driver;
26using namespace clang;
27using namespace llvm::opt;
28
29static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
30  return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
31                         options::OPT_fno_rtti, options::OPT_frtti);
32}
33
34static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
35                                             const llvm::Triple &Triple,
36                                             const Arg *CachedRTTIArg) {
37  // Explicit rtti/no-rtti args
38  if (CachedRTTIArg) {
39    if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
40      return ToolChain::RM_EnabledExplicitly;
41    else
42      return ToolChain::RM_DisabledExplicitly;
43  }
44
45  // -frtti is default, except for the PS4 CPU.
46  if (!Triple.isPS4CPU())
47    return ToolChain::RM_EnabledImplicitly;
48
49  // On the PS4, turning on c++ exceptions turns on rtti.
50  // We're assuming that, if we see -fexceptions, rtti gets turned on.
51  Arg *Exceptions = Args.getLastArgNoClaim(
52      options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
53      options::OPT_fexceptions, options::OPT_fno_exceptions);
54  if (Exceptions &&
55      (Exceptions->getOption().matches(options::OPT_fexceptions) ||
56       Exceptions->getOption().matches(options::OPT_fcxx_exceptions)))
57    return ToolChain::RM_EnabledImplicitly;
58
59  return ToolChain::RM_DisabledImplicitly;
60}
61
62ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
63                     const ArgList &Args)
64    : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
65      CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
66  if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
67    if (!isThreadModelSupported(A->getValue()))
68      D.Diag(diag::err_drv_invalid_thread_model_for_target)
69          << A->getValue() << A->getAsString(Args);
70}
71
72ToolChain::~ToolChain() {
73}
74
75const Driver &ToolChain::getDriver() const {
76 return D;
77}
78
79bool ToolChain::useIntegratedAs() const {
80  return Args.hasFlag(options::OPT_fintegrated_as,
81                      options::OPT_fno_integrated_as,
82                      IsIntegratedAssemblerDefault());
83}
84
85const SanitizerArgs& ToolChain::getSanitizerArgs() const {
86  if (!SanitizerArguments.get())
87    SanitizerArguments.reset(new SanitizerArgs(*this, Args));
88  return *SanitizerArguments.get();
89}
90
91StringRef ToolChain::getDefaultUniversalArchName() const {
92  // In universal driver terms, the arch name accepted by -arch isn't exactly
93  // the same as the ones that appear in the triple. Roughly speaking, this is
94  // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
95  // only interesting special case is powerpc.
96  switch (Triple.getArch()) {
97  case llvm::Triple::ppc:
98    return "ppc";
99  case llvm::Triple::ppc64:
100    return "ppc64";
101  case llvm::Triple::ppc64le:
102    return "ppc64le";
103  default:
104    return Triple.getArchName();
105  }
106}
107
108bool ToolChain::IsUnwindTablesDefault() const {
109  return false;
110}
111
112Tool *ToolChain::getClang() const {
113  if (!Clang)
114    Clang.reset(new tools::Clang(*this));
115  return Clang.get();
116}
117
118Tool *ToolChain::buildAssembler() const {
119  return new tools::ClangAs(*this);
120}
121
122Tool *ToolChain::buildLinker() const {
123  llvm_unreachable("Linking is not supported by this toolchain");
124}
125
126Tool *ToolChain::getAssemble() const {
127  if (!Assemble)
128    Assemble.reset(buildAssembler());
129  return Assemble.get();
130}
131
132Tool *ToolChain::getClangAs() const {
133  if (!Assemble)
134    Assemble.reset(new tools::ClangAs(*this));
135  return Assemble.get();
136}
137
138Tool *ToolChain::getLink() const {
139  if (!Link)
140    Link.reset(buildLinker());
141  return Link.get();
142}
143
144Tool *ToolChain::getTool(Action::ActionClass AC) const {
145  switch (AC) {
146  case Action::AssembleJobClass:
147    return getAssemble();
148
149  case Action::LinkJobClass:
150    return getLink();
151
152  case Action::InputClass:
153  case Action::BindArchClass:
154  case Action::LipoJobClass:
155  case Action::DsymutilJobClass:
156  case Action::VerifyDebugInfoJobClass:
157    llvm_unreachable("Invalid tool kind.");
158
159  case Action::CompileJobClass:
160  case Action::PrecompileJobClass:
161  case Action::PreprocessJobClass:
162  case Action::AnalyzeJobClass:
163  case Action::MigrateJobClass:
164  case Action::VerifyPCHJobClass:
165  case Action::BackendJobClass:
166    return getClang();
167  }
168
169  llvm_unreachable("Invalid tool kind.");
170}
171
172Tool *ToolChain::SelectTool(const JobAction &JA) const {
173  if (getDriver().ShouldUseClangCompiler(JA))
174    return getClang();
175  Action::ActionClass AC = JA.getKind();
176  if (AC == Action::AssembleJobClass && useIntegratedAs())
177    return getClangAs();
178  return getTool(AC);
179}
180
181std::string ToolChain::GetFilePath(const char *Name) const {
182  return D.GetFilePath(Name, *this);
183
184}
185
186std::string ToolChain::GetProgramPath(const char *Name) const {
187  return D.GetProgramPath(Name, *this);
188}
189
190std::string ToolChain::GetLinkerPath() const {
191  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
192    StringRef Suffix = A->getValue();
193
194    // If we're passed -fuse-ld= with no argument, or with the argument ld,
195    // then use whatever the default system linker is.
196    if (Suffix.empty() || Suffix == "ld")
197      return GetProgramPath("ld");
198
199    llvm::SmallString<8> LinkerName("ld.");
200    LinkerName.append(Suffix);
201
202    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
203    if (llvm::sys::fs::exists(LinkerPath))
204      return LinkerPath;
205
206    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
207    return "";
208  }
209
210  return GetProgramPath("ld");
211}
212
213
214types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
215  return types::lookupTypeForExtension(Ext);
216}
217
218bool ToolChain::HasNativeLLVMSupport() const {
219  return false;
220}
221
222bool ToolChain::isCrossCompiling() const {
223  llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
224  switch (HostTriple.getArch()) {
225  // The A32/T32/T16 instruction sets are not separate architectures in this
226  // context.
227  case llvm::Triple::arm:
228  case llvm::Triple::armeb:
229  case llvm::Triple::thumb:
230  case llvm::Triple::thumbeb:
231    return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
232           getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
233  default:
234    return HostTriple.getArch() != getArch();
235  }
236}
237
238ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
239  return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
240                     VersionTuple());
241}
242
243bool ToolChain::isThreadModelSupported(const StringRef Model) const {
244  if (Model == "single") {
245    // FIXME: 'single' is only supported on ARM so far.
246    return Triple.getArch() == llvm::Triple::arm ||
247           Triple.getArch() == llvm::Triple::armeb ||
248           Triple.getArch() == llvm::Triple::thumb ||
249           Triple.getArch() == llvm::Triple::thumbeb;
250  } else if (Model == "posix")
251    return true;
252
253  return false;
254}
255
256std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
257                                         types::ID InputType) const {
258  switch (getTriple().getArch()) {
259  default:
260    return getTripleString();
261
262  case llvm::Triple::x86_64: {
263    llvm::Triple Triple = getTriple();
264    if (!Triple.isOSBinFormatMachO())
265      return getTripleString();
266
267    if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
268      // x86_64h goes in the triple. Other -march options just use the
269      // vanilla triple we already have.
270      StringRef MArch = A->getValue();
271      if (MArch == "x86_64h")
272        Triple.setArchName(MArch);
273    }
274    return Triple.getTriple();
275  }
276  case llvm::Triple::aarch64: {
277    llvm::Triple Triple = getTriple();
278    if (!Triple.isOSBinFormatMachO())
279      return getTripleString();
280
281    // FIXME: older versions of ld64 expect the "arm64" component in the actual
282    // triple string and query it to determine whether an LTO file can be
283    // handled. Remove this when we don't care any more.
284    Triple.setArchName("arm64");
285    return Triple.getTriple();
286  }
287  case llvm::Triple::arm:
288  case llvm::Triple::armeb:
289  case llvm::Triple::thumb:
290  case llvm::Triple::thumbeb: {
291    // FIXME: Factor into subclasses.
292    llvm::Triple Triple = getTriple();
293    bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
294                       getTriple().getArch() == llvm::Triple::thumbeb;
295
296    // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
297    // '-mbig-endian'/'-EB'.
298    if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
299                                 options::OPT_mbig_endian)) {
300      IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
301    }
302
303    // Thumb2 is the default for V7 on Darwin.
304    //
305    // FIXME: Thumb should just be another -target-feaure, not in the triple.
306    StringRef Suffix = Triple.isOSBinFormatMachO()
307      ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple))
308      : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple));
309    bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
310      Suffix.startswith("v7em") ||
311      (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
312    // FIXME: this is invalid for WindowsCE
313    if (getTriple().isOSWindows())
314      ThumbDefault = true;
315    std::string ArchName;
316    if (IsBigEndian)
317      ArchName = "armeb";
318    else
319      ArchName = "arm";
320
321    // Assembly files should start in ARM mode.
322    if (InputType != types::TY_PP_Asm &&
323        Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
324    {
325      if (IsBigEndian)
326        ArchName = "thumbeb";
327      else
328        ArchName = "thumb";
329    }
330    Triple.setArchName(ArchName + Suffix.str());
331
332    return Triple.getTriple();
333  }
334  }
335}
336
337std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
338                                                   types::ID InputType) const {
339  return ComputeLLVMTriple(Args, InputType);
340}
341
342void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
343                                          ArgStringList &CC1Args) const {
344  // Each toolchain should provide the appropriate include flags.
345}
346
347void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
348                                      ArgStringList &CC1Args) const {
349}
350
351void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
352
353ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
354  const ArgList &Args) const
355{
356  if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
357    StringRef Value = A->getValue();
358    if (Value == "compiler-rt")
359      return ToolChain::RLT_CompilerRT;
360    if (Value == "libgcc")
361      return ToolChain::RLT_Libgcc;
362    getDriver().Diag(diag::err_drv_invalid_rtlib_name)
363      << A->getAsString(Args);
364  }
365
366  return GetDefaultRuntimeLibType();
367}
368
369ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
370  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
371    StringRef Value = A->getValue();
372    if (Value == "libc++")
373      return ToolChain::CST_Libcxx;
374    if (Value == "libstdc++")
375      return ToolChain::CST_Libstdcxx;
376    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
377      << A->getAsString(Args);
378  }
379
380  return ToolChain::CST_Libstdcxx;
381}
382
383/// \brief Utility function to add a system include directory to CC1 arguments.
384/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
385                                            ArgStringList &CC1Args,
386                                            const Twine &Path) {
387  CC1Args.push_back("-internal-isystem");
388  CC1Args.push_back(DriverArgs.MakeArgString(Path));
389}
390
391/// \brief Utility function to add a system include directory with extern "C"
392/// semantics to CC1 arguments.
393///
394/// Note that this should be used rarely, and only for directories that
395/// historically and for legacy reasons are treated as having implicit extern
396/// "C" semantics. These semantics are *ignored* by and large today, but its
397/// important to preserve the preprocessor changes resulting from the
398/// classification.
399/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
400                                                   ArgStringList &CC1Args,
401                                                   const Twine &Path) {
402  CC1Args.push_back("-internal-externc-isystem");
403  CC1Args.push_back(DriverArgs.MakeArgString(Path));
404}
405
406void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
407                                                ArgStringList &CC1Args,
408                                                const Twine &Path) {
409  if (llvm::sys::fs::exists(Path))
410    addExternCSystemInclude(DriverArgs, CC1Args, Path);
411}
412
413/// \brief Utility function to add a list of system include directories to CC1.
414/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
415                                             ArgStringList &CC1Args,
416                                             ArrayRef<StringRef> Paths) {
417  for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end();
418       I != E; ++I) {
419    CC1Args.push_back("-internal-isystem");
420    CC1Args.push_back(DriverArgs.MakeArgString(*I));
421  }
422}
423
424void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
425                                             ArgStringList &CC1Args) const {
426  // Header search paths should be handled by each of the subclasses.
427  // Historically, they have not been, and instead have been handled inside of
428  // the CC1-layer frontend. As the logic is hoisted out, this generic function
429  // will slowly stop being called.
430  //
431  // While it is being called, replicate a bit of a hack to propagate the
432  // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
433  // header search paths with it. Once all systems are overriding this
434  // function, the CC1 flag and this line can be removed.
435  DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
436}
437
438void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
439                                    ArgStringList &CmdArgs) const {
440  CXXStdlibType Type = GetCXXStdlibType(Args);
441
442  switch (Type) {
443  case ToolChain::CST_Libcxx:
444    CmdArgs.push_back("-lc++");
445    break;
446
447  case ToolChain::CST_Libstdcxx:
448    CmdArgs.push_back("-lstdc++");
449    break;
450  }
451}
452
453void ToolChain::AddCCKextLibArgs(const ArgList &Args,
454                                 ArgStringList &CmdArgs) const {
455  CmdArgs.push_back("-lcc_kext");
456}
457
458bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
459                                              ArgStringList &CmdArgs) const {
460  // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
461  // (to keep the linker options consistent with gcc and clang itself).
462  if (!isOptimizationLevelFast(Args)) {
463    // Check if -ffast-math or -funsafe-math.
464    Arg *A =
465        Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
466                        options::OPT_funsafe_math_optimizations,
467                        options::OPT_fno_unsafe_math_optimizations);
468
469    if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
470        A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
471      return false;
472  }
473  // If crtfastmath.o exists add it to the arguments.
474  std::string Path = GetFilePath("crtfastmath.o");
475  if (Path == "crtfastmath.o") // Not found.
476    return false;
477
478  CmdArgs.push_back(Args.MakeArgString(Path));
479  return true;
480}
481