clang 19.0.0git
DependenceFlags.h
Go to the documentation of this file.
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
12#include "llvm/ADT/BitmaskEnum.h"
13#include <cstdint>
14
15namespace clang {
17 enum ExprDependence : uint8_t {
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.
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
45
46 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
47 };
48};
50
52 enum TypeDependence : uint8_t {
53 /// Whether this type contains an unexpanded parameter pack
54 /// (for C++11 variadic templates)
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.
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)
65 /// Whether this type is a variably-modified type (C99 6.7.5).
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
76
77 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
78 };
79};
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
99LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence)
100LLVM_COMMON_DEPENDENCE(TemplateNameDependence)
101LLVM_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.
107public:
108 enum Bits : uint8_t {
109 None = 0,
110
111 // Contains a template parameter pack that wasn't expanded.
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.
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.
126 // Includes an error, and depends on how it is resolved.
127 Error = 16,
128 // Type depends on a runtime value (variable-length array).
130
131 // Dependence that is propagated syntactically, regardless of semantics.
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 =
141
142 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
143 };
144
145 Dependence() : V(None) {}
146
148 : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
150 translate(D, TypeDependence::Dependent, Dependent) |
151 translate(D, TypeDependence::Error, Error) |
153
155 : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
157 translate(D, ExprDependence::Type, Type) |
158 translate(D, ExprDependence::Value, Value) |
159 translate(D, ExprDependence::Error, Error)) {}
160
161 Dependence(NestedNameSpecifierDependence D) :
162 V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
163 translate(D, NNSDependence::Instantiation, Instantiation) |
164 translate(D, NNSDependence::Dependent, Dependent) |
165 translate(D, NNSDependence::Error, Error)) {}
166
167 Dependence(TemplateArgumentDependence D)
168 : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
169 translate(D, TADependence::Instantiation, Instantiation) |
170 translate(D, TADependence::Dependent, Dependent) |
171 translate(D, TADependence::Error, Error)) {}
172
173 Dependence(TemplateNameDependence D)
174 : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
175 translate(D, TNDependence::Instantiation, Instantiation) |
176 translate(D, TNDependence::Dependent, Dependent) |
177 translate(D, TNDependence::Error, Error)) {}
178
179 /// Extract only the syntactic portions of this type's dependence.
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.
189 Dependence Result = *this;
190 Result.V &= Semantic;
191 return Result;
192 }
193
195 return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
196 translate(V, Instantiation, TypeDependence::Instantiation) |
197 translate(V, Dependent, TypeDependence::Dependent) |
198 translate(V, Error, TypeDependence::Error) |
199 translate(V, VariablyModified, TypeDependence::VariablyModified);
200 }
201
203 return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) |
204 translate(V, Instantiation, ExprDependence::Instantiation) |
205 translate(V, Type, ExprDependence::Type) |
206 translate(V, Value, ExprDependence::Value) |
207 translate(V, Error, ExprDependence::Error);
208 }
209
210 NestedNameSpecifierDependence nestedNameSpecifier() const {
211 return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
212 translate(V, Instantiation, NNSDependence::Instantiation) |
213 translate(V, Dependent, NNSDependence::Dependent) |
214 translate(V, Error, NNSDependence::Error);
215 }
216
217 TemplateArgumentDependence templateArgument() const {
218 return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
219 translate(V, Instantiation, TADependence::Instantiation) |
220 translate(V, Dependent, TADependence::Dependent) |
221 translate(V, Error, TADependence::Error);
222 }
223
224 TemplateNameDependence templateName() const {
225 return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
226 translate(V, Instantiation, TNDependence::Instantiation) |
227 translate(V, Dependent, TNDependence::Dependent) |
228 translate(V, Error, TNDependence::Error);
229 }
230
231private:
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.
247inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
248 return Dependence(TA).expr();
249}
251 return Dependence(D).semantic().expr();
252}
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.
259inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) {
260 return Dependence(D).expr();
261}
263 // Type-dependent expressions are always be value-dependent, so we simply drop
264 // type dependency.
265 return D & ~ExprDependence::Type;
266}
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.
276 return Dependence(D).type();
277}
278inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) {
279 return Dependence(D).type();
280}
281inline TypeDependence toTypeDependence(TemplateNameDependence D) {
282 return Dependence(D).type();
283}
284inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
285 return Dependence(D).type();
286}
287
289 return Dependence(D).syntactic().type();
290}
292 return Dependence(D).semantic().type();
293}
294
295inline NestedNameSpecifierDependence
298}
299
300inline TemplateArgumentDependence
302 return Dependence(D).templateArgument();
303}
304inline TemplateArgumentDependence
305toTemplateArgumentDependence(TemplateNameDependence D) {
306 return Dependence(D).templateArgument();
307}
308inline TemplateArgumentDependence
310 return Dependence(D).templateArgument();
311}
312
313inline TemplateNameDependence
314toTemplateNameDependence(NestedNameSpecifierDependence D) {
315 return Dependence(D).templateName();
316}
317
319
320} // namespace clang
321#endif
Provides LLVM's BitmaskEnum facility to enumeration types declared in namespace clang.
#define LLVM_COMMON_DEPENDENCE(NAME)
Dependence(TemplateNameDependence D)
Dependence(ExprDependence D)
TemplateArgumentDependence templateArgument() const
Dependence syntactic()
Extract only the syntactic portions of this type's dependence.
TypeDependence type() const
Dependence(NestedNameSpecifierDependence D)
Dependence(TemplateArgumentDependence D)
NestedNameSpecifierDependence nestedNameSpecifier() const
TemplateNameDependence templateName() const
Dependence(TypeDependence D)
ExprDependence expr() const
Dependence semantic()
Extract the semantic portions of this type's dependence that apply even to uses where the type does n...
The base class of the type hierarchy.
Definition: Type.h:1607
The JSON file list parser is used to communicate input to InstallAPI.
ExprDependence toExprDependence(TemplateArgumentDependence TA)
Computes dependencies of a reference with the name having template arguments with TA dependencies.
ExprDependence turnTypeToValueDependence(ExprDependence D)
ExprDependence toExprDependenceAsWritten(TypeDependence D)
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
TypeDependence toTypeDependence(ExprDependence D)
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
ExprDependence turnValueToTypeDependence(ExprDependence D)
@ Result
The result type of a method or function.
ExprDependence toExprDependenceForImpliedType(TypeDependence D)
const FunctionProtoType * T
NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D)
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
TypeDependence toSemanticDependence(TypeDependence D)
TypeDependence toSyntacticDependence(TypeDependence D)
@ Dependent
Whether this type.
@ VariablyModified
Whether this type is a variably-modified type (C99 6.7.5).
@ Error
Whether this type references an error, e.g.
@ UnexpandedPack
Whether this type contains an unexpanded parameter pack (for C++11 variadic templates)
@ Instantiation
Whether this type somehow involves.