--- /dev/null
+#ifndef __COCO_IR_DEF_HOOK_H__
+#define __COCO_IR_DEF_HOOK_H__
+
+#include "coco/IR/Object.h"
+#include "coco/IR/ObjectInfo.forward.h"
+
+#include "coco/ADT/PtrLink.h"
+
+namespace coco
+{
+
+class DefHook final
+{
+public:
+ DefHook(const PtrLink<Object, ObjectInfo> *obj_link, Object::Def *def)
+ : _obj_link{obj_link}, _def{def}
+ {
+ // DO NOTHING
+ }
+
+private:
+ ObjectInfo *info(Object *o) const;
+
+public:
+ void onTake(Object *o);
+ void onRelease(Object *o);
+
+private:
+ const PtrLink<Object, ObjectInfo> *const _obj_link;
+ Object::Def *const _def;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_DEF_HOOK_H__
--- /dev/null
+#include "coco/IR/DefHook.h"
+#include "coco/IR/ObjectInfo.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+ObjectInfo *DefHook::info(Object *o) const
+{
+ auto info = _obj_link->find(o);
+ assert(info != nullptr);
+ return info;
+}
+
+void DefHook::onTake(Object *o) { info(o)->def(_def); }
+void DefHook::onRelease(Object *o) { info(o)->def(nullptr); }
+
+} // namespace coco
--- /dev/null
+#include "coco/IR/DefHook.h"
+#include "coco/IR/ObjectInfo.h"
+#include "coco/IR/ObjectManager.h"
+
+#include "coco/IR/FeatureObject.h"
+
+#include <gtest/gtest.h>
+
+namespace
+{
+namespace mock
+{
+struct Def final : public coco::Object::Def
+{
+};
+} // namespace mock
+} // namespace
+
+namespace
+{
+class DefHookTest : public ::testing::Test
+{
+protected:
+ coco::PtrLink<coco::Bag, coco::BagInfo> bag_link;
+ coco::PtrLink<coco::Object, coco::ObjectInfo> obj_link;
+
+ coco::ObjectManager obj_mgr{&obj_link, &bag_link};
+};
+} // namespace
+
+TEST_F(DefHookTest, TakeAndRelease)
+{
+ auto o = obj_mgr.create(nncc::core::ADT::feature::Shape{1, 1, 1});
+
+ ::mock::Def use;
+
+ coco::DefHook hook{&obj_link, &use};
+
+ hook.onTake(o);
+ hook.onRelease(o);
+}