Ensure MDNode used as key in metadata linking map cannot be RAUWed
[oota-llvm.git] / include / llvm / IR / SymbolTableListTraits.h
index 9a7f28d0d467846b1e40506d8bf79748ff2240ae..5fc48d10d63f817d92aa409a0725b9ebec032a2f 100644 (file)
@@ -34,26 +34,61 @@ template <typename NodeTy> class ilist_iterator;
 template <typename NodeTy, typename Traits> class iplist;
 template <typename Ty> struct ilist_traits;
 
+template <typename NodeTy>
+struct SymbolTableListSentinelTraits
+    : public ilist_embedded_sentinel_traits<NodeTy> {};
+
+/// Template metafunction to get the parent type for a symbol table list.
+///
+/// Implementations create a typedef called \c type so that we only need a
+/// single template parameter for the list and traits.
+template <typename NodeTy> struct SymbolTableListParentType {};
+class Argument;
+class BasicBlock;
+class Function;
+class Instruction;
+class GlobalVariable;
+class GlobalAlias;
+class Module;
+#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT)                          \
+  template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; };
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
+DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
+#undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
+
+template <typename NodeTy> class SymbolTableList;
+
 // ValueSubClass   - The type of objects that I hold, e.g. Instruction.
 // ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
 //
-template<typename ValueSubClass, typename ItemParentClass>
-class SymbolTableListTraits : public ilist_default_traits<ValueSubClass> {
-  typedef ilist_traits<ValueSubClass> TraitsClass;
+template <typename ValueSubClass>
+class SymbolTableListTraits
+    : public ilist_nextprev_traits<ValueSubClass>,
+      public SymbolTableListSentinelTraits<ValueSubClass>,
+      public ilist_node_traits<ValueSubClass> {
+  typedef SymbolTableList<ValueSubClass> ListTy;
+  typedef
+      typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass;
+
 public:
   SymbolTableListTraits() {}
 
+private:
   /// getListOwner - Return the object that owns this list.  If this is a list
   /// of instructions, it returns the BasicBlock that owns them.
   ItemParentClass *getListOwner() {
     size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
                            getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
-    iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this));
+    ListTy *Anchor(static_cast<ListTy *>(this));
     return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
                                               Offset);
   }
 
-  static iplist<ValueSubClass> &getList(ItemParentClass *Par) {
+  static ListTy &getList(ItemParentClass *Par) {
     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
   }
 
@@ -61,9 +96,10 @@ public:
     return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
   }
 
+public:
   void addNodeToList(ValueSubClass *V);
   void removeNodeFromList(ValueSubClass *V);
-  void transferNodesFromList(ilist_traits<ValueSubClass> &L2,
+  void transferNodesFromList(SymbolTableListTraits &L2,
                              ilist_iterator<ValueSubClass> first,
                              ilist_iterator<ValueSubClass> last);
 //private:
@@ -73,6 +109,14 @@ public:
   static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
 };
 
+/// List that automatically updates parent links and symbol tables.
+///
+/// When nodes are inserted into and removed from this list, the associated
+/// symbol table will be automatically updated.  Similarly, parent links get
+/// updated automatically.
+template <typename NodeTy>
+class SymbolTableList : public iplist<NodeTy, SymbolTableListTraits<NodeTy>> {};
+
 } // End llvm namespace
 
 #endif