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