namespace llvm {
class Module;
class ModuleProvider;
+ class MemoryBuffer;
- ModuleProvider *getBitcodeModuleProvider(const std::string &Filename,
+ /// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
+ /// and prepare for lazy deserialization of function bodies. If successful,
+ /// this takes ownership of 'buffer' and returns a non-null pointer. On
+ /// error, this returns null, *does not* take ownership of Buffer, and fills
+ /// in *ErrMsg with an error description if ErrMsg is non-null.
+ ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer,
std::string *ErrMsg = 0);
-
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
- /// If an error occurs, return null and fill in *ErrMsg if non-null.
- Module *ParseBitcodeFile(const std::string &Filename,
- std::string *ErrMsg = 0);
+ /// If an error occurs, this returns null and fills in *ErrMsg if it is
+ /// non-null. This method *never* takes ownership of Buffer.
+ Module *ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg = 0);
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
//
//===----------------------------------------------------------------------===//
+#include "llvm/Bitcode/ReaderWriter.h"
#include "BitcodeReader.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
using namespace llvm;
+BitcodeReader::~BitcodeReader() {
+ delete Buffer;
+}
+
+
/// ConvertToString - Convert a string from a record into an std::string, return
/// true on failure.
template<typename StrTy>
}
-bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length,
- const std::string &ModuleID) {
+bool BitcodeReader::ParseBitcode() {
TheModule = 0;
- if (Length & 3)
+ if (Buffer->getBufferSize() & 3)
return Error("Bitcode stream should be a multiple of 4 bytes in length");
- BitstreamReader Stream(Buf, Buf+Length);
+ unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+ BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
// We only know the MODULE subblock ID.
if (BlockID == bitc::MODULE_BLOCK_ID) {
- if (ParseModule(Stream, ModuleID))
+ if (ParseModule(Stream, Buffer->getBufferIdentifier()))
return true;
} else if (Stream.SkipBlock()) {
return Error("Malformed block record");
return false;
}
+
+//===----------------------------------------------------------------------===//
+// External interface
+//===----------------------------------------------------------------------===//
+
+/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
+///
+ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
+ std::string *ErrMsg) {
+ BitcodeReader *R = new BitcodeReader(Buffer);
+ if (R->ParseBitcode()) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ // Don't let the BitcodeReader dtor delete 'Buffer'.
+ R->releaseMemoryBuffer();
+ delete R;
+ return 0;
+ }
+ return R;
+}
+
+/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+/// If an error occurs, return null and fill in *ErrMsg if non-null.
+Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg){
+ BitcodeReader *R;
+ R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, ErrMsg));
+ if (!R) return 0;
+
+ // Read the whole module, get a pointer to it, tell ModuleProvider not to
+ // delete it when its dtor is run.
+ Module *M = R->releaseModule(ErrMsg);
+
+ // Don't let the BitcodeReader dtor delete 'Buffer'.
+ R->releaseMemoryBuffer();
+ delete R;
+ return M;
+}
namespace llvm {
class BitstreamReader;
+ class MemoryBuffer;
class BitcodeReaderValueList : public User {
std::vector<Use> Uses;
class BitcodeReader : public ModuleProvider {
+ MemoryBuffer *Buffer;
const char *ErrorString;
std::vector<PATypeHolder> TypeList;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
public:
- BitcodeReader() : ErrorString(0) {}
- virtual ~BitcodeReader() {}
+ BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {}
+ ~BitcodeReader();
- virtual void FreeState() {}
+
+ /// releaseMemoryBuffer - This causes the reader to completely forget about
+ /// the memory buffer it contains, which prevents the buffer from being
+ /// destroyed when it is deleted.
+ void releaseMemoryBuffer() {
+ Buffer = 0;
+ }
virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) {
// FIXME: TODO
/// @brief Main interface to parsing a bitcode buffer.
/// @returns true if an error occurred.
- bool ParseBitcode(unsigned char *Buf, unsigned Length,
- const std::string &ModuleID);
+ bool ParseBitcode();
private:
const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
+++ /dev/null
-//===- ReaderWrappers.cpp - Parse bitcode from file or buffer -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements loading and parsing a bitcode file and parsing a
-// module from a memory buffer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "BitcodeReader.h"
-#include "llvm/System/MappedFile.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// BitcodeFileReader - Read from an mmap'able file descriptor.
-
-namespace {
- /// BitcodeFileReader - parses bitcode from a file.
- ///
- class BitcodeFileReader : public BitcodeReader {
- private:
- std::string Filename;
- sys::MappedFile File;
-
- BitcodeFileReader(const BitcodeFileReader&); // DO NOT IMPLEMENT
- void operator=(const BitcodeFileReader&); // DO NOT IMPLEMENT
- public:
- BitcodeFileReader(const std::string &FN) : Filename(FN) {}
- bool Read(std::string *ErrMsg);
-
- void FreeState() {
- BitcodeReader::FreeState();
- File.close();
- }
- };
-}
-
-bool BitcodeFileReader::Read(std::string *ErrMsg) {
- if (File.open(sys::Path(Filename), sys::MappedFile::READ_ACCESS, ErrMsg))
- return true;
- if (!File.map(ErrMsg)) {
- File.close();
- return true;
- }
- unsigned char *Buffer = reinterpret_cast<unsigned char*>(File.base());
- if (!ParseBitcode(Buffer, File.size(), Filename))
- return false;
- assert(getErrorString() && "Didn't set an error string?");
- if (ErrMsg) *ErrMsg = getErrorString();
- return true;
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// External interface
-//===----------------------------------------------------------------------===//
-
-/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
-///
-ModuleProvider *llvm::getBitcodeModuleProvider(const std::string &Filename,
- std::string *ErrMsg) {
- if (Filename != std::string("-")) {
- BitcodeFileReader *R = new BitcodeFileReader(Filename);
- if (R->Read(ErrMsg)) {
- delete R;
- return 0;
- }
- return R;
- }
-
- assert(0 && "FIXME: stdin reading unimp!");
-#if 0
- // Read from stdin
- BytecodeStdinReader *R = new BytecodeStdinReader();
- if (R->Read(ErrMsg)) {
- delete R;
- return 0;
- }
- return R;
-#endif
-}
-
-/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
-/// If an error occurs, return null and fill in *ErrMsg if non-null.
-Module *llvm::ParseBitcodeFile(const std::string &Filename,std::string *ErrMsg){
- ModuleProvider *MP = getBitcodeModuleProvider(Filename, ErrMsg);
- if (!MP) return 0;
- Module *M = MP->releaseModule(ErrMsg);
- delete MP;
- return M;
-}
#include "llvm/Support/Compressor.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Signals.h"
#include <iostream>
static cl::opt<bool>
DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
+static cl::opt<bool>
+Bitcode("bitcode", cl::desc("Read a bitcode file"));
+
int main(int argc, char **argv) {
llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
try {
std::auto_ptr<Module> M;
- if (InputFilename != "-")
- M.reset(ParseBitcodeFile(InputFilename, &ErrorMessage));
-
- if (M.get() == 0)
- M.reset(ParseBytecodeFile(InputFilename,Compressor::decompressToNewBuffer,
+ if (Bitcode) {
+ MemoryBuffer *Buffer;
+ if (InputFilename == "-") {
+ Buffer = MemoryBuffer::getSTDIN();
+ } else {
+ Buffer = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size());
+ }
+
+ if (Buffer == 0)
+ ErrorMessage = "Error reading file '" + InputFilename + "'";
+ else
+ M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
+
+ delete Buffer;
+ } else {
+ M.reset(ParseBytecodeFile(InputFilename,
+ Compressor::decompressToNewBuffer,
&ErrorMessage));
+ }
+
if (M.get() == 0) {
cerr << argv[0] << ": ";
if (ErrorMessage.size())
cerr << "bytecode didn't read correctly.\n";
return 1;
}
-
+
if (DontPrint) {
// Just use stdout. We won't actually print anything on it.
} else if (OutputFilename != "") { // Specified an output filename?