aboutsummaryrefslogtreecommitdiff
path: root/lib/Linker
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Linker')
-rw-r--r--lib/Linker/CMakeLists.txt1
-rw-r--r--lib/Linker/LinkModules.cpp63
-rw-r--r--lib/Linker/Linker.cpp91
3 files changed, 39 insertions, 116 deletions
diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt
index 28f1262a43..221b55a9c4 100644
--- a/lib/Linker/CMakeLists.txt
+++ b/lib/Linker/CMakeLists.txt
@@ -1,4 +1,3 @@
add_llvm_library(LLVMLinker
LinkModules.cpp
- Linker.cpp
)
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 2fdb8cc9cd..156b536353 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -13,21 +13,15 @@
#include "llvm/Linker.h"
#include "llvm-c/Linker.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
-#include <cctype>
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -35,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.
@@ -55,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.
@@ -331,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;
}
@@ -379,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();
@@ -594,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;
@@ -629,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);
}
@@ -1300,24 +1301,38 @@ bool ModuleLinker::run() {
return false;
}
+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, IdentifiedStructTypes, Src, Mode);
+ if (TheLinker.run()) {
+ if (ErrorMsg)
+ *ErrorMsg = TheLinker.ErrorMsg;
+ return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// LinkModules entrypoint.
//===----------------------------------------------------------------------===//
/// LinkModules - This function links two modules together, with the resulting
-/// left module modified to be the composite of the two input modules. If an
+/// Dest module modified to be the composite of the two input modules. If an
/// error occurs, true is returned and ErrorMsg (if not null) is set to indicate
/// the problem. Upon failure, the Dest module could be in a modified state,
/// and shouldn't be relied on to be consistent.
bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode,
std::string *ErrorMsg) {
- ModuleLinker TheLinker(Dest, Src, Mode);
- if (TheLinker.run()) {
- if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg;
- return true;
- }
-
- return false;
+ Linker L(Dest);
+ return L.linkInModule(Src, Mode, ErrorMsg);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp
deleted file mode 100644
index c8ea8ff0a9..0000000000
--- a/lib/Linker/Linker.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- lib/Linker/Linker.cpp - Basic Linker functionality ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains basic Linker functionality that all usages will need.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Linker.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-using namespace llvm;
-
-Linker::Linker(StringRef progname, StringRef modname,
- LLVMContext& C, unsigned flags):
- Context(C),
- Composite(new Module(modname, C)),
- LibPaths(),
- Flags(flags),
- Error(),
- ProgramName(progname) { }
-
-Linker::Linker(StringRef progname, Module* aModule, unsigned flags) :
- Context(aModule->getContext()),
- Composite(aModule),
- LibPaths(),
- Flags(flags),
- Error(),
- ProgramName(progname) { }
-
-Linker::~Linker() {
- delete Composite;
-}
-
-bool
-Linker::error(StringRef message) {
- Error = message;
- if (!(Flags&QuietErrors))
- errs() << ProgramName << ": error: " << message << "\n";
- return true;
-}
-
-bool
-Linker::warning(StringRef message) {
- Error = message;
- if (!(Flags&QuietWarnings))
- errs() << ProgramName << ": warning: " << message << "\n";
- return false;
-}
-
-void
-Linker::verbose(StringRef message) {
- if (Flags&Verbose)
- errs() << " " << message << "\n";
-}
-
-void
-Linker::addPath(const sys::Path& path) {
- LibPaths.push_back(path);
-}
-
-void
-Linker::addPaths(const std::vector<std::string>& paths) {
- for (unsigned i = 0, e = paths.size(); i != e; ++i)
- LibPaths.push_back(sys::Path(paths[i]));
-}
-
-void
-Linker::addSystemPaths() {
- sys::Path::GetBitcodeLibraryPaths(LibPaths);
- LibPaths.insert(LibPaths.begin(),sys::Path("./"));
-}
-
-Module*
-Linker::releaseModule() {
- Module* result = Composite;
- LibPaths.clear();
- Error.clear();
- Composite = 0;
- Flags = 0;
- return result;
-}