eliminate residual cruft related to recognizing bytecode
[oota-llvm.git] / lib / Linker / LinkModules.cpp
index 83765345bb1d755c120e1094f50032062d187d29..462a4b7c6622c5d91718a61006c915356a11947f 100644 (file)
@@ -295,11 +295,11 @@ static Value *RemapOperand(const Value *In,
       Result = ConstantStruct::get(cast<StructType>(CPS->getType()), Operands);
     } else if (isa<ConstantPointerNull>(CPV) || isa<UndefValue>(CPV)) {
       Result = const_cast<Constant*>(CPV);
-    } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CPV)) {
+    } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CPV)) {
       std::vector<Constant*> Operands(CP->getNumOperands());
       for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
         Operands[i] = cast<Constant>(RemapOperand(CP->getOperand(i), ValueMap));
-      Result = ConstantPacked::get(Operands);
+      Result = ConstantVector::get(Operands);
     } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
       std::vector<Constant*> Ops;
       for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
@@ -337,18 +337,15 @@ static void ForceRenaming(GlobalValue *GV, const std::string &Name) {
   ValueSymbolTable &ST = GV->getParent()->getValueSymbolTable();
 
   // If there is a conflict, rename the conflict.
-  GlobalValue *ConflictGV = cast_or_null<GlobalValue>(ST.lookup(Name));
-  if (ConflictGV) {
+  if (GlobalValue *ConflictGV = cast_or_null<GlobalValue>(ST.lookup(Name))) {
     assert(ConflictGV->hasInternalLinkage() &&
            "Not conflicting with a static global, should link instead!");
-    ConflictGV->setName("");        // Eliminate the conflict
-  }
-  GV->setName(Name);              // Force the name back
-  if (ConflictGV) {
-    ConflictGV->setName(Name);      // This will cause ConflictGV to get renamed
+    GV->takeName(ConflictGV);
+    ConflictGV->setName(Name);    // This will cause ConflictGV to get renamed
     assert(ConflictGV->getName() != Name && "ForceRenaming didn't work");
+  } else {
+    GV->setName(Name);              // Force the name back
   }
-  assert(GV->getName() == Name && "ForceRenaming didn't work");
 }
 
 /// CopyGVAttributes - copy additional attributes (those not needed to construct
@@ -368,7 +365,9 @@ static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
 /// the result will look like in the destination module.  In particular, it
 /// computes the resultant linkage type, computes whether the global in the
 /// source should be copied over to the destination (replacing the existing
-/// one), and computes whether this linkage is an error or not.
+/// one), and computes whether this linkage is an error or not. It also performs
+/// visibility checks: we cannot link together two symbols with different
+/// visibilities.
 static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
                              GlobalValue::LinkageTypes &LT, bool &LinkFromSrc,
                              std::string *Err) {
@@ -438,6 +437,11 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
     return Error(Err, "Linking globals named '" + Src->getName() +
                  "': symbol multiply defined!");
   }
+
+  // Check visibility
+  if (Dest && Src->getVisibility() != Dest->getVisibility())
+    return Error(Err, "Linking globals named '" + Src->getName() +
+                 "': symbols have different visibilities!");
   return false;
 }
 
@@ -480,7 +484,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
       GlobalVariable *NewDGV =
         new GlobalVariable(SGV->getType()->getElementType(),
                            SGV->isConstant(), SGV->getLinkage(), /*init*/0,
-                           SGV->getName(), Dest);
+                           SGV->getName(), Dest, SGV->isThreadLocal());
       // Propagate alignment, visibility and section info.
       CopyGVAttributes(NewDGV, SGV);
 
@@ -503,7 +507,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
       GlobalVariable *NewDGV =
         new GlobalVariable(SGV->getType()->getElementType(),
                            SGV->isConstant(), SGV->getLinkage(), /*init*/0,
-                           "", Dest);
+                           "", Dest, SGV->isThreadLocal());
 
       // Propagate alignment, section and visibility  info.
       NewDGV->setAlignment(DGV->getAlignment());
