diff options
author | Chris Lattner <sabre@nondot.org> | 2007-04-29 07:54:31 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-04-29 07:54:31 +0000 |
commit | c453f76e2b4d7fd1e042b5b6d4c20556779186df (patch) | |
tree | a24882c0c4c773a77d7e16562335fe8364ffc47d | |
parent | 333ffd4abfcc3be32a945dc73c81adeafde1ba6b (diff) | |
download | llvm-c453f76e2b4d7fd1e042b5b6d4c20556779186df.tar.gz llvm-c453f76e2b4d7fd1e042b5b6d4c20556779186df.tar.bz2 llvm-c453f76e2b4d7fd1e042b5b6d4c20556779186df.tar.xz |
Switch the bitcode reader interface to take a MemoryBuffer instead of knowing
anything about disk I/O itself. This greatly simplifies its interface -
eliminating the need for the ReaderWrappers.cpp file.
This adds a new option to llvm-dis (-bitcode) which instructs it to read
the input file as bitcode. Until/unless the bytecode reader is taught to
read from MemoryBuffer, there is no way to handle stdin reading without it.
I don't plan to switch the bytecode reader over, I'd rather delete it :),
so the option will stay around temporarily.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36554 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Bitcode/ReaderWriter.h | 15 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 55 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 17 | ||||
-rw-r--r-- | lib/Bitcode/Reader/ReaderWrappers.cpp | 98 | ||||
-rw-r--r-- | tools/llvm-dis/llvm-dis.cpp | 30 |
5 files changed, 96 insertions, 119 deletions
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 0522f1bb28..a37cc7bf4c 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -20,15 +20,20 @@ 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. diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2a6de412cd..6157a5db5d 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Bitcode/ReaderWriter.h" #include "BitcodeReader.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Constants.h" @@ -18,8 +19,14 @@ #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> @@ -852,14 +859,14 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream, } -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' || @@ -882,7 +889,7 @@ bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length, // 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"); @@ -891,3 +898,41 @@ bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length, 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; +} diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 8e21134602..0935c06f93 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -22,6 +22,7 @@ namespace llvm { class BitstreamReader; + class MemoryBuffer; class BitcodeReaderValueList : public User { std::vector<Use> Uses; @@ -57,6 +58,7 @@ public: class BitcodeReader : public ModuleProvider { + MemoryBuffer *Buffer; const char *ErrorString; std::vector<PATypeHolder> TypeList; @@ -64,10 +66,16 @@ class BitcodeReader : public ModuleProvider { 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 @@ -89,8 +97,7 @@ public: /// @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); diff --git a/lib/Bitcode/Reader/ReaderWrappers.cpp b/lib/Bitcode/Reader/ReaderWrappers.cpp deleted file mode 100644 index 8bf81a2f83..0000000000 --- a/lib/Bitcode/Reader/ReaderWrappers.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//===- 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; -} diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index bb91ad6fce..6065e9ba5e 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -24,6 +24,7 @@ #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> @@ -44,6 +45,9 @@ Force("f", cl::desc("Overwrite output files")); 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 { @@ -55,12 +59,26 @@ int main(int argc, char **argv) { 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()) @@ -69,7 +87,7 @@ int main(int argc, char **argv) { 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? |