clang API Documentation

Multilib.h
Go to the documentation of this file.
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