clang  9.0.0svn
ASTTypeTraits.h
Go to the documentation of this file.
1 //===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
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 //
9 // Provides a dynamic type identifier and a dynamically typed node container
10 // that can be used to store an AST base node at runtime in the same storage in
11 // a type safe way.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
16 #define LLVM_CLANG_AST_ASTTYPETRAITS_H
17 
18 #include "clang/AST/ASTFwd.h"
19 #include "clang/AST/Decl.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/Stmt.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/AST/TypeLoc.h"
25 #include "clang/Basic/LLVM.h"
26 #include "llvm/ADT/DenseMapInfo.h"
27 #include "llvm/Support/AlignOf.h"
28 
29 namespace llvm {
30 
31 class raw_ostream;
32 
33 }
34 
35 namespace clang {
36 
37 struct PrintingPolicy;
38 
39 namespace ast_type_traits {
40 
41 /// Kind identifier.
42 ///
43 /// It can be constructed from any node kind and allows for runtime type
44 /// hierarchy checks.
45 /// Use getFromNodeKind<T>() to construct them.
46 class ASTNodeKind {
47 public:
48  /// Empty identifier. It matches nothing.
49  ASTNodeKind() : KindId(NKI_None) {}
50 
51  /// Construct an identifier for T.
52  template <class T>
55  }
56 
57  /// \{
58  /// Construct an identifier for the dynamic type of the node
59  static ASTNodeKind getFromNode(const Decl &D);
60  static ASTNodeKind getFromNode(const Stmt &S);
61  static ASTNodeKind getFromNode(const Type &T);
62  static ASTNodeKind getFromNode(const OMPClause &C);
63  /// \}
64 
65  /// Returns \c true if \c this and \c Other represent the same kind.
66  bool isSame(ASTNodeKind Other) const {
67  return KindId != NKI_None && KindId == Other.KindId;
68  }
69 
70  /// Returns \c true only for the default \c ASTNodeKind()
71  bool isNone() const { return KindId == NKI_None; }
72 
73  /// Returns \c true if \c this is a base kind of (or same as) \c Other.
74  /// \param Distance If non-null, used to return the distance between \c this
75  /// and \c Other in the class hierarchy.
76  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
77 
78  /// String representation of the kind.
79  StringRef asStringRef() const;
80 
81  /// Strict weak ordering for ASTNodeKind.
82  bool operator<(const ASTNodeKind &Other) const {
83  return KindId < Other.KindId;
84  }
85 
86  /// Return the most derived type between \p Kind1 and \p Kind2.
87  ///
88  /// Return ASTNodeKind() if they are not related.
89  static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
90 
91  /// Return the most derived common ancestor between Kind1 and Kind2.
92  ///
93  /// Return ASTNodeKind() if they are not related.
94  static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
95  ASTNodeKind Kind2);
96 
97  /// Hooks for using ASTNodeKind as a key in a DenseMap.
98  struct DenseMapInfo {
99  // ASTNodeKind() is a good empty key because it is represented as a 0.
100  static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
101  // NKI_NumberOfKinds is not a valid value, so it is good for a
102  // tombstone key.
103  static inline ASTNodeKind getTombstoneKey() {
104  return ASTNodeKind(NKI_NumberOfKinds);
105  }
106  static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
107  static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
108  return LHS.KindId == RHS.KindId;
109  }
110  };
111 
112  /// Check if the given ASTNodeKind identifies a type that offers pointer
113  /// identity. This is useful for the fast path in DynTypedNode.
114  bool hasPointerIdentity() const {
115  return KindId > NKI_LastKindWithoutPointerIdentity;
116  }
117 
118 private:
119  /// Kind ids.
120  ///
121  /// Includes all possible base and derived kinds.
122  enum NodeKindId {
123  NKI_None,
124  NKI_TemplateArgument,
125  NKI_TemplateName,
126  NKI_NestedNameSpecifierLoc,
127  NKI_QualType,
128  NKI_TypeLoc,
129  NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
130  NKI_CXXCtorInitializer,
131  NKI_NestedNameSpecifier,
132  NKI_Decl,
133 #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
134 #include "clang/AST/DeclNodes.inc"
135  NKI_Stmt,
136 #define STMT(DERIVED, BASE) NKI_##DERIVED,
137 #include "clang/AST/StmtNodes.inc"
138  NKI_Type,
139 #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
140 #include "clang/AST/TypeNodes.def"
141  NKI_OMPClause,
142 #define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class,
143 #include "clang/Basic/OpenMPKinds.def"
144  NKI_NumberOfKinds
145  };
146 
147  /// Use getFromNodeKind<T>() to construct the kind.
148  ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
149 
150  /// Returns \c true if \c Base is a base kind of (or same as) \c
151  /// Derived.
152  /// \param Distance If non-null, used to return the distance between \c Base
153  /// and \c Derived in the class hierarchy.
154  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
155 
156  /// Helper meta-function to convert a kind T to its enum value.
157  ///
158  /// This struct is specialized below for all known kinds.
159  template <class T> struct KindToKindId {
160  static const NodeKindId Id = NKI_None;
161  };
162  template <class T>
163  struct KindToKindId<const T> : KindToKindId<T> {};
164 
165  /// Per kind info.
166  struct KindInfo {
167  /// The id of the parent kind, or None if it has no parent.
168  NodeKindId ParentId;
169  /// Name of the kind.
170  const char *Name;
171  };
172  static const KindInfo AllKindInfo[NKI_NumberOfKinds];
173 
174  NodeKindId KindId;
175 };
176 
177 #define KIND_TO_KIND_ID(Class) \
178  template <> struct ASTNodeKind::KindToKindId<Class> { \
179  static const NodeKindId Id = NKI_##Class; \
180  };
181 KIND_TO_KIND_ID(CXXCtorInitializer)
182 KIND_TO_KIND_ID(TemplateArgument)
183 KIND_TO_KIND_ID(TemplateName)
184 KIND_TO_KIND_ID(NestedNameSpecifier)
185 KIND_TO_KIND_ID(NestedNameSpecifierLoc)
186 KIND_TO_KIND_ID(QualType)
187 KIND_TO_KIND_ID(TypeLoc)
188 KIND_TO_KIND_ID(Decl)
189 KIND_TO_KIND_ID(Stmt)
190 KIND_TO_KIND_ID(Type)
192 #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
193 #include "clang/AST/DeclNodes.inc"
194 #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
195 #include "clang/AST/StmtNodes.inc"
196 #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
197 #include "clang/AST/TypeNodes.def"
198 #define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class)
199 #include "clang/Basic/OpenMPKinds.def"
200 #undef KIND_TO_KIND_ID
201 
202 inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
203  OS << K.asStringRef();
204  return OS;
205 }
206 
207 /// A dynamically typed AST node container.
208 ///
209 /// Stores an AST node in a type safe way. This allows writing code that
210 /// works with different kinds of AST nodes, despite the fact that they don't
211 /// have a common base class.
212 ///
213 /// Use \c create(Node) to create a \c DynTypedNode from an AST node,
214 /// and \c get<T>() to retrieve the node as type T if the types match.
215 ///
216 /// See \c ASTNodeKind for which node base types are currently supported;
217 /// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
218 /// the supported base types.
220 public:
221  /// Creates a \c DynTypedNode from \c Node.
222  template <typename T>
223  static DynTypedNode create(const T &Node) {
224  return BaseConverter<T>::create(Node);
225  }
226 
227  /// Retrieve the stored node as type \c T.
228  ///
229  /// Returns NULL if the stored node does not have a type that is
230  /// convertible to \c T.
231  ///
232  /// For types that have identity via their pointer in the AST
233  /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
234  /// pointer points to the referenced AST node.
235  /// For other types (like \c QualType) the value is stored directly
236  /// in the \c DynTypedNode, and the returned pointer points at
237  /// the storage inside DynTypedNode. For those nodes, do not
238  /// use the pointer outside the scope of the DynTypedNode.
239  template <typename T>
240  const T *get() const {
241  return BaseConverter<T>::get(NodeKind, Storage.buffer);
242  }
243 
244  /// Retrieve the stored node as type \c T.
245  ///
246  /// Similar to \c get(), but asserts that the type is what we are expecting.
247  template <typename T>
248  const T &getUnchecked() const {
249  return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
250  }
251 
252  ASTNodeKind getNodeKind() const { return NodeKind; }
253 
254  /// Returns a pointer that identifies the stored AST node.
255  ///
256  /// Note that this is not supported by all AST nodes. For AST nodes
257  /// that don't have a pointer-defined identity inside the AST, this
258  /// method returns NULL.
259  const void *getMemoizationData() const {
260  return NodeKind.hasPointerIdentity()
261  ? *reinterpret_cast<void *const *>(Storage.buffer)
262  : nullptr;
263  }
264 
265  /// Prints the node to the given output stream.
266  void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
267 
268  /// Dumps the node to the given output stream.
269  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
270 
271  /// For nodes which represent textual entities in the source code,
272  /// return their SourceRange. For all other nodes, return SourceRange().
273  SourceRange getSourceRange() const;
274 
275  /// @{
276  /// Imposes an order on \c DynTypedNode.
277  ///
278  /// Supports comparison of nodes that support memoization.
279  /// FIXME: Implement comparison for other node types (currently
280  /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
281  bool operator<(const DynTypedNode &Other) const {
282  if (!NodeKind.isSame(Other.NodeKind))
283  return NodeKind < Other.NodeKind;
284 
285  if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
286  return getUnchecked<QualType>().getAsOpaquePtr() <
287  Other.getUnchecked<QualType>().getAsOpaquePtr();
288 
289  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
290  auto TLA = getUnchecked<TypeLoc>();
291  auto TLB = Other.getUnchecked<TypeLoc>();
292  return std::make_pair(TLA.getType().getAsOpaquePtr(),
293  TLA.getOpaqueData()) <
294  std::make_pair(TLB.getType().getAsOpaquePtr(),
295  TLB.getOpaqueData());
296  }
297 
298  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
299  NodeKind)) {
300  auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
301  auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
302  return std::make_pair(NNSLA.getNestedNameSpecifier(),
303  NNSLA.getOpaqueData()) <
304  std::make_pair(NNSLB.getNestedNameSpecifier(),
305  NNSLB.getOpaqueData());
306  }
307 
308  assert(getMemoizationData() && Other.getMemoizationData());
309  return getMemoizationData() < Other.getMemoizationData();
310  }
311  bool operator==(const DynTypedNode &Other) const {
312  // DynTypedNode::create() stores the exact kind of the node in NodeKind.
313  // If they contain the same node, their NodeKind must be the same.
314  if (!NodeKind.isSame(Other.NodeKind))
315  return false;
316 
317  // FIXME: Implement for other types.
318  if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
319  return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
320 
321  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
322  return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
323 
324  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
325  return getUnchecked<NestedNameSpecifierLoc>() ==
327 
328  assert(getMemoizationData() && Other.getMemoizationData());
329  return getMemoizationData() == Other.getMemoizationData();
330  }
331  bool operator!=(const DynTypedNode &Other) const {
332  return !operator==(Other);
333  }
334  /// @}
335 
336  /// Hooks for using DynTypedNode as a key in a DenseMap.
337  struct DenseMapInfo {
338  static inline DynTypedNode getEmptyKey() {
340  Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
341  return Node;
342  }
343  static inline DynTypedNode getTombstoneKey() {
345  Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey();
346  return Node;
347  }
348  static unsigned getHashValue(const DynTypedNode &Val) {
349  // FIXME: Add hashing support for the remaining types.
350  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
351  auto TL = Val.getUnchecked<TypeLoc>();
352  return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
353  TL.getOpaqueData());
354  }
355 
356  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
357  Val.NodeKind)) {
358  auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
359  return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
360  NNSL.getOpaqueData());
361  }
362 
363  assert(Val.getMemoizationData());
364  return llvm::hash_value(Val.getMemoizationData());
365  }
366  static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
367  auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
368  auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
369  return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
370  ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
371  (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
372  ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
373  LHS == RHS;
374  }
375  };
376 
377 private:
378  /// Takes care of converting from and to \c T.
379  template <typename T, typename EnablerT = void> struct BaseConverter;
380 
381  /// Converter that uses dyn_cast<T> from a stored BaseT*.
382  template <typename T, typename BaseT> struct DynCastPtrConverter {
383  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
384  if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
385  return &getUnchecked(NodeKind, Storage);
386  return nullptr;
387  }
388  static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
389  assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
390  return *cast<T>(static_cast<const BaseT *>(
391  *reinterpret_cast<const void *const *>(Storage)));
392  }
393  static DynTypedNode create(const BaseT &Node) {
394  DynTypedNode Result;
395  Result.NodeKind = ASTNodeKind::getFromNode(Node);
396  new (Result.Storage.buffer) const void *(&Node);
397  return Result;
398  }
399  };
400 
401  /// Converter that stores T* (by pointer).
402  template <typename T> struct PtrConverter {
403  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
404  if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
405  return &getUnchecked(NodeKind, Storage);
406  return nullptr;
407  }
408  static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
409  assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
410  return *static_cast<const T *>(
411  *reinterpret_cast<const void *const *>(Storage));
412  }
413  static DynTypedNode create(const T &Node) {
414  DynTypedNode Result;
415  Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
416  new (Result.Storage.buffer) const void *(&Node);
417  return Result;
418  }
419  };
420 
421  /// Converter that stores T (by value).
422  template <typename T> struct ValueConverter {
423  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
424  if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
425  return reinterpret_cast<const T *>(Storage);
426  return nullptr;
427  }
428  static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
429  assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
430  return *reinterpret_cast<const T *>(Storage);
431  }
432  static DynTypedNode create(const T &Node) {
433  DynTypedNode Result;
434  Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
435  new (Result.Storage.buffer) T(Node);
436  return Result;
437  }
438  };
439 
440  ASTNodeKind NodeKind;
441 
442  /// Stores the data of the node.
443  ///
444  /// Note that we can store \c Decls, \c Stmts, \c Types,
445  /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
446  /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
447  /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
448  /// \c TemplateArguments on the other hand do not have storage or unique
449  /// pointers and thus need to be stored by value.
450  llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
452  TypeLoc> Storage;
453 };
454 
455 template <typename T>
456 struct DynTypedNode::BaseConverter<
457  T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
458  : public DynCastPtrConverter<T, Decl> {};
459 
460 template <typename T>
461 struct DynTypedNode::BaseConverter<
462  T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
463  : public DynCastPtrConverter<T, Stmt> {};
464 
465 template <typename T>
466 struct DynTypedNode::BaseConverter<
467  T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
468  : public DynCastPtrConverter<T, Type> {};
469 
470 template <typename T>
471 struct DynTypedNode::BaseConverter<
472  T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type>
473  : public DynCastPtrConverter<T, OMPClause> {};
474 
475 template <>
476 struct DynTypedNode::BaseConverter<
477  NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
478 
479 template <>
480 struct DynTypedNode::BaseConverter<
481  CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
482 
483 template <>
484 struct DynTypedNode::BaseConverter<
485  TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
486 
487 template <>
488 struct DynTypedNode::BaseConverter<
489  TemplateName, void> : public ValueConverter<TemplateName> {};
490 
491 template <>
492 struct DynTypedNode::BaseConverter<
494  void> : public ValueConverter<NestedNameSpecifierLoc> {};
495 
496 template <>
497 struct DynTypedNode::BaseConverter<QualType,
498  void> : public ValueConverter<QualType> {};
499 
500 template <>
501 struct DynTypedNode::BaseConverter<
502  TypeLoc, void> : public ValueConverter<TypeLoc> {};
503 
504 // The only operation we allow on unsupported types is \c get.
505 // This allows to conveniently use \c DynTypedNode when having an arbitrary
506 // AST node that is not supported, but prevents misuse - a user cannot create
507 // a DynTypedNode from arbitrary types.
508 template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
509  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
510  return NULL;
511  }
512 };
513 
514 } // end namespace ast_type_traits
515 } // end namespace clang
516 
517 namespace llvm {
518 
519 template <>
520 struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
522 
523 template <>
526 
527 } // end namespace llvm
528 
529 #endif
bool operator<(const ASTNodeKind &Other) const
Strict weak ordering for ASTNodeKind.
Definition: ASTTypeTraits.h:82
A (possibly-)qualified type.
Definition: Type.h:639
bool operator==(CanQual< T > x, CanQual< U > y)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:29
Stmt - This represents one statement.
Definition: Stmt.h:65
StringRef asStringRef() const
String representation of the kind.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
bool operator==(const DynTypedNode &Other) const
The base class of the type hierarchy.
Definition: Type.h:1414
bool isSame(ASTNodeKind Other) const
Returns true if this and Other represent the same kind.
Definition: ASTTypeTraits.h:66
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
CharSourceRange getSourceRange(const SourceRange &Range)
Returns the token CharSourceRange corresponding to Range.
Definition: FixIt.h:32
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
A C++ nested-name-specifier augmented with source location information.
Definition: Format.h:2222
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:49
static void hash_combine(std::size_t &seed, const T &v)
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Forward declaration of all AST node types.
#define NULL
Definition: opencl-c.h:157
static raw_ostream & operator<<(raw_ostream &os, BindingKey K)
static unsigned getHashValue(const DynTypedNode &Val)
Hooks for using ASTNodeKind as a key in a DenseMap.
Definition: ASTTypeTraits.h:98
bool hasPointerIdentity() const
Check if the given ASTNodeKind identifies a type that offers pointer identity.
int Id
Definition: ASTDiff.cpp:190
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
Definition: Sanitizers.cpp:51
Represents a C++ template name within the type system.
Definition: TemplateName.h:178
Defines the clang::TypeLoc interface and its subclasses.
const SourceManager & SM
Definition: Format.cpp:1568
This file defines OpenMP AST classes for clauses.
#define KIND_TO_KIND_ID(Class)
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:50
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
static unsigned getHashValue(const ASTNodeKind &Val)
if(!SameAsAllPredecessors) State -> printDOT(Out, N->getLocationContext())
ast_type_traits::DynTypedNode DynTypedNode
ast_type_traits::DynTypedNode Node
Represents a template argument.
Definition: TemplateBase.h:50
Dataflow Directional Tag Classes.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Hooks for using DynTypedNode as a key in a DenseMap.
A dynamically typed AST node container.
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2263
bool isNone() const
Returns true only for the default ASTNodeKind()
Definition: ASTTypeTraits.h:71
bool operator<(const DynTypedNode &Other) const
const T & getUnchecked() const
Retrieve the stored node as type T.
bool operator!=(const DynTypedNode &Other) const
A trivial tuple used to represent a source range.
static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS)
static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS)
This class handles loading and caching of source files into memory.
const void * getMemoizationData() const
Returns a pointer that identifies the stored AST node.
static ASTNodeKind getFromNodeKind()
Construct an identifier for T.
Definition: ASTTypeTraits.h:53