@@ -525,6 +529,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
         GlobalVariable *NewDGV =
           new GlobalVariable(SGV->getType()->getElementType(),
                              DGV->isConstant(), DGV->getLinkage());
+        NewDGV->setThreadLocal(DGV->isThreadLocal());
         CopyGVAttributes(NewDGV, DGV);
         Dest->getGlobalList().insert(DGV, NewDGV);
         DGV->replaceAllUsesWith(
@@ -556,6 +561,30 @@ static bool LinkGlobals(Module *Dest, Module *Src,
   return false;
 }
 
+// LinkAlias - Loop through the alias in the src module and link them into the
+// dest module.
+static bool LinkAlias(Module *Dest, const Module *Src, std::string *Err) {
+  // Loop over all alias in the src module
+  for (Module::const_alias_iterator I = Src->alias_begin(),
+         E = Src->alias_end(); I != E; ++I) {
+    const GlobalAlias *GA = I;
+
+    GlobalValue *NewAliased = NULL;
+    const GlobalValue *Aliased = GA->getAliasedGlobal();
+    if (isa<GlobalVariable>(*Aliased))
+      NewAliased = Dest->getGlobalVariable(Aliased->getName());
+    else if (isa<Function>(*Aliased))
+      NewAliased = Dest->getFunction(Aliased->getName());
+    // FIXME: we should handle the bitcast alias.
+    assert(NewAliased && "Can't find the aliased GV.");
+
+    GlobalAlias *NewGA = new GlobalAlias(GA->getType(), GA->getLinkage(),
+                                         GA->getName(), NewAliased, Dest);
+    CopyGVAttributes(NewGA, GA);
+  }
+  return false;
+}
+
 
 // LinkGlobalInits - Update the initializers in the Dest module now that all
 // globals that may be referenced are in Dest.
@@ -619,6 +648,12 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
         RecursiveResolveTypes(SF->getType(), DF->getType(), 
                               &Dest->getTypeSymbolTable(), "");
     }
+
+    // Check visibility
+    if (DF && !DF->hasInternalLinkage() &&
+        SF->getVisibility() != DF->getVisibility())
+      return Error(Err, "Linking functions named '" + SF->getName() +
+                   "': symbols have different visibilities!");
     
     if (DF && DF->getType() != SF->getType()) {
       if (DF->isDeclaration() && !SF->isDeclaration()) {
@@ -816,6 +851,18 @@ static bool LinkAppendingVars(Module *M,
         return Error(ErrorMsg,
                      "Appending variables linked with different const'ness!");
 
+      if (G1->getAlignment() != G2->getAlignment())
+        return Error(ErrorMsg,
+         "Appending variables with different alignment need to be linked!");
+
+      if (G1->getVisibility() != G2->getVisibility())
+        return Error(ErrorMsg,
+         "Appending variables with different visibility need to be linked!");
+
+      if (G1->getSection() != G2->getSection())
+        return Error(ErrorMsg,
+         "Appending variables with different section name need to be linked!");
+      
       unsigned NewSize = T1->getNumElements() + T2->getNumElements();
       ArrayType *NewType = ArrayType::get(T1->getElementType(), NewSize);
 
@@ -824,7 +871,10 @@ static bool LinkAppendingVars(Module *M,
       // Create the new global variable...
       GlobalVariable *NG =
         new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(),
-                           /*init*/0, First->first, M);
+                           /*init*/0, First->first, M, G1->isThreadLocal());
+
+      // Propagate alignment, visibility and section info.
+      CopyGVAttributes(NG, G1);
 
       // Merge the initializer...
       Inits.reserve(NewSize);
@@ -979,6 +1029,9 @@ Linker::LinkModules(Module *Dest, Module *Src, std::string *ErrorMsg) {
   // If there were any appending global variables, link them together now.
   if (LinkAppendingVars(Dest, AppendingVars, ErrorMsg)) return true;
 
+  // If there were any alias, link them now.
+  if (LinkAlias(Dest, Src, ErrorMsg)) return true;
+
   // If the source library's module id is in the dependent library list of the
   // destination library, remove it since that module is now linked in.
   sys::Path modId;