1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===--- Multilib.h ---------------------------------------------*- C++ -*-===// 2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// The LLVM Compiler Infrastructure 4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This file is distributed under the University of Illinois Open Source 6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// License. See LICENSE.TXT for details. 7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===// 9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef CLANG_LIB_DRIVER_MULTILIB_H_ 11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define CLANG_LIB_DRIVER_MULTILIB_H_ 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/LLVM.h" 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/Triple.h" 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Option/Option.h" 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <string> 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <vector> 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace clang { 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace driver { 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// This corresponds to a single GCC Multilib, or a segment of one controlled 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// by a command line flag 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass Multilib { 25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef std::vector<std::string> flags_list; 27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string GCCSuffix; 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string OSSuffix; 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string IncludeSuffix; 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines flags_list Flags; 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "", 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef IncludeSuffix = ""); 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Get the detected GCC installation path suffix for the multi-arch 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// target variant. Always starts with a '/', unless empty 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::string &gccSuffix() const { 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(GCCSuffix.empty() || 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1)); 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return GCCSuffix; 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Set the GCC installation path suffix. 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Multilib &gccSuffix(StringRef S); 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Get the detected os path suffix for the multi-arch 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// target variant. Always starts with a '/', unless empty 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::string &osSuffix() const { 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(OSSuffix.empty() || 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1)); 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return OSSuffix; 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Set the os path suffix. 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Multilib &osSuffix(StringRef S); 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Get the include directory suffix. Always starts with a '/', unless 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// empty 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::string &includeSuffix() const { 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(IncludeSuffix.empty() || 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1)); 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return IncludeSuffix; 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Set the include directory suffix 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Multilib &includeSuffix(StringRef S); 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Get the flags that indicate or contraindicate this multilib's use 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// All elements begin with either '+' or '-' 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const flags_list &flags() const { return Flags; } 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines flags_list &flags() { return Flags; } 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add a flag to the flags list 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Multilib &flag(StringRef F) { 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(F.front() == '+' || F.front() == '-'); 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags.push_back(F); 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return *this; 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief print summary of the Multilib 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void print(raw_ostream &OS) const; 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Check whether any of the 'against' flags contradict the 'for' flags. 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isValid() const; 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Check whether the default is selected 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isDefault() const 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); } 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool operator==(const Multilib &Other) const; 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream &operator<<(raw_ostream &OS, const Multilib &M); 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass MultilibSet { 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef std::vector<Multilib> multilib_list; 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef multilib_list::iterator iterator; 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef multilib_list::const_iterator const_iterator; 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct FilterCallback { 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual ~FilterCallback() {}; 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \return true iff the filter should remove the Multilib from the set 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool operator()(const Multilib &M) const = 0; 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }; 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines multilib_list Multilibs; 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet() {} 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add an optional Multilib segment 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Maybe(const Multilib &M); 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add a set of mutually incompatible Multilib segments 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Either(const Multilib &M1, const Multilib &M2); 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Either(const Multilib &M1, const Multilib &M2, 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Multilib &M3); 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Either(const Multilib &M1, const Multilib &M2, 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Multilib &M3, const Multilib &M4); 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Either(const Multilib &M1, const Multilib &M2, 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Multilib &M3, const Multilib &M4, 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Multilib &M5); 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &Either(const std::vector<Multilib> &Ms); 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Filter out some subset of the Multilibs using a user defined callback 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &FilterOut(const FilterCallback &F); 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Filter out those Multilibs whose gccSuffix matches the given expression 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MultilibSet &FilterOut(std::string Regex); 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add a completed Multilib to the set 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void push_back(const Multilib &M); 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Union this set of multilibs with another 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void combineWith(const MultilibSet &MS); 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Remove all of thie multilibs from the set 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void clear() { Multilibs.clear(); } 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines iterator begin() { return Multilibs.begin(); } 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const_iterator begin() const { return Multilibs.begin(); } 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines iterator end() { return Multilibs.end(); } 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const_iterator end() const { return Multilibs.end(); } 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Pick the best multilib in the set, \returns false if none are compatible 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool select(const Multilib::flags_list &Flags, Multilib &M) const; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned size() const { return Multilibs.size(); } 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void print(raw_ostream &OS) const; 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Apply the filter to Multilibs and return the subset that remains 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static multilib_list filterCopy(const FilterCallback &F, 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const multilib_list &Ms); 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Apply the filter to the multilib_list, removing those that don't match 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void filterInPlace(const FilterCallback &F, multilib_list &Ms); 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS); 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 168