[PATCH] Rename DynTypedNode to ASTNode

Alp Toker alp at nuanti.com
Sun May 18 22:18:32 PDT 2014


This is always referred to as an AST node in documentation. By wrapping 
Decls, Stmts and QualTypes it provides a generalised way to reference 
AST nodes. And despite the name, DynTypedNode doesn't have anything to 
do with dynamic types in the AST.

The attached patch renames the class and implementation to ASTNode.

(Indeed the namespace "ast_type_traits" is equally confusing. Presumably 
both are cases where implementation details have leaked into the naming 
scheme?)

Alp.

-- 
http://www.nuanti.com
the browser experts

-------------- next part --------------
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 229ac9f..ae132ad 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -15,7 +15,7 @@
 #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
 #define LLVM_CLANG_AST_ASTCONTEXT_H
 
-#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/ASTNode.h"
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
@@ -421,7 +421,7 @@ public:
   ASTMutationListener *Listener;
 
   /// \brief Contains parents of a node.
-  typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
+  typedef llvm::SmallVector<ast_type_traits::ASTNode, 1> ParentVector;
 
   /// \brief Maps from a node to its parents.
   typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
@@ -452,10 +452,10 @@ public:
   /// NestedNameSpecifier or NestedNameSpecifierLoc.
   template <typename NodeT>
   ParentVector getParents(const NodeT &Node) {
-    return getParents(ast_type_traits::DynTypedNode::create(Node));
+    return getParents(ast_type_traits::ASTNode::create(Node));
   }
 
