Properly link alias and function decls. This fixes PR2146

llvm-svn: 53154
This commit is contained in:
Anton Korobeynikov 2008-07-05 23:03:21 +00:00
parent a91c655ee5
commit 1bb56dedf5
1 changed files with 27 additions and 8 deletions

View File

@ -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) { for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
const Function *SF = I; // SrcFunction const Function *SF = I; // SrcFunction
Function *DF = 0; GlobalValue *DGV = 0;
Value *MappedDF; Value *MappedDF;
// If this function is internal or has no name, it doesn't participate in // If this function is internal or has no name, it doesn't participate in
// linkage. // linkage.
if (SF->hasName() && !SF->hasInternalLinkage()) { if (SF->hasName() && !SF->hasInternalLinkage()) {
// Check to see if may have to link the function. // Check to see if may have to link the function.
DF = Dest->getFunction(SF->getName()); DGV = Dest->getFunction(SF->getName());
if (DF && DF->hasInternalLinkage())
DF = 0;
} }
// 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 // If there is no linkage to be performed, just bring over SF without
// modifying it. // modifying it.
if (DF == 0) { if (DGV == 0) {
// Function does not already exist, simply insert an function signature // Function does not already exist, simply insert an function signature
// identical to SF into the dest module. // identical to SF into the dest module.
Function *NewDF = Function::Create(SF->getFunctionType(), Function *NewDF = Function::Create(SF->getFunctionType(),
@ -930,9 +939,19 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
// ... and remember this mapping... // ... and remember this mapping...
ValueMap[SF] = NewDF; ValueMap[SF] = NewDF;
continue; 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 types don't agree because of opaque, try to resolve them.
if (SF->getType() != DF->getType()) if (SF->getType() != DF->getType())
RecursiveResolveTypes(SF->getType(), DF->getType()); RecursiveResolveTypes(SF->getType(), DF->getType());