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 #include "llvm/ADT/simple_ilist.h"
     30 #include <cstddef>
     31 
     32 namespace llvm {
     33 
     34 class Argument;
     35 class BasicBlock;
     36 class Function;
     37 class GlobalAlias;
     38 class GlobalIFunc;
     39 class GlobalVariable;
     40 class Instruction;
     41 class Module;
     42 class ValueSymbolTable;
     43 
     44 /// Template metafunction to get the parent type for a symbol table list.
     45 ///
     46 /// Implementations create a typedef called \c type so that we only need a
     47 /// single template parameter for the list and traits.
     48 template <typename NodeTy> struct SymbolTableListParentType {};
     49 
     50 #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT)                          \
     51   template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
     52 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
     53 DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
     54 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
     55 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
     56 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
     57 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
     58 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
     59 #undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
     60 
     61 template <typename NodeTy> class SymbolTableList;
     62 
     63 // ValueSubClass   - The type of objects that I hold, e.g. Instruction.
     64 // ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
     65 //
     66 template <typename ValueSubClass>
     67 class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
     68   using ListTy = SymbolTableList<ValueSubClass>;
     69   using iterator = typename simple_ilist<ValueSubClass>::iterator;
     70   using ItemParentClass =
     71       typename SymbolTableListParentType<ValueSubClass>::type;
     72 
     73 public:
     74   SymbolTableListTraits() = default;
     75 
     76 private:
     77   /// getListOwner - Return the object that owns this list.  If this is a list
     78   /// of instructions, it returns the BasicBlock that owns them.
     79   ItemParentClass *getListOwner() {
     80     size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
     81                            getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
     82     ListTy *Anchor(static_cast<ListTy *>(this));
     83     return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
     84                                               Offset);
     85   }
     86 
     87   static ListTy &getList(ItemParentClass *Par) {
     88     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
     89   }
     90 
     91   static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
     92     return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
     93   }
     94 
     95 public:
     96   void addNodeToList(ValueSubClass *V);
     97   void removeNodeFromList(ValueSubClass *V);
     98   void transferNodesFromList(SymbolTableListTraits &L2, iterator first,
     99                              iterator last);
    100   // private:
    101   template<typename TPtr>
    102   void setSymTabObject(TPtr *, TPtr);
    103   static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
    104   static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
    105 };
    106 
    107 /// List that automatically updates parent links and symbol tables.
    108 ///
    109 /// When nodes are inserted into and removed from this list, the associated
    110 /// symbol table will be automatically updated.  Similarly, parent links get
    111 /// updated automatically.
    112 template <class T>
    113 class SymbolTableList
    114     : public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
    115 
    116 } // end namespace llvm
    117 
    118 #endif // LLVM_IR_SYMBOLTABLELISTTRAITS_H
    119