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 
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.
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) |
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
MatchType Type
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:1813
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)
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.