1 | //===- MultilibBuilder.h |
2 | //-----------------------------------------------*- C++ -*-===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef LLVM_CLANG_DRIVER_MULTILIBBUILDER_H |
11 | #define LLVM_CLANG_DRIVER_MULTILIBBUILDER_H |
12 | |
13 | #include "clang/Driver/Multilib.h" |
14 | |
15 | namespace clang { |
16 | namespace driver { |
17 | |
18 | /// This corresponds to a single GCC multilib, or a segment of one controlled |
19 | /// by a command line flag. This class can be used to create a Multilib, and |
20 | /// contains helper functions to mutate it before creating a Multilib instance |
21 | /// with makeMultilib(). |
22 | class MultilibBuilder { |
23 | public: |
24 | using flags_list = std::vector<std::string>; |
25 | |
26 | private: |
27 | std::string GCCSuffix; |
28 | std::string OSSuffix; |
29 | std::string IncludeSuffix; |
30 | flags_list Flags; |
31 | |
32 | public: |
33 | MultilibBuilder(StringRef GCCSuffix, StringRef OSSuffix, |
34 | StringRef IncludeSuffix); |
35 | |
36 | /// Initializes GCCSuffix, OSSuffix & IncludeSuffix to the same value. |
37 | MultilibBuilder(StringRef Suffix = {}); |
38 | |
39 | /// Get the detected GCC installation path suffix for the multi-arch |
40 | /// target variant. Always starts with a '/', unless empty |
41 | const std::string &gccSuffix() const { |
42 | assert(GCCSuffix.empty() || |
43 | (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1)); |
44 | return GCCSuffix; |
45 | } |
46 | |
47 | /// Set the GCC installation path suffix. |
48 | MultilibBuilder &gccSuffix(StringRef S); |
49 | |
50 | /// Get the detected os path suffix for the multi-arch |
51 | /// target variant. Always starts with a '/', unless empty |
52 | const std::string &osSuffix() const { |
53 | assert(OSSuffix.empty() || |
54 | (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1)); |
55 | return OSSuffix; |
56 | } |
57 | |
58 | /// Set the os path suffix. |
59 | MultilibBuilder &osSuffix(StringRef S); |
60 | |
61 | /// Get the include directory suffix. Always starts with a '/', unless |
62 | /// empty |
63 | const std::string &includeSuffix() const { |
64 | assert(IncludeSuffix.empty() || (StringRef(IncludeSuffix).front() == '/' && |
65 | IncludeSuffix.size() > 1)); |
66 | return IncludeSuffix; |
67 | } |
68 | |
69 | /// Set the include directory suffix |
70 | MultilibBuilder &includeSuffix(StringRef S); |
71 | |
72 | /// Get the flags that indicate or contraindicate this multilib's use |
73 | /// All elements begin with either '-' or '!' |
74 | const flags_list &flags() const { return Flags; } |
75 | flags_list &flags() { return Flags; } |
76 | |
77 | /// Add a flag to the flags list |
78 | /// \p Flag must be a flag accepted by the driver. |
79 | /// \p Disallow defines whether the flag is negated and therefore disallowed. |
80 | MultilibBuilder &flag(StringRef Flag, bool Disallow = false); |
81 | |
82 | Multilib makeMultilib() const; |
83 | |
84 | /// Check whether any of the 'against' flags contradict the 'for' flags. |
85 | bool isValid() const; |
86 | |
87 | /// Check whether the default is selected |
88 | bool isDefault() const { |
89 | return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); |
90 | } |
91 | }; |
92 | |
93 | /// This class can be used to create a MultilibSet, and contains helper |
94 | /// functions to add combinations of multilibs before creating a MultilibSet |
95 | /// instance with makeMultilibSet(). |
96 | class MultilibSetBuilder { |
97 | public: |
98 | using multilib_list = std::vector<MultilibBuilder>; |
99 | |
100 | MultilibSetBuilder() = default; |
101 | |
102 | /// Add an optional Multilib segment |
103 | MultilibSetBuilder &Maybe(const MultilibBuilder &M); |
104 | |
105 | /// Add a set of mutually incompatible Multilib segments |
106 | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
107 | const MultilibBuilder &M2); |
108 | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
109 | const MultilibBuilder &M2, |
110 | const MultilibBuilder &M3); |
111 | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
112 | const MultilibBuilder &M2, |
113 | const MultilibBuilder &M3, |
114 | const MultilibBuilder &M4); |
115 | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
116 | const MultilibBuilder &M2, |
117 | const MultilibBuilder &M3, |
118 | const MultilibBuilder &M4, |
119 | const MultilibBuilder &M5); |
120 | MultilibSetBuilder &Either(ArrayRef<MultilibBuilder> Ms); |
121 | |
122 | /// Filter out those Multilibs whose gccSuffix matches the given expression |
123 | MultilibSetBuilder &FilterOut(const char *Regex); |
124 | |
125 | MultilibSet makeMultilibSet() const; |
126 | |
127 | private: |
128 | multilib_list Multilibs; |
129 | }; |
130 | |
131 | } // namespace driver |
132 | } // namespace clang |
133 | |
134 | #endif // LLVM_CLANG_DRIVER_MULTILIBBUILDER_H |
135 | |