1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H |
10 | #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H |
11 | |
12 | #include "Cuda.h" |
13 | #include "clang/Driver/Tool.h" |
14 | #include "clang/Driver/ToolChain.h" |
15 | #include <set> |
16 | |
17 | namespace clang { |
18 | namespace driver { |
19 | |
20 | struct DetectedMultilibs { |
21 | |
22 | MultilibSet Multilibs; |
23 | |
24 | |
25 | Multilib SelectedMultilib; |
26 | |
27 | |
28 | |
29 | llvm::Optional<Multilib> BiarchSibling; |
30 | }; |
31 | |
32 | bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, |
33 | StringRef Path, const llvm::opt::ArgList &Args, |
34 | DetectedMultilibs &Result); |
35 | |
36 | namespace tools { |
37 | |
38 | |
39 | |
40 | class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool { |
41 | virtual void anchor(); |
42 | |
43 | public: |
44 | GnuTool(const char *Name, const char *ShortName, const ToolChain &TC) |
45 | : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {} |
46 | }; |
47 | |
48 | |
49 | namespace gnutools { |
50 | class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { |
51 | public: |
52 | Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {} |
53 | |
54 | bool hasIntegratedCPP() const override { return false; } |
55 | |
56 | void ConstructJob(Compilation &C, const JobAction &JA, |
57 | const InputInfo &Output, const InputInfoList &Inputs, |
58 | const llvm::opt::ArgList &TCArgs, |
59 | const char *LinkingOutput) const override; |
60 | }; |
61 | |
62 | class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { |
63 | public: |
64 | Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {} |
65 | |
66 | bool hasIntegratedCPP() const override { return false; } |
67 | bool isLinkJob() const override { return true; } |
68 | |
69 | void ConstructJob(Compilation &C, const JobAction &JA, |
70 | const InputInfo &Output, const InputInfoList &Inputs, |
71 | const llvm::opt::ArgList &TCArgs, |
72 | const char *LinkingOutput) const override; |
73 | }; |
74 | } |
75 | |
76 | |
77 | namespace gcc { |
78 | class LLVM_LIBRARY_VISIBILITY Common : public GnuTool { |
79 | public: |
80 | Common(const char *Name, const char *ShortName, const ToolChain &TC) |
81 | : GnuTool(Name, ShortName, TC) {} |
82 | |
83 | |
84 | |
85 | |
86 | bool hasIntegratedAssembler() const override { return true; } |
87 | void ConstructJob(Compilation &C, const JobAction &JA, |
88 | const InputInfo &Output, const InputInfoList &Inputs, |
89 | const llvm::opt::ArgList &TCArgs, |
90 | const char *LinkingOutput) const override; |
91 | |
92 | |
93 | |
94 | virtual void RenderExtraToolArgs(const JobAction &JA, |
95 | llvm::opt::ArgStringList &CmdArgs) const = 0; |
96 | }; |
97 | |
98 | class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common { |
99 | public: |
100 | Preprocessor(const ToolChain &TC) |
101 | : Common("gcc::Preprocessor", "gcc preprocessor", TC) {} |
102 | |
103 | bool hasGoodDiagnostics() const override { return true; } |
104 | bool hasIntegratedCPP() const override { return false; } |
105 | |
106 | void RenderExtraToolArgs(const JobAction &JA, |
107 | llvm::opt::ArgStringList &CmdArgs) const override; |
108 | }; |
109 | |
110 | class LLVM_LIBRARY_VISIBILITY Compiler : public Common { |
111 | public: |
112 | Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {} |
113 | |
114 | bool hasGoodDiagnostics() const override { return true; } |
115 | bool hasIntegratedCPP() const override { return true; } |
116 | |
117 | void RenderExtraToolArgs(const JobAction &JA, |
118 | llvm::opt::ArgStringList &CmdArgs) const override; |
119 | }; |
120 | |
121 | class LLVM_LIBRARY_VISIBILITY Linker : public Common { |
122 | public: |
123 | Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {} |
124 | |
125 | bool hasIntegratedCPP() const override { return false; } |
126 | bool isLinkJob() const override { return true; } |
127 | |
128 | void RenderExtraToolArgs(const JobAction &JA, |
129 | llvm::opt::ArgStringList &CmdArgs) const override; |
130 | }; |
131 | } |
132 | } |
133 | |
134 | namespace toolchains { |
135 | |
136 | |
137 | |
138 | |
139 | class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { |
140 | public: |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | struct GCCVersion { |
157 | |
158 | std::string Text; |
159 | |
160 | |
161 | int Major, Minor, Patch; |
162 | |
163 | |
164 | std::string MajorStr, MinorStr; |
165 | |
166 | |
167 | std::string PatchSuffix; |
168 | |
169 | static GCCVersion Parse(StringRef VersionText); |
170 | bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch, |
171 | StringRef RHSPatchSuffix = StringRef()) const; |
172 | bool operator<(const GCCVersion &RHS) const { |
173 | return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix); |
174 | } |
175 | bool operator>(const GCCVersion &RHS) const { return RHS < *this; } |
176 | bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } |
177 | bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } |
178 | }; |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | class GCCInstallationDetector { |
187 | bool IsValid; |
188 | llvm::Triple GCCTriple; |
189 | const Driver &D; |
190 | |
191 | |
192 | std::string GCCInstallPath; |
193 | std::string GCCParentLibPath; |
194 | |
195 | |
196 | Multilib SelectedMultilib; |
197 | |
198 | |
199 | llvm::Optional<Multilib> BiarchSibling; |
200 | |
201 | GCCVersion Version; |
202 | |
203 | |
204 | |
205 | std::set<std::string> CandidateGCCInstallPaths; |
206 | |
207 | |
208 | MultilibSet Multilibs; |
209 | |
210 | public: |
211 | explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} |
212 | void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, |
213 | ArrayRef<std::string> ExtraTripleAliases = None); |
214 | |
215 | |
216 | bool isValid() const { return IsValid; } |
217 | |
218 | |
219 | const llvm::Triple &getTriple() const { return GCCTriple; } |
220 | |
221 | |
222 | StringRef getInstallPath() const { return GCCInstallPath; } |
223 | |
224 | |
225 | StringRef getParentLibPath() const { return GCCParentLibPath; } |
226 | |
227 | |
228 | const Multilib &getMultilib() const { return SelectedMultilib; } |
229 | |
230 | |
231 | const MultilibSet &getMultilibs() const { return Multilibs; } |
232 | |
233 | |
234 | |
235 | bool getBiarchSibling(Multilib &M) const; |
236 | |
237 | |
238 | const GCCVersion &getVersion() const { return Version; } |
239 | |
240 | |
241 | void print(raw_ostream &OS) const; |
242 | |
243 | private: |
244 | static void |
245 | CollectLibDirsAndTriples(const llvm::Triple &TargetTriple, |
246 | const llvm::Triple &BiarchTriple, |
247 | SmallVectorImpl<StringRef> &LibDirs, |
248 | SmallVectorImpl<StringRef> &TripleAliases, |
249 | SmallVectorImpl<StringRef> &BiarchLibDirs, |
250 | SmallVectorImpl<StringRef> &BiarchTripleAliases); |
251 | |
252 | void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple, |
253 | SmallVectorImpl<std::string> &Prefixes, |
254 | StringRef SysRoot); |
255 | |
256 | bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple, |
257 | const llvm::opt::ArgList &Args, |
258 | StringRef Path, |
259 | bool NeedsBiarchSuffix = false); |
260 | |
261 | void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, |
262 | const llvm::opt::ArgList &Args, |
263 | const std::string &LibDir, |
264 | StringRef CandidateTriple, |
265 | bool NeedsBiarchSuffix = false); |
266 | |
267 | bool ScanGentooConfigs(const llvm::Triple &TargetTriple, |
268 | const llvm::opt::ArgList &Args, |
269 | const SmallVectorImpl<StringRef> &CandidateTriples, |
270 | const SmallVectorImpl<StringRef> &BiarchTriples); |
271 | |
272 | bool ScanGentooGccConfig(const llvm::Triple &TargetTriple, |
273 | const llvm::opt::ArgList &Args, |
274 | StringRef CandidateTriple, |
275 | bool NeedsBiarchSuffix = false); |
276 | }; |
277 | |
278 | protected: |
279 | GCCInstallationDetector GCCInstallation; |
280 | CudaInstallationDetector CudaInstallation; |
281 | |
282 | public: |
283 | Generic_GCC(const Driver &D, const llvm::Triple &Triple, |
284 | const llvm::opt::ArgList &Args); |
285 | ~Generic_GCC() override; |
286 | |
287 | void printVerboseInfo(raw_ostream &OS) const override; |
288 | |
289 | bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; |
290 | bool isPICDefault() const override; |
291 | bool isPIEDefault() const override; |
292 | bool isPICDefaultForced() const override; |
293 | bool IsIntegratedAssemblerDefault() const override; |
294 | llvm::opt::DerivedArgList * |
295 | TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, |
296 | Action::OffloadKind DeviceOffloadKind) const override; |
297 | |
298 | protected: |
299 | Tool *getTool(Action::ActionClass AC) const override; |
300 | Tool *buildAssembler() const override; |
301 | Tool *buildLinker() const override; |
302 | |
303 | |
304 | |
305 | |
306 | |
307 | bool isTarget64Bit() const { return getTriple().isArch64Bit(); } |
308 | |
309 | |
310 | bool isTarget32Bit() const { return getTriple().isArch32Bit(); } |
311 | |
312 | |
313 | |
314 | void AddClangCXXStdlibIncludeArgs( |
315 | const llvm::opt::ArgList &DriverArgs, |
316 | llvm::opt::ArgStringList &CC1Args) const override; |
317 | |
318 | virtual void |
319 | addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
320 | llvm::opt::ArgStringList &CC1Args) const; |
321 | virtual void |
322 | addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
323 | llvm::opt::ArgStringList &CC1Args) const; |
324 | |
325 | bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, |
326 | StringRef GCCMultiarchTriple, |
327 | StringRef TargetMultiarchTriple, |
328 | Twine IncludeSuffix, |
329 | const llvm::opt::ArgList &DriverArgs, |
330 | llvm::opt::ArgStringList &CC1Args) const; |
331 | |
332 | |
333 | |
334 | private: |
335 | mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; |
336 | mutable std::unique_ptr<tools::gcc::Compiler> Compile; |
337 | }; |
338 | |
339 | class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { |
340 | virtual void anchor(); |
341 | |
342 | public: |
343 | Generic_ELF(const Driver &D, const llvm::Triple &Triple, |
344 | const llvm::opt::ArgList &Args) |
345 | : Generic_GCC(D, Triple, Args) {} |
346 | |
347 | void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, |
348 | llvm::opt::ArgStringList &CC1Args, |
349 | Action::OffloadKind DeviceOffloadKind) const override; |
350 | }; |
351 | |
352 | } |
353 | } |
354 | } |
355 | |
356 | #endif |
357 | |