brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.3 KiB · 5fe143b Raw
459 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H10#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H11 12#include "clang/Driver/CudaInstallationDetector.h"13#include "clang/Driver/LazyDetector.h"14#include "clang/Driver/RocmInstallationDetector.h"15#include "clang/Driver/SyclInstallationDetector.h"16#include "clang/Driver/Tool.h"17#include "clang/Driver/ToolChain.h"18#include <set>19 20namespace clang {21namespace driver {22 23struct DetectedMultilibs {24  /// The set of multilibs that the detected installation supports.25  MultilibSet Multilibs;26 27  /// The multilibs appropriate for the given flags.28  llvm::SmallVector<Multilib> SelectedMultilibs;29 30  /// On Biarch systems, this corresponds to the default multilib when31  /// targeting the non-default multilib. Otherwise, it is empty.32  std::optional<Multilib> BiarchSibling;33};34 35bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,36                       StringRef Path, const llvm::opt::ArgList &Args,37                       DetectedMultilibs &Result);38 39namespace tools {40 41/// Directly call GNU Binutils' assembler and linker.42namespace gnutools {43class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {44public:45  Assembler(const ToolChain &TC) : Tool("GNU::Assembler", "assembler", TC) {}46 47  bool hasIntegratedCPP() const override { return false; }48 49  void ConstructJob(Compilation &C, const JobAction &JA,50                    const InputInfo &Output, const InputInfoList &Inputs,51                    const llvm::opt::ArgList &TCArgs,52                    const char *LinkingOutput) const override;53};54 55class LLVM_LIBRARY_VISIBILITY Linker : public Tool {56public:57  Linker(const ToolChain &TC) : Tool("GNU::Linker", "linker", TC) {}58 59  bool hasIntegratedCPP() const override { return false; }60  bool isLinkJob() const override { return true; }61 62  void ConstructJob(Compilation &C, const JobAction &JA,63                    const InputInfo &Output, const InputInfoList &Inputs,64                    const llvm::opt::ArgList &TCArgs,65                    const char *LinkingOutput) const override;66};67 68class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool {69public:70  StaticLibTool(const ToolChain &TC)71      : Tool("GNU::StaticLibTool", "static-lib-linker", TC) {}72 73  bool hasIntegratedCPP() const override { return false; }74  bool isLinkJob() const override { return true; }75 76  void ConstructJob(Compilation &C, const JobAction &JA,77                    const InputInfo &Output, const InputInfoList &Inputs,78                    const llvm::opt::ArgList &TCArgs,79                    const char *LinkingOutput) const override;80};81} // end namespace gnutools82 83/// gcc - Generic GCC tool implementations.84namespace gcc {85class LLVM_LIBRARY_VISIBILITY Common : public Tool {86public:87  Common(const char *Name, const char *ShortName, const ToolChain &TC)88      : Tool(Name, ShortName, TC) {}89 90  // A gcc tool has an "integrated" assembler that it will call to produce an91  // object. Let it use that assembler so that we don't have to deal with92  // assembly syntax incompatibilities.93  bool hasIntegratedAssembler() const override { return true; }94  void ConstructJob(Compilation &C, const JobAction &JA,95                    const InputInfo &Output, const InputInfoList &Inputs,96                    const llvm::opt::ArgList &TCArgs,97                    const char *LinkingOutput) const override;98 99  /// RenderExtraToolArgs - Render any arguments necessary to force100  /// the particular tool mode.101  virtual void RenderExtraToolArgs(const JobAction &JA,102                                   llvm::opt::ArgStringList &CmdArgs) const = 0;103};104 105class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common {106public:107  Preprocessor(const ToolChain &TC)108      : Common("gcc::Preprocessor", "gcc preprocessor", TC) {}109 110  bool hasGoodDiagnostics() const override { return true; }111  bool hasIntegratedCPP() const override { return false; }112 113  void RenderExtraToolArgs(const JobAction &JA,114                           llvm::opt::ArgStringList &CmdArgs) const override;115};116 117class LLVM_LIBRARY_VISIBILITY Compiler : public Common {118public:119  Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {}120 121  bool hasGoodDiagnostics() const override { return true; }122  bool hasIntegratedCPP() const override { return true; }123 124  void RenderExtraToolArgs(const JobAction &JA,125                           llvm::opt::ArgStringList &CmdArgs) const override;126};127 128class LLVM_LIBRARY_VISIBILITY Linker : public Common {129public:130  Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {}131 132  bool hasIntegratedCPP() const override { return false; }133  bool isLinkJob() const override { return true; }134 135  void RenderExtraToolArgs(const JobAction &JA,136                           llvm::opt::ArgStringList &CmdArgs) const override;137};138} // end namespace gcc139} // end namespace tools140 141namespace toolchains {142 143/// Generic_GCC - A tool chain using the 'gcc' command to perform144/// all subcommands; this relies on gcc translating the majority of145/// command line options.146class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {147public:148  /// Struct to store and manipulate GCC versions.149  ///150  /// We rely on assumptions about the form and structure of GCC version151  /// numbers: they consist of at most three '.'-separated components, and each152  /// component is a non-negative integer except for the last component. For153  /// the last component we are very flexible in order to tolerate release154  /// candidates or 'x' wildcards.155  ///156  /// Note that the ordering established among GCCVersions is based on the157  /// preferred version string to use. For example we prefer versions without158  /// a hard-coded patch number to those with a hard coded patch number.159  ///160  /// Currently this doesn't provide any logic for textual suffixes to patches161  /// in the way that (for example) Debian's version format does. If that ever162  /// becomes necessary, it can be added.163  struct GCCVersion {164    /// The unparsed text of the version.165    std::string Text;166 167    /// The parsed major, minor, and patch numbers.168    int Major, Minor, Patch;169 170    /// The text of the parsed major, and major+minor versions.171    std::string MajorStr, MinorStr;172 173    /// Any textual suffix on the patch number.174    std::string PatchSuffix;175 176    static GCCVersion Parse(StringRef VersionText);177    bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch,178                     StringRef RHSPatchSuffix = StringRef()) const;179    bool operator<(const GCCVersion &RHS) const {180      return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix);181    }182    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }183    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }184    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }185  };186 187  struct GCCInstallCandidate {188    // FIXME: These might be better as path objects.189    std::string GCCInstallPath;190    std::string GCCParentLibPath;191 192    llvm::Triple GCCTriple;193 194    /// The primary multilib appropriate for the given flags.195    Multilib SelectedMultilib;196 197    GCCVersion Version;198 199    /// Get the GCC triple for the detected install.200    const llvm::Triple &getTriple() const { return GCCTriple; }201 202    /// Get the detected GCC installation path.203    StringRef getInstallPath() const { return GCCInstallPath; }204 205    /// Get the detected GCC parent lib path.206    StringRef getParentLibPath() const { return GCCParentLibPath; }207 208    /// Get the detected Multilib209    const Multilib &getMultilib() const { return SelectedMultilib; }210 211    /// Get the detected GCC version string.212    const GCCVersion &getVersion() const { return Version; }213 214    bool addGCCLibStdCxxIncludePaths(llvm::vfs::FileSystem &vfs,215                                     const llvm::opt::ArgList &DriverArgs,216                                     llvm::opt::ArgStringList &CC1Args,217                                     StringRef DebianMultiarch) const;218  };219 220  /// This is a class to find a viable GCC installation for Clang to221  /// use.222  ///223  /// This class tries to find a GCC installation on the system, and report224  /// information about it. It starts from the host information provided to the225  /// Driver, and has logic for fuzzing that where appropriate.226  class GCCInstallationDetector {227    bool IsValid;228 229    const Driver &D;230 231    GCCInstallCandidate SelectedInstallation;232 233    /// On Biarch systems, this corresponds to the default multilib when234    /// targeting the non-default multilib. Otherwise, it is empty.235    std::optional<Multilib> BiarchSibling;236 237    // We retain the list of install paths that were considered and rejected in238    // order to print out detailed information in verbose mode.239    std::set<std::string> CandidateGCCInstallPaths;240 241    /// The set of multilibs that the detected installation supports.242    MultilibSet Multilibs;243 244    // Gentoo-specific toolchain configurations are stored here.245    const std::string GentooConfigDir = "/etc/env.d/gcc";246 247  public:248    /// Function for converting a triple to a Debian multiarch.  The249    /// toolchains use this to adjust the target specific component of250    /// include paths for Debian.251    std::function<StringRef(const llvm::Triple &)> TripleToDebianMultiarch =252        [](const llvm::Triple &T) {253          StringRef S = T.str();254          return S;255        };256 257    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}258 259    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);260 261    // TODO Replace isValid by changing SelectedInstallation into262    // std::optional<SelectedInstallation>263    // and move all accessors for fields of GCCInstallCandidate into264    // that struct.265 266    /// Check whether we detected a valid GCC install.267    bool isValid() const { return IsValid; }268 269    const GCCInstallCandidate &getSelectedInstallation() const {270      return SelectedInstallation;271    }272 273    /// Get the GCC triple for the detected install.274    const llvm::Triple &getTriple() const {275      return SelectedInstallation.GCCTriple;276    }277 278    /// Get the detected GCC installation path.279    StringRef getInstallPath() const {280      return SelectedInstallation.GCCInstallPath;281    }282 283    /// Get the detected GCC parent lib path.284    StringRef getParentLibPath() const {285      return SelectedInstallation.GCCParentLibPath;286    }287 288    /// Get the detected Multilib289    const Multilib &getMultilib() const {290      return SelectedInstallation.SelectedMultilib;291    }292 293    /// Get the whole MultilibSet294    const MultilibSet &getMultilibs() const { return Multilibs; }295 296    /// Get the biarch sibling multilib (if it exists).297    /// \return true iff such a sibling exists298    bool getBiarchSibling(Multilib &M) const;299 300    /// Get the detected GCC version string.301    const GCCVersion &getVersion() const {302      return SelectedInstallation.Version;303    }304 305    /// Print information about the detected GCC installation.306    void print(raw_ostream &OS) const;307 308  private:309    static void310    CollectLibDirsAndTriples(const llvm::Triple &TargetTriple,311                             const llvm::Triple &BiarchTriple,312                             SmallVectorImpl<StringRef> &LibDirs,313                             SmallVectorImpl<StringRef> &TripleAliases,314                             SmallVectorImpl<StringRef> &BiarchLibDirs,315                             SmallVectorImpl<StringRef> &BiarchTripleAliases);316 317    void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple,318                               SmallVectorImpl<std::string> &Prefixes,319                               StringRef SysRoot);320 321    /// Checks if the \p GCCInstallation has libstdc++ include322    /// directories.323    bool GCCInstallationHasLibStdcxxIncludePaths(324        const GCCInstallCandidate &GCCInstallation,325        const llvm::opt::ArgList &DriverArgs) const;326 327    /// Select a GCC installation directory from \p Installations and328    /// set \p SelectedInstallation accordingly.329    bool SelectGCCInstallationDirectory(330        const SmallVector<GCCInstallCandidate, 3> &Installations,331        const llvm::opt::ArgList &Args,332        GCCInstallCandidate &SelectedInstallation) const;333 334    bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple,335                             const llvm::opt::ArgList &Args, StringRef Path,336                             bool NeedsBiarchSuffix = false);337 338    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,339                                const llvm::opt::ArgList &Args,340                                const std::string &LibDir,341                                StringRef CandidateTriple,342                                bool NeedsBiarchSuffix, bool GCCDirExists,343                                bool GCCCrossDirExists);344 345    bool ScanGentooConfigs(const llvm::Triple &TargetTriple,346                           const llvm::opt::ArgList &Args,347                           const SmallVectorImpl<StringRef> &CandidateTriples,348                           const SmallVectorImpl<StringRef> &BiarchTriples);349 350    bool ScanGentooGccConfig(const llvm::Triple &TargetTriple,351                             const llvm::opt::ArgList &Args,352                             StringRef CandidateTriple,353                             bool NeedsBiarchSuffix = false);354  };355 356protected:357  GCCInstallationDetector GCCInstallation;358  LazyDetector<CudaInstallationDetector> CudaInstallation;359  LazyDetector<RocmInstallationDetector> RocmInstallation;360  LazyDetector<SYCLInstallationDetector> SYCLInstallation;361 362public:363  Generic_GCC(const Driver &D, const llvm::Triple &Triple,364              const llvm::opt::ArgList &Args);365  ~Generic_GCC() override;366 367  void printVerboseInfo(raw_ostream &OS) const override;368 369  UnwindTableLevel370  getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;371  bool isPICDefault() const override;372  bool isPIEDefault(const llvm::opt::ArgList &Args) const override;373  bool isPICDefaultForced() const override;374  bool IsIntegratedAssemblerDefault() const override;375  llvm::opt::DerivedArgList *376  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,377                Action::OffloadKind DeviceOffloadKind) const override;378 379protected:380  Tool *getTool(Action::ActionClass AC) const override;381  Tool *buildAssembler() const override;382  Tool *buildLinker() const override;383 384  /// \name ToolChain Implementation Helper Functions385  /// @{386 387  /// Check whether the target triple's architecture is 64-bits.388  bool isTarget64Bit() const { return getTriple().isArch64Bit(); }389 390  /// Check whether the target triple's architecture is 32-bits.391  bool isTarget32Bit() const { return getTriple().isArch32Bit(); }392 393  void PushPPaths(ToolChain::path_list &PPaths);394  void AddMultilibPaths(const Driver &D, const std::string &SysRoot,395                        const std::string &OSLibDir,396                        const std::string &MultiarchTriple,397                        path_list &Paths);398  void AddMultiarchPaths(const Driver &D, const std::string &SysRoot,399                         const std::string &OSLibDir, path_list &Paths);400  void AddMultilibIncludeArgs(const llvm::opt::ArgList &DriverArgs,401                              llvm::opt::ArgStringList &CC1Args) const;402 403  // FIXME: This should be final, but the CrossWindows toolchain does weird404  // things that can't be easily generalized.405  void AddClangCXXStdlibIncludeArgs(406      const llvm::opt::ArgList &DriverArgs,407      llvm::opt::ArgStringList &CC1Args) const override;408 409  void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,410                          llvm::opt::ArgStringList &CC1Args) const override;411 412  virtual void413  addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,414                        llvm::opt::ArgStringList &CC1Args) const;415  virtual void416  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,417                           llvm::opt::ArgStringList &CC1Args) const;418 419  bool addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,420                                   llvm::opt::ArgStringList &CC) const;421 422  bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,423                                Twine IncludeSuffix,424                                const llvm::opt::ArgList &DriverArgs,425                                llvm::opt::ArgStringList &CC1Args,426                                bool DetectDebian = false) const;427 428  /// @}429 430private:431  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess;432  mutable std::unique_ptr<tools::gcc::Compiler> Compile;433};434 435class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {436  virtual void anchor();437 438public:439  Generic_ELF(const Driver &D, const llvm::Triple &Triple,440              const llvm::opt::ArgList &Args)441      : Generic_GCC(D, Triple, Args) {}442 443  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,444                             llvm::opt::ArgStringList &CC1Args,445                             Action::OffloadKind DeviceOffloadKind) const override;446 447  virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const {448    return {};449  }450 451  virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {}452};453 454} // end namespace toolchains455} // end namespace driver456} // end namespace clang457 458#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H459