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