Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.