File indexing completed on 2026-05-10 08:36:52
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_DRIVER_MULTILIB_H
0010 #define LLVM_CLANG_DRIVER_MULTILIB_H
0011
0012 #include "clang/Basic/LLVM.h"
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/STLExtras.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/ADT/StringSet.h"
0017 #include "llvm/Support/Compiler.h"
0018 #include "llvm/Support/SourceMgr.h"
0019 #include <cassert>
0020 #include <functional>
0021 #include <optional>
0022 #include <string>
0023 #include <utility>
0024 #include <vector>
0025
0026 namespace clang {
0027 namespace driver {
0028
0029 class Driver;
0030
0031
0032
0033
0034
0035 class Multilib {
0036 public:
0037 using flags_list = std::vector<std::string>;
0038
0039 private:
0040 std::string GCCSuffix;
0041 std::string OSSuffix;
0042 std::string IncludeSuffix;
0043 flags_list Flags;
0044
0045
0046
0047
0048
0049
0050
0051
0052 std::string ExclusiveGroup;
0053
0054
0055
0056
0057 std::optional<std::string> Error;
0058
0059 public:
0060
0061
0062
0063 Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
0064 StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
0065 StringRef ExclusiveGroup = {},
0066 std::optional<StringRef> Error = std::nullopt);
0067
0068
0069
0070 const std::string &gccSuffix() const { return GCCSuffix; }
0071
0072
0073
0074 const std::string &osSuffix() const { return OSSuffix; }
0075
0076
0077
0078 const std::string &includeSuffix() const { return IncludeSuffix; }
0079
0080
0081
0082 const flags_list &flags() const { return Flags; }
0083
0084
0085 const std::string &exclusiveGroup() const { return ExclusiveGroup; }
0086
0087 LLVM_DUMP_METHOD void dump() const;
0088
0089 void print(raw_ostream &OS) const;
0090
0091
0092 bool isDefault() const
0093 { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
0094
0095 bool operator==(const Multilib &Other) const;
0096
0097 bool isError() const { return Error.has_value(); }
0098
0099 const std::string &getErrorMessage() const { return Error.value(); }
0100 };
0101
0102 raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
0103
0104 namespace custom_flag {
0105 struct Declaration;
0106
0107 struct ValueDetail {
0108 std::string Name;
0109 std::optional<SmallVector<std::string>> MacroDefines;
0110 Declaration *Decl;
0111 };
0112
0113 struct Declaration {
0114 std::string Name;
0115 SmallVector<ValueDetail> ValueList;
0116 std::optional<size_t> DefaultValueIdx;
0117
0118 Declaration() = default;
0119 Declaration(const Declaration &);
0120 Declaration(Declaration &&);
0121 Declaration &operator=(const Declaration &);
0122 Declaration &operator=(Declaration &&);
0123 };
0124
0125 static constexpr StringRef Prefix = "-fmultilib-flag=";
0126 }
0127
0128
0129 class MultilibSet {
0130 public:
0131 using multilib_list = std::vector<Multilib>;
0132 using const_iterator = multilib_list::const_iterator;
0133 using IncludeDirsFunc =
0134 std::function<std::vector<std::string>(const Multilib &M)>;
0135 using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
0136
0137
0138
0139
0140 struct FlagMatcher {
0141 std::string Match;
0142 std::vector<std::string> Flags;
0143 };
0144
0145 private:
0146 multilib_list Multilibs;
0147 SmallVector<FlagMatcher> FlagMatchers;
0148 SmallVector<custom_flag::Declaration> CustomFlagDecls;
0149 IncludeDirsFunc IncludeCallback;
0150 IncludeDirsFunc FilePathsCallback;
0151
0152 public:
0153 MultilibSet() = default;
0154 MultilibSet(multilib_list &&Multilibs,
0155 SmallVector<FlagMatcher> &&FlagMatchers = {},
0156 SmallVector<custom_flag::Declaration> &&CustomFlagDecls = {})
0157 : Multilibs(std::move(Multilibs)), FlagMatchers(std::move(FlagMatchers)),
0158 CustomFlagDecls(std::move(CustomFlagDecls)) {}
0159
0160 const multilib_list &getMultilibs() { return Multilibs; }
0161
0162
0163 MultilibSet &FilterOut(FilterCallback F);
0164
0165
0166 void push_back(const Multilib &M);
0167
0168 const_iterator begin() const { return Multilibs.begin(); }
0169 const_iterator end() const { return Multilibs.end(); }
0170
0171
0172
0173
0174
0175
0176 std::pair<Multilib::flags_list, SmallVector<StringRef>>
0177 processCustomFlags(const Driver &D, const Multilib::flags_list &Flags) const;
0178
0179
0180 bool select(const Driver &D, const Multilib::flags_list &Flags,
0181 llvm::SmallVectorImpl<Multilib> &,
0182 llvm::SmallVector<StringRef> * = nullptr) const;
0183
0184 unsigned size() const { return Multilibs.size(); }
0185
0186
0187
0188
0189 llvm::StringSet<> expandFlags(const Multilib::flags_list &) const;
0190
0191 LLVM_DUMP_METHOD void dump() const;
0192 void print(raw_ostream &OS) const;
0193
0194 MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) {
0195 IncludeCallback = std::move(F);
0196 return *this;
0197 }
0198
0199 const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
0200
0201 MultilibSet &setFilePathsCallback(IncludeDirsFunc F) {
0202 FilePathsCallback = std::move(F);
0203 return *this;
0204 }
0205
0206 const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
0207
0208 static llvm::ErrorOr<MultilibSet>
0209 parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy = nullptr,
0210 void *DiagHandlerCtxt = nullptr);
0211 };
0212
0213 raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
0214
0215 }
0216 }
0217
0218 #endif