summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp')
-rw-r--r--contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp402
1 files changed, 204 insertions, 198 deletions
diff --git a/contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp b/contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp
index 6476d28..ec531c3 100644
--- a/contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp
+++ b/contrib/llvm/lib/ProfileData/CoverageMappingReader.cpp
@@ -14,9 +14,13 @@
#include "llvm/ProfileData/CoverageMappingReader.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace coverage;
@@ -33,13 +37,13 @@ void CoverageMappingIterator::increment() {
std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
if (Data.size() < 1)
- return error(instrprof_error::truncated);
+ return coveragemap_error::truncated;
unsigned N = 0;
Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
- return error(instrprof_error::malformed);
+ return coveragemap_error::malformed;
Data = Data.substr(N);
- return success();
+ return std::error_code();
}
std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
@@ -47,8 +51,8 @@ std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
if (auto Err = readULEB128(Result))
return Err;
if (Result >= MaxPlus1)
- return error(instrprof_error::malformed);
- return success();
+ return coveragemap_error::malformed;
+ return std::error_code();
}
std::error_code RawCoverageReader::readSize(uint64_t &Result) {
@@ -56,8 +60,8 @@ std::error_code RawCoverageReader::readSize(uint64_t &Result) {
return Err;
// Sanity check the number.
if (Result > Data.size())
- return error(instrprof_error::malformed);
- return success();
+ return coveragemap_error::malformed;
+ return std::error_code();
}
std::error_code RawCoverageReader::readString(StringRef &Result) {
@@ -66,7 +70,7 @@ std::error_code RawCoverageReader::readString(StringRef &Result) {
return Err;
Result = Data.substr(0, Length);
Data = Data.substr(Length);
- return success();
+ return std::error_code();
}
std::error_code RawCoverageFilenamesReader::read() {
@@ -79,7 +83,7 @@ std::error_code RawCoverageFilenamesReader::read() {
return Err;
Filenames.push_back(Filename);
}
- return success();
+ return std::error_code();
}
std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
@@ -88,10 +92,10 @@ std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
switch (Tag) {
case Counter::Zero:
C = Counter::getZero();
- return success();
+ return std::error_code();
case Counter::CounterValueReference:
C = Counter::getCounter(Value >> Counter::EncodingTagBits);
- return success();
+ return std::error_code();
default:
break;
}
@@ -101,15 +105,15 @@ std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
case CounterExpression::Add: {
auto ID = Value >> Counter::EncodingTagBits;
if (ID >= Expressions.size())
- return error(instrprof_error::malformed);
+ return coveragemap_error::malformed;
Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
C = Counter::getExpression(ID);
break;
}
default:
- return error(instrprof_error::malformed);
+ return coveragemap_error::malformed;
}
- return success();
+ return std::error_code();
}
std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
@@ -119,7 +123,7 @@ std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
return Err;
if (auto Err = decodeCounter(EncodedCounter, C))
return Err;
- return success();
+ return std::error_code();
}
static const unsigned EncodingExpansionRegionBit = 1
@@ -156,7 +160,7 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
ExpandedFileID = EncodedCounterAndRegion >>
Counter::EncodingCounterTagAndExpansionRegionTagBits;
if (ExpandedFileID >= NumFileIDs)
- return error(instrprof_error::malformed);
+ return coveragemap_error::malformed;
} else {
switch (EncodedCounterAndRegion >>
Counter::EncodingCounterTagAndExpansionRegionTagBits) {
@@ -167,23 +171,20 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
Kind = CounterMappingRegion::SkippedRegion;
break;
default:
- return error(instrprof_error::malformed);
+ return coveragemap_error::malformed;
}
}
}
// Read the source range.
- uint64_t LineStartDelta, CodeBeforeColumnStart, NumLines, ColumnEnd;
+ uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
if (auto Err =
readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
return Err;
- if (auto Err = readULEB128(CodeBeforeColumnStart))
+ if (auto Err = readULEB128(ColumnStart))
return Err;
- bool HasCodeBefore = CodeBeforeColumnStart & 1;
- uint64_t ColumnStart = CodeBeforeColumnStart >>
- CounterMappingRegion::EncodingHasCodeBeforeBits;
if (ColumnStart > std::numeric_limits<unsigned>::max())
- return error(instrprof_error::malformed);
+ return 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()))
@@ -214,14 +215,13 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
});
MappingRegions.push_back(CounterMappingRegion(
- C, InferredFileID, LineStart, ColumnStart, LineStart + NumLines,
- ColumnEnd, HasCodeBefore, Kind));
- MappingRegions.back().ExpandedFileID = ExpandedFileID;
+ C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
+ LineStart + NumLines, ColumnEnd, Kind));
}
- return success();
+ return std::error_code();
}
-std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) {
+std::error_code RawCoverageMappingReader::read() {
// Read the virtual file mapping.
llvm::SmallVector<unsigned, 8> VirtualFileMapping;
@@ -287,42 +287,10 @@ std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) {
}
}
- Record.FunctionName = FunctionName;
- Record.Filenames = Filenames;
- Record.Expressions = Expressions;
- Record.MappingRegions = MappingRegions;
- return success();
-}
-
-ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
- StringRef FileName)
- : CurrentRecord(0) {
- auto File = llvm::object::ObjectFile::createObjectFile(FileName);
- if (!File)
- error(File.getError());
- else
- Object = std::move(File.get());
+ return std::error_code();
}
namespace {
-/// \brief The coverage mapping data for a single function.
-/// It points to the function's name.
-template <typename IntPtrT> struct CoverageMappingFunctionRecord {
- IntPtrT FunctionNamePtr;
- uint32_t FunctionNameSize;
- uint32_t CoverageMappingSize;
- uint64_t FunctionHash;
-};
-
-/// \brief The coverage mapping data for a single translation unit.
-/// It points to the array of function coverage mapping records and the encoded
-/// filenames array.
-template <typename IntPtrT> struct CoverageMappingTURecord {
- uint32_t FunctionRecordsSize;
- uint32_t FilenamesSize;
- uint32_t CoverageMappingsSize;
- uint32_t Version;
-};
/// \brief A helper structure to access the data from a section
/// in an object file.
@@ -334,220 +302,258 @@ struct SectionData {
if (auto Err = Section.getContents(Data))
return Err;
Address = Section.getAddress();
- return instrprof_error::success;
+ return std::error_code();
}
std::error_code get(uint64_t Pointer, size_t Size, StringRef &Result) {
if (Pointer < Address)
- return instrprof_error::malformed;
+ return coveragemap_error::malformed;
auto Offset = Pointer - Address;
if (Offset + Size > Data.size())
- return instrprof_error::malformed;
+ return coveragemap_error::malformed;
Result = Data.substr(Pointer - Address, Size);
- return instrprof_error::success;
+ return std::error_code();
}
};
}
-template <typename T>
+template <typename T, support::endianness Endian>
std::error_code readCoverageMappingData(
SectionData &ProfileNames, StringRef Data,
- std::vector<ObjectFileCoverageMappingReader::ProfileMappingRecord> &Records,
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
std::vector<StringRef> &Filenames) {
+ using namespace support;
llvm::DenseSet<T> UniqueFunctionMappingData;
// Read the records in the coverage data section.
- while (!Data.empty()) {
- if (Data.size() < sizeof(CoverageMappingTURecord<T>))
- return instrprof_error::malformed;
- auto TU = reinterpret_cast<const CoverageMappingTURecord<T> *>(Data.data());
- Data = Data.substr(sizeof(CoverageMappingTURecord<T>));
- switch (TU->Version) {
+ for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
+ if (Buf + 4 * sizeof(uint32_t) > End)
+ return coveragemap_error::malformed;
+ uint32_t NRecords = endian::readNext<uint32_t, Endian, unaligned>(Buf);
+ uint32_t FilenamesSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
+ uint32_t CoverageSize = endian::readNext<uint32_t, Endian, unaligned>(Buf);
+ uint32_t Version = endian::readNext<uint32_t, Endian, unaligned>(Buf);
+
+ switch (Version) {
case CoverageMappingVersion1:
break;
default:
- return instrprof_error::unsupported_version;
+ return coveragemap_error::unsupported_version;
}
- auto Version = CoverageMappingVersion(TU->Version);
- // Get the function records.
- auto FunctionRecords =
- reinterpret_cast<const CoverageMappingFunctionRecord<T> *>(Data.data());
- if (Data.size() <
- sizeof(CoverageMappingFunctionRecord<T>) * TU->FunctionRecordsSize)
- return instrprof_error::malformed;
- Data = Data.substr(sizeof(CoverageMappingFunctionRecord<T>) *
- TU->FunctionRecordsSize);
+ // Skip past the function records, saving the start and end for later.
+ const char *FunBuf = Buf;
+ Buf += NRecords * (sizeof(T) + 2 * sizeof(uint32_t) + sizeof(uint64_t));
+ const char *FunEnd = Buf;
// Get the filenames.
- if (Data.size() < TU->FilenamesSize)
- return instrprof_error::malformed;
- auto RawFilenames = Data.substr(0, TU->FilenamesSize);
- Data = Data.substr(TU->FilenamesSize);
+ if (Buf + FilenamesSize > End)
+ return coveragemap_error::malformed;
size_t FilenamesBegin = Filenames.size();
- RawCoverageFilenamesReader Reader(RawFilenames, Filenames);
+ RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
if (auto Err = Reader.read())
return Err;
-
- // Get the coverage mappings.
- if (Data.size() < TU->CoverageMappingsSize)
- return instrprof_error::malformed;
- auto CoverageMappings = Data.substr(0, TU->CoverageMappingsSize);
- Data = Data.substr(TU->CoverageMappingsSize);
-
- for (unsigned I = 0; I < TU->FunctionRecordsSize; ++I) {
- auto &MappingRecord = FunctionRecords[I];
-
- // Get the coverage mapping.
- if (CoverageMappings.size() < MappingRecord.CoverageMappingSize)
- return instrprof_error::malformed;
- auto Mapping =
- CoverageMappings.substr(0, MappingRecord.CoverageMappingSize);
- CoverageMappings =
- CoverageMappings.substr(MappingRecord.CoverageMappingSize);
+ Buf += FilenamesSize;
+
+ // We'll read the coverage mapping records in the loop below.
+ const char *CovBuf = Buf;
+ Buf += CoverageSize;
+ const char *CovEnd = Buf;
+
+ if (Buf > End)
+ return 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);
+
+ while (FunBuf < FunEnd) {
+ // Read the function information
+ T NamePtr = endian::readNext<T, Endian, unaligned>(FunBuf);
+ uint32_t NameSize = endian::readNext<uint32_t, Endian, unaligned>(FunBuf);
+ uint32_t DataSize = endian::readNext<uint32_t, Endian, unaligned>(FunBuf);
+ uint64_t FuncHash = endian::readNext<uint64_t, Endian, unaligned>(FunBuf);
+
+ // Now use that to read the coverage data.
+ if (CovBuf + DataSize > CovEnd)
+ return coveragemap_error::malformed;
+ auto Mapping = StringRef(CovBuf, DataSize);
+ CovBuf += DataSize;
// Ignore this record if we already have a record that points to the same
- // function name.
- // This is useful to ignore the redundant records for the functions
- // with ODR linkage.
- if (!UniqueFunctionMappingData.insert(MappingRecord.FunctionNamePtr)
- .second)
+ // function name. This is useful to ignore the redundant records for the
+ // functions with ODR linkage.
+ if (!UniqueFunctionMappingData.insert(NamePtr).second)
continue;
- StringRef FunctionName;
- if (auto Err =
- ProfileNames.get(MappingRecord.FunctionNamePtr,
- MappingRecord.FunctionNameSize, FunctionName))
- return Err;
- Records.push_back(ObjectFileCoverageMappingReader::ProfileMappingRecord(
- Version, FunctionName, MappingRecord.FunctionHash, Mapping,
+
+ // Finally, grab the name and create a record.
+ StringRef FuncName;
+ if (std::error_code EC = ProfileNames.get(NamePtr, NameSize, FuncName))
+ return EC;
+ Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
+ CoverageMappingVersion(Version), FuncName, FuncHash, Mapping,
FilenamesBegin, Filenames.size() - FilenamesBegin));
}
}
- return instrprof_error::success;
+ return std::error_code();
}
static const char *TestingFormatMagic = "llvmcovmtestdata";
-static std::error_code decodeTestingFormat(StringRef Data,
- SectionData &ProfileNames,
- StringRef &CoverageMapping) {
+static std::error_code loadTestingFormat(StringRef Data,
+ SectionData &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 instrprof_error::truncated;
+ return coveragemap_error::truncated;
unsigned N = 0;
auto ProfileNamesSize =
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
- return instrprof_error::malformed;
+ return coveragemap_error::malformed;
Data = Data.substr(N);
if (Data.size() < 1)
- return instrprof_error::truncated;
+ return coveragemap_error::truncated;
N = 0;
ProfileNames.Address =
decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
if (N > Data.size())
- return instrprof_error::malformed;
+ return coveragemap_error::malformed;
Data = Data.substr(N);
if (Data.size() < ProfileNamesSize)
- return instrprof_error::malformed;
+ return coveragemap_error::malformed;
ProfileNames.Data = Data.substr(0, ProfileNamesSize);
CoverageMapping = Data.substr(ProfileNamesSize);
- return instrprof_error::success;
+ return std::error_code();
}
-ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
- std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type)
- : CurrentRecord(0) {
- if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) {
- // This is a special format used for testing.
- SectionData ProfileNames;
- StringRef CoverageMapping;
- if (auto Err = decodeTestingFormat(ObjectBuffer->getBuffer(), ProfileNames,
- CoverageMapping)) {
- error(Err);
- return;
- }
- error(readCoverageMappingData<uint64_t>(ProfileNames, CoverageMapping,
- MappingRecords, Filenames));
- Object = OwningBinary<ObjectFile>(std::unique_ptr<ObjectFile>(),
- std::move(ObjectBuffer));
- return;
+static ErrorOr<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
+ StringRef FoundName;
+ for (const auto &Section : OF.sections()) {
+ if (auto EC = Section.getName(FoundName))
+ return EC;
+ if (FoundName == Name)
+ return Section;
}
-
- auto File = object::ObjectFile::createObjectFile(
- ObjectBuffer->getMemBufferRef(), Type);
- if (!File)
- error(File.getError());
- else
- Object = OwningBinary<ObjectFile>(std::move(File.get()),
- std::move(ObjectBuffer));
+ return coveragemap_error::no_data_found;
}
-std::error_code ObjectFileCoverageMappingReader::readHeader() {
- const ObjectFile *OF = Object.getBinary();
- if (!OF)
- return getError();
- auto BytesInAddress = OF->getBytesInAddress();
- if (BytesInAddress != 4 && BytesInAddress != 8)
- return error(instrprof_error::malformed);
+static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
+ SectionData &ProfileNames,
+ StringRef &CoverageMapping,
+ uint8_t &BytesInAddress,
+ support::endianness &Endian,
+ Triple::ArchType Arch) {
+ auto BinOrErr = object::createBinary(ObjectBuffer);
+ if (std::error_code EC = BinOrErr.getError())
+ return EC;
+ 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;
+ 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 != Triple::ArchType::UnknownArch && OF->getArch() != Arch)
+ return object_error::arch_not_found;
+ } else
+ // We can only handle object files.
+ return coveragemap_error::malformed;
+
+ // The coverage uses native pointer sizes for the object it's written in.
+ BytesInAddress = OF->getBytesInAddress();
+ Endian = OF->isLittleEndian() ? support::endianness::little
+ : support::endianness::big;
// Look for the sections that we are interested in.
- int FoundSectionCount = 0;
- SectionRef ProfileNames, CoverageMapping;
- for (const auto &Section : OF->sections()) {
- StringRef Name;
- if (auto Err = Section.getName(Name))
- return Err;
- if (Name == "__llvm_prf_names") {
- ProfileNames = Section;
- } else if (Name == "__llvm_covmap") {
- CoverageMapping = Section;
- } else
- continue;
- ++FoundSectionCount;
- }
- if (FoundSectionCount != 2)
- return error(instrprof_error::bad_header);
+ auto NamesSection = lookupSection(*OF, "__llvm_prf_names");
+ if (auto EC = NamesSection.getError())
+ return EC;
+ auto CoverageSection = lookupSection(*OF, "__llvm_covmap");
+ if (auto EC = CoverageSection.getError())
+ return EC;
// Get the contents of the given sections.
- StringRef Data;
- if (auto Err = CoverageMapping.getContents(Data))
- return Err;
- SectionData ProfileNamesData;
- if (auto Err = ProfileNamesData.load(ProfileNames))
- return Err;
+ if (std::error_code EC = CoverageSection->getContents(CoverageMapping))
+ return EC;
+ if (std::error_code EC = ProfileNames.load(*NamesSection))
+ return EC;
- // Load the data from the found sections.
- std::error_code Err;
- if (BytesInAddress == 4)
- Err = readCoverageMappingData<uint32_t>(ProfileNamesData, Data,
- MappingRecords, Filenames);
- else
- Err = readCoverageMappingData<uint64_t>(ProfileNamesData, Data,
- MappingRecords, Filenames);
- if (Err)
- return error(Err);
+ return std::error_code();
+}
- return success();
+ErrorOr<std::unique_ptr<BinaryCoverageReader>>
+BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+ Triple::ArchType Arch) {
+ std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
+
+ SectionData Profile;
+ StringRef Coverage;
+ uint8_t BytesInAddress;
+ support::endianness Endian;
+ std::error_code EC;
+ if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
+ // This is a special format used for testing.
+ EC = loadTestingFormat(ObjectBuffer->getBuffer(), Profile, Coverage,
+ BytesInAddress, Endian);
+ else
+ EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage,
+ BytesInAddress, Endian, Arch);
+ if (EC)
+ return EC;
+
+ if (BytesInAddress == 4 && Endian == support::endianness::little)
+ EC = readCoverageMappingData<uint32_t, support::endianness::little>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else if (BytesInAddress == 4 && Endian == support::endianness::big)
+ EC = readCoverageMappingData<uint32_t, support::endianness::big>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else if (BytesInAddress == 8 && Endian == support::endianness::little)
+ EC = readCoverageMappingData<uint64_t, support::endianness::little>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else if (BytesInAddress == 8 && Endian == support::endianness::big)
+ EC = readCoverageMappingData<uint64_t, support::endianness::big>(
+ Profile, Coverage, Reader->MappingRecords, Reader->Filenames);
+ else
+ return coveragemap_error::malformed;
+ if (EC)
+ return EC;
+ return std::move(Reader);
}
std::error_code
-ObjectFileCoverageMappingReader::readNextRecord(CoverageMappingRecord &Record) {
+BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
if (CurrentRecord >= MappingRecords.size())
- return error(instrprof_error::eof);
+ return coveragemap_error::eof;
FunctionsFilenames.clear();
Expressions.clear();
MappingRegions.clear();
auto &R = MappingRecords[CurrentRecord];
RawCoverageMappingReader Reader(
- R.FunctionName, R.CoverageMapping,
- makeArrayRef(Filenames.data() + R.FilenamesBegin, R.FilenamesSize),
+ R.CoverageMapping,
+ makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
FunctionsFilenames, Expressions, MappingRegions);
- if (auto Err = Reader.read(Record))
+ if (auto Err = Reader.read())
return Err;
+
+ Record.FunctionName = R.FunctionName;
Record.FunctionHash = R.FunctionHash;
+ Record.Filenames = FunctionsFilenames;
+ Record.Expressions = Expressions;
+ Record.MappingRegions = MappingRegions;
+
++CurrentRecord;
- return success();
+ return std::error_code();
}
OpenPOWER on IntegriCloud