-  ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
+  ParentVector getParents(const ast_type_traits::ASTNode &Node);
 
   const clang::PrintingPolicy &getPrintingPolicy() const {
     return PrintingPolicy;
diff --git a/include/clang/AST/ASTNode.h b/include/clang/AST/ASTNode.h
new file mode 100644
index 0000000..58c487d
--- /dev/null
+++ b/include/clang/AST/ASTNode.h
@@ -0,0 +1,364 @@
+//===--- ASTNode.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Provides a dynamic type identifier and a dynamically typed node container
+//  that can be used to store an AST base node at runtime in the same storage in
+//  a type safe way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+
+#include "clang/AST/ASTFwd.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/AlignOf.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+}
+
+namespace clang {
+
+struct PrintingPolicy;
+
+namespace ast_type_traits {
+
+/// \brief Kind identifier.
+///
+/// It can be constructed from any node kind and allows for runtime type
+/// hierarchy checks.
+/// Use getFromNodeKind<T>() to construct them.
+class ASTNodeKind {
+public:
+  /// \brief Empty identifier. It matches nothing.
+  ASTNodeKind() : KindId(NKI_None) {}
+
+  /// \brief Construct an identifier for T.
+  template <class T>
+  static ASTNodeKind getFromNodeKind() {
+    return ASTNodeKind(KindToKindId<T>::Id);
+  }
+
+  /// \brief Returns \c true if \c this and \c Other represent the same kind.
+  bool isSame(ASTNodeKind Other) const;
+
+  /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
+  /// \param Distance If non-null, used to return the distance between \c this
+  /// and \c Other in the class hierarchy.
+  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
+
+  /// \brief String representation of the kind.
+  StringRef asStringRef() const;
+
+  /// \brief Strict weak ordering for ASTNodeKind.
+  bool operator<(const ASTNodeKind &Other) const {
+    return KindId < Other.KindId;
+  }
+
+private:
+  /// \brief Kind ids.
+  ///
+  /// Includes all possible base and derived kinds.
+  enum NodeKindId {
+    NKI_None,
+    NKI_CXXCtorInitializer,
+    NKI_TemplateArgument,
+    NKI_NestedNameSpecifier,
+    NKI_NestedNameSpecifierLoc,
+    NKI_QualType,
+    NKI_TypeLoc,
+    NKI_Decl,
+#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
+#include "clang/AST/DeclNodes.inc"
+    NKI_Stmt,
+#define STMT(DERIVED, BASE) NKI_##DERIVED,
+#include "clang/AST/StmtNodes.inc"
+    NKI_Type,
+#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
+#include "clang/AST/TypeNodes.def"
+    NKI_NumberOfKinds
+  };
+
+  /// \brief Use getFromNodeKind<T>() to construct the kind.
+  ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+
+  /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
+  ///   Derived.
+  /// \param Distance If non-null, used to return the distance between \c Base
+  /// and \c Derived in the class hierarchy.
+  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
+
+  /// \brief Helper meta-function to convert a kind T to its enum value.
+  ///
+  /// This struct is specialized below for all known kinds.
+  template <class T> struct KindToKindId {
+    static const NodeKindId Id = NKI_None;
+  };
+
+  /// \brief Per kind info.
+  struct KindInfo {
+    /// \brief The id of the parent kind, or None if it has no parent.
+    NodeKindId ParentId;
+    /// \brief Name of the kind.
+    const char *Name;
+  };
+  static const KindInfo AllKindInfo[NKI_NumberOfKinds];
+
+  NodeKindId KindId;
+};
+
+#define KIND_TO_KIND_ID(Class)                                                 \
+  template <> struct ASTNodeKind::KindToKindId<Class> {                        \
+    static const NodeKindId Id = NKI_##Class;                                  \
+  };
+KIND_TO_KIND_ID(CXXCtorInitializer)
+KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(NestedNameSpecifier)
+KIND_TO_KIND_ID(NestedNameSpecifierLoc)
+KIND_TO_KIND_ID(QualType)
+KIND_TO_KIND_ID(TypeLoc)
+KIND_TO_KIND_ID(Decl)
+KIND_TO_KIND_ID(Stmt)
+KIND_TO_KIND_ID(Type)
+#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
+#include "clang/AST/DeclNodes.inc"
+#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
+#include "clang/AST/StmtNodes.inc"
+#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
+#include "clang/AST/TypeNodes.def"
+#undef KIND_TO_KIND_ID
+
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+  OS << K.asStringRef();
+  return OS;
+}
+
+/// \brief A dynamically typed AST node container.
+///
+/// Stores an AST node in a type safe way. This allows writing code that
+/// works with different kinds of AST nodes, despite the fact that they don't
+/// have a common base class.
+///
+/// Use \c create(Node) to create a \c ASTNode from an AST node,
+/// and \c get<T>() to retrieve the node as type T if the types match.
+///
+/// See \c ASTNodeKind for which node base types are currently supported;
+/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
+/// the supported base types.
+class ASTNode {
+public:
+  /// \brief Creates a \c ASTNode from \c Node.
+  template <typename T>
+  static ASTNode create(const T &Node) {
+    return BaseConverter<T>::create(Node);
+  }
+
+  /// \brief Retrieve the stored node as type \c T.
+  ///
+  /// Returns NULL if the stored node does not have a type that is
+  /// convertible to \c T.
+  ///
+  /// For types that have identity via their pointer in the AST
+  /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
+  /// pointer points to the referenced AST node.
+  /// For other types (like \c QualType) the value is stored directly
+  /// in the \c ASTNode, and the returned pointer points at
+  /// the storage inside ASTNode. For those nodes, do not
+  /// use the pointer outside the scope of the ASTNode.
+  template <typename T>
+  const T *get() const {
+    return BaseConverter<T>::get(NodeKind, Storage.buffer);
+  }
+
+  /// \brief Returns a pointer that identifies the stored AST node.
+  ///
+  /// Note that this is not supported by all AST nodes. For AST nodes
+  /// that don't have a pointer-defined identity inside the AST, this
+  /// method returns NULL.
+  const void *getMemoizationData() const;
+
+  /// \brief Prints the node to the given output stream.
+  void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
+
+  /// \brief Dumps the node to the given output stream.
+  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
+
+  /// \brief For nodes which represent textual entities in the source code,
+  /// return their SourceRange.  For all other nodes, return SourceRange().
+  SourceRange getSourceRange() const;
+
+  /// @{
+  /// \brief Imposes an order on \c ASTNode.
+  ///
+  /// Supports comparison of nodes that support memoization.
+  /// FIXME: Implement comparsion for other node types (currently
+  /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
+  bool operator<(const ASTNode &Other) const {
+    assert(getMemoizationData() && Other.getMemoizationData());
+    return getMemoizationData() < Other.getMemoizationData();
+  }
+  bool operator==(const ASTNode &Other) const {
+    if (!NodeKind.isBaseOf(Other.NodeKind) &&
+        !Other.NodeKind.isBaseOf(NodeKind))
+      return false;
+
+    // FIXME: Implement for other types.
+    if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
+      return *get<QualType>() == *Other.get<QualType>();
+    }
+    assert(getMemoizationData() && Other.getMemoizationData());
+    return getMemoizationData() == Other.getMemoizationData();
+  }
+  bool operator!=(const ASTNode &Other) const {
+    return !operator==(Other);
+  }
+  /// @}
+
+private:
+  /// \brief Takes care of converting from and to \c T.
+  template <typename T, typename EnablerT = void> struct BaseConverter;
+
+  /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
+  template <typename T, typename BaseT> struct DynCastPtrConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
+        return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+      return nullptr;
+    }
+    static ASTNode create(const BaseT &Node) {
+      ASTNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) const BaseT * (&Node);
+      return Result;
+    }
+  };
+
+  /// \brief Converter that stores T* (by pointer).
+  template <typename T> struct PtrConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+        return *reinterpret_cast<T *const *>(Storage);
+      return nullptr;
+    }
+    static ASTNode create(const T &Node) {
+      ASTNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) const T * (&Node);
+      return Result;
+    }
+  };
+
+  /// \brief Converter that stores T (by value).
+  template <typename T> struct ValueConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+        return reinterpret_cast<const T *>(Storage);
+      return nullptr;
+    }
+    static ASTNode create(const T &Node) {
+      ASTNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) T(Node);
+      return Result;
+    }
+  };
+
+  ASTNodeKind NodeKind;
+
+  /// \brief Stores the data of the node.
+  ///
+  /// Note that we can store \c Decls, \c Stmts, \c Types,
+  /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
+  /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
+  /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
+  /// \c TemplateArguments on the other hand do not have storage or unique
+  /// pointers and thus need to be stored by value.
+  typedef llvm::AlignedCharArrayUnion<
+      Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *>
+      KindsByPointer;
+  llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument,
+                              NestedNameSpecifierLoc, QualType, TypeLoc>
+      Storage;
+};
+
+template <typename T>
+struct ASTNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+    : public DynCastPtrConverter<T, Decl> {};
+
+template <typename T>
+struct ASTNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+    : public DynCastPtrConverter<T, Stmt> {};
+
+template <typename T>
+struct ASTNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+    : public DynCastPtrConverter<T, Type> {};
+
+template <>
+struct ASTNode::BaseConverter<
+    NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
+
+template <>
+struct ASTNode::BaseConverter<
+    CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
+
+template <>
+struct ASTNode::BaseConverter<
+    TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
+
+template <>
+struct ASTNode::BaseConverter<
+    NestedNameSpecifierLoc,
+    void> : public ValueConverter<NestedNameSpecifierLoc> {};
+
+template <>
+struct ASTNode::BaseConverter<QualType,
+                                   void> : public ValueConverter<QualType> {};
+
+template <>
+struct ASTNode::BaseConverter<
+    TypeLoc, void> : public ValueConverter<TypeLoc> {};
+
+// The only operation we allow on unsupported types is \c get.
+// This allows to conveniently use \c ASTNode when having an arbitrary
+// AST node that is not supported, but prevents misuse - a user cannot create
+// a ASTNode from arbitrary types.
+template <typename T, typename EnablerT> struct ASTNode::BaseConverter {
+  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+    return NULL;
+  }
+};
+
+inline const void *ASTNode::getMemoizationData() const {
+  if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
+    return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
+    return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
+    return BaseConverter<Type>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
+    return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
+  }
+  return nullptr;
+}
+
+} // end namespace ast_type_traits
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
deleted file mode 100644
index 0e06e26..0000000
--- a/include/clang/AST/ASTTypeTraits.h
+++ /dev/null
@@ -1,364 +0,0 @@
-//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  Provides a dynamic type identifier and a dynamically typed node container
-//  that can be used to store an AST base node at runtime in the same storage in
-//  a type safe way.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
-#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
-
-#include "clang/AST/ASTFwd.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/AlignOf.h"
-
-namespace llvm {
-
-class raw_ostream;
-
-}
-
-namespace clang {
-
-struct PrintingPolicy;
-
-namespace ast_type_traits {
-
-/// \brief Kind identifier.
-///
-/// It can be constructed from any node kind and allows for runtime type
-/// hierarchy checks.
-/// Use getFromNodeKind<T>() to construct them.
-class ASTNodeKind {
-public:
-  /// \brief Empty identifier. It matches nothing.
-  ASTNodeKind() : KindId(NKI_None) {}
-
-  /// \brief Construct an identifier for T.
-  template <class T>
-  static ASTNodeKind getFromNodeKind() {
-    return ASTNodeKind(KindToKindId<T>::Id);
-  }
-
-  /// \brief Returns \c true if \c this and \c Other represent the same kind.
-  bool isSame(ASTNodeKind Other) const;
-
-  /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
-  /// \param Distance If non-null, used to return the distance between \c this
-  /// and \c Other in the class hierarchy.
-  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
-
-  /// \brief String representation of the kind.
-  StringRef asStringRef() const;
-
-  /// \brief Strict weak ordering for ASTNodeKind.
-  bool operator<(const ASTNodeKind &Other) const {
-    return KindId < Other.KindId;
-  }
-
-private:
-  /// \brief Kind ids.
-  ///
-  /// Includes all possible base and derived kinds.
-  enum NodeKindId {
-    NKI_None,
-    NKI_CXXCtorInitializer,
-    NKI_TemplateArgument,
-    NKI_NestedNameSpecifier,
-    NKI_NestedNameSpecifierLoc,
-    NKI_QualType,
-    NKI_TypeLoc,
-    NKI_Decl,
-#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
-#include "clang/AST/DeclNodes.inc"
-    NKI_Stmt,
-#define STMT(DERIVED, BASE) NKI_##DERIVED,
-#include "clang/AST/StmtNodes.inc"
-    NKI_Type,
-#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
-#include "clang/AST/TypeNodes.def"
-    NKI_NumberOfKinds
-  };
-
-  /// \brief Use getFromNodeKind<T>() to construct the kind.
-  ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
-
-  /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
-  ///   Derived.
-  /// \param Distance If non-null, used to return the distance between \c Base
-  /// and \c Derived in the class hierarchy.
-  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
-
-  /// \brief Helper meta-function to convert a kind T to its enum value.
-  ///
-  /// This struct is specialized below for all known kinds.
-  template <class T> struct KindToKindId {
-    static const NodeKindId Id = NKI_None;
-  };
-
-  /// \brief Per kind info.
-  struct KindInfo {
-    /// \brief The id of the parent kind, or None if it has no parent.
-    NodeKindId ParentId;
-    /// \brief Name of the kind.
-    const char *Name;
-  };
-  static const KindInfo AllKindInfo[NKI_NumberOfKinds];
-
-  NodeKindId KindId;
-};
-
-#define KIND_TO_KIND_ID(Class)                                                 \
-  template <> struct ASTNodeKind::KindToKindId<Class> {                        \
-    static const NodeKindId Id = NKI_##Class;                                  \
-  };
-KIND_TO_KIND_ID(CXXCtorInitializer)
-KIND_TO_KIND_ID(TemplateArgument)
-KIND_TO_KIND_ID(NestedNameSpecifier)
-KIND_TO_KIND_ID(NestedNameSpecifierLoc)
-KIND_TO_KIND_ID(QualType)
-KIND_TO_KIND_ID(TypeLoc)
-KIND_TO_KIND_ID(Decl)
-KIND_TO_KIND_ID(Stmt)
-KIND_TO_KIND_ID(Type)
-#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
-#include "clang/AST/DeclNodes.inc"
-#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
-#include "clang/AST/StmtNodes.inc"
-#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
-#include "clang/AST/TypeNodes.def"
-#undef KIND_TO_KIND_ID
-
-inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
-  OS << K.asStringRef();
-  return OS;
-}
-
-/// \brief A dynamically typed AST node container.
-///
-/// Stores an AST node in a type safe way. This allows writing code that
-/// works with different kinds of AST nodes, despite the fact that they don't
-/// have a common base class.
-///
-/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
-/// and \c get<T>() to retrieve the node as type T if the types match.
-///
-/// See \c ASTNodeKind for which node base types are currently supported;
-/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
-/// the supported base types.
-class DynTypedNode {
-public:
-  /// \brief Creates a \c DynTypedNode from \c Node.
-  template <typename T>
-  static DynTypedNode create(const T &Node) {
-    return BaseConverter<T>::create(Node);
-  }
-
-  /// \brief Retrieve the stored node as type \c T.
-  ///
-  /// Returns NULL if the stored node does not have a type that is
-  /// convertible to \c T.
-  ///
-  /// For types that have identity via their pointer in the AST
-  /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
-  /// pointer points to the referenced AST node.
-  /// For other types (like \c QualType) the value is stored directly
-  /// in the \c DynTypedNode, and the returned pointer points at
-  /// the storage inside DynTypedNode. For those nodes, do not
-  /// use the pointer outside the scope of the DynTypedNode.
-  template <typename T>
-  const T *get() const {
-    return BaseConverter<T>::get(NodeKind, Storage.buffer);
-  }
-
-  /// \brief Returns a pointer that identifies the stored AST node.
-  ///
-  /// Note that this is not supported by all AST nodes. For AST nodes
-  /// that don't have a pointer-defined identity inside the AST, this
-  /// method returns NULL.
-  const void *getMemoizationData() const;
-
-  /// \brief Prints the node to the given output stream.
-  void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
-
-  /// \brief Dumps the node to the given output stream.
-  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
-
-  /// \brief For nodes which represent textual entities in the source code,
-  /// return their SourceRange.  For all other nodes, return SourceRange().
-  SourceRange getSourceRange() const;
-
-  /// @{
-  /// \brief Imposes an order on \c DynTypedNode.
-  ///
-  /// Supports comparison of nodes that support memoization.
-  /// FIXME: Implement comparsion for other node types (currently
-  /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
-  bool operator<(const DynTypedNode &Other) const {
-    assert(getMemoizationData() && Other.getMemoizationData());
-    return getMemoizationData() < Other.getMemoizationData();
-  }
-  bool operator==(const DynTypedNode &Other) const {
-    if (!NodeKind.isBaseOf(Other.NodeKind) &&
-        !Other.NodeKind.isBaseOf(NodeKind))
-      return false;
-
-    // FIXME: Implement for other types.
-    if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
-      return *get<QualType>() == *Other.get<QualType>();
-    }
-    assert(getMemoizationData() && Other.getMemoizationData());
-    return getMemoizationData() == Other.getMemoizationData();
-  }
-  bool operator!=(const DynTypedNode &Other) const {
-    return !operator==(Other);
-  }
-  /// @}
-
-private:
-  /// \brief Takes care of converting from and to \c T.
-  template <typename T, typename EnablerT = void> struct BaseConverter;
-
-  /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
-  template <typename T, typename BaseT> struct DynCastPtrConverter {
-    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-      if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
-        return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
-      return nullptr;
-    }
-    static DynTypedNode create(const BaseT &Node) {
-      DynTypedNode Result;
-      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-      new (Result.Storage.buffer) const BaseT * (&Node);
-      return Result;
-    }
-  };
-
-  /// \brief Converter that stores T* (by pointer).
-  template <typename T> struct PtrConverter {
-    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
-        return *reinterpret_cast<T *const *>(Storage);
-      return nullptr;
-    }
-    static DynTypedNode create(const T &Node) {
-      DynTypedNode Result;
-      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-      new (Result.Storage.buffer) const T * (&Node);
-      return Result;
-    }
-  };
-
-  /// \brief Converter that stores T (by value).
-  template <typename T> struct ValueConverter {
-    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
-        return reinterpret_cast<const T *>(Storage);
-      return nullptr;
-    }
-    static DynTypedNode create(const T &Node) {
-      DynTypedNode Result;
-      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-      new (Result.Storage.buffer) T(Node);
-      return Result;
-    }
-  };
-
-  ASTNodeKind NodeKind;
-
-  /// \brief Stores the data of the node.
-  ///
-  /// Note that we can store \c Decls, \c Stmts, \c Types,
-  /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
-  /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
-  /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
-  /// \c TemplateArguments on the other hand do not have storage or unique
-  /// pointers and thus need to be stored by value.
-  typedef llvm::AlignedCharArrayUnion<
-      Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *>
-      KindsByPointer;
-  llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument,
-                              NestedNameSpecifierLoc, QualType, TypeLoc>
-      Storage;
-};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
-    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
-    : public DynCastPtrConverter<T, Decl> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
-    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
-    : public DynCastPtrConverter<T, Stmt> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
-    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
-    : public DynCastPtrConverter<T, Type> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
-    NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
-    CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
-    TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
-    NestedNameSpecifierLoc,
-    void> : public ValueConverter<NestedNameSpecifierLoc> {};
-
-template <>
-struct DynTypedNode::BaseConverter<QualType,
-                                   void> : public ValueConverter<QualType> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
-    TypeLoc, void> : public ValueConverter<TypeLoc> {};
-
-// The only operation we allow on unsupported types is \c get.
-// This allows to conveniently use \c DynTypedNode when having an arbitrary
-// AST node that is not supported, but prevents misuse - a user cannot create
-// a DynTypedNode from arbitrary types.
-template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
-  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-    return NULL;
-  }
-};
-
-inline const void *DynTypedNode::getMemoizationData() const {
-  if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
-    return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
-  } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
-    return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
-  } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
-    return BaseConverter<Type>::get(NodeKind, Storage.buffer);
-  } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
-    return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
-  }
-  return nullptr;
-}
-
-} // end namespace ast_type_traits
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 8af0546..a69974f 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -157,9 +157,9 @@ public:
   ///
   /// @{
   template <typename T> void match(const T &Node, ASTContext &Context) {
-    match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
+    match(clang::ast_type_traits::ASTNode::create(Node), Context);
   }
