11#include "llvm/ADT/StringMap.h"
12#include "llvm/Support/Path.h"
13#include "llvm/Support/Regex.h"
14#include "llvm/Support/raw_ostream.h"
17using namespace driver;
21 StringRef seg = Segment;
25 StringRef last = llvm::sys::path::filename(seg);
28 seg = llvm::sys::path::parent_path(seg);
31 if (seg.empty() || seg ==
"/") {
37 if (seg.front() !=
'/') {
38 Segment =
"/" + seg.str();
40 Segment = std::string(seg);
45 : GCCSuffix(GCC), OSSuffix(OS), IncludeSuffix(Include) {
55 GCCSuffix = std::string(S);
61 OSSuffix = std::string(S);
67 IncludeSuffix = std::string(S);
73 llvm::StringMap<int> FlagSet;
74 for (
unsigned I = 0, N = Flags.size(); I != N; ++I) {
75 StringRef Flag(Flags[I]);
76 auto [SI, Inserted] = FlagSet.try_emplace(Flag.substr(1), I);
78 assert(StringRef(Flag).front() ==
'-' || StringRef(Flag).front() ==
'!');
80 if (!Inserted && Flags[I] != Flags[SI->getValue()])
92 return Multilib(GCCSuffix, OSSuffix, IncludeSuffix, Flags);
98 for (StringRef Flag : M.
flags()) {
99 if (Flag.front() ==
'-')
100 Opposite.
flag(Flag,
true);
102 return Either(M, Opposite);
113 return Either({M1, M2, M3});
120 return Either({M1, M2, M3, M4});
128 return Either({M1, M2, M3, M4, M5});
134 llvm::sys::path::append(GCCSuffix,
"/",
Base.gccSuffix(), New.
gccSuffix());
136 llvm::sys::path::append(OSSuffix,
"/",
Base.osSuffix(), New.
osSuffix());
138 llvm::sys::path::append(IncludeSuffix,
"/",
Base.includeSuffix(),
145 Flags.insert(Flags.end(),
Base.flags().begin(),
Base.flags().end());
146 Flags.insert(Flags.end(), New.
flags().begin(), New.
flags().end());
155 if (Multilibs.empty())
156 Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
157 MultilibSegments.end());
159 for (
const auto &New : MultilibSegments) {
160 for (
const auto &
Base : Multilibs) {
163 Composed.push_back(MO);
167 Multilibs = Composed;
174 llvm::Regex R(Regex);
177 if (!R.isValid(Error)) {
178 llvm::errs() << Error;
179 llvm_unreachable(
"Invalid regex!");
190 for (
const auto &M : Multilibs) {
191 Result.push_back(M.makeMultilib());
static MultilibBuilder compose(const MultilibBuilder &Base, const MultilibBuilder &New)
static void normalizePathSegment(std::string &Segment)
normalize Segment to "/foo/bar" or "".
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
bool isValid() const
Check whether any of the 'against' flags contradict the 'for' flags.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
const std::string & includeSuffix() const
Get the include directory suffix.
const std::string & osSuffix() const
Get the detected os path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Multilib makeMultilib() const
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
MultilibBuilder(StringRef GCCSuffix, StringRef OSSuffix, StringRef IncludeSuffix)
This class can be used to create a MultilibSet, and contains helper functions to add combinations of ...
MultilibSetBuilder & Maybe(const MultilibBuilder &M)
Add an optional Multilib segment.
MultilibSetBuilder & FilterOut(const char *Regex)
Filter out those Multilibs whose gccSuffix matches the given expression.
MultilibSetBuilder & Either(const MultilibBuilder &M1, const MultilibBuilder &M2)
Add a set of mutually incompatible Multilib segments.
std::vector< MultilibBuilder > multilib_list
MultilibSet makeMultilibSet() const
See also MultilibSetBuilder for combining multilibs into a set.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.