diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-05-10 14:41:43 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-05-10 14:41:43 +0000 |
commit | caa8ae8125124822b01ac21a8de186c13fcdd8f3 (patch) | |
tree | d853515101d3a727db36e0246ce5bdce04dfa9d9 /lib/Linker/LinkModules.cpp | |
parent | 1b2f72912fde45086bc2c5c00e78210661a419a5 (diff) | |
download | external_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/Linker/LinkModules.cpp')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 83 |
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()); |