1 //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Instrumentation-based code coverage mapping generator 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CoverageMappingGen.h" 15 #include "CodeGenFunction.h" 16 #include "clang/AST/StmtVisitor.h" 17 #include "clang/Lex/Lexer.h" 18 #include "llvm/ProfileData/CoverageMapping.h" 19 #include "llvm/ProfileData/CoverageMappingReader.h" 20 #include "llvm/ProfileData/CoverageMappingWriter.h" 21 #include "llvm/ProfileData/InstrProfReader.h" 22 #include "llvm/Support/FileSystem.h" 23 24 using namespace clang; 25 using namespace CodeGen; 26 using namespace llvm::coverage; 27 28 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) { 29 SkippedRanges.push_back(Range); 30 } 31 32 namespace { 33 34 /// \brief A region of source code that can be mapped to a counter. 35 class SourceMappingRegion { 36 public: 37 enum RegionFlags { 38 /// \brief This region won't be emitted if it wasn't extended. 39 /// This is useful so that we won't emit source ranges for single tokens 40 /// that we don't really care that much about, like: 41 /// the '(' token in #define MACRO ( 42 IgnoreIfNotExtended = 0x0001, 43 }; 44 45 private: 46 FileID File, MacroArgumentFile; 47 48 Counter Count; 49 50 /// \brief A statement that initiated the count of Zero. 51 /// 52 /// This initiator statement is useful to prevent merging of unreachable 53 /// regions with different statements that caused the counter to become 54 /// unreachable. 55 const Stmt *UnreachableInitiator; 56 57 /// \brief A statement that separates certain mapping regions into groups. 58 /// 59 /// The group statement is sometimes useful when we are emitting the source 60 /// regions not in their correct lexical order, e.g. the regions for the 61 /// incrementation expression in the 'for' construct. By marking the regions 62 /// in the incrementation expression with the group statement, we avoid the 63 /// merging of the regions from the incrementation expression and the loop's 64 /// body. 65 const Stmt *Group; 66 67 /// \brief The region's starting location. 68 SourceLocation LocStart; 69 70 /// \brief The region's ending location. 71 SourceLocation LocEnd, AlternativeLocEnd; 72 unsigned Flags; 73 74 public: 75 SourceMappingRegion(FileID File, FileID MacroArgumentFile, Counter Count, 76 const Stmt *UnreachableInitiator, const Stmt *Group, 77 SourceLocation LocStart, SourceLocation LocEnd, 78 unsigned Flags = 0) 79 : File(File), MacroArgumentFile(MacroArgumentFile), Count(Count), 80 UnreachableInitiator(UnreachableInitiator), Group(Group), 81 LocStart(LocStart), LocEnd(LocEnd), AlternativeLocEnd(LocStart), 82 Flags(Flags) {} 83 84 const FileID &getFile() const { return File; } 85 86 const Counter &getCounter() const { return Count; } 87 88 const SourceLocation &getStartLoc() const { return LocStart; } 89 90 const SourceLocation &getEndLoc(const SourceManager &SM) const { 91 if (SM.getFileID(LocEnd) != File) 92 return AlternativeLocEnd; 93 return LocEnd; 94 } 95 96 bool hasFlag(RegionFlags Flag) const { return (Flags & Flag) != 0; } 97 98 void setFlag(RegionFlags Flag) { Flags |= Flag; } 99 100 void clearFlag(RegionFlags Flag) { Flags &= ~Flag; } 101 102 /// \brief Return true if two regions can be merged together. 103 bool isMergeable(SourceMappingRegion &R) { 104 // FIXME: We allow merging regions with a gap in between them. Should we? 105 return File == R.File && MacroArgumentFile == R.MacroArgumentFile && 106 Count == R.Count && UnreachableInitiator == R.UnreachableInitiator && 107 Group == R.Group; 108 } 109 110 /// \brief A comparison that sorts such that mergeable regions are adjacent. 111 friend bool operator<(const SourceMappingRegion &LHS, 112 const SourceMappingRegion &RHS) { 113 return std::tie(LHS.File, LHS.MacroArgumentFile, LHS.Count, 114 LHS.UnreachableInitiator, LHS.Group) < 115 std::tie(RHS.File, RHS.MacroArgumentFile, RHS.Count, 116 RHS.UnreachableInitiator, RHS.Group); 117 } 118 }; 119 120 /// \brief Provides the common functionality for the different 121 /// coverage mapping region builders. 122 class CoverageMappingBuilder { 123 public: 124 CoverageMappingModuleGen &CVM; 125 SourceManager &SM; 126 const LangOptions &LangOpts; 127 128 private: 129 struct FileInfo { 130 /// \brief The file id that will be used by the coverage mapping system. 131 unsigned CovMappingFileID; 132 const FileEntry *Entry; 133 134 FileInfo(unsigned CovMappingFileID, const FileEntry *Entry) 135 : CovMappingFileID(CovMappingFileID), Entry(Entry) {} 136 }; 137 138 /// \brief This mapping maps clang's FileIDs to file ids used 139 /// by the coverage mapping system and clang's file entries. 140 llvm::SmallDenseMap<FileID, FileInfo, 8> FileIDMapping; 141 142 public: 143 /// \brief The statement that corresponds to the current source group. 144 const Stmt *CurrentSourceGroup; 145 146 /// \brief The statement the initiated the current unreachable region. 147 const Stmt *CurrentUnreachableRegionInitiator; 148 149 /// \brief The coverage mapping regions for this function 150 llvm::SmallVector<CounterMappingRegion, 32> MappingRegions; 151 /// \brief The source mapping regions for this function. 152 std::vector<SourceMappingRegion> SourceRegions; 153 154 CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 155 const LangOptions &LangOpts) 156 : CVM(CVM), SM(SM), LangOpts(LangOpts), 157 CurrentSourceGroup(nullptr), 158 CurrentUnreachableRegionInitiator(nullptr) {} 159 160 /// \brief Return the precise end location for the given token. 161 SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) { 162 return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM, LangOpts); 163 } 164 165 /// \brief Create the mapping that maps from the function's file ids to 166 /// the indices for the translation unit's filenames. 167 void createFileIDMapping(SmallVectorImpl<unsigned> &Mapping) { 168 Mapping.resize(FileIDMapping.size(), 0); 169 for (const auto &I : FileIDMapping) 170 Mapping[I.second.CovMappingFileID] = CVM.getFileID(I.second.Entry); 171 } 172 173 /// \brief Get the coverage mapping file id that corresponds to the given 174 /// clang file id. If such file id doesn't exist, it gets added to the 175 /// mapping that maps from clang's file ids to coverage mapping file ids. 176 /// Return true if there was an error getting the coverage mapping file id. 177 /// An example of an when this function fails is when the region tries 178 /// to get a coverage file id for a location in a built-in macro. 179 bool getCoverageFileID(SourceLocation LocStart, FileID File, 180 FileID SpellingFile, unsigned &Result) { 181 auto Mapping = FileIDMapping.find(File); 182 if (Mapping != FileIDMapping.end()) { 183 Result = Mapping->second.CovMappingFileID; 184 return false; 185 } 186 187 auto Entry = SM.getFileEntryForID(SpellingFile); 188 if (!Entry) 189 return true; 190 191 Result = FileIDMapping.size(); 192 FileIDMapping.insert(std::make_pair(File, FileInfo(Result, Entry))); 193 createFileExpansionRegion(LocStart, File); 194 return false; 195 } 196 197 /// \brief Get the coverage mapping file id that corresponds to the given 198 /// clang file id. 199 /// Return true if there was an error getting the coverage mapping file id. 200 bool getExistingCoverageFileID(FileID File, unsigned &Result) { 201 // Make sure that the file is valid. 202 if (File.isInvalid()) 203 return true; 204 auto Mapping = FileIDMapping.find(File); 205 if (Mapping != FileIDMapping.end()) { 206 Result = Mapping->second.CovMappingFileID; 207 return false; 208 } 209 return true; 210 } 211 212 /// \brief Return true if the given clang's file id has a corresponding 213 /// coverage file id. 214 bool hasExistingCoverageFileID(FileID File) const { 215 return FileIDMapping.count(File); 216 } 217 218 /// \brief Gather all the regions that were skipped by the preprocessor 219 /// using the constructs like #if. 220 void gatherSkippedRegions() { 221 /// An array of the minimum lineStarts and the maximum lineEnds 222 /// for mapping regions from the appropriate source files. 223 llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges; 224 FileLineRanges.resize( 225 FileIDMapping.size(), 226 std::make_pair(std::numeric_limits<unsigned>::max(), 0)); 227 for (const auto &R : MappingRegions) { 228 FileLineRanges[R.FileID].first = 229 std::min(FileLineRanges[R.FileID].first, R.LineStart); 230 FileLineRanges[R.FileID].second = 231 std::max(FileLineRanges[R.FileID].second, R.LineEnd); 232 } 233 234 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges(); 235 for (const auto &I : SkippedRanges) { 236 auto LocStart = I.getBegin(); 237 auto LocEnd = I.getEnd(); 238 auto FileStart = SM.getFileID(LocStart); 239 if (!hasExistingCoverageFileID(FileStart)) 240 continue; 241 auto ActualFileStart = SM.getDecomposedSpellingLoc(LocStart).first; 242 if (ActualFileStart != SM.getDecomposedSpellingLoc(LocEnd).first) 243 // Ignore regions that span across multiple files. 244 continue; 245 246 unsigned CovFileID; 247 if (getCoverageFileID(LocStart, FileStart, ActualFileStart, CovFileID)) 248 continue; 249 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 250 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 251 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd); 252 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd); 253 CounterMappingRegion Region(Counter(), CovFileID, LineStart, ColumnStart, 254 LineEnd, ColumnEnd, false, 255 CounterMappingRegion::SkippedRegion); 256 // Make sure that we only collect the regions that are inside 257 // the souce code of this function. 258 if (Region.LineStart >= FileLineRanges[CovFileID].first && 259 Region.LineEnd <= FileLineRanges[CovFileID].second) 260 MappingRegions.push_back(Region); 261 } 262 } 263 264 /// \brief Create a mapping region that correponds to an expansion of 265 /// a macro or an embedded include. 266 void createFileExpansionRegion(SourceLocation Loc, FileID ExpandedFile) { 267 SourceLocation LocStart; 268 if (Loc.isMacroID()) 269 LocStart = SM.getImmediateExpansionRange(Loc).first; 270 else { 271 LocStart = SM.getIncludeLoc(ExpandedFile); 272 if (LocStart.isInvalid()) 273 return; // This file has no expansion region. 274 } 275 276 auto File = SM.getFileID(LocStart); 277 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first; 278 unsigned CovFileID, ExpandedFileID; 279 if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID)) 280 return; 281 if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID)) 282 return; 283 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 284 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 285 unsigned LineEnd = LineStart; 286 // Compute the end column manually as Lexer::getLocForEndOfToken doesn't 287 // give the correct result in all cases. 288 unsigned ColumnEnd = 289 ColumnStart + 290 Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM, LangOpts); 291 292 MappingRegions.push_back(CounterMappingRegion( 293 Counter(), CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd, 294 false, CounterMappingRegion::ExpansionRegion)); 295 MappingRegions.back().ExpandedFileID = ExpandedFileID; 296 } 297 298 /// \brief Enter a source region group that is identified by the given 299 /// statement. 300 /// It's not possible to enter a group when there is already 301 /// another group present. 302 void beginSourceRegionGroup(const Stmt *Group) { 303 assert(!CurrentSourceGroup); 304 CurrentSourceGroup = Group; 305 } 306 307 /// \brief Exit the current source region group. 308 void endSourceRegionGroup() { CurrentSourceGroup = nullptr; } 309 310 /// \brief Associate a counter with a given source code range. 311 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 312 Counter Count, const Stmt *UnreachableInitiator, 313 const Stmt *SourceGroup, unsigned Flags = 0, 314 FileID MacroArgumentFile = FileID()) { 315 if (SM.isMacroArgExpansion(LocStart)) { 316 // Map the code range with the macro argument's value. 317 mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart), 318 SM.getImmediateSpellingLoc(LocEnd), Count, 319 UnreachableInitiator, SourceGroup, Flags, 320 SM.getFileID(LocStart)); 321 // Map the code range where the macro argument is referenced. 322 SourceLocation RefLocStart(SM.getImmediateExpansionRange(LocStart).first); 323 SourceLocation RefLocEnd(RefLocStart); 324 if (SM.isMacroArgExpansion(RefLocStart)) 325 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator, 326 SourceGroup, 0, SM.getFileID(RefLocStart)); 327 else 328 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator, 329 SourceGroup); 330 return; 331 } 332 auto File = SM.getFileID(LocStart); 333 // Make sure that the file id is valid. 334 if (File.isInvalid()) 335 return; 336 SourceRegions.emplace_back(File, MacroArgumentFile, Count, 337 UnreachableInitiator, SourceGroup, LocStart, 338 LocEnd, Flags); 339 } 340 341 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 342 Counter Count, unsigned Flags = 0) { 343 mapSourceCodeRange(LocStart, LocEnd, Count, 344 CurrentUnreachableRegionInitiator, CurrentSourceGroup, 345 Flags); 346 } 347 348 /// \brief Generate the coverage counter mapping regions from collected 349 /// source regions. 350 void emitSourceRegions() { 351 std::sort(SourceRegions.begin(), SourceRegions.end()); 352 353 for (auto I = SourceRegions.begin(), E = SourceRegions.end(); I != E; ++I) { 354 // Keep the original start location of this region. 355 SourceLocation LocStart = I->getStartLoc(); 356 SourceLocation LocEnd = I->getEndLoc(SM); 357 358 bool Ignore = I->hasFlag(SourceMappingRegion::IgnoreIfNotExtended); 359 // We need to handle mergeable regions together. 360 for (auto Next = I + 1; Next != E && Next->isMergeable(*I); ++Next) { 361 ++I; 362 LocStart = std::min(LocStart, I->getStartLoc()); 363 LocEnd = std::max(LocEnd, I->getEndLoc(SM)); 364 // FIXME: Should we && together the Ignore flag of multiple regions? 365 Ignore = false; 366 } 367 if (Ignore) 368 continue; 369 370 // Find the spilling locations for the mapping region. 371 LocEnd = getPreciseTokenLocEnd(LocEnd); 372 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 373 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 374 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd); 375 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd); 376 377 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first; 378 unsigned CovFileID; 379 if (getCoverageFileID(LocStart, I->getFile(), SpellingFile, CovFileID)) 380 continue; 381 382 assert(LineStart <= LineEnd); 383 MappingRegions.push_back(CounterMappingRegion( 384 I->getCounter(), CovFileID, LineStart, ColumnStart, LineEnd, 385 ColumnEnd, false, CounterMappingRegion::CodeRegion)); 386 } 387 } 388 }; 389 390 /// \brief Creates unreachable coverage regions for the functions that 391 /// are not emitted. 392 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder { 393 EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 394 const LangOptions &LangOpts) 395 : CoverageMappingBuilder(CVM, SM, LangOpts) {} 396 397 void VisitDecl(const Decl *D) { 398 if (!D->hasBody()) 399 return; 400 auto Body = D->getBody(); 401 mapSourceCodeRange(Body->getLocStart(), Body->getLocEnd(), Counter()); 402 } 403 404 /// \brief Write the mapping data to the output stream 405 void write(llvm::raw_ostream &OS) { 406 emitSourceRegions(); 407 SmallVector<unsigned, 16> FileIDMapping; 408 createFileIDMapping(FileIDMapping); 409 410 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions); 411 Writer.write(OS); 412 } 413 }; 414 415 /// \brief A StmtVisitor that creates coverage mapping regions which map 416 /// from the source code locations to the PGO counters. 417 struct CounterCoverageMappingBuilder 418 : public CoverageMappingBuilder, 419 public ConstStmtVisitor<CounterCoverageMappingBuilder> { 420 /// \brief The map of statements to count values. 421 llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 422 423 Counter CurrentRegionCount; 424 425 CounterExpressionBuilder Builder; 426 427 /// \brief Return a counter that represents the 428 /// expression that subracts rhs from lhs. 429 Counter subtractCounters(Counter LHS, Counter RHS) { 430 return Builder.subtract(LHS, RHS); 431 } 432 433 /// \brief Return a counter that represents the 434 /// the exression that adds lhs and rhs. 435 Counter addCounters(Counter LHS, Counter RHS) { 436 return Builder.add(LHS, RHS); 437 } 438 439 /// \brief Return the region counter for the given statement. 440 /// This should only be called on statements that have a dedicated counter. 441 unsigned getRegionCounter(const Stmt *S) { return CounterMap[S]; } 442 443 /// \brief Return the region count for the counter at the given index. 444 Counter getRegionCount(unsigned CounterId) { 445 return Counter::getCounter(CounterId); 446 } 447 448 /// \brief Return the counter value of the current region. 449 Counter getCurrentRegionCount() { return CurrentRegionCount; } 450 451 /// \brief Set the counter value for the current region. 452 /// This is used to keep track of changes to the most recent counter 453 /// from control flow and non-local exits. 454 void setCurrentRegionCount(Counter Count) { 455 CurrentRegionCount = Count; 456 CurrentUnreachableRegionInitiator = nullptr; 457 } 458 459 /// \brief Indicate that the current region is never reached, 460 /// and thus should have a counter value of zero. 461 /// This is important so that subsequent regions can correctly track 462 /// their parent counts. 463 void setCurrentRegionUnreachable(const Stmt *Initiator) { 464 CurrentRegionCount = Counter::getZero(); 465 CurrentUnreachableRegionInitiator = Initiator; 466 } 467 468 /// \brief A counter for a particular region. 469 /// This is the primary interface through 470 /// which the coverage mapping builder manages counters and their values. 471 class RegionMapper { 472 CounterCoverageMappingBuilder &Mapping; 473 Counter Count; 474 Counter ParentCount; 475 Counter RegionCount; 476 Counter Adjust; 477 478 public: 479 RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt *S) 480 : Mapping(*Mapper), 481 Count(Mapper->getRegionCount(Mapper->getRegionCounter(S))), 482 ParentCount(Mapper->getCurrentRegionCount()) {} 483 484 /// Get the value of the counter. In most cases this is the number of times 485 /// the region of the counter was entered, but for switch labels it's the 486 /// number of direct jumps to that label. 487 Counter getCount() const { return Count; } 488 489 /// Get the value of the counter with adjustments applied. Adjustments occur 490 /// when control enters or leaves the region abnormally; i.e., if there is a 491 /// jump to a label within the region, or if the function can return from 492 /// within the region. The adjusted count, then, is the value of the counter 493 /// at the end of the region. 494 Counter getAdjustedCount() const { 495 return Mapping.addCounters(Count, Adjust); 496 } 497 498 /// Get the value of the counter in this region's parent, i.e., the region 499 /// that was active when this region began. This is useful for deriving 500 /// counts in implicitly counted regions, like the false case of a condition 501 /// or the normal exits of a loop. 502 Counter getParentCount() const { return ParentCount; } 503 504 /// Activate the counter by emitting an increment and starting to track 505 /// adjustments. If AddIncomingFallThrough is true, the current region count 506 /// will be added to the counter for the purposes of tracking the region. 507 void beginRegion(bool AddIncomingFallThrough = false) { 508 RegionCount = Count; 509 if (AddIncomingFallThrough) 510 RegionCount = 511 Mapping.addCounters(RegionCount, Mapping.getCurrentRegionCount()); 512 Mapping.setCurrentRegionCount(RegionCount); 513 } 514 515 /// For counters on boolean branches, begins tracking adjustments for the 516 /// uncounted path. 517 void beginElseRegion() { 518 RegionCount = Mapping.subtractCounters(ParentCount, Count); 519 Mapping.setCurrentRegionCount(RegionCount); 520 } 521 522 /// Reset the current region count. 523 void setCurrentRegionCount(Counter CurrentCount) { 524 RegionCount = CurrentCount; 525 Mapping.setCurrentRegionCount(RegionCount); 526 } 527 528 /// Adjust for non-local control flow after emitting a subexpression or 529 /// substatement. This must be called to account for constructs such as 530 /// gotos, 531 /// labels, and returns, so that we can ensure that our region's count is 532 /// correct in the code that follows. 533 void adjustForControlFlow() { 534 Adjust = Mapping.addCounters( 535 Adjust, Mapping.subtractCounters(Mapping.getCurrentRegionCount(), 536 RegionCount)); 537 // Reset the region count in case this is called again later. 538 RegionCount = Mapping.getCurrentRegionCount(); 539 } 540 541 /// Commit all adjustments to the current region. If the region is a loop, 542 /// the LoopAdjust value should be the count of all the breaks and continues 543 /// from the loop, to compensate for those counts being deducted from the 544 /// adjustments for the body of the loop. 545 void applyAdjustmentsToRegion() { 546 Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount, Adjust)); 547 } 548 void applyAdjustmentsToRegion(Counter LoopAdjust) { 549 Mapping.setCurrentRegionCount(Mapping.addCounters( 550 Mapping.addCounters(ParentCount, Adjust), LoopAdjust)); 551 } 552 }; 553 554 /// \brief Keep counts of breaks and continues inside loops. 555 struct BreakContinue { 556 Counter BreakCount; 557 Counter ContinueCount; 558 }; 559 SmallVector<BreakContinue, 8> BreakContinueStack; 560 561 CounterCoverageMappingBuilder( 562 CoverageMappingModuleGen &CVM, 563 llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM, 564 const LangOptions &LangOpts) 565 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {} 566 567 /// \brief Write the mapping data to the output stream 568 void write(llvm::raw_ostream &OS) { 569 emitSourceRegions(); 570 llvm::SmallVector<unsigned, 8> VirtualFileMapping; 571 createFileIDMapping(VirtualFileMapping); 572 gatherSkippedRegions(); 573 574 CoverageMappingWriter Writer( 575 VirtualFileMapping, Builder.getExpressions(), MappingRegions); 576 Writer.write(OS); 577 } 578 579 /// \brief Associate the source code range with the current region count. 580 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 581 unsigned Flags = 0) { 582 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd, 583 CurrentRegionCount, Flags); 584 } 585 586 void mapSourceCodeRange(SourceLocation LocStart) { 587 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart, 588 CurrentRegionCount); 589 } 590 591 /// \brief Associate the source range of a token with the current region 592 /// count. 593 /// Ignore the source range for this token if it produces a distinct 594 /// mapping region with no other source ranges. 595 void mapToken(SourceLocation LocStart) { 596 CoverageMappingBuilder::mapSourceCodeRange( 597 LocStart, LocStart, CurrentRegionCount, 598 SourceMappingRegion::IgnoreIfNotExtended); 599 } 600 601 void VisitStmt(const Stmt *S) { 602 mapSourceCodeRange(S->getLocStart()); 603 for (Stmt::const_child_range I = S->children(); I; ++I) { 604 if (*I) 605 this->Visit(*I); 606 } 607 } 608 609 void VisitDecl(const Decl *D) { 610 if (!D->hasBody()) 611 return; 612 // Counter tracks entry to the function body. 613 auto Body = D->getBody(); 614 RegionMapper Cnt(this, Body); 615 Cnt.beginRegion(); 616 Visit(Body); 617 } 618 619 void VisitDeclStmt(const DeclStmt *S) { 620 mapSourceCodeRange(S->getLocStart()); 621 for (Stmt::const_child_range I = static_cast<const Stmt *>(S)->children(); 622 I; ++I) { 623 if (*I) 624 this->Visit(*I); 625 } 626 } 627 628 void VisitCompoundStmt(const CompoundStmt *S) { 629 mapSourceCodeRange(S->getLBracLoc()); 630 mapSourceCodeRange(S->getRBracLoc()); 631 for (Stmt::const_child_range I = S->children(); I; ++I) { 632 if (*I) 633 this->Visit(*I); 634 } 635 } 636 637 void VisitReturnStmt(const ReturnStmt *S) { 638 mapSourceCodeRange(S->getLocStart()); 639 if (S->getRetValue()) 640 Visit(S->getRetValue()); 641 setCurrentRegionUnreachable(S); 642 } 643 644 void VisitGotoStmt(const GotoStmt *S) { 645 mapSourceCodeRange(S->getLocStart()); 646 mapToken(S->getLabelLoc()); 647 setCurrentRegionUnreachable(S); 648 } 649 650 void VisitLabelStmt(const LabelStmt *S) { 651 // Counter tracks the block following the label. 652 RegionMapper Cnt(this, S); 653 Cnt.beginRegion(); 654 mapSourceCodeRange(S->getLocStart()); 655 // Can't map the ':' token as its location isn't known. 656 Visit(S->getSubStmt()); 657 } 658 659 void VisitBreakStmt(const BreakStmt *S) { 660 mapSourceCodeRange(S->getLocStart()); 661 assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 662 BreakContinueStack.back().BreakCount = addCounters( 663 BreakContinueStack.back().BreakCount, getCurrentRegionCount()); 664 setCurrentRegionUnreachable(S); 665 } 666 667 void VisitContinueStmt(const ContinueStmt *S) { 668 mapSourceCodeRange(S->getLocStart()); 669 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 670 BreakContinueStack.back().ContinueCount = addCounters( 671 BreakContinueStack.back().ContinueCount, getCurrentRegionCount()); 672 setCurrentRegionUnreachable(S); 673 } 674 675 void VisitWhileStmt(const WhileStmt *S) { 676 mapSourceCodeRange(S->getLocStart()); 677 // Counter tracks the body of the loop. 678 RegionMapper Cnt(this, S); 679 BreakContinueStack.push_back(BreakContinue()); 680 // Visit the body region first so the break/continue adjustments can be 681 // included when visiting the condition. 682 Cnt.beginRegion(); 683 Visit(S->getBody()); 684 Cnt.adjustForControlFlow(); 685 686 // ...then go back and propagate counts through the condition. The count 687 // at the start of the condition is the sum of the incoming edges, 688 // the backedge from the end of the loop body, and the edges from 689 // continue statements. 690 BreakContinue BC = BreakContinueStack.pop_back_val(); 691 Cnt.setCurrentRegionCount( 692 addCounters(Cnt.getParentCount(), 693 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount))); 694 beginSourceRegionGroup(S->getCond()); 695 Visit(S->getCond()); 696 endSourceRegionGroup(); 697 Cnt.adjustForControlFlow(); 698 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 699 } 700 701 void VisitDoStmt(const DoStmt *S) { 702 mapSourceCodeRange(S->getLocStart()); 703 // Counter tracks the body of the loop. 704 RegionMapper Cnt(this, S); 705 BreakContinueStack.push_back(BreakContinue()); 706 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 707 Visit(S->getBody()); 708 Cnt.adjustForControlFlow(); 709 710 BreakContinue BC = BreakContinueStack.pop_back_val(); 711 // The count at the start of the condition is equal to the count at the 712 // end of the body. The adjusted count does not include either the 713 // fall-through count coming into the loop or the continue count, so add 714 // both of those separately. This is coincidentally the same equation as 715 // with while loops but for different reasons. 716 Cnt.setCurrentRegionCount( 717 addCounters(Cnt.getParentCount(), 718 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount))); 719 Visit(S->getCond()); 720 Cnt.adjustForControlFlow(); 721 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 722 } 723 724 void VisitForStmt(const ForStmt *S) { 725 mapSourceCodeRange(S->getLocStart()); 726 if (S->getInit()) 727 Visit(S->getInit()); 728 729 // Counter tracks the body of the loop. 730 RegionMapper Cnt(this, S); 731 BreakContinueStack.push_back(BreakContinue()); 732 // Visit the body region first. (This is basically the same as a while 733 // loop; see further comments in VisitWhileStmt.) 734 Cnt.beginRegion(); 735 Visit(S->getBody()); 736 Cnt.adjustForControlFlow(); 737 738 // The increment is essentially part of the body but it needs to include 739 // the count for all the continue statements. 740 if (S->getInc()) { 741 Cnt.setCurrentRegionCount(addCounters( 742 getCurrentRegionCount(), BreakContinueStack.back().ContinueCount)); 743 beginSourceRegionGroup(S->getInc()); 744 Visit(S->getInc()); 745 endSourceRegionGroup(); 746 Cnt.adjustForControlFlow(); 747 } 748 749 BreakContinue BC = BreakContinueStack.pop_back_val(); 750 751 // ...then go back and propagate counts through the condition. 752 if (S->getCond()) { 753 Cnt.setCurrentRegionCount( 754 addCounters(addCounters(Cnt.getParentCount(), Cnt.getAdjustedCount()), 755 BC.ContinueCount)); 756 beginSourceRegionGroup(S->getCond()); 757 Visit(S->getCond()); 758 endSourceRegionGroup(); 759 Cnt.adjustForControlFlow(); 760 } 761 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 762 } 763 764 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 765 mapSourceCodeRange(S->getLocStart()); 766 Visit(S->getRangeStmt()); 767 Visit(S->getBeginEndStmt()); 768 // Counter tracks the body of the loop. 769 RegionMapper Cnt(this, S); 770 BreakContinueStack.push_back(BreakContinue()); 771 // Visit the body region first. (This is basically the same as a while 772 // loop; see further comments in VisitWhileStmt.) 773 Cnt.beginRegion(); 774 Visit(S->getBody()); 775 Cnt.adjustForControlFlow(); 776 BreakContinue BC = BreakContinueStack.pop_back_val(); 777 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 778 } 779 780 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 781 mapSourceCodeRange(S->getLocStart()); 782 Visit(S->getElement()); 783 // Counter tracks the body of the loop. 784 RegionMapper Cnt(this, S); 785 BreakContinueStack.push_back(BreakContinue()); 786 Cnt.beginRegion(); 787 Visit(S->getBody()); 788 BreakContinue BC = BreakContinueStack.pop_back_val(); 789 Cnt.adjustForControlFlow(); 790 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 791 } 792 793 void VisitSwitchStmt(const SwitchStmt *S) { 794 mapSourceCodeRange(S->getLocStart()); 795 Visit(S->getCond()); 796 BreakContinueStack.push_back(BreakContinue()); 797 // Map the '}' for the body to have the same count as the regions after 798 // the switch. 799 SourceLocation RBracLoc; 800 if (const auto *CS = dyn_cast<CompoundStmt>(S->getBody())) { 801 mapSourceCodeRange(CS->getLBracLoc()); 802 setCurrentRegionUnreachable(S); 803 for (Stmt::const_child_range I = CS->children(); I; ++I) { 804 if (*I) 805 this->Visit(*I); 806 } 807 RBracLoc = CS->getRBracLoc(); 808 } else { 809 setCurrentRegionUnreachable(S); 810 Visit(S->getBody()); 811 } 812 // If the switch is inside a loop, add the continue counts. 813 BreakContinue BC = BreakContinueStack.pop_back_val(); 814 if (!BreakContinueStack.empty()) 815 BreakContinueStack.back().ContinueCount = addCounters( 816 BreakContinueStack.back().ContinueCount, BC.ContinueCount); 817 // Counter tracks the exit block of the switch. 818 RegionMapper ExitCnt(this, S); 819 ExitCnt.beginRegion(); 820 if (RBracLoc.isValid()) 821 mapSourceCodeRange(RBracLoc); 822 } 823 824 void VisitCaseStmt(const CaseStmt *S) { 825 // Counter for this particular case. This counts only jumps from the 826 // switch header and does not include fallthrough from the case before 827 // this one. 828 RegionMapper Cnt(this, S); 829 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 830 mapSourceCodeRange(S->getLocStart()); 831 mapToken(S->getColonLoc()); 832 Visit(S->getSubStmt()); 833 } 834 835 void VisitDefaultStmt(const DefaultStmt *S) { 836 // Counter for this default case. This does not include fallthrough from 837 // the previous case. 838 RegionMapper Cnt(this, S); 839 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 840 mapSourceCodeRange(S->getLocStart()); 841 mapToken(S->getColonLoc()); 842 Visit(S->getSubStmt()); 843 } 844 845 void VisitIfStmt(const IfStmt *S) { 846 mapSourceCodeRange(S->getLocStart()); 847 Visit(S->getCond()); 848 mapToken(S->getElseLoc()); 849 850 // Counter tracks the "then" part of an if statement. The count for 851 // the "else" part, if it exists, will be calculated from this counter. 852 RegionMapper Cnt(this, S); 853 Cnt.beginRegion(); 854 Visit(S->getThen()); 855 Cnt.adjustForControlFlow(); 856 857 if (S->getElse()) { 858 Cnt.beginElseRegion(); 859 Visit(S->getElse()); 860 Cnt.adjustForControlFlow(); 861 } 862 Cnt.applyAdjustmentsToRegion(); 863 } 864 865 void VisitCXXTryStmt(const CXXTryStmt *S) { 866 mapSourceCodeRange(S->getLocStart()); 867 Visit(S->getTryBlock()); 868 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 869 Visit(S->getHandler(I)); 870 // Counter tracks the continuation block of the try statement. 871 RegionMapper Cnt(this, S); 872 Cnt.beginRegion(); 873 } 874 875 void VisitCXXCatchStmt(const CXXCatchStmt *S) { 876 mapSourceCodeRange(S->getLocStart()); 877 // Counter tracks the catch statement's handler block. 878 RegionMapper Cnt(this, S); 879 Cnt.beginRegion(); 880 Visit(S->getHandlerBlock()); 881 } 882 883 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 884 Visit(E->getCond()); 885 mapToken(E->getQuestionLoc()); 886 mapToken(E->getColonLoc()); 887 888 // Counter tracks the "true" part of a conditional operator. The 889 // count in the "false" part will be calculated from this counter. 890 RegionMapper Cnt(this, E); 891 Cnt.beginRegion(); 892 Visit(E->getTrueExpr()); 893 Cnt.adjustForControlFlow(); 894 895 Cnt.beginElseRegion(); 896 Visit(E->getFalseExpr()); 897 Cnt.adjustForControlFlow(); 898 899 Cnt.applyAdjustmentsToRegion(); 900 } 901 902 void VisitBinLAnd(const BinaryOperator *E) { 903 Visit(E->getLHS()); 904 mapToken(E->getOperatorLoc()); 905 // Counter tracks the right hand side of a logical and operator. 906 RegionMapper Cnt(this, E); 907 Cnt.beginRegion(); 908 Visit(E->getRHS()); 909 Cnt.adjustForControlFlow(); 910 Cnt.applyAdjustmentsToRegion(); 911 } 912 913 void VisitBinLOr(const BinaryOperator *E) { 914 Visit(E->getLHS()); 915 mapToken(E->getOperatorLoc()); 916 // Counter tracks the right hand side of a logical or operator. 917 RegionMapper Cnt(this, E); 918 Cnt.beginRegion(); 919 Visit(E->getRHS()); 920 Cnt.adjustForControlFlow(); 921 Cnt.applyAdjustmentsToRegion(); 922 } 923 924 void VisitParenExpr(const ParenExpr *E) { 925 mapToken(E->getLParen()); 926 Visit(E->getSubExpr()); 927 mapToken(E->getRParen()); 928 } 929 930 void VisitBinaryOperator(const BinaryOperator *E) { 931 Visit(E->getLHS()); 932 mapToken(E->getOperatorLoc()); 933 Visit(E->getRHS()); 934 } 935 936 void VisitUnaryOperator(const UnaryOperator *E) { 937 bool Postfix = E->isPostfix(); 938 if (!Postfix) 939 mapToken(E->getOperatorLoc()); 940 Visit(E->getSubExpr()); 941 if (Postfix) 942 mapToken(E->getOperatorLoc()); 943 } 944 945 void VisitMemberExpr(const MemberExpr *E) { 946 Visit(E->getBase()); 947 mapToken(E->getMemberLoc()); 948 } 949 950 void VisitCallExpr(const CallExpr *E) { 951 Visit(E->getCallee()); 952 for (const auto &Arg : E->arguments()) 953 Visit(Arg); 954 mapToken(E->getRParenLoc()); 955 } 956 957 void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { 958 Visit(E->getLHS()); 959 Visit(E->getRHS()); 960 mapToken(E->getRBracketLoc()); 961 } 962 963 void VisitCStyleCastExpr(const CStyleCastExpr *E) { 964 mapToken(E->getLParenLoc()); 965 mapToken(E->getRParenLoc()); 966 Visit(E->getSubExpr()); 967 } 968 969 // Map literals as tokens so that the macros like #define PI 3.14 970 // won't generate coverage mapping regions. 971 972 void VisitIntegerLiteral(const IntegerLiteral *E) { 973 mapToken(E->getLocStart()); 974 } 975 976 void VisitFloatingLiteral(const FloatingLiteral *E) { 977 mapToken(E->getLocStart()); 978 } 979 980 void VisitCharacterLiteral(const CharacterLiteral *E) { 981 mapToken(E->getLocStart()); 982 } 983 984 void VisitStringLiteral(const StringLiteral *E) { 985 mapToken(E->getLocStart()); 986 } 987 988 void VisitImaginaryLiteral(const ImaginaryLiteral *E) { 989 mapToken(E->getLocStart()); 990 } 991 992 void VisitObjCMessageExpr(const ObjCMessageExpr *E) { 993 mapToken(E->getLeftLoc()); 994 for (Stmt::const_child_range I = static_cast<const Stmt*>(E)->children(); I; 995 ++I) { 996 if (*I) 997 this->Visit(*I); 998 } 999 mapToken(E->getRightLoc()); 1000 } 1001 }; 1002 } 1003 1004 static bool isMachO(const CodeGenModule &CGM) { 1005 return CGM.getTarget().getTriple().isOSBinFormatMachO(); 1006 } 1007 1008 static StringRef getCoverageSection(const CodeGenModule &CGM) { 1009 return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap"; 1010 } 1011 1012 static void dump(llvm::raw_ostream &OS, const CoverageMappingRecord &Function) { 1013 OS << Function.FunctionName << ":\n"; 1014 CounterMappingContext Ctx(Function.Expressions); 1015 for (const auto &R : Function.MappingRegions) { 1016 OS.indent(2); 1017 switch (R.Kind) { 1018 case CounterMappingRegion::CodeRegion: 1019 break; 1020 case CounterMappingRegion::ExpansionRegion: 1021 OS << "Expansion,"; 1022 break; 1023 case CounterMappingRegion::SkippedRegion: 1024 OS << "Skipped,"; 1025 break; 1026 } 1027 1028 OS << "File " << R.FileID << ", " << R.LineStart << ":" 1029 << R.ColumnStart << " -> " << R.LineEnd << ":" << R.ColumnEnd 1030 << " = "; 1031 Ctx.dump(R.Count); 1032 OS << " (HasCodeBefore = " << R.HasCodeBefore; 1033 if (R.Kind == CounterMappingRegion::ExpansionRegion) 1034 OS << ", Expanded file = " << R.ExpandedFileID; 1035 1036 OS << ")\n"; 1037 } 1038 } 1039 1040 void CoverageMappingModuleGen::addFunctionMappingRecord( 1041 llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, 1042 uint64_t FunctionHash, const std::string &CoverageMapping) { 1043 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1044 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 1045 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx); 1046 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx); 1047 if (!FunctionRecordTy) { 1048 llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty, Int64Ty}; 1049 FunctionRecordTy = 1050 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes)); 1051 } 1052 1053 llvm::Constant *FunctionRecordVals[] = { 1054 llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy), 1055 llvm::ConstantInt::get(Int32Ty, FunctionNameValue.size()), 1056 llvm::ConstantInt::get(Int32Ty, CoverageMapping.size()), 1057 llvm::ConstantInt::get(Int64Ty, FunctionHash)}; 1058 FunctionRecords.push_back(llvm::ConstantStruct::get( 1059 FunctionRecordTy, makeArrayRef(FunctionRecordVals))); 1060 CoverageMappings += CoverageMapping; 1061 1062 if (CGM.getCodeGenOpts().DumpCoverageMapping) { 1063 // Dump the coverage mapping data for this function by decoding the 1064 // encoded data. This allows us to dump the mapping regions which were 1065 // also processed by the CoverageMappingWriter which performs 1066 // additional minimization operations such as reducing the number of 1067 // expressions. 1068 std::vector<StringRef> Filenames; 1069 std::vector<CounterExpression> Expressions; 1070 std::vector<CounterMappingRegion> Regions; 1071 llvm::SmallVector<StringRef, 16> FilenameRefs; 1072 FilenameRefs.resize(FileEntries.size()); 1073 for (const auto &Entry : FileEntries) 1074 FilenameRefs[Entry.second] = Entry.first->getName(); 1075 RawCoverageMappingReader Reader(FunctionNameValue, CoverageMapping, 1076 FilenameRefs, 1077 Filenames, Expressions, Regions); 1078 CoverageMappingRecord FunctionRecord; 1079 if (Reader.read(FunctionRecord)) 1080 return; 1081 dump(llvm::outs(), FunctionRecord); 1082 } 1083 } 1084 1085 void CoverageMappingModuleGen::emit() { 1086 if (FunctionRecords.empty()) 1087 return; 1088 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1089 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 1090 1091 // Create the filenames and merge them with coverage mappings 1092 llvm::SmallVector<std::string, 16> FilenameStrs; 1093 llvm::SmallVector<StringRef, 16> FilenameRefs; 1094 FilenameStrs.resize(FileEntries.size()); 1095 FilenameRefs.resize(FileEntries.size()); 1096 for (const auto &Entry : FileEntries) { 1097 llvm::SmallString<256> Path(Entry.first->getName()); 1098 llvm::sys::fs::make_absolute(Path); 1099 1100 auto I = Entry.second; 1101 FilenameStrs[I] = std::move(std::string(Path.begin(), Path.end())); 1102 FilenameRefs[I] = FilenameStrs[I]; 1103 } 1104 1105 std::string FilenamesAndCoverageMappings; 1106 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings); 1107 CoverageFilenamesSectionWriter(FilenameRefs).write(OS); 1108 OS << CoverageMappings; 1109 size_t CoverageMappingSize = CoverageMappings.size(); 1110 size_t FilenamesSize = OS.str().size() - CoverageMappingSize; 1111 // Append extra zeroes if necessary to ensure that the size of the filenames 1112 // and coverage mappings is a multiple of 8. 1113 if (size_t Rem = OS.str().size() % 8) { 1114 CoverageMappingSize += 8 - Rem; 1115 for (size_t I = 0, S = 8 - Rem; I < S; ++I) 1116 OS << '\0'; 1117 } 1118 auto *FilenamesAndMappingsVal = 1119 llvm::ConstantDataArray::getString(Ctx, OS.str(), false); 1120 1121 // Create the deferred function records array 1122 auto RecordsTy = 1123 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size()); 1124 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords); 1125 1126 // Create the coverage data record 1127 llvm::Type *CovDataTypes[] = {Int32Ty, Int32Ty, 1128 Int32Ty, Int32Ty, 1129 RecordsTy, FilenamesAndMappingsVal->getType()}; 1130 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes)); 1131 llvm::Constant *TUDataVals[] = { 1132 llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()), 1133 llvm::ConstantInt::get(Int32Ty, FilenamesSize), 1134 llvm::ConstantInt::get(Int32Ty, CoverageMappingSize), 1135 llvm::ConstantInt::get(Int32Ty, 1136 /*Version=*/CoverageMappingVersion1), 1137 RecordsVal, FilenamesAndMappingsVal}; 1138 auto CovDataVal = 1139 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals)); 1140 auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy, true, 1141 llvm::GlobalValue::InternalLinkage, 1142 CovDataVal, 1143 "__llvm_coverage_mapping"); 1144 1145 CovData->setSection(getCoverageSection(CGM)); 1146 CovData->setAlignment(8); 1147 1148 // Make sure the data doesn't get deleted. 1149 CGM.addUsedGlobal(CovData); 1150 } 1151 1152 unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) { 1153 auto It = FileEntries.find(File); 1154 if (It != FileEntries.end()) 1155 return It->second; 1156 unsigned FileID = FileEntries.size(); 1157 FileEntries.insert(std::make_pair(File, FileID)); 1158 return FileID; 1159 } 1160 1161 void CoverageMappingGen::emitCounterMapping(const Decl *D, 1162 llvm::raw_ostream &OS) { 1163 assert(CounterMap); 1164 CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts); 1165 Walker.VisitDecl(D); 1166 Walker.write(OS); 1167 } 1168 1169 void CoverageMappingGen::emitEmptyMapping(const Decl *D, 1170 llvm::raw_ostream &OS) { 1171 EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts); 1172 Walker.VisitDecl(D); 1173 Walker.write(OS); 1174 } 1175