ToolChains.h revision d936d9d9abae0e5018fa0233aa51ac8390a6778f
1//===--- ToolChains.h - ToolChain Implementations ---------------*- C++ -*-===//
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#ifndef CLANG_LIB_DRIVER_TOOLCHAINS_H_
11#define CLANG_LIB_DRIVER_TOOLCHAINS_H_
12
13#include "clang/Driver/Action.h"
14#include "clang/Driver/ToolChain.h"
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/Support/Compiler.h"
18
19#include "Tools.h"
20
21namespace clang {
22namespace driver {
23namespace toolchains {
24
25/// Generic_GCC - A tool chain using the 'gcc' command to perform
26/// all subcommands; this relies on gcc translating the majority of
27/// command line options.
28class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
29protected:
30  /// \brief Struct to store and manipulate GCC versions.
31  ///
32  /// We rely on assumptions about the form and structure of GCC version
33  /// numbers: they consist of at most three '.'-separated components, and each
34  /// component is a non-negative integer except for the last component. For
35  /// the last component we are very flexible in order to tolerate release
36  /// candidates or 'x' wildcards.
37  ///
38  /// Note that the ordering established among GCCVersions is based on the
39  /// preferred version string to use. For example we prefer versions without
40  /// a hard-coded patch number to those with a hard coded patch number.
41  ///
42  /// Currently this doesn't provide any logic for textual suffixes to patches
43  /// in the way that (for example) Debian's version format does. If that ever
44  /// becomes necessary, it can be added.
45  struct GCCVersion {
46    /// \brief The unparsed text of the version.
47    std::string Text;
48
49    /// \brief The parsed major, minor, and patch numbers.
50    int Major, Minor, Patch;
51
52    /// \brief Any textual suffix on the patch number.
53    std::string PatchSuffix;
54
55    static GCCVersion Parse(StringRef VersionText);
56    bool operator<(const GCCVersion &RHS) const;
57    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
58    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
59    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
60  };
61
62
63  /// \brief This is a class to find a viable GCC installation for Clang to
64  /// use.
65  ///
66  /// This class tries to find a GCC installation on the system, and report
67  /// information about it. It starts from the host information provided to the
68  /// Driver, and has logic for fuzzing that where appropriate.
69  class GCCInstallationDetector {
70
71    bool IsValid;
72    std::string GccTriple;
73
74    // FIXME: These might be better as path objects.
75    std::string GccInstallPath;
76    std::string GccParentLibPath;
77
78    GCCVersion Version;
79
80  public:
81    GCCInstallationDetector(const Driver &D);
82
83    /// \brief Check whether we detected a valid GCC install.
84    bool isValid() const { return IsValid; }
85
86    /// \brief Get the GCC triple for the detected install.
87    StringRef getTriple() const { return GccTriple; }
88
89    /// \brief Get the detected GCC installation path.
90    StringRef getInstallPath() const { return GccInstallPath; }
91
92    /// \brief Get the detected GCC parent lib path.
93    StringRef getParentLibPath() const { return GccParentLibPath; }
94
95    /// \brief Get the detected GCC version string.
96    StringRef getVersion() const { return Version.Text; }
97
98  private:
99    static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
100                                         SmallVectorImpl<StringRef> &LibDirs,
101                                         SmallVectorImpl<StringRef> &Triples);
102
103    void ScanLibDirForGCCTriple(llvm::Triple::ArchType HostArch,
104                                const std::string &LibDir,
105                                StringRef CandidateTriple);
106  };
107
108  GCCInstallationDetector GCCInstallation;
109
110  mutable llvm::DenseMap<unsigned, Tool*> Tools;
111
112public:
113  Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
114  ~Generic_GCC();
115
116  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
117                           const ActionList &Inputs) const;
118
119  virtual bool IsUnwindTablesDefault() const;
120  virtual const char *GetDefaultRelocationModel() const;
121  virtual const char *GetForcedPicModel() const;
122
123protected:
124  /// \name ToolChain Implementation Helper Functions
125  /// @{
126
127  /// \brief Check whether the target triple's architecture is 64-bits.
128  bool isTarget64Bit() const {
129    return (getTriple().getArch() == llvm::Triple::x86_64 ||
130            getTriple().getArch() == llvm::Triple::ppc64);
131  }
132  /// \brief Check whether the target triple's architecture is 32-bits.
133  /// FIXME: This should likely do more than just negate the 64-bit query.
134  bool isTarget32Bit() const { return !isTarget64Bit(); }
135
136  /// @}
137};
138
139/// Darwin - The base Darwin tool chain.
140class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
141public:
142  /// The host version.
143  unsigned DarwinVersion[3];
144
145private:
146  mutable llvm::DenseMap<unsigned, Tool*> Tools;
147
148  /// Whether the information on the target has been initialized.
149  //
150  // FIXME: This should be eliminated. What we want to do is make this part of
151  // the "default target for arguments" selection process, once we get out of
152  // the argument translation business.
153  mutable bool TargetInitialized;
154
155  // FIXME: Remove this once there is a proper way to detect an ARC runtime
156  // for the simulator.
157 public:
158  mutable enum {
159    ARCSimulator_None,
160    ARCSimulator_HasARCRuntime,
161    ARCSimulator_NoARCRuntime
162  } ARCRuntimeForSimulator;
163
164  mutable enum {
165    LibCXXSimulator_None,
166    LibCXXSimulator_NotAvailable,
167    LibCXXSimulator_Available
168  } LibCXXForSimulator;
169
170private:
171  /// Whether we are targeting iPhoneOS target.
172  mutable bool TargetIsIPhoneOS;
173
174  /// Whether we are targeting the iPhoneOS simulator target.
175  mutable bool TargetIsIPhoneOSSimulator;
176
177  /// The OS version we are targeting.
178  mutable unsigned TargetVersion[3];
179
180  /// The default macosx-version-min of this tool chain; empty until
181  /// initialized.
182  std::string MacosxVersionMin;
183
184  bool hasARCRuntime() const;
185
186private:
187  void AddDeploymentTarget(DerivedArgList &Args) const;
188
189public:
190  Darwin(const HostInfo &Host, const llvm::Triple& Triple);
191  ~Darwin();
192
193  std::string ComputeEffectiveClangTriple(const ArgList &Args,
194                                          types::ID InputType) const;
195
196  /// @name Darwin Specific Toolchain API
197  /// {
198
199  // FIXME: Eliminate these ...Target functions and derive separate tool chains
200  // for these targets and put version in constructor.
201  void setTarget(bool IsIPhoneOS, unsigned Major, unsigned Minor,
202                 unsigned Micro, bool IsIOSSim) const {
203    assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!");
204
205    // FIXME: For now, allow reinitialization as long as values don't
206    // change. This will go away when we move away from argument translation.
207    if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS &&
208        TargetIsIPhoneOSSimulator == IsIOSSim &&
209        TargetVersion[0] == Major && TargetVersion[1] == Minor &&
210        TargetVersion[2] == Micro)
211      return;
212
213    assert(!TargetInitialized && "Target already initialized!");
214    TargetInitialized = true;
215    TargetIsIPhoneOS = IsIPhoneOS;
216    TargetIsIPhoneOSSimulator = IsIOSSim;
217    TargetVersion[0] = Major;
218    TargetVersion[1] = Minor;
219    TargetVersion[2] = Micro;
220  }
221
222  bool isTargetIPhoneOS() const {
223    assert(TargetInitialized && "Target not initialized!");
224    return TargetIsIPhoneOS;
225  }
226
227  bool isTargetIOSSimulator() const {
228    assert(TargetInitialized && "Target not initialized!");
229    return TargetIsIPhoneOSSimulator;
230  }
231
232  bool isTargetInitialized() const { return TargetInitialized; }
233
234  void getTargetVersion(unsigned (&Res)[3]) const {
235    assert(TargetInitialized && "Target not initialized!");
236    Res[0] = TargetVersion[0];
237    Res[1] = TargetVersion[1];
238    Res[2] = TargetVersion[2];
239  }
240
241  /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
242  /// invocation. For example, Darwin treats different ARM variations as
243  /// distinct architectures.
244  StringRef getDarwinArchName(const ArgList &Args) const;
245
246  static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
247    for (unsigned i=0; i < 3; ++i) {
248      if (A[i] > B[i]) return false;
249      if (A[i] < B[i]) return true;
250    }
251    return false;
252  }
253
254  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
255    assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
256    unsigned B[3] = { V0, V1, V2 };
257    return isVersionLT(TargetVersion, B);
258  }
259
260  bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
261    assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
262    unsigned B[3] = { V0, V1, V2 };
263    return isVersionLT(TargetVersion, B);
264  }
265
266  /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
267  ///
268  /// \param Args - The input argument list.
269  /// \param CmdArgs [out] - The command argument list to append the paths
270  /// (prefixed by -L) to.
271  virtual void AddLinkSearchPathArgs(const ArgList &Args,
272                                     ArgStringList &CmdArgs) const = 0;
273
274  /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library.
275  virtual void AddLinkARCArgs(const ArgList &Args,
276                              ArgStringList &CmdArgs) const = 0;
277
278  /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler
279  /// runtime library.
280  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
281                                     ArgStringList &CmdArgs) const = 0;
282
283  /// }
284  /// @name ToolChain Implementation
285  /// {
286
287  virtual types::ID LookupTypeForExtension(const char *Ext) const;
288
289  virtual bool HasNativeLLVMSupport() const;
290
291  virtual void configureObjCRuntime(ObjCRuntime &runtime) const;
292  virtual bool hasBlocksRuntime() const;
293
294  virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
295                                        const char *BoundArch) const;
296
297  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
298                           const ActionList &Inputs) const;
299
300  virtual bool IsBlocksDefault() const {
301    // Always allow blocks on Darwin; users interested in versioning are
302    // expected to use /usr/include/Blocks.h.
303    return true;
304  }
305  virtual bool IsIntegratedAssemblerDefault() const {
306#ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER
307    return false;
308#else
309    // Default integrated assembler to on for x86.
310    return (getTriple().getArch() == llvm::Triple::x86 ||
311            getTriple().getArch() == llvm::Triple::x86_64);
312#endif
313  }
314  virtual bool IsStrictAliasingDefault() const {
315#ifdef DISABLE_DEFAULT_STRICT_ALIASING
316    return false;
317#else
318    return ToolChain::IsStrictAliasingDefault();
319#endif
320  }
321
322  virtual bool IsObjCDefaultSynthPropertiesDefault() const {
323    return false;
324  }
325
326  virtual bool IsObjCNonFragileABIDefault() const {
327    // Non-fragile ABI is default for everything but i386.
328    return getTriple().getArch() != llvm::Triple::x86;
329  }
330  virtual bool IsObjCLegacyDispatchDefault() const {
331    // This is only used with the non-fragile ABI.
332
333    // Legacy dispatch is used everywhere except on x86_64.
334    return getTriple().getArch() != llvm::Triple::x86_64;
335  }
336  virtual bool UseObjCMixedDispatch() const {
337    // This is only used with the non-fragile ABI and non-legacy dispatch.
338
339    // Mixed dispatch is used everywhere except OS X before 10.6.
340    return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6));
341  }
342  virtual bool IsUnwindTablesDefault() const;
343  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
344    // Stack protectors default to on for user code on 10.5,
345    // and for everything in 10.6 and beyond
346    return !isTargetIPhoneOS() &&
347      (!isMacosxVersionLT(10, 6) ||
348         (!isMacosxVersionLT(10, 5) && !KernelOrKext));
349  }
350  virtual const char *GetDefaultRelocationModel() const;
351  virtual const char *GetForcedPicModel() const;
352
353  virtual bool SupportsProfiling() const;
354
355  virtual bool SupportsObjCGC() const;
356
357  virtual bool UseDwarfDebugFlags() const;
358
359  virtual bool UseSjLjExceptions() const;
360
361  /// }
362};
363
364/// DarwinClang - The Darwin toolchain used by Clang.
365class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
366private:
367  void AddGCCLibexecPath(unsigned darwinVersion);
368
369public:
370  DarwinClang(const HostInfo &Host, const llvm::Triple& Triple);
371
372  /// @name Darwin ToolChain Implementation
373  /// {
374
375  virtual void AddLinkSearchPathArgs(const ArgList &Args,
376                                    ArgStringList &CmdArgs) const;
377
378  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
379                                     ArgStringList &CmdArgs) const;
380  void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
381                         const char *DarwinStaticLib) const;
382
383  virtual void AddCXXStdlibLibArgs(const ArgList &Args,
384                                   ArgStringList &CmdArgs) const;
385
386  virtual void AddCCKextLibArgs(const ArgList &Args,
387                                ArgStringList &CmdArgs) const;
388
389  virtual void AddLinkARCArgs(const ArgList &Args,
390                              ArgStringList &CmdArgs) const;
391  /// }
392};
393
394/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
395class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
396public:
397  Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
398    : Generic_GCC(Host, Triple) {}
399
400  std::string ComputeEffectiveClangTriple(const ArgList &Args,
401                                          types::ID InputType) const;
402
403  virtual const char *GetDefaultRelocationModel() const { return "pic"; }
404};
405
406class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
407 public:
408  Generic_ELF(const HostInfo &Host, const llvm::Triple& Triple)
409    : Generic_GCC(Host, Triple) {}
410
411  virtual bool IsIntegratedAssemblerDefault() const {
412    // Default integrated assembler to on for x86.
413    return (getTriple().getArch() == llvm::Triple::x86 ||
414            getTriple().getArch() == llvm::Triple::x86_64);
415  }
416};
417
418class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
419public:
420  AuroraUX(const HostInfo &Host, const llvm::Triple& Triple);
421
422  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
423                           const ActionList &Inputs) const;
424};
425
426class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
427public:
428  OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
429
430  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
431                           const ActionList &Inputs) const;
432};
433
434class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
435public:
436  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple);
437
438  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
439                           const ActionList &Inputs) const;
440};
441
442class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
443  const llvm::Triple ToolTriple;
444
445public:
446  NetBSD(const HostInfo &Host, const llvm::Triple& Triple,
447         const llvm::Triple& ToolTriple);
448
449  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
450                           const ActionList &Inputs) const;
451};
452
453class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC {
454public:
455  Minix(const HostInfo &Host, const llvm::Triple& Triple);
456
457  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
458                           const ActionList &Inputs) const;
459};
460
461class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
462public:
463  DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
464
465  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
466                           const ActionList &Inputs) const;
467};
468
469class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
470public:
471  Linux(const HostInfo &Host, const llvm::Triple& Triple);
472
473  virtual bool HasNativeLLVMSupport() const;
474
475  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
476                           const ActionList &Inputs) const;
477
478  virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
479                                         ArgStringList &CC1Args) const;
480  virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
481                                            ArgStringList &CC1Args) const;
482
483  std::string Linker;
484  std::vector<std::string> ExtraOpts;
485};
486
487
488/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
489/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
490class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
491public:
492  TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
493  ~TCEToolChain();
494
495  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
496                           const ActionList &Inputs) const;
497  bool IsMathErrnoDefault() const;
498  bool IsUnwindTablesDefault() const;
499  const char* GetDefaultRelocationModel() const;
500  const char* GetForcedPicModel() const;
501
502private:
503  mutable llvm::DenseMap<unsigned, Tool*> Tools;
504
505};
506
507class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
508  mutable llvm::DenseMap<unsigned, Tool*> Tools;
509
510public:
511  Windows(const HostInfo &Host, const llvm::Triple& Triple);
512
513  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
514                           const ActionList &Inputs) const;
515
516  virtual bool IsIntegratedAssemblerDefault() const;
517  virtual bool IsUnwindTablesDefault() const;
518  virtual const char *GetDefaultRelocationModel() const;
519  virtual const char *GetForcedPicModel() const;
520
521  virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
522                                         ArgStringList &CC1Args) const;
523  virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
524                                            ArgStringList &CC1Args) const;
525
526};
527
528} // end namespace toolchains
529} // end namespace driver
530} // end namespace clang
531
532#endif
533