bool isSame(ASTNodeKind Other) const;
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
- bool isBaseOf(ASTNodeKind Other) const;
+ /// \param Distance If non-null, used to return the distance between \c this
+ /// and \c Other in the class hierarchy.
+ bool isBaseOf(ASTNodeKind Other, unsigned *Distance = 0) const;
/// \brief String representation of the kind.
StringRef asStringRef() const;
/// \brief Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
- static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+ /// \param Distance If non-null, used to return the distance between \c Base
+ /// and \c Derived in the class hierarchy.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
/// \brief Helper meta-function to convert a kind T to its enum value.
///
#include "clang/AST/TypeNodes.def"
};
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other) const {
- return isBaseOf(KindId, Other.KindId);
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
+ return isBaseOf(KindId, Other.KindId, Distance);
}
bool ASTNodeKind::isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived) {
+bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
+ unsigned *Distance) {
if (Base == NKI_None || Derived == NKI_None) return false;
- while (Derived != Base && Derived != NKI_None)
+ unsigned Dist = 0;
+ while (Derived != Base && Derived != NKI_None) {
Derived = AllKindInfo[Derived].ParentId;
+ ++Dist;
+ }
+ if (Distance)
+ *Distance = Dist;
return Derived == Base;
}
EXPECT_TRUE(DNT<Decl>().isSame(DNT<Decl>()));
}
+TEST(ASTNodeKind, BaseDistances) {
+ unsigned Distance = 1;
+ EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<Expr>(), &Distance));
+ EXPECT_EQ(0u, Distance);
+
+ EXPECT_TRUE(DNT<Stmt>().isBaseOf(DNT<IfStmt>(), &Distance));
+ EXPECT_EQ(1u, Distance);
+
+ Distance = 3;
+ EXPECT_TRUE(DNT<DeclaratorDecl>().isBaseOf(DNT<ParmVarDecl>(), &Distance));
+ EXPECT_EQ(2u, Distance);
+}
+
TEST(ASTNodeKind, SameBase) {
EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<CallExpr>()));
EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<BinaryOperator>()));