clang  15.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 
15 namespace 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)
64  Dependent = 4,
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 
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.
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.
141 
142  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
143  };
144 
145  Dependence() : V(None) {}
146 
148  : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
149  translate(D, TypeDependence::Instantiation, Instantiation) |
150  translate(D, TypeDependence::Dependent, Dependent) |
151  translate(D, TypeDependence::Error, Error) |
153 
155  : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
156  translate(D, ExprDependence::Instantiation, Instantiation) |
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 
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 }
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.
259 inline 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)
271  return D;
272 }
273 
274 // Returned type-dependence will never have VariablyModified set.
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 
289  return Dependence(D).syntactic().type();
290 }
292  return Dependence(D).semantic().type();
293 }
294 
295 inline NestedNameSpecifierDependence
297  return Dependence(D).nestedNameSpecifier();
298 }
299 
300 inline TemplateArgumentDependence
302  return Dependence(D).templateArgument();
303 }
304 inline TemplateArgumentDependence
305 toTemplateArgumentDependence(TemplateNameDependence D) {
306  return Dependence(D).templateArgument();
307 }
308 inline TemplateArgumentDependence
310  return Dependence(D).templateArgument();
311 }
312 
313 inline TemplateNameDependence
314 toTemplateNameDependence(NestedNameSpecifierDependence D) {
315  return Dependence(D).templateName();
316 }
317 
319 
320 } // namespace clang
321 #endif
clang::Dependence::Dependence
Dependence(ExprDependence D)
Definition: DependenceFlags.h:154
clang::LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
clang::ExprDependenceScope::ErrorDependent
@ ErrorDependent
Definition: DependenceFlags.h:44
clang::ExprDependenceScope
Definition: DependenceFlags.h:16
clang::toSemanticDependence
TypeDependence toSemanticDependence(TypeDependence D)
Definition: DependenceFlags.h:291
Error
llvm::Error Error
Definition: ByteCodeEmitter.cpp:20
clang::Dependence::Dependence
Dependence(NestedNameSpecifierDependence D)
Definition: DependenceFlags.h:161
clang::ExprDependenceScope::UnexpandedPack
@ UnexpandedPack
Definition: DependenceFlags.h:18
clang::Dependence::Dependent
@ Dependent
Definition: DependenceFlags.h:125
LLVM_COMMON_DEPENDENCE
#define LLVM_COMMON_DEPENDENCE(NAME)
Definition: DependenceFlags.h:82
clang::ExprDependenceScope::Error
@ Error
Definition: DependenceFlags.h:35
clang::toTemplateNameDependence
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
Definition: DependenceFlags.h:314
clang::Dependence::Value
@ Value
Definition: DependenceFlags.h:122
clang::TypeDependenceScope::TypeDependence
TypeDependence
Definition: DependenceFlags.h:52
clang::toExprDependence
ExprDependence toExprDependence(TemplateArgumentDependence TA)
Computes dependencies of a reference with the name having template arguments with TA dependencies.
Definition: DependenceFlags.h:247
clang::Dependence::VariablyModified
@ VariablyModified
Definition: DependenceFlags.h:129
clang::ExprDependenceScope::ExprDependence
ExprDependence
Definition: DependenceFlags.h:17
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1556
clang::toTemplateArgumentDependence
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
Definition: DependenceFlags.h:301
U
clang::Dependence::UnexpandedPack
@ UnexpandedPack
Definition: DependenceFlags.h:112
clang::TypeDependenceScope::UnexpandedPack
@ UnexpandedPack
Whether this type contains an unexpanded parameter pack (for C++11 variadic templates)
Definition: DependenceFlags.h:55
clang::toSyntacticDependence
TypeDependence toSyntacticDependence(TypeDependence D)
Definition: DependenceFlags.h:288
clang::TypeDependenceScope::None
@ None
Definition: DependenceFlags.h:72
clang::ExprDependenceScope::Value
@ Value
Definition: DependenceFlags.h:31
clang::Dependence::templateArgument
TemplateArgumentDependence templateArgument() const
Definition: DependenceFlags.h:217
clang::toNestedNameSpecifierDependendence
NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D)
Definition: DependenceFlags.h:296
clang::Dependence::Bits
Bits
Definition: DependenceFlags.h:108
clang::TypeDependenceScope::VariablyModified
@ VariablyModified
Whether this type is a variably-modified type (C99 6.7.5).
Definition: DependenceFlags.h:66
clang::Dependence::None
@ None
Definition: DependenceFlags.h:109
clang::Dependence::Error
@ Error
Definition: DependenceFlags.h:127
clang::Dependence::Dependence
Dependence(TemplateArgumentDependence D)
Definition: DependenceFlags.h:167
clang::turnTypeToValueDependence
ExprDependence turnTypeToValueDependence(ExprDependence D)
Definition: DependenceFlags.h:262
clang::ExprDependenceScope::TypeValue
@ TypeValue
Definition: DependenceFlags.h:40
clang::Dependence::Instantiation
@ Instantiation
Definition: DependenceFlags.h:116
clang::TypeDependenceScope::Error
@ Error
Whether this type references an error, e.g.
Definition: DependenceFlags.h:70
clang::TypeDependenceScope
Definition: DependenceFlags.h:51
clang::toTypeDependence
TypeDependence toTypeDependence(ExprDependence D)
Definition: DependenceFlags.h:275
clang::Dependence::Syntactic
@ Syntactic
Definition: DependenceFlags.h:132
clang::TypeDependenceScope::DependentInstantiation
@ DependentInstantiation
Definition: DependenceFlags.h:75
clang::ExprDependenceScope::TypeInstantiation
@ TypeInstantiation
Definition: DependenceFlags.h:41
clang::Dependence::syntactic
Dependence syntactic()
Extract only the syntactic portions of this type's dependence.
Definition: DependenceFlags.h:180
clang::Dependence::expr
ExprDependence expr() const
Definition: DependenceFlags.h:202
Value
Value
Definition: UninitializedValues.cpp:102
clang::toExprDependenceForImpliedType
ExprDependence toExprDependenceForImpliedType(TypeDependence D)
Definition: DependenceFlags.h:250
clang::ExprDependenceScope::None
@ None
Definition: DependenceFlags.h:37
BitmaskEnum.h
clang::ExprDependenceScope::All
@ All
Definition: DependenceFlags.h:38
clang::Dependence::nestedNameSpecifier
NestedNameSpecifierDependence nestedNameSpecifier() const
Definition: DependenceFlags.h:210
clang::turnValueToTypeDependence
ExprDependence turnValueToTypeDependence(ExprDependence D)
Definition: DependenceFlags.h:267
clang::Dependence::Dependence
Dependence()
Definition: DependenceFlags.h:145
clang
Definition: CalledOnceCheck.h:17
clang::Dependence::Semantic
@ Semantic
Definition: DependenceFlags.h:139
clang::TypeDependenceScope::All
@ All
Definition: DependenceFlags.h:73
clang::Dependence
Definition: DependenceFlags.h:106
clang::Dependence::Dependence
Dependence(TypeDependence D)
Definition: DependenceFlags.h:147
clang::Dependence::semantic
Dependence semantic()
Extract the semantic portions of this type's dependence that apply even to uses where the type does n...
Definition: DependenceFlags.h:188
clang::Dependence::type
TypeDependence type() const
Definition: DependenceFlags.h:194
clang::ExprDependenceScope::Instantiation
@ Instantiation
Definition: DependenceFlags.h:27
clang::Dependence::templateName
TemplateNameDependence templateName() const
Definition: DependenceFlags.h:224
clang::ExprDependenceScope::ValueInstantiation
@ ValueInstantiation
Definition: DependenceFlags.h:42
clang::Dependence::Dependence
Dependence(TemplateNameDependence D)
Definition: DependenceFlags.h:173
clang::TypeDependenceScope::Instantiation
@ Instantiation
Whether this type somehow involves.
Definition: DependenceFlags.h:60
clang::toExprDependenceAsWritten
ExprDependence toExprDependenceAsWritten(TypeDependence D)
Definition: DependenceFlags.h:253
clang::TypeDependenceScope::Dependent
@ Dependent
Whether this type.
Definition: DependenceFlags.h:64
clang::ExprDependenceScope::TypeValueInstantiation
@ TypeValueInstantiation
Definition: DependenceFlags.h:43
Type
MatchType Type
Definition: ASTMatchFinder.cpp:71