class BitcodeReaderBase {
protected:
- BitcodeReaderBase(MemoryBuffer *Buffer) : Buffer(Buffer) {}
+ BitcodeReaderBase(MemoryBufferRef Buffer) : Buffer(Buffer) {}
- std::unique_ptr<MemoryBuffer> Buffer;
+ MemoryBufferRef Buffer;
BitstreamBlockInfo BlockInfo;
BitstreamCursor Stream;
};
std::error_code BitcodeReaderBase::initStream() {
- const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
- const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+ const unsigned char *BufPtr = (const unsigned char*)Buffer.getBufferStart();
+ const unsigned char *BufEnd = BufPtr+Buffer.getBufferSize();
- if (Buffer->getBufferSize() & 3)
+ if (Buffer.getBufferSize() & 3)
return error("Invalid bitcode signature");
// If we have a wrapper header, parse it and ignore the non-bc file contents.
std::error_code error(BitcodeError E, const Twine &Message);
std::error_code error(const Twine &Message) override;
- BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context);
- ~BitcodeReader() override { freeState(); }
+ BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context);
std::error_code materializeForwardReferencedFunctions();
- void freeState();
-
- void releaseBuffer();
-
std::error_code materialize(GlobalValue *GV) override;
std::error_code materializeModule() override;
std::vector<StructType *> getIdentifiedStructTypes() const override;
std::error_code error(const Twine &Message);
ModuleSummaryIndexBitcodeReader(
- MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
+ MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
bool CheckGlobalValSummaryPresenceOnly = false);
- ~ModuleSummaryIndexBitcodeReader() { freeState(); }
-
- void freeState();
-
- void releaseBuffer();
/// Check if the parser has encountered a summary section.
bool foundGlobalValSummary() { return SeenGlobalValSummary; }
Message);
}
-BitcodeReader::BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context)
+BitcodeReader::BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context)
: BitcodeReaderBase(Buffer), Context(Context), ValueList(Context),
MetadataList(Context) {}
return std::error_code();
}
-void BitcodeReader::freeState() {
- Buffer = nullptr;
- std::vector<Type*>().swap(TypeList);
- ValueList.clear();
- MetadataList.clear();
- std::vector<Comdat *>().swap(ComdatList);
-
- std::vector<AttributeSet>().swap(MAttributes);
- std::vector<BasicBlock*>().swap(FunctionBBs);
- std::vector<Function*>().swap(FunctionsWithBodies);
- DeferredFunctionInfo.clear();
- DeferredMetadataInfo.clear();
- MDKindMap.clear();
-
- assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references");
- BasicBlockFwdRefQueue.clear();
-}
-
//===----------------------------------------------------------------------===//
// Helper functions to implement forward reference resolution, etc.
//===----------------------------------------------------------------------===//
// GVMaterializer implementation
//===----------------------------------------------------------------------===//
-void BitcodeReader::releaseBuffer() { Buffer.release(); }
-
std::error_code BitcodeReader::materialize(GlobalValue *GV) {
Function *F = dyn_cast<Function>(GV);
// If it's not a function or is already material, ignore the request.
}
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
- MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
+ MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
bool CheckGlobalValSummaryPresenceOnly)
: BitcodeReaderBase(Buffer),
DiagnosticHandler(std::move(DiagnosticHandler)),
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
-void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; }
-
-void ModuleSummaryIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
-
std::pair<GlobalValue::GUID, GlobalValue::GUID>
ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);
break;
if (TheIndex->modulePaths().empty())
// We always seed the index with the module.
- TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0);
+ TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0);
if (TheIndex->modulePaths().size() != 1)
return error("Don't expect multiple modules defined?");
auto &Hash = TheIndex->modulePaths().begin()->second.second;
// module path string table entry with an empty (0) ID to take
// ownership.
FS->setModulePath(
- TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
+ TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
static int RefListStartIndex = 4;
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
assert(Record.size() >= RefListStartIndex + NumRefs &&
// module path string table entry with an empty (0) ID to take
// ownership.
AS->setModulePath(
- TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
+ TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;
auto *AliaseeSummary = TheIndex->getGlobalValueSummary(AliaseeGUID);
std::unique_ptr<GlobalVarSummary> FS =
llvm::make_unique<GlobalVarSummary>(Flags);
FS->setModulePath(
- TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
+ TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
for (unsigned I = 2, E = Record.size(); I != E; ++I) {
unsigned RefValueId = Record[I];
GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
// External interface
//===----------------------------------------------------------------------===//
+/// \brief Get a lazy one-at-time loading module from bitcode.
+///
+/// This isn't always used in a lazy context. In particular, it's also used by
+/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
+/// in forward-referenced functions from block address references.
+///
+/// \param[in] MaterializeAll Set to \c true if we should materialize
+/// everything.
static ErrorOr<std::unique_ptr<Module>>
-getBitcodeModuleImpl(StringRef Name, BitcodeReader *R, LLVMContext &Context,
- bool MaterializeAll, bool ShouldLazyLoadMetadata) {
- std::unique_ptr<Module> M = llvm::make_unique<Module>(Name, Context);
- M->setMaterializer(R);
+getLazyBitcodeModuleImpl(MemoryBufferRef Buffer, LLVMContext &Context,
+ bool MaterializeAll,
+ bool ShouldLazyLoadMetadata = false) {
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
- auto cleanupOnError = [&](std::error_code EC) {
- R->releaseBuffer(); // Never take ownership on error.
- return EC;
- };
+ std::unique_ptr<Module> M =
+ llvm::make_unique<Module>(Buffer.getBufferIdentifier(), Context);
+ M->setMaterializer(R);
// Delay parsing Metadata if ShouldLazyLoadMetadata is true.
if (std::error_code EC = R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata))
- return cleanupOnError(EC);
+ return EC;
if (MaterializeAll) {
// Read in the entire module, and destroy the BitcodeReader.
if (std::error_code EC = M->materializeAll())
- return cleanupOnError(EC);
+ return EC;
} else {
// Resolve forward references from blockaddresses.
if (std::error_code EC = R->materializeForwardReferencedFunctions())
- return cleanupOnError(EC);
+ return EC;
}
return std::move(M);
}
-/// \brief Get a lazy one-at-time loading module from bitcode.
-///
-/// This isn't always used in a lazy context. In particular, it's also used by
-/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
-/// in forward-referenced functions from block address references.
-///
-/// \param[in] MaterializeAll Set to \c true if we should materialize
-/// everything.
-static ErrorOr<std::unique_ptr<Module>>
-getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context, bool MaterializeAll,
- bool ShouldLazyLoadMetadata = false) {
- BitcodeReader *R = new BitcodeReader(Buffer.get(), Context);
-
- ErrorOr<std::unique_ptr<Module>> Ret =
- getBitcodeModuleImpl(Buffer->getBufferIdentifier(), R, Context,
- MaterializeAll, ShouldLazyLoadMetadata);
- if (!Ret)
- return Ret;
-
- Buffer.release(); // The BitcodeReader owns it now.
- return Ret;
-}
-
ErrorOr<std::unique_ptr<Module>>
-llvm::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+llvm::getLazyBitcodeModule(MemoryBufferRef Buffer,
LLVMContext &Context, bool ShouldLazyLoadMetadata) {
- return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
+ return getLazyBitcodeModuleImpl(Buffer, Context, false,
ShouldLazyLoadMetadata);
}
+ErrorOr<std::unique_ptr<Module>>
+llvm::getOwningLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+ LLVMContext &Context,
+ bool ShouldLazyLoadMetadata) {
+ auto MOrErr = getLazyBitcodeModule(*Buffer, Context, ShouldLazyLoadMetadata);
+ if (MOrErr)
+ (*MOrErr)->setOwnedMemoryBuffer(std::move(Buffer));
+ return MOrErr;
+}
+
ErrorOr<std::unique_ptr<Module>> llvm::parseBitcodeFile(MemoryBufferRef Buffer,
LLVMContext &Context) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- return getLazyBitcodeModuleImpl(std::move(Buf), Context, true);
+ return getLazyBitcodeModuleImpl(Buffer, Context, true);
// TODO: Restore the use-lists to the in-memory state when the bitcode was
// written. We must defer until the Module has been fully materialized.
}
std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer,
LLVMContext &Context) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- auto R = llvm::make_unique<BitcodeReader>(Buf.release(), Context);
- ErrorOr<std::string> Triple = R->parseTriple();
+ BitcodeReader R(Buffer, Context);
+ ErrorOr<std::string> Triple = R.parseTriple();
if (Triple.getError())
return "";
return Triple.get();
bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer,
LLVMContext &Context) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- auto R = llvm::make_unique<BitcodeReader>(Buf.release(), Context);
- ErrorOr<bool> hasObjCCategory = R->hasObjCCategory();
+ BitcodeReader R(Buffer, Context);
+ ErrorOr<bool> hasObjCCategory = R.hasObjCCategory();
if (hasObjCCategory.getError())
return false;
return hasObjCCategory.get();
std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer,
LLVMContext &Context) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- BitcodeReader R(Buf.release(), Context);
+ BitcodeReader R(Buffer, Context);
ErrorOr<std::string> ProducerString = R.parseIdentificationBlock();
if (ProducerString.getError())
return "";
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndex(
MemoryBufferRef Buffer,
const DiagnosticHandlerFunction &DiagnosticHandler) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler);
+ ModuleSummaryIndexBitcodeReader R(Buffer, DiagnosticHandler);
auto Index = llvm::make_unique<ModuleSummaryIndex>();
- auto cleanupOnError = [&](std::error_code EC) {
- R.releaseBuffer(); // Never take ownership on error.
- return EC;
- };
-
if (std::error_code EC = R.parseSummaryIndexInto(Index.get()))
- return cleanupOnError(EC);
+ return EC;
- Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
return std::move(Index);
}
bool llvm::hasGlobalValueSummary(
MemoryBufferRef Buffer,
const DiagnosticHandlerFunction &DiagnosticHandler) {
- std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, true);
+ ModuleSummaryIndexBitcodeReader R(Buffer, DiagnosticHandler, true);
- auto cleanupOnError = [&](std::error_code EC) {
- R.releaseBuffer(); // Never take ownership on error.
+ if (R.parseSummaryIndexInto(nullptr))
return false;
- };
-
- if (std::error_code EC = R.parseSummaryIndexInto(nullptr))
- return cleanupOnError(EC);
- Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
return R.foundGlobalValSummary();
}