Index: cfe/trunk/include/clang/AST/ASTTypeTraits.h =================================================================== --- cfe/trunk/include/clang/AST/ASTTypeTraits.h +++ cfe/trunk/include/clang/AST/ASTTypeTraits.h @@ -145,6 +145,8 @@ template struct KindToKindId { static const NodeKindId Id = NKI_None; }; + template + struct KindToKindId : KindToKindId {}; /// \brief Per kind info. struct KindInfo { @@ -221,6 +223,14 @@ return BaseConverter::get(NodeKind, Storage.buffer); } + /// \brief Retrieve the stored node as type \c T. + /// + /// Similar to \c get(), but asserts that the type is what we are expecting. + template + const T &getUnchecked() const { + return BaseConverter::getUnchecked(NodeKind, Storage.buffer); + } + ASTNodeKind getNodeKind() const { return NodeKind; } /// \brief Returns a pointer that identifies the stored AST node. @@ -251,14 +261,15 @@ return getMemoizationData() < Other.getMemoizationData(); } bool operator==(const DynTypedNode &Other) const { - if (!NodeKind.isBaseOf(Other.NodeKind) && - !Other.NodeKind.isBaseOf(NodeKind)) + // DynTypedNode::create() stores the exact kind of the node in NodeKind. + // If they contain the same node, their NodeKind must be the same. + if (!NodeKind.isSame(Other.NodeKind)) return false; // FIXME: Implement for other types. - if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { - return *get() == *Other.get(); - } + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return getUnchecked() == Other.getUnchecked(); + assert(getMemoizationData() && Other.getMemoizationData()); return getMemoizationData() == Other.getMemoizationData(); } @@ -274,10 +285,14 @@ /// \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)); + if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) + return cast(*reinterpret_cast(Storage)); return nullptr; } + static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { + assert(ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)); + return *cast(*reinterpret_cast(Storage)); + } static DynTypedNode create(const BaseT &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNode(Node); @@ -294,6 +309,10 @@ return *reinterpret_cast(Storage); return nullptr; } + static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { + assert(ASTNodeKind::getFromNodeKind().isSame(NodeKind)); + return **reinterpret_cast(Storage); + } static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind(); @@ -310,6 +329,10 @@ return reinterpret_cast(Storage); return nullptr; } + static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { + assert(ASTNodeKind::getFromNodeKind().isSame(NodeKind)); + return *reinterpret_cast(Storage); + } static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind(); Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -218,10 +218,7 @@ bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - if (const T *Node = DynNode.get()) { - return matches(*Node, Finder, Builder); - } - return false; + return matches(DynNode.getUnchecked(), Finder, Builder); } };