From: Peter Collingbourne Date: Sat, 23 Nov 2013 01:40:07 +0000 (+0000) Subject: Add Distance parameter to ASTNodeKind::isBaseOf. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6d601f912ea8fb367204f342f799196782195dd;p=clang Add Distance parameter to ASTNodeKind::isBaseOf. This will allow the completer to order results by relevance. Differential Revision: http://llvm-reviews.chandlerc.com/D2209 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195540 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index 087ad56090..f826436c6d 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -57,7 +57,9 @@ public: 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; @@ -91,7 +93,9 @@ private: /// \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. /// diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp index ae47ea9888..02d82d819e 100644 --- a/lib/AST/ASTTypeTraits.cpp +++ b/lib/AST/ASTTypeTraits.cpp @@ -39,18 +39,24 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { #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; } diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp index dd73b52206..634577c5e8 100644 --- a/unittests/AST/ASTTypeTraitsTest.cpp +++ b/unittests/AST/ASTTypeTraitsTest.cpp @@ -34,6 +34,19 @@ TEST(ASTNodeKind, Bases) { EXPECT_TRUE(DNT().isSame(DNT())); } +TEST(ASTNodeKind, BaseDistances) { + unsigned Distance = 1; + EXPECT_TRUE(DNT().isBaseOf(DNT(), &Distance)); + EXPECT_EQ(0u, Distance); + + EXPECT_TRUE(DNT().isBaseOf(DNT(), &Distance)); + EXPECT_EQ(1u, Distance); + + Distance = 3; + EXPECT_TRUE(DNT().isBaseOf(DNT(), &Distance)); + EXPECT_EQ(2u, Distance); +} + TEST(ASTNodeKind, SameBase) { EXPECT_TRUE(DNT().isBaseOf(DNT())); EXPECT_TRUE(DNT().isBaseOf(DNT()));