Index: llvm/trunk/include/llvm/Bitcode/BitcodeReader.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/BitcodeReader.h +++ llvm/trunk/include/llvm/Bitcode/BitcodeReader.h @@ -66,7 +66,9 @@ bool ShouldLazyLoadMetadata); public: - ArrayRef getBuffer() const { return Buffer; } + StringRef getBuffer() const { + return StringRef((const char *)Buffer.begin(), Buffer.size()); + } /// Read the bitcode module and prepare for lazy deserialization of function /// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well. Index: llvm/trunk/test/CMakeLists.txt =================================================================== --- llvm/trunk/test/CMakeLists.txt +++ llvm/trunk/test/CMakeLists.txt @@ -48,6 +48,7 @@ llvm-lto2 llvm-mc llvm-mcmarkup + llvm-modextract llvm-nm llvm-objdump llvm-opt-report Index: llvm/trunk/test/lit.cfg =================================================================== --- llvm/trunk/test/lit.cfg +++ llvm/trunk/test/lit.cfg @@ -298,6 +298,7 @@ r"\bllvm-lto2\b", r"\bllvm-mc\b", r"\bllvm-mcmarkup\b", + r"\bllvm-modextract\b", r"\bllvm-nm\b", r"\bllvm-objdump\b", r"\bllvm-pdbdump\b", Index: llvm/trunk/test/tools/llvm-modextract/single.ll =================================================================== --- llvm/trunk/test/tools/llvm-modextract/single.ll +++ llvm/trunk/test/tools/llvm-modextract/single.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as -o %t %s +; RUN: llvm-modextract -n 0 -o - %t | llvm-dis | FileCheck %s +; RUN: not llvm-modextract -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s +; RUN: llvm-modextract -b -n 0 -o - %t | llvm-dis | FileCheck %s +; RUN: not llvm-modextract -b -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s + +; CHECK: define void @f() +; ERROR: llvm-modextract: error: module index out of range; bitcode file contains 1 module(s) + +define void @f() { + ret void +} Index: llvm/trunk/tools/LLVMBuild.txt =================================================================== --- llvm/trunk/tools/LLVMBuild.txt +++ llvm/trunk/tools/LLVMBuild.txt @@ -36,6 +36,7 @@ llvm-lto llvm-mc llvm-mcmarkup + llvm-modextract llvm-nm llvm-objdump llvm-pdbdump Index: llvm/trunk/tools/llvm-modextract/CMakeLists.txt =================================================================== --- llvm/trunk/tools/llvm-modextract/CMakeLists.txt +++ llvm/trunk/tools/llvm-modextract/CMakeLists.txt @@ -0,0 +1,10 @@ +set(LLVM_LINK_COMPONENTS + IRReader + BitWriter + Core + Support + ) + +add_llvm_tool(llvm-modextract + llvm-modextract.cpp + ) Index: llvm/trunk/tools/llvm-modextract/LLVMBuild.txt =================================================================== --- llvm/trunk/tools/llvm-modextract/LLVMBuild.txt +++ llvm/trunk/tools/llvm-modextract/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-modextract/LLVMBuild.txt --------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = llvm-modextract +parent = Tools +required_libraries = BitReader BitWriter Index: llvm/trunk/tools/llvm-modextract/llvm-modextract.cpp =================================================================== --- llvm/trunk/tools/llvm-modextract/llvm-modextract.cpp +++ llvm/trunk/tools/llvm-modextract/llvm-modextract.cpp @@ -0,0 +1,72 @@ +//===-- llvm-modextract.cpp - LLVM module extractor utility ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is for testing features that rely on multi-module bitcode files. +// It takes a multi-module bitcode file, extracts one of the modules and writes +// it to the output file. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ToolOutputFile.h" + +using namespace llvm; + +static cl::opt + BinaryExtract("b", cl::desc("Whether to perform binary extraction")); + +static cl::opt OutputFilename("o", cl::Required, + cl::desc("Output filename"), + cl::value_desc("filename")); + +static cl::opt + InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + +static cl::opt ModuleIndex("n", cl::Required, + cl::desc("Index of module to extract"), + cl::value_desc("index")); + +int main(int argc, char **argv) { + cl::ParseCommandLineOptions(argc, argv, "Module extractor"); + + ExitOnError ExitOnErr("llvm-modextract: error: "); + + std::unique_ptr MB = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename))); + std::vector Ms = ExitOnErr(getBitcodeModuleList(*MB)); + + LLVMContext Context; + if (ModuleIndex >= Ms.size()) { + errs() << "llvm-modextract: error: module index out of range; bitcode file " + "contains " + << Ms.size() << " module(s)\n"; + return 1; + } + + std::error_code EC; + std::unique_ptr Out( + new tool_output_file(OutputFilename, EC, sys::fs::F_None)); + ExitOnErr(errorCodeToError(EC)); + + if (BinaryExtract) { + SmallVector Header; + BitcodeWriter Writer(Header); + Out->os() << Header << Ms[ModuleIndex].getBuffer(); + return 0; + } + + std::unique_ptr M = ExitOnErr(Ms[ModuleIndex].parseModule(Context)); + WriteBitcodeToFile(M.get(), Out->os()); + + return 0; +}