From 0dbabb52a46d287d2381706c135fce222065c37d Mon Sep 17 00:00:00 2001 From: Samuel Benzaquen Date: Tue, 16 Jul 2013 15:47:24 +0000 Subject: [PATCH] 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 llvm-svn: 186422 --- clang/include/clang/AST/ASTFwd.h | 1 + clang/include/clang/AST/ASTTypeTraits.h | 211 ++++++++++++++++---------------- clang/lib/AST/ASTTypeTraits.cpp | 2 + 3 files changed, 107 insertions(+), 107 deletions(-) diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 27e7faa..4f32798 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -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 diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index fc09987..e0b67c4 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -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 { \ 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() 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 struct BaseConverter; + /// \brief Converter that uses dyn_cast from a stored BaseT*. + template struct DynCastPtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) + return dyn_cast(*reinterpret_cast(Storage)); + return NULL; + } + static DynTypedNode create(const BaseT &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + new (Result.Storage.buffer) const BaseT * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T* (by pointer). + template struct PtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return *reinterpret_cast(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + new (Result.Storage.buffer) const T * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T (by value). + template struct ValueConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return reinterpret_cast(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + 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 + KindsByPointer; + llvm::AlignedCharArrayUnion Storage; }; -// FIXME: Pull out abstraction for the following. -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(ASTNodeKind NodeKind, const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Decl &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) const Decl*(&Node); - return Result; - } -}; -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(ASTNodeKind NodeKind, const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Stmt &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) const Stmt*(&Node); - return Result; - } -}; -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(ASTNodeKind NodeKind, const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Type &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) const Type*(&Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const NestedNameSpecifier *get(ASTNodeKind NodeKind, - const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return *reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const NestedNameSpecifier &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) const NestedNameSpecifier*(&Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const NestedNameSpecifierLoc *get(ASTNodeKind NodeKind, - const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf( - NodeKind)) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const NestedNameSpecifierLoc &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) NestedNameSpecifierLoc(Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const QualType *get(ASTNodeKind NodeKind, const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const QualType &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) QualType(Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const TypeLoc *get(ASTNodeKind NodeKind, const char Storage[]) { - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const TypeLoc &Node) { - DynTypedNode Result; - Result.NodeKind = ASTNodeKind::getFromNodeKind(); - new (Result.Storage.buffer) TypeLoc(Node); - return Result; - } -}; +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifier, void> : public PtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + CXXCtorInitializer, void> : public PtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + TemplateArgument, void> : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifierLoc, + void> : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + TypeLoc, void> : public ValueConverter {}; + // 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 diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index 7f930b4..7cf0759 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -20,6 +20,8 @@ namespace ast_type_traits { const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { { NKI_None, "" }, + { NKI_None, "CXXCtorInitializer" }, + { NKI_None, "TemplateArgument" }, { NKI_None, "NestedNameSpecifier" }, { NKI_None, "NestedNameSpecifierLoc" }, { NKI_None, "QualType" }, -- 2.7.4