clang 20.0.0git
Multilib.h
Go to the documentation of this file.
1//===- Multilib.h -----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_DRIVER_MULTILIB_H
10#define LLVM_CLANG_DRIVER_MULTILIB_H
11
12#include "clang/Basic/LLVM.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/ADT/StringSet.h"
17#include "llvm/Support/Compiler.h"
18#include "llvm/Support/SourceMgr.h"
19#include <cassert>
20#include <functional>
21#include <optional>
22#include <string>
23#include <utility>
24#include <vector>
25
26namespace clang {
27namespace driver {
28
29class Driver;
30
31/// This corresponds to a single GCC Multilib, or a segment of one controlled
32/// by a command line flag.
33/// See also MultilibBuilder for building a multilib by mutating it
34/// incrementally.
35class Multilib {
36public:
37 using flags_list = std::vector<std::string>;
38
39private:
40 std::string GCCSuffix;
41 std::string OSSuffix;
42 std::string IncludeSuffix;
43 flags_list Flags;
44
45 // Optionally, a multilib can be assigned a string tag indicating that it's
46 // part of a group of mutually exclusive possibilities. If two or more
47 // multilibs have the same non-empty value of ExclusiveGroup, then only the
48 // last matching one of them will be selected.
49 //
50 // Setting this to the empty string is a special case, indicating that the
51 // directory is not mutually exclusive with anything else.
52 std::string ExclusiveGroup;
53
54 // Some Multilib objects don't actually represent library directories you can
55 // select. Instead, they represent failures of multilib selection, of the
56 // form 'Sorry, we don't have any library compatible with these constraints'.
57 std::optional<std::string> Error;
58
59public:
60 /// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
61 /// sysroot string so they must either be empty or begin with a '/' character.
62 /// This is enforced with an assert in the constructor.
63 Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
64 StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
65 StringRef ExclusiveGroup = {},
66 std::optional<StringRef> Error = std::nullopt);
67
68 /// Get the detected GCC installation path suffix for the multi-arch
69 /// target variant. Always starts with a '/', unless empty
70 const std::string &gccSuffix() const { return GCCSuffix; }
71
72 /// Get the detected os path suffix for the multi-arch
73 /// target variant. Always starts with a '/', unless empty
74 const std::string &osSuffix() const { return OSSuffix; }
75
76 /// Get the include directory suffix. Always starts with a '/', unless
77 /// empty
78 const std::string &includeSuffix() const { return IncludeSuffix; }
79
80 /// Get the flags that indicate or contraindicate this multilib's use
81 /// All elements begin with either '-' or '!'
82 const flags_list &flags() const { return Flags; }
83
84 /// Get the exclusive group label.
85 const std::string &exclusiveGroup() const { return ExclusiveGroup; }
86
87 LLVM_DUMP_METHOD void dump() const;
88 /// print summary of the Multilib
89 void print(raw_ostream &OS) const;
90
91 /// Check whether the default is selected
92 bool isDefault() const
93 { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
94
95 bool operator==(const Multilib &Other) const;
96
97 bool isError() const { return Error.has_value(); }
98
99 const std::string &getErrorMessage() const { return Error.value(); }
100};
101
102raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
103
104namespace custom_flag {
105struct Declaration;
106
108 std::string Name;
109 std::optional<SmallVector<std::string>> MacroDefines;
111};
112
114 std::string Name;
116 std::optional<size_t> DefaultValueIdx;
117
118 Declaration() = default;
119 Declaration(const Declaration &);
123};
124
125static constexpr StringRef Prefix = "-fmultilib-flag=";
126} // namespace custom_flag
127
128/// See also MultilibSetBuilder for combining multilibs into a set.
130public:
131 using multilib_list = std::vector<Multilib>;
132 using const_iterator = multilib_list::const_iterator;
134 std::function<std::vector<std::string>(const Multilib &M)>;
135 using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
136
137 /// Uses regular expressions to simplify flags used for multilib selection.
138 /// For example, we may wish both -mfloat-abi=soft and -mfloat-abi=softfp to
139 /// be treated as -mfloat-abi=soft.
140 struct FlagMatcher {
141 std::string Match;
142 std::vector<std::string> Flags;
143 };
144
145private:
146 multilib_list Multilibs;
147 SmallVector<FlagMatcher> FlagMatchers;
149 IncludeDirsFunc IncludeCallback;
150 IncludeDirsFunc FilePathsCallback;
151
152public:
153 MultilibSet() = default;
155 SmallVector<FlagMatcher> &&FlagMatchers = {},
156 SmallVector<custom_flag::Declaration> &&CustomFlagDecls = {})
157 : Multilibs(std::move(Multilibs)), FlagMatchers(std::move(FlagMatchers)),
158 CustomFlagDecls(std::move(CustomFlagDecls)) {}
159
160 const multilib_list &getMultilibs() { return Multilibs; }
161
162 /// Filter out some subset of the Multilibs using a user defined callback
164
165 /// Add a completed Multilib to the set
166 void push_back(const Multilib &M);
167
168 const_iterator begin() const { return Multilibs.begin(); }
169 const_iterator end() const { return Multilibs.end(); }
170
171 /// Process custom flags from \p Flags and returns an expanded flags list and
172 /// a list of macro defines.
173 /// Returns a pair where:
174 /// - first: the new flags list including custom flags after processing.
175 /// - second: the extra macro defines to be fed to the driver.
176 std::pair<Multilib::flags_list, SmallVector<StringRef>>
177 processCustomFlags(const Driver &D, const Multilib::flags_list &Flags) const;
178
179 /// Select compatible variants, \returns false if none are compatible
180 bool select(const Driver &D, const Multilib::flags_list &Flags,
182 llvm::SmallVector<StringRef> * = nullptr) const;
183
184 unsigned size() const { return Multilibs.size(); }
185
186 /// Get the given flags plus flags found by matching them against the
187 /// FlagMatchers and choosing the Flags of each accordingly. The select method
188 /// calls this method so in most cases it's not necessary to call it directly.
189 llvm::StringSet<> expandFlags(const Multilib::flags_list &) const;
190
191 LLVM_DUMP_METHOD void dump() const;
192 void print(raw_ostream &OS) const;
193
195 IncludeCallback = std::move(F);
196 return *this;
197 }
198
199 const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
200
202 FilePathsCallback = std::move(F);
203 return *this;
204 }
205
206 const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
207
208 static llvm::ErrorOr<MultilibSet>
209 parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy = nullptr,
210 void *DiagHandlerCtxt = nullptr);
211};
212
213raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
214
215} // namespace driver
216} // namespace clang
217
218#endif // LLVM_CLANG_DRIVER_MULTILIB_H
const Decl * D
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
#define bool
Definition: amdgpuintrin.h:20
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:99
See also MultilibSetBuilder for combining multilibs into a set.
Definition: Multilib.h:129
bool select(const Driver &D, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &, llvm::SmallVector< StringRef > *=nullptr) const
Select compatible variants,.
Definition: Multilib.cpp:218
MultilibSet & setFilePathsCallback(IncludeDirsFunc F)
Definition: Multilib.h:201
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:513
llvm::function_ref< bool(const Multilib &)> FilterCallback
Definition: Multilib.h:135
const_iterator end() const
Definition: Multilib.h:169
unsigned size() const
Definition: Multilib.h:184
const multilib_list & getMultilibs()
Definition: Multilib.h:160
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
Definition: Multilib.cpp:483
void print(raw_ostream &OS) const
Definition: Multilib.cpp:517
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
Definition: Multilib.cpp:88
std::vector< Multilib > multilib_list
Definition: Multilib.h:131
const IncludeDirsFunc & filePathsCallback() const
Definition: Multilib.h:206
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
Definition: Multilib.cpp:274
void push_back(const Multilib &M)
Add a completed Multilib to the set.
Definition: Multilib.cpp:93
MultilibSet(multilib_list &&Multilibs, SmallVector< FlagMatcher > &&FlagMatchers={}, SmallVector< custom_flag::Declaration > &&CustomFlagDecls={})
Definition: Multilib.h:154
const IncludeDirsFunc & includeDirsCallback() const
Definition: Multilib.h:199
MultilibSet & setIncludeDirsCallback(IncludeDirsFunc F)
Definition: Multilib.h:194
std::pair< Multilib::flags_list, SmallVector< StringRef > > processCustomFlags(const Driver &D, const Multilib::flags_list &Flags) const
Process custom flags from Flags and returns an expanded flags list and a list of macro defines.
Definition: Multilib.cpp:153
multilib_list::const_iterator const_iterator
Definition: Multilib.h:132
std::function< std::vector< std::string >(const Multilib &M)> IncludeDirsFunc
Definition: Multilib.h:134
const_iterator begin() const
Definition: Multilib.h:168
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:35
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:70
const std::string & getErrorMessage() const
Definition: Multilib.h:99
const std::string & osSuffix() const
Get the detected os path suffix for the multi-arch target variant.
Definition: Multilib.h:74
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
Definition: Multilib.h:82
std::vector< std::string > flags_list
Definition: Multilib.h:37
const std::string & includeSuffix() const
Get the include directory suffix.
Definition: Multilib.h:78
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:43
const std::string & exclusiveGroup() const
Get the exclusive group label.
Definition: Multilib.h:85
void print(raw_ostream &OS) const
print summary of the Multilib
Definition: Multilib.cpp:47
bool isDefault() const
Check whether the default is selected.
Definition: Multilib.h:92
bool isError() const
Definition: Multilib.h:97
bool operator==(const Multilib &Other) const
Definition: Multilib.cpp:60
static constexpr StringRef Prefix
Definition: Multilib.h:125
raw_ostream & operator<<(raw_ostream &OS, const Multilib &M)
Definition: Multilib.cpp:83
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.
bool(*)(llvm::ArrayRef< const char * >, llvm::raw_ostream &, llvm::raw_ostream &, bool, bool) Driver
Definition: Wasm.cpp:36
Uses regular expressions to simplify flags used for multilib selection.
Definition: Multilib.h:140
std::vector< std::string > Flags
Definition: Multilib.h:142
SmallVector< ValueDetail > ValueList
Definition: Multilib.h:115
Declaration & operator=(const Declaration &)
Definition: Multilib.cpp:542
std::optional< size_t > DefaultValueIdx
Definition: Multilib.h:116
std::optional< SmallVector< std::string > > MacroDefines
Definition: Multilib.h:109