1 //===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Code coverage mapping data is generated by clang and read by
10 // llvm-cov to show code coverage statistics for a file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
15 #define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/BitVector.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/ADT/Hashing.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/iterator.h"
24 #include "llvm/ADT/iterator_range.h"
25 #include "llvm/Object/BuildID.h"
26 #include "llvm/ProfileData/InstrProf.h"
27 #include "llvm/Support/Alignment.h"
28 #include "llvm/Support/Compiler.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/Endian.h"
31 #include "llvm/Support/Error.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include <cassert>
34 #include <cstdint>
35 #include <iterator>
36 #include <memory>
37 #include <sstream>
38 #include <string>
39 #include <system_error>
40 #include <tuple>
41 #include <utility>
42 #include <vector>
43 
44 namespace llvm {
45 
46 class IndexedInstrProfReader;
47 
48 namespace object {
49 class BuildIDFetcher;
50 } // namespace object
51 
52 namespace vfs {
53 class FileSystem;
54 } // namespace vfs
55 
56 namespace coverage {
57 
58 class CoverageMappingReader;
59 struct CoverageMappingRecord;
60 
61 enum class coveragemap_error {
62   success = 0,
63   eof,
64   no_data_found,
65   unsupported_version,
66   truncated,
67   malformed,
68   decompression_failed,
69   invalid_or_missing_arch_specifier
70 };
71 
72 const std::error_category &coveragemap_category();
73 
74 inline std::error_code make_error_code(coveragemap_error E) {
75   return std::error_code(static_cast<int>(E), coveragemap_category());
76 }
77 
78 class CoverageMapError : public ErrorInfo<CoverageMapError> {
79 public:
80   CoverageMapError(coveragemap_error Err, const Twine &ErrStr = Twine())
81       : Err(Err), Msg(ErrStr.str()) {
82     assert(Err != coveragemap_error::success && "Not an error");
83   }
84 
85   std::string message() const override;
86 
87   void log(raw_ostream &OS) const override { OS << message(); }
88 
89   std::error_code convertToErrorCode() const override {
90     return make_error_code(Err);
91   }
92 
93   coveragemap_error get() const { return Err; }
94   const std::string &getMessage() const { return Msg; }
95 
96   static char ID;
97 
98 private:
99   coveragemap_error Err;
100   std::string Msg;
101 };
102 
103 /// A Counter is an abstract value that describes how to compute the
104 /// execution count for a region of code using the collected profile count data.
105 struct Counter {
106   /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
107   /// the CounterKind. This means CounterKind has to leave bit 0 free.
108   enum CounterKind { Zero, CounterValueReference, Expression };
109   static const unsigned EncodingTagBits = 2;
110   static const unsigned EncodingTagMask = 0x3;
111   static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
112       EncodingTagBits + 1;
113 
114 private:
115   CounterKind Kind = Zero;
116   unsigned ID = 0;
117 
118   Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
119 
120 public:
121   Counter() = default;
122 
123   CounterKind getKind() const { return Kind; }
124 
125   bool isZero() const { return Kind == Zero; }
126 
127   bool isExpression() const { return Kind == Expression; }
128 
129   unsigned getCounterID() const { return ID; }
130 
131   unsigned getExpressionID() const { return ID; }
132 
133   friend bool operator==(const Counter &LHS, const Counter &RHS) {
134     return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
135   }
136 
137   friend bool operator!=(const Counter &LHS, const Counter &RHS) {
138     return !(LHS == RHS);
139   }
140 
141   friend bool operator<(const Counter &LHS, const Counter &RHS) {
142     return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
143   }
144 
145   /// Return the counter that represents the number zero.
146   static Counter getZero() { return Counter(); }
147 
148   /// Return the counter that corresponds to a specific profile counter.
149   static Counter getCounter(unsigned CounterId) {
150     return Counter(CounterValueReference, CounterId);
151   }
152 
153   /// Return the counter that corresponds to a specific addition counter
154   /// expression.
155   static Counter getExpression(unsigned ExpressionId) {
156     return Counter(Expression, ExpressionId);
157   }
158 };
159 
160 /// A Counter expression is a value that represents an arithmetic operation
161 /// with two counters.
162 struct CounterExpression {
163   enum ExprKind { Subtract, Add };
164   ExprKind Kind;
165   Counter LHS, RHS;
166 
167   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
168       : Kind(Kind), LHS(LHS), RHS(RHS) {}
169 };
170 
171 /// A Counter expression builder is used to construct the counter expressions.
172 /// It avoids unnecessary duplication and simplifies algebraic expressions.
173 class CounterExpressionBuilder {
174   /// A list of all the counter expressions
175   std::vector<CounterExpression> Expressions;
176 
177   /// A lookup table for the index of a given expression.
178   DenseMap<CounterExpression, unsigned> ExpressionIndices;
179 
180   /// Return the counter which corresponds to the given expression.
181   ///
182   /// If the given expression is already stored in the builder, a counter
183   /// that references that expression is returned. Otherwise, the given
184   /// expression is added to the builder's collection of expressions.
185   Counter get(const CounterExpression &E);
186 
187   /// Represents a term in a counter expression tree.
188   struct Term {
189     unsigned CounterID;
190     int Factor;
191 
192     Term(unsigned CounterID, int Factor)
193         : CounterID(CounterID), Factor(Factor) {}
194   };
195 
196   /// Gather the terms of the expression tree for processing.
197   ///
198   /// This collects each addition and subtraction referenced by the counter into
199   /// a sequence that can be sorted and combined to build a simplified counter
200   /// expression.
201   void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
202 
203   /// Simplifies the given expression tree
204   /// by getting rid of algebraically redundant operations.
205   Counter simplify(Counter ExpressionTree);
206 
207 public:
208   ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
209 
210   /// Return a counter that represents the expression that adds LHS and RHS.
211   Counter add(Counter LHS, Counter RHS, bool Simplify = true);
212 
213   /// Return a counter that represents the expression that subtracts RHS from
214   /// LHS.
215   Counter subtract(Counter LHS, Counter RHS, bool Simplify = true);
216 };
217 
218 using LineColPair = std::pair<unsigned, unsigned>;
219 
220 /// A Counter mapping region associates a source range with a specific counter.
221 struct CounterMappingRegion {
222   enum RegionKind {
223     /// A CodeRegion associates some code with a counter
224     CodeRegion,
225 
226     /// An ExpansionRegion represents a file expansion region that associates
227     /// a source range with the expansion of a virtual source file, such as
228     /// for a macro instantiation or #include file.
229     ExpansionRegion,
230 
231     /// A SkippedRegion represents a source range with code that was skipped
232     /// by a preprocessor or similar means.
233     SkippedRegion,
234 
235     /// A GapRegion is like a CodeRegion, but its count is only set as the
236     /// line execution count when its the only region in the line.
237     GapRegion,
238 
239     /// A BranchRegion represents leaf-level boolean expressions and is
240     /// associated with two counters, each representing the number of times the
241     /// expression evaluates to true or false.
242     BranchRegion,
243 
244     /// A DecisionRegion represents a top-level boolean expression and is
245     /// associated with a variable length bitmap index and condition number.
246     MCDCDecisionRegion,
247 
248     /// A Branch Region can be extended to include IDs to facilitate MC/DC.
249     MCDCBranchRegion
250   };
251 
252   using MCDCConditionID = unsigned int;
253   struct MCDCParameters {
254     /// Byte Index of Bitmap Coverage Object for a Decision Region.
255     unsigned BitmapIdx = 0;
256 
257     /// Number of Conditions used for a Decision Region.
258     unsigned NumConditions = 0;
259 
260     /// IDs used to represent a branch region and other branch regions
261     /// evaluated based on True and False branches.
262     MCDCConditionID ID = 0, TrueID = 0, FalseID = 0;
263   };
264 
265   /// Primary Counter that is also used for Branch Regions (TrueCount).
266   Counter Count;
267 
268   /// Secondary Counter used for Branch Regions (FalseCount).
269   Counter FalseCount;
270 
271   /// Parameters used for Modified Condition/Decision Coverage
272   MCDCParameters MCDCParams;
273 
274   unsigned FileID = 0;
275   unsigned ExpandedFileID = 0;
276   unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
277 
278   RegionKind Kind;
279 
280   CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID,
281                        unsigned LineStart, unsigned ColumnStart,
282                        unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
283       : Count(Count), FileID(FileID), ExpandedFileID(ExpandedFileID),
284         LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd),
285         ColumnEnd(ColumnEnd), Kind(Kind) {}
286 
287   CounterMappingRegion(Counter Count, Counter FalseCount,
288                        MCDCParameters MCDCParams, unsigned FileID,
289                        unsigned ExpandedFileID, unsigned LineStart,
290                        unsigned ColumnStart, unsigned LineEnd,
291                        unsigned ColumnEnd, RegionKind Kind)
292       : Count(Count), FalseCount(FalseCount), MCDCParams(MCDCParams),
293         FileID(FileID), ExpandedFileID(ExpandedFileID), LineStart(LineStart),
294         ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
295         Kind(Kind) {}
296 
297   CounterMappingRegion(MCDCParameters MCDCParams, unsigned FileID,
298                        unsigned LineStart, unsigned ColumnStart,
299                        unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
300       : MCDCParams(MCDCParams), FileID(FileID), LineStart(LineStart),
301         ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
302         Kind(Kind) {}
303 
304   static CounterMappingRegion
305   makeRegion(Counter Count, unsigned FileID, unsigned LineStart,
306              unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
307     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
308                                 LineEnd, ColumnEnd, CodeRegion);
309   }
310 
311   static CounterMappingRegion
312   makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
313                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
314     return CounterMappingRegion(Counter(), FileID, ExpandedFileID, LineStart,
315                                 ColumnStart, LineEnd, ColumnEnd,
316                                 ExpansionRegion);
317   }
318 
319   static CounterMappingRegion
320   makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
321               unsigned LineEnd, unsigned ColumnEnd) {
322     return CounterMappingRegion(Counter(), FileID, 0, LineStart, ColumnStart,
323                                 LineEnd, ColumnEnd, SkippedRegion);
324   }
325 
326   static CounterMappingRegion
327   makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart,
328                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
329     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
330                                 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
331   }
332 
333   static CounterMappingRegion
334   makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID,
335                    unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
336                    unsigned ColumnEnd) {
337     return CounterMappingRegion(Count, FalseCount, MCDCParameters(), FileID, 0,
338                                 LineStart, ColumnStart, LineEnd, ColumnEnd,
339                                 BranchRegion);
340   }
341 
342   static CounterMappingRegion
343   makeBranchRegion(Counter Count, Counter FalseCount, MCDCParameters MCDCParams,
344                    unsigned FileID, unsigned LineStart, unsigned ColumnStart,
345                    unsigned LineEnd, unsigned ColumnEnd) {
346     return CounterMappingRegion(Count, FalseCount, MCDCParams, FileID, 0,
347                                 LineStart, ColumnStart, LineEnd, ColumnEnd,
348                                 MCDCParams.ID == 0 ? BranchRegion
349                                                    : MCDCBranchRegion);
350   }
351 
352   static CounterMappingRegion
353   makeDecisionRegion(MCDCParameters MCDCParams, unsigned FileID,
354                      unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
355                      unsigned ColumnEnd) {
356     return CounterMappingRegion(MCDCParams, FileID, LineStart, ColumnStart,
357                                 LineEnd, ColumnEnd, MCDCDecisionRegion);
358   }
359 
360   inline LineColPair startLoc() const {
361     return LineColPair(LineStart, ColumnStart);
362   }
363 
364   inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
365 };
366 
367 /// Associates a source range with an execution count.
368 struct CountedRegion : public CounterMappingRegion {
369   uint64_t ExecutionCount;
370   uint64_t FalseExecutionCount;
371   bool Folded;
372 
373   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
374       : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
375         FalseExecutionCount(0), Folded(false) {}
376 
377   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
378                 uint64_t FalseExecutionCount)
379       : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
380         FalseExecutionCount(FalseExecutionCount), Folded(false) {}
381 };
382 
383 /// MCDC Record grouping all information together.
384 struct MCDCRecord {
385   /// CondState represents the evaluation of a condition in an executed test
386   /// vector, which can be True or False. A DontCare is used to mask an
387   /// unevaluatable condition resulting from short-circuit behavior of logical
388   /// operators in languages like C/C++. When comparing the evaluation of a
389   /// condition across executed test vectors, comparisons against a DontCare
390   /// are effectively ignored.
391   enum CondState { MCDC_DontCare = -1, MCDC_False = 0, MCDC_True = 1 };
392 
393   using TestVector = llvm::SmallVector<CondState>;
394   using TestVectors = llvm::SmallVector<TestVector>;
395   using BoolVector = llvm::SmallVector<bool>;
396   using TVRowPair = std::pair<unsigned, unsigned>;
397   using TVPairMap = llvm::DenseMap<unsigned, TVRowPair>;
398   using CondIDMap = llvm::DenseMap<unsigned, unsigned>;
399   using LineColPairMap = llvm::DenseMap<unsigned, LineColPair>;
400 
401 private:
402   CounterMappingRegion Region;
403   TestVectors TV;
404   TVPairMap IndependencePairs;
405   BoolVector Folded;
406   CondIDMap PosToID;
407   LineColPairMap CondLoc;
408 
409 public:
410   MCDCRecord(CounterMappingRegion Region, TestVectors TV,
411              TVPairMap IndependencePairs, BoolVector Folded, CondIDMap PosToID,
412              LineColPairMap CondLoc)
413       : Region(Region), TV(TV), IndependencePairs(IndependencePairs),
414         Folded(Folded), PosToID(PosToID), CondLoc(CondLoc){};
415 
416   CounterMappingRegion getDecisionRegion() const { return Region; }
417   unsigned getNumConditions() const {
418     assert(Region.MCDCParams.NumConditions != 0 &&
419            "In MC/DC, NumConditions should never be zero!");
420     return Region.MCDCParams.NumConditions;
421   }
422   unsigned getNumTestVectors() const { return TV.size(); }
423   bool isCondFolded(unsigned Condition) const { return Folded[Condition]; }
424 
425   /// Return the evaluation of a condition (indicated by Condition) in an
426   /// executed test vector (indicated by TestVectorIndex), which will be True,
427   /// False, or DontCare if the condition is unevaluatable. Because condition
428   /// IDs are not associated based on their position in the expression,
429   /// accessing conditions in the TestVectors requires a translation from a
430   /// ordinal position to actual condition ID. This is done via PosToID[].
431   CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
432     return TV[TestVectorIndex][PosToID[Condition]];
433   }
434 
435   /// Return the Result evaluation for an executed test vector.
436   /// See MCDCRecordProcessor::RecordTestVector().
437   CondState getTVResult(unsigned TestVectorIndex) {
438     return TV[TestVectorIndex][getNumConditions()];
439   }
440 
441   /// Determine whether a given condition (indicated by Condition) is covered
442   /// by an Independence Pair. Because condition IDs are not associated based
443   /// on their position in the expression, accessing conditions in the
444   /// TestVectors requires a translation from a ordinal position to actual
445   /// condition ID. This is done via PosToID[].
446   bool isConditionIndependencePairCovered(unsigned Condition) const {
447     auto It = PosToID.find(Condition);
448     if (It != PosToID.end())
449       return IndependencePairs.contains(It->second);
450     llvm_unreachable("Condition ID without an Ordinal mapping");
451   }
452 
453   /// Return the Independence Pair that covers the given condition. Because
454   /// condition IDs are not associated based on their position in the
455   /// expression, accessing conditions in the TestVectors requires a
456   /// translation from a ordinal position to actual condition ID. This is done
457   /// via PosToID[].
458   TVRowPair getConditionIndependencePair(unsigned Condition) {
459     assert(isConditionIndependencePairCovered(Condition));
460     return IndependencePairs[PosToID[Condition]];
461   }
462 
463   float getPercentCovered() const {
464     unsigned Folded = 0;
465     unsigned Covered = 0;
466     for (unsigned C = 0; C < getNumConditions(); C++) {
467       if (isCondFolded(C))
468         Folded++;
469       else if (isConditionIndependencePairCovered(C))
470         Covered++;
471     }
472 
473     unsigned Total = getNumConditions() - Folded;
474     if (Total == 0)
475       return 0.0;
476     return (static_cast<double>(Covered) / static_cast<double>(Total)) * 100.0;
477   }
478 
479   std::string getConditionHeaderString(unsigned Condition) {
480     std::ostringstream OS;
481     OS << "Condition C" << Condition + 1 << " --> (";
482     OS << CondLoc[Condition].first << ":" << CondLoc[Condition].second;
483     OS << ")\n";
484     return OS.str();
485   }
486 
487   std::string getTestVectorHeaderString() const {
488     std::ostringstream OS;
489     if (getNumTestVectors() == 0) {
490       OS << "None.\n";
491       return OS.str();
492     }
493     const auto NumConditions = getNumConditions();
494     for (unsigned I = 0; I < NumConditions; I++) {
495       OS << "C" << I + 1;
496       if (I != NumConditions - 1)
497         OS << ", ";
498     }
499     OS << "    Result\n";
500     return OS.str();
501   }
502 
503   std::string getTestVectorString(unsigned TestVectorIndex) {
504     assert(TestVectorIndex < getNumTestVectors() &&
505            "TestVector index out of bounds!");
506     std::ostringstream OS;
507     const auto NumConditions = getNumConditions();
508     // Add individual condition values to the string.
509     OS << "  " << TestVectorIndex + 1 << " { ";
510     for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
511       if (isCondFolded(Condition))
512         OS << "C";
513       else {
514         switch (getTVCondition(TestVectorIndex, Condition)) {
515         case MCDCRecord::MCDC_DontCare:
516           OS << "-";
517           break;
518         case MCDCRecord::MCDC_True:
519           OS << "T";
520           break;
521         case MCDCRecord::MCDC_False:
522           OS << "F";
523           break;
524         }
525       }
526       if (Condition != NumConditions - 1)
527         OS << ",  ";
528     }
529 
530     // Add result value to the string.
531     OS << "  = ";
532     if (getTVResult(TestVectorIndex) == MCDC_True)
533       OS << "T";
534     else
535       OS << "F";
536     OS << "      }\n";
537 
538     return OS.str();
539   }
540 
541   std::string getConditionCoverageString(unsigned Condition) {
542     assert(Condition < getNumConditions() &&
543            "Condition index is out of bounds!");
544     std::ostringstream OS;
545 
546     OS << "  C" << Condition + 1 << "-Pair: ";
547     if (isCondFolded(Condition)) {
548       OS << "constant folded\n";
549     } else if (isConditionIndependencePairCovered(Condition)) {
550       TVRowPair rows = getConditionIndependencePair(Condition);
551       OS << "covered: (" << rows.first << ",";
552       OS << rows.second << ")\n";
553     } else
554       OS << "not covered\n";
555 
556     return OS.str();
557   }
558 };
559 
560 /// A Counter mapping context is used to connect the counters, expressions
561 /// and the obtained counter values.
562 class CounterMappingContext {
563   ArrayRef<CounterExpression> Expressions;
564   ArrayRef<uint64_t> CounterValues;
565   ArrayRef<uint8_t> BitmapBytes;
566 
567 public:
568   CounterMappingContext(ArrayRef<CounterExpression> Expressions,
569                         ArrayRef<uint64_t> CounterValues = std::nullopt)
570       : Expressions(Expressions), CounterValues(CounterValues) {}
571 
572   void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
573   void setBitmapBytes(ArrayRef<uint8_t> Bytes) { BitmapBytes = Bytes; }
574 
575   void dump(const Counter &C, raw_ostream &OS) const;
576   void dump(const Counter &C) const { dump(C, dbgs()); }
577 
578   /// Return the number of times that a region of code associated with this
579   /// counter was executed.
580   Expected<int64_t> evaluate(const Counter &C) const;
581 
582   /// Return the number of times that a region of code associated with this
583   /// counter was executed.
584   Expected<BitVector>
585   evaluateBitmap(const CounterMappingRegion *MCDCDecision) const;
586 
587   /// Return an MCDC record that indicates executed test vectors and condition
588   /// pairs.
589   Expected<MCDCRecord>
590   evaluateMCDCRegion(const CounterMappingRegion &Region,
591                      const BitVector &Bitmap,
592                      ArrayRef<const CounterMappingRegion *> Branches);
593 
594   unsigned getMaxCounterID(const Counter &C) const;
595 };
596 
597 /// Code coverage information for a single function.
598 struct FunctionRecord {
599   /// Raw function name.
600   std::string Name;
601   /// Mapping from FileID (i.e. vector index) to filename. Used to support
602   /// macro expansions within a function in which the macro and function are
603   /// defined in separate files.
604   ///
605   /// TODO: Uniquing filenames across all function records may be a performance
606   /// optimization.
607   std::vector<std::string> Filenames;
608   /// Regions in the function along with their counts.
609   std::vector<CountedRegion> CountedRegions;
610   /// Branch Regions in the function along with their counts.
611   std::vector<CountedRegion> CountedBranchRegions;
612   /// MCDC Records record a DecisionRegion and associated BranchRegions.
613   std::vector<MCDCRecord> MCDCRecords;
614   /// The number of times this function was executed.
615   uint64_t ExecutionCount = 0;
616 
617   FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames)
618       : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
619 
620   FunctionRecord(FunctionRecord &&FR) = default;
621   FunctionRecord &operator=(FunctionRecord &&) = default;
622 
623   void pushMCDCRecord(MCDCRecord Record) { MCDCRecords.push_back(Record); }
624 
625   void pushRegion(CounterMappingRegion Region, uint64_t Count,
626                   uint64_t FalseCount) {
627     if (Region.Kind == CounterMappingRegion::BranchRegion ||
628         Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
629       CountedBranchRegions.emplace_back(Region, Count, FalseCount);
630       // If both counters are hard-coded to zero, then this region represents a
631       // constant-folded branch.
632       if (Region.Count.isZero() && Region.FalseCount.isZero())
633         CountedBranchRegions.back().Folded = true;
634       return;
635     }
636     if (CountedRegions.empty())
637       ExecutionCount = Count;
638     CountedRegions.emplace_back(Region, Count, FalseCount);
639   }
640 };
641 
642 /// Iterator over Functions, optionally filtered to a single file.
643 class FunctionRecordIterator
644     : public iterator_facade_base<FunctionRecordIterator,
645                                   std::forward_iterator_tag, FunctionRecord> {
646   ArrayRef<FunctionRecord> Records;
647   ArrayRef<FunctionRecord>::iterator Current;
648   StringRef Filename;
649 
650   /// Skip records whose primary file is not \c Filename.
651   void skipOtherFiles();
652 
653 public:
654   FunctionRecordIterator(ArrayRef<FunctionRecord> Records_,
655                          StringRef Filename = "")
656       : Records(Records_), Current(Records.begin()), Filename(Filename) {
657     skipOtherFiles();
658   }
659 
660   FunctionRecordIterator() : Current(Records.begin()) {}
661 
662   bool operator==(const FunctionRecordIterator &RHS) const {
663     return Current == RHS.Current && Filename == RHS.Filename;
664   }
665 
666   const FunctionRecord &operator*() const { return *Current; }
667 
668   FunctionRecordIterator &operator++() {
669     assert(Current != Records.end() && "incremented past end");
670     ++Current;
671     skipOtherFiles();
672     return *this;
673   }
674 };
675 
676 /// Coverage information for a macro expansion or #included file.
677 ///
678 /// When covered code has pieces that can be expanded for more detail, such as a
679 /// preprocessor macro use and its definition, these are represented as
680 /// expansions whose coverage can be looked up independently.
681 struct ExpansionRecord {
682   /// The abstract file this expansion covers.
683   unsigned FileID;
684   /// The region that expands to this record.
685   const CountedRegion &Region;
686   /// Coverage for the expansion.
687   const FunctionRecord &Function;
688 
689   ExpansionRecord(const CountedRegion &Region,
690                   const FunctionRecord &Function)
691       : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
692 };
693 
694 /// The execution count information starting at a point in a file.
695 ///
696 /// A sequence of CoverageSegments gives execution counts for a file in format
697 /// that's simple to iterate through for processing.
698 struct CoverageSegment {
699   /// The line where this segment begins.
700   unsigned Line;
701   /// The column where this segment begins.
702   unsigned Col;
703   /// The execution count, or zero if no count was recorded.
704   uint64_t Count;
705   /// When false, the segment was uninstrumented or skipped.
706   bool HasCount;
707   /// Whether this enters a new region or returns to a previous count.
708   bool IsRegionEntry;
709   /// Whether this enters a gap region.
710   bool IsGapRegion;
711 
712   CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
713       : Line(Line), Col(Col), Count(0), HasCount(false),
714         IsRegionEntry(IsRegionEntry), IsGapRegion(false) {}
715 
716   CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
717                   bool IsRegionEntry, bool IsGapRegion = false,
718                   bool IsBranchRegion = false)
719       : Line(Line), Col(Col), Count(Count), HasCount(true),
720         IsRegionEntry(IsRegionEntry), IsGapRegion(IsGapRegion) {}
721 
722   friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
723     return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
724                     L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
725                                                R.HasCount, R.IsRegionEntry,
726                                                R.IsGapRegion);
727   }
728 };
729 
730 /// An instantiation group contains a \c FunctionRecord list, such that each
731 /// record corresponds to a distinct instantiation of the same function.
732 ///
733 /// Note that it's possible for a function to have more than one instantiation
734 /// (consider C++ template specializations or static inline functions).
735 class InstantiationGroup {
736   friend class CoverageMapping;
737 
738   unsigned Line;
739   unsigned Col;
740   std::vector<const FunctionRecord *> Instantiations;
741 
742   InstantiationGroup(unsigned Line, unsigned Col,
743                      std::vector<const FunctionRecord *> Instantiations)
744       : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
745 
746 public:
747   InstantiationGroup(const InstantiationGroup &) = delete;
748   InstantiationGroup(InstantiationGroup &&) = default;
749 
750   /// Get the number of instantiations in this group.
751   size_t size() const { return Instantiations.size(); }
752 
753   /// Get the line where the common function was defined.
754   unsigned getLine() const { return Line; }
755 
756   /// Get the column where the common function was defined.
757   unsigned getColumn() const { return Col; }
758 
759   /// Check if the instantiations in this group have a common mangled name.
760   bool hasName() const {
761     for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
762       if (Instantiations[I]->Name != Instantiations[0]->Name)
763         return false;
764     return true;
765   }
766 
767   /// Get the common mangled name for instantiations in this group.
768   StringRef getName() const {
769     assert(hasName() && "Instantiations don't have a shared name");
770     return Instantiations[0]->Name;
771   }
772 
773   /// Get the total execution count of all instantiations in this group.
774   uint64_t getTotalExecutionCount() const {
775     uint64_t Count = 0;
776     for (const FunctionRecord *F : Instantiations)
777       Count += F->ExecutionCount;
778     return Count;
779   }
780 
781   /// Get the instantiations in this group.
782   ArrayRef<const FunctionRecord *> getInstantiations() const {
783     return Instantiations;
784   }
785 };
786 
787 /// Coverage information to be processed or displayed.
788 ///
789 /// This represents the coverage of an entire file, expansion, or function. It
790 /// provides a sequence of CoverageSegments to iterate through, as well as the
791 /// list of expansions that can be further processed.
792 class CoverageData {
793   friend class CoverageMapping;
794 
795   std::string Filename;
796   std::vector<CoverageSegment> Segments;
797   std::vector<ExpansionRecord> Expansions;
798   std::vector<CountedRegion> BranchRegions;
799   std::vector<MCDCRecord> MCDCRecords;
800 
801 public:
802   CoverageData() = default;
803 
804   CoverageData(StringRef Filename) : Filename(Filename) {}
805 
806   /// Get the name of the file this data covers.
807   StringRef getFilename() const { return Filename; }
808 
809   /// Get an iterator over the coverage segments for this object. The segments
810   /// are guaranteed to be uniqued and sorted by location.
811   std::vector<CoverageSegment>::const_iterator begin() const {
812     return Segments.begin();
813   }
814 
815   std::vector<CoverageSegment>::const_iterator end() const {
816     return Segments.end();
817   }
818 
819   bool empty() const { return Segments.empty(); }
820 
821   /// Expansions that can be further processed.
822   ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
823 
824   /// Branches that can be further processed.
825   ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
826 
827   /// MCDC Records that can be further processed.
828   ArrayRef<MCDCRecord> getMCDCRecords() const { return MCDCRecords; }
829 };
830 
831 /// The mapping of profile information to coverage data.
832 ///
833 /// This is the main interface to get coverage information, using a profile to
834 /// fill out execution counts.
835 class CoverageMapping {
836   DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
837   std::vector<FunctionRecord> Functions;
838   DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
839   std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
840 
841   CoverageMapping() = default;
842 
843   // Load coverage records from readers.
844   static Error loadFromReaders(
845       ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
846       IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
847 
848   // Load coverage records from file.
849   static Error
850   loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
851                IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
852                bool &DataFound,
853                SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
854 
855   /// Add a function record corresponding to \p Record.
856   Error loadFunctionRecord(const CoverageMappingRecord &Record,
857                            IndexedInstrProfReader &ProfileReader);
858 
859   /// Look up the indices for function records which are at least partially
860   /// defined in the specified file. This is guaranteed to return a superset of
861   /// such records: extra records not in the file may be included if there is
862   /// a hash collision on the filename. Clients must be robust to collisions.
863   ArrayRef<unsigned>
864   getImpreciseRecordIndicesForFilename(StringRef Filename) const;
865 
866 public:
867   CoverageMapping(const CoverageMapping &) = delete;
868   CoverageMapping &operator=(const CoverageMapping &) = delete;
869 
870   /// Load the coverage mapping using the given readers.
871   static Expected<std::unique_ptr<CoverageMapping>>
872   load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
873        IndexedInstrProfReader &ProfileReader);
874 
875   /// Load the coverage mapping from the given object files and profile. If
876   /// \p Arches is non-empty, it must specify an architecture for each object.
877   /// Ignores non-instrumented object files unless all are not instrumented.
878   static Expected<std::unique_ptr<CoverageMapping>>
879   load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
880        vfs::FileSystem &FS, ArrayRef<StringRef> Arches = std::nullopt,
881        StringRef CompilationDir = "",
882        const object::BuildIDFetcher *BIDFetcher = nullptr,
883        bool CheckBinaryIDs = false);
884 
885   /// The number of functions that couldn't have their profiles mapped.
886   ///
887   /// This is a count of functions whose profile is out of date or otherwise
888   /// can't be associated with any coverage information.
889   unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
890 
891   /// A hash mismatch occurs when a profile record for a symbol does not have
892   /// the same hash as a coverage mapping record for the same symbol. This
893   /// returns a list of hash mismatches, where each mismatch is a pair of the
894   /// symbol name and its coverage mapping hash.
895   ArrayRef<std::pair<std::string, uint64_t>> getHashMismatches() const {
896     return FuncHashMismatches;
897   }
898 
899   /// Returns a lexicographically sorted, unique list of files that are
900   /// covered.
901   std::vector<StringRef> getUniqueSourceFiles() const;
902 
903   /// Get the coverage for a particular file.
904   ///
905   /// The given filename must be the name as recorded in the coverage
906   /// information. That is, only names returned from getUniqueSourceFiles will
907   /// yield a result.
908   CoverageData getCoverageForFile(StringRef Filename) const;
909 
910   /// Get the coverage for a particular function.
911   CoverageData getCoverageForFunction(const FunctionRecord &Function) const;
912 
913   /// Get the coverage for an expansion within a coverage set.
914   CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const;
915 
916   /// Gets all of the functions covered by this profile.
917   iterator_range<FunctionRecordIterator> getCoveredFunctions() const {
918     return make_range(FunctionRecordIterator(Functions),
919                       FunctionRecordIterator());
920   }
921 
922   /// Gets all of the functions in a particular file.
923   iterator_range<FunctionRecordIterator>
924   getCoveredFunctions(StringRef Filename) const {
925     return make_range(FunctionRecordIterator(Functions, Filename),
926                       FunctionRecordIterator());
927   }
928 
929   /// Get the list of function instantiation groups in a particular file.
930   ///
931   /// Every instantiation group in a program is attributed to exactly one file:
932   /// the file in which the definition for the common function begins.
933   std::vector<InstantiationGroup>
934   getInstantiationGroups(StringRef Filename) const;
935 };
936 
937 /// Coverage statistics for a single line.
938 class LineCoverageStats {
939   uint64_t ExecutionCount;
940   bool HasMultipleRegions;
941   bool Mapped;
942   unsigned Line;
943   ArrayRef<const CoverageSegment *> LineSegments;
944   const CoverageSegment *WrappedSegment;
945 
946   friend class LineCoverageIterator;
947   LineCoverageStats() = default;
948 
949 public:
950   LineCoverageStats(ArrayRef<const CoverageSegment *> LineSegments,
951                     const CoverageSegment *WrappedSegment, unsigned Line);
952 
953   uint64_t getExecutionCount() const { return ExecutionCount; }
954 
955   bool hasMultipleRegions() const { return HasMultipleRegions; }
956 
957   bool isMapped() const { return Mapped; }
958 
959   unsigned getLine() const { return Line; }
960 
961   ArrayRef<const CoverageSegment *> getLineSegments() const {
962     return LineSegments;
963   }
964 
965   const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
966 };
967 
968 /// An iterator over the \c LineCoverageStats objects for lines described by
969 /// a \c CoverageData instance.
970 class LineCoverageIterator
971     : public iterator_facade_base<LineCoverageIterator,
972                                   std::forward_iterator_tag,
973                                   const LineCoverageStats> {
974 public:
975   LineCoverageIterator(const CoverageData &CD)
976       : LineCoverageIterator(CD, CD.begin()->Line) {}
977 
978   LineCoverageIterator(const CoverageData &CD, unsigned Line)
979       : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
980         Line(Line) {
981     this->operator++();
982   }
983 
984   bool operator==(const LineCoverageIterator &R) const {
985     return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
986   }
987 
988   const LineCoverageStats &operator*() const { return Stats; }
989 
990   LineCoverageIterator &operator++();
991 
992   LineCoverageIterator getEnd() const {
993     auto EndIt = *this;
994     EndIt.Next = CD.end();
995     EndIt.Ended = true;
996     return EndIt;
997   }
998 
999 private:
1000   const CoverageData &CD;
1001   const CoverageSegment *WrappedSegment;
1002   std::vector<CoverageSegment>::const_iterator Next;
1003   bool Ended;
1004   unsigned Line;
1005   SmallVector<const CoverageSegment *, 4> Segments;
1006   LineCoverageStats Stats;
1007 };
1008 
1009 /// Get a \c LineCoverageIterator range for the lines described by \p CD.
1010 static inline iterator_range<LineCoverageIterator>
1011 getLineCoverageStats(const coverage::CoverageData &CD) {
1012   auto Begin = LineCoverageIterator(CD);
1013   auto End = Begin.getEnd();
1014   return make_range(Begin, End);
1015 }
1016 
1017 // Coverage mappping data (V2) has the following layout:
1018 // IPSK_covmap:
1019 //   [CoverageMapFileHeader]
1020 //   [ArrayStart]
1021 //    [CovMapFunctionRecordV2]
1022 //    [CovMapFunctionRecordV2]
1023 //    ...
1024 //   [ArrayEnd]
1025 //   [Encoded Filenames and Region Mapping Data]
1026 //
1027 // Coverage mappping data (V3) has the following layout:
1028 // IPSK_covmap:
1029 //   [CoverageMapFileHeader]
1030 //   [Encoded Filenames]
1031 // IPSK_covfun:
1032 //   [ArrayStart]
1033 //     odr_name_1: [CovMapFunctionRecordV3]
1034 //     odr_name_2: [CovMapFunctionRecordV3]
1035 //     ...
1036 //   [ArrayEnd]
1037 //
1038 // Both versions of the coverage mapping format encode the same information,
1039 // but the V3 format does so more compactly by taking advantage of linkonce_odr
1040 // semantics (it allows exactly 1 function record per name reference).
1041 
1042 /// This namespace defines accessors shared by different versions of coverage
1043 /// mapping records.
1044 namespace accessors {
1045 
1046 /// Return the structural hash associated with the function.
1047 template <class FuncRecordTy, llvm::endianness Endian>
1048 uint64_t getFuncHash(const FuncRecordTy *Record) {
1049   return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
1050 }
1051 
1052 /// Return the coverage map data size for the function.
1053 template <class FuncRecordTy, llvm::endianness Endian>
1054 uint64_t getDataSize(const FuncRecordTy *Record) {
1055   return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
1056 }
1057 
1058 /// Return the function lookup key. The value is considered opaque.
1059 template <class FuncRecordTy, llvm::endianness Endian>
1060 uint64_t getFuncNameRef(const FuncRecordTy *Record) {
1061   return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
1062 }
1063 
1064 /// Return the PGO name of the function. Used for formats in which the name is
1065 /// a hash.
1066 template <class FuncRecordTy, llvm::endianness Endian>
1067 Error getFuncNameViaRef(const FuncRecordTy *Record,
1068                         InstrProfSymtab &ProfileNames, StringRef &FuncName) {
1069   uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
1070   FuncName = ProfileNames.getFuncOrVarName(NameRef);
1071   return Error::success();
1072 }
1073 
1074 /// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
1075 /// coverage mapping is attached to the file header, instead of to the function
1076 /// record.
1077 template <class FuncRecordTy, llvm::endianness Endian>
1078 StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record,
1079                                       const char *MappingBuf) {
1080   return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
1081 }
1082 
1083 /// Advance to the next out-of-line coverage mapping and its associated
1084 /// function record.
1085 template <class FuncRecordTy, llvm::endianness Endian>
1086 std::pair<const char *, const FuncRecordTy *>
1087 advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
1088   return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
1089 }
1090 
1091 } // end namespace accessors
1092 
1093 LLVM_PACKED_START
1094 template <class IntPtrT>
1095 struct CovMapFunctionRecordV1 {
1096   using ThisT = CovMapFunctionRecordV1<IntPtrT>;
1097 
1098 #define COVMAP_V1
1099 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1100 #include "llvm/ProfileData/InstrProfData.inc"
1101 #undef COVMAP_V1
1102   CovMapFunctionRecordV1() = delete;
1103 
1104   template <llvm::endianness Endian> uint64_t getFuncHash() const {
1105     return accessors::getFuncHash<ThisT, Endian>(this);
1106   }
1107 
1108   template <llvm::endianness Endian> uint64_t getDataSize() const {
1109     return accessors::getDataSize<ThisT, Endian>(this);
1110   }
1111 
1112   /// Return function lookup key. The value is consider opaque.
1113   template <llvm::endianness Endian> IntPtrT getFuncNameRef() const {
1114     return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
1115   }
1116 
1117   /// Return the PGO name of the function.
1118   template <llvm::endianness Endian>
1119   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1120     IntPtrT NameRef = getFuncNameRef<Endian>();
1121     uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
1122     FuncName = ProfileNames.getFuncName(NameRef, NameS);
1123     if (NameS && FuncName.empty())
1124       return make_error<CoverageMapError>(coveragemap_error::malformed,
1125                                           "function name is empty");
1126     return Error::success();
1127   }
1128 
1129   template <llvm::endianness Endian>
1130   std::pair<const char *, const ThisT *>
1131   advanceByOne(const char *MappingBuf) const {
1132     return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1133   }
1134 
1135   template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1136     llvm_unreachable("V1 function format does not contain a filenames ref");
1137   }
1138 
1139   template <llvm::endianness Endian>
1140   StringRef getCoverageMapping(const char *MappingBuf) const {
1141     return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1142                                                                  MappingBuf);
1143   }
1144 };
1145 
1146 struct CovMapFunctionRecordV2 {
1147   using ThisT = CovMapFunctionRecordV2;
1148 
1149 #define COVMAP_V2
1150 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1151 #include "llvm/ProfileData/InstrProfData.inc"
1152 #undef COVMAP_V2
1153   CovMapFunctionRecordV2() = delete;
1154 
1155   template <llvm::endianness Endian> uint64_t getFuncHash() const {
1156     return accessors::getFuncHash<ThisT, Endian>(this);
1157   }
1158 
1159   template <llvm::endianness Endian> uint64_t getDataSize() const {
1160     return accessors::getDataSize<ThisT, Endian>(this);
1161   }
1162 
1163   template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1164     return accessors::getFuncNameRef<ThisT, Endian>(this);
1165   }
1166 
1167   template <llvm::endianness Endian>
1168   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1169     return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1170                                                        FuncName);
1171   }
1172 
1173   template <llvm::endianness Endian>
1174   std::pair<const char *, const ThisT *>
1175   advanceByOne(const char *MappingBuf) const {
1176     return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1177   }
1178 
1179   template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1180     llvm_unreachable("V2 function format does not contain a filenames ref");
1181   }
1182 
1183   template <llvm::endianness Endian>
1184   StringRef getCoverageMapping(const char *MappingBuf) const {
1185     return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1186                                                                  MappingBuf);
1187   }
1188 };
1189 
1190 struct CovMapFunctionRecordV3 {
1191   using ThisT = CovMapFunctionRecordV3;
1192 
1193 #define COVMAP_V3
1194 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1195 #include "llvm/ProfileData/InstrProfData.inc"
1196 #undef COVMAP_V3
1197   CovMapFunctionRecordV3() = delete;
1198 
1199   template <llvm::endianness Endian> uint64_t getFuncHash() const {
1200     return accessors::getFuncHash<ThisT, Endian>(this);
1201   }
1202 
1203   template <llvm::endianness Endian> uint64_t getDataSize() const {
1204     return accessors::getDataSize<ThisT, Endian>(this);
1205   }
1206 
1207   template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1208     return accessors::getFuncNameRef<ThisT, Endian>(this);
1209   }
1210 
1211   template <llvm::endianness Endian>
1212   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1213     return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1214                                                        FuncName);
1215   }
1216 
1217   /// Get the filename set reference.
1218   template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1219     return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
1220   }
1221 
1222   /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
1223   /// out-of-line coverage mapping data only.
1224   template <llvm::endianness Endian>
1225   StringRef getCoverageMapping(const char *) const {
1226     return StringRef(&CoverageMapping, getDataSize<Endian>());
1227   }
1228 
1229   // Advance to the next inline coverage mapping and its associated function
1230   // record. Ignore the out-of-line coverage mapping buffer.
1231   template <llvm::endianness Endian>
1232   std::pair<const char *, const CovMapFunctionRecordV3 *>
1233   advanceByOne(const char *) const {
1234     assert(isAddrAligned(Align(8), this) && "Function record not aligned");
1235     const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
1236                        sizeof(char) + getDataSize<Endian>();
1237     // Each function record has an alignment of 8, so we need to adjust
1238     // alignment before reading the next record.
1239     Next += offsetToAlignedAddr(Next, Align(8));
1240     return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
1241   }
1242 };
1243 
1244 // Per module coverage mapping data header, i.e. CoverageMapFileHeader
1245 // documented above.
1246 struct CovMapHeader {
1247 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
1248 #include "llvm/ProfileData/InstrProfData.inc"
1249   template <llvm::endianness Endian> uint32_t getNRecords() const {
1250     return support::endian::byte_swap<uint32_t, Endian>(NRecords);
1251   }
1252 
1253   template <llvm::endianness Endian> uint32_t getFilenamesSize() const {
1254     return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
1255   }
1256 
1257   template <llvm::endianness Endian> uint32_t getCoverageSize() const {
1258     return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
1259   }
1260 
1261   template <llvm::endianness Endian> uint32_t getVersion() const {
1262     return support::endian::byte_swap<uint32_t, Endian>(Version);
1263   }
1264 };
1265 
1266 LLVM_PACKED_END
1267 
1268 enum CovMapVersion {
1269   Version1 = 0,
1270   // Function's name reference from CovMapFuncRecord is changed from raw
1271   // name string pointer to MD5 to support name section compression. Name
1272   // section is also compressed.
1273   Version2 = 1,
1274   // A new interpretation of the columnEnd field is added in order to mark
1275   // regions as gap areas.
1276   Version3 = 2,
1277   // Function records are named, uniqued, and moved to a dedicated section.
1278   Version4 = 3,
1279   // Branch regions referring to two counters are added
1280   Version5 = 4,
1281   // Compilation directory is stored separately and combined with relative
1282   // filenames to produce an absolute file path.
1283   Version6 = 5,
1284   // Branch regions extended and Decision Regions added for MC/DC.
1285   Version7 = 6,
1286   // The current version is Version7.
1287   CurrentVersion = INSTR_PROF_COVMAP_VERSION
1288 };
1289 
1290 // Correspond to "llvmcovm", in little-endian.
1291 constexpr uint64_t TestingFormatMagic = 0x6d766f636d766c6c;
1292 
1293 enum class TestingFormatVersion : uint64_t {
1294   // The first version's number corresponds to the string "testdata" in
1295   // little-endian. This is for a historical reason.
1296   Version1 = 0x6174616474736574,
1297   // Version1 has a defect that it can't store multiple file records. Version2
1298   // fix this problem by adding a new field before the file records section.
1299   Version2 = 1,
1300   // The current testing format version is Version2.
1301   CurrentVersion = Version2
1302 };
1303 
1304 template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
1305   using CovMapFuncRecordType = CovMapFunctionRecordV3;
1306   using NameRefType = uint64_t;
1307 };
1308 
1309 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
1310   using CovMapFuncRecordType = CovMapFunctionRecordV2;
1311   using NameRefType = uint64_t;
1312 };
1313 
1314 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
1315   using CovMapFuncRecordType = CovMapFunctionRecordV2;
1316   using NameRefType = uint64_t;
1317 };
1318 
1319 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
1320   using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>;
1321   using NameRefType = IntPtrT;
1322 };
1323 
1324 } // end namespace coverage
1325 
1326 /// Provide DenseMapInfo for CounterExpression
1327 template<> struct DenseMapInfo<coverage::CounterExpression> {
1328   static inline coverage::CounterExpression getEmptyKey() {
1329     using namespace coverage;
1330 
1331     return CounterExpression(CounterExpression::ExprKind::Subtract,
1332                              Counter::getCounter(~0U),
1333                              Counter::getCounter(~0U));
1334   }
1335 
1336   static inline coverage::CounterExpression getTombstoneKey() {
1337     using namespace coverage;
1338 
1339     return CounterExpression(CounterExpression::ExprKind::Add,
1340                              Counter::getCounter(~0U),
1341                              Counter::getCounter(~0U));
1342   }
1343 
1344   static unsigned getHashValue(const coverage::CounterExpression &V) {
1345     return static_cast<unsigned>(
1346         hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
1347                      V.RHS.getKind(), V.RHS.getCounterID()));
1348   }
1349 
1350   static bool isEqual(const coverage::CounterExpression &LHS,
1351                       const coverage::CounterExpression &RHS) {
1352     return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
1353   }
1354 };
1355 
1356 } // end namespace llvm
1357 
1358 #endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
1359