1249259Sdim//===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- C++ -*--===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This file implements the stickier parts of the SymbolTableListTraits class,
11249259Sdim// and is explicitly instantiated where needed to avoid defining all this code
12249259Sdim// in a widely used header.
13249259Sdim//
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim
16249259Sdim#ifndef LLVM_SYMBOLTABLELISTTRAITS_IMPL_H
17249259Sdim#define LLVM_SYMBOLTABLELISTTRAITS_IMPL_H
18249259Sdim
19249259Sdim#include "llvm/IR/SymbolTableListTraits.h"
20249259Sdim#include "llvm/IR/ValueSymbolTable.h"
21249259Sdim
22249259Sdimnamespace llvm {
23249259Sdim
24249259Sdim/// setSymTabObject - This is called when (f.e.) the parent of a basic block
25249259Sdim/// changes.  This requires us to remove all the instruction symtab entries from
26249259Sdim/// the current function and reinsert them into the new function.
27249259Sdimtemplate<typename ValueSubClass, typename ItemParentClass>
28249259Sdimtemplate<typename TPtr>
29249259Sdimvoid SymbolTableListTraits<ValueSubClass,ItemParentClass>
30249259Sdim::setSymTabObject(TPtr *Dest, TPtr Src) {
31249259Sdim  // Get the old symtab and value list before doing the assignment.
32249259Sdim  ValueSymbolTable *OldST = TraitsClass::getSymTab(getListOwner());
33249259Sdim
34249259Sdim  // Do it.
35249259Sdim  *Dest = Src;
36249259Sdim
37249259Sdim  // Get the new SymTab object.
38249259Sdim  ValueSymbolTable *NewST = TraitsClass::getSymTab(getListOwner());
39249259Sdim
40249259Sdim  // If there is nothing to do, quick exit.
41249259Sdim  if (OldST == NewST) return;
42249259Sdim
43249259Sdim  // Move all the elements from the old symtab to the new one.
44249259Sdim  iplist<ValueSubClass> &ItemList = TraitsClass::getList(getListOwner());
45249259Sdim  if (ItemList.empty()) return;
46249259Sdim
47249259Sdim  if (OldST) {
48249259Sdim    // Remove all entries from the previous symtab.
49249259Sdim    for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
50249259Sdim         I != ItemList.end(); ++I)
51249259Sdim      if (I->hasName())
52249259Sdim        OldST->removeValueName(I->getValueName());
53249259Sdim  }
54249259Sdim
55249259Sdim  if (NewST) {
56249259Sdim    // Add all of the items to the new symtab.
57249259Sdim    for (typename iplist<ValueSubClass>::iterator I = ItemList.begin();
58249259Sdim         I != ItemList.end(); ++I)
59249259Sdim      if (I->hasName())
60249259Sdim        NewST->reinsertValue(I);
61249259Sdim  }
62249259Sdim
63249259Sdim}
64249259Sdim
65249259Sdimtemplate<typename ValueSubClass, typename ItemParentClass>
66249259Sdimvoid SymbolTableListTraits<ValueSubClass,ItemParentClass>
67249259Sdim::addNodeToList(ValueSubClass *V) {
68249259Sdim  assert(V->getParent() == 0 && "Value already in a container!!");
69249259Sdim  ItemParentClass *Owner = getListOwner();
70249259Sdim  V->setParent(Owner);
71249259Sdim  if (V->hasName())
72249259Sdim    if (ValueSymbolTable *ST = TraitsClass::getSymTab(Owner))
73249259Sdim      ST->reinsertValue(V);
74249259Sdim}
75249259Sdim
76249259Sdimtemplate<typename ValueSubClass, typename ItemParentClass>
77249259Sdimvoid SymbolTableListTraits<ValueSubClass,ItemParentClass>
78249259Sdim::removeNodeFromList(ValueSubClass *V) {
79249259Sdim  V->setParent(0);
80249259Sdim  if (V->hasName())
81249259Sdim    if (ValueSymbolTable *ST = TraitsClass::getSymTab(getListOwner()))
82249259Sdim      ST->removeValueName(V->getValueName());
83249259Sdim}
84249259Sdim
85249259Sdimtemplate<typename ValueSubClass, typename ItemParentClass>
86249259Sdimvoid SymbolTableListTraits<ValueSubClass,ItemParentClass>
87249259Sdim::transferNodesFromList(ilist_traits<ValueSubClass> &L2,
88249259Sdim                        ilist_iterator<ValueSubClass> first,
89249259Sdim                        ilist_iterator<ValueSubClass> last) {
90249259Sdim  // We only have to do work here if transferring instructions between BBs
91249259Sdim  ItemParentClass *NewIP = getListOwner(), *OldIP = L2.getListOwner();
92249259Sdim  if (NewIP == OldIP) return;  // No work to do at all...
93249259Sdim
94249259Sdim  // We only have to update symbol table entries if we are transferring the
95249259Sdim  // instructions to a different symtab object...
96249259Sdim  ValueSymbolTable *NewST = TraitsClass::getSymTab(NewIP);
97249259Sdim  ValueSymbolTable *OldST = TraitsClass::getSymTab(OldIP);
98249259Sdim  if (NewST != OldST) {
99249259Sdim    for (; first != last; ++first) {
100249259Sdim      ValueSubClass &V = *first;
101249259Sdim      bool HasName = V.hasName();
102249259Sdim      if (OldST && HasName)
103249259Sdim        OldST->removeValueName(V.getValueName());
104249259Sdim      V.setParent(NewIP);
105249259Sdim      if (NewST && HasName)
106249259Sdim        NewST->reinsertValue(&V);
107249259Sdim    }
108249259Sdim  } else {
109249259Sdim    // Just transferring between blocks in the same function, simply update the
110249259Sdim    // parent fields in the instructions...
111249259Sdim    for (; first != last; ++first)
112249259Sdim      first->setParent(NewIP);
113249259Sdim  }
114249259Sdim}
115249259Sdim
116249259Sdim} // End llvm namespace
117249259Sdim
118249259Sdim#endif
119