11#include "llvm/ADT/SmallString.h"
12#include "llvm/ADT/StringMap.h"
13#include "llvm/Support/Path.h"
14#include "llvm/Support/Regex.h"
15#include "llvm/Support/raw_ostream.h"
18using namespace driver;
22 StringRef seg = Segment;
26 StringRef last = llvm::sys::path::filename(seg);
29 seg = llvm::sys::path::parent_path(seg);
32 if (seg.empty() || seg ==
"/") {
38 if (seg.front() !=
'/') {
39 Segment =
"/" + seg.str();
41 Segment = std::string(seg);
46 : GCCSuffix(GCC), OSSuffix(OS), IncludeSuffix(Include) {
56 GCCSuffix = std::string(S);
62 OSSuffix = std::string(S);
68 IncludeSuffix = std::string(S);
74 llvm::StringMap<int> FlagSet;
75 for (
unsigned I = 0, N = Flags.size(); I != N; ++I) {
76 StringRef Flag(Flags[I]);
77 llvm::StringMap<int>::iterator SI = FlagSet.find(Flag.substr(1));
79 assert(StringRef(Flag).front() ==
'-' || StringRef(Flag).front() ==
'!');
81 if (SI == FlagSet.end())
82 FlagSet[Flag.substr(1)] = I;
83 else if (Flags[I] != Flags[SI->getValue()])
95 return Multilib(GCCSuffix, OSSuffix, IncludeSuffix, Flags);
101 for (StringRef Flag : M.
flags()) {
102 if (Flag.front() ==
'-')
103 Opposite.
flag(Flag,
true);
105 return Either(M, Opposite);
116 return Either({M1, M2, M3});
123 return Either({M1, M2, M3, M4});
131 return Either({M1, M2, M3, M4, M5});
137 llvm::sys::path::append(GCCSuffix,
"/",
Base.gccSuffix(), New.
gccSuffix());
139 llvm::sys::path::append(OSSuffix,
"/",
Base.osSuffix(), New.
osSuffix());
141 llvm::sys::path::append(IncludeSuffix,
"/",
Base.includeSuffix(),
148 Flags.insert(Flags.end(),
Base.flags().begin(),
Base.flags().end());
149 Flags.insert(Flags.end(), New.
flags().begin(), New.
flags().end());
158 if (Multilibs.empty())
159 Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
160 MultilibSegments.end());
162 for (
const auto &New : MultilibSegments) {
163 for (
const auto &
Base : Multilibs) {
166 Composed.push_back(MO);
170 Multilibs = Composed;
177 llvm::Regex R(Regex);
180 if (!R.isValid(Error)) {
181 llvm::errs() << Error;
182 llvm_unreachable(
"Invalid regex!");
193 for (
const auto &M : Multilibs) {
194 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.