ymandel created this revision.
ymandel added a reviewer: gribozavr.
Herald added a project: clang.
ymandel edited the summary of this revision.

Removes the `isEqual` method from StencilPartInterface and modifies equality to
use the string representation returned by the `toString` method for comparison.

This means the `run` and `selection` stencils return true by default, and
clients should be cautious in relying on equality operator for comparison of
stencils containing parts generated by these functions.

It also means we no longer need the custom RTTI support, so it has been removed.

Patch by Harshal T. Lehri.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68825

Files:
  clang/include/clang/Tooling/Transformer/Stencil.h
  clang/lib/Tooling/Transformer/Stencil.cpp
  clang/unittests/Tooling/StencilTest.cpp

Index: clang/unittests/Tooling/StencilTest.cpp
===================================================================
--- clang/unittests/Tooling/StencilTest.cpp
+++ clang/unittests/Tooling/StencilTest.cpp
@@ -375,19 +375,30 @@
   EXPECT_NE(Lhs, Rhs);
 }
 
-// node is opaque and therefore cannot be examined for equality.
-TEST(StencilEqualityTest, InEqualitySelection) {
-  auto S1 = cat(node("node"));
-  auto S2 = cat(node("node"));
-  EXPECT_NE(S1, S2);
-}
-
-// `run` is opaque.
-TEST(StencilEqualityTest, InEqualityRun) {
-  auto F = [](const MatchResult &R) { return "foo"; };
-  auto S1 = cat(run(F));
-  auto S2 = cat(run(F));
-  EXPECT_NE(S1, S2);
+// For stencils generated by `selection`, equality returns true by default
+// even if different selectors are used in the stencils.
+TEST(StencilEqualityTest, EqualitySelection) {
+  auto S1 = cat(node("node1"));
+  auto S1Dup = cat(node("node1"));
+  auto S2 = cat(node("node2"));
+  auto T = cat("foo");
+  EXPECT_EQ(S1, S1Dup);
+  EXPECT_EQ(S1, S2);
+  EXPECT_NE(S1, T);
+}
+
+// For stencils generated by `run`, equality returns true by default even if
+// different functions are used in the stencils.
+TEST(StencilEqualityTest, EqualityRun) {
+  auto F1 = [](const MatchResult &R) { return "foo"; };
+  auto F2 = [](const MatchResult &R) { return "bar"; };
+  auto S1 = cat(run(F1));
+  auto S1Dup = cat(run(F1));
+  auto S2 = cat(run(F2));
+  auto T = cat("foo");
+  EXPECT_EQ(S1, S1Dup);
+  EXPECT_EQ(S1, S2);
+  EXPECT_NE(S1, T);
 }
 
 TEST(StencilToStringTest, RawTextOp) {
Index: clang/lib/Tooling/Transformer/Stencil.cpp
===================================================================
--- clang/lib/Tooling/Transformer/Stencil.cpp
+++ clang/lib/Tooling/Transformer/Stencil.cpp
@@ -31,14 +31,6 @@
 using llvm::Expected;
 using llvm::StringError;
 
-// A down_cast function to safely down cast a StencilPartInterface to a subclass
-// D. Returns nullptr if P is not an instance of D.
-template <typename D> const D *down_cast(const StencilPartInterface *P) {
-  if (P == nullptr || D::typeId() != P->typeId())
-    return nullptr;
-  return static_cast<const D *>(P);
-}
-
 static llvm::Expected<DynTypedNode>
 getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
   auto &NodesMap = Nodes.getMap();
@@ -100,35 +92,6 @@
   StencilPart FalsePart;
 };
 
-bool isEqualData(const RawTextData &A, const RawTextData &B) {
-  return A.Text == B.Text;
-}
-
-bool isEqualData(const DebugPrintNodeData &A, const DebugPrintNodeData &B) {
-  return A.Id == B.Id;
-}
-
-bool isEqualData(const UnaryOperationData &A, const UnaryOperationData &B) {
-  return A.Op == B.Op && A.Id == B.Id;
-}
-
-// Equality is not (yet) defined for \c RangeSelector.
-bool isEqualData(const SelectorData &, const SelectorData &) { return false; }
-
-bool isEqualData(const AccessData &A, const AccessData &B) {
-  return A.BaseId == B.BaseId && A.Member == B.Member;
-}
-
-bool isEqualData(const IfBoundData &A, const IfBoundData &B) {
-  return A.Id == B.Id && A.TruePart == B.TruePart && A.FalsePart == B.FalsePart;
-}
-
-// Equality is not defined over MatchConsumers, which are opaque.
-bool isEqualData(const MatchConsumer<std::string> &A,
-                 const MatchConsumer<std::string> &B) {
-  return false;
-}
-
 std::string toStringData(const RawTextData &Data) {
   std::string Result;
   llvm::raw_string_ostream OS(Result);
@@ -275,28 +238,13 @@
 
 public:
   template <typename... Ps>
-  explicit StencilPartImpl(Ps &&... Args)
-      : StencilPartInterface(StencilPartImpl::typeId()),
-        Data(std::forward<Ps>(Args)...) {}
-
-  // Generates a unique identifier for this class (specifically, one per
-  // instantiation of the template).
-  static const void* typeId() {
-    static bool b;
-    return &b;
-  }
+  explicit StencilPartImpl(Ps &&... Args) : Data(std::forward<Ps>(Args)...) {}
 
   Error eval(const MatchFinder::MatchResult &Match,
              std::string *Result) const override {
     return evalData(Data, Match, Result);
   }
 
-  bool isEqual(const StencilPartInterface &Other) const override {
-    if (const auto *OtherPtr = down_cast<StencilPartImpl>(&Other))
-      return isEqualData(Data, OtherPtr->Data);
-    return false;
-  }
-
   std::string toString() const override { return toStringData(Data); }
 };
 } // namespace
Index: clang/include/clang/Tooling/Transformer/Stencil.h
===================================================================
--- clang/include/clang/Tooling/Transformer/Stencil.h
+++ clang/include/clang/Tooling/Transformer/Stencil.h
@@ -48,26 +48,18 @@
   virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
                            std::string *Result) const = 0;
 
-  virtual bool isEqual(const StencilPartInterface &other) const = 0;
-
   /// Constructs a string representation of the StencilPart. StencilParts
   /// generated by the `selection` and `run` functions do not have a unique
   /// string representation.
   virtual std::string toString() const = 0;
 
-  const void *typeId() const { return TypeId; }
-
 protected:
-  StencilPartInterface(const void *DerivedId) : TypeId(DerivedId) {}
+  StencilPartInterface() = default;
 
   // Since this is an abstract class, copying/assigning only make sense for
   // derived classes implementing `clone()`.
   StencilPartInterface(const StencilPartInterface &) = default;
   StencilPartInterface &operator=(const StencilPartInterface &) = default;
-
-  /// Unique identifier of the concrete type of this instance.  Supports safe
-  /// downcasting.
-  const void *TypeId;
 };
 
 /// A copyable facade for a std::unique_ptr<StencilPartInterface>. Copies result
@@ -88,7 +80,7 @@
       return true;
     if (Impl == nullptr || Other.Impl == nullptr)
       return false;
-    return Impl->isEqual(*Other.Impl);
+    return Impl->toString() == Other.Impl->toString();
   }
 
   std::string toString() const {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D68825: [libToo... Yitzhak Mandelbaum via Phabricator via cfe-commits

Reply via email to