diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-07-05 23:03:21 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-07-05 23:03:21 +0000 |
commit | fdeba113ac38aa3caaa858a34fbfdb32c5bdeb6f (patch) | |
tree | f963b917e2416cb74299ee8419f503c70fba0a4a /lib/Linker | |
parent | fc68de9959d8e3a3f245f8d98fa5473a031dc035 (diff) | |
download | external_llvm-fdeba113ac38aa3caaa858a34fbfdb32c5bdeb6f.zip external_llvm-fdeba113ac38aa3caaa858a34fbfdb32c5bdeb6f.tar.gz external_llvm-fdeba113ac38aa3caaa858a34fbfdb32c5bdeb6f.tar.bz2 |
Properly link alias and function decls. This fixes PR2146
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53154 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index e02f7fe..a915a8b 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -899,21 +899,30 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction - Function *DF = 0; + GlobalValue *DGV = 0; Value *MappedDF; // If this function is internal or has no name, it doesn't participate in // linkage. if (SF->hasName() && !SF->hasInternalLinkage()) { // Check to see if may have to link the function. - DF = Dest->getFunction(SF->getName()); - if (DF && DF->hasInternalLinkage()) - DF = 0; + DGV = Dest->getFunction(SF->getName()); } - + + // Check to see if may have to link the function with the alias + if (!DGV && SF->hasName() && !SF->hasInternalLinkage()) { + DGV = Dest->getNamedAlias(SF->getName()); + if (DGV && DGV->getType() != SF->getType()) + // If types don't agree due to opaque types, try to resolve them. + RecursiveResolveTypes(SF->getType(), DGV->getType()); + } + + if (DGV && DGV->hasInternalLinkage()) + DGV = 0; + // If there is no linkage to be performed, just bring over SF without // modifying it. - if (DF == 0) { + if (DGV == 0) { // Function does not already exist, simply insert an function signature // identical to SF into the dest module. Function *NewDF = Function::Create(SF->getFunctionType(), @@ -930,9 +939,19 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // ... and remember this mapping... ValueMap[SF] = NewDF; continue; + } else if (GlobalAlias *DGA = dyn_cast<GlobalAlias>(DGV)) { + // SF is global, but DF is alias. The only valid mapping is when SF is + // external declaration, which is effectively a no-op. + if (!SF->isDeclaration()) + return Error(Err, "Function-Alias Collision on '" + SF->getName() + + "': symbol multiple defined"); + + // Make sure to remember this mapping... + ValueMap[SF] = DGA; + continue; } - - + + Function* DF = cast<Function>(DGV); // If types don't agree because of opaque, try to resolve them. if (SF->getType() != DF->getType()) RecursiveResolveTypes(SF->getType(), DF->getType()); |