Home | History | Annotate | Download | only in IR
      1 //===-- llvm/SymbolTableListTraits.h - Traits for iplist --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines a generic class that is used to implement the automatic
     11 // symbol table manipulation that occurs when you put (for example) a named
     12 // instruction into a basic block.
     13 //
     14 // The way that this is implemented is by using a special traits class with the
     15 // intrusive list that makes up the list of instructions in a basic block.  When
     16 // a new element is added to the list of instructions, the traits class is
     17 // notified, allowing the symbol table to be updated.
     18 //
     19 // This generic class implements the traits class.  It must be generic so that
     20 // it can work for all uses it, which include lists of instructions, basic
     21 // blocks, arguments, functions, global variables, etc...
     22 //
     23 //===----------------------------------------------------------------------===//
     24 
     25 #ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H
     26 #define LLVM_IR_SYMBOLTABLELISTTRAITS_H
     27 
     28 #include "llvm/ADT/ilist.h"
     29 
     30 namespace llvm {
     31 class ValueSymbolTable;
     32 
     33 template <typename NodeTy> class ilist_iterator;
     34 template <typename NodeTy, typename Traits> class iplist;
     35 template <typename Ty> struct ilist_traits;
     36 
     37 template <typename NodeTy>
     38 struct SymbolTableListSentinelTraits
     39     : public ilist_embedded_sentinel_traits<NodeTy> {};
     40 
     41 /// Template metafunction to get the parent type for a symbol table list.
     42 ///
     43 /// Implementations create a typedef called \c type so that we only need a
     44 /// single template parameter for the list and traits.
     45 template <typename NodeTy> struct SymbolTableListParentType {};
     46 class Argument;
     47 class BasicBlock;
     48 class Function;
     49 class Instruction;
     50 class GlobalVariable;
     51 class GlobalAlias;
     52 class GlobalIFunc;
     53 class Module;
     54 #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT)                          \
     55   template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; };
     56 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
     57 DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
     58 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
     59 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
     60 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
     61 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
     62 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
     63 #undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
     64 
     65 template <typename NodeTy> class SymbolTableList;
     66 
     67 // ValueSubClass   - The type of objects that I hold, e.g. Instruction.
     68 // ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
     69 //
     70 template <typename ValueSubClass>
     71 class SymbolTableListTraits
     72     : public ilist_nextprev_traits<ValueSubClass>,
     73       public SymbolTableListSentinelTraits<ValueSubClass>,
     74       public ilist_node_traits<ValueSubClass> {
     75   typedef SymbolTableList<ValueSubClass> ListTy;
     76   typedef
     77       typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass;
     78 
     79 public:
     80   SymbolTableListTraits() {}
     81 
     82 private:
     83   /// getListOwner - Return the object that owns this list.  If this is a list
     84   /// of instructions, it returns the BasicBlock that owns them.
     85   ItemParentClass *getListOwner() {
     86     size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
     87                            getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
     88     ListTy *Anchor(static_cast<ListTy *>(this));
     89     return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
     90                                               Offset);
     91   }
     92 
     93   static ListTy &getList(ItemParentClass *Par) {
     94     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
     95   }
     96 
     97   static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
     98     return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
     99   }
    100 
    101 public:
    102   void addNodeToList(ValueSubClass *V);
    103   void removeNodeFromList(ValueSubClass *V);
    104   void transferNodesFromList(SymbolTableListTraits &L2,
    105                              ilist_iterator<ValueSubClass> first,
    106                              ilist_iterator<ValueSubClass> last);
    107 //private:
    108   template<typename TPtr>
    109   void setSymTabObject(TPtr *, TPtr);
    110   static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
    111   static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
    112 };
    113 
    114 /// List that automatically updates parent links and symbol tables.
    115 ///
    116 /// When nodes are inserted into and removed from this list, the associated
    117 /// symbol table will be automatically updated.  Similarly, parent links get
    118 /// updated automatically.
    119 template <typename NodeTy>
    120 class SymbolTableList : public iplist<NodeTy, SymbolTableListTraits<NodeTy>> {};
    121 
    122 } // End llvm namespace
    123 
    124 #endif
    125