Object: Make IRObjectFile own multiple modules and enumerate symbols from all modules.
authorPeter Collingbourne <peter@pcc.me.uk>
Tue, 13 Dec 2016 20:20:17 +0000 (20:20 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Tue, 13 Dec 2016 20:20:17 +0000 (20:20 +0000)
This implements multi-module support in IRObjectFile.

Differential Revision: https://reviews.llvm.org/D26951

llvm-svn: 289578

llvm/include/llvm/Object/IRObjectFile.h
llvm/lib/Object/IRObjectFile.cpp
llvm/test/Object/Inputs/multi-module.ll [new file with mode: 0644]
llvm/test/Object/multi-module.ll [new file with mode: 0644]

index 744af7e..0ea8901 100644 (file)
@@ -28,9 +28,10 @@ namespace object {
 class ObjectFile;
 
 class IRObjectFile : public SymbolicFile {
-  std::unique_ptr<Module> M;
+  std::vector<std::unique_ptr<Module>> Mods;
   ModuleSymbolTable SymTab;
-  IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> M);
+  IRObjectFile(MemoryBufferRef Object,
+               std::vector<std::unique_ptr<Module>> Mods);
 
 public:
   ~IRObjectFile() override;
index 07296e8..2d055e1 100644 (file)
 using namespace llvm;
 using namespace object;
 
-IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
-    : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
-  SymTab.addModule(M.get());
+IRObjectFile::IRObjectFile(MemoryBufferRef Object,
+                           std::vector<std::unique_ptr<Module>> Mods)
+    : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
+  for (auto &M : this->Mods)
+    SymTab.addModule(M.get());
 }
 
 IRObjectFile::~IRObjectFile() {}
@@ -73,7 +75,11 @@ basic_symbol_iterator IRObjectFile::symbol_end() const {
   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
 }
 
-StringRef IRObjectFile::getTargetTriple() const { return M->getTargetTriple(); }
+StringRef IRObjectFile::getTargetTriple() const {
+  // Each module must have the same target triple, so we arbitrarily access the
+  // first one.
+  return Mods[0]->getTargetTriple();
+}
 
 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
   for (const SectionRef &Sec : Obj.sections()) {
@@ -108,19 +114,26 @@ ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Ob
 }
 
 Expected<std::unique_ptr<IRObjectFile>>
-llvm::object::IRObjectFile::create(MemoryBufferRef Object,
-                                   LLVMContext &Context) {
+IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
   if (!BCOrErr)
     return errorCodeToError(BCOrErr.getError());
 
-  Expected<std::unique_ptr<Module>> MOrErr =
-      getLazyBitcodeModule(*BCOrErr, Context,
-                           /*ShouldLazyLoadMetadata*/ true);
-  if (!MOrErr)
-    return MOrErr.takeError();
+  Expected<std::vector<BitcodeModule>> BMsOrErr =
+      getBitcodeModuleList(*BCOrErr);
+  if (!BMsOrErr)
+    return BMsOrErr.takeError();
+
+  std::vector<std::unique_ptr<Module>> Mods;
+  for (auto BM : *BMsOrErr) {
+    Expected<std::unique_ptr<Module>> MOrErr =
+        BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true);
+    if (!MOrErr)
+      return MOrErr.takeError();
+
+    Mods.push_back(std::move(*MOrErr));
+  }
 
-  std::unique_ptr<Module> &M = MOrErr.get();
   return std::unique_ptr<IRObjectFile>(
-      new IRObjectFile(*BCOrErr, std::move(M)));
+      new IRObjectFile(*BCOrErr, std::move(Mods)));
 }
diff --git a/llvm/test/Object/Inputs/multi-module.ll b/llvm/test/Object/Inputs/multi-module.ll
new file mode 100644 (file)
index 0000000..e4e9b82
--- /dev/null
@@ -0,0 +1,3 @@
+define void @f2() {
+  ret void
+}
diff --git a/llvm/test/Object/multi-module.ll b/llvm/test/Object/multi-module.ll
new file mode 100644 (file)
index 0000000..204ffc6
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: llvm-cat -o - %s %S/Inputs/multi-module.ll | llvm-nm - | FileCheck %s
+
+; CHECK: T f1
+; CHECK: T f2
+
+define void @f1() {
+  ret void
+}