/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Driver/MultilibBuilder.h
Line | Count | Source (jump to first uncovered line) |
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 | 22.4k | const std::string &gccSuffix() const { |
42 | 22.4k | assert(GCCSuffix.empty() || |
43 | 22.4k | (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1)); |
44 | 22.4k | return GCCSuffix; |
45 | 22.4k | } |
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 | 15.8k | const std::string &osSuffix() const { |
53 | 15.8k | assert(OSSuffix.empty() || |
54 | 15.8k | (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1)); |
55 | 15.8k | return OSSuffix; |
56 | 15.8k | } |
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 | 15.8k | const std::string &includeSuffix() const { |
64 | 15.8k | assert(IncludeSuffix.empty() || (StringRef(IncludeSuffix).front() == '/' && |
65 | 15.8k | IncludeSuffix.size() > 1)); |
66 | 15.8k | return IncludeSuffix; |
67 | 15.8k | } |
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 | 31.8k | const flags_list &flags() const { return Flags; } |
75 | 8.04k | 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 with its leading '-' |
79 | | /// removed, |
80 | | /// and replaced with either: |
81 | | /// '-' which contraindicates using this multilib with that flag |
82 | | /// or: |
83 | | /// '+' which promotes using this multilib in the presence of that flag |
84 | | /// otherwise '-print-multi-lib' will not emit them correctly. |
85 | 8.35k | MultilibBuilder &flag(StringRef F) { |
86 | 8.35k | assert(F.front() == '+' || F.front() == '-'); |
87 | 8.35k | Flags.push_back(std::string(F)); |
88 | 8.35k | return *this; |
89 | 8.35k | } |
90 | | |
91 | | Multilib makeMultilib() const; |
92 | | |
93 | | /// Check whether any of the 'against' flags contradict the 'for' flags. |
94 | | bool isValid() const; |
95 | | |
96 | | /// Check whether the default is selected |
97 | 0 | bool isDefault() const { |
98 | 0 | return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); |
99 | 0 | } |
100 | | }; |
101 | | |
102 | | /// This class can be used to create a MultilibSet, and contains helper |
103 | | /// functions to add combinations of multilibs before creating a MultilibSet |
104 | | /// instance with makeMultilibSet(). |
105 | | class MultilibSetBuilder { |
106 | | public: |
107 | | using multilib_list = std::vector<MultilibBuilder>; |
108 | | |
109 | 343 | MultilibSetBuilder() = default; |
110 | | |
111 | | /// Add an optional Multilib segment |
112 | | MultilibSetBuilder &Maybe(const MultilibBuilder &M); |
113 | | |
114 | | /// Add a set of mutually incompatible Multilib segments |
115 | | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
116 | | const MultilibBuilder &M2); |
117 | | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
118 | | const MultilibBuilder &M2, |
119 | | const MultilibBuilder &M3); |
120 | | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
121 | | const MultilibBuilder &M2, |
122 | | const MultilibBuilder &M3, |
123 | | const MultilibBuilder &M4); |
124 | | MultilibSetBuilder &Either(const MultilibBuilder &M1, |
125 | | const MultilibBuilder &M2, |
126 | | const MultilibBuilder &M3, |
127 | | const MultilibBuilder &M4, |
128 | | const MultilibBuilder &M5); |
129 | | MultilibSetBuilder &Either(ArrayRef<MultilibBuilder> Ms); |
130 | | |
131 | | /// Filter out those Multilibs whose gccSuffix matches the given expression |
132 | | MultilibSetBuilder &FilterOut(const char *Regex); |
133 | | |
134 | | MultilibSet makeMultilibSet() const; |
135 | | |
136 | | private: |
137 | | multilib_list Multilibs; |
138 | | }; |
139 | | |
140 | | } // namespace driver |
141 | | } // namespace clang |
142 | | |
143 | | #endif // LLVM_CLANG_DRIVER_MULTILIBBUILDER_H |