bkramer updated this revision to Diff 38023. bkramer added a comment. Update casts to avoid potential undefined behavior. Now every pointer goes through const void*.
http://reviews.llvm.org/D13946 Files: include/clang/AST/ASTTypeTraits.h unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp =================================================================== --- unittests/ASTMatchers/Dynamic/RegistryTest.cpp +++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp @@ -455,8 +455,8 @@ // Polymorphic. EXPECT_TRUE(hasCompletion( Comps, "hasDescendant(", - "Matcher<NestedNameSpecifier|NestedNameSpecifierLoc|QualType|...> " - "hasDescendant(Matcher<CXXCtorInitializer|NestedNameSpecifier|" + "Matcher<TemplateArgument|NestedNameSpecifier|NestedNameSpecifierLoc|...>" + " hasDescendant(Matcher<TemplateArgument|NestedNameSpecifier|" "NestedNameSpecifierLoc|...>)")); CompVector WhileComps = getCompletions("whileStmt", 0); Index: include/clang/AST/ASTTypeTraits.h =================================================================== --- include/clang/AST/ASTTypeTraits.h +++ include/clang/AST/ASTTypeTraits.h @@ -106,18 +106,25 @@ } }; + /// Check if the given ASTNodeKind identifies a type that offers pointer + /// identity. This is useful for the fast path in DynTypedNode. + bool hasPointerIdentity() const { + return KindId > NKI_LastKindWithoutPointerIdentity; + } + 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_LastKindWithoutPointerIdentity = NKI_TypeLoc, + NKI_CXXCtorInitializer, + NKI_NestedNameSpecifier, NKI_Decl, #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl, #include "clang/AST/DeclNodes.inc" @@ -238,7 +245,11 @@ /// 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 { return MemoizationData; } + const void *getMemoizationData() const { + return NodeKind.hasPointerIdentity() + ? *reinterpret_cast<void *const *>(Storage.buffer) + : nullptr; + } /// \brief Prints the node to the given output stream. void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; @@ -286,18 +297,19 @@ template <typename T, typename BaseT> struct DynCastPtrConverter { static const T *get(ASTNodeKind NodeKind, const char Storage[]) { if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)) - return cast<T>(*reinterpret_cast<BaseT *const *>(Storage)); + return cast<T>(static_cast<const BaseT *>( + *reinterpret_cast<const void *const *>(Storage))); return nullptr; } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)); - return *cast<T>(*reinterpret_cast<BaseT *const *>(Storage)); + return *cast<T>(static_cast<const BaseT *>( + *reinterpret_cast<const void *const *>(Storage))); } static DynTypedNode create(const BaseT &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNode(Node); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const BaseT * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -311,13 +323,13 @@ } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)); - return **reinterpret_cast<T *const *>(Storage); + return *static_cast<const T *>( + *reinterpret_cast<const void *const *>(Storage)); } static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const T * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -336,14 +348,12 @@ static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); - Result.MemoizationData = nullptr; new (Result.Storage.buffer) T(Node); return Result; } }; ASTNodeKind NodeKind; - const void *MemoizationData; /// \brief Stores the data of the node. /// @@ -353,12 +363,9 @@ /// \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; + llvm::AlignedCharArrayUnion<const void *, TemplateArgument, + NestedNameSpecifierLoc, QualType, + TypeLoc> Storage; }; template <typename T>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits