r186422 - Add more types to ASTNodeKind. Refactor common instantiation code.

Samuel Benzaquen sbenza at google.com
Tue Jul 16 08:47:25 PDT 2013


Author: sbenza
Date: Tue Jul 16 10:47:24 2013
New Revision: 186422

URL: http://llvm.org/viewvc/llvm-project?rev=186422&view=rev
Log:
Add more types to ASTNodeKind. Refactor common instantiation code.

Summary:
Add support for CXXCtorInitializer and TemplateArgument types to ASTNodeKind.
This change is to support more matchers from clang/ASTMatchers/ASTMatchers.h in the dynamic layer (clang/ASTMatchers/Dynamic).

Reviewers: klimek

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1143

Modified:
    cfe/trunk/include/clang/AST/ASTFwd.h
    cfe/trunk/include/clang/AST/ASTTypeTraits.h
    cfe/trunk/lib/AST/ASTTypeTraits.cpp

Modified: cfe/trunk/include/clang/AST/ASTFwd.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTFwd.h?rev=186422&r1=186421&r2=186422&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTFwd.h (original)
+++ cfe/trunk/include/clang/AST/ASTFwd.h Tue Jul 16 10:47:24 2013
@@ -23,5 +23,6 @@ class Stmt;
 class Type;
 #define TYPE(DERIVED, BASE) class DERIVED##Type;
 #include "clang/AST/TypeNodes.def"
+class CXXCtorInitializer;
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/AST/ASTTypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTTypeTraits.h?rev=186422&r1=186421&r2=186422&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTTypeTraits.h (original)
+++ cfe/trunk/include/clang/AST/ASTTypeTraits.h Tue Jul 16 10:47:24 2013
@@ -18,7 +18,9 @@
 
 #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"
@@ -45,7 +47,7 @@ public:
   /// \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
+  /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
   bool isBaseOf(ASTNodeKind Other) const;
 
   /// \brief String representation of the kind.
@@ -57,6 +59,8 @@ private:
   /// Includes all possible base and derived kinds.
   enum NodeKindId {
     NKI_None,
+    NKI_CXXCtorInitializer,
+    NKI_TemplateArgument,
     NKI_NestedNameSpecifier,
     NKI_NestedNameSpecifierLoc,
     NKI_QualType,
@@ -77,7 +81,7 @@ private:
   ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
 
   /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
-  ///   Derived
+  ///   Derived.
   static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
 
   /// \brief Helper meta-function to convert a kind T to its enum value.
@@ -103,6 +107,8 @@ private:
   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)
@@ -127,7 +133,7 @@ KIND_TO_KIND_ID(Type)
 /// 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 NodeTypeTag for which node base types are currently supported;
+/// 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 {
@@ -193,118 +199,109 @@ 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 NULL;
+    }
+    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 NULL;
+    }
+    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 NULL;
+    }
+    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 and
-  /// \c NestedNameSpecifiers by pointer as they are guaranteed to be unique
-  /// pointers pointing to dedicated storage in the AST. \c QualTypes on the
-  /// other hand do not have storage or unique pointers and thus need to be
-  /// stored by value.
-  llvm::AlignedCharArrayUnion<Decl *, Stmt *, Type *, NestedNameSpecifier *,
+  /// 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;
 };
 
-// FIXME: Pull out abstraction for the following.
-template<typename T> struct DynTypedNode::BaseConverter<T,
-    typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> {
-  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind))
-      return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage));
-    return NULL;
-  }
-  static DynTypedNode create(const Decl &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-    new (Result.Storage.buffer) const Decl*(&Node);
-    return Result;
-  }
-};
-template<typename T> struct DynTypedNode::BaseConverter<T,
-    typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> {
-  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind))
-      return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage));
-    return NULL;
-  }
-  static DynTypedNode create(const Stmt &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-    new (Result.Storage.buffer) const Stmt*(&Node);
-    return Result;
-  }
-};
-template<typename T> struct DynTypedNode::BaseConverter<T,
-    typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> {
-  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind))
-      return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage));
-    return NULL;
-  }
-  static DynTypedNode create(const Type &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
-    new (Result.Storage.buffer) const Type*(&Node);
-    return Result;
-  }
-};
-template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> {
-  static const NestedNameSpecifier *get(ASTNodeKind NodeKind,
-                                        const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind))
-      return *reinterpret_cast<NestedNameSpecifier*const*>(Storage);
-    return NULL;
-  }
-  static DynTypedNode create(const NestedNameSpecifier &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<NestedNameSpecifier>();
-    new (Result.Storage.buffer) const NestedNameSpecifier*(&Node);
-    return Result;
-  }
-};
-template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> {
-  static const NestedNameSpecifierLoc *get(ASTNodeKind NodeKind,
-                                           const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isBaseOf(
-            NodeKind))
-      return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage);
-    return NULL;
-  }
-  static DynTypedNode create(const NestedNameSpecifierLoc &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>();
-    new (Result.Storage.buffer) NestedNameSpecifierLoc(Node);
-    return Result;
-  }
-};
-template<> struct DynTypedNode::BaseConverter<QualType, void> {
-  static const QualType *get(ASTNodeKind NodeKind, const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind))
-      return reinterpret_cast<const QualType*>(Storage);
-    return NULL;
-  }
-  static DynTypedNode create(const QualType &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<QualType>();
-    new (Result.Storage.buffer) QualType(Node);
-    return Result;
-  }
-};
-template<> struct DynTypedNode::BaseConverter<TypeLoc, void> {
-  static const TypeLoc *get(ASTNodeKind NodeKind, const char Storage[]) {
-    if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
-      return reinterpret_cast<const TypeLoc*>(Storage);
-    return NULL;
-  }
-  static DynTypedNode create(const TypeLoc &Node) {
-    DynTypedNode Result;
-    Result.NodeKind = ASTNodeKind::getFromNodeKind<TypeLoc>();
-    new (Result.Storage.buffer) TypeLoc(Node);
-    return Result;
-  }
-};
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename llvm::enable_if<llvm::is_base_of<
+           Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename llvm::enable_if<llvm::is_base_of<
+           Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename llvm::enable_if<llvm::is_base_of<
+           Type, T> >::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

Modified: cfe/trunk/lib/AST/ASTTypeTraits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTTypeTraits.cpp?rev=186422&r1=186421&r2=186422&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTTypeTraits.cpp (original)
+++ cfe/trunk/lib/AST/ASTTypeTraits.cpp Tue Jul 16 10:47:24 2013
@@ -20,6 +20,8 @@ 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" },





More information about the cfe-commits mailing list