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" }, _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
