ToolChains.h revision 609508ce95732e7e7010f79c5207613eced7c9cb
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 VISIBILITY_HIDDEN Generic_GCC : public ToolChain {
29protected:
30  mutable llvm::DenseMap<unsigned, Tool*> Tools;
31
32public:
33  Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
34  ~Generic_GCC();
35
36  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
37                                        const char *BoundArch) const;
38
39  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
40
41  virtual bool IsUnwindTablesDefault() const;
42  virtual const char *GetDefaultRelocationModel() const;
43  virtual const char *GetForcedPicModel() const;
44};
45
46/// Darwin - The base Darwin tool chain.
47class VISIBILITY_HIDDEN Darwin : public ToolChain {
48  mutable llvm::DenseMap<unsigned, Tool*> Tools;
49
50  /// Whether the information on the target has been initialized.
51  //
52  // FIXME: This should be eliminated. What we want to do is make this part of
53  // the "default target for arguments" selection process, once we get out of
54  // the argument translation business.
55  mutable bool TargetInitialized;
56
57  /// Whether we are targetting iPhoneOS target.
58  mutable bool TargetIsIPhoneOS;
59
60  /// The OS version we are targetting.
61  mutable unsigned TargetVersion[3];
62
63  /// The default macosx-version-min of this tool chain; empty until
64  /// initialized.
65  std::string MacosxVersionMin;
66
67public:
68  Darwin(const HostInfo &Host, const llvm::Triple& Triple,
69         const unsigned (&DarwinVersion)[3]);
70  ~Darwin();
71
72  /// @name Darwin Specific Toolchain API
73  /// {
74
75  // FIXME: Eliminate these ...Target functions and derive separate tool chains
76  // for these targets and put version in constructor.
77  void setTarget(bool isIPhoneOS, unsigned Major, unsigned Minor,
78                 unsigned Micro) const {
79    // FIXME: For now, allow reinitialization as long as values don't
80    // change. This will go away when we move away from argument translation.
81    if (TargetInitialized && TargetIsIPhoneOS == isIPhoneOS &&
82        TargetVersion[0] == Major && TargetVersion[1] == Minor &&
83        TargetVersion[2] == Micro)
84      return;
85
86    assert(!TargetInitialized && "Target already initialized!");
87    TargetInitialized = true;
88    TargetIsIPhoneOS = isIPhoneOS;
89    TargetVersion[0] = Major;
90    TargetVersion[1] = Minor;
91    TargetVersion[2] = Micro;
92  }
93
94  bool isTargetIPhoneOS() const {
95    assert(TargetInitialized && "Target not initialized!");
96    return TargetIsIPhoneOS;
97  }
98
99  void getTargetVersion(unsigned (&Res)[3]) const {
100    assert(TargetInitialized && "Target not initialized!");
101    Res[0] = TargetVersion[0];
102    Res[1] = TargetVersion[1];
103    Res[2] = TargetVersion[2];
104  }
105
106  /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
107  /// invocation. For example, Darwin treats different ARM variations as
108  /// distinct architectures.
109  llvm::StringRef getDarwinArchName(const ArgList &Args) const;
110
111  static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
112    for (unsigned i=0; i < 3; ++i) {
113      if (A[i] > B[i]) return false;
114      if (A[i] < B[i]) return true;
115    }
116    return false;
117  }
118
119  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
120    assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
121    unsigned B[3] = { V0, V1, V2 };
122    return isVersionLT(TargetVersion, B);
123  }
124
125  bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
126    assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
127    unsigned B[3] = { V0, V1, V2 };
128    return isVersionLT(TargetVersion, B);
129  }
130
131  /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
132  ///
133  /// \param Args - The input argument list.
134  /// \param CmdArgs [out] - The command argument list to append the paths
135  /// (prefixed by -L) to.
136  virtual void AddLinkSearchPathArgs(const ArgList &Args,
137                                     ArgStringList &CmdArgs) const = 0;
138
139  /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler
140  /// runtime library.
141  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
142                                     ArgStringList &CmdArgs) const = 0;
143
144  /// }
145  /// @name ToolChain Implementation
146  /// {
147
148  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
149                                        const char *BoundArch) const;
150
151  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
152
153  virtual bool IsBlocksDefault() const {
154    // Blocks default to on for OS X 10.6 and iPhoneOS 3.0 and beyond.
155    if (isTargetIPhoneOS())
156      return !isIPhoneOSVersionLT(3);
157    else
158      return !isMacosxVersionLT(10, 6);
159  }
160  virtual bool IsObjCNonFragileABIDefault() const {
161    // Non-fragile ABI default to on for iPhoneOS and x86-64.
162    return isTargetIPhoneOS() || getTriple().getArch() == llvm::Triple::x86_64;
163  }
164  virtual bool IsObjCLegacyDispatchDefault() const {
165    // This is only used with the non-fragile ABI.
166    return (getTriple().getArch() == llvm::Triple::arm ||
167            getTriple().getArch() == llvm::Triple::thumb);
168  }
169  virtual bool IsUnwindTablesDefault() const;
170  virtual unsigned GetDefaultStackProtectorLevel() const {
171    // Stack protectors default to on for 10.6 and beyond.
172    return !isTargetIPhoneOS() && !isMacosxVersionLT(10, 6);
173  }
174  virtual const char *GetDefaultRelocationModel() const;
175  virtual const char *GetForcedPicModel() const;
176
177  virtual bool UseDwarfDebugFlags() const;
178
179  /// }
180};
181
182/// DarwinClang - The Darwin toolchain used by Clang.
183class VISIBILITY_HIDDEN DarwinClang : public Darwin {
184public:
185  DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
186              const unsigned (&DarwinVersion)[3]);
187
188  /// @name Darwin ToolChain Implementation
189  /// {
190
191  virtual void AddLinkSearchPathArgs(const ArgList &Args,
192                                    ArgStringList &CmdArgs) const;
193
194  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
195                                     ArgStringList &CmdArgs) const;
196
197  /// }
198};
199
200/// DarwinGCC - The Darwin toolchain used by GCC.
201class VISIBILITY_HIDDEN DarwinGCC : public Darwin {
202  /// GCC version to use.
203  unsigned GCCVersion[3];
204
205  /// The directory suffix for this tool chain.
206  std::string ToolChainDir;
207
208public:
209  DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
210            const unsigned (&DarwinVersion)[3],
211            const unsigned (&GCCVersion)[3]);
212
213  /// @name Darwin ToolChain Implementation
214  /// {
215
216  virtual void AddLinkSearchPathArgs(const ArgList &Args,
217                                    ArgStringList &CmdArgs) const;
218
219  virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
220                                     ArgStringList &CmdArgs) const;
221
222  /// }
223};
224
225/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
226class VISIBILITY_HIDDEN Darwin_Generic_GCC : public Generic_GCC {
227public:
228  Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
229    : Generic_GCC(Host, Triple) {}
230
231  virtual const char *GetDefaultRelocationModel() const { return "pic"; }
232};
233
234class VISIBILITY_HIDDEN AuroraUX : public Generic_GCC {
235public:
236  AuroraUX(const HostInfo &Host, const llvm::Triple& Triple);
237
238  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
239};
240
241class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
242public:
243  OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
244
245  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
246};
247
248class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
249public:
250  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
251
252  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
253};
254
255class VISIBILITY_HIDDEN DragonFly : public Generic_GCC {
256public:
257  DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
258
259  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
260};
261
262class VISIBILITY_HIDDEN Linux : public Generic_GCC {
263public:
264  Linux(const HostInfo &Host, const llvm::Triple& Triple);
265};
266
267
268} // end namespace toolchains
269} // end namespace driver
270} // end namespace clang
271
272#endif
273