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