-  void match(const clang::ast_type_traits::DynTypedNode &Node,
+  void match(const clang::ast_type_traits::ASTNode &Node,
              ASTContext &Context);
   /// @}
 
@@ -199,7 +199,7 @@ match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
 
 template <typename MatcherT>
 SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+match(MatcherT Matcher, const ast_type_traits::ASTNode &Node,
       ASTContext &Context);
 /// @}
 
@@ -237,7 +237,7 @@ public:
 
 template <typename MatcherT>
 SmallVector<BoundNodes, 1>
-match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+match(MatcherT Matcher, const ast_type_traits::ASTNode &Node,
       ASTContext &Context) {
   internal::CollectMatchesCallback Callback;
   MatchFinder Finder;
@@ -249,7 +249,7 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
 template <typename MatcherT, typename NodeT>
 SmallVector<BoundNodes, 1>
 match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
-  return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
+  return match(Matcher, ast_type_traits::ASTNode::create(Node), Context);
 }
 
 } // end namespace ast_matchers
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index e7d5e5f..4c84715 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -88,7 +88,7 @@ public:
 
   /// \brief Type of mapping from binding identifiers to bound nodes. This type
   /// is an associative container with a key type of \c std::string and a value
-  /// type of \c clang::ast_type_traits::DynTypedNode
+  /// type of \c clang::ast_type_traits::ASTNode
   typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap;
 
   /// \brief Retrieve mapping from binding identifiers to bound nodes.
