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
32namespace llvm {
33
34class Argument;
35class BasicBlock;
36class Function;
37class GlobalAlias;
38class GlobalIFunc;
39class GlobalVariable;
40class Instruction;
41class Module;
42class 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.
48template <typename NodeTy> struct SymbolTableListParentType {};
49
50#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \
51 template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
52DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
53DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
54DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
55DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
56DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
57DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
58DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
59#undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
60
61template <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//
66template <typename ValueSubClass>
67class 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
73public:
74 SymbolTableListTraits() = default;
75
76private:
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
95public:
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.
112template <class T>
113class SymbolTableList
114 : public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
115
116} // end namespace llvm
117
118#endif // LLVM_IR_SYMBOLTABLELISTTRAITS_H
119