//===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Code coverage mapping data is generated by clang and read by // llvm-cov to show code coverage statistics for a file. // //===----------------------------------------------------------------------===// #ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H #define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Object/BuildID.h" #include "llvm/ProfileData/Coverage/MCDCTypes.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdint> #include <iterator> #include <memory> #include <sstream> #include <string> #include <system_error> #include <utility> #include <vector> namespace llvm { class IndexedInstrProfReader; namespace object { class BuildIDFetcher; } // namespace object namespace vfs { class FileSystem; } // namespace vfs namespace coverage { class CoverageMappingReader; struct CoverageMappingRecord; enum class coveragemap_error { … }; const std::error_category &coveragemap_category(); inline std::error_code make_error_code(coveragemap_error E) { … } class CoverageMapError : public ErrorInfo<CoverageMapError> { … }; /// A Counter is an abstract value that describes how to compute the /// execution count for a region of code using the collected profile count data. struct Counter { … }; /// A Counter expression is a value that represents an arithmetic operation /// with two counters. struct CounterExpression { … }; /// A Counter expression builder is used to construct the counter expressions. /// It avoids unnecessary duplication and simplifies algebraic expressions. class CounterExpressionBuilder { … }; LineColPair; /// A Counter mapping region associates a source range with a specific counter. struct CounterMappingRegion { … }; /// Associates a source range with an execution count. struct CountedRegion : public CounterMappingRegion { … }; /// MCDC Record grouping all information together. struct MCDCRecord { … }; namespace mcdc { /// Compute TestVector Indices "TVIdx" from the Conds graph. /// /// Clang CodeGen handles the bitmap index based on TVIdx. /// llvm-cov reconstructs conditions from TVIdx. /// /// For each leaf "The final decision", /// - TVIdx should be unique. /// - TVIdx has the Width. /// - The width represents the number of possible paths. /// - The minimum width is 1 "deterministic". /// - The order of leaves are sorted by Width DESC. It expects /// latter TVIdx(s) (with Width=1) could be pruned and altered to /// other simple branch conditions. /// class TVIdxBuilder { … }; } // namespace mcdc /// A Counter mapping context is used to connect the counters, expressions /// and the obtained counter values. class CounterMappingContext { … }; /// Code coverage information for a single function. struct FunctionRecord { … }; /// Iterator over Functions, optionally filtered to a single file. class FunctionRecordIterator : public iterator_facade_base<FunctionRecordIterator, std::forward_iterator_tag, FunctionRecord> { … }; /// Coverage information for a macro expansion or #included file. /// /// When covered code has pieces that can be expanded for more detail, such as a /// preprocessor macro use and its definition, these are represented as /// expansions whose coverage can be looked up independently. struct ExpansionRecord { … }; /// The execution count information starting at a point in a file. /// /// A sequence of CoverageSegments gives execution counts for a file in format /// that's simple to iterate through for processing. struct CoverageSegment { … }; /// An instantiation group contains a \c FunctionRecord list, such that each /// record corresponds to a distinct instantiation of the same function. /// /// Note that it's possible for a function to have more than one instantiation /// (consider C++ template specializations or static inline functions). class InstantiationGroup { … }; /// Coverage information to be processed or displayed. /// /// This represents the coverage of an entire file, expansion, or function. It /// provides a sequence of CoverageSegments to iterate through, as well as the /// list of expansions that can be further processed. class CoverageData { … }; /// The mapping of profile information to coverage data. /// /// This is the main interface to get coverage information, using a profile to /// fill out execution counts. class CoverageMapping { … }; /// Coverage statistics for a single line. class LineCoverageStats { … }; /// An iterator over the \c LineCoverageStats objects for lines described by /// a \c CoverageData instance. class LineCoverageIterator : public iterator_facade_base<LineCoverageIterator, std::forward_iterator_tag, const LineCoverageStats> { … }; /// Get a \c LineCoverageIterator range for the lines described by \p CD. static inline iterator_range<LineCoverageIterator> getLineCoverageStats(const coverage::CoverageData &CD) { … } // Coverage mappping data (V2) has the following layout: // IPSK_covmap: // [CoverageMapFileHeader] // [ArrayStart] // [CovMapFunctionRecordV2] // [CovMapFunctionRecordV2] // ... // [ArrayEnd] // [Encoded Filenames and Region Mapping Data] // // Coverage mappping data (V3) has the following layout: // IPSK_covmap: // [CoverageMapFileHeader] // [Encoded Filenames] // IPSK_covfun: // [ArrayStart] // odr_name_1: [CovMapFunctionRecordV3] // odr_name_2: [CovMapFunctionRecordV3] // ... // [ArrayEnd] // // Both versions of the coverage mapping format encode the same information, // but the V3 format does so more compactly by taking advantage of linkonce_odr // semantics (it allows exactly 1 function record per name reference). /// This namespace defines accessors shared by different versions of coverage /// mapping records. namespace accessors { /// Return the structural hash associated with the function. template <class FuncRecordTy, llvm::endianness Endian> uint64_t getFuncHash(const FuncRecordTy *Record) { … } /// Return the coverage map data size for the function. template <class FuncRecordTy, llvm::endianness Endian> uint64_t getDataSize(const FuncRecordTy *Record) { … } /// Return the function lookup key. The value is considered opaque. template <class FuncRecordTy, llvm::endianness Endian> uint64_t getFuncNameRef(const FuncRecordTy *Record) { … } /// Return the PGO name of the function. Used for formats in which the name is /// a hash. template <class FuncRecordTy, llvm::endianness Endian> Error getFuncNameViaRef(const FuncRecordTy *Record, InstrProfSymtab &ProfileNames, StringRef &FuncName) { … } /// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the /// coverage mapping is attached to the file header, instead of to the function /// record. template <class FuncRecordTy, llvm::endianness Endian> StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) { … } /// Advance to the next out-of-line coverage mapping and its associated /// function record. template <class FuncRecordTy, llvm::endianness Endian> std::pair<const char *, const FuncRecordTy *> advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) { … } } // end namespace accessors LLVM_PACKED_START template <class IntPtrT> struct CovMapFunctionRecordV1 { … }; struct CovMapFunctionRecordV2 { … }; struct CovMapFunctionRecordV3 { … }; // Per module coverage mapping data header, i.e. CoverageMapFileHeader // documented above. struct CovMapHeader { … }; LLVM_PACKED_END enum CovMapVersion { … }; // Correspond to "llvmcovm", in little-endian. constexpr uint64_t TestingFormatMagic = …; enum class TestingFormatVersion : uint64_t { … }; template <int CovMapVersion, class IntPtrT> struct CovMapTraits { … }; CovMapTraits<CovMapVersion::Version3, IntPtrT>; CovMapTraits<CovMapVersion::Version2, IntPtrT>; CovMapTraits<CovMapVersion::Version1, IntPtrT>; } // end namespace coverage /// Provide DenseMapInfo for CounterExpression template<> struct DenseMapInfo<coverage::CounterExpression> { … }; } // end namespace llvm #endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H