clang API Documentation
00001 //===--- Multilib.h ---------------------------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_CLANG_DRIVER_MULTILIB_H 00011 #define LLVM_CLANG_DRIVER_MULTILIB_H 00012 00013 #include "clang/Basic/LLVM.h" 00014 #include "llvm/ADT/Triple.h" 00015 #include "llvm/Option/Option.h" 00016 00017 #include <functional> 00018 #include <string> 00019 #include <vector> 00020 00021 namespace clang { 00022 namespace driver { 00023 00024 /// This corresponds to a single GCC Multilib, or a segment of one controlled 00025 /// by a command line flag 00026 class Multilib { 00027 public: 00028 typedef std::vector<std::string> flags_list; 00029 00030 private: 00031 std::string GCCSuffix; 00032 std::string OSSuffix; 00033 std::string IncludeSuffix; 00034 flags_list Flags; 00035 00036 public: 00037 Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "", 00038 StringRef IncludeSuffix = ""); 00039 00040 /// \brief Get the detected GCC installation path suffix for the multi-arch 00041 /// target variant. Always starts with a '/', unless empty 00042 const std::string &gccSuffix() const { 00043 assert(GCCSuffix.empty() || 00044 (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1)); 00045 return GCCSuffix; 00046 } 00047 /// Set the GCC installation path suffix. 00048 Multilib &gccSuffix(StringRef S); 00049 00050 /// \brief Get the detected os path suffix for the multi-arch 00051 /// target variant. Always starts with a '/', unless empty 00052 const std::string &osSuffix() const { 00053 assert(OSSuffix.empty() || 00054 (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1)); 00055 return OSSuffix; 00056 } 00057 /// Set the os path suffix. 00058 Multilib &osSuffix(StringRef S); 00059 00060 /// \brief Get the include directory suffix. Always starts with a '/', unless 00061 /// empty 00062 const std::string &includeSuffix() const { 00063 assert(IncludeSuffix.empty() || 00064 (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1)); 00065 return IncludeSuffix; 00066 } 00067 /// Set the include directory suffix 00068 Multilib &includeSuffix(StringRef S); 00069 00070 /// \brief Get the flags that indicate or contraindicate this multilib's use 00071 /// All elements begin with either '+' or '-' 00072 const flags_list &flags() const { return Flags; } 00073 flags_list &flags() { return Flags; } 00074 /// Add a flag to the flags list 00075 Multilib &flag(StringRef F) { 00076 assert(F.front() == '+' || F.front() == '-'); 00077 Flags.push_back(F); 00078 return *this; 00079 } 00080 00081 /// \brief print summary of the Multilib 00082 void print(raw_ostream &OS) const; 00083 00084 /// Check whether any of the 'against' flags contradict the 'for' flags. 00085 bool isValid() const; 00086 00087 /// Check whether the default is selected 00088 bool isDefault() const 00089 { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); } 00090 00091 bool operator==(const Multilib &Other) const; 00092 }; 00093 00094 raw_ostream &operator<<(raw_ostream &OS, const Multilib &M); 00095 00096 class MultilibSet { 00097 public: 00098 typedef std::vector<Multilib> multilib_list; 00099 typedef multilib_list::iterator iterator; 00100 typedef multilib_list::const_iterator const_iterator; 00101 00102 typedef std::function<std::vector<std::string>( 00103 StringRef InstallDir, StringRef Triple, const Multilib &M)> 00104 IncludeDirsFunc; 00105 00106 struct FilterCallback { 00107 virtual ~FilterCallback() {}; 00108 /// \return true iff the filter should remove the Multilib from the set 00109 virtual bool operator()(const Multilib &M) const = 0; 00110 }; 00111 00112 private: 00113 multilib_list Multilibs; 00114 IncludeDirsFunc IncludeCallback; 00115 00116 public: 00117 MultilibSet() {} 00118 00119 /// Add an optional Multilib segment 00120 MultilibSet &Maybe(const Multilib &M); 00121 00122 /// Add a set of mutually incompatible Multilib segments 00123 MultilibSet &Either(const Multilib &M1, const Multilib &M2); 00124 MultilibSet &Either(const Multilib &M1, const Multilib &M2, 00125 const Multilib &M3); 00126 MultilibSet &Either(const Multilib &M1, const Multilib &M2, 00127 const Multilib &M3, const Multilib &M4); 00128 MultilibSet &Either(const Multilib &M1, const Multilib &M2, 00129 const Multilib &M3, const Multilib &M4, 00130 const Multilib &M5); 00131 MultilibSet &Either(const std::vector<Multilib> &Ms); 00132 00133 /// Filter out some subset of the Multilibs using a user defined callback 00134 MultilibSet &FilterOut(const FilterCallback &F); 00135 /// Filter out those Multilibs whose gccSuffix matches the given expression 00136 MultilibSet &FilterOut(std::string Regex); 00137 00138 /// Add a completed Multilib to the set 00139 void push_back(const Multilib &M); 00140 00141 /// Union this set of multilibs with another 00142 void combineWith(const MultilibSet &MS); 00143 00144 /// Remove all of thie multilibs from the set 00145 void clear() { Multilibs.clear(); } 00146 00147 iterator begin() { return Multilibs.begin(); } 00148 const_iterator begin() const { return Multilibs.begin(); } 00149 00150 iterator end() { return Multilibs.end(); } 00151 const_iterator end() const { return Multilibs.end(); } 00152 00153 /// Pick the best multilib in the set, \returns false if none are compatible 00154 bool select(const Multilib::flags_list &Flags, Multilib &M) const; 00155 00156 unsigned size() const { return Multilibs.size(); } 00157 00158 void print(raw_ostream &OS) const; 00159 00160 MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) { 00161 IncludeCallback = F; 00162 return *this; 00163 } 00164 IncludeDirsFunc includeDirsCallback() const { return IncludeCallback; } 00165 00166 private: 00167 /// Apply the filter to Multilibs and return the subset that remains 00168 static multilib_list filterCopy(const FilterCallback &F, 00169 const multilib_list &Ms); 00170 00171 /// Apply the filter to the multilib_list, removing those that don't match 00172 static void filterInPlace(const FilterCallback &F, multilib_list &Ms); 00173 }; 00174 00175 raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS); 00176 } 00177 } 00178 00179 #endif 00180