[loco] Simplify CanonicalNodeVisitor default fallback (#3945)
author박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Mon, 24 Jun 2019 07:44:42 +0000 (16:44 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Mon, 24 Jun 2019 07:44:42 +0000 (16:44 +0900)
This commit simplifies default visitor fallback implementation.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/loco/include/loco/IR/CanonicalNodeVisitor.h
contrib/loco/src/IR/CanonicalNode.test.cpp

index 727b73f..5d1e35d 100644 (file)
 namespace loco
 {
 
-struct ThrowNotImplemented
-{
-  /**
-   * GCC rejects the following implementation of "CanonicalNodeVisitorImpl::visit":
-   *
-   * virtual T visit(const CLASS *)
-   * {
-   *   Fallback f;
-   *   return f.call<T>();
-   * }
-   *
-   * Let us pass "nullptr" of T * type (which serves as a type tag) as a workaround.
-   *
-   * TODO Remove this workaround if possible
-   */
-  template <typename T> T call(const T *) const
-  {
-    // Throw NYI exception
-    throw std::runtime_error{"Not implemented, yet"};
-  }
-};
-
 /**
- * DO NOT use this class. Use CanonicalNodeVisitor or CanonicalNodeVisitorImpl instead.
+ * DO NOT use this class. Use CanonicalNodeVisitor instead.
  */
 template <typename T> struct CanonicalNodeVisitorBase
 {
@@ -58,25 +36,17 @@ template <typename T> struct CanonicalNodeVisitorBase
 #undef CANONICAL_NODE
 };
 
-template <typename T, typename Fallback>
-struct CanonicalNodeVisitorImpl : public CanonicalNodeVisitorBase<T>
+template <typename T> struct CanonicalNodeVisitor : public CanonicalNodeVisitorBase<T>
 {
-  virtual ~CanonicalNodeVisitorImpl() = default;
+  virtual ~CanonicalNodeVisitor() = default;
 
-#define CANONICAL_NODE(OPCODE, CLASS)               \
-  virtual T visit(const CLASS *)                    \
-  {                                                 \
-    Fallback f;                                     \
-    return f.call(static_cast<const T *>(nullptr)); \
-  }
+#define CANONICAL_NODE(OPCODE, CLASS) \
+  virtual T visit(const CLASS *node) { return visit(static_cast<const Node *>(node)); }
 #include "CanonicalNodes.lst"
 #undef CANONICAL_NODE
-};
 
-template <typename T>
-struct CanonicalNodeVisitor : public CanonicalNodeVisitorImpl<T, ThrowNotImplemented>
-{
-  virtual ~CanonicalNodeVisitor() = default;
+  /// @brief Default fallback
+  virtual T visit(const Node *) { throw std::runtime_error{"Not implemented, yet"}; }
 };
 
 } // namespace loco
index 6a6ab39..eadffef 100644 (file)
 
 TEST(CanonicalNodeTest, visitor_with_user_default_impl)
 {
-  struct MyFallback
-  {
-    uint32_t call(const uint32_t *) const { return 256; }
-  };
-
-  struct MyVisitor final : public loco::CanonicalNodeVisitorImpl<uint32_t, MyFallback>
+  struct MyVisitor final : public loco::CanonicalNodeVisitor<uint32_t>
   {
+    // This visitor returns 128 if it visits a Forward node.
     uint32_t visit(const loco::Forward *) final { return 128; }
+
+    // Otherwise, this visitor returns 256.
+    uint32_t visit(const loco::Node *) final { return 256; }
   };
 
   loco::Forward forward;