clang 20.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
143 };
144
145 Dependence() : V(None) {}
146
150 translate(D, TypeDependence::Dependent, Dependent) |
151 translate(D, TypeDependence::Error, Error) |
153
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 (