1 //===- MultilibBuilder.h 2 //-----------------------------------------------*- C++ -*-===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_DRIVER_MULTILIBBUILDER_H 11 #define LLVM_CLANG_DRIVER_MULTILIBBUILDER_H 12 13 #include "clang/Driver/Multilib.h" 14 15 namespace clang { 16 namespace driver { 17 18 /// This corresponds to a single GCC multilib, or a segment of one controlled 19 /// by a command line flag. This class can be used to create a Multilib, and 20 /// contains helper functions to mutate it before creating a Multilib instance 21 /// with makeMultilib(). 22 class MultilibBuilder { 23 public: 24 using flags_list = std::vector<std::string>; 25 26 private: 27 std::string GCCSuffix; 28 std::string OSSuffix; 29 std::string IncludeSuffix; 30 flags_list Flags; 31 32 public: 33 MultilibBuilder(StringRef GCCSuffix, StringRef OSSuffix, 34 StringRef IncludeSuffix); 35 36 /// Initializes GCCSuffix, OSSuffix & IncludeSuffix to the same value. 37 MultilibBuilder(StringRef Suffix = {}); 38 39 /// Get the detected GCC installation path suffix for the multi-arch 40 /// target variant. Always starts with a '/', unless empty gccSuffix()41 const std::string &gccSuffix() const { 42 assert(GCCSuffix.empty() || 43 (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1)); 44 return GCCSuffix; 45 } 46 47 /// Set the GCC installation path suffix. 48 MultilibBuilder &gccSuffix(StringRef S); 49 50 /// Get the detected os path suffix for the multi-arch 51 /// target variant. Always starts with a '/', unless empty osSuffix()52 const std::string &osSuffix() const { 53 assert(OSSuffix.empty() || 54 (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1)); 55 return OSSuffix; 56 } 57 58 /// Set the os path suffix. 59 MultilibBuilder &osSuffix(StringRef S); 60 61 /// Get the include directory suffix. Always starts with a '/', unless 62 /// empty includeSuffix()63 const std::string &includeSuffix() const { 64 assert(IncludeSuffix.empty() || (StringRef(IncludeSuffix).front() == '/' && 65 IncludeSuffix.size() > 1)); 66 return IncludeSuffix; 67 } 68 69 /// Set the include directory suffix 70 MultilibBuilder &includeSuffix(StringRef S); 71 72 /// Get the flags that indicate or contraindicate this multilib's use 73 /// All elements begin with either '-' or '!' flags()74 const flags_list &flags() const { return Flags; } flags()75 flags_list &flags() { return Flags; } 76 77 /// Add a flag to the flags list 78 /// \p Flag must be a flag accepted by the driver. 79 /// \p Disallow defines whether the flag is negated and therefore disallowed. 80 MultilibBuilder &flag(StringRef Flag, bool Disallow = false); 81 82 Multilib makeMultilib() const; 83 84 /// Check whether any of the 'against' flags contradict the 'for' flags. 85 bool isValid() const; 86 87 /// Check whether the default is selected isDefault()88 bool isDefault() const { 89 return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); 90 } 91 }; 92 93 /// This class can be used to create a MultilibSet, and contains helper 94 /// functions to add combinations of multilibs before creating a MultilibSet 95 /// instance with makeMultilibSet(). 96 class MultilibSetBuilder { 97 public: 98 using multilib_list = std::vector<MultilibBuilder>; 99 100 MultilibSetBuilder() = default; 101 102 /// Add an optional Multilib segment 103 MultilibSetBuilder &Maybe(const MultilibBuilder &M); 104 105 /// Add a set of mutually incompatible Multilib segments 106 MultilibSetBuilder &Either(const MultilibBuilder &M1, 107 const MultilibBuilder &M2); 108 MultilibSetBuilder &Either(const MultilibBuilder &M1, 109 const MultilibBuilder &M2, 110 const MultilibBuilder &M3); 111 MultilibSetBuilder &Either(const MultilibBuilder &M1, 112 const MultilibBuilder &M2, 113 const MultilibBuilder &M3, 114 const MultilibBuilder &M4); 115 MultilibSetBuilder &Either(const MultilibBuilder &M1, 116 const MultilibBuilder &M2, 117 const MultilibBuilder &M3, 118 const MultilibBuilder &M4, 119 const MultilibBuilder &M5); 120 MultilibSetBuilder &Either(ArrayRef<MultilibBuilder> Ms); 121 122 /// Filter out those Multilibs whose gccSuffix matches the given expression 123 MultilibSetBuilder &FilterOut(const char *Regex); 124 125 MultilibSet makeMultilibSet() const; 126 127 private: 128 multilib_list Multilibs; 129 }; 130 131 } // namespace driver 132 } // namespace clang 133 134 #endif // LLVM_CLANG_DRIVER_MULTILIBBUILDER_H 135