https://github.com/RenjiSann updated https://github.com/llvm/llvm-project/pull/156307
From 78c849f1c1f98db4c16c04e3258db5411e979cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= <pe...@adacore.com> Date: Tue, 19 Aug 2025 14:12:15 +0000 Subject: [PATCH 1/4] [Coverage] Add CovInstrLevel enum and add it to the CovMapHeader struct --- compiler-rt/include/profile/InstrProfData.inc | 4 +- .../ProfileData/Coverage/CoverageMapping.h | 50 +++++++++++++++++++ .../llvm/ProfileData/InstrProfData.inc | 4 +- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc index 0496f240dc823..a2af7cfa8cbe1 100644 --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -300,6 +300,8 @@ COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) COVMAP_HEADER(uint32_t, Int32Ty, Version, \ llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion)) +COVMAP_HEADER(uint32_t, Int32Ty, CovInstrLevels, \ + llvm::ConstantInt::get(Int32Ty, CovInstrLevels)) #undef COVMAP_HEADER /* COVMAP_HEADER end. */ @@ -724,7 +726,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, /* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 12 /* Coverage mapping format version (start from 0). */ -#define INSTR_PROF_COVMAP_VERSION 6 +#define INSTR_PROF_COVMAP_VERSION 7 /* Profile version is always of type uint64_t. Reserve the upper 32 bits in the * version for other variants of profile. We set the 8th most significant bit diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 7d1a85ba528fc..e6c45cbe562c2 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -984,6 +984,46 @@ class CoverageData { ArrayRef<MCDCRecord> getMCDCRecords() const { return MCDCRecords; } }; +/// Represents a set of available capabilities +class CoverageCapabilities { + uint32_t Capabilities; + +public: + enum CovInstrLevel { + Statement = (1 << 0), + Branch = (1 << 1), + MCDC = (1 << 2), + }; + + CoverageCapabilities(uint32_t Capabilities) : Capabilities(Capabilities){}; + + static CoverageCapabilities all() { + return CoverageCapabilities(Statement | Branch | MCDC); + } + + static CoverageCapabilities none() { + return CoverageCapabilities(0); + } + + bool hasCapability(CovInstrLevel Lvl) const { + return (this->Capabilities & Lvl) != 0; + } + + /// Returns true if this includes all the capabilities of Other. + bool includes(const CoverageCapabilities &Other) const { + return (this->Capabilities & Other.Capabilities) == Other.Capabilities; + } + + CoverageCapabilities& operator |= (const CoverageCapabilities &Rhs) { + this->Capabilities |= Rhs.Capabilities; + return *this; + } + + CoverageCapabilities operator | (const CoverageCapabilities &Rhs) const { + return CoverageCapabilities(this->Capabilities | Rhs.Capabilities); + } +}; + /// The mapping of profile information to coverage data. /// /// This is the main interface to get coverage information, using a profile to @@ -994,6 +1034,10 @@ class CoverageMapping { DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices; std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches; + /// Keep track of the coverage capabilities of the loaded object file, + /// which depends on the parameters used to compile it. + CovInstrLevel AvailableInstrLevels = CovInstrLevel::All; + std::optional<bool> SingleByteCoverage; CoverageMapping() = default; @@ -1430,6 +1474,10 @@ struct CovMapHeader { template <llvm::endianness Endian> uint32_t getVersion() const { return support::endian::byte_swap<uint32_t, Endian>(Version); } + + template <llvm::endianness Endian> uint32_t getCovInstrLevels() const { + return support::endian::byte_swap<uint32_t, Endian>(CovInstrLevels); + } }; LLVM_PACKED_END @@ -1452,6 +1500,8 @@ enum CovMapVersion { Version6 = 5, // Branch regions extended and Decision Regions added for MC/DC. Version7 = 6, + // Covmap header tracks the instrumentation level + Version8 = 7, // The current version is Version7. CurrentVersion = INSTR_PROF_COVMAP_VERSION }; diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc index 0496f240dc823..a2af7cfa8cbe1 100644 --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -300,6 +300,8 @@ COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) COVMAP_HEADER(uint32_t, Int32Ty, Version, \ llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion)) +COVMAP_HEADER(uint32_t, Int32Ty, CovInstrLevels, \ + llvm::ConstantInt::get(Int32Ty, CovInstrLevels)) #undef COVMAP_HEADER /* COVMAP_HEADER end. */ @@ -724,7 +726,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, /* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 12 /* Coverage mapping format version (start from 0). */ -#define INSTR_PROF_COVMAP_VERSION 6 +#define INSTR_PROF_COVMAP_VERSION 7 /* Profile version is always of type uint64_t. Reserve the upper 32 bits in the * version for other variants of profile. We set the 8th most significant bit From 4d92c29d357a6ef97c10f0879aa6dc96e94b1052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= <pe...@adacore.com> Date: Tue, 19 Aug 2025 14:21:46 +0000 Subject: [PATCH 2/4] [Coverage] Extract Coverage capabilities from coverage mapping header --- .../ProfileData/Coverage/CoverageMapping.h | 9 ++++-- .../Coverage/CoverageMappingReader.h | 13 +++++++- .../ProfileData/Coverage/CoverageMapping.cpp | 19 ++++++++--- .../Coverage/CoverageMappingReader.cpp | 32 +++++++++++++++---- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index e6c45cbe562c2..785d798bb45cf 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -1036,7 +1036,7 @@ class CoverageMapping { /// Keep track of the coverage capabilities of the loaded object file, /// which depends on the parameters used to compile it. - CovInstrLevel AvailableInstrLevels = CovInstrLevel::All; + CoverageCapabilities AvailableInstrLevels = CoverageCapabilities::none(); std::optional<bool> SingleByteCoverage; @@ -1055,6 +1055,7 @@ class CoverageMapping { std::optional<std::reference_wrapper<IndexedInstrProfReader>> &ProfileReader, CoverageMapping &Coverage, bool &DataFound, + CoverageCapabilities RequestedCapabilities, SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr); /// Add a function record corresponding to \p Record. @@ -1078,7 +1079,8 @@ class CoverageMapping { LLVM_ABI static Expected<std::unique_ptr<CoverageMapping>> load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders, std::optional<std::reference_wrapper<IndexedInstrProfReader>> - &ProfileReader); + &ProfileReader, + CoverageCapabilities RequestCapabilities = CoverageCapabilities::none()); /// Load the coverage mapping from the given object files and profile. If /// \p Arches is non-empty, it must specify an architecture for each object. @@ -1088,7 +1090,8 @@ class CoverageMapping { std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS, ArrayRef<StringRef> Arches = {}, StringRef CompilationDir = "", const object::BuildIDFetcher *BIDFetcher = nullptr, - bool CheckBinaryIDs = false); + bool CheckBinaryIDs = false, + CoverageCapabilities RequestCapabilities = CoverageCapabilities::none()); /// The number of functions that couldn't have their profiles mapped. /// diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index e91ba9147a745..b6e68bf13c10d 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -104,6 +104,10 @@ class CoverageMappingReader { virtual Error readNextRecord(CoverageMappingRecord &Record) = 0; CoverageMappingIterator begin() { return CoverageMappingIterator(this); } CoverageMappingIterator end() { return CoverageMappingIterator(); } + + /// Returns the instrumentation levels for which the code was originally + /// instrumented. + virtual CoverageCapabilities coverageCapabilities() const = 0; }; /// Base class for the raw coverage mapping and filenames data readers. @@ -188,6 +192,7 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader { std::vector<ProfileMappingRecord> MappingRecords; std::unique_ptr<InstrProfSymtab> ProfileNames; size_t CurrentRecord = 0; + CoverageCapabilities AvailableCapabilities; std::vector<StringRef> FunctionsFilenames; std::vector<CounterExpression> Expressions; std::vector<CounterMappingRegion> MappingRegions; @@ -205,7 +210,9 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader { BinaryCoverageReader(std::unique_ptr<InstrProfSymtab> Symtab, FuncRecordsStorage &&FuncRecords, CoverageMapCopyStorage &&CoverageMapCopy) - : ProfileNames(std::move(Symtab)), FuncRecords(std::move(FuncRecords)), + : ProfileNames(std::move(Symtab)), + AvailableCapabilities(CoverageCapabilities::all()), + FuncRecords(std::move(FuncRecords)), CoverageMapCopy(std::move(CoverageMapCopy)) {} public: @@ -226,6 +233,10 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader { llvm::endianness Endian, StringRef CompilationDir = ""); Error readNextRecord(CoverageMappingRecord &Record) override; + + CoverageCapabilities coverageCapabilities() const override { + return this->AvailableCapabilities; + }; }; /// Reader for the raw coverage filenames. diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 429ec5c19f1f8..892bba1c2fb04 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -978,6 +978,7 @@ Error CoverageMapping::loadFromReaders( Coverage.SingleByteCoverage = !ProfileReader || ProfileReader.value().get().hasSingleByteCoverage(); for (const auto &CoverageReader : CoverageReaders) { + Coverage.AvailableInstrLevels |= CoverageReader->coverageCapabilities(); for (auto RecordOrErr : *CoverageReader) { if (Error E = RecordOrErr.takeError()) return E; @@ -992,7 +993,7 @@ Error CoverageMapping::loadFromReaders( Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders, std::optional<std::reference_wrapper<IndexedInstrProfReader>> - &ProfileReader) { + &ProfileReader, CoverageCapabilities RequestedCapabilities) { auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping()); if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage)) return std::move(E); @@ -1013,6 +1014,7 @@ Error CoverageMapping::loadFromFile( std::optional<std::reference_wrapper<IndexedInstrProfReader>> &ProfileReader, CoverageMapping &Coverage, bool &DataFound, + CoverageCapabilities RequestedCapabilities, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) { auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN( Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false); @@ -1045,6 +1047,12 @@ Error CoverageMapping::loadFromFile( DataFound |= !Readers.empty(); if (Error E = loadFromReaders(Readers, ProfileReader, Coverage)) return createFileError(Filename, std::move(E)); + + // Check that all the requested coverage capabilities are available. + if (!Coverage.AvailableInstrLevels.includes(RequestedCapabilities)) + return createFileError( + Filename, createStringError("is missing instrumentation levels")); + return Error::success(); } @@ -1052,7 +1060,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( ArrayRef<StringRef> ObjectFilenames, std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir, - const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) { + const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs, + CoverageCapabilities RequestedCapabilities) { std::unique_ptr<IndexedInstrProfReader> ProfileReader; if (ProfileFilename) { auto ProfileReaderOrErr = @@ -1081,7 +1090,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( for (const auto &File : llvm::enumerate(ObjectFilenames)) { if (Error E = loadFromFile(File.value(), GetArch(File.index()), CompilationDir, ProfileReaderRef, *Coverage, - DataFound, &FoundBinaryIDs)) + DataFound, RequestedCapabilities, + &FoundBinaryIDs)) return std::move(E); } @@ -1110,7 +1120,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load( std::string Path = std::move(*PathOpt); StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef(); if (Error E = loadFromFile(Path, Arch, CompilationDir, ProfileReaderRef, - *Coverage, DataFound)) + *Coverage, DataFound, + RequestedCapabilities)) return std::move(E); } else if (CheckBinaryIDs) { return createFileError( diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index fc2577e6ada5d..982eeec4997f0 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -25,6 +25,7 @@ #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/Wasm.h" +#include "llvm/ProfileData/Coverage/CoverageMapping.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" @@ -679,7 +680,16 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader { uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>(); uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>(); assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version); - CovBuf = reinterpret_cast<const char *>(CovHeader + 1); + + // Assume that older coverage files have data for each level. + if (Version >= CovMapVersion::Version8) { + CovBuf = reinterpret_cast<const char *>(CovHeader + 1); + } else { + // In versions before Version8, the Covmap header only has 4 uint32_t + // fields. + CovBuf = reinterpret_cast<const char *>( + reinterpret_cast<const uint32_t *>(CovHeader) + 4); + } // Skip past the function records, saving the start and end for later. // This is a no-op in Version4 (function records are read after all headers @@ -830,6 +840,7 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( case CovMapVersion::Version5: case CovMapVersion::Version6: case CovMapVersion::Version7: + case CovMapVersion::Version8: // Decompress the name data. if (Error E = P.create(P.getNameData())) return std::move(E); @@ -851,6 +862,9 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( else if (Version == CovMapVersion::Version7) return std::make_unique<VersionedCovMapFuncRecordReader< CovMapVersion::Version7, IntPtrT, Endian>>(P, R, D, F); + else if (Version == CovMapVersion::Version8) + return std::make_unique<VersionedCovMapFuncRecordReader< + CovMapVersion::Version8, IntPtrT, Endian>>(P, R, D, F); } llvm_unreachable("Unsupported version"); } @@ -859,7 +873,8 @@ template <typename T, llvm::endianness Endian> static Error readCoverageMappingData( InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, - StringRef CompilationDir, std::vector<std::string> &Filenames) { + StringRef CompilationDir, std::vector<std::string> &Filenames, + CoverageCapabilities &AvailableCapabilities) { using namespace coverage; // Read the records in the coverage data section. @@ -871,6 +886,11 @@ static Error readCoverageMappingData( Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected = CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records, CompilationDir, Filenames); + if (Version < CovMapVersion::Version8) + AvailableCapabilities = CoverageCapabilities::all(); + else + AvailableCapabilities = CoverageCapabilities(CovHeader->getCovInstrLevels<Endian>()); + if (Error E = ReaderExpected.takeError()) return E; auto Reader = std::move(ReaderExpected.get()); @@ -915,22 +935,22 @@ BinaryCoverageReader::createCoverageReaderFromBuffer( if (BytesInAddress == 4 && Endian == llvm::endianness::little) { if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>( ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, - CompilationDir, Reader->Filenames)) + CompilationDir, Reader->Filenames, Reader->AvailableCapabilities)) return std::move(E); } else if (BytesInAddress == 4 && Endian == llvm::endianness::big) { if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>( ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, - CompilationDir, Reader->Filenames)) + CompilationDir, Reader->Filenames, Reader->AvailableCapabilities)) return std::move(E); } else if (BytesInAddress == 8 && Endian == llvm::endianness::little) { if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>( ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, - CompilationDir, Reader->Filenames)) + CompilationDir, Reader->Filenames, Reader->AvailableCapabilities)) return std::move(E); } else if (BytesInAddress == 8 && Endian == llvm::endianness::big) { if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>( ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, - CompilationDir, Reader->Filenames)) + CompilationDir, Reader->Filenames, Reader->AvailableCapabilities)) return std::move(E); } else return make_error<CoverageMapError>( From cd3be5364520328abaead8b5cdcfcb241d49519c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= <pe...@adacore.com> Date: Tue, 19 Aug 2025 14:15:13 +0000 Subject: [PATCH 3/4] [clang][Coverage] Populate the CovInstrLevel field at compilation --- clang/lib/CodeGen/CoverageMappingGen.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 05fb137ca0575..441d537e1f33f 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -2604,6 +2604,15 @@ void CoverageMappingModuleGen::emit() { }; auto CovDataHeaderTy = llvm::StructType::get(Ctx, ArrayRef(CovDataHeaderTypes)); + + // By default, clang instruments the code for "statement" and "branch" + // coverage, and can instrument for MCDC when `-fcoverage-mcdc` is passed. + uint32_t CovInstrLevels = CoverageCapabilities::CovInstrLevel::Statement | + CoverageCapabilities::CovInstrLevel::Branch; + if (CGM.getCodeGenOpts().hasProfileClangInstr() && + CGM.getCodeGenOpts().MCDCCoverage) + CovInstrLevels |= CoverageCapabilities::CovInstrLevel::MCDC; + llvm::Constant *CovDataHeaderVals[] = { #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init, #include "llvm/ProfileData/InstrProfData.inc" From 3ea7c7b6ea6d4c2bb3aaf6c4d10d210ddfe18897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= <pe...@adacore.com> Date: Thu, 28 Aug 2025 18:56:55 +0000 Subject: [PATCH 4/4] [llvm-cov] Set the requested coverage capabilities depending on given options --- llvm/tools/llvm-cov/CodeCoverage.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 6c66858c4de8c..5799fd77ed668 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -462,9 +462,18 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { ObjectFilename); } auto FS = vfs::getRealFileSystem(); - auto CoverageOrErr = CoverageMapping::load( - ObjectFilenames, PGOFilename, *FS, CoverageArches, - ViewOpts.CompilationDirectory, BIDFetcher.get(), CheckBinaryIDs); + + CoverageCapabilities RequestCapabilities = + CoverageCapabilities(CoverageCapabilities::CovInstrLevel::Statement); + if (ViewOpts.ShowBranches != CoverageViewOptions::BranchOutputType::Off) + RequestCapabilities |= CoverageCapabilities::CovInstrLevel::Branch; + if (ViewOpts.ShowMCDC || ViewOpts.ShowMCDCSummary) + RequestCapabilities |= CoverageCapabilities::CovInstrLevel::MCDC; + + auto CoverageOrErr = + CoverageMapping::load(ObjectFilenames, PGOFilename, *FS, CoverageArches, + ViewOpts.CompilationDirectory, BIDFetcher.get(), + CheckBinaryIDs, RequestCapabilities); if (Error E = CoverageOrErr.takeError()) { error("failed to load coverage: " + toString(std::move(E))); return nullptr; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits