One side-effect per line.

http://reviews.llvm.org/D5577

Files:
  include/clang/AST/ASTTypeTraits.h
  lib/AST/ASTTypeTraits.cpp
  lib/ASTMatchers/Dynamic/VariantValue.cpp
  unittests/AST/ASTTypeTraitsTest.cpp
Index: include/clang/AST/ASTTypeTraits.h
===================================================================
--- include/clang/AST/ASTTypeTraits.h
+++ include/clang/AST/ASTTypeTraits.h
@@ -64,9 +64,12 @@
   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;
+
+  /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
   /// \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 = nullptr) const;
+  bool isBaseOf(ASTNodeKind Other, unsigned &Distance) const;
 
   /// \brief String representation of the kind.
   StringRef asStringRef() const;
@@ -100,15 +103,11 @@
     NKI_NumberOfKinds
   };
 
+  struct NodeParentMap;
+
   /// \brief Use getFromNodeKind<T>() to construct the kind.
   ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
 
-  /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
-  ///   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.
   ///
   /// This struct is specialized below for all known kinds.
Index: lib/AST/ASTTypeTraits.cpp
===================================================================
--- lib/AST/ASTTypeTraits.cpp
+++ lib/AST/ASTTypeTraits.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "llvm/Support/ManagedStatic.h"
 
 namespace clang {
 namespace ast_type_traits {
@@ -39,27 +40,37 @@
 #include "clang/AST/TypeNodes.def"
 };
 
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
-  return isBaseOf(KindId, Other.KindId, Distance);
+struct ASTNodeKind::NodeParentMap {
+  NodeParentMap() {
+    for (unsigned Node = NKI_None; Node < NKI_NumberOfKinds; ++Node) {
+      for (unsigned Parent = NKI_None; Parent < NKI_NumberOfKinds; ++Parent)
+        ParentDistances[Node][Parent] = -1U;
+      unsigned Distance = 0;
+      for (unsigned Parent = Node; Parent != NKI_None;
+           Parent = ASTNodeKind::AllKindInfo[Parent].ParentId) {
+        ParentDistances[Node][Parent] = Distance;
+        ++Distance;
+      }
+    }
+  }
+
+  unsigned ParentDistances[NKI_NumberOfKinds][NKI_NumberOfKinds];
+};
+
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other) const {
+  static const NodeParentMap *Map = new NodeParentMap;
+  return Map->ParentDistances[Other.KindId][KindId] != -1U;
+}
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned &Distance) const {
+  static const NodeParentMap *Map = new NodeParentMap;
+  Distance = Map->ParentDistances[Other.KindId][KindId];
+  return Distance != -1U;
 }
 
 bool ASTNodeKind::isSame(ASTNodeKind Other) const {
   return KindId != NKI_None && KindId == Other.KindId;
 }
 
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
-                           unsigned *Distance) {
-  if (Base == NKI_None || Derived == NKI_None) return false;
-  unsigned Dist = 0;
-  while (Derived != Base && Derived != NKI_None) {
-    Derived = AllKindInfo[Derived].ParentId;
-    ++Dist;
-  }
-  if (Distance)
-    *Distance = Dist;
-  return Derived == Base;
-}
-
 StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
 
 ASTNodeKind ASTNodeKind::getFromNode(const Decl &D) {
Index: lib/ASTMatchers/Dynamic/VariantValue.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -41,7 +41,7 @@
     return true;
   }
   unsigned Distance;
-  if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance))
+  if (!MatcherKind.isBaseOf(To.MatcherKind, Distance))
     return false;
 
   if (Specificity)
Index: unittests/AST/ASTTypeTraitsTest.cpp
===================================================================
--- unittests/AST/ASTTypeTraitsTest.cpp
+++ unittests/AST/ASTTypeTraitsTest.cpp
@@ -36,14 +36,14 @@
 
 TEST(ASTNodeKind, BaseDistances) {
   unsigned Distance = 1;
-  EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<Expr>(), &Distance));
+  EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<Expr>(), Distance));
   EXPECT_EQ(0u, Distance);
 
-  EXPECT_TRUE(DNT<Stmt>().isBaseOf(DNT<IfStmt>(), &Distance));
+  EXPECT_TRUE(DNT<Stmt>().isBaseOf(DNT<IfStmt>(), Distance));
   EXPECT_EQ(1u, Distance);
 
   Distance = 3;
-  EXPECT_TRUE(DNT<DeclaratorDecl>().isBaseOf(DNT<ParmVarDecl>(), &Distance));
+  EXPECT_TRUE(DNT<DeclaratorDecl>().isBaseOf(DNT<ParmVarDecl>(), Distance));
   EXPECT_EQ(2u, Distance);
 }
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to