diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-03-10 22:34:28 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-03-10 22:34:28 +0000 |
commit | 01f69399352380532d480f6749daed660f50b15c (patch) | |
tree | f94bc5992d27da697b0ac161ad36b049e46d7e19 /lib/Linker | |
parent | 8b9998ecc5fc6e25167e3903a974f7392f3c5c34 (diff) | |
download | external_llvm-01f69399352380532d480f6749daed660f50b15c.zip external_llvm-01f69399352380532d480f6749daed660f50b15c.tar.gz external_llvm-01f69399352380532d480f6749daed660f50b15c.tar.bz2 |
Properly link globals with aliases
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48179 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index e7183eb..33da668 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -462,8 +462,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, for (Module::const_global_iterator I = Src->global_begin(), E = Src->global_end(); I != E; ++I) { const GlobalVariable *SGV = I; - GlobalVariable *DGV = 0; - // Check to see if may have to link the global. + GlobalValue *DGV = 0; + + // Check to see if may have to link the global with the global if (SGV->hasName() && !SGV->hasInternalLinkage()) { DGV = Dest->getGlobalVariable(SGV->getName()); if (DGV && DGV->getType() != SGV->getType()) @@ -472,6 +473,15 @@ static bool LinkGlobals(Module *Dest, const Module *Src, &Dest->getTypeSymbolTable(), ""); } + // Check to see if may have to link the global with the alias + if (SGV->hasName() && !SGV->hasInternalLinkage()) { + DGV = Dest->getNamedAlias(SGV->getName()); + if (DGV && DGV->getType() != SGV->getType()) + // If types don't agree due to opaque types, try to resolve them. + RecursiveResolveTypes(SGV->getType(), DGV->getType(), + &Dest->getTypeSymbolTable(), ""); + } + if (DGV && DGV->hasInternalLinkage()) DGV = 0; @@ -526,26 +536,37 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // Keep track that this is an appending variable... AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV)); - } else { + } else if (GlobalAlias *DGA = dyn_cast<GlobalAlias>(DGV)) { + // SGV is global, but DGV is alias. The only valid mapping is when SGV is + // external declaration, which is effectively a no-op. Also make sure + // linkage is correct. + if (SGV->isDeclaration() && !LinkFromSrc) { + // Make sure to remember this mapping... + ValueMap.insert(std::make_pair(SGV, DGA)); + } else + return Error(Err, "Global-Alias Collision on '" + + ToStr(SGV->getType(), Src) +"':%"+SGV->getName()+ + " - symbol multiple defined"); + } else if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) { // Otherwise, perform the mapping as instructed by GetLinkageResult. if (LinkFromSrc) { // Propagate alignment, section, and visibility info. - CopyGVAttributes(DGV, SGV); + CopyGVAttributes(DGVar, SGV); // If the types don't match, and if we are to link from the source, nuke // DGV and create a new one of the appropriate type. - if (SGV->getType() != DGV->getType()) { + if (SGV->getType() != DGVar->getType()) { GlobalVariable *NewDGV = new GlobalVariable(SGV->getType()->getElementType(), - DGV->isConstant(), DGV->getLinkage(), - /*init*/0, DGV->getName(), Dest); - CopyGVAttributes(NewDGV, DGV); + DGVar->isConstant(), DGVar->getLinkage(), + /*init*/0, DGVar->getName(), Dest); + CopyGVAttributes(NewDGV, DGVar); DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, - DGV->getType())); - // DGV will conflict with NewDGV because they both had the same + DGVar->getType())); + // DGVar will conflict with NewDGV 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(); // If the symbol table renamed the global, but it is an externally // visible symbol, DGV must be an existing global with internal @@ -554,26 +575,26 @@ static bool LinkGlobals(Module *Dest, const Module *Src, !NewDGV->hasInternalLinkage()) ForceRenaming(NewDGV, SGV->getName()); - DGV = NewDGV; + DGVar = NewDGV; } // Inherit const as appropriate - DGV->setConstant(SGV->isConstant()); + DGVar->setConstant(SGV->isConstant()); // Set initializer to zero, so we can link the stuff later - DGV->setInitializer(0); + DGVar->setInitializer(0); } else { // Special case for const propagation - if (DGV->isDeclaration() && SGV->isConstant() && !DGV->isConstant()) - DGV->setConstant(true); + if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant()) + DGVar->setConstant(true); } // Set calculated linkage - DGV->setLinkage(NewLinkage); + DGVar->setLinkage(NewLinkage); // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, - ConstantExpr::getBitCast(DGV, + ConstantExpr::getBitCast(DGVar, SGV->getType()))); } } @@ -659,7 +680,7 @@ static bool LinkAlias(Module *Dest, const Module *Src, // Proceed to 'common' steps } else - return Error(Err, "Alias Collision on '" + + return Error(Err, "Global-Alias Collision on '" + ToStr(SGA->getType(), Src) +"':%"+SGA->getName()+ " - symbol multiple defined"); } else if (Function *DF = Dest->getFunction(SGA->getName())) { @@ -686,7 +707,7 @@ static bool LinkAlias(Module *Dest, const Module *Src, // Proceed to 'common' steps } else - return Error(Err, "Alias Collision on '" + + return Error(Err, "Function-Alias Collision on '" + ToStr(SGA->getType(), Src) +"':%"+SGA->getName()+ " - symbol multiple defined"); } else { |