#ifndef LLVM_BITCODE_READERWRITER_H
#define LLVM_BITCODE_READERWRITER_H
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
#include <string>
namespace llvm {
class BitstreamWriter;
class DataStreamer;
class LLVMContext;
class Module;
class ModulePass;
class raw_ostream;
static const unsigned BWH_MagicField = 0*4;
static const unsigned BWH_VersionField = 1*4;
static const unsigned BWH_OffsetField = 2*4;
static const unsigned BWH_SizeField = 3*4;
static const unsigned BWH_CPUTypeField = 4*4;
static const unsigned BWH_HeaderSize = 5*4;
ErrorOr<std::unique_ptr<Module>>
getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context,
bool ShouldLazyLoadMetadata = false);
ErrorOr<std::unique_ptr<Module>>
getStreamedBitcodeModule(StringRef Name,
std::unique_ptr<DataStreamer> Streamer,
LLVMContext &Context);
std::string getBitcodeTargetTriple(MemoryBufferRef Buffer,
LLVMContext &Context);
bool isBitcodeContainingObjCCategory(MemoryBufferRef Buffer,
LLVMContext &Context);
std::string getBitcodeProducerString(MemoryBufferRef Buffer,
LLVMContext &Context);
ErrorOr<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer,
LLVMContext &Context);
bool hasGlobalValueSummary(MemoryBufferRef Buffer,
DiagnosticHandlerFunction DiagnosticHandler);
ErrorOr<std::unique_ptr<ModuleSummaryIndex>>
getModuleSummaryIndex(MemoryBufferRef Buffer,
DiagnosticHandlerFunction DiagnosticHandler);
void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder = false,
const ModuleSummaryIndex *Index = nullptr,
bool GenerateHash = false);
void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out);
inline bool isBitcodeWrapper(const unsigned char *BufPtr,
const unsigned char *BufEnd) {
return BufPtr != BufEnd &&
BufPtr[0] == 0xDE &&
BufPtr[1] == 0xC0 &&
BufPtr[2] == 0x17 &&
BufPtr[3] == 0x0B;
}
inline bool isRawBitcode(const unsigned char *BufPtr,
const unsigned char *BufEnd) {
return BufPtr != BufEnd &&
BufPtr[0] == 'B' &&
BufPtr[1] == 'C' &&
BufPtr[2] == 0xc0 &&
BufPtr[3] == 0xde;
}
inline bool isBitcode(const unsigned char *BufPtr,
const unsigned char *BufEnd) {
return isBitcodeWrapper(BufPtr, BufEnd) ||
isRawBitcode(BufPtr, BufEnd);
}
constexpr int AppleCurrentPatchVersion = 0;
inline std::string AppleInternalGetBitcodeVersionString() {
return APPLE_BITCODE_VERSION;
}
inline std::string AppleInternalGetFullBitcodeVersionString() {
if (AppleInternalGetBitcodeVersionString().empty())
return "";
return "APPLE_1_" + AppleInternalGetBitcodeVersionString() + "_" +
Twine(AppleCurrentPatchVersion).str();
}
inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
const unsigned char *&BufEnd,
bool VerifyBufferSize) {
if (BufEnd - BufPtr < BWH_SizeField + 4)
return true;
unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]);
unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]);
uint64_t BitcodeOffsetEnd = (uint64_t)Offset + (uint64_t)Size;
if (VerifyBufferSize && BitcodeOffsetEnd > uint64_t(BufEnd-BufPtr))
return true;
BufPtr += Offset;
BufEnd = BufPtr+Size;
return false;
}
const std::error_category &BitcodeErrorCategory();
enum class BitcodeError { InvalidBitcodeSignature = 1, CorruptedBitcode };
inline std::error_code make_error_code(BitcodeError E) {
return std::error_code(static_cast<int>(E), BitcodeErrorCategory());
}
class BitcodeDiagnosticInfo : public DiagnosticInfo {
const Twine &Msg;
std::error_code EC;
public:
BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity,
const Twine &Msg);
void print(DiagnosticPrinter &DP) const override;
std::error_code getError() const { return EC; }
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_Bitcode;
}
};
}
namespace std {
template <> struct is_error_code_enum<llvm::BitcodeError> : std::true_type {};
}
#endif