1 | //===--- DependenceFlags.h ------------------------------------------------===// |
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 | #ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H |
9 | #define LLVM_CLANG_AST_DEPENDENCEFLAGS_H |
10 | |
11 | #include "clang/Basic/BitmaskEnum.h" |
12 | #include "llvm/ADT/BitmaskEnum.h" |
13 | #include <cstdint> |
14 | |
15 | namespace clang { |
16 | struct ExprDependenceScope { |
17 | enum ExprDependence : uint8_t { |
18 | UnexpandedPack = 1, |
19 | // This expr depends in any way on |
20 | // - a template parameter, it implies that the resolution of this expr may |
21 | // cause instantiation to fail |
22 | // - or an error (often in a non-template context) |
23 | // |
24 | // Note that C++ standard doesn't define the instantiation-dependent term, |
25 | // we follow the formal definition coming from the Itanium C++ ABI, and |
26 | // extend it to errors. |
27 | Instantiation = 2, |
28 | // The type of this expr depends on a template parameter, or an error. |
29 | Type = 4, |
30 | // The value of this expr depends on a template parameter, or an error. |
31 | Value = 8, |
32 | |
33 | // clang extension: this expr contains or references an error, and is |
34 | // considered dependent on how that error is resolved. |
35 | Error = 16, |
36 | |
37 | None = 0, |
38 | All = 31, |
39 | |
40 | TypeValue = Type | Value, |
41 | TypeInstantiation = Type | Instantiation, |
42 | ValueInstantiation = Value | Instantiation, |
43 | TypeValueInstantiation = Type | Value | Instantiation, |
44 | ErrorDependent = Error | ValueInstantiation, |
45 | |
46 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) |
47 | }; |
48 | }; |
49 | using ExprDependence = ExprDependenceScope::ExprDependence; |
50 | |
51 | struct TypeDependenceScope { |
52 | enum TypeDependence : uint8_t { |
53 | /// Whether this type contains an unexpanded parameter pack |
54 | /// (for C++11 variadic templates) |
55 | UnexpandedPack = 1, |
56 | /// Whether this type somehow involves |
57 | /// - a template parameter, even if the resolution of the type does not |
58 | /// depend on a template parameter. |
59 | /// - or an error. |
60 | Instantiation = 2, |
61 | /// Whether this type |
62 | /// - is a dependent type (C++ [temp.dep.type]) |
63 | /// - or it somehow involves an error, e.g. decltype(recovery-expr) |
64 | Dependent = 4, |
65 | /// Whether this type is a variably-modified type (C99 6.7.5). |
66 | VariablyModified = 8, |
67 | |
68 | /// Whether this type references an error, e.g. decltype(err-expression) |
69 | /// yields an error type. |
70 | Error = 16, |
71 | |
72 | None = 0, |
73 | All = 31, |
74 | |
75 | DependentInstantiation = Dependent | Instantiation, |
76 | |
77 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) |
78 | }; |
79 | }; |
80 | using TypeDependence = TypeDependenceScope::TypeDependence; |
81 | |
82 | #define LLVM_COMMON_DEPENDENCE(NAME) \ |
83 | struct NAME##Scope { \ |
84 | enum NAME : uint8_t { \ |
85 | UnexpandedPack = 1, \ |
86 | Instantiation = 2, \ |
87 | Dependent = 4, \ |
88 | Error = 8, \ |
89 | \ |
90 | None = 0, \ |
91 | DependentInstantiation = Dependent | Instantiation, \ |
92 | All = 15, \ |
93 | \ |
94 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \ |
95 | }; \ |
96 | }; \ |
97 | using NAME = NAME##Scope::NAME; |
98 | |
99 | LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) |
100 | LLVM_COMMON_DEPENDENCE(TemplateNameDependence) |
101 | LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) |
102 | #undef LLVM_COMMON_DEPENDENCE |
103 | |
104 | // A combined space of all dependence concepts for all node types. |
105 | // Used when aggregating dependence of nodes of different types. |
106 | class Dependence { |
107 | public: |
108 | enum Bits : uint8_t { |
109 | None = 0, |
110 | |
111 | // Contains a template parameter pack that wasn't expanded. |
112 | UnexpandedPack = 1, |
113 | // Depends on a template parameter or an error in some way. |
114 | // Validity depends on how the template is instantiated or the error is |
115 | // resolved. |
116 | Instantiation = 2, |
117 | // Expression type depends on template context, or an error. |
118 | // Value and Instantiation should also be set. |
119 | Type = 4, |
120 | // Expression value depends on template context, or an error. |
121 | // Instantiation should also be set. |
122 | Value = 8, |
123 | // Depends on template context, or an error. |
124 | // The type/value distinction is only meaningful for expressions. |
125 | Dependent = Type | Value, |
126 | // Includes an error, and depends on how it is resolved. |
127 | Error = 16, |
128 | // Type depends on a runtime value (variable-length array). |
129 | VariablyModified = 32, |
130 | |
131 | // Dependence that is propagated syntactically, regardless of semantics. |
132 | Syntactic = UnexpandedPack | Instantiation | Error, |
133 | // Dependence that is propagated semantically, even in cases where the |
134 | // type doesn't syntactically appear. This currently excludes only |
135 | // UnexpandedPack. Even though Instantiation dependence is also notionally |
136 | // syntactic, we also want to propagate it semantically because anything |
137 | // that semantically depends on an instantiation-dependent entity should |
138 | // always be instantiated when that instantiation-dependent entity is. |
139 | Semantic = |
140 | Instantiation | Type | Value | Dependent | Error | VariablyModified, |
141 | |
142 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) |
143 | }; |
144 | |
145 | Dependence() : V(None) {} |
146 | |
147 | Dependence(TypeDependence D) |
148 | : V(translate(Bits: D, FromBit: TypeDependence::UnexpandedPack, ToBit: UnexpandedPack) | |
149 | translate(Bits: D, FromBit: TypeDependence::Instantiation, ToBit: Instantiation) | |
150 | translate(Bits: D, FromBit: TypeDependence::Dependent, ToBit: Dependent) | |
151 | translate(Bits: D, FromBit: TypeDependence::Error, ToBit: Error) | |
152 | translate(Bits: D, FromBit: TypeDependence::VariablyModified, ToBit: VariablyModified)) {} |
153 | |
154 | Dependence(ExprDependence D) |
155 | : V(translate(Bits: D, FromBit: ExprDependence::UnexpandedPack, ToBit: UnexpandedPack) | |
156 | translate(Bits: D, FromBit: ExprDependence::Instantiation, ToBit: Instantiation) | |
157 | translate(Bits: D, FromBit: ExprDependence::Type, ToBit: Type) | |
158 | translate(Bits: D, FromBit: ExprDependence::Value, ToBit: Value) | |
159 | translate(Bits: D, FromBit: ExprDependence::Error, ToBit: Error)) {} |
160 | |
161 | Dependence(NestedNameSpecifierDependence D) : |
162 | V ( translate(Bits: D, FromBit: NNSDependence::UnexpandedPack, ToBit: UnexpandedPack) | |
163 | translate(Bits: D, FromBit: NNSDependence::Instantiation, ToBit: Instantiation) | |
164 | translate(Bits: D, FromBit: NNSDependence::Dependent, ToBit: Dependent) | |
165 | translate(Bits: D, FromBit: NNSDependence::Error, ToBit: Error)) {} |
166 | |
167 | Dependence(TemplateArgumentDependence D) |
168 | : V(translate(Bits: D, FromBit: TADependence::UnexpandedPack, ToBit: UnexpandedPack) | |
169 | translate(Bits: D, FromBit: TADependence::Instantiation, ToBit: Instantiation) | |
170 | translate(Bits: D, FromBit: TADependence::Dependent, ToBit: Dependent) | |
171 | translate(Bits: D, FromBit: TADependence::Error, ToBit: Error)) {} |
172 | |
173 | Dependence(TemplateNameDependence D) |
174 | : V(translate(Bits: D, FromBit: TNDependence::UnexpandedPack, ToBit: UnexpandedPack) | |
175 | translate(Bits: D, FromBit: TNDependence::Instantiation, ToBit: Instantiation) | |
176 | translate(Bits: D, FromBit: TNDependence::Dependent, ToBit: Dependent) | |
177 | translate(Bits: D, FromBit: TNDependence::Error, ToBit: Error)) {} |
178 | |
179 | /// Extract only the syntactic portions of this type's dependence. |
180 | Dependence syntactic() { |
181 | Dependence Result = *this; |
182 | Result.V &= Syntactic; |
183 | return Result; |
184 | } |
185 | |
186 | /// Extract the semantic portions of this type's dependence that apply even |
187 | /// to uses where the type does not appear syntactically. |
188 | Dependence semantic() { |
189 | Dependence Result = *this; |
190 | Result.V &= Semantic; |
191 | return Result; |
192 | } |
193 | |
194 | TypeDependence type() const { |
195 | return translate(Bits: V, FromBit: UnexpandedPack, ToBit: TypeDependence::UnexpandedPack) | |
196 | translate(Bits: V, FromBit: Instantiation, ToBit: TypeDependence::Instantiation) | |
197 | translate(Bits: V, FromBit: Dependent, ToBit: TypeDependence::Dependent) | |
198 | translate(Bits: V, FromBit: Error, ToBit: TypeDependence::Error) | |
199 | translate(Bits: V, FromBit: VariablyModified, ToBit: TypeDependence::VariablyModified); |
200 | } |
201 | |
202 | ExprDependence expr() const { |
203 | return translate(Bits: V, FromBit: UnexpandedPack, ToBit: ExprDependence::UnexpandedPack) | |
204 | translate(Bits: V, FromBit: Instantiation, ToBit: ExprDependence::Instantiation) | |
205 | translate(Bits: V, FromBit: Type, ToBit: ExprDependence::Type) | |
206 | translate(Bits: V, FromBit: Value, ToBit: ExprDependence::Value) | |
207 | translate(Bits: V, FromBit: Error, ToBit: ExprDependence::Error); |
208 | } |
209 | |
210 | NestedNameSpecifierDependence nestedNameSpecifier() const { |
211 | return translate(Bits: V, FromBit: UnexpandedPack, ToBit: NNSDependence::UnexpandedPack) | |
212 | translate(Bits: V, FromBit: Instantiation, ToBit: NNSDependence::Instantiation) | |
213 | translate(Bits: V, FromBit: Dependent, ToBit: NNSDependence::Dependent) | |
214 | translate(Bits: V, FromBit: Error, ToBit: NNSDependence::Error); |
215 | } |
216 | |
217 | TemplateArgumentDependence templateArgument() const { |
218 | return translate(Bits: V, FromBit: UnexpandedPack, ToBit: TADependence::UnexpandedPack) | |
219 | translate(Bits: V, FromBit: Instantiation, ToBit: TADependence::Instantiation) | |
220 | translate(Bits: V, FromBit: Dependent, ToBit: TADependence::Dependent) | |
221 | translate(Bits: V, FromBit: Error, ToBit: TADependence::Error); |
222 | } |
223 | |
224 | TemplateNameDependence templateName() const { |
225 | return translate(Bits: V, FromBit: UnexpandedPack, ToBit: TNDependence::UnexpandedPack) | |
226 | translate(Bits: V, FromBit: Instantiation, ToBit: TNDependence::Instantiation) | |
227 | translate(Bits: V, FromBit: Dependent, ToBit: TNDependence::Dependent) | |
228 | translate(Bits: V, FromBit: Error, ToBit: TNDependence::Error); |
229 | } |
230 | |
231 | private: |
232 | Bits V; |
233 | |
234 | template <typename T, typename U> |
235 | static U translate(T Bits, T FromBit, U ToBit) { |
236 | return (Bits & FromBit) ? ToBit : static_cast<U>(0); |
237 | } |
238 | |
239 | // Abbreviations to make conversions more readable. |
240 | using NNSDependence = NestedNameSpecifierDependence; |
241 | using TADependence = TemplateArgumentDependence; |
242 | using TNDependence = TemplateNameDependence; |
243 | }; |
244 | |
245 | /// Computes dependencies of a reference with the name having template arguments |
246 | /// with \p TA dependencies. |
247 | inline ExprDependence toExprDependence(TemplateArgumentDependence TA) { |
248 | return Dependence(TA).expr(); |
249 | } |
250 | inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) { |
251 | return Dependence(D).semantic().expr(); |
252 | } |
253 | inline ExprDependence toExprDependenceAsWritten(TypeDependence D) { |
254 | return Dependence(D).expr(); |
255 | } |
256 | // Note: it's often necessary to strip `Dependent` from qualifiers. |
257 | // If V<T>:: refers to the current instantiation, NNS is considered dependent |
258 | // but the containing V<T>::foo likely isn't. |
259 | inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) { |
260 | return Dependence(D).expr(); |
261 | } |
262 | inline ExprDependence turnTypeToValueDependence(ExprDependence D) { |
263 | // Type-dependent expressions are always be value-dependent, so we simply drop |
264 | // type dependency. |
265 | return D & ~ExprDependence::Type; |
266 | } |
267 | inline ExprDependence turnValueToTypeDependence(ExprDependence D) { |
268 | // Type-dependent expressions are always be value-dependent. |
269 | if (D & ExprDependence::Value) |
270 | D |= ExprDependence::Type; |
271 | return D; |
272 | } |
273 | |
274 | // Returned type-dependence will never have VariablyModified set. |
275 | inline TypeDependence toTypeDependence(ExprDependence D) { |
276 | return Dependence(D).type(); |
277 | } |
278 | inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { |
279 | return Dependence(D).type(); |
280 | } |
281 | inline TypeDependence toTypeDependence(TemplateNameDependence D) { |
282 | return Dependence(D).type(); |
283 | } |
284 | inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { |
285 | return Dependence(D).type(); |
286 | } |
287 | |
288 | inline TypeDependence toSyntacticDependence(TypeDependence D) { |
289 | return Dependence(D).syntactic().type(); |
290 | } |
291 | inline TypeDependence toSemanticDependence(TypeDependence D) { |
292 | return Dependence(D).semantic().type(); |
293 | } |
294 | |
295 | inline NestedNameSpecifierDependence |
296 | toNestedNameSpecifierDependendence(TypeDependence D) { |
297 | return Dependence(D).nestedNameSpecifier(); |
298 | } |
299 | |
300 | inline TemplateArgumentDependence |
301 | toTemplateArgumentDependence(TypeDependence D) { |
302 | return Dependence(D).templateArgument(); |
303 | } |
304 | inline TemplateArgumentDependence |
305 | toTemplateArgumentDependence(TemplateNameDependence D) { |
306 | return Dependence(D).templateArgument(); |
307 | } |
308 | inline TemplateArgumentDependence |
309 | toTemplateArgumentDependence(ExprDependence D) { |
310 | return Dependence(D).templateArgument(); |
311 | } |
312 | |
313 | inline TemplateNameDependence |
314 | toTemplateNameDependence(NestedNameSpecifierDependence D) { |
315 | return Dependence(D).templateName(); |
316 | } |
317 | |
318 | LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); |
319 | |
320 | } // namespace clang |
321 | #endif |
322 | |