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 <string>
22 #include <utility>
23 #include <vector>
24 
25 namespace clang {
26 namespace driver {
27 
28 /// This corresponds to a single GCC Multilib, or a segment of one controlled
29 /// by a command line flag.
30 /// See also MultilibBuilder for building a multilib by mutating it
31 /// incrementally.
32 class Multilib {
33 public:
34  using flags_list = std::vector<std::string>;
35 
36 private:
37  std::string GCCSuffix;
38  std::string OSSuffix;
39  std::string IncludeSuffix;
40  flags_list Flags;
41 
42  // Optionally, a multilib can be assigned a string tag indicating that it's
43  // part of a group of mutually exclusive possibilities. If two or more
44  // multilibs have the same non-empty value of ExclusiveGroup, then only the
45  // last matching one of them will be selected.
46  //
47  // Setting this to the empty string is a special case, indicating that the
48  // directory is not mutually exclusive with anything else.
49  std::string ExclusiveGroup;
50 
51 public:
52  /// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
53  /// sysroot string so they must either be empty or begin with a '/' character.
54  /// This is enforced with an assert in the constructor.
55  Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
56  StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
57  StringRef ExclusiveGroup = {});
58 
59  /// Get the detected GCC installation path suffix for the multi-arch
60  /// target variant. Always starts with a '/', unless empty
61  const std::string &gccSuffix() const { return GCCSuffix; }
62 
63  /// Get the detected os path suffix for the multi-arch
64  /// target variant. Always starts with a '/', unless empty
65  const std::string &osSuffix() const { return OSSuffix; }
66 
67  /// Get the include directory suffix. Always starts with a '/', unless
68  /// empty
69  const std::string &includeSuffix() const { return IncludeSuffix; }
70 
71  /// Get the flags that indicate or contraindicate this multilib's use
72  /// All elements begin with either '-' or '!'
73  const flags_list &flags() const { return Flags; }
74 
75  /// Get the exclusive group label.
76  const std::string &exclusiveGroup() const { return ExclusiveGroup; }
77 
78  LLVM_DUMP_METHOD void dump() const;
79  /// print summary of the Multilib
80  void print(raw_ostream &OS) const;
81 
82  /// Check whether the default is selected
83  bool isDefault() const
84  { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
85 
86  bool operator==(const Multilib &Other) const;
87 };
88 
89 raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
90 
91 /// See also MultilibSetBuilder for combining multilibs into a set.
92 class MultilibSet {
93 public:
94  using multilib_list = std::vector<Multilib>;
95  using const_iterator = multilib_list::const_iterator;
97  std::function<std::vector<std::string>(const Multilib &M)>;
98  using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
99 
100  /// Uses regular expressions to simplify flags used for multilib selection.
101  /// For example, we may wish both -mfloat-abi=soft and -mfloat-abi=softfp to
102  /// be treated as -mfloat-abi=soft.
103  struct FlagMatcher {
104  std::string Match;
105  std::vector<std::string> Flags;
106  };
107 
108 private:
109  multilib_list Multilibs;
110  std::vector<FlagMatcher> FlagMatchers;
111  IncludeDirsFunc IncludeCallback;
112  IncludeDirsFunc FilePathsCallback;
113 
114 public:
115  MultilibSet() = default;
117  std::vector<FlagMatcher> &&FlagMatchers = {})
118  : Multilibs(Multilibs), FlagMatchers(FlagMatchers) {}
119 
120  const multilib_list &getMultilibs() { return Multilibs; }
121 
122  /// Filter out some subset of the Multilibs using a user defined callback
124 
125  /// Add a completed Multilib to the set
126  void push_back(const Multilib &M);
127 
128  const_iterator begin() const { return Multilibs.begin(); }
129  const_iterator end() const { return Multilibs.end(); }
130 
131  /// Select compatible variants, \returns false if none are compatible
132  bool select(const Multilib::flags_list &Flags,
134 
135  unsigned size() const { return Multilibs.size(); }
136 
137  /// Get the given flags plus flags found by matching them against the
138  /// FlagMatchers and choosing the Flags of each accordingly. The select method
139  /// calls this method so in most cases it's not necessary to call it directly.
140  llvm::StringSet<> expandFlags(const Multilib::flags_list &) const;
141 
142  LLVM_DUMP_METHOD void dump() const;
143  void print(raw_ostream &OS) const;
144 
146  IncludeCallback = std::move(F);
147  return *this;
148  }
149 
150  const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
151 
153  FilePathsCallback = std::move(F);
154  return *this;
155  }
156 
157  const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
158 
159  static llvm::ErrorOr<MultilibSet>
160  parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy = nullptr,
161  void *DiagHandlerCtxt = nullptr);
162 };
163 
164 raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
165 
166 } // namespace driver
167 } // namespace clang
168 
169 #endif // LLVM_CLANG_DRIVER_MULTILIB_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
See also MultilibSetBuilder for combining multilibs into a set.
Definition: Multilib.h:92
const IncludeDirsFunc & includeDirsCallback() const
Definition: Multilib.h:150
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:311
llvm::function_ref< bool(const Multilib &)> FilterCallback
Definition: Multilib.h:98
const_iterator end() const
Definition: Multilib.h:129
unsigned size() const
Definition: Multilib.h:135
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
Definition: Multilib.cpp:286
void print(raw_ostream &OS) const
Definition: Multilib.cpp:315
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
Definition: Multilib.cpp:90
const multilib_list & getMultilibs()
Definition: Multilib.h:120
std::vector< Multilib > multilib_list
Definition: Multilib.h:94
MultilibSet(multilib_list &&Multilibs, std::vector< FlagMatcher > &&FlagMatchers={})
Definition: Multilib.h:116
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:136
bool select(const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &) const
Select compatible variants,.
Definition: Multilib.cpp:97
void push_back(const Multilib &M)
Add a completed Multilib to the set.
Definition: Multilib.cpp:95
const IncludeDirsFunc & filePathsCallback() const
Definition: Multilib.h:157
MultilibSet & setIncludeDirsCallback(IncludeDirsFunc F)
Definition: Multilib.h:145
multilib_list::const_iterator const_iterator
Definition: Multilib.h:95
MultilibSet & setFilePathsCallback(IncludeDirsFunc F)
Definition: Multilib.h:152
std::function< std::vector< std::string >(const Multilib &M)> IncludeDirsFunc
Definition: Multilib.h:97
const_iterator begin() const
Definition: Multilib.h:128
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:32
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:61
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
Definition: Multilib.h:73
Multilib(StringRef GCCSuffix={}, StringRef OSSuffix={}, StringRef IncludeSuffix={}, const flags_list &Flags=flags_list(), StringRef ExclusiveGroup={})
GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the sysroot string so they must eith...
Definition: Multilib.cpp:32
std::vector< std::string > flags_list
Definition: Multilib.h:34
const std::string & exclusiveGroup() const
Get the exclusive group label.
Definition: Multilib.h:76
LLVM_DUMP_METHOD void dump() const
Definition: Multilib.cpp:45
const std::string & osSuffix() const
Get the detected os path suffix for the multi-arch target variant.
Definition: Multilib.h:65
void print(raw_ostream &OS) const
print summary of the Multilib
Definition: Multilib.cpp:49
bool isDefault() const
Check whether the default is selected.
Definition: Multilib.h:83
const std::string & includeSuffix() const
Get the include directory suffix.
Definition: Multilib.h:69
bool operator==(const Multilib &Other) const
Definition: Multilib.cpp:62
raw_ostream & operator<<(raw_ostream &OS, const Multilib &M)
Definition: Multilib.cpp:85
The JSON file list parser is used to communicate input to InstallAPI.
#define bool
Definition: stdbool.h:24
Uses regular expressions to simplify flags used for multilib selection.
Definition: Multilib.h:103
std::vector< std::string > Flags
Definition: Multilib.h:105