@@ -2352,7 +2352,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4(
   // they're ever reused.
   internal::NotEqualsBoundNodePredicate Predicate;
   Predicate.ID = ID;
-  Predicate.Node = ast_type_traits::DynTypedNode::create(Node);
+  Predicate.Node = ast_type_traits::ASTNode::create(Node);
   return Builder->removeBindings(Predicate);
 }
 
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index ed20dee..9c49f17 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -35,7 +35,7 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
 
-#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/ASTNode.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
@@ -63,7 +63,7 @@ public:
   /// The node's base type should be in NodeBaseType or it will be unaccessible.
   template <typename T>
   void addNode(StringRef ID, const T* Node) {
-    NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node);
+    NodeMap[ID] = ast_type_traits::ASTNode::create(*Node);
   }
 
   /// \brief Returns the AST node bound to \c ID.
@@ -79,10 +79,10 @@ public:
     return It->second.get<T>();
   }
 
-  ast_type_traits::DynTypedNode getNode(StringRef ID) const {
+  ast_type_traits::ASTNode getNode(StringRef ID) const {
     IDToNodeMap::const_iterator It = NodeMap.find(ID);
     if (It == NodeMap.end()) {
-      return ast_type_traits::DynTypedNode();
+      return ast_type_traits::ASTNode();
     }
     return It->second;
   }
@@ -97,7 +97,7 @@ public:
   /// Note that we're using std::map here, as for memoization:
   /// - we need a comparison operator
   /// - we need an assignment operator
-  typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
+  typedef std::map<std::string, ast_type_traits::ASTNode> IDToNodeMap;
 
   const IDToNodeMap &getMap() const {
     return NodeMap;
@@ -305,11 +305,11 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
 
 template <typename T> class BindableMatcher;
 
-/// \brief Matcher that works on a \c DynTypedNode.
+/// \brief Matcher that works on a \c ASTNode.
 ///
 /// It is constructed from a \c Matcher<T> object and redirects most calls to
 /// underlying matcher.
-/// It checks whether the \c DynTypedNode is convertible into the type of the
+/// It checks whether the \c ASTNode is convertible into the type of the
 /// underlying matcher and then do the actual match on the actual node, or
 /// return false if it is not convertible.
 class DynTypedMatcher {
@@ -323,7 +323,7 @@ public:
   template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M);
 
   /// \brief Returns true if the matcher matches the given \c DynNode.
-  bool matches(const ast_type_traits::DynTypedNode DynNode,
+  bool matches(const ast_type_traits::ASTNode DynNode,
                ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const {
     return Storage->matches(DynNode, Finder, Builder);
   }
@@ -379,7 +379,7 @@ private:
         : SupportedKind(SupportedKind), ID(ID) {}
     virtual ~MatcherStorage();
 
-    virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
+    virtual bool matches(const ast_type_traits::ASTNode DynNode,
                          ASTMatchFinder *Finder,
                          BoundNodesTreeBuilder *Builder) const = 0;
 
@@ -410,7 +410,7 @@ public:
                        Other.getID()),
         InnerMatcher(Other), AllowBind(AllowBind) {}
 
-  bool matches(const ast_type_traits::DynTypedNode DynNode,
+  bool matches(const ast_type_traits::ASTNode DynNode,
                ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     if (const T *Node = DynNode.get<T>()) {
@@ -717,7 +717,7 @@ public:
                   std::is_base_of<TypeLoc, T>::value ||
                   std::is_base_of<QualType, T>::value,
                   "unsupported type for recursive matching");
-   return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
+   return matchesChildOf(ast_type_traits::ASTNode::create(Node),
                           Matcher, Builder, Traverse, Bind);
   }
 
@@ -733,7 +733,7 @@ public:
                   std::is_base_of<TypeLoc, T>::value ||
                   std::is_base_of<QualType, T>::value,
                   "unsupported type for recursive matching");
-    return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
+    return matchesDescendantOf(ast_type_traits::ASTNode::create(Node),
                                Matcher, Builder, Bind);
   }
 
@@ -746,25 +746,25 @@ public:
     static_assert(std::is_base_of<Decl, T>::value ||
                   std::is_base_of<Stmt, T>::value,
                   "only Decl or Stmt allowed for recursive matching");
-    return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
+    return matchesAncestorOf(ast_type_traits::ASTNode::create(Node),
                              Matcher, Builder, MatchMode);
   }
 
   virtual ASTContext &getASTContext() const = 0;
 
 protected:
-  virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
+  virtual bool matchesChildOf(const ast_type_traits::ASTNode &Node,
                               const DynTypedMatcher &Matcher,
                               BoundNodesTreeBuilder *Builder,
                               TraversalKind Traverse,
                               BindKind Bind) = 0;
 
-  virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
+  virtual bool matchesDescendantOf(const ast_type_traits::ASTNode &Node,
                                    const DynTypedMatcher &Matcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) = 0;
 
-  virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
+  virtual bool matchesAncestorOf(const ast_type_traits::ASTNode &Node,
                                  const DynTypedMatcher &Matcher,
                                  BoundNodesTreeBuilder *Builder,
                                  AncestorMatchMode MatchMode) = 0;
@@ -1092,7 +1092,7 @@ private:
 /// \brief Function signature for any variadic operator. It takes the inner
 ///   matchers as an array of DynTypedMatcher.
 typedef bool (*VariadicOperatorFunction)(
-    const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
+    const ast_type_traits::ASTNode DynNode, ASTMatchFinder *Finder,
     BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief \c MatcherInterface<T> implementation for an variadic operator.
@@ -1105,7 +1105,7 @@ public:
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
-    return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
+    return Func(ast_type_traits::ASTNode::create(Node), Finder, Builder,
                 InnerMatchers);
   }
 
@@ -1215,26 +1215,26 @@ struct VariadicOperatorMatcherFunc {
 /// \brief Matches nodes that do not match the provided matcher.
 ///
 /// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+bool NotUnaryOperator(const ast_type_traits::ASTNode DynNode,
                       ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
                       ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Matches nodes for which all provided matchers match.
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool AllOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
                            ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Matches nodes for which at least one of the provided matchers
 /// matches, but doesn't stop at the first match.
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool EachOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                             ASTMatchFinder *Finder,
                             BoundNodesTreeBuilder *Builder,
                             ArrayRef<DynTypedMatcher> InnerMatchers);
 
 /// \brief Matches nodes for which at least one of the provided matchers
 /// matches.
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool AnyOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
                            ArrayRef<DynTypedMatcher> InnerMatchers);
