Handle functions as targets during linking of aliases as well
authorAnton Korobeynikov <asl@math.spbu.ru>
Wed, 5 Mar 2008 23:08:16 +0000 (23:08 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Wed, 5 Mar 2008 23:08:16 +0000 (23:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47974 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Linker/LinkModules.cpp

index 940e94f79ce24c3692959d16766c16eb4cb7f819..c4e1c20b526b04602cddf7ac2fa7c00dc4ec1ef5 100644 (file)
@@ -623,6 +623,7 @@ static bool LinkAlias(Module *Dest, const Module *Src,
     } else if (GlobalVariable *DGV = Dest->getGlobalVariable(SGA->getName())) {
       RecursiveResolveTypes(SGA->getType(), DGV->getType(),
                             &Dest->getTypeSymbolTable(), "");
+
       // The only allowed way is to link alias with external declaration.
       if (DGV->isDeclaration()) {
         NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
@@ -649,7 +650,30 @@ static bool LinkAlias(Module *Dest, const Module *Src,
     } else if (Function *DF = Dest->getFunction(SGA->getName())) {
       RecursiveResolveTypes(SGA->getType(), DF->getType(),
                             &Dest->getTypeSymbolTable(), "");
-      assert(0 && "FIXME");
+
+      // The only allowed way is to link alias with external declaration.
+      if (DF->isDeclaration()) {
+        NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
+                                SGA->getName(), DAliasee, Dest);
+        CopyGVAttributes(NewGA, SGA);
+
+        // Any uses of DF need to change to NewGA, with cast, if needed.
+        if (SGA->getType() != DF->getType())
+          DF->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA,
+                                                          DF->getType()));
+        else
+          DF->replaceAllUsesWith(NewGA);
+
+        // DF will conflict with NewGA because they both had the same
+        // name. We must erase this now so ForceRenaming doesn't assert
+        // because DF might not have internal linkage.
+        DF->eraseFromParent();
+
+        // Proceed to 'common' steps
+      } else
+        return Error(Err, "Alias Collision on '" +
+                     ToStr(SGA->getType(), Src) +"':%"+SGA->getName()+
+                     " - symbol multiple defined");
     } else {
       // Nothing similar found, just copy alias into destination module.