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   ASTNodeKind() : KindId(NKI_None) {}
55 
56   /// Construct an identifier for T.
57   template <class T>
58   static ASTNodeKind getFromNodeKind() {
59     return ASTNodeKind(KindToKindId<T>::Id);
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.
97   static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
98 
99   /// Return the most derived common ancestor between Kind1 and Kind2.
100   ///
101   /// Return ASTNodeKind() if they are not related.
102   static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
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.
249 class DynTypedNode {
250 public:
251   /// Creates a \c DynTypedNode from \c Node.
252   template <typename T>
253   static DynTypedNode create(const T &Node) {
254     return BaseConverter<T>::create(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>() ==
355              Other.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() {
368       DynTypedNode Node;
369       Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
370       return Node;
371     }
372     static inline DynTypedNode getTombstoneKey() {
373       DynTypedNode Node;
374       Node.NodeKind = ASTNodeKind::DenseMapInfo::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) {
396       auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
397       auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
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<
559     NestedNameSpecifierLoc,
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 <>
597 struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
598 
599 }  // end namespace llvm
600 
601 #endif
602