xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- 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 // Instrumentation-based code coverage mapping generator
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CoverageMappingGen.h"
14 #include "CodeGenFunction.h"
15 #include "CodeGenPGO.h"
16 #include "clang/AST/StmtVisitor.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Lex/Lexer.h"
19 #include "llvm/ADT/DenseSet.h"
20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
23 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
24 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
25 #include "llvm/Support/FileSystem.h"
26 #include "llvm/Support/Path.h"
27 #include <optional>
28 
29 // This selects the coverage mapping format defined when `InstrProfData.inc`
30 // is textually included.
31 #define COVMAP_V3
32 
33 namespace llvm {
34 cl::opt<bool>
35     EnableSingleByteCoverage("enable-single-byte-coverage",
36                              llvm::cl::ZeroOrMore,
37                              llvm::cl::desc("Enable single byte coverage"),
38                              llvm::cl::Hidden, llvm::cl::init(false));
39 } // namespace llvm
40 
41 static llvm::cl::opt<bool> EmptyLineCommentCoverage(
42     "emptyline-comment-coverage",
43     llvm::cl::desc("Emit emptylines and comment lines as skipped regions (only "
44                    "disable it on test)"),
45     llvm::cl::init(true), llvm::cl::Hidden);
46 
47 namespace llvm::coverage {
48 cl::opt<bool> SystemHeadersCoverage(
49     "system-headers-coverage",
50     cl::desc("Enable collecting coverage from system headers"), cl::init(false),
51     cl::Hidden);
52 }
53 
54 using namespace clang;
55 using namespace CodeGen;
56 using namespace llvm::coverage;
57 
58 CoverageSourceInfo *
59 CoverageMappingModuleGen::setUpCoverageCallbacks(Preprocessor &PP) {
60   CoverageSourceInfo *CoverageInfo =
61       new CoverageSourceInfo(PP.getSourceManager());
62   PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(CoverageInfo));
63   if (EmptyLineCommentCoverage) {
64     PP.addCommentHandler(CoverageInfo);
65     PP.setEmptylineHandler(CoverageInfo);
66     PP.setPreprocessToken(true);
67     PP.setTokenWatcher([CoverageInfo](clang::Token Tok) {
68       // Update previous token location.
69       CoverageInfo->PrevTokLoc = Tok.getLocation();
70       if (Tok.getKind() != clang::tok::eod)
71         CoverageInfo->updateNextTokLoc(Tok.getLocation());
72     });
73   }
74   return CoverageInfo;
75 }
76 
77 void CoverageSourceInfo::AddSkippedRange(SourceRange Range,
78                                          SkippedRange::Kind RangeKind) {
79   if (EmptyLineCommentCoverage && !SkippedRanges.empty() &&
80       PrevTokLoc == SkippedRanges.back().PrevTokLoc &&
81       SourceMgr.isWrittenInSameFile(SkippedRanges.back().Range.getEnd(),
82                                     Range.getBegin()))
83     SkippedRanges.back().Range.setEnd(Range.getEnd());
84   else
85     SkippedRanges.push_back({Range, RangeKind, PrevTokLoc});
86 }
87 
88 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range, SourceLocation) {
89   AddSkippedRange(Range, SkippedRange::PPIfElse);
90 }
91 
92 void CoverageSourceInfo::HandleEmptyline(SourceRange Range) {
93   AddSkippedRange(Range, SkippedRange::EmptyLine);
94 }
95 
96 bool CoverageSourceInfo::HandleComment(Preprocessor &PP, SourceRange Range) {
97   AddSkippedRange(Range, SkippedRange::Comment);
98   return false;
99 }
100 
101 void CoverageSourceInfo::updateNextTokLoc(SourceLocation Loc) {
102   if (!SkippedRanges.empty() && SkippedRanges.back().NextTokLoc.isInvalid())
103     SkippedRanges.back().NextTokLoc = Loc;
104 }
105 
106 namespace {
107 /// A region of source code that can be mapped to a counter.
108 class SourceMappingRegion {
109   /// Primary Counter that is also used for Branch Regions for "True" branches.
110   Counter Count;
111 
112   /// Secondary Counter used for Branch Regions for "False" branches.
113   std::optional<Counter> FalseCount;
114 
115   /// Parameters used for Modified Condition/Decision Coverage
116   mcdc::Parameters MCDCParams;
117 
118   /// The region's starting location.
119   std::optional<SourceLocation> LocStart;
120 
121   /// The region's ending location.
122   std::optional<SourceLocation> LocEnd;
123 
124   /// Whether this region is a gap region. The count from a gap region is set
125   /// as the line execution count if there are no other regions on the line.
126   bool GapRegion;
127 
128   /// Whetever this region is skipped ('if constexpr' or 'if consteval' untaken
129   /// branch, or anything skipped but not empty line / comments)
130   bool SkippedRegion;
131 
132 public:
133   SourceMappingRegion(Counter Count, std::optional<SourceLocation> LocStart,
134                       std::optional<SourceLocation> LocEnd,
135                       bool GapRegion = false)
136       : Count(Count), LocStart(LocStart), LocEnd(LocEnd), GapRegion(GapRegion),
137         SkippedRegion(false) {}
138 
139   SourceMappingRegion(Counter Count, std::optional<Counter> FalseCount,
140                       mcdc::Parameters MCDCParams,
141                       std::optional<SourceLocation> LocStart,
142                       std::optional<SourceLocation> LocEnd,
143                       bool GapRegion = false)
144       : Count(Count), FalseCount(FalseCount), MCDCParams(MCDCParams),
145         LocStart(LocStart), LocEnd(LocEnd), GapRegion(GapRegion),
146         SkippedRegion(false) {}
147 
148   SourceMappingRegion(mcdc::Parameters MCDCParams,
149                       std::optional<SourceLocation> LocStart,
150                       std::optional<SourceLocation> LocEnd)
151       : MCDCParams(MCDCParams), LocStart(LocStart), LocEnd(LocEnd),
152         GapRegion(false), SkippedRegion(false) {}
153 
154   const Counter &getCounter() const { return Count; }
155 
156   const Counter &getFalseCounter() const {
157     assert(FalseCount && "Region has no alternate counter");
158     return *FalseCount;
159   }
160 
161   void setCounter(Counter C) { Count = C; }
162 
163   bool hasStartLoc() const { return LocStart.has_value(); }
164 
165   void setStartLoc(SourceLocation Loc) { LocStart = Loc; }
166 
167   SourceLocation getBeginLoc() const {
168     assert(LocStart && "Region has no start location");
169     return *LocStart;
170   }
171 
172   bool hasEndLoc() const { return LocEnd.has_value(); }
173 
174   void setEndLoc(SourceLocation Loc) {
175     assert(Loc.isValid() && "Setting an invalid end location");
176     LocEnd = Loc;
177   }
178 
179   SourceLocation getEndLoc() const {
180     assert(LocEnd && "Region has no end location");
181     return *LocEnd;
182   }
183 
184   bool isGap() const { return GapRegion; }
185 
186   void setGap(bool Gap) { GapRegion = Gap; }
187 
188   bool isSkipped() const { return SkippedRegion; }
189 
190   void setSkipped(bool Skipped) { SkippedRegion = Skipped; }
191 
192   bool isBranch() const { return FalseCount.has_value(); }
193 
194   bool isMCDCBranch() const {
195     return std::holds_alternative<mcdc::BranchParameters>(MCDCParams);
196   }
197 
198   const auto &getMCDCBranchParams() const {
199     return mcdc::getParams<const mcdc::BranchParameters>(MCDCParams);
200   }
201 
202   bool isMCDCDecision() const {
203     return std::holds_alternative<mcdc::DecisionParameters>(MCDCParams);
204   }
205 
206   const auto &getMCDCDecisionParams() const {
207     return mcdc::getParams<const mcdc::DecisionParameters>(MCDCParams);
208   }
209 
210   const mcdc::Parameters &getMCDCParams() const { return MCDCParams; }
211 
212   void resetMCDCParams() { MCDCParams = mcdc::Parameters(); }
213 };
214 
215 /// Spelling locations for the start and end of a source region.
216 struct SpellingRegion {
217   /// The line where the region starts.
218   unsigned LineStart;
219 
220   /// The column where the region starts.
221   unsigned ColumnStart;
222 
223   /// The line where the region ends.
224   unsigned LineEnd;
225 
226   /// The column where the region ends.
227   unsigned ColumnEnd;
228 
229   SpellingRegion(SourceManager &SM, SourceLocation LocStart,
230                  SourceLocation LocEnd) {
231     LineStart = SM.getSpellingLineNumber(LocStart);
232     ColumnStart = SM.getSpellingColumnNumber(LocStart);
233     LineEnd = SM.getSpellingLineNumber(LocEnd);
234     ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
235   }
236 
237   SpellingRegion(SourceManager &SM, SourceMappingRegion &R)
238       : SpellingRegion(SM, R.getBeginLoc(), R.getEndLoc()) {}
239 
240   /// Check if the start and end locations appear in source order, i.e
241   /// top->bottom, left->right.
242   bool isInSourceOrder() const {
243     return (LineStart < LineEnd) ||
244            (LineStart == LineEnd && ColumnStart <= ColumnEnd);
245   }
246 };
247 
248 /// Provides the common functionality for the different
249 /// coverage mapping region builders.
250 class CoverageMappingBuilder {
251 public:
252   CoverageMappingModuleGen &CVM;
253   SourceManager &SM;
254   const LangOptions &LangOpts;
255 
256 private:
257   /// Map of clang's FileIDs to IDs used for coverage mapping.
258   llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
259       FileIDMapping;
260 
261 public:
262   /// The coverage mapping regions for this function
263   llvm::SmallVector<CounterMappingRegion, 32> MappingRegions;
264   /// The source mapping regions for this function.
265   std::vector<SourceMappingRegion> SourceRegions;
266 
267   /// A set of regions which can be used as a filter.
268   ///
269   /// It is produced by emitExpansionRegions() and is used in
270   /// emitSourceRegions() to suppress producing code regions if
271   /// the same area is covered by expansion regions.
272   typedef llvm::SmallSet<std::pair<SourceLocation, SourceLocation>, 8>
273       SourceRegionFilter;
274 
275   CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
276                          const LangOptions &LangOpts)
277       : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
278 
279   /// Return the precise end location for the given token.
280   SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
281     // We avoid getLocForEndOfToken here, because it doesn't do what we want for
282     // macro locations, which we just treat as expanded files.
283     unsigned TokLen =
284         Lexer::MeasureTokenLength(SM.getSpellingLoc(Loc), SM, LangOpts);
285     return Loc.getLocWithOffset(TokLen);
286   }
287 
288   /// Return the start location of an included file or expanded macro.
289   SourceLocation getStartOfFileOrMacro(SourceLocation Loc) {
290     if (Loc.isMacroID())
291       return Loc.getLocWithOffset(-SM.getFileOffset(Loc));
292     return SM.getLocForStartOfFile(SM.getFileID(Loc));
293   }
294 
295   /// Return the end location of an included file or expanded macro.
296   SourceLocation getEndOfFileOrMacro(SourceLocation Loc) {
297     if (Loc.isMacroID())
298       return Loc.getLocWithOffset(SM.getFileIDSize(SM.getFileID(Loc)) -
299                                   SM.getFileOffset(Loc));
300     return SM.getLocForEndOfFile(SM.getFileID(Loc));
301   }
302 
303   /// Find out where a macro is expanded. If the immediate result is a
304   /// <scratch space>, keep looking until the result isn't. Return a pair of
305   /// \c SourceLocation. The first object is always the begin sloc of found
306   /// result. The second should be checked by the caller: if it has value, it's
307   /// the end sloc of the found result. Otherwise the while loop didn't get
308   /// executed, which means the location wasn't changed and the caller has to
309   /// learn the end sloc from somewhere else.
310   std::pair<SourceLocation, std::optional<SourceLocation>>
311   getNonScratchExpansionLoc(SourceLocation Loc) {
312     std::optional<SourceLocation> EndLoc = std::nullopt;
313     while (Loc.isMacroID() &&
314            SM.isWrittenInScratchSpace(SM.getSpellingLoc(Loc))) {
315       auto ExpansionRange = SM.getImmediateExpansionRange(Loc);
316       Loc = ExpansionRange.getBegin();
317       EndLoc = ExpansionRange.getEnd();
318     }
319     return std::make_pair(Loc, EndLoc);
320   }
321 
322   /// Find out where the current file is included or macro is expanded. If
323   /// \c AcceptScratch is set to false, keep looking for expansions until the
324   /// found sloc is not a <scratch space>.
325   SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc,
326                                           bool AcceptScratch = true) {
327     if (!Loc.isMacroID())
328       return SM.getIncludeLoc(SM.getFileID(Loc));
329     Loc = SM.getImmediateExpansionRange(Loc).getBegin();
330     if (AcceptScratch)
331       return Loc;
332     return getNonScratchExpansionLoc(Loc).first;
333   }
334 
335   /// Return true if \c Loc is a location in a built-in macro.
336   bool isInBuiltin(SourceLocation Loc) {
337     return SM.getBufferName(SM.getSpellingLoc(Loc)) == "<built-in>";
338   }
339 
340   /// Check whether \c Loc is included or expanded from \c Parent.
341   bool isNestedIn(SourceLocation Loc, FileID Parent) {
342     do {
343       Loc = getIncludeOrExpansionLoc(Loc);
344       if (Loc.isInvalid())
345         return false;
346     } while (!SM.isInFileID(Loc, Parent));
347     return true;
348   }
349 
350   /// Get the start of \c S ignoring macro arguments and builtin macros.
351   SourceLocation getStart(const Stmt *S) {
352     SourceLocation Loc = S->getBeginLoc();
353     while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
354       Loc = SM.getImmediateExpansionRange(Loc).getBegin();
355     return Loc;
356   }
357 
358   /// Get the end of \c S ignoring macro arguments and builtin macros.
359   SourceLocation getEnd(const Stmt *S) {
360     SourceLocation Loc = S->getEndLoc();
361     while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
362       Loc = SM.getImmediateExpansionRange(Loc).getBegin();
363     return getPreciseTokenLocEnd(Loc);
364   }
365 
366   /// Find the set of files we have regions for and assign IDs
367   ///
368   /// Fills \c Mapping with the virtual file mapping needed to write out
369   /// coverage and collects the necessary file information to emit source and
370   /// expansion regions.
371   void gatherFileIDs(SmallVectorImpl<unsigned> &Mapping) {
372     FileIDMapping.clear();
373 
374     llvm::SmallSet<FileID, 8> Visited;
375     SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs;
376     for (auto &Region : SourceRegions) {
377       SourceLocation Loc = Region.getBeginLoc();
378 
379       // Replace Region with its definition if it is in <scratch space>.
380       auto NonScratchExpansionLoc = getNonScratchExpansionLoc(Loc);
381       auto EndLoc = NonScratchExpansionLoc.second;
382       if (EndLoc.has_value()) {
383         Loc = NonScratchExpansionLoc.first;
384         Region.setStartLoc(Loc);
385         Region.setEndLoc(EndLoc.value());
386       }
387 
388       // Replace Loc with FileLoc if it is expanded with system headers.
389       if (!SystemHeadersCoverage && SM.isInSystemMacro(Loc)) {
390         auto BeginLoc = SM.getSpellingLoc(Loc);
391         auto EndLoc = SM.getSpellingLoc(Region.getEndLoc());
392         if (SM.isWrittenInSameFile(BeginLoc, EndLoc)) {
393           Loc = SM.getFileLoc(Loc);
394           Region.setStartLoc(Loc);
395           Region.setEndLoc(SM.getFileLoc(Region.getEndLoc()));
396         }
397       }
398 
399       FileID File = SM.getFileID(Loc);
400       if (!Visited.insert(File).second)
401         continue;
402 
403       assert(SystemHeadersCoverage ||
404              !SM.isInSystemHeader(SM.getSpellingLoc(Loc)));
405 
406       unsigned Depth = 0;
407       for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
408            Parent.isValid(); Parent = getIncludeOrExpansionLoc(Parent))
409         ++Depth;
410       FileLocs.push_back(std::make_pair(Loc, Depth));
411     }
412     llvm::stable_sort(FileLocs, llvm::less_second());
413 
414     for (const auto &FL : FileLocs) {
415       SourceLocation Loc = FL.first;
416       FileID SpellingFile = SM.getDecomposedSpellingLoc(Loc).first;
417       auto Entry = SM.getFileEntryRefForID(SpellingFile);
418       if (!Entry)
419         continue;
420 
421       FileIDMapping[SM.getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
422       Mapping.push_back(CVM.getFileID(*Entry));
423     }
424   }
425 
426   /// Get the coverage mapping file ID for \c Loc.
427   ///
428   /// If such file id doesn't exist, return std::nullopt.
429   std::optional<unsigned> getCoverageFileID(SourceLocation Loc) {
430     auto Mapping = FileIDMapping.find(SM.getFileID(Loc));
431     if (Mapping != FileIDMapping.end())
432       return Mapping->second.first;
433     return std::nullopt;
434   }
435 
436   /// This shrinks the skipped range if it spans a line that contains a
437   /// non-comment token. If shrinking the skipped range would make it empty,
438   /// this returns std::nullopt.
439   /// Note this function can potentially be expensive because
440   /// getSpellingLineNumber uses getLineNumber, which is expensive.
441   std::optional<SpellingRegion> adjustSkippedRange(SourceManager &SM,
442                                                    SourceLocation LocStart,
443                                                    SourceLocation LocEnd,
444                                                    SourceLocation PrevTokLoc,
445                                                    SourceLocation NextTokLoc) {
446     SpellingRegion SR{SM, LocStart, LocEnd};
447     SR.ColumnStart = 1;
448     if (PrevTokLoc.isValid() && SM.isWrittenInSameFile(LocStart, PrevTokLoc) &&
449         SR.LineStart == SM.getSpellingLineNumber(PrevTokLoc))
450       SR.LineStart++;
451     if (NextTokLoc.isValid() && SM.isWrittenInSameFile(LocEnd, NextTokLoc) &&
452         SR.LineEnd == SM.getSpellingLineNumber(NextTokLoc)) {
453       SR.LineEnd--;
454       SR.ColumnEnd++;
455     }
456     if (SR.isInSourceOrder())
457       return SR;
458     return std::nullopt;
459   }
460 
461   /// Gather all the regions that were skipped by the preprocessor
462   /// using the constructs like #if or comments.
463   void gatherSkippedRegions() {
464     /// An array of the minimum lineStarts and the maximum lineEnds
465     /// for mapping regions from the appropriate source files.
466     llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges;
467     FileLineRanges.resize(
468         FileIDMapping.size(),
469         std::make_pair(std::numeric_limits<unsigned>::max(), 0));
470     for (const auto &R : MappingRegions) {
471       FileLineRanges[R.FileID].first =
472           std::min(FileLineRanges[R.FileID].first, R.LineStart);
473       FileLineRanges[R.FileID].second =
474           std::max(FileLineRanges[R.FileID].second, R.LineEnd);
475     }
476 
477     auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
478     for (auto &I : SkippedRanges) {
479       SourceRange Range = I.Range;
480       auto LocStart = Range.getBegin();
481       auto LocEnd = Range.getEnd();
482       assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
483              "region spans multiple files");
484 
485       auto CovFileID = getCoverageFileID(LocStart);
486       if (!CovFileID)
487         continue;
488       std::optional<SpellingRegion> SR;
489       if (I.isComment())
490         SR = adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc,
491                                 I.NextTokLoc);
492       else if (I.isPPIfElse() || I.isEmptyLine())
493         SR = {SM, LocStart, LocEnd};
494 
495       if (!SR)
496         continue;
497       auto Region = CounterMappingRegion::makeSkipped(
498           *CovFileID, SR->LineStart, SR->ColumnStart, SR->LineEnd,
499           SR->ColumnEnd);
500       // Make sure that we only collect the regions that are inside
501       // the source code of this function.
502       if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
503           Region.LineEnd <= FileLineRanges[*CovFileID].second)
504         MappingRegions.push_back(Region);
505     }
506   }
507 
508   /// Generate the coverage counter mapping regions from collected
509   /// source regions.
510   void emitSourceRegions(const SourceRegionFilter &Filter) {
511     for (const auto &Region : SourceRegions) {
512       assert(Region.hasEndLoc() && "incomplete region");
513 
514       SourceLocation LocStart = Region.getBeginLoc();
515       assert(SM.getFileID(LocStart).isValid() && "region in invalid file");
516 
517       // Ignore regions from system headers unless collecting coverage from
518       // system headers is explicitly enabled.
519       if (!SystemHeadersCoverage &&
520           SM.isInSystemHeader(SM.getSpellingLoc(LocStart))) {
521         assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() &&
522                "Don't suppress the condition in system headers");
523         continue;
524       }
525 
526       auto CovFileID = getCoverageFileID(LocStart);
527       // Ignore regions that don't have a file, such as builtin macros.
528       if (!CovFileID) {
529         assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() &&
530                "Don't suppress the condition in non-file regions");
531         continue;
532       }
533 
534       SourceLocation LocEnd = Region.getEndLoc();
535       assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
536              "region spans multiple files");
537 
538       // Don't add code regions for the area covered by expansion regions.
539       // This not only suppresses redundant regions, but sometimes prevents
540       // creating regions with wrong counters if, for example, a statement's
541       // body ends at the end of a nested macro.
542       if (Filter.count(std::make_pair(LocStart, LocEnd))) {
543         assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() &&
544                "Don't suppress the condition");
545         continue;
546       }
547 
548       // Find the spelling locations for the mapping region.
549       SpellingRegion SR{SM, LocStart, LocEnd};
550       assert(SR.isInSourceOrder() && "region start and end out of order");
551 
552       if (Region.isGap()) {
553         MappingRegions.push_back(CounterMappingRegion::makeGapRegion(
554             Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
555             SR.LineEnd, SR.ColumnEnd));
556       } else if (Region.isSkipped()) {
557         MappingRegions.push_back(CounterMappingRegion::makeSkipped(
558             *CovFileID, SR.LineStart, SR.ColumnStart, SR.LineEnd,
559             SR.ColumnEnd));
560       } else if (Region.isBranch()) {
561         MappingRegions.push_back(CounterMappingRegion::makeBranchRegion(
562             Region.getCounter(), Region.getFalseCounter(), *CovFileID,
563             SR.LineStart, SR.ColumnStart, SR.LineEnd, SR.ColumnEnd,
564             Region.getMCDCParams()));
565       } else if (Region.isMCDCDecision()) {
566         MappingRegions.push_back(CounterMappingRegion::makeDecisionRegion(
567             Region.getMCDCDecisionParams(), *CovFileID, SR.LineStart,
568             SR.ColumnStart, SR.LineEnd, SR.ColumnEnd));
569       } else {
570         MappingRegions.push_back(CounterMappingRegion::makeRegion(
571             Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
572             SR.LineEnd, SR.ColumnEnd));
573       }
574     }
575   }
576 
577   /// Generate expansion regions for each virtual file we've seen.
578   SourceRegionFilter emitExpansionRegions() {
579     SourceRegionFilter Filter;
580     for (const auto &FM : FileIDMapping) {
581       SourceLocation ExpandedLoc = FM.second.second;
582       SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc, false);
583       if (ParentLoc.isInvalid())
584         continue;
585 
586       auto ParentFileID = getCoverageFileID(ParentLoc);
587       if (!ParentFileID)
588         continue;
589       auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
590       assert(ExpandedFileID && "expansion in uncovered file");
591 
592       SourceLocation LocEnd = getPreciseTokenLocEnd(ParentLoc);
593       assert(SM.isWrittenInSameFile(ParentLoc, LocEnd) &&
594              "region spans multiple files");
595       Filter.insert(std::make_pair(ParentLoc, LocEnd));
596 
597       SpellingRegion SR{SM, ParentLoc, LocEnd};
598       assert(SR.isInSourceOrder() && "region start and end out of order");
599       MappingRegions.push_back(CounterMappingRegion::makeExpansion(
600           *ParentFileID, *ExpandedFileID, SR.LineStart, SR.ColumnStart,
601           SR.LineEnd, SR.ColumnEnd));
602     }
603     return Filter;
604   }
605 };
606 
607 /// Creates unreachable coverage regions for the functions that
608 /// are not emitted.
609 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
610   EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
611                               const LangOptions &LangOpts)
612       : CoverageMappingBuilder(CVM, SM, LangOpts) {}
613 
614   void VisitDecl(const Decl *D) {
615     if (!D->hasBody())
616       return;
617     auto Body = D->getBody();
618     SourceLocation Start = getStart(Body);
619     SourceLocation End = getEnd(Body);
620     if (!SM.isWrittenInSameFile(Start, End)) {
621       // Walk up to find the common ancestor.
622       // Correct the locations accordingly.
623       FileID StartFileID = SM.getFileID(Start);
624       FileID EndFileID = SM.getFileID(End);
625       while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
626         Start = getIncludeOrExpansionLoc(Start);
627         assert(Start.isValid() &&
628                "Declaration start location not nested within a known region");
629         StartFileID = SM.getFileID(Start);
630       }
631       while (StartFileID != EndFileID) {
632         End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
633         assert(End.isValid() &&
634                "Declaration end location not nested within a known region");
635         EndFileID = SM.getFileID(End);
636       }
637     }
638     SourceRegions.emplace_back(Counter(), Start, End);
639   }
640 
641   /// Write the mapping data to the output stream
642   void write(llvm::raw_ostream &OS) {
643     SmallVector<unsigned, 16> FileIDMapping;
644     gatherFileIDs(FileIDMapping);
645     emitSourceRegions(SourceRegionFilter());
646 
647     if (MappingRegions.empty())
648       return;
649 
650     CoverageMappingWriter Writer(FileIDMapping, {}, MappingRegions);
651     Writer.write(OS);
652   }
653 };
654 
655 /// A wrapper object for maintaining stacks to track the resursive AST visitor
656 /// walks for the purpose of assigning IDs to leaf-level conditions measured by
657 /// MC/DC. The object is created with a reference to the MCDCBitmapMap that was
658 /// created during the initial AST walk. The presence of a bitmap associated
659 /// with a boolean expression (top-level logical operator nest) indicates that
660 /// the boolean expression qualified for MC/DC.  The resulting condition IDs
661 /// are preserved in a map reference that is also provided during object
662 /// creation.
663 struct MCDCCoverageBuilder {
664 
665   /// The AST walk recursively visits nested logical-AND or logical-OR binary
666   /// operator nodes and then visits their LHS and RHS children nodes.  As this
667   /// happens, the algorithm will assign IDs to each operator's LHS and RHS side
668   /// as the walk moves deeper into the nest.  At each level of the recursive
669   /// nest, the LHS and RHS may actually correspond to larger subtrees (not
670   /// leaf-conditions). If this is the case, when that node is visited, the ID
671   /// assigned to the subtree is re-assigned to its LHS, and a new ID is given
672   /// to its RHS. At the end of the walk, all leaf-level conditions will have a
673   /// unique ID -- keep in mind that the final set of IDs may not be in
674   /// numerical order from left to right.
675   ///
676   /// Example: "x = (A && B) || (C && D) || (D && F)"
677   ///
678   ///      Visit Depth1:
679   ///              (A && B) || (C && D) || (D && F)
680   ///              ^-------LHS--------^    ^-RHS--^
681   ///                      ID=1              ID=2
682   ///
683   ///      Visit LHS-Depth2:
684   ///              (A && B) || (C && D)
685   ///              ^-LHS--^    ^-RHS--^
686   ///                ID=1        ID=3
687   ///
688   ///      Visit LHS-Depth3:
689   ///               (A && B)
690   ///               LHS   RHS
691   ///               ID=1  ID=4
692   ///
693   ///      Visit RHS-Depth3:
694   ///                         (C && D)
695   ///                         LHS   RHS
696   ///                         ID=3  ID=5
697   ///
698   ///      Visit RHS-Depth2:              (D && F)
699   ///                                     LHS   RHS
700   ///                                     ID=2  ID=6
701   ///
702   ///      Visit Depth1:
703   ///              (A && B)  || (C && D)  || (D && F)
704   ///              ID=1  ID=4   ID=3  ID=5   ID=2  ID=6
705   ///
706   /// A node ID of '0' always means MC/DC isn't being tracked.
707   ///
708   /// As the AST walk proceeds recursively, the algorithm will also use a stack
709   /// to track the IDs of logical-AND and logical-OR operations on the RHS so
710   /// that it can be determined which nodes are executed next, depending on how
711   /// a LHS or RHS of a logical-AND or logical-OR is evaluated.  This
712   /// information relies on the assigned IDs and are embedded within the
713   /// coverage region IDs of each branch region associated with a leaf-level
714   /// condition. This information helps the visualization tool reconstruct all
715   /// possible test vectors for the purposes of MC/DC analysis. If a "next" node
716   /// ID is '0', it means it's the end of the test vector. The following rules
717   /// are used:
718   ///
719   /// For logical-AND ("LHS && RHS"):
720   /// - If LHS is TRUE, execution goes to the RHS node.
721   /// - If LHS is FALSE, execution goes to the LHS node of the next logical-OR.
722   ///   If that does not exist, execution exits (ID == 0).
723   ///
724   /// - If RHS is TRUE, execution goes to LHS node of the next logical-AND.
725   ///   If that does not exist, execution exits (ID == 0).
726   /// - If RHS is FALSE, execution goes to the LHS node of the next logical-OR.
727   ///   If that does not exist, execution exits (ID == 0).
728   ///
729   /// For logical-OR ("LHS || RHS"):
730   /// - If LHS is TRUE, execution goes to the LHS node of the next logical-AND.
731   ///   If that does not exist, execution exits (ID == 0).
732   /// - If LHS is FALSE, execution goes to the RHS node.
733   ///
734   /// - If RHS is TRUE, execution goes to LHS node of the next logical-AND.
735   ///   If that does not exist, execution exits (ID == 0).
736   /// - If RHS is FALSE, execution goes to the LHS node of the next logical-OR.
737   ///   If that does not exist, execution exits (ID == 0).
738   ///
739   /// Finally, the condition IDs are also used when instrumenting the code to
740   /// indicate a unique offset into a temporary bitmap that represents the true
741   /// or false evaluation of that particular condition.
742   ///
743   /// NOTE regarding the use of CodeGenFunction::stripCond(). Even though, for
744   /// simplicity, parentheses and unary logical-NOT operators are considered
745   /// part of their underlying condition for both MC/DC and branch coverage, the
746   /// condition IDs themselves are assigned and tracked using the underlying
747   /// condition itself.  This is done solely for consistency since parentheses
748   /// and logical-NOTs are ignored when checking whether the condition is
749   /// actually an instrumentable condition. This can also make debugging a bit
750   /// easier.
751 
752 private:
753   CodeGenModule &CGM;
754 
755   llvm::SmallVector<mcdc::ConditionIDs> DecisionStack;
756   MCDC::State &MCDCState;
757   const Stmt *DecisionStmt = nullptr;
758   mcdc::ConditionID NextID = 0;
759   bool NotMapped = false;
760 
761   /// Represent a sentinel value as a pair of final decisions for the bottom
762   // of DecisionStack.
763   static constexpr mcdc::ConditionIDs DecisionStackSentinel{-1, -1};
764 
765   /// Is this a logical-AND operation?
766   bool isLAnd(const BinaryOperator *E) const {
767     return E->getOpcode() == BO_LAnd;
768   }
769 
770 public:
771   MCDCCoverageBuilder(CodeGenModule &CGM, MCDC::State &MCDCState)
772       : CGM(CGM), DecisionStack(1, DecisionStackSentinel),
773         MCDCState(MCDCState) {}
774 
775   /// Return whether the build of the control flow map is at the top-level
776   /// (root) of a logical operator nest in a boolean expression prior to the
777   /// assignment of condition IDs.
778   bool isIdle() const { return (NextID == 0 && !NotMapped); }
779 
780   /// Return whether any IDs have been assigned in the build of the control
781   /// flow map, indicating that the map is being generated for this boolean
782   /// expression.
783   bool isBuilding() const { return (NextID > 0); }
784 
785   /// Set the given condition's ID.
786   void setCondID(const Expr *Cond, mcdc::ConditionID ID) {
787     MCDCState.BranchByStmt[CodeGenFunction::stripCond(Cond)] = {ID,
788                                                                 DecisionStmt};
789   }
790 
791   /// Return the ID of a given condition.
792   mcdc::ConditionID getCondID(const Expr *Cond) const {
793     auto I = MCDCState.BranchByStmt.find(CodeGenFunction::stripCond(Cond));
794     if (I == MCDCState.BranchByStmt.end())
795       return -1;
796     else
797       return I->second.ID;
798   }
799 
800   /// Return the LHS Decision ([0,0] if not set).
801   const mcdc::ConditionIDs &back() const { return DecisionStack.back(); }
802 
803   /// Push the binary operator statement to track the nest level and assign IDs
804   /// to the operator's LHS and RHS.  The RHS may be a larger subtree that is
805   /// broken up on successive levels.
806   void pushAndAssignIDs(const BinaryOperator *E) {
807     if (!CGM.getCodeGenOpts().MCDCCoverage)
808       return;
809 
810     // If binary expression is disqualified, don't do mapping.
811     if (!isBuilding() &&
812         !MCDCState.DecisionByStmt.contains(CodeGenFunction::stripCond(E)))
813       NotMapped = true;
814 
815     // Don't go any further if we don't need to map condition IDs.
816     if (NotMapped)
817       return;
818 
819     if (NextID == 0) {
820       DecisionStmt = E;
821       assert(MCDCState.DecisionByStmt.contains(E));
822     }
823 
824     const mcdc::ConditionIDs &ParentDecision = DecisionStack.back();
825 
826     // If the operator itself has an assigned ID, this means it represents a
827     // larger subtree.  In this case, assign that ID to its LHS node.  Its RHS
828     // will receive a new ID below. Otherwise, assign ID+1 to LHS.
829     if (MCDCState.BranchByStmt.contains(CodeGenFunction::stripCond(E)))
830       setCondID(E->getLHS(), getCondID(E));
831     else
832       setCondID(E->getLHS(), NextID++);
833 
834     // Assign a ID+1 for the RHS.
835     mcdc::ConditionID RHSid = NextID++;
836     setCondID(E->getRHS(), RHSid);
837 
838     // Push the LHS decision IDs onto the DecisionStack.
839     if (isLAnd(E))
840       DecisionStack.push_back({ParentDecision[false], RHSid});
841     else
842       DecisionStack.push_back({RHSid, ParentDecision[true]});
843   }
844 
845   /// Pop and return the LHS Decision ([0,0] if not set).
846   mcdc::ConditionIDs pop() {
847     if (!CGM.getCodeGenOpts().MCDCCoverage || NotMapped)
848       return DecisionStackSentinel;
849 
850     assert(DecisionStack.size() > 1);
851     return DecisionStack.pop_back_val();
852   }
853 
854   /// Return the total number of conditions and reset the state. The number of
855   /// conditions is zero if the expression isn't mapped.
856   unsigned getTotalConditionsAndReset(const BinaryOperator *E) {
857     if (!CGM.getCodeGenOpts().MCDCCoverage)
858       return 0;
859 
860     assert(!isIdle());
861     assert(DecisionStack.size() == 1);
862 
863     // Reset state if not doing mapping.
864     if (NotMapped) {
865       NotMapped = false;
866       assert(NextID == 0);
867       return 0;
868     }
869 
870     // Set number of conditions and reset.
871     unsigned TotalConds = NextID;
872 
873     // Reset ID back to beginning.
874     NextID = 0;
875 
876     return TotalConds;
877   }
878 };
879 
880 /// A StmtVisitor that creates coverage mapping regions which map
881 /// from the source code locations to the PGO counters.
882 struct CounterCoverageMappingBuilder
883     : public CoverageMappingBuilder,
884       public ConstStmtVisitor<CounterCoverageMappingBuilder> {
885   /// The map of statements to count values.
886   llvm::DenseMap<const Stmt *, CounterPair> &CounterMap;
887 
888   MCDC::State &MCDCState;
889 
890   /// A stack of currently live regions.
891   llvm::SmallVector<SourceMappingRegion> RegionStack;
892 
893   /// Set if the Expr should be handled as a leaf even if it is kind of binary
894   /// logical ops (&&, ||).
895   llvm::DenseSet<const Stmt *> LeafExprSet;
896 
897   /// An object to manage MCDC regions.
898   MCDCCoverageBuilder MCDCBuilder;
899 
900   CounterExpressionBuilder Builder;
901 
902   /// A location in the most recently visited file or macro.
903   ///
904   /// This is used to adjust the active source regions appropriately when
905   /// expressions cross file or macro boundaries.
906   SourceLocation MostRecentLocation;
907 
908   /// Whether the visitor at a terminate statement.
909   bool HasTerminateStmt = false;
910 
911   /// Gap region counter after terminate statement.
912   Counter GapRegionCounter;
913 
914   /// Return a counter for the subtraction of \c RHS from \c LHS
915   Counter subtractCounters(Counter LHS, Counter RHS, bool Simplify = true) {
916     assert(!llvm::EnableSingleByteCoverage &&
917            "cannot add counters when single byte coverage mode is enabled");
918     return Builder.subtract(LHS, RHS, Simplify);
919   }
920 
921   /// Return a counter for the sum of \c LHS and \c RHS.
922   Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) {
923     return Builder.add(LHS, RHS, Simplify);
924   }
925 
926   Counter addCounters(Counter C1, Counter C2, Counter C3,
927                       bool Simplify = true) {
928     return addCounters(addCounters(C1, C2, Simplify), C3, Simplify);
929   }
930 
931   /// Return the region counter for the given statement.
932   ///
933   /// This should only be called on statements that have a dedicated counter.
934   Counter getRegionCounter(const Stmt *S) {
935     return Counter::getCounter(CounterMap[S].Executed);
936   }
937 
938   struct BranchCounterPair {
939     Counter Executed; ///< The Counter previously assigned.
940     Counter Skipped;  ///< An expression (Parent-Executed), or equivalent to it.
941   };
942 
943   /// Retrieve or assign the pair of Counter(s).
944   ///
945   /// This returns BranchCounterPair {Executed, Skipped}.
946   /// Executed is the Counter associated with S assigned by an earlier
947   /// CounterMapping pass.
948   /// Skipped may be an expression (Executed - ParentCnt) or newly
949   /// assigned Counter in EnableSingleByteCoverage, as subtract
950   /// expressions are not available in this mode.
951   ///
952   /// \param S Key to the CounterMap
953   /// \param ParentCnt The Counter representing how many times S is evaluated.
954   /// \param SkipCntForOld (To be removed later) Optional fake Counter
955   ///                      to override Skipped for adjustment of
956   ///                      expressions in the old behavior of
957   ///                      EnableSingleByteCoverage that is unaware of
958   ///                      Branch coverage.
959   BranchCounterPair
960   getBranchCounterPair(const Stmt *S, Counter ParentCnt,
961                        std::optional<Counter> SkipCntForOld = std::nullopt) {
962     Counter ExecCnt = getRegionCounter(S);
963 
964     // The old behavior of SingleByte is unaware of Branches.
965     // Will be pruned after the migration of SingleByte.
966     if (llvm::EnableSingleByteCoverage) {
967       assert(SkipCntForOld &&
968              "SingleByte must provide SkipCntForOld as a fake Skipped count.");
969       return {ExecCnt, *SkipCntForOld};
970     }
971 
972     return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)};
973   }
974 
975   bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
976     if (OutCount == ParentCount)
977       return true;
978 
979     return false;
980   }
981 
982   /// Push a region onto the stack.
983   ///
984   /// Returns the index on the stack where the region was pushed. This can be
985   /// used with popRegions to exit a "scope", ending the region that was pushed.
986   size_t pushRegion(Counter Count,
987                     std::optional<SourceLocation> StartLoc = std::nullopt,
988                     std::optional<SourceLocation> EndLoc = std::nullopt,
989                     std::optional<Counter> FalseCount = std::nullopt,
990                     const mcdc::Parameters &BranchParams = std::monostate()) {
991 
992     if (StartLoc && !FalseCount) {
993       MostRecentLocation = *StartLoc;
994     }
995 
996     // If either of these locations is invalid, something elsewhere in the
997     // compiler has broken.
998     assert((!StartLoc || StartLoc->isValid()) && "Start location is not valid");
999     assert((!EndLoc || EndLoc->isValid()) && "End location is not valid");
1000 
1001     // However, we can still recover without crashing.
1002     // If either location is invalid, set it to std::nullopt to avoid
1003     // letting users of RegionStack think that region has a valid start/end
1004     // location.
1005     if (StartLoc && StartLoc->isInvalid())
1006       StartLoc = std::nullopt;
1007     if (EndLoc && EndLoc->isInvalid())
1008       EndLoc = std::nullopt;
1009     RegionStack.emplace_back(Count, FalseCount, BranchParams, StartLoc, EndLoc);
1010 
1011     return RegionStack.size() - 1;
1012   }
1013 
1014   size_t pushRegion(const mcdc::DecisionParameters &DecisionParams,
1015                     std::optional<SourceLocation> StartLoc = std::nullopt,
1016                     std::optional<SourceLocation> EndLoc = std::nullopt) {
1017 
1018     RegionStack.emplace_back(DecisionParams, StartLoc, EndLoc);
1019 
1020     return RegionStack.size() - 1;
1021   }
1022 
1023   size_t locationDepth(SourceLocation Loc) {
1024     size_t Depth = 0;
1025     while (Loc.isValid()) {
1026       Loc = getIncludeOrExpansionLoc(Loc);
1027       Depth++;
1028     }
1029     return Depth;
1030   }
1031 
1032   /// Pop regions from the stack into the function's list of regions.
1033   ///
1034   /// Adds all regions from \c ParentIndex to the top of the stack to the
1035   /// function's \c SourceRegions.
1036   void popRegions(size_t ParentIndex) {
1037     assert(RegionStack.size() >= ParentIndex && "parent not in stack");
1038     while (RegionStack.size() > ParentIndex) {
1039       SourceMappingRegion &Region = RegionStack.back();
1040       if (Region.hasStartLoc() &&
1041           (Region.hasEndLoc() || RegionStack[ParentIndex].hasEndLoc())) {
1042         SourceLocation StartLoc = Region.getBeginLoc();
1043         SourceLocation EndLoc = Region.hasEndLoc()
1044                                     ? Region.getEndLoc()
1045                                     : RegionStack[ParentIndex].getEndLoc();
1046         bool isBranch = Region.isBranch();
1047         size_t StartDepth = locationDepth(StartLoc);
1048         size_t EndDepth = locationDepth(EndLoc);
1049         while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) {
1050           bool UnnestStart = StartDepth >= EndDepth;
1051           bool UnnestEnd = EndDepth >= StartDepth;
1052           if (UnnestEnd) {
1053             // The region ends in a nested file or macro expansion. If the
1054             // region is not a branch region, create a separate region for each
1055             // expansion, and for all regions, update the EndLoc. Branch
1056             // regions should not be split in order to keep a straightforward
1057             // correspondance between the region and its associated branch
1058             // condition, even if the condition spans multiple depths.
1059             SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
1060             assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
1061 
1062             if (!isBranch && !isRegionAlreadyAdded(NestedLoc, EndLoc))
1063               SourceRegions.emplace_back(Region.getCounter(), NestedLoc,
1064                                          EndLoc);
1065 
1066             EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
1067             if (EndLoc.isInvalid())
1068               llvm::report_fatal_error(
1069                   "File exit not handled before popRegions");
1070             EndDepth--;
1071           }
1072           if (UnnestStart) {
1073             // The region ends in a nested file or macro expansion. If the
1074             // region is not a branch region, create a separate region for each
1075             // expansion, and for all regions, update the StartLoc. Branch
1076             // regions should not be split in order to keep a straightforward
1077             // correspondance between the region and its associated branch
1078             // condition, even if the condition spans multiple depths.
1079             SourceLocation NestedLoc = getEndOfFileOrMacro(StartLoc);
1080             assert(SM.isWrittenInSameFile(StartLoc, NestedLoc));
1081 
1082             if (!isBranch && !isRegionAlreadyAdded(StartLoc, NestedLoc))
1083               SourceRegions.emplace_back(Region.getCounter(), StartLoc,
1084                                          NestedLoc);
1085 
1086             StartLoc = getIncludeOrExpansionLoc(StartLoc);
1087             if (StartLoc.isInvalid())
1088               llvm::report_fatal_error(
1089                   "File exit not handled before popRegions");
1090             StartDepth--;
1091           }
1092         }
1093         Region.setStartLoc(StartLoc);
1094         Region.setEndLoc(EndLoc);
1095 
1096         if (!isBranch) {
1097           MostRecentLocation = EndLoc;
1098           // If this region happens to span an entire expansion, we need to
1099           // make sure we don't overlap the parent region with it.
1100           if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
1101               EndLoc == getEndOfFileOrMacro(EndLoc))
1102             MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
1103         }
1104 
1105         assert(SM.isWrittenInSameFile(Region.getBeginLoc(), EndLoc));
1106         assert(SpellingRegion(SM, Region).isInSourceOrder());
1107         SourceRegions.push_back(Region);
1108       }
1109       RegionStack.pop_back();
1110     }
1111   }
1112 
1113   /// Return the currently active region.
1114   SourceMappingRegion &getRegion() {
1115     assert(!RegionStack.empty() && "statement has no region");
1116     return RegionStack.back();
1117   }
1118 
1119   /// Propagate counts through the children of \p S if \p VisitChildren is true.
1120   /// Otherwise, only emit a count for \p S itself.
1121   Counter propagateCounts(Counter TopCount, const Stmt *S,
1122                           bool VisitChildren = true) {
1123     SourceLocation StartLoc = getStart(S);
1124     SourceLocation EndLoc = getEnd(S);
1125     size_t Index = pushRegion(TopCount, StartLoc, EndLoc);
1126     if (VisitChildren)
1127       Visit(S);
1128     Counter ExitCount = getRegion().getCounter();
1129     popRegions(Index);
1130 
1131     // The statement may be spanned by an expansion. Make sure we handle a file
1132     // exit out of this expansion before moving to the next statement.
1133     if (SM.isBeforeInTranslationUnit(StartLoc, S->getBeginLoc()))
1134       MostRecentLocation = EndLoc;
1135 
1136     return ExitCount;
1137   }
1138 
1139   /// Create a Branch Region around an instrumentable condition for coverage
1140   /// and add it to the function's SourceRegions.  A branch region tracks a
1141   /// "True" counter and a "False" counter for boolean expressions that
1142   /// result in the generation of a branch.
1143   void createBranchRegion(const Expr *C, Counter TrueCnt, Counter FalseCnt,
1144                           const mcdc::ConditionIDs &Conds = {}) {
1145     // Check for NULL conditions.
1146     if (!C)
1147       return;
1148 
1149     // Ensure we are an instrumentable condition (i.e. no "&&" or "||").  Push
1150     // region onto RegionStack but immediately pop it (which adds it to the
1151     // function's SourceRegions) because it doesn't apply to any other source
1152     // code other than the Condition.
1153     // With !SystemHeadersCoverage, binary logical ops in system headers may be
1154     // treated as instrumentable conditions.
1155     if (CodeGenFunction::isInstrumentedCondition(C) ||
1156         LeafExprSet.count(CodeGenFunction::stripCond(C))) {
1157       mcdc::Parameters BranchParams;
1158       mcdc::ConditionID ID = MCDCBuilder.getCondID(C);
1159       if (ID >= 0)
1160         BranchParams = mcdc::BranchParameters{ID, Conds};
1161 
1162       // If a condition can fold to true or false, the corresponding branch
1163       // will be removed.  Create a region with both counters hard-coded to
1164       // zero. This allows us to visualize them in a special way.
1165       // Alternatively, we can prevent any optimization done via
1166       // constant-folding by ensuring that ConstantFoldsToSimpleInteger() in
1167       // CodeGenFunction.c always returns false, but that is very heavy-handed.
1168       Expr::EvalResult Result;
1169       if (C->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext())) {
1170         if (Result.Val.getInt().getBoolValue())
1171           FalseCnt = Counter::getZero();
1172         else
1173           TrueCnt = Counter::getZero();
1174       }
1175       popRegions(
1176           pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt, BranchParams));
1177     }
1178   }
1179 
1180   /// Create a Decision Region with a BitmapIdx and number of Conditions. This
1181   /// type of region "contains" branch regions, one for each of the conditions.
1182   /// The visualization tool will group everything together.
1183   void createDecisionRegion(const Expr *C,
1184                             const mcdc::DecisionParameters &DecisionParams) {
1185     popRegions(pushRegion(DecisionParams, getStart(C), getEnd(C)));
1186   }
1187 
1188   /// Create a Branch Region around a SwitchCase for code coverage
1189   /// and add it to the function's SourceRegions.
1190   /// Returns Counter that corresponds to SC.
1191   Counter createSwitchCaseRegion(const SwitchCase *SC, Counter ParentCount) {
1192     // Push region onto RegionStack but immediately pop it (which adds it to
1193     // the function's SourceRegions) because it doesn't apply to any other
1194     // source other than the SwitchCase.
1195     Counter TrueCnt = getRegionCounter(SC);
1196     popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(),
1197                           subtractCounters(ParentCount, TrueCnt)));
1198     return TrueCnt;
1199   }
1200 
1201   /// Check whether a region with bounds \c StartLoc and \c EndLoc
1202   /// is already added to \c SourceRegions.
1203   bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc,
1204                             bool isBranch = false) {
1205     return llvm::any_of(
1206         llvm::reverse(SourceRegions), [&](const SourceMappingRegion &Region) {
1207           return Region.getBeginLoc() == StartLoc &&
1208                  Region.getEndLoc() == EndLoc && Region.isBranch() == isBranch;
1209         });
1210   }
1211 
1212   /// Adjust the most recently visited location to \c EndLoc.
1213   ///
1214   /// This should be used after visiting any statements in non-source order.
1215   void adjustForOutOfOrderTraversal(SourceLocation EndLoc) {
1216     MostRecentLocation = EndLoc;
1217     // The code region for a whole macro is created in handleFileExit() when
1218     // it detects exiting of the virtual file of that macro. If we visited
1219     // statements in non-source order, we might already have such a region
1220     // added, for example, if a body of a loop is divided among multiple
1221     // macros. Avoid adding duplicate regions in such case.
1222     if (getRegion().hasEndLoc() &&
1223         MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
1224         isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
1225                              MostRecentLocation, getRegion().isBranch()))
1226       MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
1227   }
1228 
1229   /// Adjust regions and state when \c NewLoc exits a file.
1230   ///
1231   /// If moving from our most recently tracked location to \c NewLoc exits any
1232   /// files, this adjusts our current region stack and creates the file regions
1233   /// for the exited file.
1234   void handleFileExit(SourceLocation NewLoc) {
1235     if (NewLoc.isInvalid() ||
1236         SM.isWrittenInSameFile(MostRecentLocation, NewLoc))
1237       return;
1238 
1239     // If NewLoc is not in a file that contains MostRecentLocation, walk up to
1240     // find the common ancestor.
1241     SourceLocation LCA = NewLoc;
1242     FileID ParentFile = SM.getFileID(LCA);
1243     while (!isNestedIn(MostRecentLocation, ParentFile)) {
1244       LCA = getIncludeOrExpansionLoc(LCA);
1245       if (LCA.isInvalid() || SM.isWrittenInSameFile(LCA, MostRecentLocation)) {
1246         // Since there isn't a common ancestor, no file was exited. We just need
1247         // to adjust our location to the new file.
1248         MostRecentLocation = NewLoc;
1249         return;
1250       }
1251       ParentFile = SM.getFileID(LCA);
1252     }
1253 
1254     llvm::SmallSet<SourceLocation, 8> StartLocs;
1255     std::optional<Counter> ParentCounter;
1256     for (SourceMappingRegion &I : llvm::reverse(RegionStack)) {
1257       if (!I.hasStartLoc())
1258         continue;
1259       SourceLocation Loc = I.getBeginLoc();
1260       if (!isNestedIn(Loc, ParentFile)) {
1261         ParentCounter = I.getCounter();
1262         break;
1263       }
1264 
1265       while (!SM.isInFileID(Loc, ParentFile)) {
1266         // The most nested region for each start location is the one with the
1267         // correct count. We avoid creating redundant regions by stopping once
1268         // we've seen this region.
1269         if (StartLocs.insert(Loc).second) {
1270           if (I.isBranch())
1271             SourceRegions.emplace_back(I.getCounter(), I.getFalseCounter(),
1272                                        I.getMCDCParams(), Loc,
1273                                        getEndOfFileOrMacro(Loc), I.isBranch());
1274           else
1275             SourceRegions.emplace_back(I.getCounter(), Loc,
1276                                        getEndOfFileOrMacro(Loc));
1277         }
1278         Loc = getIncludeOrExpansionLoc(Loc);
1279       }
1280       I.setStartLoc(getPreciseTokenLocEnd(Loc));
1281     }
1282 
1283     if (ParentCounter) {
1284       // If the file is contained completely by another region and doesn't
1285       // immediately start its own region, the whole file gets a region
1286       // corresponding to the parent.
1287       SourceLocation Loc = MostRecentLocation;
1288       while (isNestedIn(Loc, ParentFile)) {
1289         SourceLocation FileStart = getStartOfFileOrMacro(Loc);
1290         if (StartLocs.insert(FileStart).second) {
1291           SourceRegions.emplace_back(*ParentCounter, FileStart,
1292                                      getEndOfFileOrMacro(Loc));
1293           assert(SpellingRegion(SM, SourceRegions.back()).isInSourceOrder());
1294         }
1295         Loc = getIncludeOrExpansionLoc(Loc);
1296       }
1297     }
1298 
1299     MostRecentLocation = NewLoc;
1300   }
1301 
1302   /// Ensure that \c S is included in the current region.
1303   void extendRegion(const Stmt *S) {
1304     SourceMappingRegion &Region = getRegion();
1305     SourceLocation StartLoc = getStart(S);
1306 
1307     handleFileExit(StartLoc);
1308     if (!Region.hasStartLoc())
1309       Region.setStartLoc(StartLoc);
1310   }
1311 
1312   /// Mark \c S as a terminator, starting a zero region.
1313   void terminateRegion(const Stmt *S) {
1314     extendRegion(S);
1315     SourceMappingRegion &Region = getRegion();
1316     SourceLocation EndLoc = getEnd(S);
1317     if (!Region.hasEndLoc())
1318       Region.setEndLoc(EndLoc);
1319     pushRegion(Counter::getZero());
1320     HasTerminateStmt = true;
1321   }
1322 
1323   /// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
1324   std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc,
1325                                                 SourceLocation BeforeLoc) {
1326     // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't
1327     // have valid source locations. Do not emit a gap region if this is the case
1328     // in either AfterLoc end or BeforeLoc end.
1329     if (AfterLoc.isInvalid() || BeforeLoc.isInvalid())
1330       return std::nullopt;
1331 
1332     // If AfterLoc is in function-like macro, use the right parenthesis
1333     // location.
1334     if (AfterLoc.isMacroID()) {
1335       FileID FID = SM.getFileID(AfterLoc);
1336       const SrcMgr::ExpansionInfo *EI = &SM.getSLocEntry(FID).getExpansion();
1337       if (EI->isFunctionMacroExpansion())
1338         AfterLoc = EI->getExpansionLocEnd();
1339     }
1340 
1341     size_t StartDepth = locationDepth(AfterLoc);
1342     size_t EndDepth = locationDepth(BeforeLoc);
1343     while (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc)) {
1344       bool UnnestStart = StartDepth >= EndDepth;
1345       bool UnnestEnd = EndDepth >= StartDepth;
1346       if (UnnestEnd) {
1347         assert(SM.isWrittenInSameFile(getStartOfFileOrMacro(BeforeLoc),
1348                                       BeforeLoc));
1349 
1350         BeforeLoc = getIncludeOrExpansionLoc(BeforeLoc);
1351         assert(BeforeLoc.isValid());
1352         EndDepth--;
1353       }
1354       if (UnnestStart) {
1355         assert(SM.isWrittenInSameFile(AfterLoc,
1356                                       getEndOfFileOrMacro(AfterLoc)));
1357 
1358         AfterLoc = getIncludeOrExpansionLoc(AfterLoc);
1359         assert(AfterLoc.isValid());
1360         AfterLoc = getPreciseTokenLocEnd(AfterLoc);
1361         assert(AfterLoc.isValid());
1362         StartDepth--;
1363       }
1364     }
1365     AfterLoc = getPreciseTokenLocEnd(AfterLoc);
1366     // If the start and end locations of the gap are both within the same macro
1367     // file, the range may not be in source order.
1368     if (AfterLoc.isMacroID() || BeforeLoc.isMacroID())
1369       return std::nullopt;
1370     if (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc) ||
1371         !SpellingRegion(SM, AfterLoc, BeforeLoc).isInSourceOrder())
1372       return std::nullopt;
1373     return {{AfterLoc, BeforeLoc}};
1374   }
1375 
1376   /// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
1377   void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc,
1378                             Counter Count) {
1379     if (StartLoc == EndLoc)
1380       return;
1381     assert(SpellingRegion(SM, StartLoc, EndLoc).isInSourceOrder());
1382     handleFileExit(StartLoc);
1383     size_t Index = pushRegion(Count, StartLoc, EndLoc);
1384     getRegion().setGap(true);
1385     handleFileExit(EndLoc);
1386     popRegions(Index);
1387   }
1388 
1389   /// Find a valid range starting with \p StartingLoc and ending before \p
1390   /// BeforeLoc.
1391   std::optional<SourceRange> findAreaStartingFromTo(SourceLocation StartingLoc,
1392                                                     SourceLocation BeforeLoc) {
1393     // If StartingLoc is in function-like macro, use its start location.
1394     if (StartingLoc.isMacroID()) {
1395       FileID FID = SM.getFileID(StartingLoc);
1396       const SrcMgr::ExpansionInfo *EI = &SM.getSLocEntry(FID).getExpansion();
1397       if (EI->isFunctionMacroExpansion())
1398         StartingLoc = EI->getExpansionLocStart();
1399     }
1400 
1401     size_t StartDepth = locationDepth(StartingLoc);
1402     size_t EndDepth = locationDepth(BeforeLoc);
1403     while (!SM.isWrittenInSameFile(StartingLoc, BeforeLoc)) {
1404       bool UnnestStart = StartDepth >= EndDepth;
1405       bool UnnestEnd = EndDepth >= StartDepth;
1406       if (UnnestEnd) {
1407         assert(SM.isWrittenInSameFile(getStartOfFileOrMacro(BeforeLoc),
1408                                       BeforeLoc));
1409 
1410         BeforeLoc = getIncludeOrExpansionLoc(BeforeLoc);
1411         assert(BeforeLoc.isValid());
1412         EndDepth--;
1413       }
1414       if (UnnestStart) {
1415         assert(SM.isWrittenInSameFile(StartingLoc,
1416                                       getStartOfFileOrMacro(StartingLoc)));
1417 
1418         StartingLoc = getIncludeOrExpansionLoc(StartingLoc);
1419         assert(StartingLoc.isValid());
1420         StartDepth--;
1421       }
1422     }
1423     // If the start and end locations of the gap are both within the same macro
1424     // file, the range may not be in source order.
1425     if (StartingLoc.isMacroID() || BeforeLoc.isMacroID())
1426       return std::nullopt;
1427     if (!SM.isWrittenInSameFile(StartingLoc, BeforeLoc) ||
1428         !SpellingRegion(SM, StartingLoc, BeforeLoc).isInSourceOrder())
1429       return std::nullopt;
1430     return {{StartingLoc, BeforeLoc}};
1431   }
1432 
1433   void markSkipped(SourceLocation StartLoc, SourceLocation BeforeLoc) {
1434     const auto Skipped = findAreaStartingFromTo(StartLoc, BeforeLoc);
1435 
1436     if (!Skipped)
1437       return;
1438 
1439     const auto NewStartLoc = Skipped->getBegin();
1440     const auto EndLoc = Skipped->getEnd();
1441 
1442     if (NewStartLoc == EndLoc)
1443       return;
1444     assert(SpellingRegion(SM, NewStartLoc, EndLoc).isInSourceOrder());
1445     handleFileExit(NewStartLoc);
1446     size_t Index = pushRegion(Counter{}, NewStartLoc, EndLoc);
1447     getRegion().setSkipped(true);
1448     handleFileExit(EndLoc);
1449     popRegions(Index);
1450   }
1451 
1452   /// Keep counts of breaks and continues inside loops.
1453   struct BreakContinue {
1454     Counter BreakCount;
1455     Counter ContinueCount;
1456   };
1457   SmallVector<BreakContinue, 8> BreakContinueStack;
1458 
1459   CounterCoverageMappingBuilder(
1460       CoverageMappingModuleGen &CVM,
1461       llvm::DenseMap<const Stmt *, CounterPair> &CounterMap,
1462       MCDC::State &MCDCState, SourceManager &SM, const LangOptions &LangOpts)
1463       : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
1464         MCDCState(MCDCState), MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {}
1465 
1466   /// Write the mapping data to the output stream
1467   void write(llvm::raw_ostream &OS) {
1468     llvm::SmallVector<unsigned, 8> VirtualFileMapping;
1469     gatherFileIDs(VirtualFileMapping);
1470     SourceRegionFilter Filter = emitExpansionRegions();
1471     emitSourceRegions(Filter);
1472     gatherSkippedRegions();
1473 
1474     if (MappingRegions.empty())
1475       return;
1476 
1477     CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(),
1478                                  MappingRegions);
1479     Writer.write(OS);
1480   }
1481 
1482   void VisitStmt(const Stmt *S) {
1483     if (S->getBeginLoc().isValid())
1484       extendRegion(S);
1485     const Stmt *LastStmt = nullptr;
1486     bool SaveTerminateStmt = HasTerminateStmt;
1487     HasTerminateStmt = false;
1488     GapRegionCounter = Counter::getZero();
1489     for (const Stmt *Child : S->children())
1490       if (Child) {
1491         // If last statement contains terminate statements, add a gap area
1492         // between the two statements.
1493         if (LastStmt && HasTerminateStmt) {
1494           auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child));
1495           if (Gap)
1496             fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(),
1497                                  GapRegionCounter);
1498           SaveTerminateStmt = true;
1499           HasTerminateStmt = false;
1500         }
1501         this->Visit(Child);
1502         LastStmt = Child;
1503       }
1504     if (SaveTerminateStmt)
1505       HasTerminateStmt = true;
1506     handleFileExit(getEnd(S));
1507   }
1508 
1509   void VisitStmtExpr(const StmtExpr *E) {
1510     Visit(E->getSubStmt());
1511     // Any region termination (such as a noreturn CallExpr) within the statement
1512     // expression has been handled by visiting the sub-statement. The visitor
1513     // cannot be at a terminate statement leaving the statement expression.
1514     HasTerminateStmt = false;
1515   }
1516 
1517   void VisitDecl(const Decl *D) {
1518     Stmt *Body = D->getBody();
1519 
1520     // Do not propagate region counts into system headers unless collecting
1521     // coverage from system headers is explicitly enabled.
1522     if (!SystemHeadersCoverage && Body &&
1523         SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
1524       return;
1525 
1526     // Do not visit the artificial children nodes of defaulted methods. The
1527     // lexer may not be able to report back precise token end locations for
1528     // these children nodes (llvm.org/PR39822), and moreover users will not be
1529     // able to see coverage for them.
1530     Counter BodyCounter = getRegionCounter(Body);
1531     bool Defaulted = false;
1532     if (auto *Method = dyn_cast<CXXMethodDecl>(D))
1533       Defaulted = Method->isDefaulted();
1534     if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1535       for (auto *Initializer : Ctor->inits()) {
1536         if (Initializer->isWritten()) {
1537           auto *Init = Initializer->getInit();
1538           if (getStart(Init).isValid() && getEnd(Init).isValid())
1539             propagateCounts(BodyCounter, Init);
1540         }
1541       }
1542     }
1543 
1544     propagateCounts(BodyCounter, Body,
1545                     /*VisitChildren=*/!Defaulted);
1546     assert(RegionStack.empty() && "Regions entered but never exited");
1547   }
1548 
1549   void VisitReturnStmt(const ReturnStmt *S) {
1550     extendRegion(S);
1551     if (S->getRetValue())
1552       Visit(S->getRetValue());
1553     terminateRegion(S);
1554   }
1555 
1556   void VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
1557     extendRegion(S);
1558     Visit(S->getBody());
1559   }
1560 
1561   void VisitCoreturnStmt(const CoreturnStmt *S) {
1562     extendRegion(S);
1563     if (S->getOperand())
1564       Visit(S->getOperand());
1565     terminateRegion(S);
1566   }
1567 
1568   void VisitCoroutineSuspendExpr(const CoroutineSuspendExpr *E) {
1569     Visit(E->getOperand());
1570   }
1571 
1572   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
1573     extendRegion(E);
1574     if (E->getSubExpr())
1575       Visit(E->getSubExpr());
1576     terminateRegion(E);
1577   }
1578 
1579   void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
1580 
1581   void VisitLabelStmt(const LabelStmt *S) {
1582     Counter LabelCount = getRegionCounter(S);
1583     SourceLocation Start = getStart(S);
1584     // We can't extendRegion here or we risk overlapping with our new region.
1585     handleFileExit(Start);
1586     pushRegion(LabelCount, Start);
1587     Visit(S->getSubStmt());
1588   }
1589 
1590   void VisitBreakStmt(const BreakStmt *S) {
1591     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
1592     if (!llvm::EnableSingleByteCoverage)
1593       BreakContinueStack.back().BreakCount = addCounters(
1594           BreakContinueStack.back().BreakCount, getRegion().getCounter());
1595     // FIXME: a break in a switch should terminate regions for all preceding
1596     // case statements, not just the most recent one.
1597     terminateRegion(S);
1598   }
1599 
1600   void VisitContinueStmt(const ContinueStmt *S) {
1601     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
1602     if (!llvm::EnableSingleByteCoverage)
1603       BreakContinueStack.back().ContinueCount = addCounters(
1604           BreakContinueStack.back().ContinueCount, getRegion().getCounter());
1605     terminateRegion(S);
1606   }
1607 
1608   void VisitCallExpr(const CallExpr *E) {
1609     VisitStmt(E);
1610 
1611     // Terminate the region when we hit a noreturn function.
1612     // (This is helpful dealing with switch statements.)
1613     QualType CalleeType = E->getCallee()->getType();
1614     if (getFunctionExtInfo(*CalleeType).getNoReturn())
1615       terminateRegion(E);
1616   }
1617 
1618   void VisitWhileStmt(const WhileStmt *S) {
1619     extendRegion(S);
1620 
1621     Counter ParentCount = getRegion().getCounter();
1622     Counter BodyCount = llvm::EnableSingleByteCoverage
1623                             ? getRegionCounter(S->getBody())
1624                             : getRegionCounter(S);
1625 
1626     // Handle the body first so that we can get the backedge count.
1627     BreakContinueStack.push_back(BreakContinue());
1628     extendRegion(S->getBody());
1629     Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1630     BreakContinue BC = BreakContinueStack.pop_back_val();
1631 
1632     bool BodyHasTerminateStmt = HasTerminateStmt;
1633     HasTerminateStmt = false;
1634 
1635     // Go back to handle the condition.
1636     Counter CondCount =
1637         llvm::EnableSingleByteCoverage
1638             ? getRegionCounter(S->getCond())
1639             : addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1640     auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S));
1641     assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount ||
1642            llvm::EnableSingleByteCoverage);
1643 
1644     propagateCounts(CondCount, S->getCond());
1645     adjustForOutOfOrderTraversal(getEnd(S));
1646 
1647     // The body count applies to the area immediately after the increment.
1648     auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
1649     if (Gap)
1650       fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1651 
1652     assert(
1653         !llvm::EnableSingleByteCoverage ||
1654         (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S)));
1655     Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped);
1656     if (!IsCounterEqual(OutCount, ParentCount)) {
1657       pushRegion(OutCount);
1658       GapRegionCounter = OutCount;
1659       if (BodyHasTerminateStmt)
1660         HasTerminateStmt = true;
1661     }
1662 
1663     // Create Branch Region around condition.
1664     if (!llvm::EnableSingleByteCoverage)
1665       createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped);
1666   }
1667 
1668   void VisitDoStmt(const DoStmt *S) {
1669     extendRegion(S);
1670 
1671     Counter ParentCount = getRegion().getCounter();
1672     Counter BodyCount = llvm::EnableSingleByteCoverage
1673                             ? getRegionCounter(S->getBody())
1674                             : getRegionCounter(S);
1675 
1676     BreakContinueStack.push_back(BreakContinue());
1677     extendRegion(S->getBody());
1678 
1679     Counter BackedgeCount;
1680     if (llvm::EnableSingleByteCoverage)
1681       propagateCounts(BodyCount, S->getBody());
1682     else
1683       BackedgeCount =
1684           propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
1685 
1686     BreakContinue BC = BreakContinueStack.pop_back_val();
1687 
1688     bool BodyHasTerminateStmt = HasTerminateStmt;
1689     HasTerminateStmt = false;
1690 
1691     Counter CondCount = llvm::EnableSingleByteCoverage
1692                             ? getRegionCounter(S->getCond())
1693                             : addCounters(BackedgeCount, BC.ContinueCount);
1694     auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S));
1695     assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount ||
1696            llvm::EnableSingleByteCoverage);
1697 
1698     propagateCounts(CondCount, S->getCond());
1699 
1700     assert(
1701         !llvm::EnableSingleByteCoverage ||
1702         (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S)));
1703     Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped);
1704     if (!IsCounterEqual(OutCount, ParentCount)) {
1705       pushRegion(OutCount);
1706       GapRegionCounter = OutCount;
1707       if (BodyHasTerminateStmt)
1708         HasTerminateStmt = true;
1709     }
1710 
1711     // Create Branch Region around condition.
1712     if (!llvm::EnableSingleByteCoverage)
1713       createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped);
1714   }
1715 
1716   void VisitForStmt(const ForStmt *S) {
1717     extendRegion(S);
1718     if (S->getInit())
1719       Visit(S->getInit());
1720 
1721     Counter ParentCount = getRegion().getCounter();
1722     Counter BodyCount = llvm::EnableSingleByteCoverage
1723                             ? getRegionCounter(S->getBody())
1724                             : getRegionCounter(S);
1725 
1726     // The loop increment may contain a break or continue.
1727     if (S->getInc())
1728       BreakContinueStack.emplace_back();
1729 
1730     // Handle the body first so that we can get the backedge count.
1731     BreakContinueStack.emplace_back();
1732     extendRegion(S->getBody());
1733     Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1734     BreakContinue BodyBC = BreakContinueStack.pop_back_val();
1735 
1736     bool BodyHasTerminateStmt = HasTerminateStmt;
1737     HasTerminateStmt = false;
1738 
1739     // The increment is essentially part of the body but it needs to include
1740     // the count for all the continue statements.
1741     BreakContinue IncrementBC;
1742     if (const Stmt *Inc = S->getInc()) {
1743       Counter IncCount;
1744       if (llvm::EnableSingleByteCoverage)
1745         IncCount = getRegionCounter(S->getInc());
1746       else
1747         IncCount = addCounters(BackedgeCount, BodyBC.ContinueCount);
1748       propagateCounts(IncCount, Inc);
1749       IncrementBC = BreakContinueStack.pop_back_val();
1750     }
1751 
1752     // Go back to handle the condition.
1753     Counter CondCount =
1754         llvm::EnableSingleByteCoverage
1755             ? getRegionCounter(S->getCond())
1756             : addCounters(
1757                   addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
1758                   IncrementBC.ContinueCount);
1759     auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S));
1760     assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount ||
1761            llvm::EnableSingleByteCoverage);
1762 
1763     if (const Expr *Cond = S->getCond()) {
1764       propagateCounts(CondCount, Cond);
1765       adjustForOutOfOrderTraversal(getEnd(S));
1766     }
1767 
1768     // The body count applies to the area immediately after the increment.
1769     auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
1770     if (Gap)
1771       fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1772 
1773     assert(!llvm::EnableSingleByteCoverage ||
1774            (BodyBC.BreakCount.isZero() && IncrementBC.BreakCount.isZero()));
1775     Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
1776                                    BranchCount.Skipped);
1777     if (!IsCounterEqual(OutCount, ParentCount)) {
1778       pushRegion(OutCount);
1779       GapRegionCounter = OutCount;
1780       if (BodyHasTerminateStmt)
1781         HasTerminateStmt = true;
1782     }
1783 
1784     // Create Branch Region around condition.
1785     if (!llvm::EnableSingleByteCoverage)
1786       createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped);
1787   }
1788 
1789   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
1790     extendRegion(S);
1791     if (S->getInit())
1792       Visit(S->getInit());
1793     Visit(S->getLoopVarStmt());
1794     Visit(S->getRangeStmt());
1795 
1796     Counter ParentCount = getRegion().getCounter();
1797     Counter BodyCount = llvm::EnableSingleByteCoverage
1798                             ? getRegionCounter(S->getBody())
1799                             : getRegionCounter(S);
1800 
1801     BreakContinueStack.push_back(BreakContinue());
1802     extendRegion(S->getBody());
1803     Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1804     BreakContinue BC = BreakContinueStack.pop_back_val();
1805 
1806     bool BodyHasTerminateStmt = HasTerminateStmt;
1807     HasTerminateStmt = false;
1808 
1809     // The body count applies to the area immediately after the range.
1810     auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
1811     if (Gap)
1812       fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1813 
1814     Counter LoopCount =
1815         addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1816     auto BranchCount = getBranchCounterPair(S, LoopCount, getRegionCounter(S));
1817     assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount ||
1818            llvm::EnableSingleByteCoverage);
1819     assert(
1820         !llvm::EnableSingleByteCoverage ||
1821         (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S)));
1822 
1823     Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped);
1824     if (!IsCounterEqual(OutCount, ParentCount)) {
1825       pushRegion(OutCount);
1826       GapRegionCounter = OutCount;
1827       if (BodyHasTerminateStmt)
1828         HasTerminateStmt = true;
1829     }
1830 
1831     // Create Branch Region around condition.
1832     if (!llvm::EnableSingleByteCoverage)
1833       createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped);
1834   }
1835 
1836   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
1837     extendRegion(S);
1838     Visit(S->getElement());
1839 
1840     Counter ParentCount = getRegion().getCounter();
1841     Counter BodyCount = getRegionCounter(S);
1842 
1843     BreakContinueStack.push_back(BreakContinue());
1844     extendRegion(S->getBody());
1845     Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1846     BreakContinue BC = BreakContinueStack.pop_back_val();
1847 
1848     // The body count applies to the area immediately after the collection.
1849     auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
1850     if (Gap)
1851       fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1852 
1853     Counter LoopCount =
1854         addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1855     auto BranchCount = getBranchCounterPair(S, LoopCount);
1856     assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount);
1857     Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped);
1858     if (!IsCounterEqual(OutCount, ParentCount)) {
1859       pushRegion(OutCount);
1860       GapRegionCounter = OutCount;
1861     }
1862   }
1863 
1864   void VisitSwitchStmt(const SwitchStmt *S) {
1865     extendRegion(S);
1866     if (S->getInit())
1867       Visit(S->getInit());
1868     Visit(S->getCond());
1869 
1870     BreakContinueStack.push_back(BreakContinue());
1871 
1872     const Stmt *Body = S->getBody();
1873     extendRegion(Body);
1874     if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
1875       if (!CS->body_empty()) {
1876         // Make a region for the body of the switch.  If the body starts with
1877         // a case, that case will reuse this region; otherwise, this covers
1878         // the unreachable code at the beginning of the switch body.
1879         size_t Index = pushRegion(Counter::getZero(), getStart(CS));
1880         getRegion().setGap(true);
1881         Visit(Body);
1882 
1883         // Set the end for the body of the switch, if it isn't already set.
1884         for (size_t i = RegionStack.size(); i != Index; --i) {
1885           if (!RegionStack[i - 1].hasEndLoc())
1886             RegionStack[i - 1].setEndLoc(getEnd(CS->body_back()));
1887         }
1888 
1889         popRegions(Index);
1890       }
1891     } else
1892       propagateCounts(Counter::getZero(), Body);
1893     BreakContinue BC = BreakContinueStack.pop_back_val();
1894 
1895     if (!BreakContinueStack.empty() && !llvm::EnableSingleByteCoverage)
1896       BreakContinueStack.back().ContinueCount = addCounters(
1897           BreakContinueStack.back().ContinueCount, BC.ContinueCount);
1898 
1899     Counter ParentCount = getRegion().getCounter();
1900     Counter ExitCount = getRegionCounter(S);
1901     SourceLocation ExitLoc = getEnd(S);
1902     pushRegion(ExitCount);
1903     GapRegionCounter = ExitCount;
1904 
1905     // Ensure that handleFileExit recognizes when the end location is located
1906     // in a different file.
1907     MostRecentLocation = getStart(S);
1908     handleFileExit(ExitLoc);
1909 
1910     // When single byte coverage mode is enabled, do not create branch region by
1911     // early returning.
1912     if (llvm::EnableSingleByteCoverage)
1913       return;
1914 
1915     // Create a Branch Region around each Case. Subtract the case's
1916     // counter from the Parent counter to track the "False" branch count.
1917     Counter CaseCountSum;
1918     bool HasDefaultCase = false;
1919     const SwitchCase *Case = S->getSwitchCaseList();
1920     for (; Case; Case = Case->getNextSwitchCase()) {
1921       HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case);
1922       auto CaseCount = createSwitchCaseRegion(Case, ParentCount);
1923       CaseCountSum = addCounters(CaseCountSum, CaseCount, /*Simplify=*/false);
1924     }
1925     // If no explicit default case exists, create a branch region to represent
1926     // the hidden branch, which will be added later by the CodeGen. This region
1927     // will be associated with the switch statement's condition.
1928     if (!HasDefaultCase) {
1929       // Simplify is skipped while building the counters above: it can get
1930       // really slow on top of switches with thousands of cases. Instead,
1931       // trigger simplification by adding zero to the last counter.
1932       CaseCountSum =
1933           addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true);
1934 
1935       // This is considered as the False count on SwitchStmt.
1936       Counter SwitchFalse = subtractCounters(ParentCount, CaseCountSum);
1937       createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse);
1938     }
1939   }
1940 
1941   void VisitSwitchCase(const SwitchCase *S) {
1942     extendRegion(S);
1943 
1944     SourceMappingRegion &Parent = getRegion();
1945     Counter Count = llvm::EnableSingleByteCoverage
1946                         ? getRegionCounter(S)
1947                         : addCounters(Parent.getCounter(), getRegionCounter(S));
1948 
1949     // Reuse the existing region if it starts at our label. This is typical of
1950     // the first case in a switch.
1951     if (Parent.hasStartLoc() && Parent.getBeginLoc() == getStart(S))
1952       Parent.setCounter(Count);
1953     else
1954       pushRegion(Count, getStart(S));
1955 
1956     GapRegionCounter = Count;
1957 
1958     if (const auto *CS = dyn_cast<CaseStmt>(S)) {
1959       Visit(CS->getLHS());
1960       if (const Expr *RHS = CS->getRHS())
1961         Visit(RHS);
1962     }
1963     Visit(S->getSubStmt());
1964   }
1965 
1966   void coverIfConsteval(const IfStmt *S) {
1967     assert(S->isConsteval());
1968 
1969     const auto *Then = S->getThen();
1970     const auto *Else = S->getElse();
1971 
1972     // It's better for llvm-cov to create a new region with same counter
1973     // so line-coverage can be properly calculated for lines containing
1974     // a skipped region (without it the line is marked uncovered)
1975     const Counter ParentCount = getRegion().getCounter();
1976 
1977     extendRegion(S);
1978 
1979     if (S->isNegatedConsteval()) {
1980       // ignore 'if consteval'
1981       markSkipped(S->getIfLoc(), getStart(Then));
1982       propagateCounts(ParentCount, Then);
1983 
1984       if (Else) {
1985         // ignore 'else <else>'
1986         markSkipped(getEnd(Then), getEnd(Else));
1987       }
1988     } else {
1989       assert(S->isNonNegatedConsteval());
1990       // ignore 'if consteval <then> [else]'
1991       markSkipped(S->getIfLoc(), Else ? getStart(Else) : getEnd(Then));
1992 
1993       if (Else)
1994         propagateCounts(ParentCount, Else);
1995     }
1996   }
1997 
1998   void coverIfConstexpr(const IfStmt *S) {
1999     assert(S->isConstexpr());
2000 
2001     // evaluate constant condition...
2002     const bool isTrue =
2003         S->getCond()
2004             ->EvaluateKnownConstInt(CVM.getCodeGenModule().getContext())
2005             .getBoolValue();
2006 
2007     extendRegion(S);
2008 
2009     // I'm using 'propagateCounts' later as new region is better and allows me
2010     // to properly calculate line coverage in llvm-cov utility
2011     const Counter ParentCount = getRegion().getCounter();
2012 
2013     // ignore 'if constexpr ('
2014     SourceLocation startOfSkipped = S->getIfLoc();
2015 
2016     if (const auto *Init = S->getInit()) {
2017       const auto start = getStart(Init);
2018       const auto end = getEnd(Init);
2019 
2020       // this check is to make sure typedef here which doesn't have valid source
2021       // location won't crash it
2022       if (start.isValid() && end.isValid()) {
2023         markSkipped(startOfSkipped, start);
2024         propagateCounts(ParentCount, Init);
2025         startOfSkipped = getEnd(Init);
2026       }
2027     }
2028 
2029     const auto *Then = S->getThen();
2030     const auto *Else = S->getElse();
2031 
2032     if (isTrue) {
2033       // ignore '<condition>)'
2034       markSkipped(startOfSkipped, getStart(Then));
2035       propagateCounts(ParentCount, Then);
2036 
2037       if (Else)
2038         // ignore 'else <else>'
2039         markSkipped(getEnd(Then), getEnd(Else));
2040     } else {
2041       // ignore '<condition>) <then> [else]'
2042       markSkipped(startOfSkipped, Else ? getStart(Else) : getEnd(Then));
2043 
2044       if (Else)
2045         propagateCounts(ParentCount, Else);
2046     }
2047   }
2048 
2049   void VisitIfStmt(const IfStmt *S) {
2050     // "if constexpr" and "if consteval" are not normal conditional statements,
2051     // their discarded statement should be skipped
2052     if (S->isConsteval())
2053       return coverIfConsteval(S);
2054     else if (S->isConstexpr())
2055       return coverIfConstexpr(S);
2056 
2057     extendRegion(S);
2058     if (S->getInit())
2059       Visit(S->getInit());
2060 
2061     // Extend into the condition before we propagate through it below - this is
2062     // needed to handle macros that generate the "if" but not the condition.
2063     extendRegion(S->getCond());
2064 
2065     Counter ParentCount = getRegion().getCounter();
2066     auto [ThenCount, ElseCount] =
2067         (llvm::EnableSingleByteCoverage
2068              ? BranchCounterPair{getRegionCounter(S->getThen()),
2069                                  (S->getElse() ? getRegionCounter(S->getElse())
2070                                                : Counter::getZero())}
2071              : getBranchCounterPair(S, ParentCount));
2072 
2073     // Emitting a counter for the condition makes it easier to interpret the
2074     // counter for the body when looking at the coverage.
2075     propagateCounts(ParentCount, S->getCond());
2076 
2077     // The 'then' count applies to the area immediately after the condition.
2078     std::optional<SourceRange> Gap =
2079         findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen()));
2080     if (Gap)
2081       fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount);
2082 
2083     extendRegion(S->getThen());
2084     Counter OutCount = propagateCounts(ThenCount, S->getThen());
2085 
2086     if (const Stmt *Else = S->getElse()) {
2087       bool ThenHasTerminateStmt = HasTerminateStmt;
2088       HasTerminateStmt = false;
2089       // The 'else' count applies to the area immediately after the 'then'.
2090       std::optional<SourceRange> Gap =
2091           findGapAreaBetween(getEnd(S->getThen()), getStart(Else));
2092       if (Gap)
2093         fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount);
2094       extendRegion(Else);
2095 
2096       Counter ElseOutCount = propagateCounts(ElseCount, Else);
2097       if (!llvm::EnableSingleByteCoverage)
2098         OutCount = addCounters(OutCount, ElseOutCount);
2099 
2100       if (ThenHasTerminateStmt)
2101         HasTerminateStmt = true;
2102     } else if (!llvm::EnableSingleByteCoverage)
2103       OutCount = addCounters(OutCount, ElseCount);
2104 
2105     if (llvm::EnableSingleByteCoverage)
2106       OutCount = getRegionCounter(S);
2107 
2108     if (!IsCounterEqual(OutCount, ParentCount)) {
2109       pushRegion(OutCount);
2110       GapRegionCounter = OutCount;
2111     }
2112 
2113     if (!llvm::EnableSingleByteCoverage)
2114       // Create Branch Region around condition.
2115       createBranchRegion(S->getCond(), ThenCount, ElseCount);
2116   }
2117 
2118   void VisitCXXTryStmt(const CXXTryStmt *S) {
2119     extendRegion(S);
2120     // Handle macros that generate the "try" but not the rest.
2121     extendRegion(S->getTryBlock());
2122 
2123     Counter ParentCount = getRegion().getCounter();
2124     propagateCounts(ParentCount, S->getTryBlock());
2125 
2126     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
2127       Visit(S->getHandler(I));
2128 
2129     Counter ExitCount = getRegionCounter(S);
2130     pushRegion(ExitCount);
2131   }
2132 
2133   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
2134     propagateCounts(getRegionCounter(S), S->getHandlerBlock());
2135   }
2136 
2137   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
2138     extendRegion(E);
2139 
2140     Counter ParentCount = getRegion().getCounter();
2141     auto [TrueCount, FalseCount] =
2142         (llvm::EnableSingleByteCoverage
2143              ? BranchCounterPair{getRegionCounter(E->getTrueExpr()),
2144                                  getRegionCounter(E->getFalseExpr())}
2145              : getBranchCounterPair(E, ParentCount));
2146     Counter OutCount;
2147 
2148     if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) {
2149       propagateCounts(ParentCount, BCO->getCommon());
2150       OutCount = TrueCount;
2151     } else {
2152       propagateCounts(ParentCount, E->getCond());
2153       // The 'then' count applies to the area immediately after the condition.
2154       auto Gap =
2155           findGapAreaBetween(E->getQuestionLoc(), getStart(E->getTrueExpr()));
2156       if (Gap)
2157         fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), TrueCount);
2158 
2159       extendRegion(E->getTrueExpr());
2160       OutCount = propagateCounts(TrueCount, E->getTrueExpr());
2161     }
2162 
2163     extendRegion(E->getFalseExpr());
2164     Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr());
2165     if (llvm::EnableSingleByteCoverage)
2166       OutCount = getRegionCounter(E);
2167     else
2168       OutCount = addCounters(OutCount, FalseOutCount);
2169 
2170     if (!IsCounterEqual(OutCount, ParentCount)) {
2171       pushRegion(OutCount);
2172       GapRegionCounter = OutCount;
2173     }
2174 
2175     // Create Branch Region around condition.
2176     if (!llvm::EnableSingleByteCoverage)
2177       createBranchRegion(E->getCond(), TrueCount, FalseCount);
2178   }
2179 
2180   void createOrCancelDecision(const BinaryOperator *E, unsigned Since) {
2181     unsigned NumConds = MCDCBuilder.getTotalConditionsAndReset(E);
2182     if (NumConds == 0)
2183       return;
2184 
2185     // Extract [ID, Conds] to construct the graph.
2186     llvm::SmallVector<mcdc::ConditionIDs> CondIDs(NumConds);
2187     for (const auto &SR : ArrayRef(SourceRegions).slice(Since)) {
2188       if (SR.isMCDCBranch()) {
2189         auto [ID, Conds] = SR.getMCDCBranchParams();
2190         CondIDs[ID] = Conds;
2191       }
2192     }
2193 
2194     // Construct the graph and calculate `Indices`.
2195     mcdc::TVIdxBuilder Builder(CondIDs);
2196     unsigned NumTVs = Builder.NumTestVectors;
2197     unsigned MaxTVs = CVM.getCodeGenModule().getCodeGenOpts().MCDCMaxTVs;
2198     assert(MaxTVs < mcdc::TVIdxBuilder::HardMaxTVs);
2199 
2200     if (NumTVs > MaxTVs) {
2201       // NumTVs exceeds MaxTVs -- warn and cancel the Decision.
2202       cancelDecision(E, Since, NumTVs, MaxTVs);
2203       return;
2204     }
2205 
2206     // Update the state for CodeGenPGO
2207     assert(MCDCState.DecisionByStmt.contains(E));
2208     MCDCState.DecisionByStmt[E] = {
2209         MCDCState.BitmapBits, // Top
2210         std::move(Builder.Indices),
2211     };
2212 
2213     auto DecisionParams = mcdc::DecisionParameters{
2214         MCDCState.BitmapBits += NumTVs, // Tail
2215         NumConds,
2216     };
2217 
2218     // Create MCDC Decision Region.
2219     createDecisionRegion(E, DecisionParams);
2220   }
2221 
2222   // Warn and cancel the Decision.
2223   void cancelDecision(const BinaryOperator *E, unsigned Since, int NumTVs,
2224                       int MaxTVs) {
2225     auto &Diag = CVM.getCodeGenModule().getDiags();
2226     unsigned DiagID =
2227         Diag.getCustomDiagID(DiagnosticsEngine::Warning,
2228                              "unsupported MC/DC boolean expression; "
2229                              "number of test vectors (%0) exceeds max (%1). "
2230                              "Expression will not be covered");
2231     Diag.Report(E->getBeginLoc(), DiagID) << NumTVs << MaxTVs;
2232 
2233     // Restore MCDCBranch to Branch.
2234     for (auto &SR : MutableArrayRef(SourceRegions).slice(Since)) {
2235       assert(!SR.isMCDCDecision() && "Decision shouldn't be seen here");
2236       if (SR.isMCDCBranch())
2237         SR.resetMCDCParams();
2238     }
2239 
2240     // Tell CodeGenPGO not to instrument.
2241     MCDCState.DecisionByStmt.erase(E);
2242   }
2243 
2244   /// Check if E belongs to system headers.
2245   bool isExprInSystemHeader(const BinaryOperator *E) const {
2246     return (!SystemHeadersCoverage &&
2247             SM.isInSystemHeader(SM.getSpellingLoc(E->getOperatorLoc())) &&
2248             SM.isInSystemHeader(SM.getSpellingLoc(E->getBeginLoc())) &&
2249             SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc())));
2250   }
2251 
2252   void VisitBinLAnd(const BinaryOperator *E) {
2253     if (isExprInSystemHeader(E)) {
2254       LeafExprSet.insert(E);
2255       return;
2256     }
2257 
2258     bool IsRootNode = MCDCBuilder.isIdle();
2259 
2260     unsigned SourceRegionsSince = SourceRegions.size();
2261 
2262     // Keep track of Binary Operator and assign MCDC condition IDs.
2263     MCDCBuilder.pushAndAssignIDs(E);
2264 
2265     extendRegion(E->getLHS());
2266     propagateCounts(getRegion().getCounter(), E->getLHS());
2267     handleFileExit(getEnd(E->getLHS()));
2268 
2269     // Track LHS True/False Decision.
2270     const auto DecisionLHS = MCDCBuilder.pop();
2271 
2272     // Counter tracks the right hand side of a logical and operator.
2273     extendRegion(E->getRHS());
2274     propagateCounts(getRegionCounter(E), E->getRHS());
2275 
2276     if (llvm::EnableSingleByteCoverage)
2277       return;
2278 
2279     // Track RHS True/False Decision.
2280     const auto DecisionRHS = MCDCBuilder.back();
2281 
2282     // Extract the Parent Region Counter.
2283     Counter ParentCnt = getRegion().getCounter();
2284 
2285     // Extract the RHS's Execution Counter.
2286     auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt);
2287 
2288     // Extract the RHS's "True" Instance Counter.
2289     auto [RHSTrueCnt, RHSExitCnt] =
2290         getBranchCounterPair(E->getRHS(), RHSExecCnt);
2291 
2292     // Create Branch Region around LHS condition.
2293     createBranchRegion(E->getLHS(), RHSExecCnt, LHSExitCnt, DecisionLHS);
2294 
2295     // Create Branch Region around RHS condition.
2296     createBranchRegion(E->getRHS(), RHSTrueCnt, RHSExitCnt, DecisionRHS);
2297 
2298     // Create MCDC Decision Region if at top-level (root).
2299     if (IsRootNode)
2300       createOrCancelDecision(E, SourceRegionsSince);
2301   }
2302 
2303   // Determine whether the right side of OR operation need to be visited.
2304   bool shouldVisitRHS(const Expr *LHS) {
2305     bool LHSIsTrue = false;
2306     bool LHSIsConst = false;
2307     if (!LHS->isValueDependent())
2308       LHSIsConst = LHS->EvaluateAsBooleanCondition(
2309           LHSIsTrue, CVM.getCodeGenModule().getContext());
2310     return !LHSIsConst || (LHSIsConst && !LHSIsTrue);
2311   }
2312 
2313   void VisitBinLOr(const BinaryOperator *E) {
2314     if (isExprInSystemHeader(E)) {
2315       LeafExprSet.insert(E);
2316       return;
2317     }
2318 
2319     bool IsRootNode = MCDCBuilder.isIdle();
2320 
2321     unsigned SourceRegionsSince = SourceRegions.size();
2322 
2323     // Keep track of Binary Operator and assign MCDC condition IDs.
2324     MCDCBuilder.pushAndAssignIDs(E);
2325 
2326     extendRegion(E->getLHS());
2327     Counter OutCount = propagateCounts(getRegion().getCounter(), E->getLHS());
2328     handleFileExit(getEnd(E->getLHS()));
2329 
2330     // Track LHS True/False Decision.
2331     const auto DecisionLHS = MCDCBuilder.pop();
2332 
2333     // Counter tracks the right hand side of a logical or operator.
2334     extendRegion(E->getRHS());
2335     propagateCounts(getRegionCounter(E), E->getRHS());
2336 
2337     if (llvm::EnableSingleByteCoverage)
2338       return;
2339 
2340     // Track RHS True/False Decision.
2341     const auto DecisionRHS = MCDCBuilder.back();
2342 
2343     // Extract the Parent Region Counter.
2344     Counter ParentCnt = getRegion().getCounter();
2345 
2346     // Extract the RHS's Execution Counter.
2347     auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt);
2348 
2349     // Extract the RHS's "False" Instance Counter.
2350     auto [RHSFalseCnt, RHSExitCnt] =
2351         getBranchCounterPair(E->getRHS(), RHSExecCnt);
2352 
2353     if (!shouldVisitRHS(E->getLHS())) {
2354       GapRegionCounter = OutCount;
2355     }
2356 
2357     // Create Branch Region around LHS condition.
2358     createBranchRegion(E->getLHS(), LHSExitCnt, RHSExecCnt, DecisionLHS);
2359 
2360     // Create Branch Region around RHS condition.
2361     createBranchRegion(E->getRHS(), RHSExitCnt, RHSFalseCnt, DecisionRHS);
2362 
2363     // Create MCDC Decision Region if at top-level (root).
2364     if (IsRootNode)
2365       createOrCancelDecision(E, SourceRegionsSince);
2366   }
2367 
2368   void VisitLambdaExpr(const LambdaExpr *LE) {
2369     // Lambdas are treated as their own functions for now, so we shouldn't
2370     // propagate counts into them.
2371   }
2372 
2373   void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *AILE) {
2374     Visit(AILE->getCommonExpr()->getSourceExpr());
2375   }
2376 
2377   void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
2378     // Just visit syntatic expression as this is what users actually write.
2379     VisitStmt(POE->getSyntacticForm());
2380   }
2381 
2382   void VisitOpaqueValueExpr(const OpaqueValueExpr* OVE) {
2383     if (OVE->isUnique())
2384       Visit(OVE->getSourceExpr());
2385   }
2386 };
2387 
2388 } // end anonymous namespace
2389 
2390 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
2391                  ArrayRef<CounterExpression> Expressions,
2392                  ArrayRef<CounterMappingRegion> Regions) {
2393   OS << FunctionName << ":\n";
2394   CounterMappingContext Ctx(Expressions);
2395   for (const auto &R : Regions) {
2396     OS.indent(2);
2397     switch (R.Kind) {
2398     case CounterMappingRegion::CodeRegion:
2399       break;
2400     case CounterMappingRegion::ExpansionRegion:
2401       OS << "Expansion,";
2402       break;
2403     case CounterMappingRegion::SkippedRegion:
2404       OS << "Skipped,";
2405       break;
2406     case CounterMappingRegion::GapRegion:
2407       OS << "Gap,";
2408       break;
2409     case CounterMappingRegion::BranchRegion:
2410     case CounterMappingRegion::MCDCBranchRegion:
2411       OS << "Branch,";
2412       break;
2413     case CounterMappingRegion::MCDCDecisionRegion:
2414       OS << "Decision,";
2415       break;
2416     }
2417 
2418     OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
2419        << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = ";
2420 
2421     if (const auto *DecisionParams =
2422             std::get_if<mcdc::DecisionParameters>(&R.MCDCParams)) {
2423       OS << "M:" << DecisionParams->BitmapIdx;
2424       OS << ", C:" << DecisionParams->NumConditions;
2425     } else {
2426       Ctx.dump(R.Count, OS);
2427 
2428       if (R.isBranch()) {
2429         OS << ", ";
2430         Ctx.dump(R.FalseCount, OS);
2431       }
2432     }
2433 
2434     if (const auto *BranchParams =
2435             std::get_if<mcdc::BranchParameters>(&R.MCDCParams)) {
2436       OS << " [" << BranchParams->ID + 1 << ","
2437          << BranchParams->Conds[true] + 1;
2438       OS << "," << BranchParams->Conds[false] + 1 << "] ";
2439     }
2440 
2441     if (R.Kind == CounterMappingRegion::ExpansionRegion)
2442       OS << " (Expanded file = " << R.ExpandedFileID << ")";
2443     OS << "\n";
2444   }
2445 }
2446 
2447 CoverageMappingModuleGen::CoverageMappingModuleGen(
2448     CodeGenModule &CGM, CoverageSourceInfo &SourceInfo)
2449     : CGM(CGM), SourceInfo(SourceInfo) {}
2450 
2451 std::string CoverageMappingModuleGen::getCurrentDirname() {
2452   if (!CGM.getCodeGenOpts().CoverageCompilationDir.empty())
2453     return CGM.getCodeGenOpts().CoverageCompilationDir;
2454 
2455   SmallString<256> CWD;
2456   llvm::sys::fs::current_path(CWD);
2457   return CWD.str().str();
2458 }
2459 
2460 std::string CoverageMappingModuleGen::normalizeFilename(StringRef Filename) {
2461   llvm::SmallString<256> Path(Filename);
2462   llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true);
2463 
2464   /// Traverse coverage prefix map in reverse order because prefix replacements
2465   /// are applied in reverse order starting from the last one when multiple
2466   /// prefix replacement options are provided.
2467   for (const auto &[From, To] :
2468        llvm::reverse(CGM.getCodeGenOpts().CoveragePrefixMap)) {
2469     if (llvm::sys::path::replace_path_prefix(Path, From, To))
2470       break;
2471   }
2472   return Path.str().str();
2473 }
2474 
2475 static std::string getInstrProfSection(const CodeGenModule &CGM,
2476                                        llvm::InstrProfSectKind SK) {
2477   return llvm::getInstrProfSectionName(
2478       SK, CGM.getContext().getTargetInfo().getTriple().getObjectFormat());
2479 }
2480 
2481 void CoverageMappingModuleGen::emitFunctionMappingRecord(
2482     const FunctionInfo &Info, uint64_t FilenamesRef) {
2483   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
2484 
2485   // Assign a name to the function record. This is used to merge duplicates.
2486   std::string FuncRecordName = "__covrec_" + llvm::utohexstr(Info.NameHash);
2487 
2488   // A dummy description for a function included-but-not-used in a TU can be
2489   // replaced by full description provided by a different TU. The two kinds of
2490   // descriptions play distinct roles: therefore, assign them different names
2491   // to prevent `linkonce_odr` merging.
2492   if (Info.IsUsed)
2493     FuncRecordName += "u";
2494 
2495   // Create the function record type.
2496   const uint64_t NameHash = Info.NameHash;
2497   const uint64_t FuncHash = Info.FuncHash;
2498   const std::string &CoverageMapping = Info.CoverageMapping;
2499 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
2500   llvm::Type *FunctionRecordTypes[] = {
2501 #include "llvm/ProfileData/InstrProfData.inc"
2502   };
2503   auto *FunctionRecordTy =
2504       llvm::StructType::get(Ctx, ArrayRef(FunctionRecordTypes),
2505                             /*isPacked=*/true);
2506 
2507   // Create the function record constant.
2508 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
2509   llvm::Constant *FunctionRecordVals[] = {
2510       #include "llvm/ProfileData/InstrProfData.inc"
2511   };
2512   auto *FuncRecordConstant =
2513       llvm::ConstantStruct::get(FunctionRecordTy, ArrayRef(FunctionRecordVals));
2514 
2515   // Create the function record global.
2516   auto *FuncRecord = new llvm::GlobalVariable(
2517       CGM.getModule(), FunctionRecordTy, /*isConstant=*/true,
2518       llvm::GlobalValue::LinkOnceODRLinkage, FuncRecordConstant,
2519       FuncRecordName);
2520   FuncRecord->setVisibility(llvm::GlobalValue::HiddenVisibility);
2521   FuncRecord->setSection(getInstrProfSection(CGM, llvm::IPSK_covfun));
2522   FuncRecord->setAlignment(llvm::Align(8));
2523   if (CGM.supportsCOMDAT())
2524     FuncRecord->setComdat(CGM.getModule().getOrInsertComdat(FuncRecordName));
2525 
2526   // Make sure the data doesn't get deleted.
2527   CGM.addUsedGlobal(FuncRecord);
2528 }
2529 
2530 void CoverageMappingModuleGen::addFunctionMappingRecord(
2531     llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
2532     const std::string &CoverageMapping, bool IsUsed) {
2533   const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue);
2534   FunctionRecords.push_back({NameHash, FuncHash, CoverageMapping, IsUsed});
2535 
2536   if (!IsUsed)
2537     FunctionNames.push_back(NamePtr);
2538 
2539   if (CGM.getCodeGenOpts().DumpCoverageMapping) {
2540     // Dump the coverage mapping data for this function by decoding the
2541     // encoded data. This allows us to dump the mapping regions which were
2542     // also processed by the CoverageMappingWriter which performs
2543     // additional minimization operations such as reducing the number of
2544     // expressions.
2545     llvm::SmallVector<std::string, 16> FilenameStrs;
2546     std::vector<StringRef> Filenames;
2547     std::vector<CounterExpression> Expressions;
2548     std::vector<CounterMappingRegion> Regions;
2549     FilenameStrs.resize(FileEntries.size() + 1);
2550     FilenameStrs[0] = normalizeFilename(getCurrentDirname());
2551     for (const auto &Entry : FileEntries) {
2552       auto I = Entry.second;
2553       FilenameStrs[I] = normalizeFilename(Entry.first.getName());
2554     }
2555     ArrayRef<std::string> FilenameRefs = llvm::ArrayRef(FilenameStrs);
2556     RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
2557                                     Expressions, Regions);
2558     if (Reader.read())
2559       return;
2560     dump(llvm::outs(), NameValue, Expressions, Regions);
2561   }
2562 }
2563 
2564 void CoverageMappingModuleGen::emit() {
2565   if (FunctionRecords.empty())
2566     return;
2567   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
2568   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
2569 
2570   // Create the filenames and merge them with coverage mappings
2571   llvm::SmallVector<std::string, 16> FilenameStrs;
2572   FilenameStrs.resize(FileEntries.size() + 1);
2573   // The first filename is the current working directory.
2574   FilenameStrs[0] = normalizeFilename(getCurrentDirname());
2575   for (const auto &Entry : FileEntries) {
2576     auto I = Entry.second;
2577     FilenameStrs[I] = normalizeFilename(Entry.first.getName());
2578   }
2579 
2580   std::string Filenames;
2581   {
2582     llvm::raw_string_ostream OS(Filenames);
2583     CoverageFilenamesSectionWriter(FilenameStrs).write(OS);
2584   }
2585   auto *FilenamesVal =
2586       llvm::ConstantDataArray::getString(Ctx, Filenames, false);
2587   const int64_t FilenamesRef = llvm::IndexedInstrProf::ComputeHash(Filenames);
2588 
2589   // Emit the function records.
2590   for (const FunctionInfo &Info : FunctionRecords)
2591     emitFunctionMappingRecord(Info, FilenamesRef);
2592 
2593   const unsigned NRecords = 0;
2594   const size_t FilenamesSize = Filenames.size();
2595   const unsigned CoverageMappingSize = 0;
2596   llvm::Type *CovDataHeaderTypes[] = {
2597 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
2598 #include "llvm/ProfileData/InstrProfData.inc"
2599   };
2600   auto CovDataHeaderTy =
2601       llvm::StructType::get(Ctx, ArrayRef(CovDataHeaderTypes));
2602   llvm::Constant *CovDataHeaderVals[] = {
2603 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
2604 #include "llvm/ProfileData/InstrProfData.inc"
2605   };
2606   auto CovDataHeaderVal =
2607       llvm::ConstantStruct::get(CovDataHeaderTy, ArrayRef(CovDataHeaderVals));
2608 
2609   // Create the coverage data record
2610   llvm::Type *CovDataTypes[] = {CovDataHeaderTy, FilenamesVal->getType()};
2611   auto CovDataTy = llvm::StructType::get(Ctx, ArrayRef(CovDataTypes));
2612   llvm::Constant *TUDataVals[] = {CovDataHeaderVal, FilenamesVal};
2613   auto CovDataVal = llvm::ConstantStruct::get(CovDataTy, ArrayRef(TUDataVals));
2614   auto CovData = new llvm::GlobalVariable(
2615       CGM.getModule(), CovDataTy, true, llvm::GlobalValue::PrivateLinkage,
2616       CovDataVal, llvm::getCoverageMappingVarName());
2617 
2618   CovData->setSection(getInstrProfSection(CGM, llvm::IPSK_covmap));
2619   CovData->setAlignment(llvm::Align(8));
2620 
2621   // Make sure the data doesn't get deleted.
2622   CGM.addUsedGlobal(CovData);
2623   // Create the deferred function records array
2624   if (!FunctionNames.empty()) {
2625     auto AddrSpace = FunctionNames.front()->getType()->getPointerAddressSpace();
2626     auto NamesArrTy = llvm::ArrayType::get(
2627         llvm::PointerType::get(Ctx, AddrSpace), FunctionNames.size());
2628     auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
2629     // This variable will *NOT* be emitted to the object file. It is used
2630     // to pass the list of names referenced to codegen.
2631     new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true,
2632                              llvm::GlobalValue::InternalLinkage, NamesArrVal,
2633                              llvm::getCoverageUnusedNamesVarName());
2634   }
2635 }
2636 
2637 unsigned CoverageMappingModuleGen::getFileID(FileEntryRef File) {
2638   return FileEntries.try_emplace(File, FileEntries.size() + 1).first->second;
2639 }
2640 
2641 void CoverageMappingGen::emitCounterMapping(const Decl *D,
2642                                             llvm::raw_ostream &OS) {
2643   assert(CounterMap && MCDCState);
2644   CounterCoverageMappingBuilder Walker(CVM, *CounterMap, *MCDCState, SM,
2645                                        LangOpts);
2646   Walker.VisitDecl(D);
2647   Walker.write(OS);
2648 }
2649 
2650 void CoverageMappingGen::emitEmptyMapping(const Decl *D,
2651                                           llvm::raw_ostream &OS) {
2652   EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
2653   Walker.VisitDecl(D);
2654   Walker.write(OS);
2655 }
2656