1 //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Instrumentation-based code coverage mapping generator
11 //===----------------------------------------------------------------------===//
13 #include "CoverageMappingGen.h"
14 #include "CodeGenFunction.h"
15 #include "clang/AST/StmtVisitor.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/FileManager.h"
18 #include "clang/Frontend/FrontendDiagnostic.h"
19 #include "clang/Lex/Lexer.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/ProfileData/InstrProfReader.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/Path.h"
30 // This selects the coverage mapping format defined when `InstrProfData.inc`
31 // is textually included.
34 static llvm::cl::opt
<bool> EmptyLineCommentCoverage(
35 "emptyline-comment-coverage",
36 llvm::cl::desc("Emit emptylines and comment lines as skipped regions (only "
37 "disable it on test)"),
38 llvm::cl::init(true), llvm::cl::Hidden
);
40 static llvm::cl::opt
<bool> SystemHeadersCoverage(
41 "system-headers-coverage",
42 llvm::cl::desc("Enable collecting coverage from system headers"),
43 llvm::cl::init(false), llvm::cl::Hidden
);
45 using namespace clang
;
46 using namespace CodeGen
;
47 using namespace llvm::coverage
;
50 CoverageMappingModuleGen::setUpCoverageCallbacks(Preprocessor
&PP
) {
51 CoverageSourceInfo
*CoverageInfo
=
52 new CoverageSourceInfo(PP
.getSourceManager());
53 PP
.addPPCallbacks(std::unique_ptr
<PPCallbacks
>(CoverageInfo
));
54 if (EmptyLineCommentCoverage
) {
55 PP
.addCommentHandler(CoverageInfo
);
56 PP
.setEmptylineHandler(CoverageInfo
);
57 PP
.setPreprocessToken(true);
58 PP
.setTokenWatcher([CoverageInfo
](clang::Token Tok
) {
59 // Update previous token location.
60 CoverageInfo
->PrevTokLoc
= Tok
.getLocation();
61 if (Tok
.getKind() != clang::tok::eod
)
62 CoverageInfo
->updateNextTokLoc(Tok
.getLocation());
68 void CoverageSourceInfo::AddSkippedRange(SourceRange Range
,
69 SkippedRange::Kind RangeKind
) {
70 if (EmptyLineCommentCoverage
&& !SkippedRanges
.empty() &&
71 PrevTokLoc
== SkippedRanges
.back().PrevTokLoc
&&
72 SourceMgr
.isWrittenInSameFile(SkippedRanges
.back().Range
.getEnd(),
74 SkippedRanges
.back().Range
.setEnd(Range
.getEnd());
76 SkippedRanges
.push_back({Range
, RangeKind
, PrevTokLoc
});
79 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range
, SourceLocation
) {
80 AddSkippedRange(Range
, SkippedRange::PPIfElse
);
83 void CoverageSourceInfo::HandleEmptyline(SourceRange Range
) {
84 AddSkippedRange(Range
, SkippedRange::EmptyLine
);
87 bool CoverageSourceInfo::HandleComment(Preprocessor
&PP
, SourceRange Range
) {
88 AddSkippedRange(Range
, SkippedRange::Comment
);
92 void CoverageSourceInfo::updateNextTokLoc(SourceLocation Loc
) {
93 if (!SkippedRanges
.empty() && SkippedRanges
.back().NextTokLoc
.isInvalid())
94 SkippedRanges
.back().NextTokLoc
= Loc
;
99 /// A region of source code that can be mapped to a counter.
100 class SourceMappingRegion
{
101 /// Primary Counter that is also used for Branch Regions for "True" branches.
104 /// Secondary Counter used for Branch Regions for "False" branches.
105 std::optional
<Counter
> FalseCount
;
107 /// The region's starting location.
108 std::optional
<SourceLocation
> LocStart
;
110 /// The region's ending location.
111 std::optional
<SourceLocation
> LocEnd
;
113 /// Whether this region is a gap region. The count from a gap region is set
114 /// as the line execution count if there are no other regions on the line.
118 SourceMappingRegion(Counter Count
, std::optional
<SourceLocation
> LocStart
,
119 std::optional
<SourceLocation
> LocEnd
,
120 bool GapRegion
= false)
121 : Count(Count
), LocStart(LocStart
), LocEnd(LocEnd
), GapRegion(GapRegion
) {
124 SourceMappingRegion(Counter Count
, std::optional
<Counter
> FalseCount
,
125 std::optional
<SourceLocation
> LocStart
,
126 std::optional
<SourceLocation
> LocEnd
,
127 bool GapRegion
= false)
128 : Count(Count
), FalseCount(FalseCount
), LocStart(LocStart
),
129 LocEnd(LocEnd
), GapRegion(GapRegion
) {}
131 const Counter
&getCounter() const { return Count
; }
133 const Counter
&getFalseCounter() const {
134 assert(FalseCount
&& "Region has no alternate counter");
138 void setCounter(Counter C
) { Count
= C
; }
140 bool hasStartLoc() const { return LocStart
.has_value(); }
142 void setStartLoc(SourceLocation Loc
) { LocStart
= Loc
; }
144 SourceLocation
getBeginLoc() const {
145 assert(LocStart
&& "Region has no start location");
149 bool hasEndLoc() const { return LocEnd
.has_value(); }
151 void setEndLoc(SourceLocation Loc
) {
152 assert(Loc
.isValid() && "Setting an invalid end location");
156 SourceLocation
getEndLoc() const {
157 assert(LocEnd
&& "Region has no end location");
161 bool isGap() const { return GapRegion
; }
163 void setGap(bool Gap
) { GapRegion
= Gap
; }
165 bool isBranch() const { return FalseCount
.has_value(); }
168 /// Spelling locations for the start and end of a source region.
169 struct SpellingRegion
{
170 /// The line where the region starts.
173 /// The column where the region starts.
174 unsigned ColumnStart
;
176 /// The line where the region ends.
179 /// The column where the region ends.
182 SpellingRegion(SourceManager
&SM
, SourceLocation LocStart
,
183 SourceLocation LocEnd
) {
184 LineStart
= SM
.getSpellingLineNumber(LocStart
);
185 ColumnStart
= SM
.getSpellingColumnNumber(LocStart
);
186 LineEnd
= SM
.getSpellingLineNumber(LocEnd
);
187 ColumnEnd
= SM
.getSpellingColumnNumber(LocEnd
);
190 SpellingRegion(SourceManager
&SM
, SourceMappingRegion
&R
)
191 : SpellingRegion(SM
, R
.getBeginLoc(), R
.getEndLoc()) {}
193 /// Check if the start and end locations appear in source order, i.e
194 /// top->bottom, left->right.
195 bool isInSourceOrder() const {
196 return (LineStart
< LineEnd
) ||
197 (LineStart
== LineEnd
&& ColumnStart
<= ColumnEnd
);
201 /// Provides the common functionality for the different
202 /// coverage mapping region builders.
203 class CoverageMappingBuilder
{
205 CoverageMappingModuleGen
&CVM
;
207 const LangOptions
&LangOpts
;
210 /// Map of clang's FileIDs to IDs used for coverage mapping.
211 llvm::SmallDenseMap
<FileID
, std::pair
<unsigned, SourceLocation
>, 8>
215 /// The coverage mapping regions for this function
216 llvm::SmallVector
<CounterMappingRegion
, 32> MappingRegions
;
217 /// The source mapping regions for this function.
218 std::vector
<SourceMappingRegion
> SourceRegions
;
220 /// A set of regions which can be used as a filter.
222 /// It is produced by emitExpansionRegions() and is used in
223 /// emitSourceRegions() to suppress producing code regions if
224 /// the same area is covered by expansion regions.
225 typedef llvm::SmallSet
<std::pair
<SourceLocation
, SourceLocation
>, 8>
228 CoverageMappingBuilder(CoverageMappingModuleGen
&CVM
, SourceManager
&SM
,
229 const LangOptions
&LangOpts
)
230 : CVM(CVM
), SM(SM
), LangOpts(LangOpts
) {}
232 /// Return the precise end location for the given token.
233 SourceLocation
getPreciseTokenLocEnd(SourceLocation Loc
) {
234 // We avoid getLocForEndOfToken here, because it doesn't do what we want for
235 // macro locations, which we just treat as expanded files.
237 Lexer::MeasureTokenLength(SM
.getSpellingLoc(Loc
), SM
, LangOpts
);
238 return Loc
.getLocWithOffset(TokLen
);
241 /// Return the start location of an included file or expanded macro.
242 SourceLocation
getStartOfFileOrMacro(SourceLocation Loc
) {
244 return Loc
.getLocWithOffset(-SM
.getFileOffset(Loc
));
245 return SM
.getLocForStartOfFile(SM
.getFileID(Loc
));
248 /// Return the end location of an included file or expanded macro.
249 SourceLocation
getEndOfFileOrMacro(SourceLocation Loc
) {
251 return Loc
.getLocWithOffset(SM
.getFileIDSize(SM
.getFileID(Loc
)) -
252 SM
.getFileOffset(Loc
));
253 return SM
.getLocForEndOfFile(SM
.getFileID(Loc
));
256 /// Find out where the current file is included or macro is expanded.
257 SourceLocation
getIncludeOrExpansionLoc(SourceLocation Loc
) {
258 return Loc
.isMacroID() ? SM
.getImmediateExpansionRange(Loc
).getBegin()
259 : SM
.getIncludeLoc(SM
.getFileID(Loc
));
262 /// Return true if \c Loc is a location in a built-in macro.
263 bool isInBuiltin(SourceLocation Loc
) {
264 return SM
.getBufferName(SM
.getSpellingLoc(Loc
)) == "<built-in>";
267 /// Check whether \c Loc is included or expanded from \c Parent.
268 bool isNestedIn(SourceLocation Loc
, FileID Parent
) {
270 Loc
= getIncludeOrExpansionLoc(Loc
);
273 } while (!SM
.isInFileID(Loc
, Parent
));
277 /// Get the start of \c S ignoring macro arguments and builtin macros.
278 SourceLocation
getStart(const Stmt
*S
) {
279 SourceLocation Loc
= S
->getBeginLoc();
280 while (SM
.isMacroArgExpansion(Loc
) || isInBuiltin(Loc
))
281 Loc
= SM
.getImmediateExpansionRange(Loc
).getBegin();
285 /// Get the end of \c S ignoring macro arguments and builtin macros.
286 SourceLocation
getEnd(const Stmt
*S
) {
287 SourceLocation Loc
= S
->getEndLoc();
288 while (SM
.isMacroArgExpansion(Loc
) || isInBuiltin(Loc
))
289 Loc
= SM
.getImmediateExpansionRange(Loc
).getBegin();
290 return getPreciseTokenLocEnd(Loc
);
293 /// Find the set of files we have regions for and assign IDs
295 /// Fills \c Mapping with the virtual file mapping needed to write out
296 /// coverage and collects the necessary file information to emit source and
297 /// expansion regions.
298 void gatherFileIDs(SmallVectorImpl
<unsigned> &Mapping
) {
299 FileIDMapping
.clear();
301 llvm::SmallSet
<FileID
, 8> Visited
;
302 SmallVector
<std::pair
<SourceLocation
, unsigned>, 8> FileLocs
;
303 for (const auto &Region
: SourceRegions
) {
304 SourceLocation Loc
= Region
.getBeginLoc();
305 FileID File
= SM
.getFileID(Loc
);
306 if (!Visited
.insert(File
).second
)
309 // Do not map FileID's associated with system headers unless collecting
310 // coverage from system headers is explicitly enabled.
311 if (!SystemHeadersCoverage
&& SM
.isInSystemHeader(SM
.getSpellingLoc(Loc
)))
315 for (SourceLocation Parent
= getIncludeOrExpansionLoc(Loc
);
316 Parent
.isValid(); Parent
= getIncludeOrExpansionLoc(Parent
))
318 FileLocs
.push_back(std::make_pair(Loc
, Depth
));
320 llvm::stable_sort(FileLocs
, llvm::less_second());
322 for (const auto &FL
: FileLocs
) {
323 SourceLocation Loc
= FL
.first
;
324 FileID SpellingFile
= SM
.getDecomposedSpellingLoc(Loc
).first
;
325 auto Entry
= SM
.getFileEntryForID(SpellingFile
);
329 FileIDMapping
[SM
.getFileID(Loc
)] = std::make_pair(Mapping
.size(), Loc
);
330 Mapping
.push_back(CVM
.getFileID(Entry
));
334 /// Get the coverage mapping file ID for \c Loc.
336 /// If such file id doesn't exist, return std::nullopt.
337 std::optional
<unsigned> getCoverageFileID(SourceLocation Loc
) {
338 auto Mapping
= FileIDMapping
.find(SM
.getFileID(Loc
));
339 if (Mapping
!= FileIDMapping
.end())
340 return Mapping
->second
.first
;
344 /// This shrinks the skipped range if it spans a line that contains a
345 /// non-comment token. If shrinking the skipped range would make it empty,
346 /// this returns std::nullopt.
347 /// Note this function can potentially be expensive because
348 /// getSpellingLineNumber uses getLineNumber, which is expensive.
349 std::optional
<SpellingRegion
> adjustSkippedRange(SourceManager
&SM
,
350 SourceLocation LocStart
,
351 SourceLocation LocEnd
,
352 SourceLocation PrevTokLoc
,
353 SourceLocation NextTokLoc
) {
354 SpellingRegion SR
{SM
, LocStart
, LocEnd
};
356 if (PrevTokLoc
.isValid() && SM
.isWrittenInSameFile(LocStart
, PrevTokLoc
) &&
357 SR
.LineStart
== SM
.getSpellingLineNumber(PrevTokLoc
))
359 if (NextTokLoc
.isValid() && SM
.isWrittenInSameFile(LocEnd
, NextTokLoc
) &&
360 SR
.LineEnd
== SM
.getSpellingLineNumber(NextTokLoc
)) {
364 if (SR
.isInSourceOrder())
369 /// Gather all the regions that were skipped by the preprocessor
370 /// using the constructs like #if or comments.
371 void gatherSkippedRegions() {
372 /// An array of the minimum lineStarts and the maximum lineEnds
373 /// for mapping regions from the appropriate source files.
374 llvm::SmallVector
<std::pair
<unsigned, unsigned>, 8> FileLineRanges
;
375 FileLineRanges
.resize(
376 FileIDMapping
.size(),
377 std::make_pair(std::numeric_limits
<unsigned>::max(), 0));
378 for (const auto &R
: MappingRegions
) {
379 FileLineRanges
[R
.FileID
].first
=
380 std::min(FileLineRanges
[R
.FileID
].first
, R
.LineStart
);
381 FileLineRanges
[R
.FileID
].second
=
382 std::max(FileLineRanges
[R
.FileID
].second
, R
.LineEnd
);
385 auto SkippedRanges
= CVM
.getSourceInfo().getSkippedRanges();
386 for (auto &I
: SkippedRanges
) {
387 SourceRange Range
= I
.Range
;
388 auto LocStart
= Range
.getBegin();
389 auto LocEnd
= Range
.getEnd();
390 assert(SM
.isWrittenInSameFile(LocStart
, LocEnd
) &&
391 "region spans multiple files");
393 auto CovFileID
= getCoverageFileID(LocStart
);
396 std::optional
<SpellingRegion
> SR
;
398 SR
= adjustSkippedRange(SM
, LocStart
, LocEnd
, I
.PrevTokLoc
,
400 else if (I
.isPPIfElse() || I
.isEmptyLine())
401 SR
= {SM
, LocStart
, LocEnd
};
405 auto Region
= CounterMappingRegion::makeSkipped(
406 *CovFileID
, SR
->LineStart
, SR
->ColumnStart
, SR
->LineEnd
,
408 // Make sure that we only collect the regions that are inside
409 // the source code of this function.
410 if (Region
.LineStart
>= FileLineRanges
[*CovFileID
].first
&&
411 Region
.LineEnd
<= FileLineRanges
[*CovFileID
].second
)
412 MappingRegions
.push_back(Region
);
416 /// Generate the coverage counter mapping regions from collected
418 void emitSourceRegions(const SourceRegionFilter
&Filter
) {
419 for (const auto &Region
: SourceRegions
) {
420 assert(Region
.hasEndLoc() && "incomplete region");
422 SourceLocation LocStart
= Region
.getBeginLoc();
423 assert(SM
.getFileID(LocStart
).isValid() && "region in invalid file");
425 // Ignore regions from system headers unless collecting coverage from
426 // system headers is explicitly enabled.
427 if (!SystemHeadersCoverage
&&
428 SM
.isInSystemHeader(SM
.getSpellingLoc(LocStart
)))
431 auto CovFileID
= getCoverageFileID(LocStart
);
432 // Ignore regions that don't have a file, such as builtin macros.
436 SourceLocation LocEnd
= Region
.getEndLoc();
437 assert(SM
.isWrittenInSameFile(LocStart
, LocEnd
) &&
438 "region spans multiple files");
440 // Don't add code regions for the area covered by expansion regions.
441 // This not only suppresses redundant regions, but sometimes prevents
442 // creating regions with wrong counters if, for example, a statement's
443 // body ends at the end of a nested macro.
444 if (Filter
.count(std::make_pair(LocStart
, LocEnd
)))
447 // Find the spelling locations for the mapping region.
448 SpellingRegion SR
{SM
, LocStart
, LocEnd
};
449 assert(SR
.isInSourceOrder() && "region start and end out of order");
451 if (Region
.isGap()) {
452 MappingRegions
.push_back(CounterMappingRegion::makeGapRegion(
453 Region
.getCounter(), *CovFileID
, SR
.LineStart
, SR
.ColumnStart
,
454 SR
.LineEnd
, SR
.ColumnEnd
));
455 } else if (Region
.isBranch()) {
456 MappingRegions
.push_back(CounterMappingRegion::makeBranchRegion(
457 Region
.getCounter(), Region
.getFalseCounter(), *CovFileID
,
458 SR
.LineStart
, SR
.ColumnStart
, SR
.LineEnd
, SR
.ColumnEnd
));
460 MappingRegions
.push_back(CounterMappingRegion::makeRegion(
461 Region
.getCounter(), *CovFileID
, SR
.LineStart
, SR
.ColumnStart
,
462 SR
.LineEnd
, SR
.ColumnEnd
));
467 /// Generate expansion regions for each virtual file we've seen.
468 SourceRegionFilter
emitExpansionRegions() {
469 SourceRegionFilter Filter
;
470 for (const auto &FM
: FileIDMapping
) {
471 SourceLocation ExpandedLoc
= FM
.second
.second
;
472 SourceLocation ParentLoc
= getIncludeOrExpansionLoc(ExpandedLoc
);
473 if (ParentLoc
.isInvalid())
476 auto ParentFileID
= getCoverageFileID(ParentLoc
);
479 auto ExpandedFileID
= getCoverageFileID(ExpandedLoc
);
480 assert(ExpandedFileID
&& "expansion in uncovered file");
482 SourceLocation LocEnd
= getPreciseTokenLocEnd(ParentLoc
);
483 assert(SM
.isWrittenInSameFile(ParentLoc
, LocEnd
) &&
484 "region spans multiple files");
485 Filter
.insert(std::make_pair(ParentLoc
, LocEnd
));
487 SpellingRegion SR
{SM
, ParentLoc
, LocEnd
};
488 assert(SR
.isInSourceOrder() && "region start and end out of order");
489 MappingRegions
.push_back(CounterMappingRegion::makeExpansion(
490 *ParentFileID
, *ExpandedFileID
, SR
.LineStart
, SR
.ColumnStart
,
491 SR
.LineEnd
, SR
.ColumnEnd
));
497 /// Creates unreachable coverage regions for the functions that
499 struct EmptyCoverageMappingBuilder
: public CoverageMappingBuilder
{
500 EmptyCoverageMappingBuilder(CoverageMappingModuleGen
&CVM
, SourceManager
&SM
,
501 const LangOptions
&LangOpts
)
502 : CoverageMappingBuilder(CVM
, SM
, LangOpts
) {}
504 void VisitDecl(const Decl
*D
) {
507 auto Body
= D
->getBody();
508 SourceLocation Start
= getStart(Body
);
509 SourceLocation End
= getEnd(Body
);
510 if (!SM
.isWrittenInSameFile(Start
, End
)) {
511 // Walk up to find the common ancestor.
512 // Correct the locations accordingly.
513 FileID StartFileID
= SM
.getFileID(Start
);
514 FileID EndFileID
= SM
.getFileID(End
);
515 while (StartFileID
!= EndFileID
&& !isNestedIn(End
, StartFileID
)) {
516 Start
= getIncludeOrExpansionLoc(Start
);
517 assert(Start
.isValid() &&
518 "Declaration start location not nested within a known region");
519 StartFileID
= SM
.getFileID(Start
);
521 while (StartFileID
!= EndFileID
) {
522 End
= getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End
));
523 assert(End
.isValid() &&
524 "Declaration end location not nested within a known region");
525 EndFileID
= SM
.getFileID(End
);
528 SourceRegions
.emplace_back(Counter(), Start
, End
);
531 /// Write the mapping data to the output stream
532 void write(llvm::raw_ostream
&OS
) {
533 SmallVector
<unsigned, 16> FileIDMapping
;
534 gatherFileIDs(FileIDMapping
);
535 emitSourceRegions(SourceRegionFilter());
537 if (MappingRegions
.empty())
540 CoverageMappingWriter
Writer(FileIDMapping
, std::nullopt
, MappingRegions
);
545 /// A StmtVisitor that creates coverage mapping regions which map
546 /// from the source code locations to the PGO counters.
547 struct CounterCoverageMappingBuilder
548 : public CoverageMappingBuilder
,
549 public ConstStmtVisitor
<CounterCoverageMappingBuilder
> {
550 /// The map of statements to count values.
551 llvm::DenseMap
<const Stmt
*, unsigned> &CounterMap
;
553 /// A stack of currently live regions.
554 std::vector
<SourceMappingRegion
> RegionStack
;
556 CounterExpressionBuilder Builder
;
558 /// A location in the most recently visited file or macro.
560 /// This is used to adjust the active source regions appropriately when
561 /// expressions cross file or macro boundaries.
562 SourceLocation MostRecentLocation
;
564 /// Whether the visitor at a terminate statement.
565 bool HasTerminateStmt
= false;
567 /// Gap region counter after terminate statement.
568 Counter GapRegionCounter
;
570 /// Return a counter for the subtraction of \c RHS from \c LHS
571 Counter
subtractCounters(Counter LHS
, Counter RHS
, bool Simplify
= true) {
572 return Builder
.subtract(LHS
, RHS
, Simplify
);
575 /// Return a counter for the sum of \c LHS and \c RHS.
576 Counter
addCounters(Counter LHS
, Counter RHS
, bool Simplify
= true) {
577 return Builder
.add(LHS
, RHS
, Simplify
);
580 Counter
addCounters(Counter C1
, Counter C2
, Counter C3
,
581 bool Simplify
= true) {
582 return addCounters(addCounters(C1
, C2
, Simplify
), C3
, Simplify
);
585 /// Return the region counter for the given statement.
587 /// This should only be called on statements that have a dedicated counter.
588 Counter
getRegionCounter(const Stmt
*S
) {
589 return Counter::getCounter(CounterMap
[S
]);
592 /// Push a region onto the stack.
594 /// Returns the index on the stack where the region was pushed. This can be
595 /// used with popRegions to exit a "scope", ending the region that was pushed.
596 size_t pushRegion(Counter Count
,
597 std::optional
<SourceLocation
> StartLoc
= std::nullopt
,
598 std::optional
<SourceLocation
> EndLoc
= std::nullopt
,
599 std::optional
<Counter
> FalseCount
= std::nullopt
) {
601 if (StartLoc
&& !FalseCount
) {
602 MostRecentLocation
= *StartLoc
;
605 // If either of these locations is invalid, something elsewhere in the
606 // compiler has broken.
607 assert((!StartLoc
|| StartLoc
->isValid()) && "Start location is not valid");
608 assert((!EndLoc
|| EndLoc
->isValid()) && "End location is not valid");
610 // However, we can still recover without crashing.
611 // If either location is invalid, set it to std::nullopt to avoid
612 // letting users of RegionStack think that region has a valid start/end
614 if (StartLoc
&& StartLoc
->isInvalid())
615 StartLoc
= std::nullopt
;
616 if (EndLoc
&& EndLoc
->isInvalid())
617 EndLoc
= std::nullopt
;
618 RegionStack
.emplace_back(Count
, FalseCount
, StartLoc
, EndLoc
);
620 return RegionStack
.size() - 1;
623 size_t locationDepth(SourceLocation Loc
) {
625 while (Loc
.isValid()) {
626 Loc
= getIncludeOrExpansionLoc(Loc
);
632 /// Pop regions from the stack into the function's list of regions.
634 /// Adds all regions from \c ParentIndex to the top of the stack to the
635 /// function's \c SourceRegions.
636 void popRegions(size_t ParentIndex
) {
637 assert(RegionStack
.size() >= ParentIndex
&& "parent not in stack");
638 while (RegionStack
.size() > ParentIndex
) {
639 SourceMappingRegion
&Region
= RegionStack
.back();
640 if (Region
.hasStartLoc() &&
641 (Region
.hasEndLoc() || RegionStack
[ParentIndex
].hasEndLoc())) {
642 SourceLocation StartLoc
= Region
.getBeginLoc();
643 SourceLocation EndLoc
= Region
.hasEndLoc()
645 : RegionStack
[ParentIndex
].getEndLoc();
646 bool isBranch
= Region
.isBranch();
647 size_t StartDepth
= locationDepth(StartLoc
);
648 size_t EndDepth
= locationDepth(EndLoc
);
649 while (!SM
.isWrittenInSameFile(StartLoc
, EndLoc
)) {
650 bool UnnestStart
= StartDepth
>= EndDepth
;
651 bool UnnestEnd
= EndDepth
>= StartDepth
;
653 // The region ends in a nested file or macro expansion. If the
654 // region is not a branch region, create a separate region for each
655 // expansion, and for all regions, update the EndLoc. Branch
656 // regions should not be split in order to keep a straightforward
657 // correspondance between the region and its associated branch
658 // condition, even if the condition spans multiple depths.
659 SourceLocation NestedLoc
= getStartOfFileOrMacro(EndLoc
);
660 assert(SM
.isWrittenInSameFile(NestedLoc
, EndLoc
));
662 if (!isBranch
&& !isRegionAlreadyAdded(NestedLoc
, EndLoc
))
663 SourceRegions
.emplace_back(Region
.getCounter(), NestedLoc
,
666 EndLoc
= getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc
));
667 if (EndLoc
.isInvalid())
668 llvm::report_fatal_error(
669 "File exit not handled before popRegions");
673 // The region ends in a nested file or macro expansion. If the
674 // region is not a branch region, create a separate region for each
675 // expansion, and for all regions, update the StartLoc. Branch
676 // regions should not be split in order to keep a straightforward
677 // correspondance between the region and its associated branch
678 // condition, even if the condition spans multiple depths.
679 SourceLocation NestedLoc
= getEndOfFileOrMacro(StartLoc
);
680 assert(SM
.isWrittenInSameFile(StartLoc
, NestedLoc
));
682 if (!isBranch
&& !isRegionAlreadyAdded(StartLoc
, NestedLoc
))
683 SourceRegions
.emplace_back(Region
.getCounter(), StartLoc
,
686 StartLoc
= getIncludeOrExpansionLoc(StartLoc
);
687 if (StartLoc
.isInvalid())
688 llvm::report_fatal_error(
689 "File exit not handled before popRegions");
693 Region
.setStartLoc(StartLoc
);
694 Region
.setEndLoc(EndLoc
);
697 MostRecentLocation
= EndLoc
;
698 // If this region happens to span an entire expansion, we need to
699 // make sure we don't overlap the parent region with it.
700 if (StartLoc
== getStartOfFileOrMacro(StartLoc
) &&
701 EndLoc
== getEndOfFileOrMacro(EndLoc
))
702 MostRecentLocation
= getIncludeOrExpansionLoc(EndLoc
);
705 assert(SM
.isWrittenInSameFile(Region
.getBeginLoc(), EndLoc
));
706 assert(SpellingRegion(SM
, Region
).isInSourceOrder());
707 SourceRegions
.push_back(Region
);
709 RegionStack
.pop_back();
713 /// Return the currently active region.
714 SourceMappingRegion
&getRegion() {
715 assert(!RegionStack
.empty() && "statement has no region");
716 return RegionStack
.back();
719 /// Propagate counts through the children of \p S if \p VisitChildren is true.
720 /// Otherwise, only emit a count for \p S itself.
721 Counter
propagateCounts(Counter TopCount
, const Stmt
*S
,
722 bool VisitChildren
= true) {
723 SourceLocation StartLoc
= getStart(S
);
724 SourceLocation EndLoc
= getEnd(S
);
725 size_t Index
= pushRegion(TopCount
, StartLoc
, EndLoc
);
728 Counter ExitCount
= getRegion().getCounter();
731 // The statement may be spanned by an expansion. Make sure we handle a file
732 // exit out of this expansion before moving to the next statement.
733 if (SM
.isBeforeInTranslationUnit(StartLoc
, S
->getBeginLoc()))
734 MostRecentLocation
= EndLoc
;
739 /// Determine whether the given condition can be constant folded.
740 bool ConditionFoldsToBool(const Expr
*Cond
) {
741 Expr::EvalResult Result
;
742 return (Cond
->EvaluateAsInt(Result
, CVM
.getCodeGenModule().getContext()));
745 /// Create a Branch Region around an instrumentable condition for coverage
746 /// and add it to the function's SourceRegions. A branch region tracks a
747 /// "True" counter and a "False" counter for boolean expressions that
748 /// result in the generation of a branch.
749 void createBranchRegion(const Expr
*C
, Counter TrueCnt
, Counter FalseCnt
) {
750 // Check for NULL conditions.
754 // Ensure we are an instrumentable condition (i.e. no "&&" or "||"). Push
755 // region onto RegionStack but immediately pop it (which adds it to the
756 // function's SourceRegions) because it doesn't apply to any other source
757 // code other than the Condition.
758 if (CodeGenFunction::isInstrumentedCondition(C
)) {
759 // If a condition can fold to true or false, the corresponding branch
760 // will be removed. Create a region with both counters hard-coded to
761 // zero. This allows us to visualize them in a special way.
762 // Alternatively, we can prevent any optimization done via
763 // constant-folding by ensuring that ConstantFoldsToSimpleInteger() in
764 // CodeGenFunction.c always returns false, but that is very heavy-handed.
765 if (ConditionFoldsToBool(C
))
766 popRegions(pushRegion(Counter::getZero(), getStart(C
), getEnd(C
),
767 Counter::getZero()));
769 // Otherwise, create a region with the True counter and False counter.
770 popRegions(pushRegion(TrueCnt
, getStart(C
), getEnd(C
), FalseCnt
));
774 /// Create a Branch Region around a SwitchCase for code coverage
775 /// and add it to the function's SourceRegions.
776 void createSwitchCaseRegion(const SwitchCase
*SC
, Counter TrueCnt
,
778 // Push region onto RegionStack but immediately pop it (which adds it to
779 // the function's SourceRegions) because it doesn't apply to any other
780 // source other than the SwitchCase.
781 popRegions(pushRegion(TrueCnt
, getStart(SC
), SC
->getColonLoc(), FalseCnt
));
784 /// Check whether a region with bounds \c StartLoc and \c EndLoc
785 /// is already added to \c SourceRegions.
786 bool isRegionAlreadyAdded(SourceLocation StartLoc
, SourceLocation EndLoc
,
787 bool isBranch
= false) {
789 llvm::reverse(SourceRegions
), [&](const SourceMappingRegion
&Region
) {
790 return Region
.getBeginLoc() == StartLoc
&&
791 Region
.getEndLoc() == EndLoc
&& Region
.isBranch() == isBranch
;
795 /// Adjust the most recently visited location to \c EndLoc.
797 /// This should be used after visiting any statements in non-source order.
798 void adjustForOutOfOrderTraversal(SourceLocation EndLoc
) {
799 MostRecentLocation
= EndLoc
;
800 // The code region for a whole macro is created in handleFileExit() when
801 // it detects exiting of the virtual file of that macro. If we visited
802 // statements in non-source order, we might already have such a region
803 // added, for example, if a body of a loop is divided among multiple
804 // macros. Avoid adding duplicate regions in such case.
805 if (getRegion().hasEndLoc() &&
806 MostRecentLocation
== getEndOfFileOrMacro(MostRecentLocation
) &&
807 isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation
),
808 MostRecentLocation
, getRegion().isBranch()))
809 MostRecentLocation
= getIncludeOrExpansionLoc(MostRecentLocation
);
812 /// Adjust regions and state when \c NewLoc exits a file.
814 /// If moving from our most recently tracked location to \c NewLoc exits any
815 /// files, this adjusts our current region stack and creates the file regions
816 /// for the exited file.
817 void handleFileExit(SourceLocation NewLoc
) {
818 if (NewLoc
.isInvalid() ||
819 SM
.isWrittenInSameFile(MostRecentLocation
, NewLoc
))
822 // If NewLoc is not in a file that contains MostRecentLocation, walk up to
823 // find the common ancestor.
824 SourceLocation LCA
= NewLoc
;
825 FileID ParentFile
= SM
.getFileID(LCA
);
826 while (!isNestedIn(MostRecentLocation
, ParentFile
)) {
827 LCA
= getIncludeOrExpansionLoc(LCA
);
828 if (LCA
.isInvalid() || SM
.isWrittenInSameFile(LCA
, MostRecentLocation
)) {
829 // Since there isn't a common ancestor, no file was exited. We just need
830 // to adjust our location to the new file.
831 MostRecentLocation
= NewLoc
;
834 ParentFile
= SM
.getFileID(LCA
);
837 llvm::SmallSet
<SourceLocation
, 8> StartLocs
;
838 std::optional
<Counter
> ParentCounter
;
839 for (SourceMappingRegion
&I
: llvm::reverse(RegionStack
)) {
840 if (!I
.hasStartLoc())
842 SourceLocation Loc
= I
.getBeginLoc();
843 if (!isNestedIn(Loc
, ParentFile
)) {
844 ParentCounter
= I
.getCounter();
848 while (!SM
.isInFileID(Loc
, ParentFile
)) {
849 // The most nested region for each start location is the one with the
850 // correct count. We avoid creating redundant regions by stopping once
851 // we've seen this region.
852 if (StartLocs
.insert(Loc
).second
) {
854 SourceRegions
.emplace_back(I
.getCounter(), I
.getFalseCounter(), Loc
,
855 getEndOfFileOrMacro(Loc
), I
.isBranch());
857 SourceRegions
.emplace_back(I
.getCounter(), Loc
,
858 getEndOfFileOrMacro(Loc
));
860 Loc
= getIncludeOrExpansionLoc(Loc
);
862 I
.setStartLoc(getPreciseTokenLocEnd(Loc
));
866 // If the file is contained completely by another region and doesn't
867 // immediately start its own region, the whole file gets a region
868 // corresponding to the parent.
869 SourceLocation Loc
= MostRecentLocation
;
870 while (isNestedIn(Loc
, ParentFile
)) {
871 SourceLocation FileStart
= getStartOfFileOrMacro(Loc
);
872 if (StartLocs
.insert(FileStart
).second
) {
873 SourceRegions
.emplace_back(*ParentCounter
, FileStart
,
874 getEndOfFileOrMacro(Loc
));
875 assert(SpellingRegion(SM
, SourceRegions
.back()).isInSourceOrder());
877 Loc
= getIncludeOrExpansionLoc(Loc
);
881 MostRecentLocation
= NewLoc
;
884 /// Ensure that \c S is included in the current region.
885 void extendRegion(const Stmt
*S
) {
886 SourceMappingRegion
&Region
= getRegion();
887 SourceLocation StartLoc
= getStart(S
);
889 handleFileExit(StartLoc
);
890 if (!Region
.hasStartLoc())
891 Region
.setStartLoc(StartLoc
);
894 /// Mark \c S as a terminator, starting a zero region.
895 void terminateRegion(const Stmt
*S
) {
897 SourceMappingRegion
&Region
= getRegion();
898 SourceLocation EndLoc
= getEnd(S
);
899 if (!Region
.hasEndLoc())
900 Region
.setEndLoc(EndLoc
);
901 pushRegion(Counter::getZero());
902 HasTerminateStmt
= true;
905 /// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
906 std::optional
<SourceRange
> findGapAreaBetween(SourceLocation AfterLoc
,
907 SourceLocation BeforeLoc
) {
908 // If AfterLoc is in function-like macro, use the right parenthesis
910 if (AfterLoc
.isMacroID()) {
911 FileID FID
= SM
.getFileID(AfterLoc
);
912 const SrcMgr::ExpansionInfo
*EI
= &SM
.getSLocEntry(FID
).getExpansion();
913 if (EI
->isFunctionMacroExpansion())
914 AfterLoc
= EI
->getExpansionLocEnd();
917 size_t StartDepth
= locationDepth(AfterLoc
);
918 size_t EndDepth
= locationDepth(BeforeLoc
);
919 while (!SM
.isWrittenInSameFile(AfterLoc
, BeforeLoc
)) {
920 bool UnnestStart
= StartDepth
>= EndDepth
;
921 bool UnnestEnd
= EndDepth
>= StartDepth
;
923 assert(SM
.isWrittenInSameFile(getStartOfFileOrMacro(BeforeLoc
),
926 BeforeLoc
= getIncludeOrExpansionLoc(BeforeLoc
);
927 assert(BeforeLoc
.isValid());
931 assert(SM
.isWrittenInSameFile(AfterLoc
,
932 getEndOfFileOrMacro(AfterLoc
)));
934 AfterLoc
= getIncludeOrExpansionLoc(AfterLoc
);
935 assert(AfterLoc
.isValid());
936 AfterLoc
= getPreciseTokenLocEnd(AfterLoc
);
937 assert(AfterLoc
.isValid());
941 AfterLoc
= getPreciseTokenLocEnd(AfterLoc
);
942 // If the start and end locations of the gap are both within the same macro
943 // file, the range may not be in source order.
944 if (AfterLoc
.isMacroID() || BeforeLoc
.isMacroID())
946 if (!SM
.isWrittenInSameFile(AfterLoc
, BeforeLoc
) ||
947 !SpellingRegion(SM
, AfterLoc
, BeforeLoc
).isInSourceOrder())
949 return {{AfterLoc
, BeforeLoc
}};
952 /// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
953 void fillGapAreaWithCount(SourceLocation StartLoc
, SourceLocation EndLoc
,
955 if (StartLoc
== EndLoc
)
957 assert(SpellingRegion(SM
, StartLoc
, EndLoc
).isInSourceOrder());
958 handleFileExit(StartLoc
);
959 size_t Index
= pushRegion(Count
, StartLoc
, EndLoc
);
960 getRegion().setGap(true);
961 handleFileExit(EndLoc
);
965 /// Keep counts of breaks and continues inside loops.
966 struct BreakContinue
{
968 Counter ContinueCount
;
970 SmallVector
<BreakContinue
, 8> BreakContinueStack
;
972 CounterCoverageMappingBuilder(
973 CoverageMappingModuleGen
&CVM
,
974 llvm::DenseMap
<const Stmt
*, unsigned> &CounterMap
, SourceManager
&SM
,
975 const LangOptions
&LangOpts
)
976 : CoverageMappingBuilder(CVM
, SM
, LangOpts
), CounterMap(CounterMap
) {}
978 /// Write the mapping data to the output stream
979 void write(llvm::raw_ostream
&OS
) {
980 llvm::SmallVector
<unsigned, 8> VirtualFileMapping
;
981 gatherFileIDs(VirtualFileMapping
);
982 SourceRegionFilter Filter
= emitExpansionRegions();
983 emitSourceRegions(Filter
);
984 gatherSkippedRegions();
986 if (MappingRegions
.empty())
989 CoverageMappingWriter
Writer(VirtualFileMapping
, Builder
.getExpressions(),
994 void VisitStmt(const Stmt
*S
) {
995 if (S
->getBeginLoc().isValid())
997 const Stmt
*LastStmt
= nullptr;
998 bool SaveTerminateStmt
= HasTerminateStmt
;
999 HasTerminateStmt
= false;
1000 GapRegionCounter
= Counter::getZero();
1001 for (const Stmt
*Child
: S
->children())
1003 // If last statement contains terminate statements, add a gap area
1004 // between the two statements. Skipping attributed statements, because
1005 // they don't have valid start location.
1006 if (LastStmt
&& HasTerminateStmt
&& !isa
<AttributedStmt
>(Child
)) {
1007 auto Gap
= findGapAreaBetween(getEnd(LastStmt
), getStart(Child
));
1009 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(),
1011 SaveTerminateStmt
= true;
1012 HasTerminateStmt
= false;
1017 if (SaveTerminateStmt
)
1018 HasTerminateStmt
= true;
1019 handleFileExit(getEnd(S
));
1022 void VisitDecl(const Decl
*D
) {
1023 Stmt
*Body
= D
->getBody();
1025 // Do not propagate region counts into system headers unless collecting
1026 // coverage from system headers is explicitly enabled.
1027 if (!SystemHeadersCoverage
&& Body
&&
1028 SM
.isInSystemHeader(SM
.getSpellingLoc(getStart(Body
))))
1031 // Do not visit the artificial children nodes of defaulted methods. The
1032 // lexer may not be able to report back precise token end locations for
1033 // these children nodes (llvm.org/PR39822), and moreover users will not be
1034 // able to see coverage for them.
1035 bool Defaulted
= false;
1036 if (auto *Method
= dyn_cast
<CXXMethodDecl
>(D
))
1037 Defaulted
= Method
->isDefaulted();
1039 propagateCounts(getRegionCounter(Body
), Body
,
1040 /*VisitChildren=*/!Defaulted
);
1041 assert(RegionStack
.empty() && "Regions entered but never exited");
1044 void VisitReturnStmt(const ReturnStmt
*S
) {
1046 if (S
->getRetValue())
1047 Visit(S
->getRetValue());
1051 void VisitCoroutineBodyStmt(const CoroutineBodyStmt
*S
) {
1053 Visit(S
->getBody());
1056 void VisitCoreturnStmt(const CoreturnStmt
*S
) {
1058 if (S
->getOperand())
1059 Visit(S
->getOperand());
1063 void VisitCXXThrowExpr(const CXXThrowExpr
*E
) {
1065 if (E
->getSubExpr())
1066 Visit(E
->getSubExpr());
1070 void VisitGotoStmt(const GotoStmt
*S
) { terminateRegion(S
); }
1072 void VisitLabelStmt(const LabelStmt
*S
) {
1073 Counter LabelCount
= getRegionCounter(S
);
1074 SourceLocation Start
= getStart(S
);
1075 // We can't extendRegion here or we risk overlapping with our new region.
1076 handleFileExit(Start
);
1077 pushRegion(LabelCount
, Start
);
1078 Visit(S
->getSubStmt());
1081 void VisitBreakStmt(const BreakStmt
*S
) {
1082 assert(!BreakContinueStack
.empty() && "break not in a loop or switch!");
1083 BreakContinueStack
.back().BreakCount
= addCounters(
1084 BreakContinueStack
.back().BreakCount
, getRegion().getCounter());
1085 // FIXME: a break in a switch should terminate regions for all preceding
1086 // case statements, not just the most recent one.
1090 void VisitContinueStmt(const ContinueStmt
*S
) {
1091 assert(!BreakContinueStack
.empty() && "continue stmt not in a loop!");
1092 BreakContinueStack
.back().ContinueCount
= addCounters(
1093 BreakContinueStack
.back().ContinueCount
, getRegion().getCounter());
1097 void VisitCallExpr(const CallExpr
*E
) {
1100 // Terminate the region when we hit a noreturn function.
1101 // (This is helpful dealing with switch statements.)
1102 QualType CalleeType
= E
->getCallee()->getType();
1103 if (getFunctionExtInfo(*CalleeType
).getNoReturn())
1107 void VisitWhileStmt(const WhileStmt
*S
) {
1110 Counter ParentCount
= getRegion().getCounter();
1111 Counter BodyCount
= getRegionCounter(S
);
1113 // Handle the body first so that we can get the backedge count.
1114 BreakContinueStack
.push_back(BreakContinue());
1115 extendRegion(S
->getBody());
1116 Counter BackedgeCount
= propagateCounts(BodyCount
, S
->getBody());
1117 BreakContinue BC
= BreakContinueStack
.pop_back_val();
1119 bool BodyHasTerminateStmt
= HasTerminateStmt
;
1120 HasTerminateStmt
= false;
1122 // Go back to handle the condition.
1124 addCounters(ParentCount
, BackedgeCount
, BC
.ContinueCount
);
1125 propagateCounts(CondCount
, S
->getCond());
1126 adjustForOutOfOrderTraversal(getEnd(S
));
1128 // The body count applies to the area immediately after the increment.
1129 auto Gap
= findGapAreaBetween(S
->getRParenLoc(), getStart(S
->getBody()));
1131 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), BodyCount
);
1134 addCounters(BC
.BreakCount
, subtractCounters(CondCount
, BodyCount
));
1135 if (OutCount
!= ParentCount
) {
1136 pushRegion(OutCount
);
1137 GapRegionCounter
= OutCount
;
1138 if (BodyHasTerminateStmt
)
1139 HasTerminateStmt
= true;
1142 // Create Branch Region around condition.
1143 createBranchRegion(S
->getCond(), BodyCount
,
1144 subtractCounters(CondCount
, BodyCount
));
1147 void VisitDoStmt(const DoStmt
*S
) {
1150 Counter ParentCount
= getRegion().getCounter();
1151 Counter BodyCount
= getRegionCounter(S
);
1153 BreakContinueStack
.push_back(BreakContinue());
1154 extendRegion(S
->getBody());
1155 Counter BackedgeCount
=
1156 propagateCounts(addCounters(ParentCount
, BodyCount
), S
->getBody());
1157 BreakContinue BC
= BreakContinueStack
.pop_back_val();
1159 bool BodyHasTerminateStmt
= HasTerminateStmt
;
1160 HasTerminateStmt
= false;
1162 Counter CondCount
= addCounters(BackedgeCount
, BC
.ContinueCount
);
1163 propagateCounts(CondCount
, S
->getCond());
1166 addCounters(BC
.BreakCount
, subtractCounters(CondCount
, BodyCount
));
1167 if (OutCount
!= ParentCount
) {
1168 pushRegion(OutCount
);
1169 GapRegionCounter
= OutCount
;
1172 // Create Branch Region around condition.
1173 createBranchRegion(S
->getCond(), BodyCount
,
1174 subtractCounters(CondCount
, BodyCount
));
1176 if (BodyHasTerminateStmt
)
1177 HasTerminateStmt
= true;
1180 void VisitForStmt(const ForStmt
*S
) {
1183 Visit(S
->getInit());
1185 Counter ParentCount
= getRegion().getCounter();
1186 Counter BodyCount
= getRegionCounter(S
);
1188 // The loop increment may contain a break or continue.
1190 BreakContinueStack
.emplace_back();
1192 // Handle the body first so that we can get the backedge count.
1193 BreakContinueStack
.emplace_back();
1194 extendRegion(S
->getBody());
1195 Counter BackedgeCount
= propagateCounts(BodyCount
, S
->getBody());
1196 BreakContinue BodyBC
= BreakContinueStack
.pop_back_val();
1198 bool BodyHasTerminateStmt
= HasTerminateStmt
;
1199 HasTerminateStmt
= false;
1201 // The increment is essentially part of the body but it needs to include
1202 // the count for all the continue statements.
1203 BreakContinue IncrementBC
;
1204 if (const Stmt
*Inc
= S
->getInc()) {
1205 propagateCounts(addCounters(BackedgeCount
, BodyBC
.ContinueCount
), Inc
);
1206 IncrementBC
= BreakContinueStack
.pop_back_val();
1209 // Go back to handle the condition.
1210 Counter CondCount
= addCounters(
1211 addCounters(ParentCount
, BackedgeCount
, BodyBC
.ContinueCount
),
1212 IncrementBC
.ContinueCount
);
1213 if (const Expr
*Cond
= S
->getCond()) {
1214 propagateCounts(CondCount
, Cond
);
1215 adjustForOutOfOrderTraversal(getEnd(S
));
1218 // The body count applies to the area immediately after the increment.
1219 auto Gap
= findGapAreaBetween(S
->getRParenLoc(), getStart(S
->getBody()));
1221 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), BodyCount
);
1223 Counter OutCount
= addCounters(BodyBC
.BreakCount
, IncrementBC
.BreakCount
,
1224 subtractCounters(CondCount
, BodyCount
));
1225 if (OutCount
!= ParentCount
) {
1226 pushRegion(OutCount
);
1227 GapRegionCounter
= OutCount
;
1228 if (BodyHasTerminateStmt
)
1229 HasTerminateStmt
= true;
1232 // Create Branch Region around condition.
1233 createBranchRegion(S
->getCond(), BodyCount
,
1234 subtractCounters(CondCount
, BodyCount
));
1237 void VisitCXXForRangeStmt(const CXXForRangeStmt
*S
) {
1240 Visit(S
->getInit());
1241 Visit(S
->getLoopVarStmt());
1242 Visit(S
->getRangeStmt());
1244 Counter ParentCount
= getRegion().getCounter();
1245 Counter BodyCount
= getRegionCounter(S
);
1247 BreakContinueStack
.push_back(BreakContinue());
1248 extendRegion(S
->getBody());
1249 Counter BackedgeCount
= propagateCounts(BodyCount
, S
->getBody());
1250 BreakContinue BC
= BreakContinueStack
.pop_back_val();
1252 bool BodyHasTerminateStmt
= HasTerminateStmt
;
1253 HasTerminateStmt
= false;
1255 // The body count applies to the area immediately after the range.
1256 auto Gap
= findGapAreaBetween(S
->getRParenLoc(), getStart(S
->getBody()));
1258 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), BodyCount
);
1261 addCounters(ParentCount
, BackedgeCount
, BC
.ContinueCount
);
1263 addCounters(BC
.BreakCount
, subtractCounters(LoopCount
, BodyCount
));
1264 if (OutCount
!= ParentCount
) {
1265 pushRegion(OutCount
);
1266 GapRegionCounter
= OutCount
;
1267 if (BodyHasTerminateStmt
)
1268 HasTerminateStmt
= true;
1271 // Create Branch Region around condition.
1272 createBranchRegion(S
->getCond(), BodyCount
,
1273 subtractCounters(LoopCount
, BodyCount
));
1276 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt
*S
) {
1278 Visit(S
->getElement());
1280 Counter ParentCount
= getRegion().getCounter();
1281 Counter BodyCount
= getRegionCounter(S
);
1283 BreakContinueStack
.push_back(BreakContinue());
1284 extendRegion(S
->getBody());
1285 Counter BackedgeCount
= propagateCounts(BodyCount
, S
->getBody());
1286 BreakContinue BC
= BreakContinueStack
.pop_back_val();
1288 // The body count applies to the area immediately after the collection.
1289 auto Gap
= findGapAreaBetween(S
->getRParenLoc(), getStart(S
->getBody()));
1291 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), BodyCount
);
1294 addCounters(ParentCount
, BackedgeCount
, BC
.ContinueCount
);
1296 addCounters(BC
.BreakCount
, subtractCounters(LoopCount
, BodyCount
));
1297 if (OutCount
!= ParentCount
) {
1298 pushRegion(OutCount
);
1299 GapRegionCounter
= OutCount
;
1303 void VisitSwitchStmt(const SwitchStmt
*S
) {
1306 Visit(S
->getInit());
1307 Visit(S
->getCond());
1309 BreakContinueStack
.push_back(BreakContinue());
1311 const Stmt
*Body
= S
->getBody();
1313 if (const auto *CS
= dyn_cast
<CompoundStmt
>(Body
)) {
1314 if (!CS
->body_empty()) {
1315 // Make a region for the body of the switch. If the body starts with
1316 // a case, that case will reuse this region; otherwise, this covers
1317 // the unreachable code at the beginning of the switch body.
1318 size_t Index
= pushRegion(Counter::getZero(), getStart(CS
));
1319 getRegion().setGap(true);
1322 // Set the end for the body of the switch, if it isn't already set.
1323 for (size_t i
= RegionStack
.size(); i
!= Index
; --i
) {
1324 if (!RegionStack
[i
- 1].hasEndLoc())
1325 RegionStack
[i
- 1].setEndLoc(getEnd(CS
->body_back()));
1331 propagateCounts(Counter::getZero(), Body
);
1332 BreakContinue BC
= BreakContinueStack
.pop_back_val();
1334 if (!BreakContinueStack
.empty())
1335 BreakContinueStack
.back().ContinueCount
= addCounters(
1336 BreakContinueStack
.back().ContinueCount
, BC
.ContinueCount
);
1338 Counter ParentCount
= getRegion().getCounter();
1339 Counter ExitCount
= getRegionCounter(S
);
1340 SourceLocation ExitLoc
= getEnd(S
);
1341 pushRegion(ExitCount
);
1342 GapRegionCounter
= ExitCount
;
1344 // Ensure that handleFileExit recognizes when the end location is located
1345 // in a different file.
1346 MostRecentLocation
= getStart(S
);
1347 handleFileExit(ExitLoc
);
1349 // Create a Branch Region around each Case. Subtract the case's
1350 // counter from the Parent counter to track the "False" branch count.
1351 Counter CaseCountSum
;
1352 bool HasDefaultCase
= false;
1353 const SwitchCase
*Case
= S
->getSwitchCaseList();
1354 for (; Case
; Case
= Case
->getNextSwitchCase()) {
1355 HasDefaultCase
= HasDefaultCase
|| isa
<DefaultStmt
>(Case
);
1357 addCounters(CaseCountSum
, getRegionCounter(Case
), /*Simplify=*/false);
1358 createSwitchCaseRegion(
1359 Case
, getRegionCounter(Case
),
1360 subtractCounters(ParentCount
, getRegionCounter(Case
)));
1362 // Simplify is skipped while building the counters above: it can get really
1363 // slow on top of switches with thousands of cases. Instead, trigger
1364 // simplification by adding zero to the last counter.
1365 CaseCountSum
= addCounters(CaseCountSum
, Counter::getZero());
1367 // If no explicit default case exists, create a branch region to represent
1368 // the hidden branch, which will be added later by the CodeGen. This region
1369 // will be associated with the switch statement's condition.
1370 if (!HasDefaultCase
) {
1371 Counter DefaultTrue
= subtractCounters(ParentCount
, CaseCountSum
);
1372 Counter DefaultFalse
= subtractCounters(ParentCount
, DefaultTrue
);
1373 createBranchRegion(S
->getCond(), DefaultTrue
, DefaultFalse
);
1377 void VisitSwitchCase(const SwitchCase
*S
) {
1380 SourceMappingRegion
&Parent
= getRegion();
1382 Counter Count
= addCounters(Parent
.getCounter(), getRegionCounter(S
));
1383 // Reuse the existing region if it starts at our label. This is typical of
1384 // the first case in a switch.
1385 if (Parent
.hasStartLoc() && Parent
.getBeginLoc() == getStart(S
))
1386 Parent
.setCounter(Count
);
1388 pushRegion(Count
, getStart(S
));
1390 GapRegionCounter
= Count
;
1392 if (const auto *CS
= dyn_cast
<CaseStmt
>(S
)) {
1393 Visit(CS
->getLHS());
1394 if (const Expr
*RHS
= CS
->getRHS())
1397 Visit(S
->getSubStmt());
1400 void VisitIfStmt(const IfStmt
*S
) {
1403 Visit(S
->getInit());
1405 // Extend into the condition before we propagate through it below - this is
1406 // needed to handle macros that generate the "if" but not the condition.
1407 if (!S
->isConsteval())
1408 extendRegion(S
->getCond());
1410 Counter ParentCount
= getRegion().getCounter();
1411 Counter ThenCount
= getRegionCounter(S
);
1413 if (!S
->isConsteval()) {
1414 // Emitting a counter for the condition makes it easier to interpret the
1415 // counter for the body when looking at the coverage.
1416 propagateCounts(ParentCount
, S
->getCond());
1418 // The 'then' count applies to the area immediately after the condition.
1419 std::optional
<SourceRange
> Gap
=
1420 findGapAreaBetween(S
->getRParenLoc(), getStart(S
->getThen()));
1422 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), ThenCount
);
1425 extendRegion(S
->getThen());
1426 Counter OutCount
= propagateCounts(ThenCount
, S
->getThen());
1428 Counter ElseCount
= subtractCounters(ParentCount
, ThenCount
);
1429 if (const Stmt
*Else
= S
->getElse()) {
1430 bool ThenHasTerminateStmt
= HasTerminateStmt
;
1431 HasTerminateStmt
= false;
1432 // The 'else' count applies to the area immediately after the 'then'.
1433 std::optional
<SourceRange
> Gap
=
1434 findGapAreaBetween(getEnd(S
->getThen()), getStart(Else
));
1436 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), ElseCount
);
1438 OutCount
= addCounters(OutCount
, propagateCounts(ElseCount
, Else
));
1440 if (ThenHasTerminateStmt
)
1441 HasTerminateStmt
= true;
1443 OutCount
= addCounters(OutCount
, ElseCount
);
1445 if (OutCount
!= ParentCount
) {
1446 pushRegion(OutCount
);
1447 GapRegionCounter
= OutCount
;
1450 if (!S
->isConsteval()) {
1451 // Create Branch Region around condition.
1452 createBranchRegion(S
->getCond(), ThenCount
,
1453 subtractCounters(ParentCount
, ThenCount
));
1457 void VisitCXXTryStmt(const CXXTryStmt
*S
) {
1459 // Handle macros that generate the "try" but not the rest.
1460 extendRegion(S
->getTryBlock());
1462 Counter ParentCount
= getRegion().getCounter();
1463 propagateCounts(ParentCount
, S
->getTryBlock());
1465 for (unsigned I
= 0, E
= S
->getNumHandlers(); I
< E
; ++I
)
1466 Visit(S
->getHandler(I
));
1468 Counter ExitCount
= getRegionCounter(S
);
1469 pushRegion(ExitCount
);
1472 void VisitCXXCatchStmt(const CXXCatchStmt
*S
) {
1473 propagateCounts(getRegionCounter(S
), S
->getHandlerBlock());
1476 void VisitAbstractConditionalOperator(const AbstractConditionalOperator
*E
) {
1479 Counter ParentCount
= getRegion().getCounter();
1480 Counter TrueCount
= getRegionCounter(E
);
1482 propagateCounts(ParentCount
, E
->getCond());
1485 if (!isa
<BinaryConditionalOperator
>(E
)) {
1486 // The 'then' count applies to the area immediately after the condition.
1488 findGapAreaBetween(E
->getQuestionLoc(), getStart(E
->getTrueExpr()));
1490 fillGapAreaWithCount(Gap
->getBegin(), Gap
->getEnd(), TrueCount
);
1492 extendRegion(E
->getTrueExpr());
1493 OutCount
= propagateCounts(TrueCount
, E
->getTrueExpr());
1496 extendRegion(E
->getFalseExpr());
1497 OutCount
= addCounters(
1498 OutCount
, propagateCounts(subtractCounters(ParentCount
, TrueCount
),
1499 E
->getFalseExpr()));
1501 if (OutCount
!= ParentCount
) {
1502 pushRegion(OutCount
);
1503 GapRegionCounter
= OutCount
;
1506 // Create Branch Region around condition.
1507 createBranchRegion(E
->getCond(), TrueCount
,
1508 subtractCounters(ParentCount
, TrueCount
));
1511 void VisitBinLAnd(const BinaryOperator
*E
) {
1512 extendRegion(E
->getLHS());
1513 propagateCounts(getRegion().getCounter(), E
->getLHS());
1514 handleFileExit(getEnd(E
->getLHS()));
1516 // Counter tracks the right hand side of a logical and operator.
1517 extendRegion(E
->getRHS());
1518 propagateCounts(getRegionCounter(E
), E
->getRHS());
1520 // Extract the RHS's Execution Counter.
1521 Counter RHSExecCnt
= getRegionCounter(E
);
1523 // Extract the RHS's "True" Instance Counter.
1524 Counter RHSTrueCnt
= getRegionCounter(E
->getRHS());
1526 // Extract the Parent Region Counter.
1527 Counter ParentCnt
= getRegion().getCounter();
1529 // Create Branch Region around LHS condition.
1530 createBranchRegion(E
->getLHS(), RHSExecCnt
,
1531 subtractCounters(ParentCnt
, RHSExecCnt
));
1533 // Create Branch Region around RHS condition.
1534 createBranchRegion(E
->getRHS(), RHSTrueCnt
,
1535 subtractCounters(RHSExecCnt
, RHSTrueCnt
));
1538 // Determine whether the right side of OR operation need to be visited.
1539 bool shouldVisitRHS(const Expr
*LHS
) {
1540 bool LHSIsTrue
= false;
1541 bool LHSIsConst
= false;
1542 if (!LHS
->isValueDependent())
1543 LHSIsConst
= LHS
->EvaluateAsBooleanCondition(
1544 LHSIsTrue
, CVM
.getCodeGenModule().getContext());
1545 return !LHSIsConst
|| (LHSIsConst
&& !LHSIsTrue
);
1548 void VisitBinLOr(const BinaryOperator
*E
) {
1549 extendRegion(E
->getLHS());
1550 Counter OutCount
= propagateCounts(getRegion().getCounter(), E
->getLHS());
1551 handleFileExit(getEnd(E
->getLHS()));
1553 // Counter tracks the right hand side of a logical or operator.
1554 extendRegion(E
->getRHS());
1555 propagateCounts(getRegionCounter(E
), E
->getRHS());
1557 // Extract the RHS's Execution Counter.
1558 Counter RHSExecCnt
= getRegionCounter(E
);
1560 // Extract the RHS's "False" Instance Counter.
1561 Counter RHSFalseCnt
= getRegionCounter(E
->getRHS());
1563 if (!shouldVisitRHS(E
->getLHS())) {
1564 GapRegionCounter
= OutCount
;
1567 // Extract the Parent Region Counter.
1568 Counter ParentCnt
= getRegion().getCounter();
1570 // Create Branch Region around LHS condition.
1571 createBranchRegion(E
->getLHS(), subtractCounters(ParentCnt
, RHSExecCnt
),
1574 // Create Branch Region around RHS condition.
1575 createBranchRegion(E
->getRHS(), subtractCounters(RHSExecCnt
, RHSFalseCnt
),
1579 void VisitLambdaExpr(const LambdaExpr
*LE
) {
1580 // Lambdas are treated as their own functions for now, so we shouldn't
1581 // propagate counts into them.
1584 void VisitPseudoObjectExpr(const PseudoObjectExpr
*POE
) {
1585 // Just visit syntatic expression as this is what users actually write.
1586 VisitStmt(POE
->getSyntacticForm());
1589 void VisitOpaqueValueExpr(const OpaqueValueExpr
* OVE
) {
1590 Visit(OVE
->getSourceExpr());
1594 } // end anonymous namespace
1596 static void dump(llvm::raw_ostream
&OS
, StringRef FunctionName
,
1597 ArrayRef
<CounterExpression
> Expressions
,
1598 ArrayRef
<CounterMappingRegion
> Regions
) {
1599 OS
<< FunctionName
<< ":\n";
1600 CounterMappingContext
Ctx(Expressions
);
1601 for (const auto &R
: Regions
) {
1604 case CounterMappingRegion::CodeRegion
:
1606 case CounterMappingRegion::ExpansionRegion
:
1609 case CounterMappingRegion::SkippedRegion
:
1612 case CounterMappingRegion::GapRegion
:
1615 case CounterMappingRegion::BranchRegion
:
1620 OS
<< "File " << R
.FileID
<< ", " << R
.LineStart
<< ":" << R
.ColumnStart
1621 << " -> " << R
.LineEnd
<< ":" << R
.ColumnEnd
<< " = ";
1622 Ctx
.dump(R
.Count
, OS
);
1624 if (R
.Kind
== CounterMappingRegion::BranchRegion
) {
1626 Ctx
.dump(R
.FalseCount
, OS
);
1629 if (R
.Kind
== CounterMappingRegion::ExpansionRegion
)
1630 OS
<< " (Expanded file = " << R
.ExpandedFileID
<< ")";
1635 CoverageMappingModuleGen::CoverageMappingModuleGen(
1636 CodeGenModule
&CGM
, CoverageSourceInfo
&SourceInfo
)
1637 : CGM(CGM
), SourceInfo(SourceInfo
) {}
1639 std::string
CoverageMappingModuleGen::getCurrentDirname() {
1640 if (!CGM
.getCodeGenOpts().CoverageCompilationDir
.empty())
1641 return CGM
.getCodeGenOpts().CoverageCompilationDir
;
1643 SmallString
<256> CWD
;
1644 llvm::sys::fs::current_path(CWD
);
1645 return CWD
.str().str();
1648 std::string
CoverageMappingModuleGen::normalizeFilename(StringRef Filename
) {
1649 llvm::SmallString
<256> Path(Filename
);
1650 llvm::sys::path::remove_dots(Path
, /*remove_dot_dot=*/true);
1652 /// Traverse coverage prefix map in reverse order because prefix replacements
1653 /// are applied in reverse order starting from the last one when multiple
1654 /// prefix replacement options are provided.
1655 for (const auto &[From
, To
] :
1656 llvm::reverse(CGM
.getCodeGenOpts().CoveragePrefixMap
)) {
1657 if (llvm::sys::path::replace_path_prefix(Path
, From
, To
))
1660 return Path
.str().str();
1663 static std::string
getInstrProfSection(const CodeGenModule
&CGM
,
1664 llvm::InstrProfSectKind SK
) {
1665 return llvm::getInstrProfSectionName(
1666 SK
, CGM
.getContext().getTargetInfo().getTriple().getObjectFormat());
1669 void CoverageMappingModuleGen::emitFunctionMappingRecord(
1670 const FunctionInfo
&Info
, uint64_t FilenamesRef
) {
1671 llvm::LLVMContext
&Ctx
= CGM
.getLLVMContext();
1673 // Assign a name to the function record. This is used to merge duplicates.
1674 std::string FuncRecordName
= "__covrec_" + llvm::utohexstr(Info
.NameHash
);
1676 // A dummy description for a function included-but-not-used in a TU can be
1677 // replaced by full description provided by a different TU. The two kinds of
1678 // descriptions play distinct roles: therefore, assign them different names
1679 // to prevent `linkonce_odr` merging.
1681 FuncRecordName
+= "u";
1683 // Create the function record type.
1684 const uint64_t NameHash
= Info
.NameHash
;
1685 const uint64_t FuncHash
= Info
.FuncHash
;
1686 const std::string
&CoverageMapping
= Info
.CoverageMapping
;
1687 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
1688 llvm::Type
*FunctionRecordTypes
[] = {
1689 #include "llvm/ProfileData/InstrProfData.inc"
1691 auto *FunctionRecordTy
=
1692 llvm::StructType::get(Ctx
, ArrayRef(FunctionRecordTypes
),
1695 // Create the function record constant.
1696 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
1697 llvm::Constant
*FunctionRecordVals
[] = {
1698 #include "llvm/ProfileData/InstrProfData.inc"
1700 auto *FuncRecordConstant
=
1701 llvm::ConstantStruct::get(FunctionRecordTy
, ArrayRef(FunctionRecordVals
));
1703 // Create the function record global.
1704 auto *FuncRecord
= new llvm::GlobalVariable(
1705 CGM
.getModule(), FunctionRecordTy
, /*isConstant=*/true,
1706 llvm::GlobalValue::LinkOnceODRLinkage
, FuncRecordConstant
,
1708 FuncRecord
->setVisibility(llvm::GlobalValue::HiddenVisibility
);
1709 FuncRecord
->setSection(getInstrProfSection(CGM
, llvm::IPSK_covfun
));
1710 FuncRecord
->setAlignment(llvm::Align(8));
1711 if (CGM
.supportsCOMDAT())
1712 FuncRecord
->setComdat(CGM
.getModule().getOrInsertComdat(FuncRecordName
));
1714 // Make sure the data doesn't get deleted.
1715 CGM
.addUsedGlobal(FuncRecord
);
1718 void CoverageMappingModuleGen::addFunctionMappingRecord(
1719 llvm::GlobalVariable
*NamePtr
, StringRef NameValue
, uint64_t FuncHash
,
1720 const std::string
&CoverageMapping
, bool IsUsed
) {
1721 llvm::LLVMContext
&Ctx
= CGM
.getLLVMContext();
1722 const uint64_t NameHash
= llvm::IndexedInstrProf::ComputeHash(NameValue
);
1723 FunctionRecords
.push_back({NameHash
, FuncHash
, CoverageMapping
, IsUsed
});
1726 FunctionNames
.push_back(
1727 llvm::ConstantExpr::getBitCast(NamePtr
, llvm::Type::getInt8PtrTy(Ctx
)));
1729 if (CGM
.getCodeGenOpts().DumpCoverageMapping
) {
1730 // Dump the coverage mapping data for this function by decoding the
1731 // encoded data. This allows us to dump the mapping regions which were
1732 // also processed by the CoverageMappingWriter which performs
1733 // additional minimization operations such as reducing the number of
1735 llvm::SmallVector
<std::string
, 16> FilenameStrs
;
1736 std::vector
<StringRef
> Filenames
;
1737 std::vector
<CounterExpression
> Expressions
;
1738 std::vector
<CounterMappingRegion
> Regions
;
1739 FilenameStrs
.resize(FileEntries
.size() + 1);
1740 FilenameStrs
[0] = normalizeFilename(getCurrentDirname());
1741 for (const auto &Entry
: FileEntries
) {
1742 auto I
= Entry
.second
;
1743 FilenameStrs
[I
] = normalizeFilename(Entry
.first
->getName());
1745 ArrayRef
<std::string
> FilenameRefs
= llvm::ArrayRef(FilenameStrs
);
1746 RawCoverageMappingReader
Reader(CoverageMapping
, FilenameRefs
, Filenames
,
1747 Expressions
, Regions
);
1750 dump(llvm::outs(), NameValue
, Expressions
, Regions
);
1754 void CoverageMappingModuleGen::emit() {
1755 if (FunctionRecords
.empty())
1757 llvm::LLVMContext
&Ctx
= CGM
.getLLVMContext();
1758 auto *Int32Ty
= llvm::Type::getInt32Ty(Ctx
);
1760 // Create the filenames and merge them with coverage mappings
1761 llvm::SmallVector
<std::string
, 16> FilenameStrs
;
1762 FilenameStrs
.resize(FileEntries
.size() + 1);
1763 // The first filename is the current working directory.
1764 FilenameStrs
[0] = normalizeFilename(getCurrentDirname());
1765 for (const auto &Entry
: FileEntries
) {
1766 auto I
= Entry
.second
;
1767 FilenameStrs
[I
] = normalizeFilename(Entry
.first
->getName());
1770 std::string Filenames
;
1772 llvm::raw_string_ostream
OS(Filenames
);
1773 CoverageFilenamesSectionWriter(FilenameStrs
).write(OS
);
1775 auto *FilenamesVal
=
1776 llvm::ConstantDataArray::getString(Ctx
, Filenames
, false);
1777 const int64_t FilenamesRef
= llvm::IndexedInstrProf::ComputeHash(Filenames
);
1779 // Emit the function records.
1780 for (const FunctionInfo
&Info
: FunctionRecords
)
1781 emitFunctionMappingRecord(Info
, FilenamesRef
);
1783 const unsigned NRecords
= 0;
1784 const size_t FilenamesSize
= Filenames
.size();
1785 const unsigned CoverageMappingSize
= 0;
1786 llvm::Type
*CovDataHeaderTypes
[] = {
1787 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1788 #include "llvm/ProfileData/InstrProfData.inc"
1790 auto CovDataHeaderTy
=
1791 llvm::StructType::get(Ctx
, ArrayRef(CovDataHeaderTypes
));
1792 llvm::Constant
*CovDataHeaderVals
[] = {
1793 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1794 #include "llvm/ProfileData/InstrProfData.inc"
1796 auto CovDataHeaderVal
=
1797 llvm::ConstantStruct::get(CovDataHeaderTy
, ArrayRef(CovDataHeaderVals
));
1799 // Create the coverage data record
1800 llvm::Type
*CovDataTypes
[] = {CovDataHeaderTy
, FilenamesVal
->getType()};
1801 auto CovDataTy
= llvm::StructType::get(Ctx
, ArrayRef(CovDataTypes
));
1802 llvm::Constant
*TUDataVals
[] = {CovDataHeaderVal
, FilenamesVal
};
1803 auto CovDataVal
= llvm::ConstantStruct::get(CovDataTy
, ArrayRef(TUDataVals
));
1804 auto CovData
= new llvm::GlobalVariable(
1805 CGM
.getModule(), CovDataTy
, true, llvm::GlobalValue::PrivateLinkage
,
1806 CovDataVal
, llvm::getCoverageMappingVarName());
1808 CovData
->setSection(getInstrProfSection(CGM
, llvm::IPSK_covmap
));
1809 CovData
->setAlignment(llvm::Align(8));
1811 // Make sure the data doesn't get deleted.
1812 CGM
.addUsedGlobal(CovData
);
1813 // Create the deferred function records array
1814 if (!FunctionNames
.empty()) {
1815 auto NamesArrTy
= llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx
),
1816 FunctionNames
.size());
1817 auto NamesArrVal
= llvm::ConstantArray::get(NamesArrTy
, FunctionNames
);
1818 // This variable will *NOT* be emitted to the object file. It is used
1819 // to pass the list of names referenced to codegen.
1820 new llvm::GlobalVariable(CGM
.getModule(), NamesArrTy
, true,
1821 llvm::GlobalValue::InternalLinkage
, NamesArrVal
,
1822 llvm::getCoverageUnusedNamesVarName());
1826 unsigned CoverageMappingModuleGen::getFileID(const FileEntry
*File
) {
1827 auto It
= FileEntries
.find(File
);
1828 if (It
!= FileEntries
.end())
1830 unsigned FileID
= FileEntries
.size() + 1;
1831 FileEntries
.insert(std::make_pair(File
, FileID
));
1835 void CoverageMappingGen::emitCounterMapping(const Decl
*D
,
1836 llvm::raw_ostream
&OS
) {
1838 CounterCoverageMappingBuilder
Walker(CVM
, *CounterMap
, SM
, LangOpts
);
1839 Walker
.VisitDecl(D
);
1843 void CoverageMappingGen::emitEmptyMapping(const Decl
*D
,
1844 llvm::raw_ostream
&OS
) {
1845 EmptyCoverageMappingBuilder
Walker(CVM
, SM
, LangOpts
);
1846 Walker
.VisitDecl(D
);