//===-- SymbolTable.cpp - Implement the SymbolTable class -----------------===//
//
// This file implements the SymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "Support/StringExtras.h"
#include <algorithm>

#define DEBUG_SYMBOL_TABLE 0
#define DEBUG_ABSTYPE 0

SymbolTable::~SymbolTable() {
  // Drop all abstract type references in the type plane...
  iterator TyPlane = find(Type::TypeTy);
  if (TyPlane != end()) {
    VarMap &TyP = TyPlane->second;
    for (VarMap::iterator I = TyP.begin(), E = TyP.end(); I != E; ++I) {
      const Type *Ty = cast<Type>(I->second);
      if (Ty->isAbstract())   // If abstract, drop the reference...
	cast<DerivedType>(Ty)->removeAbstractTypeUser(this);
    }
  }

 // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the planes
 // that could still have entries!

#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator i = begin(); i != end(); ++i) {
    for (type_iterator I = i->second.begin(); I != i->second.end(); ++I)
      if (!isa<Constant>(I->second) && !isa<Type>(I->second)) {
	std::cerr << "Value still in symbol table! Type = '"
                  << i->first->getDescription() << "' Name = '"
                  << I->first << "'\n";
	LeftoverValues = false;
      }
  }
  
  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

// getUniqueName - Given a base name, return a string that is either equal to
// it (or derived from it) that does not already occur in the symbol table for
// the specified type.
//
std::string SymbolTable::getUniqueName(const Type *Ty,
                                       const std::string &BaseName) {
  iterator I = find(Ty);
  if (I == end()) return BaseName;

  std::string TryName = BaseName;
  unsigned Counter = 0;
  type_iterator End = I->second.end();

  while (I->second.find(TryName) != End)     // Loop until we find unoccupied
    TryName = BaseName + utostr(++Counter);  // Name in the symbol table
  return TryName;
}



// lookup - Returns null on failure...
Value *SymbolTable::lookup(const Type *Ty, const std::string &Name) {
  iterator I = find(Ty);
  if (I != end()) {                      // We have symbols in that plane...
    type_iterator J = I->second.find(Name);
    if (J != I->second.end())            // and the name is in our hash table...
      return J->second;
  }

  return 0;
}

void SymbolTable::remove(Value *N) {
  assert(N->hasName() && "Value doesn't have name!");
  if (InternallyInconsistent) return;

  iterator I = find(N->getType());
  assert(I != end() &&
         "Trying to remove a type that doesn't have a plane yet!");
  removeEntry(I, I->second.find(N->getName()));
}

// removeEntry - Remove a value from the symbol table...
//
Value *SymbolTable::removeEntry(iterator Plane, type_iterator Entry) {
  if (InternallyInconsistent) return 0;
  assert(Plane != super::end() &&
         Entry != Plane->second.end() && "Invalid entry to remove!");

  Value *Result = Entry->second;
  const Type *Ty = Result->getType();
#if DEBUG_SYMBOL_TABLE
  dump();
  std::cerr << " Removing Value: " << Result->getName() << "\n";
#endif

  // Remove the value from the plane...
  Plane->second.erase(Entry);

  // If the plane is empty, remove it now!
  if (Plane->second.empty()) {
    // If the plane represented an abstract type that we were interested in,
    // unlink ourselves from this plane.
    //
    if (Plane->first->isAbstract()) {
#if DEBUG_ABSTYPE
      std::cerr << "Plane Empty: Removing type: "
                << Plane->first->getDescription() << "\n";
#endif
      cast<DerivedType>(Plane->first)->removeAbstractTypeUser(this);
    }

    erase(Plane);
  }

  // If we are removing an abstract type, remove the symbol table from it's use
  // list...
  if (Ty == Type::TypeTy) {
    const Type *T = cast<Type>(Result);
    if (T->isAbstract()) {
#if DEBUG_ABSTYPE
      std::cerr << "Removing abs type from symtab" << T->getDescription()<<"\n";
#endif
      cast<DerivedType>(T)->removeAbstractTypeUser(this);
    }
  }

  return Result;
}

// insertEntry - Insert a value into the symbol table with the specified
// name...
//
void SymbolTable::insertEntry(const std::string &Name, const Type *VTy,
                              Value *V) {

  // Check to see if there is a naming conflict.  If so, rename this value!
  if (lookup(VTy, Name)) {
    std::string UniqueName = getUniqueName(VTy, Name);
    assert(InternallyInconsistent == false && "Infinite loop inserting entry!");
    InternallyInconsistent = true;
    V->setName(UniqueName, this);
    InternallyInconsistent = false;
    return;
  }

#if DEBUG_SYMBOL_TABLE
  dump();
  std::cerr << " Inserting definition: " << Name << ": " 
            << VTy->getDescription() << "\n";
#endif

  iterator I = find(VTy);
  if (I == end()) {      // Not in collection yet... insert dummy entry
    // Insert a new empty element.  I points to the new elements.
    I = super::insert(make_pair(VTy, VarMap())).first;
    assert(I != end() && "How did insert fail?");

    // Check to see if the type is abstract.  If so, it might be refined in the
    // future, which would cause the plane of the old type to get merged into
    // a new type plane.
    //
    if (VTy->isAbstract()) {
      cast<DerivedType>(VTy)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
      std::cerr << "Added abstract type value: " << VTy->getDescription()
                << "\n";
#endif
    }
  }

  I->second.insert(make_pair(Name, V));

  // If we are adding an abstract type, add the symbol table to it's use list.
  if (VTy == Type::TypeTy) {
    const Type *T = cast<Type>(V);
    if (T->isAbstract()) {
      cast<DerivedType>(T)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
      std::cerr << "Added abstract type to ST: " << T->getDescription() << "\n";
#endif
    }
  }
}

