Convert to SymbolTable's new iteration interface.
[oota-llvm.git] / lib / VMCore / Linker.cpp
index 0be840fb6cd8189df793db59ab5325435e788857..6220140afe372e85c7e5c7e9301015e1c9c3c1b4 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/Linker.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/iOther.h"
-#include "llvm/Constants.h"
+#include "llvm/Assembly/Writer.h"
+using namespace llvm;
 
 // Error - Simple wrapper function to conditionally assign to E and return true.
 // This just makes error return conditions a little bit simpler...
@@ -170,22 +172,21 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) {
   const SymbolTable *SrcST  = &Src->getSymbolTable();
 
   // Look for a type plane for Type's...
-  SymbolTable::const_iterator PI = SrcST->find(Type::TypeTy);
-  if (PI == SrcST->end()) return false;  // No named types, do nothing.
+  SymbolTable::type_const_iterator TI = SrcST->type_begin();
+  SymbolTable::type_const_iterator TE = SrcST->type_end();
+  if (TI == TE) return false;  // No named types, do nothing.
 
   // Some types cannot be resolved immediately because they depend on other
   // types being resolved to each other first.  This contains a list of types we
   // are waiting to recheck.
   std::vector<std::string> DelayedTypesToResolve;
 
-  const SymbolTable::VarMap &VM = PI->second;
-  for (SymbolTable::type_const_iterator I = VM.begin(), E = VM.end();
-       I != E; ++I) {
-    const std::string &Name = I->first;
-    Type *RHS = cast<Type>(I->second);
+  for ( ; TI != TE; ++TI ) {
+    const std::string &Name = TI->first;
+    Type *RHS = TI->second;
 
     // Check to see if this type name is already in the dest module...
-    Type *Entry = cast_or_null<Type>(DestST->lookup(Type::TypeTy, Name));
+    Type *Entry = DestST->lookupType(Name);
 
     if (ResolveTypes(Entry, RHS, DestST, Name)) {
       // They look different, save the types 'till later to resolve.
@@ -201,8 +202,8 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) {
     // Try direct resolution by name...
     for (unsigned i = 0; i != DelayedTypesToResolve.size(); ++i) {
       const std::string &Name = DelayedTypesToResolve[i];
-      Type *T1 = cast<Type>(VM.find(Name)->second);
-      Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
+      Type *T1 = SrcST->lookupType(Name);
+      Type *T2 = DestST->lookupType(Name);
       if (!ResolveTypes(T2, T1, DestST, Name)) {
         // We are making progress!
         DelayedTypesToResolve.erase(DelayedTypesToResolve.begin()+i);
@@ -216,8 +217,8 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) {
       // two types: { int* } and { opaque* }
       for (unsigned i = 0, e = DelayedTypesToResolve.size(); i != e; ++i) {
         const std::string &Name = DelayedTypesToResolve[i];
-        PATypeHolder T1(cast<Type>(VM.find(Name)->second));
-        PATypeHolder T2(cast<Type>(DestST->lookup(Type::TypeTy, Name)));
+        PATypeHolder T1(SrcST->lookupType(Name));
+        PATypeHolder T2(DestST->lookupType(Name));
 
         if (!RecursiveResolveTypes(T2, T1, DestST, Name)) {
           // We are making progress!
@@ -234,10 +235,14 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) {
       if (DelayedTypesToResolve.size() == OldSize) {
         const std::string &Name = DelayedTypesToResolve.back();
         
-        const Type *T1 = cast<Type>(VM.find(Name)->second);
-        const Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
+        const Type *T1 = SrcST->lookupType(Name);
+        const Type *T2 = DestST->lookupType(Name);
         std::cerr << "WARNING: Type conflict between types named '" << Name
-                  <<  "'.\n    Src='" << *T1 << "'.\n   Dest='" << *T2 << "'\n";
+                  <<  "'.\n    Src='";
+        WriteTypeSymbolic(std::cerr, T1, Src);
+        std::cerr << "'.\n   Dest='";
+        WriteTypeSymbolic(std::cerr, T2, Dest);
+        std::cerr << "'\n";
 
         // Remove the symbol name from the destination.
         DelayedTypesToResolve.pop_back();
@@ -278,7 +283,8 @@ static Value *RemapOperand(const Value *In,
 
   // Check to see if it's a constant that we are interesting in transforming...
   if (const Constant *CPV = dyn_cast<Constant>(In)) {
-    if (!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV))
+    if ((!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV)) ||
+        isa<ConstantAggregateZero>(CPV))
       return const_cast<Constant*>(CPV);   // Simple constants stay identical...
 
     Constant *Result = 0;
@@ -318,12 +324,14 @@ static Value *RemapOperand(const Value *In,
         assert(CE->getOpcode() == Instruction::Cast);
         Value *V = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
         Result = ConstantExpr::getCast(cast<Constant>(V), CE->getType());
-      } else if (CE->getOpcode() == Instruction::Shl ||
-                 CE->getOpcode() == Instruction::Shr) {      // Shift
+      } else if (CE->getNumOperands() == 3) {
+        // Select instruction
+        assert(CE->getOpcode() == Instruction::Select);
         Value *V1 = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
         Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap);
-        Result = ConstantExpr::getShift(CE->getOpcode(), cast<Constant>(V1),
-                                        cast<Constant>(V2));
+        Value *V3 = RemapOperand(CE->getOperand(2), LocalMap, GlobalMap);
+        Result = ConstantExpr::getSelect(cast<Constant>(V1), cast<Constant>(V2),
+                                         cast<Constant>(V3));
       } else if (CE->getNumOperands() == 2) {
         // Binary operator...
         Value *V1 = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
@@ -374,29 +382,29 @@ static GlobalValue *FindGlobalNamed(const std::string &Name, const Type *Ty,
   // It doesn't exist exactly, scan through all of the type planes in the symbol
   // table, checking each of them for a type-compatible version.
   //
-  for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I)
-    if (I->first != Type::TypeTy) {
-      SymbolTable::VarMap &VM = I->second;
+  for (SymbolTable::plane_iterator PI = ST->plane_begin(), PE = ST->plane_end(); 
+       PI != PE; ++PI) {
+    SymbolTable::ValueMap &VM = PI->second;
 
-      // Does this type plane contain an entry with the specified name?
-      SymbolTable::type_iterator TI = VM.find(Name);
-      if (TI != VM.end()) {
+    // Does this type plane contain an entry with the specified name?
+    SymbolTable::value_iterator VI = VM.find(Name);
+      if (VI != VM.end()) {
         //
         // Ensure that this type if placed correctly into the symbol table.
         //
-        assert(TI->second->getType() == I->first && "Type conflict!");
+        assert(VI->second->getType() == PI->first && "Type conflict!");
 
         //
         // Save a reference to the new type.  Resolving the type can modify the
         // symbol table, invalidating the TI variable.
         //
-        Value *ValPtr = TI->second;
+        Value *ValPtr = VI->second;
 
         //
         // Determine whether we can fold the two types together, resolving them.
         // If so, we can use this value.
         //
-        if (!RecursiveResolveTypes(Ty, I->first, ST, ""))
+        if (!RecursiveResolveTypes(Ty, PI->first, ST, ""))
           return cast<GlobalValue>(ValPtr);
       }
     }
@@ -565,7 +573,6 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
 
       GlobalVariable *DGV = cast<GlobalVariable>(ValueMap[SGV]);    
       if (DGV->hasInitializer()) {
-        assert(SGV->getLinkage() == DGV->getLinkage());
         if (SGV->hasExternalLinkage()) {
           if (DGV->getInitializer() != SInit)
             return Error(Err, "Global Variable Collision on '" + 
@@ -574,6 +581,9 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
         } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
           // Nothing is required, mapped values will take the new global
           // automatically.
+        } else if (SGV->hasLinkOnceLinkage() || SGV->hasWeakLinkage()) {
+          // Nothing is required, mapped values will take the new global
+          // automatically.
         } else if (DGV->hasAppendingLinkage()) {
           assert(0 && "Appending linkage unimplemented!");
         } else {
@@ -796,12 +806,24 @@ static bool LinkAppendingVars(Module *M,
 
       // Merge the initializer...
       Inits.reserve(NewSize);
-      ConstantArray *I = cast<ConstantArray>(G1->getInitializer());
-      for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
-        Inits.push_back(cast<Constant>(I->getValues()[i]));
-      I = cast<ConstantArray>(G2->getInitializer());
-      for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
-        Inits.push_back(cast<Constant>(I->getValues()[i]));
+      if (ConstantArray *I = dyn_cast<ConstantArray>(G1->getInitializer())) {
+        for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
+          Inits.push_back(cast<Constant>(I->getValues()[i]));
+      } else {
+        assert(isa<ConstantAggregateZero>(G1->getInitializer()));
+        Constant *CV = Constant::getNullValue(T1->getElementType());
+        for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
+          Inits.push_back(CV);
+      }
+      if (ConstantArray *I = dyn_cast<ConstantArray>(G2->getInitializer())) {
+        for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
+          Inits.push_back(cast<Constant>(I->getValues()[i]));
+      } else {
+        assert(isa<ConstantAggregateZero>(G2->getInitializer()));
+        Constant *CV = Constant::getNullValue(T2->getElementType());
+        for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
+          Inits.push_back(CV);
+      }
       NG->setInitializer(ConstantArray::get(NewType, Inits));
       Inits.clear();
 
@@ -835,7 +857,7 @@ static bool LinkAppendingVars(Module *M,
 // the problem.  Upon failure, the Dest module could be in a modified state, and
 // shouldn't be relied on to be consistent.
 //
-bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
+bool llvm::LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
   if (Dest->getEndianness() == Module::AnyEndianness)
     Dest->setEndianness(Src->getEndianness());
   if (Dest->getPointerSize() == Module::AnyPointerSize)
@@ -902,3 +924,4 @@ bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
   return false;
 }
 
+// vim: sw=2