diff options
Diffstat (limited to 'lib/Linker/LinkModules.cpp')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 9801966f9d..d2e13c91c4 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -29,6 +29,8 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace { + typedef SmallPtrSet<StructType*, 32> TypeSet; + class TypeMapTy : public ValueMapTypeRemapper { /// MappedTypes - This is a mapping from a source type to a destination type /// to use. @@ -49,6 +51,9 @@ class TypeMapTy : public ValueMapTypeRemapper { SmallPtrSet<StructType*, 16> DstResolvedOpaqueTypes; public: + TypeMapTy(TypeSet &Set) : DstStructTypesSet(Set) {} + + TypeSet &DstStructTypesSet; /// addTypeMapping - Indicate that the specified type in the destination /// module is conceptually equivalent to the specified type in the source /// module. @@ -325,13 +330,20 @@ Type *TypeMapTy::getImpl(Type *Ty) { StructType *STy = cast<StructType>(Ty); // If the type is opaque, we can just use it directly. - if (STy->isOpaque()) + if (STy->isOpaque()) { + // A named structure type from src module is used. Add it to the Set of + // identified structs in the destination module. + DstStructTypesSet.insert(STy); return *Entry = STy; + } // Otherwise we create a new type and resolve its body later. This will be // resolved by the top level of get(). SrcDefinitionsToResolve.push_back(STy); StructType *DTy = StructType::create(STy->getContext()); + // A new identified structure type was created. Add it to the set of + // identified structs in the destination module. + DstStructTypesSet.insert(DTy); DstResolvedOpaqueTypes.insert(DTy); return *Entry = DTy; } @@ -373,8 +385,8 @@ namespace { public: std::string ErrorMsg; - ModuleLinker(Module *dstM, Module *srcM, unsigned mode) - : DstM(dstM), SrcM(srcM), Mode(mode) { } + ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode) + : DstM(dstM), SrcM(srcM), TypeMap(Set), Mode(mode) { } bool run(); @@ -588,11 +600,6 @@ void ModuleLinker::computeTypeMapping() { SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(), SrcStructTypes.end()); - TypeFinder DstStructTypes; - DstStructTypes.run(*DstM, true); - SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(), - DstStructTypes.end()); - for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { StructType *ST = SrcStructTypes[i]; if (!ST->hasName()) continue; @@ -623,7 +630,7 @@ void ModuleLinker::computeTypeMapping() { // we prefer to take the '%C' version. So we are then left with both // '%C.1' and '%C' being used for the same types. This leads to some // variables using one type and some using the other. - if (!SrcStructTypesSet.count(DST) && DstStructTypesSet.count(DST)) + if (!SrcStructTypesSet.count(DST) && TypeMap.DstStructTypesSet.count(DST)) TypeMap.addTypeMapping(DST, ST); } @@ -1281,13 +1288,17 @@ bool ModuleLinker::run() { return false; } -Linker::Linker(Module *M) : Composite(M) {} +Linker::Linker(Module *M) : Composite(M) { + TypeFinder StructTypes; + StructTypes.run(*M, true); + IdentifiedStructTypes.insert(StructTypes.begin(), StructTypes.end()); +} Linker::~Linker() { } bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { - ModuleLinker TheLinker(Composite, Src, Mode); + ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode); if (TheLinker.run()) { if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; |