summaryrefslogtreecommitdiffstats
path: root/lib/Linker
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-03-05 23:08:16 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-03-05 23:08:16 +0000
commitb5a4bd86df527c7d164197906861d2ca6f48678d (patch)
treecec36cbec090ebdf6c26a4b2a3e7afee1df1bdd1 /lib/Linker
parentad2715e0d787feaecb66060ea638e373dee7f6fb (diff)
downloadexternal_llvm-b5a4bd86df527c7d164197906861d2ca6f48678d.zip
external_llvm-b5a4bd86df527c7d164197906861d2ca6f48678d.tar.gz
external_llvm-b5a4bd86df527c7d164197906861d2ca6f48678d.tar.bz2
Handle functions as targets during linking of aliases as well
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r--lib/Linker/LinkModules.cpp26
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 940e94f..c4e1c20 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -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.