[coco] Generalize isa<T> and safe_cast<T> (#2490)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 4 Dec 2018 08:58:46 +0000 (17:58 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 4 Dec 2018 08:58:46 +0000 (17:58 +0900)
With this commit, isa<T> and safe_cast<T> correctly works even in the
presence of "unknown" derived classes.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/coco/core/include/coco/IR/Instr.h
contrib/coco/core/src/IR/Instr.cpp

index 0a404cd..fc1cc33 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "coco/ADT/DLinkedList.h"
 
+#include <cassert>
 #include <stdexcept>
 
 namespace coco
@@ -137,7 +138,11 @@ private:
  *
  * @note "ins" cannot be a null pointer
  */
-template <typename T> bool isa(const Instr *ins);
+template <typename T> bool isa(const Instr *ins)
+{
+  assert(ins != nullptr);
+  return dynamic_cast<const T *>(ins) != nullptr;
+}
 
 /**
  * @brief Cast as a derived instruction
@@ -145,7 +150,11 @@ template <typename T> bool isa(const Instr *ins);
  * @note "safe_cast<T>(ins)" returns a null pointer if "ins" is not of T type
  * @note "safe_cast<T>(ins)" returns a null pointer if "ins" is a null pointer
  */
-template <typename T> T *safe_cast(Instr *ins);
+template <typename T> T *safe_cast(Instr *ins)
+{
+  // NOTE dynamic_cast<T *>(nullptr) returns nullptr
+  return dynamic_cast<T *>(ins);
+}
 
 } // namespace coco
 
index bc223f7..9f000ba 100644 (file)
@@ -53,24 +53,4 @@ template <> void DLinkedList<Instr, Block>::leaving(Block *, Instr *curr_ins)
 
 template <> InstrList *DLinkedList<Instr, Block>::head(Block *b) { return b->instr(); }
 
-//
-// isa<T>
-//
-#define INSTR(Name)                            \
-  template <> bool isa<Name>(const Instr *ins) \
-  {                                            \
-    assert(ins != nullptr);                    \
-    return ins->as##Name() != nullptr;         \
-  }
-#include "coco/IR/Instr.lst"
-#undef INSTR
-
-//
-// safe_cast<T>
-//
-#define INSTR(Name) \
-  template <> Name *safe_cast<Name>(Instr * ins) { return (ins) ? ins->as##Name() : nullptr; }
-#include "coco/IR/Instr.lst"
-#undef INSTR
-
 } // namespace coco