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:
SymbolTableListTraits()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.
getListOwner()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 
getList(ItemParentClass * Par)93   static ListTy &getList(ItemParentClass *Par) {
94     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
95   }
96 
getSymTab(ItemParentClass * Par)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);
toPtr(ValueSymbolTable * P)110   static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
toPtr(ValueSymbolTable & R)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