clang  19.0.0git
Gnu.h
Go to the documentation of this file.
1 //===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 "LazyDetector.h"
14 #include "ROCm.h"
15 #include "clang/Driver/Tool.h"
16 #include "clang/Driver/ToolChain.h"
17 #include <set>
18 
19 namespace clang {
20 namespace driver {
21 
23  /// The set of multilibs that the detected installation supports.
25 
26  /// The multilibs appropriate for the given flags.
28 
29  /// On Biarch systems, this corresponds to the default multilib when
30  /// targeting the non-default multilib. Otherwise, it is empty.
31  std::optional<Multilib> BiarchSibling;
32 };
33 
34 bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
35  StringRef Path, const llvm::opt::ArgList &Args,
36  DetectedMultilibs &Result);
37 
38 namespace tools {
39 
40 /// Directly call GNU Binutils' assembler and linker.
41 namespace gnutools {
42 class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
43 public:
44  Assembler(const ToolChain &TC) : Tool("GNU::Assembler", "assembler", TC) {}
45 
46  bool hasIntegratedCPP() const override { return false; }
47 
48  void ConstructJob(Compilation &C, const JobAction &JA,
49  const InputInfo &Output, const InputInfoList &Inputs,
50  const llvm::opt::ArgList &TCArgs,
51  const char *LinkingOutput) const override;
52 };
53 
54 class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
55 public:
56  Linker(const ToolChain &TC) : Tool("GNU::Linker", "linker", TC) {}
57 
58  bool hasIntegratedCPP() const override { return false; }
59  bool isLinkJob() const override { return true; }
60 
61  void ConstructJob(Compilation &C, const JobAction &JA,
62  const InputInfo &Output, const InputInfoList &Inputs,
63  const llvm::opt::ArgList &TCArgs,
64  const char *LinkingOutput) const override;
65 
66 private:
67  void constructLLVMARCommand(Compilation &C, const JobAction &JA,
68  const InputInfo &Output,
69  const InputInfoList &InputFiles,
70  const llvm::opt::ArgList &Args) const;
71 };
72 
73 class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool {
74 public:
76  : Tool("GNU::StaticLibTool", "static-lib-linker", TC) {}
77 
78  bool hasIntegratedCPP() const override { return false; }
79  bool isLinkJob() const override { return true; }
80 
81  void ConstructJob(Compilation &C, const JobAction &JA,
82  const InputInfo &Output, const InputInfoList &Inputs,
83  const llvm::opt::ArgList &TCArgs,
84  const char *LinkingOutput) const override;
85 };
86 } // end namespace gnutools
87 
88 /// gcc - Generic GCC tool implementations.
89 namespace gcc {
90 class LLVM_LIBRARY_VISIBILITY Common : public Tool {
91 public:
92  Common(const char *Name, const char *ShortName, const ToolChain &TC)
93  : Tool(Name, ShortName, TC) {}
94 
95  // A gcc tool has an "integrated" assembler that it will call to produce an
96  // object. Let it use that assembler so that we don't have to deal with
97  // assembly syntax incompatibilities.
98  bool hasIntegratedAssembler() const override { return true; }
99  void ConstructJob(Compilation &C, const JobAction &JA,
100  const InputInfo &Output, const InputInfoList &Inputs,
101  const llvm::opt::ArgList &TCArgs,
102  const char *LinkingOutput) const override;
103 
104  /// RenderExtraToolArgs - Render any arguments necessary to force
105  /// the particular tool mode.
106  virtual void RenderExtraToolArgs(const JobAction &JA,
107  llvm::opt::ArgStringList &CmdArgs) const = 0;
108 };
109 
110 class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common {
111 public:
113  : Common("gcc::Preprocessor", "gcc preprocessor", TC) {}
114 
115  bool hasGoodDiagnostics() const override { return true; }
116  bool hasIntegratedCPP() const override { return false; }
117 
118  void RenderExtraToolArgs(const JobAction &JA,
119  llvm::opt::ArgStringList &CmdArgs) const override;
120 };
121 
122 class LLVM_LIBRARY_VISIBILITY Compiler : public Common {
123 public:
124  Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {}
125 
126  bool hasGoodDiagnostics() const override { return true; }
127  bool hasIntegratedCPP() const override { return true; }
128 
129  void RenderExtraToolArgs(const JobAction &JA,
130  llvm::opt::ArgStringList &CmdArgs) const override;
131 };
132 
133 class LLVM_LIBRARY_VISIBILITY Linker : public Common {
134 public:
135  Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {}
136 
137  bool hasIntegratedCPP() const override { return false; }
138  bool isLinkJob() const override { return true; }
139 
140  void RenderExtraToolArgs(const JobAction &JA,
141  llvm::opt::ArgStringList &CmdArgs) const override;
142 };
143 } // end namespace gcc
144 } // end namespace tools
145 
146 namespace toolchains {
147 
148 /// Generic_GCC - A tool chain using the 'gcc' command to perform
149 /// all subcommands; this relies on gcc translating the majority of
150 /// command line options.
151 class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
152 public:
153  /// Struct to store and manipulate GCC versions.
154  ///
155  /// We rely on assumptions about the form and structure of GCC version
156  /// numbers: they consist of at most three '.'-separated components, and each
157  /// component is a non-negative integer except for the last component. For
158  /// the last component we are very flexible in order to tolerate release
159  /// candidates or 'x' wildcards.
160  ///
161  /// Note that the ordering established among GCCVersions is based on the
162  /// preferred version string to use. For example we prefer versions without
163  /// a hard-coded patch number to those with a hard coded patch number.
164  ///
165  /// Currently this doesn't provide any logic for textual suffixes to patches
166  /// in the way that (for example) Debian's version format does. If that ever
167  /// becomes necessary, it can be added.
168  struct GCCVersion {
169  /// The unparsed text of the version.
170  std::string Text;
171 
172  /// The parsed major, minor, and patch numbers.
173  int Major, Minor, Patch;
174 
175  /// The text of the parsed major, and major+minor versions.
176  std::string MajorStr, MinorStr;
177 
178  /// Any textual suffix on the patch number.
179  std::string PatchSuffix;
180 
181  static GCCVersion Parse(StringRef VersionText);
182  bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch,
183  StringRef RHSPatchSuffix = StringRef()) const;
184  bool operator<(const GCCVersion &RHS) const {
185  return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix);
186  }
187  bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
188  bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
189  bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
190  };
191 
192  /// This is a class to find a viable GCC installation for Clang to
193  /// use.
194  ///
195  /// This class tries to find a GCC installation on the system, and report
196  /// information about it. It starts from the host information provided to the
197  /// Driver, and has logic for fuzzing that where appropriate.
199  bool IsValid;
200  llvm::Triple GCCTriple;
201  const Driver &D;
202 
203  // FIXME: These might be better as path objects.
204  std::string GCCInstallPath;
205  std::string GCCParentLibPath;
206 
207  /// The primary multilib appropriate for the given flags.
208  Multilib SelectedMultilib;
209  /// On Biarch systems, this corresponds to the default multilib when
210  /// targeting the non-default multilib. Otherwise, it is empty.
211  std::optional<Multilib> BiarchSibling;
212 
213  GCCVersion Version;
214 
215  // We retain the list of install paths that were considered and rejected in
216  // order to print out detailed information in verbose mode.
217  std::set<std::string> CandidateGCCInstallPaths;
218 
219  /// The set of multilibs that the detected installation supports.
220  MultilibSet Multilibs;
221 
222  // Gentoo-specific toolchain configurations are stored here.
223  const std::string GentooConfigDir = "/etc/env.d/gcc";
224 
225  public:
226  explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
227  void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);
228 
229  /// Check whether we detected a valid GCC install.
230  bool isValid() const { return IsValid; }
231 
232  /// Get the GCC triple for the detected install.
233  const llvm::Triple &getTriple() const { return GCCTriple; }
234 
235  /// Get the detected GCC installation path.
236  StringRef getInstallPath() const { return GCCInstallPath; }
237 
238  /// Get the detected GCC parent lib path.
239  StringRef getParentLibPath() const { return GCCParentLibPath; }
240 
241  /// Get the detected Multilib
242  const Multilib &getMultilib() const { return SelectedMultilib; }
243 
244  /// Get the whole MultilibSet
245  const MultilibSet &getMultilibs() const { return Multilibs; }
246 
247  /// Get the biarch sibling multilib (if it exists).
248  /// \return true iff such a sibling exists
249  bool getBiarchSibling(Multilib &M) const;
250 
251  /// Get the detected GCC version string.
252  const GCCVersion &getVersion() const { return Version; }
253 
254  /// Print information about the detected GCC installation.
255  void print(raw_ostream &OS) const;
256 
257  private:
258  static void
259  CollectLibDirsAndTriples(const llvm::Triple &TargetTriple,
260  const llvm::Triple &BiarchTriple,
262  SmallVectorImpl<StringRef> &TripleAliases,
263  SmallVectorImpl<StringRef> &BiarchLibDirs,
264  SmallVectorImpl<StringRef> &BiarchTripleAliases);
265 
266  void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple,
268  StringRef SysRoot);
269 
270  bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple,
271  const llvm::opt::ArgList &Args,
272  StringRef Path,
273  bool NeedsBiarchSuffix = false);
274 
275  void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
276  const llvm::opt::ArgList &Args,
277  const std::string &LibDir,
278  StringRef CandidateTriple,
279  bool NeedsBiarchSuffix, bool GCCDirExists,
280  bool GCCCrossDirExists);
281 
282  bool ScanGentooConfigs(const llvm::Triple &TargetTriple,
283  const llvm::opt::ArgList &Args,
284  const SmallVectorImpl<StringRef> &CandidateTriples,
285  const SmallVectorImpl<StringRef> &BiarchTriples);
286 
287  bool ScanGentooGccConfig(const llvm::Triple &TargetTriple,
288  const llvm::opt::ArgList &Args,
289  StringRef CandidateTriple,
290  bool NeedsBiarchSuffix = false);
291  };
292 
293 protected:
297 
298 public:
299  Generic_GCC(const Driver &D, const llvm::Triple &Triple,
300  const llvm::opt::ArgList &Args);
301  ~Generic_GCC() override;
302 
303  void printVerboseInfo(raw_ostream &OS) const override;
304 
306  getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;
307  bool isPICDefault() const override;
308  bool isPIEDefault(const llvm::opt::ArgList &Args) const override;
309  bool isPICDefaultForced() const override;
310  bool IsIntegratedAssemblerDefault() const override;
311  llvm::opt::DerivedArgList *
312  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
313  Action::OffloadKind DeviceOffloadKind) const override;
314 
315 protected:
316  Tool *getTool(Action::ActionClass AC) const override;
317  Tool *buildAssembler() const override;
318  Tool *buildLinker() const override;
319 
320  /// \name ToolChain Implementation Helper Functions
321  /// @{
322 
323  /// Check whether the target triple's architecture is 64-bits.
324  bool isTarget64Bit() const { return getTriple().isArch64Bit(); }
325 
326  /// Check whether the target triple's architecture is 32-bits.
327  bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
328 
329  void PushPPaths(ToolChain::path_list &PPaths);
330  void AddMultilibPaths(const Driver &D, const std::string &SysRoot,
331  const std::string &OSLibDir,
332  const std::string &MultiarchTriple,
333  path_list &Paths);
334  void AddMultiarchPaths(const Driver &D, const std::string &SysRoot,
335  const std::string &OSLibDir, path_list &Paths);
336  void AddMultilibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
337  llvm::opt::ArgStringList &CC1Args) const;
338 
339  // FIXME: This should be final, but the CrossWindows toolchain does weird
340  // things that can't be easily generalized.
341  void AddClangCXXStdlibIncludeArgs(
342  const llvm::opt::ArgList &DriverArgs,
343  llvm::opt::ArgStringList &CC1Args) const override;
344 
345  virtual void
346  addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
347  llvm::opt::ArgStringList &CC1Args) const;
348  virtual void
349  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
350  llvm::opt::ArgStringList &CC1Args) const;
351 
352  bool addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
353  llvm::opt::ArgStringList &CC1Args,
354  StringRef DebianMultiarch) const;
355 
356  bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
357  Twine IncludeSuffix,
358  const llvm::opt::ArgList &DriverArgs,
359  llvm::opt::ArgStringList &CC1Args,
360  bool DetectDebian = false) const;
361 
362  /// @}
363 
364 private:
365  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess;
366  mutable std::unique_ptr<tools::gcc::Compiler> Compile;
367 };
368 
369 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
370  virtual void anchor();
371 
372 public:
373  Generic_ELF(const Driver &D, const llvm::Triple &Triple,
374  const llvm::opt::ArgList &Args)
375  : Generic_GCC(D, Triple, Args) {}
376 
377  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
378  llvm::opt::ArgStringList &CC1Args,
379  Action::OffloadKind DeviceOffloadKind) const override;
380 
381  virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const {
382  return {};
383  }
384 
385  virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {}
386 };
387 
388 } // end namespace toolchains
389 } // end namespace driver
390 } // end namespace clang
391 
392 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, QualType Ty)
Simple wrapper for toolchain detector with costly initialization.
Definition: LazyDetector.h:21
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
See also MultilibSetBuilder for combining multilibs into a set.
Definition: Multilib.h:92
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:32
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const
Definition: Gnu.h:381
Generic_ELF(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: Gnu.h:373
virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const
Definition: Gnu.h:385
This is a class to find a viable GCC installation for Clang to use.
Definition: Gnu.h:198
bool isValid() const
Check whether we detected a valid GCC install.
Definition: Gnu.h:230
const llvm::Triple & getTriple() const
Get the GCC triple for the detected install.
Definition: Gnu.h:233
const Multilib & getMultilib() const
Get the detected Multilib.
Definition: Gnu.h:242
StringRef getParentLibPath() const
Get the detected GCC parent lib path.
Definition: Gnu.h:239
StringRef getInstallPath() const
Get the detected GCC installation path.
Definition: Gnu.h:236
const GCCVersion & getVersion() const
Get the detected GCC version string.
Definition: Gnu.h:252
const MultilibSet & getMultilibs() const
Get the whole MultilibSet.
Definition: Gnu.h:245
Generic_GCC - A tool chain using the 'gcc' command to perform all subcommands; this relies on gcc tra...
Definition: Gnu.h:151
LazyDetector< CudaInstallationDetector > CudaInstallation
Definition: Gnu.h:295
GCCInstallationDetector GCCInstallation
Definition: Gnu.h:294
bool isTarget32Bit() const
Check whether the target triple's architecture is 32-bits.
Definition: Gnu.h:327
bool isTarget64Bit() const
Check whether the target triple's architecture is 64-bits.
Definition: Gnu.h:324
LazyDetector< RocmInstallationDetector > RocmInstallation
Definition: Gnu.h:296
bool hasIntegratedAssembler() const override
Definition: Gnu.h:98
Common(const char *Name, const char *ShortName, const ToolChain &TC)
Definition: Gnu.h:92
virtual void RenderExtraToolArgs(const JobAction &JA, llvm::opt::ArgStringList &CmdArgs) const =0
RenderExtraToolArgs - Render any arguments necessary to force the particular tool mode.
bool hasIntegratedCPP() const override
Definition: Gnu.h:127
bool hasGoodDiagnostics() const override
Does this tool have "good" standardized diagnostics, or should the driver add an additional "command ...
Definition: Gnu.h:126
Compiler(const ToolChain &TC)
Definition: Gnu.h:124
Linker(const ToolChain &TC)
Definition: Gnu.h:135
bool hasIntegratedCPP() const override
Definition: Gnu.h:137
bool isLinkJob() const override
Definition: Gnu.h:138
bool hasIntegratedCPP() const override
Definition: Gnu.h:116
bool hasGoodDiagnostics() const override
Does this tool have "good" standardized diagnostics, or should the driver add an additional "command ...
Definition: Gnu.h:115
Preprocessor(const ToolChain &TC)
Definition: Gnu.h:112
bool hasIntegratedCPP() const override
Definition: Gnu.h:46
Assembler(const ToolChain &TC)
Definition: Gnu.h:44
bool isLinkJob() const override
Definition: Gnu.h:59
bool hasIntegratedCPP() const override
Definition: Gnu.h:58
Linker(const ToolChain &TC)
Definition: Gnu.h:56
StaticLibTool(const ToolChain &TC)
Definition: Gnu.h:75
bool hasIntegratedCPP() const override
Definition: Gnu.h:78
bool isLinkJob() const override
Definition: Gnu.h:79
bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const llvm::opt::ArgList &Args, DetectedMultilibs &Result)
The JSON file list parser is used to communicate input to InstallAPI.
#define false
Definition: stdbool.h:26
MultilibSet Multilibs
The set of multilibs that the detected installation supports.
Definition: Gnu.h:24
std::optional< Multilib > BiarchSibling
On Biarch systems, this corresponds to the default multilib when targeting the non-default multilib.
Definition: Gnu.h:31
llvm::SmallVector< Multilib > SelectedMultilibs
The multilibs appropriate for the given flags.
Definition: Gnu.h:27
Struct to store and manipulate GCC versions.
Definition: Gnu.h:168
std::string MajorStr
The text of the parsed major, and major+minor versions.
Definition: Gnu.h:176
bool operator<(const GCCVersion &RHS) const
Definition: Gnu.h:184
bool operator<=(const GCCVersion &RHS) const
Definition: Gnu.h:188
bool operator>=(const GCCVersion &RHS) const
Definition: Gnu.h:189
std::string PatchSuffix
Any textual suffix on the patch number.
Definition: Gnu.h:179
bool operator>(const GCCVersion &RHS) const
Definition: Gnu.h:187
int Major
The parsed major, minor, and patch numbers.
Definition: Gnu.h:173
std::string Text
The unparsed text of the version.
Definition: Gnu.h:170