@@ -1581,7 +1581,7 @@ struct NotEqualsBoundNodePredicate {
     return Nodes.getNode(ID) != Node;
   }
   std::string ID;
-  ast_type_traits::DynTypedNode Node;
+  ast_type_traits::ASTNode Node;
 };
 
 } // end namespace internal
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index fe735dc..f5e0ac4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -8164,12 +8164,12 @@ namespace {
         // when we visit all subexpressions of template instantiations; this is
         // suboptimal, bug benign: the only way to visit those is with
         // hasAncestor / hasParent, and those do not create new matches.
-        // The plan is to enable DynTypedNode to be storable in a map or hash
+        // The plan is to enable ASTNode to be storable in a map or hash
         // map. The main problem there is to implement hash functions /
-        // comparison operators for all types that DynTypedNode supports that
+        // comparison operators for all types that ASTNode supports that
         // do not have pointer identity.
         (*Parents)[Node].push_back(ParentStack.back());
-      ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
+      ParentStack.push_back(ast_type_traits::ASTNode::create(*Node));
       bool Result = (this ->* traverse) (Node);
       ParentStack.pop_back();
       return Result;
@@ -8184,7 +8184,7 @@ namespace {
     }
 
     ASTContext::ParentMap *Parents;
-    llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
+    llvm::SmallVector<ast_type_traits::ASTNode, 16> ParentStack;
 
     friend class RecursiveASTVisitor<ParentMapASTVisitor>;
   };
@@ -8192,7 +8192,7 @@ namespace {
 } // end namespace
 
 ASTContext::ParentVector
-ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
+ASTContext::getParents(const ast_type_traits::ASTNode &Node) {
   assert(Node.getMemoizationData() &&
          "Invariant broken: only nodes that support memoization may be "
          "used in the parent map.");
diff --git a/lib/AST/ASTNode.cpp b/lib/AST/ASTNode.cpp
new file mode 100644
index 0000000..c6c7923
--- /dev/null
+++ b/lib/AST/ASTNode.cpp
@@ -0,0 +1,111 @@
+//===--- ASTNode.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Provides a dynamic type identifier and a dynamically typed node container
+//  that can be used to store an AST base node at runtime in the same storage in
+//  a type safe way.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTNode.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+namespace ast_type_traits {
+
+const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
+  { NKI_None, "<None>" },
+  { NKI_None, "CXXCtorInitializer" },
+  { NKI_None, "TemplateArgument" },
+  { NKI_None, "NestedNameSpecifier" },
+  { NKI_None, "NestedNameSpecifierLoc" },
+  { NKI_None, "QualType" },
+  { NKI_None, "TypeLoc" },
+  { NKI_None, "Decl" },
+#define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
+#include "clang/AST/DeclNodes.inc"
+  { NKI_None, "Stmt" },
+#define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
+#include "clang/AST/StmtNodes.inc"
+  { NKI_None, "Type" },
+#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
+#include "clang/AST/TypeNodes.def"
+};
+
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
+  return isBaseOf(KindId, Other.KindId, Distance);
+}
+
+bool ASTNodeKind::isSame(ASTNodeKind Other) const {
+  return KindId != NKI_None && KindId == Other.KindId;
+}
+
+bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
+                           unsigned *Distance) {
+  if (Base == NKI_None || Derived == NKI_None) return false;
+  unsigned Dist = 0;
+  while (Derived != Base && Derived != NKI_None) {
+    Derived = AllKindInfo[Derived].ParentId;
+    ++Dist;
+  }
+  if (Distance)
+    *Distance = Dist;
+  return Derived == Base;
+}
+
+StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
+
+void ASTNode::print(llvm::raw_ostream &OS,
+                         const PrintingPolicy &PP) const {
+  if (const TemplateArgument *TA = get<TemplateArgument>())
+    TA->print(PP, OS);
+  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
+    NNS->print(OS, PP);
+  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
+    NNSL->getNestedNameSpecifier()->print(OS, PP);
+  else if (const QualType *QT = get<QualType>())
+    QT->print(OS, PP);
+  else if (const TypeLoc *TL = get<TypeLoc>())
+    TL->getType().print(OS, PP);
+  else if (const Decl *D = get<Decl>())
+    D->print(OS, PP);
+  else if (const Stmt *S = get<Stmt>())
+    S->printPretty(OS, nullptr, PP);
+  else if (const Type *T = get<Type>())
+    QualType(T, 0).print(OS, PP);
+  else
+    OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
+}
+
+void ASTNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
+  if (const Decl *D = get<Decl>())
+    D->dump(OS);
+  else if (const Stmt *S = get<Stmt>())
+    S->dump(OS, SM);
+  else
+    OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
+}
+
+SourceRange ASTNode::getSourceRange() const {
+  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
+    return CCI->getSourceRange();
+  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
+    return NNSL->getSourceRange();
+  if (const TypeLoc *TL = get<TypeLoc>())
+    return TL->getSourceRange();
+  if (const Decl *D = get<Decl>())
+    return D->getSourceRange();
+  if (const Stmt *S = get<Stmt>())
+    return S->getSourceRange();
+  return SourceRange();
+}
+
+} // end namespace ast_type_traits
+} // end namespace clang
diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
deleted file mode 100644
index baa8e48..0000000
--- a/lib/AST/ASTTypeTraits.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-//===--- ASTTypeTraits.cpp --------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  Provides a dynamic type identifier and a dynamically typed node container
-//  that can be used to store an AST base node at runtime in the same storage in
-//  a type safe way.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclCXX.h"
-
-namespace clang {
-namespace ast_type_traits {
-
-const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
-  { NKI_None, "<None>" },
-  { NKI_None, "CXXCtorInitializer" },
-  { NKI_None, "TemplateArgument" },
-  { NKI_None, "NestedNameSpecifier" },
-  { NKI_None, "NestedNameSpecifierLoc" },
-  { NKI_None, "QualType" },
-  { NKI_None, "TypeLoc" },
-  { NKI_None, "Decl" },
-#define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
-#include "clang/AST/DeclNodes.inc"
-  { NKI_None, "Stmt" },
-#define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
-#include "clang/AST/StmtNodes.inc"
-  { NKI_None, "Type" },
-#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
-#include "clang/AST/TypeNodes.def"
-};
-
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
-  return isBaseOf(KindId, Other.KindId, Distance);
-}
-
-bool ASTNodeKind::isSame(ASTNodeKind Other) const {
-  return KindId != NKI_None && KindId == Other.KindId;
-}
-
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
-                           unsigned *Distance) {
-  if (Base == NKI_None || Derived == NKI_None) return false;
-  unsigned Dist = 0;
-  while (Derived != Base && Derived != NKI_None) {
-    Derived = AllKindInfo[Derived].ParentId;
-    ++Dist;
-  }
-  if (Distance)
-    *Distance = Dist;
-  return Derived == Base;
-}
-
-StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
-
-void DynTypedNode::print(llvm::raw_ostream &OS,
-                         const PrintingPolicy &PP) const {
-  if (const TemplateArgument *TA = get<TemplateArgument>())
-    TA->print(PP, OS);
-  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
-    NNS->print(OS, PP);
-  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
-    NNSL->getNestedNameSpecifier()->print(OS, PP);
-  else if (const QualType *QT = get<QualType>())
-    QT->print(OS, PP);
-  else if (const TypeLoc *TL = get<TypeLoc>())
-    TL->getType().print(OS, PP);
-  else if (const Decl *D = get<Decl>())
-    D->print(OS, PP);
-  else if (const Stmt *S = get<Stmt>())
-    S->printPretty(OS, nullptr, PP);
-  else if (const Type *T = get<Type>())
-    QualType(T, 0).print(OS, PP);
-  else
-    OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
-}
-
-void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
-  if (const Decl *D = get<Decl>())
-    D->dump(OS);
-  else if (const Stmt *S = get<Stmt>())
-    S->dump(OS, SM);
-  else
-    OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
-}
-
-SourceRange DynTypedNode::getSourceRange() const {
-  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
-    return CCI->getSourceRange();
-  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
-    return NNSL->getSourceRange();
-  if (const TypeLoc *TL = get<TypeLoc>())
-    return TL->getSourceRange();
-  if (const Decl *D = get<Decl>())
-    return D->getSourceRange();
-  if (const Stmt *S = get<Stmt>())
-    return S->getSourceRange();
-  return SourceRange();
-}
-
-} // end namespace ast_type_traits
-} // end namespace clang
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 9006be6..e45a616 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -7,7 +7,7 @@ add_clang_library(clangAST
   ASTDiagnostic.cpp
   ASTDumper.cpp
   ASTImporter.cpp
-  ASTTypeTraits.cpp
+  ASTNode.cpp
   AttrImpl.cpp
   CXXInheritance.cpp
   Comment.cpp
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index 23708e2..689c76f 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -54,7 +54,7 @@ static const unsigned MaxMemoizationEntries = 10000;
 // provides enough benefit for the additional amount of code.
 struct MatchKey {
   uint64_t MatcherID;
-  ast_type_traits::DynTypedNode Node;
+  ast_type_traits::ASTNode Node;
   BoundNodesTreeBuilder BoundNodes;
 
   bool operator<(const MatchKey &Other) const {
@@ -106,7 +106,7 @@ public:
   //     Traverse*(c) for each child c of 'node'.
   //   - Traverse*(c) in turn calls Traverse(c), completing the
   //     recursion.
-  bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
+  bool findMatch(const ast_type_traits::ASTNode &DynNode) {
     reset();
     if (const Decl *D = DynNode.get<Decl>())
       traverse(*D);
@@ -247,7 +247,7 @@ private:
     }
     if (Bind != ASTMatchFinder::BK_All) {
       BoundNodesTreeBuilder RecursiveBuilder(*Builder);
-      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
+      if (Matcher->matches(ast_type_traits::ASTNode::create(Node), Finder,
                            &RecursiveBuilder)) {
         Matches = true;
         ResultBindings.addMatch(RecursiveBuilder);
@@ -255,7 +255,7 @@ private:
       }
     } else {
       BoundNodesTreeBuilder RecursiveBuilder(*Builder);
-      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
+      if (Matcher->matches(ast_type_traits::ASTNode::create(Node), Finder,
                            &RecursiveBuilder)) {
         // After the first match the matcher succeeds.
         Matches = true;
@@ -367,7 +367,7 @@ public:
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
-  bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
+  bool memoizedMatchesRecursively(const ast_type_traits::ASTNode &Node,
                                   const DynTypedMatcher &Matcher,
                                   BoundNodesTreeBuilder *Builder, int MaxDepth,
                                   TraversalKind Traversal, BindKind Bind) {
@@ -398,7 +398,7 @@ public:
   }
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
-  bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
+  bool matchesRecursively(const ast_type_traits::ASTNode &Node,
                           const DynTypedMatcher &Matcher,
                           BoundNodesTreeBuilder *Builder, int MaxDepth,
                           TraversalKind Traversal, BindKind Bind) {
@@ -412,7 +412,7 @@ public:
                           BoundNodesTreeBuilder *Builder) override;
 
   // Implements ASTMatchFinder::matchesChildOf.
-  bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
+  bool matchesChildOf(const ast_type_traits::ASTNode &Node,
                       const DynTypedMatcher &Matcher,
                       BoundNodesTreeBuilder *Builder,
                       TraversalKind Traversal,
@@ -423,7 +423,7 @@ public:
                                       Bind);
   }
   // Implements ASTMatchFinder::matchesDescendantOf.
-  bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
+  bool matchesDescendantOf(const ast_type_traits::ASTNode &Node,
                            const DynTypedMatcher &Matcher,
                            BoundNodesTreeBuilder *Builder,
                            BindKind Bind) override {
@@ -433,7 +433,7 @@ public:
                                       TK_AsIs, Bind);
   }
   // Implements ASTMatchFinder::matchesAncestorOf.
-  bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
+  bool matchesAncestorOf(const ast_type_traits::ASTNode &Node,
                          const DynTypedMatcher &Matcher,
                          BoundNodesTreeBuilder *Builder,
                          AncestorMatchMode MatchMode) override {
@@ -447,7 +447,7 @@ public:
 
   // Matches all registered matchers on the given node and calls the
   // result callback for every node that matches.
-  void match(const ast_type_traits::DynTypedNode& Node) {
+  void match(const ast_type_traits::ASTNode& Node) {
     for (std::vector<std::pair<internal::DynTypedMatcher,
                                MatchCallback *> >::const_iterator
              I = MatcherCallbackPairs->begin(),
@@ -462,7 +462,7 @@ public:
   }
 
   template <typename T> void match(const T &Node) {
-    match(ast_type_traits::DynTypedNode::create(Node));
+    match(ast_type_traits::ASTNode::create(Node));
   }
 
   // Implements ASTMatchFinder::getASTContext.
@@ -489,7 +489,7 @@ private:
   // allow simple memoization on the ancestors. Thus, we only memoize as long
   // as there is a single parent.
   bool memoizedMatchesAncestorOfRecursively(
-      const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher,
+      const ast_type_traits::ASTNode &Node, const DynTypedMatcher &Matcher,
       BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) {
     if (Node.get<TranslationUnitDecl>() ==
         ActiveASTContext->getTranslationUnitDecl())
@@ -519,7 +519,7 @@ private:
     Result.Nodes = *Builder;
     if (Parents.size() == 1) {
       // Only one parent - do recursive memoization.
-      const ast_type_traits::DynTypedNode Parent = Parents[0];
+      const ast_type_traits::ASTNode Parent = Parents[0];
       if (Matcher.matches(Parent, this, &Result.Nodes)) {
         Result.ResultOfMatch = true;
       } else if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
@@ -534,7 +534,7 @@ private:
     } else {
       // Multiple parents - BFS over the rest of the nodes.
       llvm::DenseSet<const void *> Visited;
-      std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(),
+      std::deque<ast_type_traits::ASTNode> Queue(Parents.begin(),
                                                       Parents.end());
       while (!Queue.empty()) {
         Result.Nodes = *Builder;
@@ -827,7 +827,7 @@ ASTConsumer *MatchFinder::newASTConsumer() {
   return new internal::MatchASTConsumer(this, ParsingDone);
 }
 
-void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node,
+void MatchFinder::match(const clang::ast_type_traits::ASTNode &Node,
                         ASTContext &Context) {
   internal::MatchASTVisitor Visitor(&MatcherCallbackPairs);
   Visitor.set_active_ast_context(&Context);
diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp
index 47b8b6d..7a6239e 100644
--- a/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -34,7 +34,7 @@ void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
   }
 }
 
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+bool NotUnaryOperator(const ast_type_traits::ASTNode DynNode,
                       ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
                       ArrayRef<DynTypedMatcher> InnerMatchers) {
   if (InnerMatchers.size() != 1)
@@ -54,7 +54,7 @@ bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
   return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
 }
 
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool AllOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
                            ArrayRef<DynTypedMatcher> InnerMatchers) {
@@ -68,7 +68,7 @@ bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
   return true;
 }
 
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool EachOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                             ASTMatchFinder *Finder,
                             BoundNodesTreeBuilder *Builder,
                             ArrayRef<DynTypedMatcher> InnerMatchers) {
@@ -85,7 +85,7 @@ bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
   return Matched;
 }
 
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+bool AnyOfVariadicOperator(const ast_type_traits::ASTNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
                            ArrayRef<DynTypedMatcher> InnerMatchers) {
diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp
index 0e73f76..f72b08b 100644
--- a/unittests/AST/ASTTypeTraitsTest.cpp
+++ b/unittests/AST/ASTTypeTraitsTest.cpp
@@ -1,4 +1,4 @@
-//===- unittest/AST/ASTTypeTraits.cpp - AST type traits unit tests ------===//
+//===- unittest/AST/ASTNode.cpp - AST type traits unit tests ------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -8,7 +8,7 @@
 //===--------------------------------------------------------------------===//
 
 
-#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/ASTNode.h"
 #include "MatchVerifier.h"
 #include "gtest/gtest.h"
 
@@ -74,50 +74,50 @@ TEST(ASTNodeKind, Name) {
   EXPECT_EQ("<None>", ASTNodeKind().asStringRef());
 }
 
-TEST(DynTypedNode, DeclSourceRange) {
-  RangeVerifier<DynTypedNode> Verifier;
+TEST(ASTNode, DeclSourceRange) {
+  RangeVerifier<ASTNode> Verifier;
   Verifier.expectRange(1, 1, 1, 11);
   EXPECT_TRUE(Verifier.match("void f() {}", decl()));
 }
 
-TEST(DynTypedNode, StmtSourceRange) {
-  RangeVerifier<DynTypedNode> Verifier;
+TEST(ASTNode, StmtSourceRange) {
+  RangeVerifier<ASTNode> Verifier;
   Verifier.expectRange(1, 10, 1, 11);
   EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
 }
 
-TEST(DynTypedNode, TypeLocSourceRange) {
-  RangeVerifier<DynTypedNode> Verifier;
+TEST(ASTNode, TypeLocSourceRange) {
+  RangeVerifier<ASTNode> Verifier;
   Verifier.expectRange(1, 1, 1, 8);
   EXPECT_TRUE(Verifier.match("void f() {}", typeLoc(loc(functionType()))));
 }
 
-TEST(DynTypedNode, NNSLocSourceRange) {
-  RangeVerifier<DynTypedNode> Verifier;
+TEST(ASTNode, NNSLocSourceRange) {
+  RangeVerifier<ASTNode> Verifier;
   Verifier.expectRange(1, 33, 1, 34);
   EXPECT_TRUE(Verifier.match("namespace N { typedef void T; } N::T f() {}",
                              nestedNameSpecifierLoc()));
 }
 
-TEST(DynTypedNode, DeclDump) {
+TEST(ASTNode, DeclDump) {
   DumpVerifier Verifier;
   Verifier.expectSubstring("FunctionDecl");
   EXPECT_TRUE(Verifier.match("void f() {}", functionDecl()));
 }
 
-TEST(DynTypedNode, StmtDump) {
+TEST(ASTNode, StmtDump) {
   DumpVerifier Verifier;
   Verifier.expectSubstring("CompoundStmt");
   EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
 }
 
-TEST(DynTypedNode, DeclPrint) {
+TEST(ASTNode, DeclPrint) {
   PrintVerifier Verifier;
   Verifier.expectString("void f() {\n}\n\n");
   EXPECT_TRUE(Verifier.match("void f() {}", functionDecl()));
 }
 
-TEST(DynTypedNode, StmtPrint) {
+TEST(ASTNode, StmtPrint) {
   PrintVerifier Verifier;
   Verifier.expectString("{\n}\n");
   EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h
index 0265f4a..6983dfa 100644
--- a/unittests/AST/MatchVerifier.h
+++ b/unittests/AST/MatchVerifier.h
@@ -126,7 +126,7 @@ void MatchVerifier<NodeType>::run(const MatchFinder::MatchResult &Result) {
 }
 
 template <>
-inline void MatchVerifier<ast_type_traits::DynTypedNode>::run(
+inline void MatchVerifier<ast_type_traits::ASTNode>::run(
     const MatchFinder::MatchResult &Result) {
   BoundNodes::IDToNodeMap M = Result.Nodes.getMap();
   BoundNodes::IDToNodeMap::const_iterator I = M.find("");
@@ -222,7 +222,7 @@ private:
 };
 
 /// \brief Verify whether a node's dump contains a given substring.
-class DumpVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
+class DumpVerifier : public MatchVerifier<ast_type_traits::ASTNode> {
 public:
   void expectSubstring(const std::string &Str) {
     ExpectSubstring = Str;
@@ -230,7 +230,7 @@ public:
 
 protected:
   void verify(const MatchFinder::MatchResult &Result,
-              const ast_type_traits::DynTypedNode &Node) {
+              const ast_type_traits::ASTNode &Node) {
     std::string DumpStr;
     llvm::raw_string_ostream Dump(DumpStr);
     Node.dump(Dump, *Result.SourceManager);
@@ -249,7 +249,7 @@ private:
 };
 
 /// \brief Verify whether a node's pretty print matches a given string.
-class PrintVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
+class PrintVerifier : public MatchVerifier<ast_type_traits::ASTNode> {
 public:
   void expectString(const std::string &Str) {
     ExpectString = Str;
@@ -257,7 +257,7 @@ public:
 
 protected:
   void verify(const MatchFinder::MatchResult &Result,
-              const ast_type_traits::DynTypedNode &Node) {
+              const ast_type_traits::ASTNode &Node) {
     std::string PrintStr;
     llvm::raw_string_ostream Print(PrintStr);
     Node.print(Print, Result.Context->getPrintingPolicy());


More information about the cfe-commits mailing list