aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-05-10 14:41:43 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-05-10 14:41:43 +0000
commitcaa8ae8125124822b01ac21a8de186c13fcdd8f3 (patch)
treed853515101d3a727db36e0246ce5bdce04dfa9d9 /lib
parent1b2f72912fde45086bc2c5c00e78210661a419a5 (diff)
downloadexternal_llvm-caa8ae8125124822b01ac21a8de186c13fcdd8f3.zip
external_llvm-caa8ae8125124822b01ac21a8de186c13fcdd8f3.tar.gz
external_llvm-caa8ae8125124822b01ac21a8de186c13fcdd8f3.tar.bz2
Fix linking of internal aliases
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50950 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Linker/LinkModules.cpp83
1 files changed, 55 insertions, 28 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 57df014..3db5b09 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -627,20 +627,52 @@ static bool LinkAlias(Module *Dest, const Module *Src,
GlobalAlias *NewGA = NULL;
// Globals were already linked, thus we can just query ValueMap for variant
- // of SAliasee in Dest
+ // of SAliasee in Dest.
std::map<const Value*,Value*>::const_iterator VMI = ValueMap.find(SAliasee);
assert(VMI != ValueMap.end() && "Aliasee not linked");
GlobalValue* DAliasee = cast<GlobalValue>(VMI->second);
+ GlobalValue* DGV = NULL;
// Try to find something 'similar' to SGA in destination module.
- if (GlobalAlias *DGA = Dest->getNamedAlias(SGA->getName())) {
+ if (!DGV && !SGA->hasInternalLinkage()) {
+ DGV = Dest->getNamedAlias(SGA->getName());
+
+ // If types don't agree due to opaque types, try to resolve them.
+ if (DGV && DGV->getType() != SGA->getType())
+ if (RecursiveResolveTypes(SGA->getType(), DGV->getType(),
+ &Dest->getTypeSymbolTable(), ""))
+ return Error(Err, "Alias Collision on '" + SGA->getName()+
+ "': aliases have different types");
+ }
+
+ if (!DGV && !SGA->hasInternalLinkage()) {
+ DGV = Dest->getGlobalVariable(SGA->getName());
+
// If types don't agree due to opaque types, try to resolve them.
- if (RecursiveResolveTypes(SGA->getType(), DGA->getType(),
- &Dest->getTypeSymbolTable(), ""))
- return Error(Err, "Alias Collision on '" + SGA->getName()+
- "': aliases have different types");
+ if (DGV && DGV->getType() != SGA->getType())
+ if (RecursiveResolveTypes(SGA->getType(), DGV->getType(),
+ &Dest->getTypeSymbolTable(), ""))
+ return Error(Err, "Alias Collision on '" + SGA->getName()+
+ "': aliases have different types");
+ }
- // Now types are known to be the same, check whether aliasees equal. As
+ if (!DGV && !SGA->hasInternalLinkage()) {
+ DGV = Dest->getFunction(SGA->getName());
+
+ // If types don't agree due to opaque types, try to resolve them.
+ if (DGV && DGV->getType() != SGA->getType())
+ if (RecursiveResolveTypes(SGA->getType(), DGV->getType(),
+ &Dest->getTypeSymbolTable(), ""))
+ return Error(Err, "Alias Collision on '" + SGA->getName()+
+ "': aliases have different types");
+ }
+
+ // No linking to be performed on internal stuff.
+ if (DGV && DGV->hasInternalLinkage())
+ DGV = NULL;
+
+ if (GlobalAlias *DGA = dyn_cast_or_null<GlobalAlias>(DGV)) {
+ // Types are known to be the same, check whether aliasees equal. As
// globals are already linked we just need query ValueMap to find the
// mapping.
if (DAliasee == DGA->getAliasedGlobal()) {
@@ -653,47 +685,41 @@ static bool LinkAlias(Module *Dest, const Module *Src,
} else
return Error(Err, "Alias Collision on '" + SGA->getName()+
"': aliases have different aliasees");
- } else if (GlobalVariable *DGV = Dest->getGlobalVariable(SGA->getName())) {
- RecursiveResolveTypes(SGA->getType(), DGV->getType(),
- &Dest->getTypeSymbolTable(), "");
-
+ } else if (GlobalVariable *DGVar = dyn_cast_or_null<GlobalVariable>(DGV)) {
// The only allowed way is to link alias with external declaration.
- if (DGV->isDeclaration()) {
+ if (DGVar->isDeclaration()) {
// But only if aliasee is global too...
if (!isa<GlobalVariable>(DAliasee))
- return Error(Err, "Global-Alias Collision on '" + SGA->getName() +
- "': aliasee is not global variable");
+ return Error(Err, "Global-Alias Collision on '" + SGA->getName() +
+ "': aliasee is not global variable");
NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
SGA->getName(), DAliasee, Dest);
CopyGVAttributes(NewGA, SGA);
// Any uses of DGV need to change to NewGA, with cast, if needed.
- if (SGA->getType() != DGV->getType())
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA,
- DGV->getType()));
+ if (SGA->getType() != DGVar->getType())
+ DGVar->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA,
+ DGVar->getType()));
else
- DGV->replaceAllUsesWith(NewGA);
+ DGVar->replaceAllUsesWith(NewGA);
- // DGV will conflict with NewGA because they both had the same
+ // DGVar will conflict with NewGA because they both had the same
// name. We must erase this now so ForceRenaming doesn't assert
// because DGV might not have internal linkage.
- DGV->eraseFromParent();
+ DGVar->eraseFromParent();
// Proceed to 'common' steps
} else
return Error(Err, "Global-Alias Collision on '" + SGA->getName() +
"': symbol multiple defined");
- } else if (Function *DF = Dest->getFunction(SGA->getName())) {
- RecursiveResolveTypes(SGA->getType(), DF->getType(),
- &Dest->getTypeSymbolTable(), "");
-
+ } else if (Function *DF = dyn_cast_or_null<Function>(DGV)) {
// The only allowed way is to link alias with external declaration.
if (DF->isDeclaration()) {
// But only if aliasee is function too...
if (!isa<Function>(DAliasee))
- return Error(Err, "Function-Alias Collision on '" + SGA->getName() +
- "': aliasee is not function");
+ return Error(Err, "Function-Alias Collision on '" + SGA->getName() +
+ "': aliasee is not function");
NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
SGA->getName(), DAliasee, Dest);
@@ -716,7 +742,8 @@ static bool LinkAlias(Module *Dest, const Module *Src,
return Error(Err, "Function-Alias Collision on '" + SGA->getName() +
"': symbol multiple defined");
} else {
- // Nothing similar found, just copy alias into destination module.
+ // No linking to be performed, simply create an identical version of the
+ // alias over in the dest module...
NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
SGA->getName(), DAliasee, Dest);
@@ -728,7 +755,7 @@ static bool LinkAlias(Module *Dest, const Module *Src,
assert(NewGA && "No alias was created in destination module!");
// If the symbol table renamed the alias, but it is an externally visible
- // symbol, DGV must be an global value with internal linkage. Rename it.
+ // symbol, DGA must be an global value with internal linkage. Rename it.
if (NewGA->getName() != SGA->getName() &&
!NewGA->hasInternalLinkage())
ForceRenaming(NewGA, SGA->getName());