Index: lld/trunk/ELF/Driver.h =================================================================== --- lld/trunk/ELF/Driver.h +++ lld/trunk/ELF/Driver.h @@ -16,7 +16,6 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/raw_ostream.h" @@ -30,7 +29,6 @@ void main(ArrayRef Args, bool CanExitEarly); void addFile(StringRef Path); void addLibrary(StringRef Name); - llvm::LLVMContext Context; // to parse bitcode files std::unique_ptr Cpio; // for reproduce private: Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -24,6 +24,7 @@ #include "lld/Driver/Driver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include @@ -202,12 +203,6 @@ InitializeAllAsmPrinters(); InitializeAllAsmParsers(); - // This is a flag to discard all but GlobalValue names. - // We want to enable it by default because it saves memory. - // Disable it only when a developer option (-save-temps) is given. - Driver->Context.setDiscardValueNames(!Config->SaveTemps); - Driver->Context.enableDebugTypeODRUniquing(); - // Parse and evaluate -mllvm options. std::vector V; V.push_back("lld (LLVM option parsing)"); Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -653,14 +653,14 @@ } static ELFKind getBitcodeELFKind(MemoryBufferRef MB) { - Triple T(getBitcodeTargetTriple(MB, Driver->Context)); + Triple T(check(getBitcodeTargetTriple(MB))); if (T.isLittleEndian()) return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind; return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind; } static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { - Triple T(getBitcodeTargetTriple(MB, Driver->Context)); + Triple T(check(getBitcodeTargetTriple(MB))); switch (T.getArch()) { case Triple::aarch64: return EM_AARCH64; Index: llvm/trunk/include/llvm/Bitcode/BitcodeReader.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/BitcodeReader.h +++ llvm/trunk/include/llvm/Bitcode/BitcodeReader.h @@ -18,6 +18,7 @@ #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" #include @@ -26,6 +27,22 @@ class LLVMContext; class Module; + // These functions are for converting Expected/Error values to + // ErrorOr/std::error_code for compatibility with legacy clients. FIXME: + // Remove these functions once no longer needed by the C and libLTO APIs. + + std::error_code errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, Error Err); + std::error_code + errorToErrorCodeAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, + Error Err); + + template + ErrorOr expectedToErrorOrAndEmitErrors(LLVMContext &Ctx, Expected Val) { + if (!Val) + return errorToErrorCodeAndEmitErrors(Ctx, Val.takeError()); + return std::move(*Val); + } + /// Read the header of the specified bitcode buffer and prepare for lazy /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, /// lazily load metadata as well. @@ -44,28 +61,23 @@ /// Read the header of the specified bitcode buffer and extract just the /// triple information. If successful, this returns a string. On error, this /// returns "". - std::string getBitcodeTargetTriple(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected getBitcodeTargetTriple(MemoryBufferRef Buffer); /// Return true if \p Buffer contains a bitcode file with ObjC code (category /// or class) in it. - bool isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected isBitcodeContainingObjCCategory(MemoryBufferRef Buffer); /// Read the header of the specified bitcode buffer and extract just the /// producer string information. If successful, this returns a string. On /// error, this returns "". - std::string getBitcodeProducerString(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected getBitcodeProducerString(MemoryBufferRef Buffer); /// Read the specified bitcode file, returning the module. ErrorOr> parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context); /// Check if the given bitcode buffer contains a summary block. - bool - hasGlobalValueSummary(MemoryBufferRef Buffer, - const DiagnosticHandlerFunction &DiagnosticHandler); + Expected hasGlobalValueSummary(MemoryBufferRef Buffer); /// Parse the specified bitcode buffer, returning the module summary index. ErrorOr> Index: llvm/trunk/include/llvm/Object/ModuleSummaryIndexObjectFile.h =================================================================== --- llvm/trunk/include/llvm/Object/ModuleSummaryIndexObjectFile.h +++ llvm/trunk/include/llvm/Object/ModuleSummaryIndexObjectFile.h @@ -79,12 +79,6 @@ static ErrorOr findBitcodeInMemBuffer(MemoryBufferRef Object); - /// \brief Looks for summary sections in the given memory buffer, - /// returns true if found, else false. - static bool hasGlobalValueSummaryInMemBuffer( - MemoryBufferRef Object, - const DiagnosticHandlerFunction &DiagnosticHandler); - /// \brief Parse module summary index in the given memory buffer. /// Return new ModuleSummaryIndexObjectFile instance containing parsed module /// summary/index. Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -267,6 +267,228 @@ return std::move(Stream); } +/// Convert a string from a record into an std::string, return true on failure. +template +static bool convertToString(ArrayRef Record, unsigned Idx, + StrTy &Result) { + if (Idx > Record.size()) + return true; + + for (unsigned i = Idx, e = Record.size(); i != e; ++i) + Result += (char)Record[i]; + return false; +} + +/// Read the "IDENTIFICATION_BLOCK_ID" block, do some basic enforcement on the +/// "epoch" encoded in the bitcode, and return the producer name if any. +Expected readIdentificationBlock(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) + return error("Invalid record"); + + // Read all the records. + SmallVector Record; + + std::string ProducerIdentification; + + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + default: + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return ProducerIdentification; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: reject + return error("Invalid value"); + case bitc::IDENTIFICATION_CODE_STRING: // IDENTIFICATION: [strchr x N] + convertToString(Record, 0, ProducerIdentification); + break; + case bitc::IDENTIFICATION_CODE_EPOCH: { // EPOCH: [epoch#] + unsigned epoch = (unsigned)Record[0]; + if (epoch != bitc::BITCODE_CURRENT_EPOCH) { + return error( + Twine("Incompatible epoch: Bitcode '") + Twine(epoch) + + "' vs current: '" + Twine(bitc::BITCODE_CURRENT_EPOCH) + "'"); + } + } + } + } +} + +Expected readIdentificationCode(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + if (Stream.AtEndOfStream()) + return ""; + + BitstreamEntry Entry = Stream.advance(); + switch (Entry.Kind) { + case BitstreamEntry::EndBlock: + case BitstreamEntry::Error: + return error("Malformed block"); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) + return readIdentificationBlock(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + +Expected hasObjCCategoryInModule(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector Record; + // Read all the records for this module. + + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: + break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + // Check for the i386 and other (x86_64, ARM) conventions + if (S.find("__DATA, __objc_catlist") != std::string::npos || + S.find("__OBJC,__category") != std::string::npos) + return true; + break; + } + } + Record.clear(); + } + llvm_unreachable("Exit infinite loop"); +} + +Expected hasObjCCategory(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return false; + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return hasObjCCategoryInModule(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + +Expected readModuleTriple(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector Record; + + std::string Triple; + + // Read all the records for this module. + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Triple; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + Triple = S; + break; + } + } + Record.clear(); + } + llvm_unreachable("Exit infinite loop"); +} + +Expected readTriple(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return ""; + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return readModuleTriple(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + class BitcodeReaderBase { protected: BitcodeReaderBase(BitstreamCursor Stream) : Stream(std::move(Stream)) { @@ -397,17 +619,6 @@ /// \returns true if an error occurred. Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata = false); - /// \brief Cheap mechanism to just extract module triple - /// \returns true if an error occurred. - Expected parseTriple(); - - /// Cheap mechanism to just extract the identification block out of bitcode. - Expected parseIdentificationBlock(); - - /// Peak at the module content and return true if any ObjC category or class - /// is found. - Expected hasObjCCategory(); - static uint64_t decodeSignRotatedValue(uint64_t V); /// Materialize any deferred Metadata block. @@ -416,11 +627,6 @@ void setStripDebugInfo() override; private: - /// Parse the "IDENTIFICATION_BLOCK_ID" block, populate the - // ProducerIdentification data member, and do some basic enforcement on the - // "epoch" encoded in the bitcode. - Error parseBitcodeVersion(); - std::vector IdentifiedStructTypes; StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); StructType *createIdentifiedStructType(LLVMContext &Context); @@ -546,8 +752,6 @@ Error parseGlobalObjectAttachment(GlobalObject &GO, ArrayRef Record); Error parseMetadataAttachment(Function &F); - Expected parseModuleTriple(); - Expected hasObjCCategoryInModule(); Error parseUseLists(); Error findFunctionInStream( Function *F, @@ -622,7 +826,10 @@ bool IsOldProfileFormat, bool HasProfile); }; -std::error_code errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, Error Err) { +} // end anonymous namespace + +std::error_code llvm::errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, + Error Err) { if (Err) { std::error_code EC; handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { @@ -634,9 +841,8 @@ return std::error_code(); } -std::error_code -errorToErrorCodeAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, - Error Err) { +std::error_code llvm::errorToErrorCodeAndEmitErrors( + const DiagnosticHandlerFunction &DiagHandler, Error Err) { if (Err) { std::error_code EC; handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { @@ -648,24 +854,6 @@ return std::error_code(); } -template -ErrorOr expectedToErrorOrAndEmitErrors(LLVMContext &Ctx, Expected Val) { - if (!Val) - return errorToErrorCodeAndEmitErrors(Ctx, Val.takeError()); - return std::move(*Val); -} - -template -static ErrorOr -expectedToErrorOrAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, - Expected Val) { - if (!Val) - return errorToErrorCodeAndEmitErrors(DiagHandler, Val.takeError()); - return std::move(*Val); -} - -} // end anonymous namespace - BitcodeReader::BitcodeReader(BitstreamCursor Stream, LLVMContext &Context) : BitcodeReaderBase(std::move(Stream)), Context(Context), ValueList(Context), MetadataList(Context) {} @@ -707,18 +895,6 @@ // Helper functions to implement forward reference resolution, etc. //===----------------------------------------------------------------------===// -/// Convert a string from a record into an std::string, return true on failure. -template -static bool convertToString(ArrayRef Record, unsigned Idx, - StrTy &Result) { - if (Idx > Record.size()) - return true; - - for (unsigned i = Idx, e = Record.size(); i != e; ++i) - Result += (char)Record[i]; - return false; -} - static bool hasImplicitComdat(size_t Val) { switch (Val) { default: @@ -3713,50 +3889,6 @@ } } -Error BitcodeReader::parseBitcodeVersion() { - if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) - return error("Invalid record"); - - // Read all the records. - SmallVector Record; - - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - default: - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Error::success(); - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - Record.clear(); - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { - default: // Default behavior: reject - return error("Invalid value"); - case bitc::IDENTIFICATION_CODE_STRING: { // IDENTIFICATION: [strchr x - // N] - convertToString(Record, 0, ProducerIdentification); - break; - } - case bitc::IDENTIFICATION_CODE_EPOCH: { // EPOCH: [epoch#] - unsigned epoch = (unsigned)Record[0]; - if (epoch != bitc::BITCODE_CURRENT_EPOCH) { - return error( - Twine("Incompatible epoch: Bitcode '") + Twine(epoch) + - "' vs current: '" + Twine(bitc::BITCODE_CURRENT_EPOCH) + "'"); - } - } - } - } -} - bool BitcodeReaderBase::readBlockInfo() { Optional NewBlockInfo = Stream.ReadBlockInfoBlock(); if (!NewBlockInfo) @@ -4259,8 +4391,11 @@ return error("Malformed block"); if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { - if (Error Err = parseBitcodeVersion()) - return Err; + Expected ProducerIdentificationOrErr = + readIdentificationBlock(Stream); + if (!ProducerIdentificationOrErr) + return ProducerIdentificationOrErr.takeError(); + ProducerIdentification = *ProducerIdentificationOrErr; continue; } @@ -4272,107 +4407,6 @@ } } -Expected BitcodeReader::parseModuleTriple() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); - - SmallVector Record; - - std::string Triple; - - // Read all the records for this module. - while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - - switch (Entry.Kind) { - case BitstreamEntry::SubBlock: // Handled for us already. - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Triple; - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { - default: break; // Default behavior, ignore unknown content. - case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] - std::string S; - if (convertToString(Record, 0, S)) - return error("Invalid record"); - Triple = S; - break; - } - } - Record.clear(); - } - llvm_unreachable("Exit infinite loop"); -} - -Expected BitcodeReader::parseTriple() { - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return ""; - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::MODULE_BLOCK_ID) - return parseModuleTriple(); - - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - -Expected BitcodeReader::parseIdentificationBlock() { - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - // This loop iterates at the top-level: since there is no enclosing block - // we need to make sure we aren't at the end of the stream before calling - // advance, otherwise we'll get an error. - if (Stream.AtEndOfStream()) - return ""; - - BitstreamEntry Entry = Stream.advance(); - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return ""; - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { - if (Error Err = parseBitcodeVersion()) - return std::move(Err); - return ProducerIdentification; - } - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO, ArrayRef Record) { assert(Record.size() % 2 == 0); @@ -4388,75 +4422,6 @@ return Error::success(); } -Expected BitcodeReader::hasObjCCategory() { - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return false; - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::MODULE_BLOCK_ID) - return hasObjCCategoryInModule(); - - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - -Expected BitcodeReader::hasObjCCategoryInModule() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); - - SmallVector Record; - // Read all the records for this module. - - while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - - switch (Entry.Kind) { - case BitstreamEntry::SubBlock: // Handled for us already. - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return false; - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { - default: - break; // Default behavior, ignore unknown content. - case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] - std::string S; - if (convertToString(Record, 0, S)) - return error("Invalid record"); - // Check for the i386 and other (x86_64, ARM) conventions - if (S.find("__DATA, __objc_catlist") != std::string::npos || - S.find("__OBJC,__category") != std::string::npos) - return true; - break; - } - } - Record.clear(); - } - llvm_unreachable("Exit infinite loop"); -} - /// Parse metadata attachments. Error BitcodeReader::parseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) @@ -6673,49 +6638,28 @@ // written. We must defer until the Module has been fully materialized. } -std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, - LLVMContext &Context) { - ErrorOr StreamOrErr = - expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); +Expected llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); if (!StreamOrErr) - return ""; + return StreamOrErr.takeError(); - BitcodeReader R(std::move(*StreamOrErr), Context); - ErrorOr Triple = - expectedToErrorOrAndEmitErrors(Context, R.parseTriple()); - if (Triple.getError()) - return ""; - return Triple.get(); + return readTriple(*StreamOrErr); } -bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, - LLVMContext &Context) { - ErrorOr StreamOrErr = - expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); +Expected llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); if (!StreamOrErr) - return false; + return StreamOrErr.takeError(); - BitcodeReader R(std::move(*StreamOrErr), Context); - ErrorOr hasObjCCategory = - expectedToErrorOrAndEmitErrors(Context, R.hasObjCCategory()); - if (hasObjCCategory.getError()) - return false; - return hasObjCCategory.get(); + return hasObjCCategory(*StreamOrErr); } -std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer, - LLVMContext &Context) { - ErrorOr StreamOrErr = - expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); +Expected llvm::getBitcodeProducerString(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); if (!StreamOrErr) - return ""; - - BitcodeReader R(std::move(*StreamOrErr), Context); - ErrorOr ProducerString = - expectedToErrorOrAndEmitErrors(Context, R.parseIdentificationBlock()); - if (ProducerString.getError()) - return ""; - return ProducerString.get(); + return StreamOrErr.takeError(); + + return readIdentificationCode(*StreamOrErr); } // Parse the specified bitcode buffer, returning the function info index. @@ -6740,19 +6684,16 @@ } // Check if the given bitcode buffer contains a global value summary block. -bool llvm::hasGlobalValueSummary( - MemoryBufferRef Buffer, - const DiagnosticHandlerFunction &DiagnosticHandler) { - ErrorOr StreamOrErr = expectedToErrorOrAndEmitErrors( - DiagnosticHandler, initStream(Buffer)); +Expected llvm::hasGlobalValueSummary(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); if (!StreamOrErr) - return false; + return StreamOrErr.takeError(); ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr), true); - if (errorToErrorCodeAndEmitErrors( - DiagnosticHandler, - R.parseSummaryIndexInto(nullptr, Buffer.getBufferIdentifier()))) - return false; + + if (Error Err = + R.parseSummaryIndexInto(nullptr, Buffer.getBufferIdentifier())) + return std::move(Err); return R.foundGlobalValSummary(); } Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -328,9 +328,11 @@ M.setTargetTriple(Conf.DefaultTriple); MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); - bool HasThinLTOSummary = hasGlobalValueSummary(MBRef, Conf.DiagHandler); + Expected HasThinLTOSummary = hasGlobalValueSummary(MBRef); + if (!HasThinLTOSummary) + return HasThinLTOSummary.takeError(); - if (HasThinLTOSummary) + if (*HasThinLTOSummary) return addThinLTO(std::move(Input), Res); else return addRegularLTO(std::move(Input), Res); Index: llvm/trunk/lib/LTO/LTOModule.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOModule.cpp +++ llvm/trunk/lib/LTO/LTOModule.cpp @@ -76,13 +76,12 @@ bool LTOModule::isThinLTO() { // Right now the detection is only based on the summary presence. We may want // to add a dedicated flag at some point. - return hasGlobalValueSummary(IRFile->getMemoryBufferRef(), - [](const DiagnosticInfo &DI) { - DiagnosticPrinterRawOStream DP(errs()); - DI.print(DP); - errs() << '\n'; - return; - }); + Expected Result = hasGlobalValueSummary(IRFile->getMemoryBufferRef()); + if (!Result) { + logAllUnhandledErrors(Result.takeError(), errs(), ""); + return false; + } + return *Result; } bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, @@ -92,8 +91,11 @@ if (!BCOrErr) return false; LLVMContext Context; - std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context); - return StringRef(Triple).startswith(TriplePrefix); + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(*BCOrErr)); + if (!TripleOrErr) + return false; + return StringRef(*TripleOrErr).startswith(TriplePrefix); } std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { @@ -102,7 +104,11 @@ if (!BCOrErr) return ""; LLVMContext Context; - return getBitcodeProducerString(*BCOrErr, Context); + ErrorOr ProducerOrErr = expectedToErrorOrAndEmitErrors( + Context, getBitcodeProducerString(*BCOrErr)); + if (!ProducerOrErr) + return ""; + return *ProducerOrErr; } ErrorOr> Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -453,14 +453,23 @@ if (Modules.empty()) { // First module added, so initialize the triple and some options LLVMContext Context; - Triple TheTriple(getBitcodeTargetTriple(Buffer, Context)); + StringRef TripleStr; + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(Buffer)); + if (TripleOrErr) + TripleStr = *TripleOrErr; + Triple TheTriple(TripleStr); initTMBuilder(TMBuilder, Triple(TheTriple)); } #ifndef NDEBUG else { LLVMContext Context; - assert(TMBuilder.TheTriple.str() == - getBitcodeTargetTriple(Buffer, Context) && + StringRef TripleStr; + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(Buffer)); + if (TripleOrErr) + TripleStr = *TripleOrErr; + assert(TMBuilder.TheTriple.str() == TripleStr && "ThinLTO modules with different triple not supported"); } #endif Index: llvm/trunk/lib/Object/ModuleSummaryIndexObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/ModuleSummaryIndexObjectFile.cpp +++ llvm/trunk/lib/Object/ModuleSummaryIndexObjectFile.cpp @@ -67,18 +67,6 @@ } } -// Looks for module summary index in the given memory buffer. -// returns true if found, else false. -bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer( - MemoryBufferRef Object, - const DiagnosticHandlerFunction &DiagnosticHandler) { - ErrorOr BCOrErr = findBitcodeInMemBuffer(Object); - if (!BCOrErr) - return false; - - return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler); -} - // Parse module summary index in the given memory buffer. // Return new ModuleSummaryIndexObjectFile instance containing parsed // module summary/index. Index: llvm/trunk/tools/llvm-lto/llvm-lto.cpp =================================================================== --- llvm/trunk/tools/llvm-lto/llvm-lto.cpp +++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp @@ -773,12 +773,12 @@ if (CheckHasObjC) { for (auto &Filename : InputFilenames) { - ErrorOr> BufferOrErr = - MemoryBuffer::getFile(Filename); - error(BufferOrErr, "error loading file '" + Filename + "'"); + ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" + + Filename + "': "); + std::unique_ptr BufferOrErr = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename))); auto Buffer = std::move(BufferOrErr.get()); - LLVMContext Ctx; - if (llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx)) + if (ExitOnErr(llvm::isBitcodeContainingObjCCategory(*Buffer))) outs() << "Bitcode " << Filename << " contains ObjC\n"; else outs() << "Bitcode " << Filename << " does not contain ObjC\n"; Index: llvm/trunk/tools/lto/lto.cpp =================================================================== --- llvm/trunk/tools/lto/lto.cpp +++ llvm/trunk/tools/lto/lto.cpp @@ -187,7 +187,9 @@ if (!Buffer) return false; LLVMContext Ctx; - return llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx); + ErrorOr Result = expectedToErrorOrAndEmitErrors( + Ctx, llvm::isBitcodeContainingObjCCategory(*Buffer)); + return Result && *Result; } bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {