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