mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
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
This commit is contained in:
@@ -20,15 +20,20 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Module;
|
class Module;
|
||||||
class ModuleProvider;
|
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);
|
std::string *ErrMsg = 0);
|
||||||
|
|
||||||
|
|
||||||
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
||||||
/// If an error occurs, return null and fill in *ErrMsg if non-null.
|
/// If an error occurs, this returns null and fills in *ErrMsg if it is
|
||||||
Module *ParseBitcodeFile(const std::string &Filename,
|
/// non-null. This method *never* takes ownership of Buffer.
|
||||||
std::string *ErrMsg = 0);
|
Module *ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg = 0);
|
||||||
|
|
||||||
/// WriteBitcodeToFile - Write the specified module to the specified output
|
/// WriteBitcodeToFile - Write the specified module to the specified output
|
||||||
/// stream.
|
/// stream.
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Bitcode/ReaderWriter.h"
|
||||||
#include "BitcodeReader.h"
|
#include "BitcodeReader.h"
|
||||||
#include "llvm/Bitcode/BitstreamReader.h"
|
#include "llvm/Bitcode/BitstreamReader.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
@@ -18,8 +19,14 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
BitcodeReader::~BitcodeReader() {
|
||||||
|
delete Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ConvertToString - Convert a string from a record into an std::string, return
|
/// ConvertToString - Convert a string from a record into an std::string, return
|
||||||
/// true on failure.
|
/// true on failure.
|
||||||
template<typename StrTy>
|
template<typename StrTy>
|
||||||
@@ -852,14 +859,14 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length,
|
bool BitcodeReader::ParseBitcode() {
|
||||||
const std::string &ModuleID) {
|
|
||||||
TheModule = 0;
|
TheModule = 0;
|
||||||
|
|
||||||
if (Length & 3)
|
if (Buffer->getBufferSize() & 3)
|
||||||
return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
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.
|
// Sniff for the signature.
|
||||||
if (Stream.Read(8) != 'B' ||
|
if (Stream.Read(8) != 'B' ||
|
||||||
@@ -882,7 +889,7 @@ bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length,
|
|||||||
|
|
||||||
// We only know the MODULE subblock ID.
|
// We only know the MODULE subblock ID.
|
||||||
if (BlockID == bitc::MODULE_BLOCK_ID) {
|
if (BlockID == bitc::MODULE_BLOCK_ID) {
|
||||||
if (ParseModule(Stream, ModuleID))
|
if (ParseModule(Stream, Buffer->getBufferIdentifier()))
|
||||||
return true;
|
return true;
|
||||||
} else if (Stream.SkipBlock()) {
|
} else if (Stream.SkipBlock()) {
|
||||||
return Error("Malformed block record");
|
return Error("Malformed block record");
|
||||||
@@ -891,3 +898,41 @@ bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length,
|
|||||||
|
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class BitstreamReader;
|
class BitstreamReader;
|
||||||
|
class MemoryBuffer;
|
||||||
|
|
||||||
class BitcodeReaderValueList : public User {
|
class BitcodeReaderValueList : public User {
|
||||||
std::vector<Use> Uses;
|
std::vector<Use> Uses;
|
||||||
@@ -57,6 +58,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
class BitcodeReader : public ModuleProvider {
|
class BitcodeReader : public ModuleProvider {
|
||||||
|
MemoryBuffer *Buffer;
|
||||||
const char *ErrorString;
|
const char *ErrorString;
|
||||||
|
|
||||||
std::vector<PATypeHolder> TypeList;
|
std::vector<PATypeHolder> TypeList;
|
||||||
@@ -64,10 +66,16 @@ class BitcodeReader : public ModuleProvider {
|
|||||||
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
||||||
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
|
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
|
||||||
public:
|
public:
|
||||||
BitcodeReader() : ErrorString(0) {}
|
BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {}
|
||||||
virtual ~BitcodeReader() {}
|
~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) {
|
virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) {
|
||||||
// FIXME: TODO
|
// FIXME: TODO
|
||||||
@@ -89,8 +97,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Main interface to parsing a bitcode buffer.
|
/// @brief Main interface to parsing a bitcode buffer.
|
||||||
/// @returns true if an error occurred.
|
/// @returns true if an error occurred.
|
||||||
bool ParseBitcode(unsigned char *Buf, unsigned Length,
|
bool ParseBitcode();
|
||||||
const std::string &ModuleID);
|
|
||||||
private:
|
private:
|
||||||
const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
|
const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
|
||||||
|
|
||||||
|
@@ -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;
|
|
||||||
}
|
|
@@ -24,6 +24,7 @@
|
|||||||
#include "llvm/Support/Compressor.h"
|
#include "llvm/Support/Compressor.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/Streams.h"
|
#include "llvm/Support/Streams.h"
|
||||||
#include "llvm/System/Signals.h"
|
#include "llvm/System/Signals.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -44,6 +45,9 @@ Force("f", cl::desc("Overwrite output files"));
|
|||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
|
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) {
|
int main(int argc, char **argv) {
|
||||||
llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
|
llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
|
||||||
try {
|
try {
|
||||||
@@ -55,12 +59,26 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
std::auto_ptr<Module> M;
|
std::auto_ptr<Module> M;
|
||||||
|
|
||||||
if (InputFilename != "-")
|
if (Bitcode) {
|
||||||
M.reset(ParseBitcodeFile(InputFilename, &ErrorMessage));
|
MemoryBuffer *Buffer;
|
||||||
|
if (InputFilename == "-") {
|
||||||
if (M.get() == 0)
|
Buffer = MemoryBuffer::getSTDIN();
|
||||||
M.reset(ParseBytecodeFile(InputFilename,Compressor::decompressToNewBuffer,
|
} 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));
|
&ErrorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
if (M.get() == 0) {
|
if (M.get() == 0) {
|
||||||
cerr << argv[0] << ": ";
|
cerr << argv[0] << ": ";
|
||||||
if (ErrorMessage.size())
|
if (ErrorMessage.size())
|
||||||
@@ -69,7 +87,7 @@ int main(int argc, char **argv) {
|
|||||||
cerr << "bytecode didn't read correctly.\n";
|
cerr << "bytecode didn't read correctly.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DontPrint) {
|
if (DontPrint) {
|
||||||
// Just use stdout. We won't actually print anything on it.
|
// Just use stdout. We won't actually print anything on it.
|
||||||
} else if (OutputFilename != "") { // Specified an output filename?
|
} else if (OutputFilename != "") { // Specified an output filename?
|
||||||
|
Reference in New Issue
Block a user