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