clang  12.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 
44 
45  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
46  };
47 };
49 
51  enum TypeDependence : uint8_t {
52  /// Whether this type contains an unexpanded parameter pack
53  /// (for C++11 variadic templates)
55  /// Whether this type somehow involves
56  /// - a template parameter, even if the resolution of the type does not
57  /// depend on a template parameter.
58  /// - or an error.
60  /// Whether this type
61  /// - is a dependent type (C++ [temp.dep.type])
62  /// - or it somehow involves an error, e.g. decltype(recovery-expr)
63  Dependent = 4,
64  /// Whether this type is a variably-modified type (C99 6.7.5).
65  VariablyModified = 8,
66 
67  /// Whether this type references an error, e.g. decltype(err-expression)
68  /// yields an error type.
69  Error = 16,
70 
71  None = 0,
72  All = 31,
73 
74  DependentInstantiation = Dependent | Instantiation,
75 
76  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
77  };
78 };
80 
81 #define LLVM_COMMON_DEPENDENCE(NAME) \
82  struct NAME##Scope { \
83  enum NAME : uint8_t { \
84  UnexpandedPack = 1, \
85  Instantiation = 2, \
86  Dependent = 4, \
87  Error = 8, \
88  \
89  None = 0, \
90  DependentInstantiation = Dependent | Instantiation, \
91  All = 15, \
92  \
93  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \
94  }; \
95  }; \
96  using NAME = NAME##Scope::NAME;
97 
98 LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence)
99 LLVM_COMMON_DEPENDENCE(TemplateNameDependence)
100 LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence)
101 #undef LLVM_COMMON_DEPENDENCE
102 
103 // A combined space of all dependence concepts for all node types.
104 // Used when aggregating dependence of nodes of different types.
105 class Dependence {
106 public:
107  enum Bits : uint8_t {
108  None = 0,
109 
110  // Contains a template parameter pack that wasn't expanded.
112  // Depends on a template parameter or an error in some way.
113  // Validity depends on how the template is instantiated or the error is
114  // resolved.
116  // Expression type depends on template context, or an error.
117  // Value and Instantiation should also be set.
118  Type = 4,
119  // Expression value depends on template context, or an error.
120  // Instantiation should also be set.
121  Value = 8,
122  // Depends on template context, or an error.
123  // The type/value distinction is only meaningful for expressions.
124  Dependent = Type | Value,
125  // Includes an error, and depends on how it is resolved.
126  Error = 16,
127  // Type depends on a runtime value (variable-length array).
128  VariablyModified = 32,
129 
130  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
131  };
132 
133  Dependence() : V(None) {}
134 
136  : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
137  translate(D, TypeDependence::Instantiation, Instantiation) |
138  translate(D, TypeDependence::Dependent, Dependent) |
139  translate(D, TypeDependence::Error, Error) |
140  translate(D, TypeDependence::VariablyModified, VariablyModified)) {}
141 
143  : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
144  translate(D, ExprDependence::Instantiation, Instantiation) |
145  translate(D, ExprDependence::Type, Type) |
146  translate(D, ExprDependence::Value, Value) |
147  translate(D, ExprDependence::Error, Error)) {}
148 
149  Dependence(NestedNameSpecifierDependence D) :
150  V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
151  translate(D, NNSDependence::Instantiation, Instantiation) |
152  translate(D, NNSDependence::Dependent, Dependent) |
153  translate(D, NNSDependence::Error, Error)) {}
154 
155  Dependence(TemplateArgumentDependence D)
156  : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
157  translate(D, TADependence::Instantiation, Instantiation) |
158  translate(D, TADependence::Dependent, Dependent) |
159  translate(D, TADependence::Error, Error)) {}
160 
161  Dependence(TemplateNameDependence D)
162  : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
163  translate(D, TNDependence::Instantiation, Instantiation) |
164  translate(D, TNDependence::Dependent, Dependent) |
165  translate(D, TNDependence::Error, Error)) {}
166 
168  return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
169  translate(V, Instantiation, TypeDependence::Instantiation) |
170  translate(V, Dependent, TypeDependence::Dependent) |
171  translate(V, Error, TypeDependence::Error) |
172  translate(V, VariablyModified, TypeDependence::VariablyModified);
173  }
174 
176  return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) |
177  translate(V, Instantiation, ExprDependence::Instantiation) |
178  translate(V, Type, ExprDependence::Type) |
179  translate(V, Value, ExprDependence::Value) |
180  translate(V, Error, ExprDependence::Error);
181  }
182 
183  NestedNameSpecifierDependence nestedNameSpecifier() const {
184  return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
185  translate(V, Instantiation, NNSDependence::Instantiation) |
186  translate(V, Dependent, NNSDependence::Dependent) |
187  translate(V, Error, NNSDependence::Error);
188  }
189 
190  TemplateArgumentDependence templateArgument() const {
191  return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
192  translate(V, Instantiation, TADependence::Instantiation) |
193  translate(V, Dependent, TADependence::Dependent) |
194  translate(V, Error, TADependence::Error);
195  }
196 
197  TemplateNameDependence templateName() const {
198  return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
199  translate(V, Instantiation, TNDependence::Instantiation) |
200  translate(V, Dependent, TNDependence::Dependent) |
201  translate(V, Error, TNDependence::Error);
202  }
203 
204 private:
205  Bits V;
206 
207  template <typename T, typename U>
208  static U translate(T Bits, T FromBit, U ToBit) {
209  return (Bits & FromBit) ? ToBit : static_cast<U>(0);
210  }
211 
212  // Abbreviations to make conversions more readable.
213  using NNSDependence = NestedNameSpecifierDependence;
214  using TADependence = TemplateArgumentDependence;
215  using TNDependence = TemplateNameDependence;
216 };
217 
218 /// Computes dependencies of a reference with the name having template arguments
219 /// with \p TA dependencies.
220 inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
221  return Dependence(TA).expr();
222 }
224  return Dependence(D).expr();
225 }
226 // Note: it's often necessary to strip `Dependent` from qualifiers.
227 // If V<T>:: refers to the current instantiation, NNS is considered dependent
228 // but the containing V<T>::foo likely isn't.
229 inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) {
230  return Dependence(D).expr();
231 }
233  // Type-dependent expressions are always be value-dependent, so we simply drop
234  // type dependency.
235  return D & ~ExprDependence::Type;
236 }
238  // Type-dependent expressions are always be value-dependent.
239  if (D & ExprDependence::Value)
241  return D;
242 }
243 
244 // Returned type-dependence will never have VariablyModified set.
246  return Dependence(D).type();
247 }
248 inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) {
249  return Dependence(D).type();
250 }
251 inline TypeDependence toTypeDependence(TemplateNameDependence D) {
252  return Dependence(D).type();
253 }
254 inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
255  return Dependence(D).type();
256 }
257 
258 inline NestedNameSpecifierDependence
260  return Dependence(D).nestedNameSpecifier();
261 }
262 
263 inline TemplateArgumentDependence
265  return Dependence(D).templateArgument();
266 }
267 inline TemplateArgumentDependence
268 toTemplateArgumentDependence(TemplateNameDependence D) {
269  return Dependence(D).templateArgument();
270 }
271 inline TemplateArgumentDependence
273  return Dependence(D).templateArgument();
274 }
275 
276 inline TemplateNameDependence
277 toTemplateNameDependence(NestedNameSpecifierDependence D) {
278  return Dependence(D).templateName();
279 }
280 
282 
283 } // namespace clang
284 #endif
TypeDependence toTypeDependence(ExprDependence D)
The base class of the type hierarchy.
Definition: Type.h:1472
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
MatchType Type
ExprDependence toExprDependence(TemplateArgumentDependence TA)
Computes dependencies of a reference with the name having template arguments with TA dependencies...
TemplateArgumentDependence templateArgument() const
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
#define LLVM_COMMON_DEPENDENCE(NAME)
#define V(N, I)
Definition: ASTContext.h:2899
ExprDependence expr() const
Provides LLVM&#39;s BitmaskEnum facility to enumeration types declared in namespace clang.
ExprDependence turnValueToTypeDependence(ExprDependence D)
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
TemplateNameDependence templateName() const
NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D)
Dependence(TemplateArgumentDependence D)
Dependence(TemplateNameDependence D)
Dataflow Directional Tag Classes.
NestedNameSpecifierDependence nestedNameSpecifier() const
Dependence(ExprDependence D)
Dependence(NestedNameSpecifierDependence D)
Dependence(TypeDependence D)
TypeDependence type() const
ExprDependence turnTypeToValueDependence(ExprDependence D)