clang  16.0.0git
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/DeclCXX.h"
22 #include "clang/AST/TemplateBase.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/LLVM.h"
25 #include "llvm/ADT/DenseMapInfo.h"
26 #include "llvm/Support/AlignOf.h"
27 
28 namespace llvm {
29 class raw_ostream;
30 } // namespace llvm
31 
32 namespace clang {
33 
34 struct PrintingPolicy;
35 
36 /// Defines how we descend a level in the AST when we pass
37 /// through expressions.
39  /// Will traverse all child nodes.
41 
42  /// Ignore AST nodes not written in the source
44 };
45 
46 /// Kind identifier.
47 ///
48 /// It can be constructed from any node kind and allows for runtime type
49 /// hierarchy checks.
50 /// Use getFromNodeKind<T>() to construct them.
51 class ASTNodeKind {
52 public:
53  /// Empty identifier. It matches nothing.
54  ASTNodeKind() : KindId(NKI_None) {}
55 
56  /// Construct an identifier for T.
57  template <class T>
60  }
61 
62  /// \{
63  /// Construct an identifier for the dynamic type of the node
64  static ASTNodeKind getFromNode(const Decl &D);
65  static ASTNodeKind getFromNode(const Stmt &S);
66  static ASTNodeKind getFromNode(const Type &T);
67  static ASTNodeKind getFromNode(const TypeLoc &T);
68  static ASTNodeKind getFromNode(const LambdaCapture &L);
69  static ASTNodeKind getFromNode(const OMPClause &C);
70  static ASTNodeKind getFromNode(const Attr &A);
71  /// \}
72 
73  /// Returns \c true if \c this and \c Other represent the same kind.
74  bool isSame(ASTNodeKind Other) const {
75  return KindId != NKI_None && KindId == Other.KindId;
76  }
77 
78  /// Returns \c true only for the default \c ASTNodeKind()
79  bool isNone() const { return KindId == NKI_None; }
80 
81  /// Returns \c true if \c this is a base kind of (or same as) \c Other.
82  /// \param Distance If non-null, used to return the distance between \c this
83  /// and \c Other in the class hierarchy.
84  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
85 
86  /// String representation of the kind.
87  StringRef asStringRef() const;
88 
89  /// Strict weak ordering for ASTNodeKind.
90  bool operator<(const ASTNodeKind &Other) const {
91  return KindId < Other.KindId;
92  }
93 
94  /// Return the most derived type between \p Kind1 and \p Kind2.
95  ///
96  /// Return ASTNodeKind() if they are not related.
98 
99  /// Return the most derived common ancestor between Kind1 and Kind2.
100  ///
101  /// Return ASTNodeKind() if they are not related.
103  ASTNodeKind Kind2);
104 
105  ASTNodeKind getCladeKind() const;
106 
107  /// Hooks for using ASTNodeKind as a key in a DenseMap.
108  struct DenseMapInfo {
109  // ASTNodeKind() is a good empty key because it is represented as a 0.
110  static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
111  // NKI_NumberOfKinds is not a valid value, so it is good for a
112  // tombstone key.
113  static inline ASTNodeKind getTombstoneKey() {
114  return ASTNodeKind(NKI_NumberOfKinds);
115  }
116  static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
117  static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
118  return LHS.KindId == RHS.KindId;
119  }
120  };
121 
122  /// Check if the given ASTNodeKind identifies a type that offers pointer
123  /// identity. This is useful for the fast path in DynTypedNode.
124  bool hasPointerIdentity() const {
125  return KindId > NKI_LastKindWithoutPointerIdentity;
126  }
127 
128 private:
129  /// Kind ids.
130  ///
131  /// Includes all possible base and derived kinds.
132  enum NodeKindId {
133  NKI_None,
134  NKI_TemplateArgument,
135  NKI_TemplateArgumentLoc,
136  NKI_LambdaCapture,
137  NKI_TemplateName,
138  NKI_NestedNameSpecifierLoc,
139  NKI_QualType,
140 #define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
141 #include "clang/AST/TypeLocNodes.def"
142  NKI_TypeLoc,
143  NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
144  NKI_CXXBaseSpecifier,
145  NKI_CXXCtorInitializer,
146  NKI_NestedNameSpecifier,
147  NKI_Decl,
148 #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
149 #include "clang/AST/DeclNodes.inc"
150  NKI_Stmt,
151 #define STMT(DERIVED, BASE) NKI_##DERIVED,
152 #include "clang/AST/StmtNodes.inc"
153  NKI_Type,
154 #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
155 #include "clang/AST/TypeNodes.inc"
156  NKI_OMPClause,
157 #define GEN_CLANG_CLAUSE_CLASS
158 #define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
159 #include "llvm/Frontend/OpenMP/OMP.inc"
160  NKI_Attr,
161 #define ATTR(A) NKI_##A##Attr,
162 #include "clang/Basic/AttrList.inc"
163  NKI_ObjCProtocolLoc,
164  NKI_NumberOfKinds
165  };
166 
167  /// Use getFromNodeKind<T>() to construct the kind.
168  ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
169 
170  /// Returns \c true if \c Base is a base kind of (or same as) \c
171  /// Derived.
172  /// \param Distance If non-null, used to return the distance between \c Base
173  /// and \c Derived in the class hierarchy.
174  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
175 
176  /// Helper meta-function to convert a kind T to its enum value.
177  ///
178  /// This struct is specialized below for all known kinds.
179  template <class T> struct KindToKindId {
180  static const NodeKindId Id = NKI_None;
181  };
182  template <class T>
183  struct KindToKindId<const T> : KindToKindId<T> {};
184 
185  /// Per kind info.
186  struct KindInfo {
187  /// The id of the parent kind, or None if it has no parent.
188  NodeKindId ParentId;
189  /// Name of the kind.
190  const char *Name;
191  };
192  static const KindInfo AllKindInfo[NKI_NumberOfKinds];
193 
194  NodeKindId KindId;
195 };
196 
197 #define KIND_TO_KIND_ID(Class) \
198  template <> struct ASTNodeKind::KindToKindId<Class> { \
199  static const NodeKindId Id = NKI_##Class; \
200  };
201 KIND_TO_KIND_ID(CXXCtorInitializer)
202 KIND_TO_KIND_ID(TemplateArgument)
203 KIND_TO_KIND_ID(TemplateArgumentLoc)
204 KIND_TO_KIND_ID(LambdaCapture)
205 KIND_TO_KIND_ID(TemplateName)
206 KIND_TO_KIND_ID(NestedNameSpecifier)
207 KIND_TO_KIND_ID(NestedNameSpecifierLoc)
208 KIND_TO_KIND_ID(QualType)
209 #define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
210 #include "clang/AST/TypeLocNodes.def"
211 KIND_TO_KIND_ID(TypeLoc)
212 KIND_TO_KIND_ID(Decl)
213 KIND_TO_KIND_ID(Stmt)
214 KIND_TO_KIND_ID(Type)
215 KIND_TO_KIND_ID(OMPClause)
216 KIND_TO_KIND_ID(Attr)
217 KIND_TO_KIND_ID(ObjCProtocolLoc)
218 KIND_TO_KIND_ID(CXXBaseSpecifier)
219 #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
220 #include "clang/AST/DeclNodes.inc"
221 #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
222 #include "clang/AST/StmtNodes.inc"
223 #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
224 #include "clang/AST/TypeNodes.inc"
225 #define GEN_CLANG_CLAUSE_CLASS
226 #define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
227 #include "llvm/Frontend/OpenMP/OMP.inc"
228 #define ATTR(A) KIND_TO_KIND_ID(A##Attr)
229 #include "clang/Basic/AttrList.inc"
230 #undef KIND_TO_KIND_ID
231 
232 inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
233  OS << K.asStringRef();
234  return OS;
235 }
236 
237 /// A dynamically typed AST node container.
238 ///
239 /// Stores an AST node in a type safe way. This allows writing code that
240 /// works with different kinds of AST nodes, despite the fact that they don't
241 /// have a common base class.
242 ///
243 /// Use \c create(Node) to create a \c DynTypedNode from an AST node,
244 /// and \c get<T>() to retrieve the node as type T if the types match.
245 ///
246 /// See \c ASTNodeKind for which node base types are currently supported;
247 /// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
248 /// the supported base types.
250 public:
251  /// Creates a \c DynTypedNode from \c Node.
252  template <typename T>
253  static DynTypedNode create(const T &Node) {
255  }
256 
257  /// Retrieve the stored node as type \c T.
258  ///
259  /// Returns NULL if the stored node does not have a type that is
260  /// convertible to \c T.
261  ///
262  /// For types that have identity via their pointer in the AST
263  /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
264  /// pointer points to the referenced AST node.
265  /// For other types (like \c QualType) the value is stored directly
266  /// in the \c DynTypedNode, and the returned pointer points at
267  /// the storage inside DynTypedNode. For those nodes, do not
268  /// use the pointer outside the scope of the DynTypedNode.
269  template <typename T> const T *get() const {
270  return BaseConverter<T>::get(NodeKind, &Storage);
271  }
272 
273  /// Retrieve the stored node as type \c T.
274  ///
275  /// Similar to \c get(), but asserts that the type is what we are expecting.
276  template <typename T>
277  const T &getUnchecked() const {
278  return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
279  }
280 
281  ASTNodeKind getNodeKind() const { return NodeKind; }
282 
283  /// Returns a pointer that identifies the stored AST node.
284  ///
285  /// Note that this is not supported by all AST nodes. For AST nodes
286  /// that don't have a pointer-defined identity inside the AST, this
287  /// method returns NULL.
288  const void *getMemoizationData() const {
289  return NodeKind.hasPointerIdentity()
290  ? *reinterpret_cast<void *const *>(&Storage)
291  : nullptr;
292  }
293 
294  /// Prints the node to the given output stream.
295  void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
296 
297  /// Dumps the node to the given output stream.
298  void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
299 
300  /// For nodes which represent textual entities in the source code,
301  /// return their SourceRange. For all other nodes, return SourceRange().
302  SourceRange getSourceRange() const;
303 
304  /// @{
305  /// Imposes an order on \c DynTypedNode.
306  ///
307  /// Supports comparison of nodes that support memoization.
308  /// FIXME: Implement comparison for other node types (currently
309  /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
310  bool operator<(const DynTypedNode &Other) const {
311  if (!NodeKind.isSame(Other.NodeKind))
312  return NodeKind < Other.NodeKind;
313 
314  if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
315  return getUnchecked<QualType>().getAsOpaquePtr() <
316  Other.getUnchecked<QualType>().getAsOpaquePtr();
317 
318  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
319  auto TLA = getUnchecked<TypeLoc>();
320  auto TLB = Other.getUnchecked<TypeLoc>();
321  return std::make_pair(TLA.getType().getAsOpaquePtr(),
322  TLA.getOpaqueData()) <
323  std::make_pair(TLB.getType().getAsOpaquePtr(),
324  TLB.getOpaqueData());
325  }
326 
327  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
328  NodeKind)) {
329  auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
330  auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
331  return std::make_pair(NNSLA.getNestedNameSpecifier(),
332  NNSLA.getOpaqueData()) <
333  std::make_pair(NNSLB.getNestedNameSpecifier(),
334  NNSLB.getOpaqueData());
335  }
336 
337  assert(getMemoizationData() && Other.getMemoizationData());
338  return getMemoizationData() < Other.getMemoizationData();
339  }
340  bool operator==(const DynTypedNode &Other) const {
341  // DynTypedNode::create() stores the exact kind of the node in NodeKind.
342  // If they contain the same node, their NodeKind must be the same.
343  if (!NodeKind.isSame(Other.NodeKind))
344  return false;
345 
346  // FIXME: Implement for other types.
347  if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
348  return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
349 
350  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
351  return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
352 
353  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
354  return getUnchecked<NestedNameSpecifierLoc>() ==
356 
357  assert(getMemoizationData() && Other.getMemoizationData());
358  return getMemoizationData() == Other.getMemoizationData();
359  }
360  bool operator!=(const DynTypedNode &Other) const {
361  return !operator==(Other);
362  }
363  /// @}
364 
365  /// Hooks for using DynTypedNode as a key in a DenseMap.
366  struct DenseMapInfo {
367  static inline DynTypedNode getEmptyKey() {
370  return Node;
371  }
372  static inline DynTypedNode getTombstoneKey() {
375  return Node;
376  }
377  static unsigned getHashValue(const DynTypedNode &Val) {
378  // FIXME: Add hashing support for the remaining types.
379  if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
380  auto TL = Val.getUnchecked<TypeLoc>();
381  return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
382  TL.getOpaqueData());
383  }
384 
385  if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
386  Val.NodeKind)) {
387  auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
388  return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
389  NNSL.getOpaqueData());
390  }
391 
392  assert(Val.getMemoizationData());
393  return llvm::hash_value(Val.getMemoizationData());
394  }
395  static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
398  return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
399  ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
400  (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
401  ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
402  LHS == RHS;
403  }
404  };
405 
406 private:
407  /// Takes care of converting from and to \c T.
408  template <typename T, typename EnablerT = void> struct BaseConverter;
409 
410  /// Converter that uses dyn_cast<T> from a stored BaseT*.
411  template <typename T, typename BaseT> struct DynCastPtrConverter {
412  static const T *get(ASTNodeKind NodeKind, const void *Storage) {
413  if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
414  return &getUnchecked(NodeKind, Storage);
415  return nullptr;
416  }
417  static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
418  assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
419  return *cast<T>(static_cast<const BaseT *>(
420  *reinterpret_cast<const void *const *>(Storage)));
421  }
422  static DynTypedNode create(const BaseT &Node) {
423  DynTypedNode Result;
424  Result.NodeKind = ASTNodeKind::getFromNode(Node);
425  new (&Result.Storage) const void *(&Node);
426  return Result;
427  }
428  };
429 
430  /// Converter that stores T* (by pointer).
431  template <typename T> struct PtrConverter {
432  static const T *get(ASTNodeKind NodeKind, const void *Storage) {
433  if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
434  return &getUnchecked(NodeKind, Storage);
435  return nullptr;
436  }
437  static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
438  assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
439  return *static_cast<const T *>(
440  *reinterpret_cast<const void *const *>(Storage));
441  }
442  static DynTypedNode create(const T &Node) {
443  DynTypedNode Result;
444  Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
445  new (&Result.Storage) const void *(&Node);
446  return Result;
447  }
448  };
449 
450  /// Converter that stores T (by value).
451  template <typename T> struct ValueConverter {
452  static const T *get(ASTNodeKind NodeKind, const void *Storage) {
453  if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
454  return reinterpret_cast<const T *>(Storage);
455  return nullptr;
456  }
457  static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
458  assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
459  return *reinterpret_cast<const T *>(Storage);
460  }
461  static DynTypedNode create(const T &Node) {
462  DynTypedNode Result;
463  Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
464  new (&Result.Storage) T(Node);
465  return Result;
466  }
467  };
468 
469  /// Converter that stores nodes by value. It must be possible to dynamically
470  /// cast the stored node within a type hierarchy without breaking (especially
471  /// through slicing).
472  template <typename T, typename BaseT,
473  typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
474  struct DynCastValueConverter {
475  static const T *get(ASTNodeKind NodeKind, const void *Storage) {
476  if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
477  return &getUnchecked(NodeKind, Storage);
478  return nullptr;
479  }
480  static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
481  assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
482  return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
483  }
484  static DynTypedNode create(const T &Node) {
485  DynTypedNode Result;
486  Result.NodeKind = ASTNodeKind::getFromNode(Node);
487  new (&Result.Storage) T(Node);
488  return Result;
489  }
490  };
491 
492  ASTNodeKind NodeKind;
493 
494  /// Stores the data of the node.
495  ///
496  /// Note that we can store \c Decls, \c Stmts, \c Types,
497  /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
498  /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
499  /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
500  /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
501  /// have storage or unique pointers and thus need to be stored by value.
502  llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
503  TemplateArgumentLoc, NestedNameSpecifierLoc,
504  QualType, TypeLoc, ObjCProtocolLoc>
505  Storage;
506 };
507 
508 template <typename T>
509 struct DynTypedNode::BaseConverter<
510  T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
511  : public DynCastPtrConverter<T, Decl> {};
512 
513 template <typename T>
514 struct DynTypedNode::BaseConverter<
515  T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
516  : public DynCastPtrConverter<T, Stmt> {};
517 
518 template <typename T>
519 struct DynTypedNode::BaseConverter<
520  T, std::enable_if_t<std::is_base_of<Type, T>::value>>
521  : public DynCastPtrConverter<T, Type> {};
522 
523 template <typename T>
524 struct DynTypedNode::BaseConverter<
525  T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
526  : public DynCastPtrConverter<T, OMPClause> {};
527 
528 template <typename T>
529 struct DynTypedNode::BaseConverter<
530  T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
531  : public DynCastPtrConverter<T, Attr> {};
532 
533 template <>
534 struct DynTypedNode::BaseConverter<
535  NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
536 
537 template <>
538 struct DynTypedNode::BaseConverter<
539  CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
540 
541 template <>
542 struct DynTypedNode::BaseConverter<
543  TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
544 
545 template <>
546 struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
547  : public ValueConverter<TemplateArgumentLoc> {};
548 
549 template <>
550 struct DynTypedNode::BaseConverter<LambdaCapture, void>
551  : public ValueConverter<LambdaCapture> {};
552 
553 template <>
554 struct DynTypedNode::BaseConverter<
555  TemplateName, void> : public ValueConverter<TemplateName> {};
556 
557 template <>
558 struct DynTypedNode::BaseConverter<
560  void> : public ValueConverter<NestedNameSpecifierLoc> {};
561 
562 template <>
563 struct DynTypedNode::BaseConverter<QualType,
564  void> : public ValueConverter<QualType> {};
565 
566 template <typename T>
567 struct DynTypedNode::BaseConverter<
568  T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
569  : public DynCastValueConverter<T, TypeLoc> {};
570 
571 template <>
572 struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
573  : public PtrConverter<CXXBaseSpecifier> {};
574 
575 template <>
576 struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
577  : public ValueConverter<ObjCProtocolLoc> {};
578 
579 // The only operation we allow on unsupported types is \c get.
580 // This allows to conveniently use \c DynTypedNode when having an arbitrary
581 // AST node that is not supported, but prevents misuse - a user cannot create
582 // a DynTypedNode from arbitrary types.
583 template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
584  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
585  return NULL;
586  }
587 };
588 
589 } // end namespace clang
590 
591 namespace llvm {
592 
593 template <>
594 struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
595 
596 template <>
598 
599 } // end namespace llvm
600 
601 #endif
clang::DynTypedNode::getUnchecked
const T & getUnchecked() const
Retrieve the stored node as type T.
Definition: ASTTypeTraits.h:277
clang::TraversalKind
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
Definition: ASTTypeTraits.h:38
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::ASTNodeKind::isBaseOf
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
Definition: ASTTypeTraits.cpp:59
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::LambdaCapture
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
clang::DynTypedNode::DenseMapInfo::getHashValue
static unsigned getHashValue(const DynTypedNode &Val)
Definition: ASTTypeTraits.h:377
clang::DynTypedNode::dump
void dump(llvm::raw_ostream &OS, const ASTContext &Context) const
Dumps the node to the given output stream.
Definition: ASTTypeTraits.cpp:204
clang::ASTNodeKind::getMostDerivedCommonAncestor
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
Definition: ASTTypeTraits.cpp:96
clang::DynTypedNode::operator<
bool operator<(const DynTypedNode &Other) const
Definition: ASTTypeTraits.h:310
NULL
#define NULL
Definition: stddef.h:89
clang::DynTypedNode::getSourceRange
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
Definition: ASTTypeTraits.cpp:216
clang::ASTNodeKind::hasPointerIdentity
bool hasPointerIdentity() const
Check if the given ASTNodeKind identifies a type that offers pointer identity.
Definition: ASTTypeTraits.h:124
clang::ASTNodeKind::DenseMapInfo::getHashValue
static unsigned getHashValue(const ASTNodeKind &Val)
Definition: ASTTypeTraits.h:116
clang::DynTypedNode::DenseMapInfo::getTombstoneKey
static DynTypedNode getTombstoneKey()
Definition: ASTTypeTraits.h:372
clang::DynTypedNode::create
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
Definition: ASTTypeTraits.h:253
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::NestedNameSpecifier
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Definition: NestedNameSpecifier.h:50
clang::DynTypedNode::DenseMapInfo::isEqual
static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS)
Definition: ASTTypeTraits.h:395
DeclCXX.h
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::DynTypedNode::getMemoizationData
const void * getMemoizationData() const
Returns a pointer that identifies the stored AST node.
Definition: ASTTypeTraits.h:288
ASTFwd.h
clang::ASTNodeKind::ASTNodeKind
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:54
clang::DynTypedNode::getNodeKind
ASTNodeKind getNodeKind() const
Definition: ASTTypeTraits.h:281
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
clang::hash_value
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
Definition: Sanitizers.cpp:68
TemplateBase.h
Node
DynTypedNode Node
Definition: ASTMatchFinder.cpp:68
clang::OMPClause
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
Id
int Id
Definition: ASTDiff.cpp:191
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:209
NestedNameSpecifier.h
clang::DynTypedNode::operator!=
bool operator!=(const DynTypedNode &Other) const
Definition: ASTTypeTraits.h:360
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::TemplateArgumentLoc
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:457
clang::diff::DynTypedNode
DynTypedNode DynTypedNode
Definition: ASTDiffInternal.h:18
clang::ASTNodeKind::isNone
bool isNone() const
Returns true only for the default ASTNodeKind()
Definition: ASTTypeTraits.h:79
KIND_TO_KIND_ID
#define KIND_TO_KIND_ID(Class)
Definition: ASTTypeTraits.h:197
clang::NestedNameSpecifierLoc
A C++ nested-name-specifier augmented with source location information.
Definition: NestedNameSpecifier.h:243
Base
clang::operator<<
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
Definition: ASTContext.cpp:13355
clang::ASTNodeKind::DenseMapInfo::getEmptyKey
static ASTNodeKind getEmptyKey()
Definition: ASTTypeTraits.h:110
clang::DynTypedNode::DenseMapInfo
Hooks for using DynTypedNode as a key in a DenseMap.
Definition: ASTTypeTraits.h:366
clang::format::hash_combine
static void hash_combine(std::size_t &seed, const T &v)
Definition: UnwrappedLineParser.cpp:770
clang::ASTNodeKind::operator<
bool operator<(const ASTNodeKind &Other) const
Strict weak ordering for ASTNodeKind.
Definition: ASTTypeTraits.h:90
clang::serialized_diags::create
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Definition: SerializedDiagnosticPrinter.cpp:301
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:192
clang::TK_AsIs
@ TK_AsIs
Will traverse all child nodes.
Definition: ASTTypeTraits.h:40
clang::DynTypedNode::print
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
Definition: ASTTypeTraits.cpp:171
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::TypeLoc
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
LLVM.h
clang::TK_IgnoreUnlessSpelledInSource
@ TK_IgnoreUnlessSpelledInSource
Ignore AST nodes not written in the source.
Definition: ASTTypeTraits.h:43
std
Definition: Format.h:4321
clang::ASTNodeKind
Kind identifier.
Definition: ASTTypeTraits.h:51
clang::DynTypedNode::operator==
bool operator==(const DynTypedNode &Other) const
Definition: ASTTypeTraits.h:340
clang
Definition: CalledOnceCheck.h:17
clang::syntax::NodeKind
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:32
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:70
clang::ASTNodeKind::getFromNodeKind
static ASTNodeKind getFromNodeKind()
Construct an identifier for T.
Definition: ASTTypeTraits.h:58
clang::CXXBaseSpecifier
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
clang::Attr
Attr - This represents one attribute.
Definition: Attr.h:40
clang::DynTypedNode::get
const T * get() const
Retrieve the stored node as type T.
Definition: ASTTypeTraits.h:269
LambdaCapture.h
clang::DynTypedNode
A dynamically typed AST node container.
Definition: ASTTypeTraits.h:249
clang::ASTNodeKind::isSame
bool isSame(ASTNodeKind Other) const
Returns true if this and Other represent the same kind.
Definition: ASTTypeTraits.h:74
clang::DynTypedNode::DenseMapInfo::getEmptyKey
static DynTypedNode getEmptyKey()
Definition: ASTTypeTraits.h:367
clang::ASTNodeKind::getMostDerivedType
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
Definition: ASTTypeTraits.cpp:89
clang::CXXCtorInitializer
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2207
clang::ASTNodeKind::DenseMapInfo
Hooks for using ASTNodeKind as a key in a DenseMap.
Definition: ASTTypeTraits.h:108
clang::ASTNodeKind::getCladeKind
ASTNodeKind getCladeKind() const
Definition: ASTTypeTraits.cpp:76
clang::ASTNodeKind::DenseMapInfo::getTombstoneKey
static ASTNodeKind getTombstoneKey()
Definition: ASTTypeTraits.h:113
clang::ObjCProtocolLoc
Definition: TypeLoc.h:2656
clang::ASTNodeKind::asStringRef
StringRef asStringRef() const
String representation of the kind.
Definition: ASTTypeTraits.cpp:87
clang::ASTNodeKind::getFromNode
static ASTNodeKind getFromNode(const Decl &D)
Definition: ASTTypeTraits.cpp:105
TypeLoc.h
clang::ASTNodeKind::DenseMapInfo::isEqual
static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS)
Definition: ASTTypeTraits.h:117