// This function is called when one of the types in the type plane are refined
void SymbolTable::refineAbstractType(const DerivedType *OldType,
				     const Type *NewType) {
  // Search to see if we have any values of the type oldtype.  If so, we need to
  // move them into the newtype plane...
  iterator TPI = find(OldType);
  if (TPI != end()) {
    // Get a handle to the new type plane...
    iterator NewTypeIt = find(NewType);
    if (NewTypeIt == super::end()) {      // If no plane exists, add one
      NewTypeIt = super::insert(make_pair(NewType, VarMap())).first;
      
      if (NewType->isAbstract()) {
        cast<DerivedType>(NewType)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
        std::cerr << "[Added] refined to abstype: " << NewType->getDescription()
                  << "\n";
#endif
      }
    }

    VarMap &NewPlane = NewTypeIt->second;
    VarMap &OldPlane = TPI->second;
    while (!OldPlane.empty()) {
      std::pair<const std::string, Value*> V = *OldPlane.begin();

      // Check to see if there is already a value in the symbol table that this
      // would collide with.
      type_iterator TI = NewPlane.find(V.first);
      if (TI != NewPlane.end() && TI->second == V.second) {
        // No action

      } else if (TI != NewPlane.end()) {
        // The only thing we are allowing for now is two external global values
        // folded into one.
        //
        GlobalValue *ExistGV = dyn_cast<GlobalValue>(TI->second);
        GlobalValue *NewGV = dyn_cast<GlobalValue>(V.second);

        if (ExistGV && NewGV) {
          assert((ExistGV->isExternal() || NewGV->isExternal()) &&
                 "Two planes folded together with overlapping value names!");

          // Make sure that ExistGV is the one we want to keep!
          if (!NewGV->isExternal())
            std::swap(NewGV, ExistGV);

          // Ok we have two external global values.  Make all uses of the new
          // one use the old one...
          NewGV->uncheckedReplaceAllUsesWith(ExistGV);
          
          // Now we just convert it to an unnamed method... which won't get
          // added to our symbol table.  The problem is that if we call
          // setName on the method that it will try to remove itself from
          // the symbol table and die... because it's not in the symtab
          // right now.  To fix this, we have an internally consistent flag
          // that turns remove into a noop.  Thus the name will get null'd
          // out, but the symbol table won't get upset.
          //
          assert(InternallyInconsistent == false &&
                 "Symbol table already inconsistent!");
          InternallyInconsistent = true;

          // Remove newM from the symtab
          NewGV->setName("");
          InternallyInconsistent = false;

          // Now we can remove this global from the module entirely...
          Module *M = NewGV->getParent();
          if (Function *F = dyn_cast<Function>(NewGV))
            M->getFunctionList().remove(F);
          else
            M->getGlobalList().remove(cast<GlobalVariable>(NewGV));
          delete NewGV;
        }
      } else {
        insertEntry(V.first, NewType, V.second);

      }
      // Remove the item from the old type plane
      OldPlane.erase(OldPlane.begin());
    }

    // Ok, now we are not referencing the type anymore... take me off your user
    // list please!
#if DEBUG_ABSTYPE
    std::cerr << "Removing type " << OldType->getDescription() << "\n";
#endif
    OldType->removeAbstractTypeUser(this);

    // Remove the plane that is no longer used
    erase(TPI);
  }

  TPI = find(Type::TypeTy);
  if (TPI != end()) {  
    // Loop over all of the types in the symbol table, replacing any references
    // to OldType with references to NewType.  Note that there may be multiple
    // occurrences, and although we only need to remove one at a time, it's
    // faster to remove them all in one pass.
    //
    VarMap &TyPlane = TPI->second;
    for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I)
      if (I->second == (Value*)OldType) {  // FIXME when Types aren't const.
#if DEBUG_ABSTYPE
        std::cerr << "Removing type " << OldType->getDescription() << "\n";
#endif
        OldType->removeAbstractTypeUser(this);
        
        I->second = (Value*)NewType;  // TODO FIXME when types aren't const
        if (NewType->isAbstract()) {
#if DEBUG_ABSTYPE
          std::cerr << "Added type " << NewType->getDescription() << "\n";
#endif
          cast<DerivedType>(NewType)->addAbstractTypeUser(this);
        }
      }
  }
}

void SymbolTable::typeBecameConcrete(const DerivedType *AbsTy) {
  iterator TPI = find(AbsTy);

  // If there are any values in the symbol table of this type, then the type
  // plan is a use of the abstract type which must be dropped.
  if (TPI != end())
    AbsTy->removeAbstractTypeUser(this);

  TPI = find(Type::TypeTy);
  if (TPI != end()) {  
    // Loop over all of the types in the symbol table, dropping any abstract
    // type user entries for AbsTy which occur because there are names for the
    // type.
    //
    VarMap &TyPlane = TPI->second;
    for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I)
      if (I->second == (Value*)AbsTy)   // FIXME when Types aren't const.
        AbsTy->removeAbstractTypeUser(this);
  }
}

static void DumpVal(const std::pair<const std::string, Value *> &V) {
  std::cout << "  '" << V.first << "' = ";
  V.second->dump();
  std::cout << "\n";
}

static void DumpPlane(const std::pair<const Type *,
                                      std::map<const std::string, Value *> >&P){
  std::cout << "  Plane: ";
  P.first->dump();
  std::cout << "\n";
  for_each(P.second.begin(), P.second.end(), DumpVal);
}

void SymbolTable::dump() const {
  std::cout << "Symbol table dump:\n";
  for_each(begin(), end(), DumpPlane);
}
