clang 17.0.0git
Multilib.cpp
Go to the documentation of this file.
1//===- Multilib.cpp - Multilib Implementation -----------------------------===//
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
10#include "clang/Basic/LLVM.h"
11#include "llvm/ADT/SmallString.h"
12#include "llvm/ADT/StringMap.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSet.h"
15#include "llvm/Support/Compiler.h"
16#include "llvm/Support/ErrorHandling.h"
17#include "llvm/Support/Path.h"
18#include "llvm/Support/Regex.h"
19#include "llvm/Support/raw_ostream.h"
20#include <algorithm>
21#include <cassert>
22#include <string>
23
24using namespace clang;
25using namespace driver;
26using namespace llvm::sys;
27
28Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
29 StringRef IncludeSuffix, const flags_list &Flags)
30 : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
31 Flags(Flags) {
32 assert(GCCSuffix.empty() ||
33 (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
34 assert(OSSuffix.empty() ||
35 (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
36 assert(IncludeSuffix.empty() ||
37 (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
38}
39
40LLVM_DUMP_METHOD void Multilib::dump() const {
41 print(llvm::errs());
42}
43
44void Multilib::print(raw_ostream &OS) const {
45 if (GCCSuffix.empty())
46 OS << ".";
47 else {
48 OS << StringRef(GCCSuffix).drop_front();
49 }
50 OS << ";";
51 for (StringRef Flag : Flags) {
52 if (Flag.front() == '+')
53 OS << "@" << Flag.substr(1);
54 }
55}
56
57bool Multilib::operator==(const Multilib &Other) const {
58 // Check whether the flags sets match
59 // allowing for the match to be order invariant
60 llvm::StringSet<> MyFlags;
61 for (const auto &Flag : Flags)
62 MyFlags.insert(Flag);
63
64 for (const auto &Flag : Other.Flags)
65 if (!MyFlags.contains(Flag))
66 return false;
67
68 if (osSuffix() != Other.osSuffix())
69 return false;
70
71 if (gccSuffix() != Other.gccSuffix())
72 return false;
73
74 if (includeSuffix() != Other.includeSuffix())
75 return false;
76
77 return true;
78}
79
80raw_ostream &clang::driver::operator<<(raw_ostream &OS, const Multilib &M) {
81 M.print(OS);
82 return OS;
83}
84
86 llvm::erase_if(Multilibs, F);
87 return *this;
88}
89
90void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
91
94 llvm::StringSet<> FlagSet;
95 for (const auto &Flag : Flags)
96 FlagSet.insert(Flag);
97
99 llvm::copy_if(Multilibs, std::back_inserter(Result),
100 [&FlagSet](const Multilib &M) {
101 for (const std::string &F : M.flags())
102 if (!FlagSet.contains(F))
103 return false;
104 return true;
105 });
106 return Result;
107}
108
110 Multilib &Selected) const {
111 multilib_list Result = select(Flags);
112 if (Result.empty())
113 return false;
114 Selected = Result.back();
115 return true;
116}
117
118LLVM_DUMP_METHOD void MultilibSet::dump() const {
119 print(llvm::errs());
120}
121
122void MultilibSet::print(raw_ostream &OS) const {
123 for (const auto &M : *this)
124 OS << M << "\n";
125}
126
127raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) {
128 MS.print(OS);
129 return OS;
130}
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::raw_ostream & OS
Definition: Logger.cpp:24
See also MultilibSetBuilder for combining multilibs into a set.
Definition: Multilib.h:78
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:118
llvm::function_ref< bool(const Multilib &)> FilterCallback
Definition: Multilib.h:84
void print(raw_ostream &OS) const
Definition: Multilib.cpp:122
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
Definition: Multilib.cpp:85
multilib_list select(const Multilib::flags_list &Flags) const
Select compatible variants.
Definition: Multilib.cpp:93
std::vector< Multilib > multilib_list
Definition: Multilib.h:80
void push_back(const Multilib &M)
Add a completed Multilib to the set.
Definition: Multilib.cpp:90
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:30
Multilib(StringRef GCCSuffix={}, StringRef OSSuffix={}, StringRef IncludeSuffix={}, const flags_list &Flags=flags_list())
GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the sysroot string so they must eith...
Definition: Multilib.cpp:28
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:50
const std::string & osSuffix() const
Get the detected os path suffix for the multi-arch target variant.
Definition: Multilib.h:54
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '+' ...
Definition: Multilib.h:62
std::vector< std::string > flags_list
Definition: Multilib.h:32
const std::string & includeSuffix() const
Get the include directory suffix.
Definition: Multilib.h:58
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:40
void print(raw_ostream &OS) const
print summary of the Multilib
Definition: Multilib.cpp:44
bool operator==(const Multilib &Other) const
Definition: Multilib.cpp:57
raw_ostream & operator<<(raw_ostream &OS, const Multilib &M)
Definition: Multilib.cpp:80
@ Result
The result type of a method or function.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))