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