Clang Project

clang_source_code/include/clang/AST/ASTTypeTraits.h
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"
20#include "clang/AST/NestedNameSpecifier.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
29namespace llvm {
30
31class raw_ostream;
32
33}
34
35namespace clang {
36
37struct PrintingPolicy;
38
39namespace 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.
46class ASTNodeKind {
47public:
48  /// Empty identifier. It matches nothing.
49  ASTNodeKind() : KindId(NKI_None) {}
50
51  /// Construct an identifier for T.
52  template <class T>
53  static ASTNodeKind getFromNodeKind() {
54    return ASTNodeKind(KindToKindId<T>::Id);
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 Otherconst {
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 Otherunsigned *Distance = nullptrconst;
77
78  /// String representation of the kind.
79  StringRef asStringRef() const;
80
81  /// Strict weak ordering for ASTNodeKind.
82  bool operator<(const ASTNodeKind &Otherconst {
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 Kind1ASTNodeKind 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 &LHSconst 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
118private:
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 BaseNodeKindId Derivedunsigned *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  };
181KIND_TO_KIND_ID(CXXCtorInitializer)
182KIND_TO_KIND_ID(TemplateArgument)
183KIND_TO_KIND_ID(TemplateName)
184KIND_TO_KIND_ID(NestedNameSpecifier)
185KIND_TO_KIND_ID(NestedNameSpecifierLoc)
186KIND_TO_KIND_ID(QualType)
187KIND_TO_KIND_ID(TypeLoc)
188KIND_TO_KIND_ID(Decl)
189KIND_TO_KIND_ID(Stmt)
190KIND_TO_KIND_ID(Type)
191KIND_TO_KIND_ID(OMPClause)
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
202inline raw_ostream &operator<<(raw_ostream &OSASTNodeKind 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.
219class DynTypedNode {
220public:
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 &OSconst PrintingPolicy &PPconst;
267
268  /// Dumps the node to the given output stream.
269  void dump(llvm::raw_ostream &OSSourceManager &SMconst;
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 &Otherconst {
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 &Otherconst {
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>() ==
326             Other.getUnchecked<NestedNameSpecifierLoc>();
327
328    assert(getMemoizationData() && Other.getMemoizationData());
329    return getMemoizationData() == Other.getMemoizationData();
330  }
331  bool operator!=(const DynTypedNode &Otherconst {
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() {
339      DynTypedNode Node;
340      Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
341      return Node;
342    }
343    static inline DynTypedNode getTombstoneKey() {
344      DynTypedNode Node;
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 &LHSconst DynTypedNode &RHS) {
367      auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
368      auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
369      return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKindEmpty) &&
370              ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKindEmpty)) ||
371             (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKindTombStone) &&
372              ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKindTombStone)) ||
373             LHS == RHS;
374    }
375  };
376
377private:
378  /// Takes care of converting from and to \c T.
379  template <typename T, typename EnablerT = voidstruct 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 NodeKindconst char Storage[]) {
384      if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
385        return &getUnchecked(NodeKindStorage);
386      return nullptr;
387    }
388    static const T &getUnchecked(ASTNodeKind NodeKindconst char Storage[]) {
389      ().isBaseOf(NodeKind)", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ASTTypeTraits.h", 389, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">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 NodeKindconst char Storage[]) {
404      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
405        return &getUnchecked(NodeKindStorage);
406      return nullptr;
407    }
408    static const T &getUnchecked(ASTNodeKind NodeKindconst char Storage[]) {
409      ().isSame(NodeKind)", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ASTTypeTraits.h", 409, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">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 NodeKindconst 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 NodeKindconst char Storage[]) {
429      ().isSame(NodeKind)", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ASTTypeTraits.h", 429, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">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,
451                              NestedNameSpecifierLoc, QualType,
452                              TypeLoc> Storage;
453};
454
455template <typename T>
456struct DynTypedNode::BaseConverter<
457    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
458    : public DynCastPtrConverter<T, Decl> {};
459
460template <typename T>
461struct DynTypedNode::BaseConverter<
462    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
463    : public DynCastPtrConverter<T, Stmt> {};
464
465template <typename T>
466struct DynTypedNode::BaseConverter<
467    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
468    : public DynCastPtrConverter<T, Type> {};
469
470template <typename T>
471struct DynTypedNode::BaseConverter<
472    T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type>
473    : public DynCastPtrConverter<T, OMPClause> {};
474
475template <>
476struct DynTypedNode::BaseConverter<
477    NestedNameSpecifiervoid> : public PtrConverter<NestedNameSpecifier> {};
478
479template <>
480struct DynTypedNode::BaseConverter<
481    CXXCtorInitializervoid> : public PtrConverter<CXXCtorInitializer> {};
482
483template <>
484struct DynTypedNode::BaseConverter<
485    TemplateArgumentvoid> : public ValueConverter<TemplateArgument> {};
486
487template <>
488struct DynTypedNode::BaseConverter<
489    TemplateNamevoid> : public ValueConverter<TemplateName> {};
490
491template <>
492struct DynTypedNode::BaseConverter<
493    NestedNameSpecifierLoc,
494    void> : public ValueConverter<NestedNameSpecifierLoc> {};
495
496template <>
497struct DynTypedNode::BaseConverter<QualType,
498                                   void> : public ValueConverter<QualType> {};
499
500template <>
501struct DynTypedNode::BaseConverter<
502    TypeLocvoid> : 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.
508template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
509  static const T *get(ASTNodeKind NodeKindconst char Storage[]) {
510    return NULL;
511  }
512};
513
514// end namespace ast_type_traits
515// end namespace clang
516
517namespace llvm {
518
519template <>
520struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
521    : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {};
522
523template <>
524struct DenseMapInfo<clang::ast_type_traits::DynTypedNode>
525    : clang::ast_type_traits::DynTypedNode::DenseMapInfo {};
526
527}  // end namespace llvm
528
529#endif
530
clang::ast_type_traits::ASTNodeKind::getFromNodeKind
clang::ast_type_traits::ASTNodeKind::getFromNode
clang::ast_type_traits::ASTNodeKind::getFromNode
clang::ast_type_traits::ASTNodeKind::getFromNode
clang::ast_type_traits::ASTNodeKind::getFromNode
clang::ast_type_traits::ASTNodeKind::isSame
clang::ast_type_traits::ASTNodeKind::isNone
clang::ast_type_traits::ASTNodeKind::isBaseOf
clang::ast_type_traits::ASTNodeKind::asStringRef
clang::ast_type_traits::ASTNodeKind::getMostDerivedType
clang::ast_type_traits::ASTNodeKind::getMostDerivedCommonAncestor
clang::ast_type_traits::ASTNodeKind::DenseMapInfo
clang::ast_type_traits::ASTNodeKind::DenseMapInfo::getEmptyKey
clang::ast_type_traits::ASTNodeKind::DenseMapInfo::getTombstoneKey
clang::ast_type_traits::ASTNodeKind::DenseMapInfo::getHashValue
clang::ast_type_traits::ASTNodeKind::DenseMapInfo::isEqual
clang::ast_type_traits::ASTNodeKind::hasPointerIdentity
clang::ast_type_traits::ASTNodeKind::NodeKindId
clang::ast_type_traits::ASTNodeKind::isBaseOf
clang::ast_type_traits::ASTNodeKind::KindToKindId
clang::ast_type_traits::ASTNodeKind::KindToKindId::Id
clang::ast_type_traits::ASTNodeKind::KindInfo
clang::ast_type_traits::ASTNodeKind::KindInfo::ParentId
clang::ast_type_traits::ASTNodeKind::KindInfo::Name
clang::ast_type_traits::ASTNodeKind::AllKindInfo
clang::ast_type_traits::ASTNodeKind::KindId
clang::ast_type_traits::DynTypedNode::create
clang::ast_type_traits::DynTypedNode::get
clang::ast_type_traits::DynTypedNode::getUnchecked
clang::ast_type_traits::DynTypedNode::getNodeKind
clang::ast_type_traits::DynTypedNode::getMemoizationData
clang::ast_type_traits::DynTypedNode::print
clang::ast_type_traits::DynTypedNode::dump
clang::ast_type_traits::DynTypedNode::getSourceRange
clang::ast_type_traits::DynTypedNode::DenseMapInfo
clang::ast_type_traits::DynTypedNode::DenseMapInfo::getEmptyKey
clang::ast_type_traits::DynTypedNode::DenseMapInfo::getTombstoneKey
clang::ast_type_traits::DynTypedNode::DenseMapInfo::getHashValue
clang::ast_type_traits::DynTypedNode::DenseMapInfo::isEqual
clang::ast_type_traits::DynTypedNode::DynCastPtrConverter
clang::ast_type_traits::DynTypedNode::DynCastPtrConverter::get
clang::ast_type_traits::DynTypedNode::DynCastPtrConverter::getUnchecked
clang::ast_type_traits::DynTypedNode::DynCastPtrConverter::create
clang::ast_type_traits::DynTypedNode::PtrConverter
clang::ast_type_traits::DynTypedNode::PtrConverter::get
clang::ast_type_traits::DynTypedNode::PtrConverter::getUnchecked
clang::ast_type_traits::DynTypedNode::PtrConverter::create
clang::ast_type_traits::DynTypedNode::ValueConverter
clang::ast_type_traits::DynTypedNode::ValueConverter::get
clang::ast_type_traits::DynTypedNode::ValueConverter::getUnchecked
clang::ast_type_traits::DynTypedNode::ValueConverter::create
clang::ast_type_traits::DynTypedNode::NodeKind
clang::ast_type_traits::DynTypedNode::Storage
clang::ast_type_traits::DynTypedNode::BaseConverter
clang::ast_type_traits::DynTypedNode::BaseConverter::get