[llvm] r269491 - Retry "[ProfileData] (llvm) Use Error in InstrProf and Coverage, NFC"
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Fri May 13 22:32:10 PDT 2016
(Note that Craig tried to fix this without a revert but wasn't successful,
I think at this point revert is the best option...)
On Fri, May 13, 2016 at 11:22 PM Chandler Carruth <chandlerc at google.com>
wrote:
> It's also breaking -Werror build bots:
> http://lab.llvm.org:8011/builders/sanitizer-ppc64le-linux/builds/1079
>
> I'm reverting this for now, we've lost hours and hours of build bot
> coverage already.
>
> On Fri, May 13, 2016 at 7:13 PM Craig Topper via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> I think this is causing some warnings on my build like this
>>
>> *llvm/include/llvm/Support/Error.h:301:52: **warning: **instantiation of
>> variable 'llvm::ProfErrorInfoBase<llvm::instrprof_error>::ID' required
>> here, but no definition is available [-Wundefined-var-template]*
>>
>> static const void *classID() { return &ThisErrT::ID; }
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:61:28: **note: *in instantiation of
>> member function
>> 'llvm::ErrorInfo<llvm::ProfErrorInfoBase<llvm::instrprof_error>,
>> llvm::ErrorInfoBase>::classID' requested here
>>
>> return isA(ErrorInfoT::classID());
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:399:23: **note: *in instantiation of
>> function template specialization
>> 'llvm::ErrorInfoBase::isA<llvm::InstrProfError>' requested here
>>
>> return E.template isA<ErrT>();
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:482:37: **note: *in instantiation of
>> member function 'llvm::ErrorHandlerTraits<void (&)(llvm::InstrProfError
>> &)>::appliesTo' requested here
>>
>> if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:508:11: **note: *in instantiation of
>> function template specialization 'llvm::handleErrorImpl<(lambda at
>> llvm/include/llvm/ProfileData/InstrProf.h:294:35)>' requested here
>>
>> handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:520:12: **note: *in instantiation of
>> function template specialization 'llvm::handleErrors<(lambda at
>> llvm/include/llvm/ProfileData/InstrProf.h:294:35)>' requested here
>>
>> auto F = handleErrors(std::move(E),
>> std::forward<HandlerTs>(Handlers)...);
>>
>> * ^*
>>
>> *llvm/include/llvm/ProfileData/InstrProf.h:294:5: **note: *in
>> instantiation of function template specialization
>> 'llvm::handleAllErrors<(lambda at
>> llvm/include/llvm/ProfileData/InstrProf.h:294:35)>' requested here
>>
>> handleAllErrors(std::move(E), [&Err](const InstrProfError &IPE) {
>>
>> * ^*
>>
>> *llvm/include/llvm/ProfileData/ProfileCommon.h:57:15: **note: *forward
>> declaration of template entity is here
>>
>> static char ID;
>>
>> * ^*
>>
>> *llvm/include/llvm/Support/Error.h:301:52: **note: *add an explicit
>> instantiation declaration to suppress this warning if
>> 'llvm::ProfErrorInfoBase<llvm::instrprof_error>::ID' is explicitly
>> instantiated in another translation unit
>>
>> static const void *classID() { return &ThisErrT::ID; }
>>
>> * ^*
>>
>> 1 warning generated.
>>
>> On Fri, May 13, 2016 at 2:50 PM, Vedant Kumar via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: vedantk
>>> Date: Fri May 13 16:50:56 2016
>>> New Revision: 269491
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=269491&view=rev
>>> Log:
>>> Retry "[ProfileData] (llvm) Use Error in InstrProf and Coverage, NFC"
>>>
>>> Transition InstrProf and Coverage over to the stricter Error/Expected
>>> interface.
>>>
>>> Changes since the initial commit:
>>> - Fix error message printing in llvm-profdata.
>>> - Check errors in loadTestingFormat() + annotateAllFunctions().
>>> - Defer error handling in InstrProfIterator to InstrProfReader.
>>>
>>> Differential Revision: http://reviews.llvm.org/D19901
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMapping.h
>>> llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
>>> llvm/trunk/include/llvm/ProfileData/InstrProf.h
>>> llvm/trunk/include/llvm/ProfileData/InstrProfData.inc
>>> llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
>>> llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h
>>> llvm/trunk/include/llvm/ProfileData/ProfileCommon.h
>>> llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
>>> llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp
>>> llvm/trunk/lib/ProfileData/InstrProf.cpp
>>> llvm/trunk/lib/ProfileData/InstrProfReader.cpp
>>> llvm/trunk/lib/ProfileData/InstrProfWriter.cpp
>>> llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
>>> llvm/trunk/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
>>> llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
>>> llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
>>> llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp
>>> llvm/trunk/unittests/ProfileData/InstrProfTest.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMapping.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMapping.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMapping.h
>>> (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMapping.h Fri
>>> May 13 16:50:56 2016
>>> @@ -23,13 +23,13 @@
>>> #include "llvm/ProfileData/InstrProf.h"
>>> #include "llvm/Support/Debug.h"
>>> #include "llvm/Support/Endian.h"
>>> -#include "llvm/Support/ErrorOr.h"
>>> #include "llvm/Support/raw_ostream.h"
>>> #include <system_error>
>>> #include <tuple>
>>>
>>> namespace llvm {
>>> namespace coverage {
>>> +
>>> enum class coveragemap_error {
>>> success = 0,
>>> eof,
>>> @@ -38,13 +38,16 @@ enum class coveragemap_error {
>>> truncated,
>>> malformed
>>> };
>>> -} // end of coverage namespace.
>>> -}
>>>
>>> -namespace std {
>>> -template <>
>>> -struct is_error_code_enum<llvm::coverage::coveragemap_error> :
>>> std::true_type {
>>> +class CoverageMapError : public ProfErrorInfoBase<coveragemap_error> {
>>> +public:
>>> + CoverageMapError(coveragemap_error Err)
>>> + : ProfErrorInfoBase<coveragemap_error>(Err) {}
>>> +
>>> + std::string message() const override;
>>> };
>>> +
>>> +} // end of coverage namespace.
>>> }
>>>
>>> namespace llvm {
>>> @@ -265,7 +268,7 @@ public:
>>>
>>> /// \brief Return the number of times that a region of code
>>> associated with
>>> /// this counter was executed.
>>> - ErrorOr<int64_t> evaluate(const Counter &C) const;
>>> + Expected<int64_t> evaluate(const Counter &C) const;
>>> };
>>>
>>> /// \brief Code coverage information for a single function.
>>> @@ -415,12 +418,12 @@ class CoverageMapping {
>>>
>>> public:
>>> /// \brief Load the coverage mapping using the given readers.
>>> - static ErrorOr<std::unique_ptr<CoverageMapping>>
>>> + static Expected<std::unique_ptr<CoverageMapping>>
>>> load(CoverageMappingReader &CoverageReader,
>>> IndexedInstrProfReader &ProfileReader);
>>>
>>> /// \brief Load the coverage mapping from the given files.
>>> - static ErrorOr<std::unique_ptr<CoverageMapping>>
>>> + static Expected<std::unique_ptr<CoverageMapping>>
>>> load(StringRef ObjectFilename, StringRef ProfileFilename,
>>> StringRef Arch = StringRef());
>>>
>>> @@ -501,14 +504,13 @@ template <class IntPtrT> struct CovMapFu
>>> }
>>> // Return the PGO name of the function */
>>> template <support::endianness Endian>
>>> - std::error_code getFuncName(InstrProfSymtab &ProfileNames,
>>> - StringRef &FuncName) const {
>>> + Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName)
>>> const {
>>> IntPtrT NameRef = getFuncNameRef<Endian>();
>>> uint32_t NameS = support::endian::byte_swap<uint32_t,
>>> Endian>(NameSize);
>>> FuncName = ProfileNames.getFuncName(NameRef, NameS);
>>> if (NameS && FuncName.empty())
>>> - return coveragemap_error::malformed;
>>> - return std::error_code();
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> + return Error::success();
>>> }
>>> };
>>>
>>> @@ -530,11 +532,10 @@ struct CovMapFunctionRecord {
>>> }
>>> // Return the PGO name of the function */
>>> template <support::endianness Endian>
>>> - std::error_code getFuncName(InstrProfSymtab &ProfileNames,
>>> - StringRef &FuncName) const {
>>> + Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName)
>>> const {
>>> uint64_t NameRef = getFuncNameRef<Endian>();
>>> FuncName = ProfileNames.getFuncName(NameRef);
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>> };
>>>
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
>>> (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
>>> Fri May 13 16:50:56 2016
>>> @@ -69,7 +69,7 @@ public:
>>>
>>> class CoverageMappingReader {
>>> public:
>>> - virtual std::error_code readNextRecord(CoverageMappingRecord &Record)
>>> = 0;
>>> + virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
>>> CoverageMappingIterator begin() { return
>>> CoverageMappingIterator(this); }
>>> CoverageMappingIterator end() { return CoverageMappingIterator(); }
>>> virtual ~CoverageMappingReader() {}
>>> @@ -82,10 +82,10 @@ protected:
>>>
>>> RawCoverageReader(StringRef Data) : Data(Data) {}
>>>
>>> - std::error_code readULEB128(uint64_t &Result);
>>> - std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
>>> - std::error_code readSize(uint64_t &Result);
>>> - std::error_code readString(StringRef &Result);
>>> + Error readULEB128(uint64_t &Result);
>>> + Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
>>> + Error readSize(uint64_t &Result);
>>> + Error readString(StringRef &Result);
>>> };
>>>
>>> /// \brief Reader for the raw coverage filenames.
>>> @@ -100,7 +100,7 @@ public:
>>> RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef>
>>> &Filenames)
>>> : RawCoverageReader(Data), Filenames(Filenames) {}
>>>
>>> - std::error_code read();
>>> + Error read();
>>> };
>>>
>>> /// \brief Reader for the raw coverage mapping data.
>>> @@ -125,12 +125,12 @@ public:
>>> Filenames(Filenames), Expressions(Expressions),
>>> MappingRegions(MappingRegions) {}
>>>
>>> - std::error_code read();
>>> + Error read();
>>>
>>> private:
>>> - std::error_code decodeCounter(unsigned Value, Counter &C);
>>> - std::error_code readCounter(Counter &C);
>>> - std::error_code
>>> + Error decodeCounter(unsigned Value, Counter &C);
>>> + Error readCounter(Counter &C);
>>> + Error
>>> readMappingRegionsSubArray(std::vector<CounterMappingRegion>
>>> &MappingRegions,
>>> unsigned InferredFileID, size_t
>>> NumFileIDs);
>>> };
>>> @@ -170,11 +170,11 @@ private:
>>> BinaryCoverageReader() : CurrentRecord(0) {}
>>>
>>> public:
>>> - static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
>>> + static Expected<std::unique_ptr<BinaryCoverageReader>>
>>> create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
>>> StringRef Arch);
>>>
>>> - std::error_code readNextRecord(CoverageMappingRecord &Record)
>>> override;
>>> + Error readNextRecord(CoverageMappingRecord &Record) override;
>>> };
>>>
>>> } // end namespace coverage
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/InstrProf.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/InstrProf.h (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/InstrProf.h Fri May 13 16:50:56
>>> 2016
>>> @@ -25,7 +25,6 @@
>>> #include "llvm/ProfileData/ProfileCommon.h"
>>> #include "llvm/Support/Endian.h"
>>> #include "llvm/Support/ErrorHandling.h"
>>> -#include "llvm/Support/ErrorOr.h"
>>> #include "llvm/Support/MD5.h"
>>> #include "llvm/Support/MathExtras.h"
>>> #include <cstdint>
>>> @@ -204,20 +203,17 @@ StringRef getFuncNameWithoutPrefix(Strin
>>> /// third field is the uncompressed strings; otherwise it is the
>>> /// compressed string. When the string compression is off, the
>>> /// second field will have value zero.
>>> -std::error_code
>>> -collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
>>> - bool doCompression, std::string &Result);
>>> +Error collectPGOFuncNameStrings(const std::vector<std::string>
>>> &NameStrs,
>>> + bool doCompression, std::string
>>> &Result);
>>> /// Produce \c Result string with the same format described above. The
>>> input
>>> /// is vector of PGO function name variables that are referenced.
>>> -std::error_code
>>> -collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,
>>> - std::string &Result, bool doCompression =
>>> true);
>>> +Error collectPGOFuncNameStrings(const std::vector<GlobalVariable *>
>>> &NameVars,
>>> + std::string &Result, bool doCompression
>>> = true);
>>> class InstrProfSymtab;
>>> /// \c NameStrings is a string composed of one of more sub-strings
>>> encoded in
>>> /// the format described above. The substrings are seperated by 0 or
>>> more zero
>>> /// bytes. This method decodes the string and populates the \c Symtab.
>>> -std::error_code readPGOFuncNameStrings(StringRef NameStrings,
>>> - InstrProfSymtab &Symtab);
>>> +Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab
>>> &Symtab);
>>>
>>> enum InstrProfValueKind : uint32_t {
>>> #define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,
>>> @@ -284,6 +280,25 @@ inline std::error_code make_error_code(i
>>> return std::error_code(static_cast<int>(E), instrprof_category());
>>> }
>>>
>>> +class InstrProfError : public ProfErrorInfoBase<instrprof_error> {
>>> +public:
>>> + InstrProfError(instrprof_error Err)
>>> + : ProfErrorInfoBase<instrprof_error>(Err) {}
>>> +
>>> + std::string message() const override;
>>> +
>>> + /// Consume an Error and return the raw enum value contained within
>>> it. The
>>> + /// Error must either be a success value, or contain a single
>>> InstrProfError.
>>> + static instrprof_error take(Error E) {
>>> + auto Err = instrprof_error::success;
>>> + handleAllErrors(std::move(E), [&Err](const InstrProfError &IPE) {
>>> + assert(Err == instrprof_error::success && "Multiple errors
>>> encountered");
>>> + Err = IPE.get();
>>> + });
>>> + return Err;
>>> + }
>>> +};
>>> +
>>> class SoftInstrProfErrors {
>>> /// Count the number of soft instrprof_errors encountered and keep
>>> track of
>>> /// the first such error for reporting purposes.
>>> @@ -309,6 +324,11 @@ public:
>>> NumCountMismatches(0), NumCounterOverflows(0),
>>> NumValueSiteCountMismatches(0) {}
>>>
>>> + ~SoftInstrProfErrors() {
>>> + assert(FirstError == instrprof_error::success &&
>>> + "Unchecked soft error encountered");
>>> + }
>>> +
>>> /// Track a soft error (\p IE) and increment its associated counter.
>>> void addError(instrprof_error IE);
>>>
>>> @@ -326,8 +346,15 @@ public:
>>> return NumValueSiteCountMismatches;
>>> }
>>>
>>> - /// Return an error code for the first encountered error.
>>> - std::error_code getError() const { return
>>> make_error_code(FirstError); }
>>> + /// Return the first encountered error and reset FirstError to a
>>> success
>>> + /// value.
>>> + Error takeError() {
>>> + if (FirstError == instrprof_error::success)
>>> + return Error::success();
>>> + auto E = make_error<InstrProfError>(FirstError);
>>> + FirstError = instrprof_error::success;
>>> + return E;
>>> + }
>>> };
>>>
>>> namespace object {
>>> @@ -372,14 +399,14 @@ public:
>>> /// only initialize the symtab with reference to the data and
>>> /// the section base address. The decompression will be delayed
>>> /// until before it is used. See also \c create(StringRef) method.
>>> - std::error_code create(object::SectionRef &Section);
>>> + Error create(object::SectionRef &Section);
>>> /// This interface is used by reader of CoverageMapping test
>>> /// format.
>>> - inline std::error_code create(StringRef D, uint64_t BaseAddr);
>>> + inline Error create(StringRef D, uint64_t BaseAddr);
>>> /// \c NameStrings is a string composed of one of more sub-strings
>>> /// encoded in the format described in \c collectPGOFuncNameStrings.
>>> /// This method is a wrapper to \c readPGOFuncNameStrings method.
>>> - inline std::error_code create(StringRef NameStrings);
>>> + inline Error create(StringRef NameStrings);
>>> /// A wrapper interface to populate the PGO symtab with functions
>>> /// decls from module \c M. This interface is used by transformation
>>> /// passes such as indirect function call promotion. Variable \c InLTO
>>> @@ -424,13 +451,13 @@ public:
>>> inline StringRef getNameData() const { return Data; }
>>> };
>>>
>>> -std::error_code InstrProfSymtab::create(StringRef D, uint64_t BaseAddr)
>>> {
>>> +Error InstrProfSymtab::create(StringRef D, uint64_t BaseAddr) {
>>> Data = D;
>>> Address = BaseAddr;
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code InstrProfSymtab::create(StringRef NameStrings) {
>>> +Error InstrProfSymtab::create(StringRef NameStrings) {
>>> return readPGOFuncNameStrings(NameStrings, *this);
>>> }
>>>
>>> @@ -572,7 +599,7 @@ struct InstrProfRecord {
>>> }
>>>
>>> /// Get the error contained within the record's soft error counter.
>>> - std::error_code getError() const { return SIPE.getError(); }
>>> + Error takeError() { return SIPE.takeError(); }
>>>
>>> private:
>>> std::vector<InstrProfValueSiteRecord> IndirectCallSites;
>>> @@ -890,9 +917,4 @@ struct Header {
>>>
>>> } // end namespace llvm
>>>
>>> -namespace std {
>>> -template <>
>>> -struct is_error_code_enum<llvm::instrprof_error> : std::true_type {};
>>> -}
>>> -
>>> #endif // LLVM_PROFILEDATA_INSTRPROF_H
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/InstrProfData.inc
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfData.inc?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/InstrProfData.inc (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/InstrProfData.inc Fri May 13
>>> 16:50:56 2016
>>> @@ -295,16 +295,15 @@ typedef struct ValueProfData {
>>> static std::unique_ptr<ValueProfData>
>>> serializeFrom(const InstrProfRecord &Record);
>>> /*!
>>> - * Check the integrity of the record. Return the error code when
>>> - * an error is detected, otherwise return instrprof_error::success.
>>> + * Check the integrity of the record.
>>> */
>>> - instrprof_error checkIntegrity();
>>> + Error checkIntegrity();
>>> /*!
>>> * Return a pointer to \c ValueProfileData instance ready to be read.
>>> * All data in the instance are properly byte swapped. The input
>>> * data is assumed to be in little endian order.
>>> */
>>> - static ErrorOr<std::unique_ptr<ValueProfData>>
>>> + static Expected<std::unique_ptr<ValueProfData>>
>>> getValueProfData(const unsigned char *SrcBuffer,
>>> const unsigned char *const SrcBufferEnd,
>>> support::endianness SrcDataEndianness);
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfReader.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/InstrProfReader.h (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/InstrProfReader.h Fri May 13
>>> 16:50:56 2016
>>> @@ -19,7 +19,6 @@
>>> #include "llvm/ADT/StringExtras.h"
>>> #include "llvm/ProfileData/InstrProf.h"
>>> #include "llvm/Support/EndianStream.h"
>>> -#include "llvm/Support/ErrorOr.h"
>>> #include "llvm/Support/LineIterator.h"
>>> #include "llvm/Support/MemoryBuffer.h"
>>> #include "llvm/Support/OnDiskHashTable.h"
>>> @@ -51,16 +50,16 @@ public:
>>> /// Base class and interface for reading profiling data of any known
>>> instrprof
>>> /// format. Provides an iterator over InstrProfRecords.
>>> class InstrProfReader {
>>> - std::error_code LastError;
>>> + instrprof_error LastError;
>>>
>>> public:
>>> InstrProfReader() : LastError(instrprof_error::success), Symtab() {}
>>> virtual ~InstrProfReader() {}
>>>
>>> /// Read the header. Required before reading first record.
>>> - virtual std::error_code readHeader() = 0;
>>> + virtual Error readHeader() = 0;
>>> /// Read a single record.
>>> - virtual std::error_code readNextRecord(InstrProfRecord &Record) = 0;
>>> + virtual Error readNextRecord(InstrProfRecord &Record) = 0;
>>> /// Iterator over profile data.
>>> InstrProfIterator begin() { return InstrProfIterator(this); }
>>> InstrProfIterator end() { return InstrProfIterator(); }
>>> @@ -80,28 +79,35 @@ public:
>>>
>>> protected:
>>> std::unique_ptr<InstrProfSymtab> Symtab;
>>> - /// Set the current std::error_code and return same.
>>> - std::error_code error(std::error_code EC) {
>>> - LastError = EC;
>>> - return EC;
>>> + /// Set the current error and return same.
>>> + Error error(instrprof_error Err) {
>>> + LastError = Err;
>>> + if (Err == instrprof_error::success)
>>> + return Error::success();
>>> + return make_error<InstrProfError>(Err);
>>> }
>>> + Error error(Error E) { return
>>> error(InstrProfError::take(std::move(E))); }
>>>
>>> - /// Clear the current error code and return a successful one.
>>> - std::error_code success() { return error(instrprof_error::success); }
>>> + /// Clear the current error and return a successful one.
>>> + Error success() { return error(instrprof_error::success); }
>>>
>>> public:
>>> /// Return true if the reader has finished reading the profile data.
>>> bool isEOF() { return LastError == instrprof_error::eof; }
>>> /// Return true if the reader encountered an error reading profiling
>>> data.
>>> - bool hasError() { return LastError && !isEOF(); }
>>> - /// Get the current error code.
>>> - std::error_code getError() { return LastError; }
>>> + bool hasError() { return LastError != instrprof_error::success &&
>>> !isEOF(); }
>>> + /// Get the current error.
>>> + Error getError() {
>>> + if (hasError())
>>> + return make_error<InstrProfError>(LastError);
>>> + return Error::success();
>>> + }
>>>
>>> /// Factory method to create an appropriately typed reader for the
>>> given
>>> /// instrprof file.
>>> - static ErrorOr<std::unique_ptr<InstrProfReader>> create(std::string
>>> Path);
>>> + static Expected<std::unique_ptr<InstrProfReader>> create(std::string
>>> Path);
>>>
>>> - static ErrorOr<std::unique_ptr<InstrProfReader>>
>>> + static Expected<std::unique_ptr<InstrProfReader>>
>>> create(std::unique_ptr<MemoryBuffer> Buffer);
>>> };
>>>
>>> @@ -123,7 +129,7 @@ private:
>>>
>>> TextInstrProfReader(const TextInstrProfReader &) = delete;
>>> TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
>>> - std::error_code readValueProfileData(InstrProfRecord &Record);
>>> + Error readValueProfileData(InstrProfRecord &Record);
>>>
>>> public:
>>> TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
>>> @@ -136,9 +142,9 @@ public:
>>> bool isIRLevelProfile() const override { return IsIRLevelProfile; }
>>>
>>> /// Read the header.
>>> - std::error_code readHeader() override;
>>> + Error readHeader() override;
>>> /// Read a single record.
>>> - std::error_code readNextRecord(InstrProfRecord &Record) override;
>>> + Error readNextRecord(InstrProfRecord &Record) override;
>>>
>>> InstrProfSymtab &getSymtab() override {
>>> assert(Symtab.get());
>>> @@ -185,8 +191,8 @@ public:
>>> : DataBuffer(std::move(DataBuffer)) { }
>>>
>>> static bool hasFormat(const MemoryBuffer &DataBuffer);
>>> - std::error_code readHeader() override;
>>> - std::error_code readNextRecord(InstrProfRecord &Record) override;
>>> + Error readHeader() override;
>>> + Error readNextRecord(InstrProfRecord &Record) override;
>>> bool isIRLevelProfile() const override {
>>> return (Version & VARIANT_MASK_IR_PROF) != 0;
>>> }
>>> @@ -197,9 +203,9 @@ public:
>>> }
>>>
>>> private:
>>> - std::error_code createSymtab(InstrProfSymtab &Symtab);
>>> - std::error_code readNextHeader(const char *CurrentPos);
>>> - std::error_code readHeader(const RawInstrProf::Header &Header);
>>> + Error createSymtab(InstrProfSymtab &Symtab);
>>> + Error readNextHeader(const char *CurrentPos);
>>> + Error readHeader(const RawInstrProf::Header &Header);
>>> template <class IntT> IntT swap(IntT Int) const {
>>> return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
>>> }
>>> @@ -216,10 +222,10 @@ private:
>>> inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
>>> return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
>>> }
>>> - std::error_code readName(InstrProfRecord &Record);
>>> - std::error_code readFuncHash(InstrProfRecord &Record);
>>> - std::error_code readRawCounts(InstrProfRecord &Record);
>>> - std::error_code readValueProfilingData(InstrProfRecord &Record);
>>> + Error readName(InstrProfRecord &Record);
>>> + Error readFuncHash(InstrProfRecord &Record);
>>> + Error readRawCounts(InstrProfRecord &Record);
>>> + Error readValueProfilingData(InstrProfRecord &Record);
>>> bool atEnd() const { return Data == DataEnd; }
>>> void advanceData() {
>>> Data++;
>>> @@ -300,9 +306,9 @@ public:
>>> struct InstrProfReaderIndexBase {
>>> // Read all the profile records with the same key pointed to the
>>> current
>>> // iterator.
>>> - virtual std::error_code getRecords(ArrayRef<InstrProfRecord> &Data) =
>>> 0;
>>> + virtual Error getRecords(ArrayRef<InstrProfRecord> &Data) = 0;
>>> // Read all the profile records with the key equal to FuncName
>>> - virtual std::error_code getRecords(StringRef FuncName,
>>> + virtual Error getRecords(StringRef FuncName,
>>> ArrayRef<InstrProfRecord> &Data) =
>>> 0;
>>> virtual void advanceToNextKey() = 0;
>>> virtual bool atEnd() const = 0;
>>> @@ -330,9 +336,9 @@ public:
>>> const unsigned char *const Base,
>>> IndexedInstrProf::HashT HashType, uint64_t
>>> Version);
>>>
>>> - std::error_code getRecords(ArrayRef<InstrProfRecord> &Data) override;
>>> - std::error_code getRecords(StringRef FuncName,
>>> - ArrayRef<InstrProfRecord> &Data) override;
>>> + Error getRecords(ArrayRef<InstrProfRecord> &Data) override;
>>> + Error getRecords(StringRef FuncName,
>>> + ArrayRef<InstrProfRecord> &Data) override;
>>> void advanceToNextKey() override { RecordIterator++; }
>>> bool atEnd() const override {
>>> return RecordIterator == HashTable->data_end();
>>> @@ -379,27 +385,27 @@ public:
>>> static bool hasFormat(const MemoryBuffer &DataBuffer);
>>>
>>> /// Read the file header.
>>> - std::error_code readHeader() override;
>>> + Error readHeader() override;
>>> /// Read a single record.
>>> - std::error_code readNextRecord(InstrProfRecord &Record) override;
>>> + Error readNextRecord(InstrProfRecord &Record) override;
>>>
>>> /// Return the pointer to InstrProfRecord associated with FuncName
>>> /// and FuncHash
>>> - ErrorOr<InstrProfRecord> getInstrProfRecord(StringRef FuncName,
>>> - uint64_t FuncHash);
>>> + Expected<InstrProfRecord> getInstrProfRecord(StringRef FuncName,
>>> + uint64_t FuncHash);
>>>
>>> /// Fill Counts with the profile data for the given function name.
>>> - std::error_code getFunctionCounts(StringRef FuncName, uint64_t
>>> FuncHash,
>>> - std::vector<uint64_t> &Counts);
>>> + Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
>>> + std::vector<uint64_t> &Counts);
>>>
>>> /// Return the maximum of all known function counts.
>>> uint64_t getMaximumFunctionCount() { return
>>> Summary->getMaxFunctionCount(); }
>>>
>>> /// Factory method to create an indexed reader.
>>> - static ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
>>> + static Expected<std::unique_ptr<IndexedInstrProfReader>>
>>> create(std::string Path);
>>>
>>> - static ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
>>> + static Expected<std::unique_ptr<IndexedInstrProfReader>>
>>> create(std::unique_ptr<MemoryBuffer> Buffer);
>>>
>>> // Used for testing purpose only.
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/InstrProfWriter.h Fri May 13
>>> 16:50:56 2016
>>> @@ -46,7 +46,7 @@ public:
>>> /// Add function counts for the given function. If there are already
>>> counts
>>> /// for this function and the hash and number of counts match, each
>>> counter is
>>> /// summed. Optionally scale counts by \p Weight.
>>> - std::error_code addRecord(InstrProfRecord &&I, uint64_t Weight = 1);
>>> + Error addRecord(InstrProfRecord &&I, uint64_t Weight = 1);
>>> /// Write the profile to \c OS
>>> void write(raw_fd_ostream &OS);
>>> /// Write the profile in text format to \c OS
>>> @@ -58,13 +58,15 @@ public:
>>> std::unique_ptr<MemoryBuffer> writeBuffer();
>>>
>>> /// Set the ProfileKind. Report error if mixing FE and IR level
>>> profiles.
>>> - std::error_code setIsIRLevelProfile(bool IsIRLevel) {
>>> + Error setIsIRLevelProfile(bool IsIRLevel) {
>>> if (ProfileKind == PF_Unknown) {
>>> ProfileKind = IsIRLevel ? PF_IRLevel: PF_FE;
>>> - return instrprof_error::success;
>>> + return Error::success();
>>> }
>>> - return (IsIRLevel == (ProfileKind == PF_IRLevel)) ?
>>> - instrprof_error::success :
>>> instrprof_error::unsupported_version;
>>> + return (IsIRLevel == (ProfileKind == PF_IRLevel))
>>> + ? Error::success()
>>> + : make_error<InstrProfError>(
>>> + instrprof_error::unsupported_version);
>>> }
>>>
>>> // Internal interface for testing purpose only.
>>>
>>> Modified: llvm/trunk/include/llvm/ProfileData/ProfileCommon.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/ProfileCommon.h?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/ProfileData/ProfileCommon.h (original)
>>> +++ llvm/trunk/include/llvm/ProfileData/ProfileCommon.h Fri May 13
>>> 16:50:56 2016
>>> @@ -21,6 +21,7 @@
>>> #include <vector>
>>>
>>> #include "llvm/Support/Casting.h"
>>> +#include "llvm/Support/Error.h"
>>>
>>> namespace llvm {
>>> class Function;
>>> @@ -36,6 +37,29 @@ class Metadata;
>>> class MDTuple;
>>> class MDNode;
>>>
>>> +template <typename ErrT>
>>> +class ProfErrorInfoBase : public ErrorInfo<ProfErrorInfoBase<ErrT>> {
>>> +public:
>>> + ProfErrorInfoBase(ErrT Err) : Err(Err) {
>>> + assert(Err != ErrT::success && "Not an error");
>>> + }
>>> +
>>> + virtual std::string message() const override = 0;
>>> +
>>> + void log(raw_ostream &OS) const override { OS << message(); }
>>> +
>>> + std::error_code convertToErrorCode() const override {
>>> + return make_error_code(Err);
>>> + }
>>> +
>>> + ErrT get() const { return Err; }
>>> +
>>> + static char ID;
>>> +
>>> +protected:
>>> + ErrT Err;
>>> +};
>>> +
>>> inline const char *getHotSectionPrefix() { return ".hot"; }
>>> inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
>>>
>>>
>>> Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp (original)
>>> +++ llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp Fri May 13
>>> 16:50:56 2016
>>> @@ -143,28 +143,30 @@ void CounterMappingContext::dump(const C
>>> }
>>> if (CounterValues.empty())
>>> return;
>>> - ErrorOr<int64_t> Value = evaluate(C);
>>> - if (!Value)
>>> + Expected<int64_t> Value = evaluate(C);
>>> + if (auto E = Value.takeError()) {
>>> + llvm::consumeError(std::move(E));
>>> return;
>>> + }
>>> OS << '[' << *Value << ']';
>>> }
>>>
>>> -ErrorOr<int64_t> CounterMappingContext::evaluate(const Counter &C)
>>> const {
>>> +Expected<int64_t> CounterMappingContext::evaluate(const Counter &C)
>>> const {
>>> switch (C.getKind()) {
>>> case Counter::Zero:
>>> return 0;
>>> case Counter::CounterValueReference:
>>> if (C.getCounterID() >= CounterValues.size())
>>> - return make_error_code(errc::argument_out_of_domain);
>>> + return errorCodeToError(errc::argument_out_of_domain);
>>> return CounterValues[C.getCounterID()];
>>> case Counter::Expression: {
>>> if (C.getExpressionID() >= Expressions.size())
>>> - return make_error_code(errc::argument_out_of_domain);
>>> + return errorCodeToError(errc::argument_out_of_domain);
>>> const auto &E = Expressions[C.getExpressionID()];
>>> - ErrorOr<int64_t> LHS = evaluate(E.LHS);
>>> + Expected<int64_t> LHS = evaluate(E.LHS);
>>> if (!LHS)
>>> return LHS;
>>> - ErrorOr<int64_t> RHS = evaluate(E.RHS);
>>> + Expected<int64_t> RHS = evaluate(E.RHS);
>>> if (!RHS)
>>> return RHS;
>>> return E.Kind == CounterExpression::Subtract ? *LHS - *RHS : *LHS +
>>> *RHS;
>>> @@ -181,7 +183,7 @@ void FunctionRecordIterator::skipOtherFi
>>> *this = FunctionRecordIterator();
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<CoverageMapping>>
>>> +Expected<std::unique_ptr<CoverageMapping>>
>>> CoverageMapping::load(CoverageMappingReader &CoverageReader,
>>> IndexedInstrProfReader &ProfileReader) {
>>> auto Coverage = std::unique_ptr<CoverageMapping>(new
>>> CoverageMapping());
>>> @@ -191,13 +193,14 @@ CoverageMapping::load(CoverageMappingRea
>>> CounterMappingContext Ctx(Record.Expressions);
>>>
>>> Counts.clear();
>>> - if (std::error_code EC = ProfileReader.getFunctionCounts(
>>> + if (Error E = ProfileReader.getFunctionCounts(
>>> Record.FunctionName, Record.FunctionHash, Counts)) {
>>> - if (EC == instrprof_error::hash_mismatch) {
>>> + instrprof_error IPE = InstrProfError::take(std::move(E));
>>> + if (IPE == instrprof_error::hash_mismatch) {
>>> Coverage->MismatchedFunctionCount++;
>>> continue;
>>> - } else if (EC != instrprof_error::unknown_function)
>>> - return EC;
>>> + } else if (IPE != instrprof_error::unknown_function)
>>> + return make_error<InstrProfError>(IPE);
>>> Counts.assign(Record.MappingRegions.size(), 0);
>>> }
>>> Ctx.setCounts(Counts);
>>> @@ -212,9 +215,11 @@ CoverageMapping::load(CoverageMappingRea
>>> getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
>>> FunctionRecord Function(OrigFuncName, Record.Filenames);
>>> for (const auto &Region : Record.MappingRegions) {
>>> - ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
>>> - if (!ExecutionCount)
>>> + Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
>>> + if (auto E = ExecutionCount.takeError()) {
>>> + llvm::consumeError(std::move(E));
>>> break;
>>> + }
>>> Function.pushRegion(Region, *ExecutionCount);
>>> }
>>> if (Function.CountedRegions.size() != Record.MappingRegions.size())
>>> {
>>> @@ -228,20 +233,20 @@ CoverageMapping::load(CoverageMappingRea
>>> return std::move(Coverage);
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<CoverageMapping>>
>>> +Expected<std::unique_ptr<CoverageMapping>>
>>> CoverageMapping::load(StringRef ObjectFilename, StringRef
>>> ProfileFilename,
>>> StringRef Arch) {
>>> auto CounterMappingBuff =
>>> MemoryBuffer::getFileOrSTDIN(ObjectFilename);
>>> if (std::error_code EC = CounterMappingBuff.getError())
>>> - return EC;
>>> + return errorCodeToError(EC);
>>> auto CoverageReaderOrErr =
>>> BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
>>> - if (std::error_code EC = CoverageReaderOrErr.getError())
>>> - return EC;
>>> + if (Error E = CoverageReaderOrErr.takeError())
>>> + return std::move(E);
>>> auto CoverageReader = std::move(CoverageReaderOrErr.get());
>>> auto ProfileReaderOrErr =
>>> IndexedInstrProfReader::create(ProfileFilename);
>>> - if (auto EC = ProfileReaderOrErr.getError())
>>> - return EC;
>>> + if (Error E = ProfileReaderOrErr.takeError())
>>> + return std::move(E);
>>> auto ProfileReader = std::move(ProfileReaderOrErr.get());
>>> return load(*CoverageReader, *ProfileReader);
>>> }
>>> @@ -533,27 +538,34 @@ CoverageMapping::getCoverageForExpansion
>>> }
>>>
>>> namespace {
>>> +std::string getCoverageMapErrString(coveragemap_error Err) {
>>> + switch (Err) {
>>> + case coveragemap_error::success:
>>> + return "Success";
>>> + case coveragemap_error::eof:
>>> + return "End of File";
>>> + case coveragemap_error::no_data_found:
>>> + return "No coverage data found";
>>> + case coveragemap_error::unsupported_version:
>>> + return "Unsupported coverage format version";
>>> + case coveragemap_error::truncated:
>>> + return "Truncated coverage data";
>>> + case coveragemap_error::malformed:
>>> + return "Malformed coverage data";
>>> + }
>>> + llvm_unreachable("A value of coveragemap_error has no message.");
>>> +}
>>> +
>>> class CoverageMappingErrorCategoryType : public std::error_category {
>>> const char *name() const LLVM_NOEXCEPT override { return
>>> "llvm.coveragemap"; }
>>> std::string message(int IE) const override {
>>> - auto E = static_cast<coveragemap_error>(IE);
>>> - switch (E) {
>>> - case coveragemap_error::success:
>>> - return "Success";
>>> - case coveragemap_error::eof:
>>> - return "End of File";
>>> - case coveragemap_error::no_data_found:
>>> - return "No coverage data found";
>>> - case coveragemap_error::unsupported_version:
>>> - return "Unsupported coverage format version";
>>> - case coveragemap_error::truncated:
>>> - return "Truncated coverage data";
>>> - case coveragemap_error::malformed:
>>> - return "Malformed coverage data";
>>> - }
>>> - llvm_unreachable("A value of coveragemap_error has no message.");
>>> + return getCoverageMapErrString(static_cast<coveragemap_error>(IE));
>>> }
>>> };
>>> +} // end anonymous namespace
>>> +
>>> +std::string CoverageMapError::message() const {
>>> + return getCoverageMapErrString(Err);
>>> }
>>>
>>> static ManagedStatic<CoverageMappingErrorCategoryType> ErrorCategory;
>>> @@ -561,3 +573,5 @@ static ManagedStatic<CoverageMappingErro
>>> const std::error_category &llvm::coverage::coveragemap_category() {
>>> return *ErrorCategory;
>>> }
>>> +
>>> +template <> char ProfErrorInfoBase<coveragemap_error>::ID = 0;
>>>
>>> Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp
>>> (original)
>>> +++ llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp Fri
>>> May 13 16:50:56 2016
>>> @@ -31,49 +31,54 @@ using namespace object;
>>> void CoverageMappingIterator::increment() {
>>> // Check if all the records were read or if an error occurred while
>>> reading
>>> // the next record.
>>> - if (Reader->readNextRecord(Record))
>>> - *this = CoverageMappingIterator();
>>> + if (auto E = Reader->readNextRecord(Record)) {
>>> + handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
>>> + if (CME.get() == coveragemap_error::eof)
>>> + *this = CoverageMappingIterator();
>>> + else
>>> + llvm_unreachable("Unexpected error in coverage mapping
>>> iterator");
>>> + });
>>> + }
>>> }
>>>
>>> -std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
>>> +Error RawCoverageReader::readULEB128(uint64_t &Result) {
>>> if (Data.size() < 1)
>>> - return coveragemap_error::truncated;
>>> + return make_error<CoverageMapError>(coveragemap_error::truncated);
>>> unsigned N = 0;
>>> Result = decodeULEB128(reinterpret_cast<const uint8_t
>>> *>(Data.data()), &N);
>>> if (N > Data.size())
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> Data = Data.substr(N);
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
>>> - uint64_t MaxPlus1) {
>>> +Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t
>>> MaxPlus1) {
>>> if (auto Err = readULEB128(Result))
>>> return Err;
>>> if (Result >= MaxPlus1)
>>> - return coveragemap_error::malformed;
>>> - return std::error_code();
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageReader::readSize(uint64_t &Result) {
>>> +Error RawCoverageReader::readSize(uint64_t &Result) {
>>> if (auto Err = readULEB128(Result))
>>> return Err;
>>> // Sanity check the number.
>>> if (Result > Data.size())
>>> - return coveragemap_error::malformed;
>>> - return std::error_code();
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageReader::readString(StringRef &Result) {
>>> +Error RawCoverageReader::readString(StringRef &Result) {
>>> uint64_t Length;
>>> if (auto Err = readSize(Length))
>>> return Err;
>>> Result = Data.substr(0, Length);
>>> Data = Data.substr(Length);
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageFilenamesReader::read() {
>>> +Error RawCoverageFilenamesReader::read() {
>>> uint64_t NumFilenames;
>>> if (auto Err = readSize(NumFilenames))
>>> return Err;
>>> @@ -83,19 +88,18 @@ std::error_code RawCoverageFilenamesRead
>>> return Err;
>>> Filenames.push_back(Filename);
>>> }
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
>>> - Counter &C) {
>>> +Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter
>>> &C) {
>>> auto Tag = Value & Counter::EncodingTagMask;
>>> switch (Tag) {
>>> case Counter::Zero:
>>> C = Counter::getZero();
>>> - return std::error_code();
>>> + return Error::success();
>>> case Counter::CounterValueReference:
>>> C = Counter::getCounter(Value >> Counter::EncodingTagBits);
>>> - return std::error_code();
>>> + return Error::success();
>>> default:
>>> break;
>>> }
>>> @@ -105,25 +109,25 @@ std::error_code RawCoverageMappingReader
>>> case CounterExpression::Add: {
>>> auto ID = Value >> Counter::EncodingTagBits;
>>> if (ID >= Expressions.size())
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
>>> C = Counter::getExpression(ID);
>>> break;
>>> }
>>> default:
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> }
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
>>> +Error RawCoverageMappingReader::readCounter(Counter &C) {
>>> uint64_t EncodedCounter;
>>> if (auto Err =
>>> readIntMax(EncodedCounter,
>>> std::numeric_limits<unsigned>::max()))
>>> return Err;
>>> if (auto Err = decodeCounter(EncodedCounter, C))
>>> return Err;
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> static const unsigned EncodingExpansionRegionBit = 1
>>> @@ -132,7 +136,7 @@ static const unsigned EncodingExpansionR
>>> /// \brief Read the sub-array of regions for the given inferred file id.
>>> /// \param NumFileIDs the number of file ids that are defined for this
>>> /// function.
>>> -std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
>>> +Error RawCoverageMappingReader::readMappingRegionsSubArray(
>>> std::vector<CounterMappingRegion> &MappingRegions, unsigned
>>> InferredFileID,
>>> size_t NumFileIDs) {
>>> uint64_t NumRegions;
>>> @@ -160,7 +164,7 @@ std::error_code RawCoverageMappingReader
>>> ExpandedFileID = EncodedCounterAndRegion >>
>>>
>>> Counter::EncodingCounterTagAndExpansionRegionTagBits;
>>> if (ExpandedFileID >= NumFileIDs)
>>> - return coveragemap_error::malformed;
>>> + return
>>> make_error<CoverageMapError>(coveragemap_error::malformed);
>>> } else {
>>> switch (EncodedCounterAndRegion >>
>>> Counter::EncodingCounterTagAndExpansionRegionTagBits) {
>>> @@ -171,7 +175,7 @@ std::error_code RawCoverageMappingReader
>>> Kind = CounterMappingRegion::SkippedRegion;
>>> break;
>>> default:
>>> - return coveragemap_error::malformed;
>>> + return
>>> make_error<CoverageMapError>(coveragemap_error::malformed);
>>> }
>>> }
>>> }
>>> @@ -184,7 +188,7 @@ std::error_code RawCoverageMappingReader
>>> if (auto Err = readULEB128(ColumnStart))
>>> return Err;
>>> if (ColumnStart > std::numeric_limits<unsigned>::max())
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> if (auto Err = readIntMax(NumLines,
>>> std::numeric_limits<unsigned>::max()))
>>> return Err;
>>> if (auto Err = readIntMax(ColumnEnd,
>>> std::numeric_limits<unsigned>::max()))
>>> @@ -218,10 +222,10 @@ std::error_code RawCoverageMappingReader
>>> C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
>>> LineStart + NumLines, ColumnEnd, Kind));
>>> }
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code RawCoverageMappingReader::read() {
>>> +Error RawCoverageMappingReader::read() {
>>>
>>> // Read the virtual file mapping.
>>> llvm::SmallVector<unsigned, 8> VirtualFileMapping;
>>> @@ -287,14 +291,14 @@ std::error_code RawCoverageMappingReader
>>> }
>>> }
>>>
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -std::error_code InstrProfSymtab::create(SectionRef &Section) {
>>> - if (auto Err = Section.getContents(Data))
>>> - return Err;
>>> +Error InstrProfSymtab::create(SectionRef &Section) {
>>> + if (auto EC = Section.getContents(Data))
>>> + return errorCodeToError(EC);
>>> Address = Section.getAddress();
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
>>> @@ -312,11 +316,10 @@ struct CovMapFuncRecordReader {
>>> // a module. \p Buf is a reference to the buffer pointer pointing
>>> // to the \c CovHeader of coverage mapping data associated with
>>> // the module.
>>> - virtual std::error_code readFunctionRecords(const char *&Buf,
>>> - const char *End) = 0;
>>> + virtual Error readFunctionRecords(const char *&Buf, const char *End)
>>> = 0;
>>> virtual ~CovMapFuncRecordReader() {}
>>> template <class IntPtrT, support::endianness Endian>
>>> - static ErrorOr<std::unique_ptr<CovMapFuncRecordReader>>
>>> + static Expected<std::unique_ptr<CovMapFuncRecordReader>>
>>> get(coverage::CovMapVersion Version, InstrProfSymtab &P,
>>> std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
>>> std::vector<StringRef> &F);
>>> @@ -344,11 +347,10 @@ public:
>>> : ProfileNames(P), Filenames(F), Records(R) {}
>>> ~VersionedCovMapFuncRecordReader() override {}
>>>
>>> - std::error_code readFunctionRecords(const char *&Buf,
>>> - const char *End) override {
>>> + Error readFunctionRecords(const char *&Buf, const char *End) override
>>> {
>>> using namespace support;
>>> if (Buf + sizeof(CovMapHeader) > End)
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> auto CovHeader = reinterpret_cast<const coverage::CovMapHeader
>>> *>(Buf);
>>> uint32_t NRecords = CovHeader->getNRecords<Endian>();
>>> uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
>>> @@ -363,7 +365,7 @@ public:
>>>
>>> // Get the filenames.
>>> if (Buf + FilenamesSize > End)
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> size_t FilenamesBegin = Filenames.size();
>>> RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize),
>>> Filenames);
>>> if (auto Err = Reader.read())
>>> @@ -376,7 +378,7 @@ public:
>>> const char *CovEnd = Buf;
>>>
>>> if (Buf > End)
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> // Each coverage map has an alignment of 8, so we need to adjust
>>> alignment
>>> // before reading the next map.
>>> Buf += alignmentAdjustment(Buf, 8);
>>> @@ -389,7 +391,7 @@ public:
>>>
>>> // Now use that to read the coverage data.
>>> if (CovBuf + DataSize > CovEnd)
>>> - return coveragemap_error::malformed;
>>> + return
>>> make_error<CoverageMapError>(coveragemap_error::malformed);
>>> auto Mapping = StringRef(CovBuf, DataSize);
>>> CovBuf += DataSize;
>>>
>>> @@ -403,21 +405,20 @@ public:
>>> }
>>>
>>> StringRef FuncName;
>>> - if (std::error_code EC =
>>> - CFR->template getFuncName<Endian>(ProfileNames, FuncName))
>>> - return EC;
>>> + if (Error E = CFR->template getFuncName<Endian>(ProfileNames,
>>> FuncName))
>>> + return E;
>>> Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
>>> Version, FuncName, FuncHash, Mapping, FilenamesBegin,
>>> Filenames.size() - FilenamesBegin));
>>> CFR++;
>>> }
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>> };
>>> } // end anonymous namespace
>>>
>>> template <class IntPtrT, support::endianness Endian>
>>> -ErrorOr<std::unique_ptr<CovMapFuncRecordReader>>
>>> CovMapFuncRecordReader::get(
>>> +Expected<std::unique_ptr<CovMapFuncRecordReader>>
>>> CovMapFuncRecordReader::get(
>>> coverage::CovMapVersion Version, InstrProfSymtab &P,
>>> std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
>>> std::vector<StringRef> &F) {
>>> @@ -428,8 +429,8 @@ ErrorOr<std::unique_ptr<CovMapFuncRecord
>>> CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
>>> case CovMapVersion::Version2:
>>> // Decompress the name data.
>>> - if (auto EC = P.create(P.getNameData()))
>>> - return EC;
>>> + if (Error E = P.create(P.getNameData()))
>>> + return std::move(E);
>>> return llvm::make_unique<VersionedCovMapFuncRecordReader<
>>> CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
>>> }
>>> @@ -437,7 +438,7 @@ ErrorOr<std::unique_ptr<CovMapFuncRecord
>>> }
>>>
>>> template <typename T, support::endianness Endian>
>>> -static std::error_code readCoverageMappingData(
>>> +static Error readCoverageMappingData(
>>> InstrProfSymtab &ProfileNames, StringRef Data,
>>> std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
>>> std::vector<StringRef> &Filenames) {
>>> @@ -447,89 +448,90 @@ static std::error_code readCoverageMappi
>>> reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
>>> CovMapVersion Version =
>>> (CovMapVersion)CovHeader->getVersion<Endian>();
>>> if (Version > coverage::CovMapVersion::CurrentVersion)
>>> - return coveragemap_error::unsupported_version;
>>> - ErrorOr<std::unique_ptr<CovMapFuncRecordReader>> ReaderErrorOr =
>>> + return
>>> make_error<CoverageMapError>(coveragemap_error::unsupported_version);
>>> + Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
>>> CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames,
>>> Records,
>>> Filenames);
>>> - if (auto EC = ReaderErrorOr.getError())
>>> - return EC;
>>> - auto Reader = std::move(ReaderErrorOr.get());
>>> + if (Error E = ReaderExpected.takeError())
>>> + return E;
>>> + auto Reader = std::move(ReaderExpected.get());
>>> for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf <
>>> End;) {
>>> - if (std::error_code EC = Reader->readFunctionRecords(Buf, End))
>>> - return EC;
>>> + if (Error E = Reader->readFunctionRecords(Buf, End))
>>> + return E;
>>> }
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>> static const char *TestingFormatMagic = "llvmcovmtestdata";
>>>
>>> -static std::error_code loadTestingFormat(StringRef Data,
>>> - InstrProfSymtab &ProfileNames,
>>> - StringRef &CoverageMapping,
>>> - uint8_t &BytesInAddress,
>>> - support::endianness &Endian) {
>>> +static Error loadTestingFormat(StringRef Data, InstrProfSymtab
>>> &ProfileNames,
>>> + StringRef &CoverageMapping,
>>> + uint8_t &BytesInAddress,
>>> + support::endianness &Endian) {
>>> BytesInAddress = 8;
>>> Endian = support::endianness::little;
>>>
>>> Data = Data.substr(StringRef(TestingFormatMagic).size());
>>> if (Data.size() < 1)
>>> - return coveragemap_error::truncated;
>>> + return make_error<CoverageMapError>(coveragemap_error::truncated);
>>> unsigned N = 0;
>>> auto ProfileNamesSize =
>>> decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
>>> if (N > Data.size())
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> Data = Data.substr(N);
>>> if (Data.size() < 1)
>>> - return coveragemap_error::truncated;
>>> + return make_error<CoverageMapError>(coveragemap_error::truncated);
>>> N = 0;
>>> uint64_t Address =
>>> decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
>>> if (N > Data.size())
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> Data = Data.substr(N);
>>> if (Data.size() < ProfileNamesSize)
>>> - return coveragemap_error::malformed;
>>> - ProfileNames.create(Data.substr(0, ProfileNamesSize), Address);
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> + if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize),
>>> Address))
>>> + return E;
>>> CoverageMapping = Data.substr(ProfileNamesSize);
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -static ErrorOr<SectionRef> lookupSection(ObjectFile &OF, StringRef
>>> Name) {
>>> +static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef
>>> Name) {
>>> StringRef FoundName;
>>> for (const auto &Section : OF.sections()) {
>>> if (auto EC = Section.getName(FoundName))
>>> - return EC;
>>> + return errorCodeToError(EC);
>>> if (FoundName == Name)
>>> return Section;
>>> }
>>> - return coveragemap_error::no_data_found;
>>> + return make_error<CoverageMapError>(coveragemap_error::no_data_found);
>>> }
>>>
>>> -static std::error_code
>>> -loadBinaryFormat(MemoryBufferRef ObjectBuffer, InstrProfSymtab
>>> &ProfileNames,
>>> - StringRef &CoverageMapping, uint8_t &BytesInAddress,
>>> - support::endianness &Endian, StringRef Arch) {
>>> +static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
>>> + InstrProfSymtab &ProfileNames,
>>> + StringRef &CoverageMapping,
>>> + uint8_t &BytesInAddress,
>>> + support::endianness &Endian, StringRef
>>> Arch) {
>>> auto BinOrErr = object::createBinary(ObjectBuffer);
>>> if (!BinOrErr)
>>> - return errorToErrorCode(BinOrErr.takeError());
>>> + return BinOrErr.takeError();
>>> auto Bin = std::move(BinOrErr.get());
>>> std::unique_ptr<ObjectFile> OF;
>>> if (auto *Universal =
>>> dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
>>> // If we have a universal binary, try to look up the object for the
>>> // appropriate architecture.
>>> auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
>>> - if (std::error_code EC = ObjectFileOrErr.getError())
>>> - return EC;
>>> + if (auto EC = ObjectFileOrErr.getError())
>>> + return errorCodeToError(EC);
>>> OF = std::move(ObjectFileOrErr.get());
>>> } else if (isa<object::ObjectFile>(Bin.get())) {
>>> // For any other object file, upcast and take ownership.
>>> OF.reset(cast<object::ObjectFile>(Bin.release()));
>>> // If we've asked for a particular arch, make sure they match.
>>> if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
>>> - return object_error::arch_not_found;
>>> + return errorCodeToError(object_error::arch_not_found);
>>> } else
>>> // We can only handle object files.
>>> - return coveragemap_error::malformed;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>>
>>> // The coverage uses native pointer sizes for the object it's written
>>> in.
>>> BytesInAddress = OF->getBytesInAddress();
>>> @@ -538,23 +540,23 @@ loadBinaryFormat(MemoryBufferRef ObjectB
>>>
>>> // Look for the sections that we are interested in.
>>> auto NamesSection = lookupSection(*OF,
>>> getInstrProfNameSectionName(false));
>>> - if (auto EC = NamesSection.getError())
>>> - return EC;
>>> + if (auto E = NamesSection.takeError())
>>> + return E;
>>> auto CoverageSection =
>>> lookupSection(*OF, getInstrProfCoverageSectionName(false));
>>> - if (auto EC = CoverageSection.getError())
>>> - return EC;
>>> + if (auto E = CoverageSection.takeError())
>>> + return E;
>>>
>>> // Get the contents of the given sections.
>>> - if (std::error_code EC =
>>> CoverageSection->getContents(CoverageMapping))
>>> - return EC;
>>> - if (std::error_code EC = ProfileNames.create(*NamesSection))
>>> - return EC;
>>> + if (auto EC = CoverageSection->getContents(CoverageMapping))
>>> + return errorCodeToError(EC);
>>> + if (Error E = ProfileNames.create(*NamesSection))
>>> + return E;
>>>
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<BinaryCoverageReader>>
>>> +Expected<std::unique_ptr<BinaryCoverageReader>>
>>> BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer>
>>> &ObjectBuffer,
>>> StringRef Arch) {
>>> std::unique_ptr<BinaryCoverageReader> Reader(new
>>> BinaryCoverageReader());
>>> @@ -562,44 +564,44 @@ BinaryCoverageReader::create(std::unique
>>> StringRef Coverage;
>>> uint8_t BytesInAddress;
>>> support::endianness Endian;
>>> - std::error_code EC;
>>> + Error E;
>>> + consumeError(std::move(E));
>>> if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
>>> // This is a special format used for testing.
>>> - EC = loadTestingFormat(ObjectBuffer->getBuffer(),
>>> Reader->ProfileNames,
>>> - Coverage, BytesInAddress, Endian);
>>> + E = loadTestingFormat(ObjectBuffer->getBuffer(),
>>> Reader->ProfileNames,
>>> + Coverage, BytesInAddress, Endian);
>>> else
>>> - EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(),
>>> Reader->ProfileNames,
>>> - Coverage, BytesInAddress, Endian, Arch);
>>> - if (EC)
>>> - return EC;
>>> + E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(),
>>> Reader->ProfileNames,
>>> + Coverage, BytesInAddress, Endian, Arch);
>>> + if (E)
>>> + return std::move(E);
>>>
>>> if (BytesInAddress == 4 && Endian == support::endianness::little)
>>> - EC = readCoverageMappingData<uint32_t, support::endianness::little>(
>>> + E = readCoverageMappingData<uint32_t, support::endianness::little>(
>>> Reader->ProfileNames, Coverage, Reader->MappingRecords,
>>> Reader->Filenames);
>>> else if (BytesInAddress == 4 && Endian == support::endianness::big)
>>> - EC = readCoverageMappingData<uint32_t, support::endianness::big>(
>>> + E = readCoverageMappingData<uint32_t, support::endianness::big>(
>>> Reader->ProfileNames, Coverage, Reader->MappingRecords,
>>> Reader->Filenames);
>>> else if (BytesInAddress == 8 && Endian == support::endianness::little)
>>> - EC = readCoverageMappingData<uint64_t, support::endianness::little>(
>>> + E = readCoverageMappingData<uint64_t, support::endianness::little>(
>>> Reader->ProfileNames, Coverage, Reader->MappingRecords,
>>> Reader->Filenames);
>>> else if (BytesInAddress == 8 && Endian == support::endianness::big)
>>> - EC = readCoverageMappingData<uint64_t, support::endianness::big>(
>>> + E = readCoverageMappingData<uint64_t, support::endianness::big>(
>>> Reader->ProfileNames, Coverage, Reader->MappingRecords,
>>> Reader->Filenames);
>>> else
>>> - return coveragemap_error::malformed;
>>> - if (EC)
>>> - return EC;
>>> + return make_error<CoverageMapError>(coveragemap_error::malformed);
>>> + if (E)
>>> + return std::move(E);
>>> return std::move(Reader);
>>> }
>>>
>>> -std::error_code
>>> -BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
>>> +Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord
>>> &Record) {
>>> if (CurrentRecord >= MappingRecords.size())
>>> - return coveragemap_error::eof;
>>> + return make_error<CoverageMapError>(coveragemap_error::eof);
>>>
>>> FunctionsFilenames.clear();
>>> Expressions.clear();
>>> @@ -619,5 +621,5 @@ BinaryCoverageReader::readNextRecord(Cov
>>> Record.MappingRegions = MappingRegions;
>>>
>>> ++CurrentRecord;
>>> - return std::error_code();
>>> + return Error::success();
>>> }
>>>
>>> Modified: llvm/trunk/lib/ProfileData/InstrProf.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProf.cpp?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/ProfileData/InstrProf.cpp (original)
>>> +++ llvm/trunk/lib/ProfileData/InstrProf.cpp Fri May 13 16:50:56 2016
>>> @@ -27,47 +27,50 @@
>>> using namespace llvm;
>>>
>>> namespace {
>>> +std::string getInstrProfErrString(instrprof_error Err) {
>>> + switch (Err) {
>>> + case instrprof_error::success:
>>> + return "Success";
>>> + case instrprof_error::eof:
>>> + return "End of File";
>>> + case instrprof_error::unrecognized_format:
>>> + return "Unrecognized instrumentation profile encoding format";
>>> + case instrprof_error::bad_magic:
>>> + return "Invalid instrumentation profile data (bad magic)";
>>> + case instrprof_error::bad_header:
>>> + return "Invalid instrumentation profile data (file header is
>>> corrupt)";
>>> + case instrprof_error::unsupported_version:
>>> + return "Unsupported instrumentation profile format version";
>>> + case instrprof_error::unsupported_hash_type:
>>> + return "Unsupported instrumentation profile hash type";
>>> + case instrprof_error::too_large:
>>> + return "Too much profile data";
>>> + case instrprof_error::truncated:
>>> + return "Truncated profile data";
>>> + case instrprof_error::malformed:
>>> + return "Malformed instrumentation profile data";
>>> + case instrprof_error::unknown_function:
>>> + return "No profile data available for function";
>>> + case instrprof_error::hash_mismatch:
>>> + return "Function control flow change detected (hash mismatch)";
>>> + case instrprof_error::count_mismatch:
>>> + return "Function basic block count change detected (counter
>>> mismatch)";
>>> + case instrprof_error::counter_overflow:
>>> + return "Counter overflow";
>>> + case instrprof_error::value_site_count_mismatch:
>>> + return "Function value site count change detected (counter
>>> mismatch)";
>>> + case instrprof_error::compress_failed:
>>> + return "Failed to compress data (zlib)";
>>> + case instrprof_error::uncompress_failed:
>>> + return "Failed to uncompress data (zlib)";
>>> + }
>>> + llvm_unreachable("A value of instrprof_error has no message.");
>>> +}
>>> +
>>> class InstrProfErrorCategoryType : public std::error_category {
>>> const char *name() const LLVM_NOEXCEPT override { return
>>> "llvm.instrprof"; }
>>> std::string message(int IE) const override {
>>> - instrprof_error E = static_cast<instrprof_error>(IE);
>>> - switch (E) {
>>> - case instrprof_error::success:
>>> - return "Success";
>>> - case instrprof_error::eof:
>>> - return "End of File";
>>> - case instrprof_error::unrecognized_format:
>>> - return "Unrecognized instrumentation profile encoding format";
>>> - case instrprof_error::bad_magic:
>>> - return "Invalid instrumentation profile data (bad magic)";
>>> - case instrprof_error::bad_header:
>>> - return "Invalid instrumentation profile data (file header is
>>> corrupt)";
>>> - case instrprof_error::unsupported_version:
>>> - return "Unsupported instrumentation profile format version";
>>> - case instrprof_error::unsupported_hash_type:
>>> - return "Unsupported instrumentation profile hash type";
>>> - case instrprof_error::too_large:
>>> - return "Too much profile data";
>>> - case instrprof_error::truncated:
>>> - return "Truncated profile data";
>>> - case instrprof_error::malformed:
>>> - return "Malformed instrumentation profile data";
>>> - case instrprof_error::unknown_function:
>>> - return "No profile data available for function";
>>> - case instrprof_error::hash_mismatch:
>>> - return "Function control flow change detected (hash mismatch)";
>>> - case instrprof_error::count_mismatch:
>>> - return "Function basic block count change detected (counter
>>> mismatch)";
>>> - case instrprof_error::counter_overflow:
>>> - return "Counter overflow";
>>> - case instrprof_error::value_site_count_mismatch:
>>> - return "Function value site count change detected (counter
>>> mismatch)";
>>> - case instrprof_error::compress_failed:
>>> - return "Failed to compress data (zlib)";
>>> - case instrprof_error::uncompress_failed:
>>> - return "Failed to uncompress data (zlib)";
>>> - }
>>> - llvm_unreachable("A value of instrprof_error has no message.");
>>> + return getInstrProfErrString(static_cast<instrprof_error>(IE));
>>> }
>>> };
>>> } // end anonymous namespace
>>> @@ -105,6 +108,12 @@ void SoftInstrProfErrors::addError(instr
>>> }
>>> }
>>>
>>> +std::string InstrProfError::message() const {
>>> + return getInstrProfErrString(Err);
>>> +}
>>> +
>>> +template <> char ProfErrorInfoBase<instrprof_error>::ID = 0;
>>> +
>>> std::string getPGOFuncName(StringRef RawFuncName,
>>> GlobalValue::LinkageTypes Linkage,
>>> StringRef FileName,
>>> @@ -214,9 +223,8 @@ void InstrProfSymtab::create(Module &M,
>>> finalizeSymtab();
>>> }
>>>
>>> -std::error_code
>>> -collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
>>> - bool doCompression, std::string &Result) {
>>> +Error collectPGOFuncNameStrings(const std::vector<std::string>
>>> &NameStrs,
>>> + bool doCompression, std::string
>>> &Result) {
>>> assert(NameStrs.size() && "No name data to emit");
>>>
>>> uint8_t Header[16], *P = Header;
>>> @@ -238,11 +246,12 @@ collectPGOFuncNameStrings(const std::vec
>>> unsigned HeaderLen = P - &Header[0];
>>> Result.append(HeaderStr, HeaderLen);
>>> Result += InputStr;
>>> - return make_error_code(instrprof_error::success);
>>> + return Error::success();
>>> };
>>>
>>> - if (!doCompression)
>>> + if (!doCompression) {
>>> return WriteStringToResult(0, UncompressedNameStrings);
>>> + }
>>>
>>> SmallVector<char, 128> CompressedNameStrings;
>>> zlib::Status Success =
>>> @@ -250,7 +259,7 @@ collectPGOFuncNameStrings(const std::vec
>>> zlib::BestSizeCompression);
>>>
>>> if (Success != zlib::StatusOK)
>>> - return make_error_code(instrprof_error::compress_failed);
>>> + return make_error<InstrProfError>(instrprof_error::compress_failed);
>>>
>>> return WriteStringToResult(
>>> CompressedNameStrings.size(),
>>> @@ -264,9 +273,8 @@ StringRef getPGOFuncNameVarInitializer(G
>>> return NameStr;
>>> }
>>>
>>> -std::error_code
>>> -collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,
>>> - std::string &Result, bool doCompression) {
>>> +Error collectPGOFuncNameStrings(const std::vector<GlobalVariable *>
>>> &NameVars,
>>> + std::string &Result, bool
>>> doCompression) {
>>> std::vector<std::string> NameStrs;
>>> for (auto *NameVar : NameVars) {
>>> NameStrs.push_back(getPGOFuncNameVarInitializer(NameVar));
>>> @@ -275,8 +283,7 @@ collectPGOFuncNameStrings(const std::vec
>>> NameStrs, zlib::isAvailable() && doCompression, Result);
>>> }
>>>
>>> -std::error_code readPGOFuncNameStrings(StringRef NameStrings,
>>> - InstrProfSymtab &Symtab) {
>>> +Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab
>>> &Symtab) {
>>> const uint8_t *P = reinterpret_cast<const uint8_t
>>> *>(NameStrings.data());
>>> const uint8_t *EndP = reinterpret_cast<const uint8_t
>>> *>(NameStrings.data() +
>>>
>>> NameStrings.size());
>>> @@ -294,7 +301,7 @@ std::error_code readPGOFuncNameStrings(S
>>> CompressedSize);
>>> if (zlib::uncompress(CompressedNameStrings,
>>> UncompressedNameStrings,
>>> UncompressedSize) != zlib::StatusOK)
>>> - return make_error_code(instrprof_error::uncompress_failed);
>>> + return
>>> make_error<InstrProfError>(instrprof_error::uncompress_failed);
>>> P += CompressedSize;
>>> NameStrings = StringRef(UncompressedNameStrings.data(),
>>> UncompressedNameStrings.size());
>>> @@ -313,7 +320,7 @@ std::error_code readPGOFuncNameStrings(S
>>> P++;
>>> }
>>> Symtab.finalizeSymtab();
>>> - return make_error_code(instrprof_error::success);
>>> + return Error::success();
>>> }
>>>
>>> void InstrProfValueSiteRecord::merge(SoftInstrProfErrors &SIPE,
>>> @@ -577,45 +584,45 @@ static std::unique_ptr<ValueProfData> al
>>> ValueProfData());
>>> }
>>>
>>> -instrprof_error ValueProfData::checkIntegrity() {
>>> +Error ValueProfData::checkIntegrity() {
>>> if (NumValueKinds > IPVK_Last + 1)
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>> // Total size needs to be mulltiple of quadword size.
>>> if (TotalSize % sizeof(uint64_t))
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>>
>>> ValueProfRecord *VR = getFirstValueProfRecord(this);
>>> for (uint32_t K = 0; K < this->NumValueKinds; K++) {
>>> if (VR->Kind > IPVK_Last)
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>> VR = getValueProfRecordNext(VR);
>>> if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize)
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>> }
>>> - return instrprof_error::success;
>>> + return Error::success();
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<ValueProfData>>
>>> +Expected<std::unique_ptr<ValueProfData>>
>>> ValueProfData::getValueProfData(const unsigned char *D,
>>> const unsigned char *const BufferEnd,
>>> support::endianness Endianness) {
>>> using namespace support;
>>> if (D + sizeof(ValueProfData) > BufferEnd)
>>> - return instrprof_error::truncated;
>>> + return make_error<InstrProfError>(instrprof_error::truncated);
>>>
>>> const unsigned char *Header = D;
>>> uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness);
>>> if (D + TotalSize > BufferEnd)
>>> - return instrprof_error::too_large;
>>> + return make_error<InstrProfError>(instrprof_error::too_large);
>>>
>>> std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize);
>>> memcpy(VPD.get(), D, TotalSize);
>>> // Byte swap.
>>> VPD->swapBytesToHost(Endianness);
>>>
>>> - instrprof_error EC = VPD->checkIntegrity();
>>> - if (EC != instrprof_error::success)
>>> - return EC;
>>> + Error E = VPD->checkIntegrity();
>>> + if (E)
>>> + return std::move(E);
>>>
>>> return std::move(VPD);
>>> }
>>>
>>> Modified: llvm/trunk/lib/ProfileData/InstrProfReader.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=269491&r1=269490&r2=269491&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/ProfileData/InstrProfReader.cpp (original)
>>> +++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp Fri May 13 16:50:56
>>> 2016
>>> @@ -18,33 +18,33 @@
>>>
>>> using namespace llvm;
>>>
>>> -static ErrorOr<std::unique_ptr<MemoryBuffer>>
>>> +static Expected<std::unique_ptr<MemoryBuffer>>
>>> setupMemoryBuffer(std::string Path) {
>>> ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
>>> MemoryBuffer::getFileOrSTDIN(Path);
>>> if (std::error_code EC = BufferOrErr.getError())
>>> - return EC;
>>> + return errorCodeToError(EC);
>>> return std::move(BufferOrErr.get());
>>> }
>>>
>>> -static std::error_code initializeReader(InstrProfReader &Reader) {
>>> +static Error initializeReader(InstrProfReader &Reader) {
>>>
>> return Reader.readHeader();
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<InstrProfReader>>
>>> +Expected<std::unique_ptr<InstrProfReader>>
>>> InstrProfReader::create(std::string Path) {
>>> // Set up the buffer to read.
>>> auto BufferOrError = setupMemoryBuffer(Path);
>>> - if (std::error_code EC = BufferOrError.getError())
>>> - return EC;
>>> + if (Error E = BufferOrError.takeError())
>>> + return std::move(E);
>>> return InstrProfReader::create(std::move(BufferOrError.get()));
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<InstrProfReader>>
>>> +Expected<std::unique_ptr<InstrProfReader>>
>>> InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
>>> // Sanity check the buffer.
>>> if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
>>
>>
>>> - return instrprof_error::too_large;
>>> + return make_error<InstrProfError>(instrprof_error::too_large);
>>>
>>> std::unique_ptr<InstrProfReader> Result;
>>> // Create the reader.
>>> @@ -57,46 +57,49 @@ InstrProfReader::create(std::unique_ptr<
>>> else if (TextInstrProfReader::hasFormat(*Buffer))
>>> Result.reset(new TextInstrProfReader(std::move(Buffer)));
>>> else
>>> - return instrprof_error::unrecognized_format;
>>> + return
>>> make_error<InstrProfError>(instrprof_error::unrecognized_format);
>>>
>>> // Initialize the reader and return the result.
>>> - if (std::error_code EC = initializeReader(*Result))
>>> - return EC;
>>> + if (Error E = initializeReader(*Result))
>>> + return std::move(E);
>>>
>>> return std::move(Result);
>>> }
>>>
>>> -ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
>>> +Expected<std::unique_ptr<IndexedInstrProfReader>>
>>> IndexedInstrProfReader::create(std::string Path) {
>>> // Set up the buffer to read.
>>> auto BufferOrError = setupMemoryBuffer(Path);
>>> - if (std::error_code EC = BufferOrError.getError())
>>> - return EC;
>>> + if (Error E = BufferOrError.takeError())
>>> + return std::move(E);
>>> return IndexedInstrProfReader::create(std::move(BufferOrError.get()));
>>> }
>>>
>>>
>>> -ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
>>> +Expected<std::unique_ptr<IndexedInstrProfReader>>
>>
>>
>>> IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
>>>
>> // Sanity check the buffer.
>>> if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
>>
>>
>>> - return instrprof_error::too_large;
>>> + return make_error<InstrProfError>(instrprof_error::too_large);
>>>
>>> // Create the reader.
>>> if (!IndexedInstrProfReader::hasFormat(*Buffer))
>>> - return instrprof_error::bad_magic;
>>> + return make_error<InstrProfError>(instrprof_error::bad_magic);
>>> auto Result =
>>> llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer));
>>>
>>> // Initialize the reader and return the result.
>>> - if (std::error_code EC = initializeReader(*Result))
>>> - return EC;
>>> + if (Error E = initializeReader(*Result))
>>> + return std::move(E);
>>>
>>> return std::move(Result);
>>> }
>>>
>>> void InstrProfIterator::Increment() {
>>> - if (Reader->readNextRecord(Record))
>>
>>
>>> + if (auto E = Reader->readNextRecord(Record)) {
>>>
>> + // Handle errors in the reader.
>>> + InstrProfError::take(std::move(E));
>>> *this = InstrProfIterator();
>>> + }
>>> }
>>>
>>> bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
>>> @@ -112,7 +115,7 @@ bool TextInstrProfReader::hasFormat(cons
>>> // Read the profile variant flag from the header: ":FE" means this is a
>>> FE
>>> // generated profile. ":IR" means this is an IR level profile. Other
>>> strings
>>> // with a leading ':' will be reported an error format.
>>> -std::error_code TextInstrProfReader::readHeader() {
>>> +Error TextInstrProfReader::readHeader() {
>>> Symtab.reset(new InstrProfSymtab());
>>> bool IsIRInstr = false;
>>> if (!Line->startswith(":")) {
>>> @@ -125,14 +128,14 @@ std::error_code TextInstrProfReader::rea
>>> else if (Str.equals_lower("fe"))
>>> IsIRInstr = false;
>>> else
>>> - return instrprof_error::bad_header;
>>> + return error(instrprof_error::bad_header);
>>>
>>> ++Line;
>>> IsIRLevelProfile = IsIRInstr;
>>> return success();
>>> }
>>>
>>> -std::error_code
>>> +Error
>>> TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
>>>
>>> #define CHECK_LINE_END(Line)
>>> \
>>> @@ -196,7 +199,7 @@ TextInstrProfReader::readValueProfileDat
>>> #undef VP_READ_ADVANCE
>>> }
>>>
>>> -std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord
>>> &Record) {
>>> +Error TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
>>> // Skip empty lines and comments.
>>> while (!Line.is_at_end() && (Line->empty() || Line->startswith("#")))
>>> ++Line;
>>> @@ -238,8 +241,8 @@ std::error_code TextInstrProfReader::rea
>>> }
>>>
>>> // Check if value profile data exists and read it if so.
>>> - if (std::error_code EC = readValueProfileData(Record))
>>> - return EC;
>>> + if (Error E = readValueProfileData(Record))
>>> + return E;
>>>
>>> // This is needed to avoid two pass parsing because llvm-profdata
>>> // does dumping while reading.
>>> @@ -258,7 +261,7 @@ bool RawInstrProfReader<IntPtrT>::hasFor
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code RawInstrProfReader<IntPtrT>::readHeader() {
>>> +Error RawInstrProfReader<IntPtrT>::readHeader() {
>>> if (!hasFormat(*DataBuffer))
>>> return error(instrprof_error::bad_magic);
>>> if (DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header))
>>> @@ -270,26 +273,25 @@ std::error_code RawInstrProfReader<IntPt
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code
>>> -RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
>>> +Error RawInstrProfReader<IntPtrT>::readNextHeader(const char
>>> *CurrentPos) {
>>> const char *End = DataBuffer->getBufferEnd();
>>> // Skip zero padding between profiles.
>>> while (CurrentPos != End && *CurrentPos == 0)
>>> ++CurrentPos;
>>> // If there's nothing left, we're done.
>>> if (CurrentPos == End)
>>> - return instrprof_error::eof;
>>> + return make_error<InstrProfError>(instrprof_error::eof);
>>> // If there isn't enough space for another header, this is probably
>>> just
>>> // garbage at the end of the file.
>>> if (CurrentPos + sizeof(RawInstrProf::Header) > End)
>>
>>
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>>
>> // The writer ensures each profile is padded to start at an aligned
>>> address.
>>> if (reinterpret_cast<size_t>(CurrentPos) % alignOf<uint64_t>())
>>
>>
>>> - return instrprof_error::malformed;
>>> + return make_error<InstrProfError>(instrprof_error::malformed);
>>>
>> // The magic should have the same byte order as in the previous header.
>>> uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
>>> if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
>>> - return instrprof_error::bad_magic;
>>> + return make_error<InstrProfError>(instrprof_error::bad_magic);
>>>
>>> // There's another profile to read, so we need to process the header.
>>> auto *Header = reinterpret_cast<const RawInstrProf::Header
>>> *>(CurrentPos);
>>> @@ -297,11 +299,9 @@ RawInstrProfReader<IntPtrT>::readNextHea
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code
>>> -RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
>>> - std::error_code EC = Symtab.create(StringRef(NamesStart, NamesSize));
>>
>>
>>> - if (EC)
>>> - return EC;
>>>
>> +Error RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab)
>>> {
>>> + if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
>>> + return error(std::move(E));
>>> for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I !=
>>> DataEnd; ++I) {
>>> const IntPtrT FPtr = swap(I->FunctionPointer);
>>> if (!FPtr)
>>> @@ -313,8 +313,8 @@ RawInstrProfReader<IntPtrT>::createSymta
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code
>>> -RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header
>>> &Header) {
>>> +Error RawInstrProfReader<IntPtrT>::readHeader(
>>> + const RawInstrProf::Header &Header) {
>>> Version = swap(Header.Version);
>>> if (GET_VERSION(Version) != RawInstrProf::Version)
>>> return error(instrprof_error::unsupported_version);
>>> @@ -346,28 +346,27 @@ RawInstrProfReader<IntPtrT>::readHeader(
>>> ValueDataStart = reinterpret_cast<const uint8_t *>(Start +
>>> ValueDataOffset);
>>>
>>> std::unique_ptr<InstrProfSymtab> NewSymtab =
>>> make_unique<InstrProfSymtab>();
>>> - if (auto EC = createSymtab(*NewSymtab.get()))
>>> - return EC;
>>> + if (Error E = createSymtab(*NewSymtab.get()))
>>> + return E;
>>>
>>> Symtab = std::move(NewSymtab);
>>> return success();
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code RawInstrProfReader<IntPtrT>::readName(InstrProfRecord
>>> &Record) {
>>> +Error RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) {
>>> Record.Name = getName(Data->NameRef);
>>> return success();
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code RawInstrProfReader<IntPtrT>::readFuncHash(
>>> - InstrProfRecord &Record) {
>>> +Error RawInstrProfReader<IntPtrT>::readFuncHash(InstrProfRecord
>>> &Record) {
>>> Record.Hash = swap(Data->FuncHash);
>>> return success();
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code RawInstrProfReader<IntPtrT>::readRawCounts(
>>> +Error RawInstrProfReader<IntPtrT>::readRawCounts(
>>> InstrProfRecord &Record) {
>>> uint32_t NumCounters = swap(Data->NumCounters);
>>> IntPtrT CounterPtr = Data->CounterPtr;
>>> @@ -394,8 +393,8 @@ std::error_code RawInstrProfReader<IntPt
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code
>>> -RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord
>>> &Record) {
>>> +Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
>>> + InstrProfRecord &Record) {
>>>
>>> Record.clearValueData();
>>> CurValueDataSize = 0;
>>> @@ -407,13 +406,13 @@ RawInstrProfReader<IntPtrT>::readValuePr
>>> if (!NumValueKinds)
>>> return success();
>>>
>>> - ErrorOr<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
>>> + Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
>>> ValueProfData::getValueProfData(
>>> ValueDataStart, (const unsigned char
>>> *)DataBuffer->getBufferEnd(),
>>> getDataEndianness());
>>>
>>> - if (VDataPtrOrErr.getError())
>>> - return VDataPtrOrErr.getError();
>>> + if (Error E = VDataPtrOrErr.takeError())
>>> + return E;
>>>
>>> // Note that besides deserialization, this also performs the
>>> conversion for
>>> // indirect call targets. The function pointers from the raw profile
>>> are
>>> @@ -424,28 +423,27 @@ RawInstrProfReader<IntPtrT>::readValuePr
>>> }
>>>
>>> template <class IntPtrT>
>>> -std::error_code
>>> -RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
>>> +Error RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord
>>> &Record) {
>>> if (atEnd())
>>> // At this point, ValueDataStart field points to the next header.
>>> -
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160514/eb3ed45f/attachment.html>
More information about the llvm-commits
mailing list