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