• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- Multilib.h ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef CLANG_LIB_DRIVER_MULTILIB_H_
11 #define CLANG_LIB_DRIVER_MULTILIB_H_
12 
13 #include "clang/Basic/LLVM.h"
14 #include "llvm/ADT/Triple.h"
15 #include "llvm/Option/Option.h"
16 #include <string>
17 #include <vector>
18 
19 namespace clang {
20 namespace driver {
21 
22 /// This corresponds to a single GCC Multilib, or a segment of one controlled
23 /// by a command line flag
24 class Multilib {
25 public:
26   typedef std::vector<std::string> flags_list;
27 
28 private:
29   std::string GCCSuffix;
30   std::string OSSuffix;
31   std::string IncludeSuffix;
32   flags_list Flags;
33 
34 public:
35   Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
36            StringRef IncludeSuffix = "");
37 
38   /// \brief Get the detected GCC installation path suffix for the multi-arch
39   /// target variant. Always starts with a '/', unless empty
gccSuffix()40   const std::string &gccSuffix() const {
41     assert(GCCSuffix.empty() ||
42            (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
43     return GCCSuffix;
44   }
45   /// Set the GCC installation path suffix.
46   Multilib &gccSuffix(StringRef S);
47 
48   /// \brief Get the detected os path suffix for the multi-arch
49   /// target variant. Always starts with a '/', unless empty
osSuffix()50   const std::string &osSuffix() const {
51     assert(OSSuffix.empty() ||
52            (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
53     return OSSuffix;
54   }
55   /// Set the os path suffix.
56   Multilib &osSuffix(StringRef S);
57 
58   /// \brief Get the include directory suffix. Always starts with a '/', unless
59   /// empty
includeSuffix()60   const std::string &includeSuffix() const {
61     assert(IncludeSuffix.empty() ||
62            (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
63     return IncludeSuffix;
64   }
65   /// Set the include directory suffix
66   Multilib &includeSuffix(StringRef S);
67 
68   /// \brief Get the flags that indicate or contraindicate this multilib's use
69   /// All elements begin with either '+' or '-'
flags()70   const flags_list &flags() const { return Flags; }
flags()71   flags_list &flags() { return Flags; }
72   /// Add a flag to the flags list
flag(StringRef F)73   Multilib &flag(StringRef F) {
74     assert(F.front() == '+' || F.front() == '-');
75     Flags.push_back(F);
76     return *this;
77   }
78 
79   /// \brief print summary of the Multilib
80   void print(raw_ostream &OS) const;
81 
82   /// Check whether any of the 'against' flags contradict the 'for' flags.
83   bool isValid() const;
84 
85   /// Check whether the default is selected
isDefault()86   bool isDefault() const
87   { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
88 
89   bool operator==(const Multilib &Other) const;
90 };
91 
92 raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
93 
94 class MultilibSet {
95 public:
96   typedef std::vector<Multilib> multilib_list;
97   typedef multilib_list::iterator iterator;
98   typedef multilib_list::const_iterator const_iterator;
99 
100   struct FilterCallback {
~FilterCallbackFilterCallback101     virtual ~FilterCallback() {};
102     /// \return true iff the filter should remove the Multilib from the set
103     virtual bool operator()(const Multilib &M) const = 0;
104   };
105 
106 private:
107   multilib_list Multilibs;
108 
109 public:
MultilibSet()110   MultilibSet() {}
111 
112   /// Add an optional Multilib segment
113   MultilibSet &Maybe(const Multilib &M);
114 
115   /// Add a set of mutually incompatible Multilib segments
116   MultilibSet &Either(const Multilib &M1, const Multilib &M2);
117   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
118                       const Multilib &M3);
119   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
120                       const Multilib &M3, const Multilib &M4);
121   MultilibSet &Either(const Multilib &M1, const Multilib &M2,
122                       const Multilib &M3, const Multilib &M4,
123                       const Multilib &M5);
124   MultilibSet &Either(const std::vector<Multilib> &Ms);
125 
126   /// Filter out some subset of the Multilibs using a user defined callback
127   MultilibSet &FilterOut(const FilterCallback &F);
128   /// Filter out those Multilibs whose gccSuffix matches the given expression
129   MultilibSet &FilterOut(std::string Regex);
130 
131   /// Add a completed Multilib to the set
132   void push_back(const Multilib &M);
133 
134   /// Union this set of multilibs with another
135   void combineWith(const MultilibSet &MS);
136 
137   /// Remove all of thie multilibs from the set
clear()138   void clear() { Multilibs.clear(); }
139 
begin()140   iterator begin() { return Multilibs.begin(); }
begin()141   const_iterator begin() const { return Multilibs.begin(); }
142 
end()143   iterator end() { return Multilibs.end(); }
end()144   const_iterator end() const { return Multilibs.end(); }
145 
146   /// Pick the best multilib in the set, \returns false if none are compatible
147   bool select(const Multilib::flags_list &Flags, Multilib &M) const;
148 
size()149   unsigned size() const { return Multilibs.size(); }
150 
151   void print(raw_ostream &OS) const;
152 
153 private:
154   /// Apply the filter to Multilibs and return the subset that remains
155   static multilib_list filterCopy(const FilterCallback &F,
156                                   const multilib_list &Ms);
157 
158   /// Apply the filter to the multilib_list, removing those that don't match
159   static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
160 };
161 
162 raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
163 }
164 }
165 
166 #endif
167 
168