Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- Multilib.h -----------------------------------------------*- 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_DRIVER_MULTILIB_H
  10. #define LLVM_CLANG_DRIVER_MULTILIB_H
  11.  
  12. #include "clang/Basic/LLVM.h"
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include "llvm/ADT/STLExtras.h"
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/Support/Compiler.h"
  17. #include <cassert>
  18. #include <functional>
  19. #include <string>
  20. #include <utility>
  21. #include <vector>
  22.  
  23. namespace clang {
  24. namespace driver {
  25.  
  26. /// This corresponds to a single GCC Multilib, or a segment of one controlled
  27. /// by a command line flag
  28. class Multilib {
  29. public:
  30.   using flags_list = std::vector<std::string>;
  31.  
  32. private:
  33.   std::string GCCSuffix;
  34.   std::string OSSuffix;
  35.   std::string IncludeSuffix;
  36.   flags_list Flags;
  37.   int Priority;
  38.  
  39. public:
  40.   Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
  41.            StringRef IncludeSuffix = {}, int Priority = 0);
  42.  
  43.   /// Get the detected GCC installation path suffix for the multi-arch
  44.   /// target variant. Always starts with a '/', unless empty
  45.   const std::string &gccSuffix() const {
  46.     assert(GCCSuffix.empty() ||
  47.            (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
  48.     return GCCSuffix;
  49.   }
  50.  
  51.   /// Set the GCC installation path suffix.
  52.   Multilib &gccSuffix(StringRef S);
  53.  
  54.   /// Get the detected os path suffix for the multi-arch
  55.   /// target variant. Always starts with a '/', unless empty
  56.   const std::string &osSuffix() const {
  57.     assert(OSSuffix.empty() ||
  58.            (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
  59.     return OSSuffix;
  60.   }
  61.  
  62.   /// Set the os path suffix.
  63.   Multilib &osSuffix(StringRef S);
  64.  
  65.   /// Get the include directory suffix. Always starts with a '/', unless
  66.   /// empty
  67.   const std::string &includeSuffix() const {
  68.     assert(IncludeSuffix.empty() ||
  69.            (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
  70.     return IncludeSuffix;
  71.   }
  72.  
  73.   /// Set the include directory suffix
  74.   Multilib &includeSuffix(StringRef S);
  75.  
  76.   /// Get the flags that indicate or contraindicate this multilib's use
  77.   /// All elements begin with either '+' or '-'
  78.   const flags_list &flags() const { return Flags; }
  79.   flags_list &flags() { return Flags; }
  80.  
  81.   /// Returns the multilib priority. When more than one multilib matches flags,
  82.   /// the one with the highest priority is selected, with 0 being the default.
  83.   int priority() const { return Priority; }
  84.  
  85.   /// Add a flag to the flags list
  86.   /// \p Flag must be a flag accepted by the driver with its leading '-' removed,
  87.   ///     and replaced with either:
  88.   ///       '-' which contraindicates using this multilib with that flag
  89.   ///     or:
  90.   ///       '+' which promotes using this multilib in the presence of that flag
  91.   ///     otherwise '-print-multi-lib' will not emit them correctly.
  92.   Multilib &flag(StringRef F) {
  93.     assert(F.front() == '+' || F.front() == '-');
  94.     Flags.push_back(std::string(F));
  95.     return *this;
  96.   }
  97.  
  98.   LLVM_DUMP_METHOD void dump() const;
  99.   /// print summary of the Multilib
  100.   void print(raw_ostream &OS) const;
  101.  
  102.   /// Check whether any of the 'against' flags contradict the 'for' flags.
  103.   bool isValid() const;
  104.  
  105.   /// Check whether the default is selected
  106.   bool isDefault() const
  107.   { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
  108.  
  109.   bool operator==(const Multilib &Other) const;
  110. };
  111.  
  112. raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
  113.  
  114. class MultilibSet {
  115. public:
  116.   using multilib_list = std::vector<Multilib>;
  117.   using iterator = multilib_list::iterator;
  118.   using const_iterator = multilib_list::const_iterator;
  119.   using IncludeDirsFunc =
  120.       std::function<std::vector<std::string>(const Multilib &M)>;
  121.   using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
  122.  
  123. private:
  124.   multilib_list Multilibs;
  125.   IncludeDirsFunc IncludeCallback;
  126.   IncludeDirsFunc FilePathsCallback;
  127.  
  128. public:
  129.   MultilibSet() = default;
  130.  
  131.   /// Add an optional Multilib segment
  132.   MultilibSet &Maybe(const Multilib &M);
  133.  
  134.   /// Add a set of mutually incompatible Multilib segments
  135.   MultilibSet &Either(const Multilib &M1, const Multilib &M2);
  136.   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
  137.                       const Multilib &M3);
  138.   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
  139.                       const Multilib &M3, const Multilib &M4);
  140.   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
  141.                       const Multilib &M3, const Multilib &M4,
  142.                       const Multilib &M5);
  143.   MultilibSet &Either(ArrayRef<Multilib> Ms);
  144.  
  145.   /// Filter out some subset of the Multilibs using a user defined callback
  146.   MultilibSet &FilterOut(FilterCallback F);
  147.  
  148.   /// Filter out those Multilibs whose gccSuffix matches the given expression
  149.   MultilibSet &FilterOut(const char *Regex);
  150.  
  151.   /// Add a completed Multilib to the set
  152.   void push_back(const Multilib &M);
  153.  
  154.   /// Union this set of multilibs with another
  155.   void combineWith(const MultilibSet &MS);
  156.  
  157.   /// Remove all of the multilibs from the set
  158.   void clear() { Multilibs.clear(); }
  159.  
  160.   iterator begin() { return Multilibs.begin(); }
  161.   const_iterator begin() const { return Multilibs.begin(); }
  162.  
  163.   iterator end() { return Multilibs.end(); }
  164.   const_iterator end() const { return Multilibs.end(); }
  165.  
  166.   /// Pick the best multilib in the set, \returns false if none are compatible
  167.   bool select(const Multilib::flags_list &Flags, Multilib &M) const;
  168.  
  169.   unsigned size() const { return Multilibs.size(); }
  170.  
  171.   LLVM_DUMP_METHOD void dump() const;
  172.   void print(raw_ostream &OS) const;
  173.  
  174.   MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) {
  175.     IncludeCallback = std::move(F);
  176.     return *this;
  177.   }
  178.  
  179.   const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
  180.  
  181.   MultilibSet &setFilePathsCallback(IncludeDirsFunc F) {
  182.     FilePathsCallback = std::move(F);
  183.     return *this;
  184.   }
  185.  
  186.   const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
  187.  
  188. private:
  189.   /// Apply the filter to Multilibs and return the subset that remains
  190.   static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms);
  191.  
  192.   /// Apply the filter to the multilib_list, removing those that don't match
  193.   static void filterInPlace(FilterCallback F, multilib_list &Ms);
  194. };
  195.  
  196. raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
  197.  
  198. } // namespace driver
  199. } // namespace clang
  200.  
  201. #endif // LLVM_CLANG_DRIVER_MULTILIB_H
  202.