clang API Documentation
00001 //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Instrumentation-based code coverage mapping generator 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "CoverageMappingGen.h" 00015 #include "CodeGenFunction.h" 00016 #include "clang/AST/StmtVisitor.h" 00017 #include "clang/Lex/Lexer.h" 00018 #include "llvm/ProfileData/InstrProfReader.h" 00019 #include "llvm/ProfileData/CoverageMapping.h" 00020 #include "llvm/ProfileData/CoverageMappingWriter.h" 00021 #include "llvm/ProfileData/CoverageMappingReader.h" 00022 #include "llvm/Support/FileSystem.h" 00023 00024 using namespace clang; 00025 using namespace CodeGen; 00026 using namespace llvm::coverage; 00027 00028 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) { 00029 SkippedRanges.push_back(Range); 00030 } 00031 00032 namespace { 00033 00034 /// \brief A region of source code that can be mapped to a counter. 00035 class SourceMappingRegion { 00036 public: 00037 enum RegionFlags { 00038 /// \brief This region won't be emitted if it wasn't extended. 00039 /// This is useful so that we won't emit source ranges for single tokens 00040 /// that we don't really care that much about, like: 00041 /// the '(' token in #define MACRO ( 00042 IgnoreIfNotExtended = 0x0001, 00043 }; 00044 00045 private: 00046 FileID File, MacroArgumentFile; 00047 00048 Counter Count; 00049 00050 /// \brief A statement that initiated the count of Zero. 00051 /// 00052 /// This initiator statement is useful to prevent merging of unreachable 00053 /// regions with different statements that caused the counter to become 00054 /// unreachable. 00055 const Stmt *UnreachableInitiator; 00056 00057 /// \brief A statement that separates certain mapping regions into groups. 00058 /// 00059 /// The group statement is sometimes useful when we are emitting the source 00060 /// regions not in their correct lexical order, e.g. the regions for the 00061 /// incrementation expression in the 'for' construct. By marking the regions 00062 /// in the incrementation expression with the group statement, we avoid the 00063 /// merging of the regions from the incrementation expression and the loop's 00064 /// body. 00065 const Stmt *Group; 00066 00067 /// \brief The region's starting location. 00068 SourceLocation LocStart; 00069 00070 /// \brief The region's ending location. 00071 SourceLocation LocEnd, AlternativeLocEnd; 00072 unsigned Flags; 00073 00074 public: 00075 SourceMappingRegion(FileID File, FileID MacroArgumentFile, Counter Count, 00076 const Stmt *UnreachableInitiator, const Stmt *Group, 00077 SourceLocation LocStart, SourceLocation LocEnd, 00078 unsigned Flags = 0) 00079 : File(File), MacroArgumentFile(MacroArgumentFile), Count(Count), 00080 UnreachableInitiator(UnreachableInitiator), Group(Group), 00081 LocStart(LocStart), LocEnd(LocEnd), AlternativeLocEnd(LocStart), 00082 Flags(Flags) {} 00083 00084 const FileID &getFile() const { return File; } 00085 00086 const Counter &getCounter() const { return Count; } 00087 00088 const SourceLocation &getStartLoc() const { return LocStart; } 00089 00090 const SourceLocation &getEndLoc(const SourceManager &SM) const { 00091 if (SM.getFileID(LocEnd) != File) 00092 return AlternativeLocEnd; 00093 return LocEnd; 00094 } 00095 00096 bool hasFlag(RegionFlags Flag) const { return (Flags & Flag) != 0; } 00097 00098 void setFlag(RegionFlags Flag) { Flags |= Flag; } 00099 00100 void clearFlag(RegionFlags Flag) { Flags &= ~Flag; } 00101 00102 /// \brief Return true if two regions can be merged together. 00103 bool isMergeable(SourceMappingRegion &R) { 00104 // FIXME: We allow merging regions with a gap in between them. Should we? 00105 return File == R.File && MacroArgumentFile == R.MacroArgumentFile && 00106 Count == R.Count && UnreachableInitiator == R.UnreachableInitiator && 00107 Group == R.Group; 00108 } 00109 00110 /// \brief A comparison that sorts such that mergeable regions are adjacent. 00111 friend bool operator<(const SourceMappingRegion &LHS, 00112 const SourceMappingRegion &RHS) { 00113 return std::tie(LHS.File, LHS.MacroArgumentFile, LHS.Count, 00114 LHS.UnreachableInitiator, LHS.Group) < 00115 std::tie(RHS.File, RHS.MacroArgumentFile, RHS.Count, 00116 RHS.UnreachableInitiator, RHS.Group); 00117 } 00118 }; 00119 00120 /// \brief The state of the coverage mapping builder. 00121 struct SourceMappingState { 00122 Counter CurrentRegionCount; 00123 const Stmt *CurrentSourceGroup; 00124 const Stmt *CurrentUnreachableRegionInitiator; 00125 00126 SourceMappingState(Counter CurrentRegionCount, const Stmt *CurrentSourceGroup, 00127 const Stmt *CurrentUnreachableRegionInitiator) 00128 : CurrentRegionCount(CurrentRegionCount), 00129 CurrentSourceGroup(CurrentSourceGroup), 00130 CurrentUnreachableRegionInitiator(CurrentUnreachableRegionInitiator) {} 00131 }; 00132 00133 /// \brief Provides the common functionality for the different 00134 /// coverage mapping region builders. 00135 class CoverageMappingBuilder { 00136 public: 00137 CoverageMappingModuleGen &CVM; 00138 SourceManager &SM; 00139 const LangOptions &LangOpts; 00140 00141 private: 00142 struct FileInfo { 00143 /// \brief The file id that will be used by the coverage mapping system. 00144 unsigned CovMappingFileID; 00145 const FileEntry *Entry; 00146 00147 FileInfo(unsigned CovMappingFileID, const FileEntry *Entry) 00148 : CovMappingFileID(CovMappingFileID), Entry(Entry) {} 00149 }; 00150 00151 /// \brief This mapping maps clang's FileIDs to file ids used 00152 /// by the coverage mapping system and clang's file entries. 00153 llvm::SmallDenseMap<FileID, FileInfo, 8> FileIDMapping; 00154 00155 public: 00156 /// \brief The statement that corresponds to the current source group. 00157 const Stmt *CurrentSourceGroup; 00158 00159 /// \brief The statement the initiated the current unreachable region. 00160 const Stmt *CurrentUnreachableRegionInitiator; 00161 00162 /// \brief The coverage mapping regions for this function 00163 llvm::SmallVector<CounterMappingRegion, 32> MappingRegions; 00164 /// \brief The source mapping regions for this function. 00165 std::vector<SourceMappingRegion> SourceRegions; 00166 00167 CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 00168 const LangOptions &LangOpts) 00169 : CVM(CVM), SM(SM), LangOpts(LangOpts), 00170 CurrentSourceGroup(nullptr), 00171 CurrentUnreachableRegionInitiator(nullptr) {} 00172 00173 /// \brief Return the precise end location for the given token. 00174 SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) { 00175 return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM, LangOpts); 00176 } 00177 00178 /// \brief Create the mapping that maps from the function's file ids to 00179 /// the indices for the translation unit's filenames. 00180 void createFileIDMapping(SmallVectorImpl<unsigned> &Mapping) { 00181 Mapping.resize(FileIDMapping.size(), 0); 00182 for (const auto &I : FileIDMapping) 00183 Mapping[I.second.CovMappingFileID] = CVM.getFileID(I.second.Entry); 00184 } 00185 00186 /// \brief Get the coverage mapping file id that corresponds to the given 00187 /// clang file id. If such file id doesn't exist, it gets added to the 00188 /// mapping that maps from clang's file ids to coverage mapping file ids. 00189 /// Return true if there was an error getting the coverage mapping file id. 00190 /// An example of an when this function fails is when the region tries 00191 /// to get a coverage file id for a location in a built-in macro. 00192 bool getCoverageFileID(SourceLocation LocStart, FileID File, 00193 FileID SpellingFile, unsigned &Result) { 00194 auto Mapping = FileIDMapping.find(File); 00195 if (Mapping != FileIDMapping.end()) { 00196 Result = Mapping->second.CovMappingFileID; 00197 return false; 00198 } 00199 00200 auto Entry = SM.getFileEntryForID(SpellingFile); 00201 if (!Entry) 00202 return true; 00203 00204 Result = FileIDMapping.size(); 00205 FileIDMapping.insert(std::make_pair(File, FileInfo(Result, Entry))); 00206 createFileExpansionRegion(LocStart, File); 00207 return false; 00208 } 00209 00210 /// \brief Get the coverage mapping file id that corresponds to the given 00211 /// clang file id. 00212 /// Return true if there was an error getting the coverage mapping file id. 00213 bool getExistingCoverageFileID(FileID File, unsigned &Result) { 00214 // Make sure that the file is valid. 00215 if (File.isInvalid()) 00216 return true; 00217 auto Mapping = FileIDMapping.find(File); 00218 if (Mapping != FileIDMapping.end()) { 00219 Result = Mapping->second.CovMappingFileID; 00220 return false; 00221 } 00222 return true; 00223 } 00224 00225 /// \brief Return true if the given clang's file id has a corresponding 00226 /// coverage file id. 00227 bool hasExistingCoverageFileID(FileID File) const { 00228 return FileIDMapping.count(File); 00229 } 00230 00231 /// \brief Gather all the regions that were skipped by the preprocessor 00232 /// using the constructs like #if. 00233 void gatherSkippedRegions() { 00234 /// An array of the minimum lineStarts and the maximum lineEnds 00235 /// for mapping regions from the appropriate source files. 00236 llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges; 00237 FileLineRanges.resize( 00238 FileIDMapping.size(), 00239 std::make_pair(std::numeric_limits<unsigned>::max(), 0)); 00240 for (const auto &R : MappingRegions) { 00241 FileLineRanges[R.FileID].first = 00242 std::min(FileLineRanges[R.FileID].first, R.LineStart); 00243 FileLineRanges[R.FileID].second = 00244 std::max(FileLineRanges[R.FileID].second, R.LineEnd); 00245 } 00246 00247 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges(); 00248 for (const auto &I : SkippedRanges) { 00249 auto LocStart = I.getBegin(); 00250 auto LocEnd = I.getEnd(); 00251 auto FileStart = SM.getFileID(LocStart); 00252 if (!hasExistingCoverageFileID(FileStart)) 00253 continue; 00254 auto ActualFileStart = SM.getDecomposedSpellingLoc(LocStart).first; 00255 if (ActualFileStart != SM.getDecomposedSpellingLoc(LocEnd).first) 00256 // Ignore regions that span across multiple files. 00257 continue; 00258 00259 unsigned CovFileID; 00260 if (getCoverageFileID(LocStart, FileStart, ActualFileStart, CovFileID)) 00261 continue; 00262 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 00263 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 00264 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd); 00265 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd); 00266 CounterMappingRegion Region(Counter(), CovFileID, LineStart, ColumnStart, 00267 LineEnd, ColumnEnd, false, 00268 CounterMappingRegion::SkippedRegion); 00269 // Make sure that we only collect the regions that are inside 00270 // the souce code of this function. 00271 if (Region.LineStart >= FileLineRanges[CovFileID].first && 00272 Region.LineEnd <= FileLineRanges[CovFileID].second) 00273 MappingRegions.push_back(Region); 00274 } 00275 } 00276 00277 /// \brief Create a mapping region that correponds to an expansion of 00278 /// a macro or an embedded include. 00279 void createFileExpansionRegion(SourceLocation Loc, FileID ExpandedFile) { 00280 SourceLocation LocStart; 00281 if (Loc.isMacroID()) 00282 LocStart = SM.getImmediateExpansionRange(Loc).first; 00283 else { 00284 LocStart = SM.getIncludeLoc(ExpandedFile); 00285 if (LocStart.isInvalid()) 00286 return; // This file has no expansion region. 00287 } 00288 00289 auto File = SM.getFileID(LocStart); 00290 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first; 00291 unsigned CovFileID, ExpandedFileID; 00292 if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID)) 00293 return; 00294 if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID)) 00295 return; 00296 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 00297 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 00298 unsigned LineEnd = LineStart; 00299 // Compute the end column manually as Lexer::getLocForEndOfToken doesn't 00300 // give the correct result in all cases. 00301 unsigned ColumnEnd = 00302 ColumnStart + 00303 Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM, LangOpts); 00304 00305 MappingRegions.push_back(CounterMappingRegion( 00306 Counter(), CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd, 00307 false, CounterMappingRegion::ExpansionRegion)); 00308 MappingRegions.back().ExpandedFileID = ExpandedFileID; 00309 } 00310 00311 /// \brief Enter a source region group that is identified by the given 00312 /// statement. 00313 /// It's not possible to enter a group when there is already 00314 /// another group present. 00315 void beginSourceRegionGroup(const Stmt *Group) { 00316 assert(!CurrentSourceGroup); 00317 CurrentSourceGroup = Group; 00318 } 00319 00320 /// \brief Exit the current source region group. 00321 void endSourceRegionGroup() { CurrentSourceGroup = nullptr; } 00322 00323 /// \brief Associate a counter with a given source code range. 00324 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 00325 Counter Count, const Stmt *UnreachableInitiator, 00326 const Stmt *SourceGroup, unsigned Flags = 0, 00327 FileID MacroArgumentFile = FileID()) { 00328 if (SM.isMacroArgExpansion(LocStart)) { 00329 // Map the code range with the macro argument's value. 00330 mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart), 00331 SM.getImmediateSpellingLoc(LocEnd), Count, 00332 UnreachableInitiator, SourceGroup, Flags, 00333 SM.getFileID(LocStart)); 00334 // Map the code range where the macro argument is referenced. 00335 SourceLocation RefLocStart(SM.getImmediateExpansionRange(LocStart).first); 00336 SourceLocation RefLocEnd(RefLocStart); 00337 if (SM.isMacroArgExpansion(RefLocStart)) 00338 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator, 00339 SourceGroup, 0, SM.getFileID(RefLocStart)); 00340 else 00341 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator, 00342 SourceGroup); 00343 return; 00344 } 00345 auto File = SM.getFileID(LocStart); 00346 // Make sure that the file id is valid. 00347 if (File.isInvalid()) 00348 return; 00349 SourceRegions.emplace_back(File, MacroArgumentFile, Count, 00350 UnreachableInitiator, SourceGroup, LocStart, 00351 LocEnd, Flags); 00352 } 00353 00354 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 00355 Counter Count, unsigned Flags = 0) { 00356 mapSourceCodeRange(LocStart, LocEnd, Count, 00357 CurrentUnreachableRegionInitiator, CurrentSourceGroup, 00358 Flags); 00359 } 00360 00361 void mapSourceCodeRange(const SourceMappingState &State, 00362 SourceLocation LocStart, SourceLocation LocEnd, 00363 unsigned Flags = 0) { 00364 mapSourceCodeRange(LocStart, LocEnd, State.CurrentRegionCount, 00365 State.CurrentUnreachableRegionInitiator, 00366 State.CurrentSourceGroup, Flags); 00367 } 00368 00369 /// \brief Generate the coverage counter mapping regions from collected 00370 /// source regions. 00371 void emitSourceRegions() { 00372 std::sort(SourceRegions.begin(), SourceRegions.end()); 00373 00374 for (auto I = SourceRegions.begin(), E = SourceRegions.end(); I != E; ++I) { 00375 // Keep the original start location of this region. 00376 SourceLocation LocStart = I->getStartLoc(); 00377 SourceLocation LocEnd = I->getEndLoc(SM); 00378 00379 bool Ignore = I->hasFlag(SourceMappingRegion::IgnoreIfNotExtended); 00380 // We need to handle mergeable regions together. 00381 for (auto Next = I + 1; Next != E && Next->isMergeable(*I); ++Next) { 00382 ++I; 00383 LocStart = std::min(LocStart, I->getStartLoc()); 00384 LocEnd = std::max(LocEnd, I->getEndLoc(SM)); 00385 // FIXME: Should we && together the Ignore flag of multiple regions? 00386 Ignore = false; 00387 } 00388 if (Ignore) 00389 continue; 00390 00391 // Find the spilling locations for the mapping region. 00392 LocEnd = getPreciseTokenLocEnd(LocEnd); 00393 unsigned LineStart = SM.getSpellingLineNumber(LocStart); 00394 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart); 00395 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd); 00396 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd); 00397 00398 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first; 00399 unsigned CovFileID; 00400 if (getCoverageFileID(LocStart, I->getFile(), SpellingFile, CovFileID)) 00401 continue; 00402 00403 assert(LineStart <= LineEnd); 00404 MappingRegions.push_back(CounterMappingRegion( 00405 I->getCounter(), CovFileID, LineStart, ColumnStart, LineEnd, 00406 ColumnEnd, false, CounterMappingRegion::CodeRegion)); 00407 } 00408 } 00409 }; 00410 00411 /// \brief Creates unreachable coverage regions for the functions that 00412 /// are not emitted. 00413 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder { 00414 EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 00415 const LangOptions &LangOpts) 00416 : CoverageMappingBuilder(CVM, SM, LangOpts) {} 00417 00418 void VisitDecl(const Decl *D) { 00419 if (!D->hasBody()) 00420 return; 00421 auto Body = D->getBody(); 00422 mapSourceCodeRange(Body->getLocStart(), Body->getLocEnd(), Counter()); 00423 } 00424 00425 /// \brief Write the mapping data to the output stream 00426 void write(llvm::raw_ostream &OS) { 00427 emitSourceRegions(); 00428 SmallVector<unsigned, 16> FileIDMapping; 00429 createFileIDMapping(FileIDMapping); 00430 00431 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions); 00432 Writer.write(OS); 00433 } 00434 }; 00435 00436 /// \brief A StmtVisitor that creates coverage mapping regions which map 00437 /// from the source code locations to the PGO counters. 00438 struct CounterCoverageMappingBuilder 00439 : public CoverageMappingBuilder, 00440 public ConstStmtVisitor<CounterCoverageMappingBuilder> { 00441 /// \brief The map of statements to count values. 00442 llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 00443 00444 Counter CurrentRegionCount; 00445 00446 CounterExpressionBuilder Builder; 00447 00448 /// \brief Return a counter that represents the 00449 /// expression that subracts rhs from lhs. 00450 Counter subtractCounters(Counter LHS, Counter RHS) { 00451 return Builder.subtract(LHS, RHS); 00452 } 00453 00454 /// \brief Return a counter that represents the 00455 /// the exression that adds lhs and rhs. 00456 Counter addCounters(Counter LHS, Counter RHS) { 00457 return Builder.add(LHS, RHS); 00458 } 00459 00460 /// \brief Return the region counter for the given statement. 00461 /// This should only be called on statements that have a dedicated counter. 00462 unsigned getRegionCounter(const Stmt *S) { return CounterMap[S]; } 00463 00464 /// \brief Return the region count for the counter at the given index. 00465 Counter getRegionCount(unsigned CounterId) { 00466 return Counter::getCounter(CounterId); 00467 } 00468 00469 /// \brief Return the counter value of the current region. 00470 Counter getCurrentRegionCount() { return CurrentRegionCount; } 00471 00472 /// \brief Set the counter value for the current region. 00473 /// This is used to keep track of changes to the most recent counter 00474 /// from control flow and non-local exits. 00475 void setCurrentRegionCount(Counter Count) { 00476 CurrentRegionCount = Count; 00477 CurrentUnreachableRegionInitiator = nullptr; 00478 } 00479 00480 /// \brief Indicate that the current region is never reached, 00481 /// and thus should have a counter value of zero. 00482 /// This is important so that subsequent regions can correctly track 00483 /// their parent counts. 00484 void setCurrentRegionUnreachable(const Stmt *Initiator) { 00485 CurrentRegionCount = Counter::getZero(); 00486 CurrentUnreachableRegionInitiator = Initiator; 00487 } 00488 00489 /// \brief A counter for a particular region. 00490 /// This is the primary interface through 00491 /// which the coverage mapping builder manages counters and their values. 00492 class RegionMapper { 00493 CounterCoverageMappingBuilder &Mapping; 00494 Counter Count; 00495 Counter ParentCount; 00496 Counter RegionCount; 00497 Counter Adjust; 00498 00499 public: 00500 RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt *S) 00501 : Mapping(*Mapper), 00502 Count(Mapper->getRegionCount(Mapper->getRegionCounter(S))), 00503 ParentCount(Mapper->getCurrentRegionCount()) {} 00504 00505 /// Get the value of the counter. In most cases this is the number of times 00506 /// the region of the counter was entered, but for switch labels it's the 00507 /// number of direct jumps to that label. 00508 Counter getCount() const { return Count; } 00509 00510 /// Get the value of the counter with adjustments applied. Adjustments occur 00511 /// when control enters or leaves the region abnormally; i.e., if there is a 00512 /// jump to a label within the region, or if the function can return from 00513 /// within the region. The adjusted count, then, is the value of the counter 00514 /// at the end of the region. 00515 Counter getAdjustedCount() const { 00516 return Mapping.addCounters(Count, Adjust); 00517 } 00518 00519 /// Get the value of the counter in this region's parent, i.e., the region 00520 /// that was active when this region began. This is useful for deriving 00521 /// counts in implicitly counted regions, like the false case of a condition 00522 /// or the normal exits of a loop. 00523 Counter getParentCount() const { return ParentCount; } 00524 00525 /// Activate the counter by emitting an increment and starting to track 00526 /// adjustments. If AddIncomingFallThrough is true, the current region count 00527 /// will be added to the counter for the purposes of tracking the region. 00528 void beginRegion(bool AddIncomingFallThrough = false) { 00529 RegionCount = Count; 00530 if (AddIncomingFallThrough) 00531 RegionCount = 00532 Mapping.addCounters(RegionCount, Mapping.getCurrentRegionCount()); 00533 Mapping.setCurrentRegionCount(RegionCount); 00534 } 00535 00536 /// For counters on boolean branches, begins tracking adjustments for the 00537 /// uncounted path. 00538 void beginElseRegion() { 00539 RegionCount = Mapping.subtractCounters(ParentCount, Count); 00540 Mapping.setCurrentRegionCount(RegionCount); 00541 } 00542 00543 /// Reset the current region count. 00544 void setCurrentRegionCount(Counter CurrentCount) { 00545 RegionCount = CurrentCount; 00546 Mapping.setCurrentRegionCount(RegionCount); 00547 } 00548 00549 /// Adjust for non-local control flow after emitting a subexpression or 00550 /// substatement. This must be called to account for constructs such as 00551 /// gotos, 00552 /// labels, and returns, so that we can ensure that our region's count is 00553 /// correct in the code that follows. 00554 void adjustForControlFlow() { 00555 Adjust = Mapping.addCounters( 00556 Adjust, Mapping.subtractCounters(Mapping.getCurrentRegionCount(), 00557 RegionCount)); 00558 // Reset the region count in case this is called again later. 00559 RegionCount = Mapping.getCurrentRegionCount(); 00560 } 00561 00562 /// Commit all adjustments to the current region. If the region is a loop, 00563 /// the LoopAdjust value should be the count of all the breaks and continues 00564 /// from the loop, to compensate for those counts being deducted from the 00565 /// adjustments for the body of the loop. 00566 void applyAdjustmentsToRegion() { 00567 Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount, Adjust)); 00568 } 00569 void applyAdjustmentsToRegion(Counter LoopAdjust) { 00570 Mapping.setCurrentRegionCount(Mapping.addCounters( 00571 Mapping.addCounters(ParentCount, Adjust), LoopAdjust)); 00572 } 00573 }; 00574 00575 /// \brief Keep counts of breaks and continues inside loops. 00576 struct BreakContinue { 00577 Counter BreakCount; 00578 Counter ContinueCount; 00579 }; 00580 SmallVector<BreakContinue, 8> BreakContinueStack; 00581 00582 CounterCoverageMappingBuilder( 00583 CoverageMappingModuleGen &CVM, 00584 llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM, 00585 const LangOptions &LangOpts) 00586 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {} 00587 00588 /// \brief Write the mapping data to the output stream 00589 void write(llvm::raw_ostream &OS) { 00590 emitSourceRegions(); 00591 llvm::SmallVector<unsigned, 8> VirtualFileMapping; 00592 createFileIDMapping(VirtualFileMapping); 00593 gatherSkippedRegions(); 00594 00595 CoverageMappingWriter Writer( 00596 VirtualFileMapping, Builder.getExpressions(), MappingRegions); 00597 Writer.write(OS); 00598 } 00599 00600 /// \brief Return the current source mapping state. 00601 SourceMappingState getCurrentState() const { 00602 return SourceMappingState(CurrentRegionCount, CurrentSourceGroup, 00603 CurrentUnreachableRegionInitiator); 00604 } 00605 00606 /// \brief Associate the source code range with the current region count. 00607 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd, 00608 unsigned Flags = 0) { 00609 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd, 00610 CurrentRegionCount, Flags); 00611 } 00612 00613 void mapSourceCodeRange(SourceLocation LocStart) { 00614 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart, 00615 CurrentRegionCount); 00616 } 00617 00618 /// \brief Associate the source range of a token with the current region 00619 /// count. 00620 /// Ignore the source range for this token if it produces a distinct 00621 /// mapping region with no other source ranges. 00622 void mapToken(SourceLocation LocStart) { 00623 CoverageMappingBuilder::mapSourceCodeRange( 00624 LocStart, LocStart, CurrentRegionCount, 00625 SourceMappingRegion::IgnoreIfNotExtended); 00626 } 00627 00628 void mapToken(const SourceMappingState &State, SourceLocation LocStart) { 00629 CoverageMappingBuilder::mapSourceCodeRange( 00630 State, LocStart, LocStart, SourceMappingRegion::IgnoreIfNotExtended); 00631 } 00632 00633 void VisitStmt(const Stmt *S) { 00634 mapSourceCodeRange(S->getLocStart()); 00635 for (Stmt::const_child_range I = S->children(); I; ++I) { 00636 if (*I) 00637 this->Visit(*I); 00638 } 00639 } 00640 00641 void VisitDecl(const Decl *D) { 00642 if (!D->hasBody()) 00643 return; 00644 // Counter tracks entry to the function body. 00645 auto Body = D->getBody(); 00646 RegionMapper Cnt(this, Body); 00647 Cnt.beginRegion(); 00648 Visit(Body); 00649 } 00650 00651 void VisitDeclStmt(const DeclStmt *S) { 00652 mapSourceCodeRange(S->getLocStart()); 00653 for (Stmt::const_child_range I = static_cast<const Stmt *>(S)->children(); 00654 I; ++I) { 00655 if (*I) 00656 this->Visit(*I); 00657 } 00658 } 00659 00660 void VisitCompoundStmt(const CompoundStmt *S) { 00661 SourceMappingState State = getCurrentState(); 00662 mapSourceCodeRange(S->getLBracLoc()); 00663 for (Stmt::const_child_range I = S->children(); I; ++I) { 00664 if (*I) 00665 this->Visit(*I); 00666 } 00667 CoverageMappingBuilder::mapSourceCodeRange(State, S->getRBracLoc(), 00668 S->getRBracLoc()); 00669 } 00670 00671 void VisitReturnStmt(const ReturnStmt *S) { 00672 mapSourceCodeRange(S->getLocStart()); 00673 if (S->getRetValue()) 00674 Visit(S->getRetValue()); 00675 setCurrentRegionUnreachable(S); 00676 } 00677 00678 void VisitGotoStmt(const GotoStmt *S) { 00679 mapSourceCodeRange(S->getLocStart()); 00680 mapToken(S->getLabelLoc()); 00681 setCurrentRegionUnreachable(S); 00682 } 00683 00684 void VisitLabelStmt(const LabelStmt *S) { 00685 // Counter tracks the block following the label. 00686 RegionMapper Cnt(this, S); 00687 Cnt.beginRegion(); 00688 mapSourceCodeRange(S->getLocStart()); 00689 // Can't map the ':' token as its location isn't known. 00690 Visit(S->getSubStmt()); 00691 } 00692 00693 void VisitBreakStmt(const BreakStmt *S) { 00694 mapSourceCodeRange(S->getLocStart()); 00695 assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 00696 BreakContinueStack.back().BreakCount = addCounters( 00697 BreakContinueStack.back().BreakCount, getCurrentRegionCount()); 00698 setCurrentRegionUnreachable(S); 00699 } 00700 00701 void VisitContinueStmt(const ContinueStmt *S) { 00702 mapSourceCodeRange(S->getLocStart()); 00703 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 00704 BreakContinueStack.back().ContinueCount = addCounters( 00705 BreakContinueStack.back().ContinueCount, getCurrentRegionCount()); 00706 setCurrentRegionUnreachable(S); 00707 } 00708 00709 void VisitWhileStmt(const WhileStmt *S) { 00710 mapSourceCodeRange(S->getLocStart()); 00711 // Counter tracks the body of the loop. 00712 RegionMapper Cnt(this, S); 00713 BreakContinueStack.push_back(BreakContinue()); 00714 // Visit the body region first so the break/continue adjustments can be 00715 // included when visiting the condition. 00716 Cnt.beginRegion(); 00717 Visit(S->getBody()); 00718 Cnt.adjustForControlFlow(); 00719 00720 // ...then go back and propagate counts through the condition. The count 00721 // at the start of the condition is the sum of the incoming edges, 00722 // the backedge from the end of the loop body, and the edges from 00723 // continue statements. 00724 BreakContinue BC = BreakContinueStack.pop_back_val(); 00725 Cnt.setCurrentRegionCount( 00726 addCounters(Cnt.getParentCount(), 00727 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount))); 00728 beginSourceRegionGroup(S->getCond()); 00729 Visit(S->getCond()); 00730 endSourceRegionGroup(); 00731 Cnt.adjustForControlFlow(); 00732 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 00733 } 00734 00735 void VisitDoStmt(const DoStmt *S) { 00736 mapSourceCodeRange(S->getLocStart()); 00737 // Counter tracks the body of the loop. 00738 RegionMapper Cnt(this, S); 00739 BreakContinueStack.push_back(BreakContinue()); 00740 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 00741 Visit(S->getBody()); 00742 Cnt.adjustForControlFlow(); 00743 00744 BreakContinue BC = BreakContinueStack.pop_back_val(); 00745 // The count at the start of the condition is equal to the count at the 00746 // end of the body. The adjusted count does not include either the 00747 // fall-through count coming into the loop or the continue count, so add 00748 // both of those separately. This is coincidentally the same equation as 00749 // with while loops but for different reasons. 00750 Cnt.setCurrentRegionCount( 00751 addCounters(Cnt.getParentCount(), 00752 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount))); 00753 Visit(S->getCond()); 00754 Cnt.adjustForControlFlow(); 00755 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 00756 } 00757 00758 void VisitForStmt(const ForStmt *S) { 00759 mapSourceCodeRange(S->getLocStart()); 00760 if (S->getInit()) 00761 Visit(S->getInit()); 00762 00763 // Counter tracks the body of the loop. 00764 RegionMapper Cnt(this, S); 00765 BreakContinueStack.push_back(BreakContinue()); 00766 // Visit the body region first. (This is basically the same as a while 00767 // loop; see further comments in VisitWhileStmt.) 00768 Cnt.beginRegion(); 00769 Visit(S->getBody()); 00770 Cnt.adjustForControlFlow(); 00771 00772 // The increment is essentially part of the body but it needs to include 00773 // the count for all the continue statements. 00774 if (S->getInc()) { 00775 Cnt.setCurrentRegionCount(addCounters( 00776 getCurrentRegionCount(), BreakContinueStack.back().ContinueCount)); 00777 beginSourceRegionGroup(S->getInc()); 00778 Visit(S->getInc()); 00779 endSourceRegionGroup(); 00780 Cnt.adjustForControlFlow(); 00781 } 00782 00783 BreakContinue BC = BreakContinueStack.pop_back_val(); 00784 00785 // ...then go back and propagate counts through the condition. 00786 if (S->getCond()) { 00787 Cnt.setCurrentRegionCount( 00788 addCounters(addCounters(Cnt.getParentCount(), Cnt.getAdjustedCount()), 00789 BC.ContinueCount)); 00790 beginSourceRegionGroup(S->getCond()); 00791 Visit(S->getCond()); 00792 endSourceRegionGroup(); 00793 Cnt.adjustForControlFlow(); 00794 } 00795 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 00796 } 00797 00798 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 00799 mapSourceCodeRange(S->getLocStart()); 00800 Visit(S->getRangeStmt()); 00801 Visit(S->getBeginEndStmt()); 00802 // Counter tracks the body of the loop. 00803 RegionMapper Cnt(this, S); 00804 BreakContinueStack.push_back(BreakContinue()); 00805 // Visit the body region first. (This is basically the same as a while 00806 // loop; see further comments in VisitWhileStmt.) 00807 Cnt.beginRegion(); 00808 Visit(S->getBody()); 00809 Cnt.adjustForControlFlow(); 00810 BreakContinue BC = BreakContinueStack.pop_back_val(); 00811 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 00812 } 00813 00814 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 00815 mapSourceCodeRange(S->getLocStart()); 00816 Visit(S->getElement()); 00817 // Counter tracks the body of the loop. 00818 RegionMapper Cnt(this, S); 00819 BreakContinueStack.push_back(BreakContinue()); 00820 Cnt.beginRegion(); 00821 Visit(S->getBody()); 00822 BreakContinue BC = BreakContinueStack.pop_back_val(); 00823 Cnt.adjustForControlFlow(); 00824 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount)); 00825 } 00826 00827 void VisitSwitchStmt(const SwitchStmt *S) { 00828 mapSourceCodeRange(S->getLocStart()); 00829 Visit(S->getCond()); 00830 BreakContinueStack.push_back(BreakContinue()); 00831 // Map the '}' for the body to have the same count as the regions after 00832 // the switch. 00833 SourceLocation RBracLoc; 00834 if (const auto *CS = dyn_cast<CompoundStmt>(S->getBody())) { 00835 mapSourceCodeRange(CS->getLBracLoc()); 00836 setCurrentRegionUnreachable(S); 00837 for (Stmt::const_child_range I = CS->children(); I; ++I) { 00838 if (*I) 00839 this->Visit(*I); 00840 } 00841 RBracLoc = CS->getRBracLoc(); 00842 } else { 00843 setCurrentRegionUnreachable(S); 00844 Visit(S->getBody()); 00845 } 00846 // If the switch is inside a loop, add the continue counts. 00847 BreakContinue BC = BreakContinueStack.pop_back_val(); 00848 if (!BreakContinueStack.empty()) 00849 BreakContinueStack.back().ContinueCount = addCounters( 00850 BreakContinueStack.back().ContinueCount, BC.ContinueCount); 00851 // Counter tracks the exit block of the switch. 00852 RegionMapper ExitCnt(this, S); 00853 ExitCnt.beginRegion(); 00854 if (RBracLoc.isValid()) 00855 mapSourceCodeRange(RBracLoc); 00856 } 00857 00858 void VisitCaseStmt(const CaseStmt *S) { 00859 // Counter for this particular case. This counts only jumps from the 00860 // switch header and does not include fallthrough from the case before 00861 // this one. 00862 RegionMapper Cnt(this, S); 00863 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 00864 mapSourceCodeRange(S->getLocStart()); 00865 mapToken(S->getColonLoc()); 00866 Visit(S->getSubStmt()); 00867 } 00868 00869 void VisitDefaultStmt(const DefaultStmt *S) { 00870 // Counter for this default case. This does not include fallthrough from 00871 // the previous case. 00872 RegionMapper Cnt(this, S); 00873 Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 00874 mapSourceCodeRange(S->getLocStart()); 00875 mapToken(S->getColonLoc()); 00876 Visit(S->getSubStmt()); 00877 } 00878 00879 void VisitIfStmt(const IfStmt *S) { 00880 mapSourceCodeRange(S->getLocStart()); 00881 Visit(S->getCond()); 00882 mapToken(S->getElseLoc()); 00883 00884 // Counter tracks the "then" part of an if statement. The count for 00885 // the "else" part, if it exists, will be calculated from this counter. 00886 RegionMapper Cnt(this, S); 00887 Cnt.beginRegion(); 00888 Visit(S->getThen()); 00889 Cnt.adjustForControlFlow(); 00890 00891 if (S->getElse()) { 00892 Cnt.beginElseRegion(); 00893 Visit(S->getElse()); 00894 Cnt.adjustForControlFlow(); 00895 } 00896 Cnt.applyAdjustmentsToRegion(); 00897 } 00898 00899 void VisitCXXTryStmt(const CXXTryStmt *S) { 00900 mapSourceCodeRange(S->getLocStart()); 00901 Visit(S->getTryBlock()); 00902 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 00903 Visit(S->getHandler(I)); 00904 // Counter tracks the continuation block of the try statement. 00905 RegionMapper Cnt(this, S); 00906 Cnt.beginRegion(); 00907 } 00908 00909 void VisitCXXCatchStmt(const CXXCatchStmt *S) { 00910 mapSourceCodeRange(S->getLocStart()); 00911 // Counter tracks the catch statement's handler block. 00912 RegionMapper Cnt(this, S); 00913 Cnt.beginRegion(); 00914 Visit(S->getHandlerBlock()); 00915 } 00916 00917 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 00918 Visit(E->getCond()); 00919 mapToken(E->getQuestionLoc()); 00920 auto State = getCurrentState(); 00921 00922 // Counter tracks the "true" part of a conditional operator. The 00923 // count in the "false" part will be calculated from this counter. 00924 RegionMapper Cnt(this, E); 00925 Cnt.beginRegion(); 00926 Visit(E->getTrueExpr()); 00927 Cnt.adjustForControlFlow(); 00928 00929 mapToken(State, E->getColonLoc()); 00930 00931 Cnt.beginElseRegion(); 00932 Visit(E->getFalseExpr()); 00933 Cnt.adjustForControlFlow(); 00934 00935 Cnt.applyAdjustmentsToRegion(); 00936 } 00937 00938 void VisitBinLAnd(const BinaryOperator *E) { 00939 Visit(E->getLHS()); 00940 mapToken(E->getOperatorLoc()); 00941 // Counter tracks the right hand side of a logical and operator. 00942 RegionMapper Cnt(this, E); 00943 Cnt.beginRegion(); 00944 Visit(E->getRHS()); 00945 Cnt.adjustForControlFlow(); 00946 Cnt.applyAdjustmentsToRegion(); 00947 } 00948 00949 void VisitBinLOr(const BinaryOperator *E) { 00950 Visit(E->getLHS()); 00951 mapToken(E->getOperatorLoc()); 00952 // Counter tracks the right hand side of a logical or operator. 00953 RegionMapper Cnt(this, E); 00954 Cnt.beginRegion(); 00955 Visit(E->getRHS()); 00956 Cnt.adjustForControlFlow(); 00957 Cnt.applyAdjustmentsToRegion(); 00958 } 00959 00960 void VisitParenExpr(const ParenExpr *E) { 00961 mapToken(E->getLParen()); 00962 Visit(E->getSubExpr()); 00963 mapToken(E->getRParen()); 00964 } 00965 00966 void VisitBinaryOperator(const BinaryOperator *E) { 00967 Visit(E->getLHS()); 00968 mapToken(E->getOperatorLoc()); 00969 Visit(E->getRHS()); 00970 } 00971 00972 void VisitUnaryOperator(const UnaryOperator *E) { 00973 bool Postfix = E->isPostfix(); 00974 if (!Postfix) 00975 mapToken(E->getOperatorLoc()); 00976 Visit(E->getSubExpr()); 00977 if (Postfix) 00978 mapToken(E->getOperatorLoc()); 00979 } 00980 00981 void VisitMemberExpr(const MemberExpr *E) { 00982 Visit(E->getBase()); 00983 mapToken(E->getMemberLoc()); 00984 } 00985 00986 void VisitCallExpr(const CallExpr *E) { 00987 Visit(E->getCallee()); 00988 for (const auto &Arg : E->arguments()) 00989 Visit(Arg); 00990 mapToken(E->getRParenLoc()); 00991 } 00992 00993 void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { 00994 Visit(E->getLHS()); 00995 Visit(E->getRHS()); 00996 mapToken(E->getRBracketLoc()); 00997 } 00998 00999 void VisitCStyleCastExpr(const CStyleCastExpr *E) { 01000 mapToken(E->getLParenLoc()); 01001 mapToken(E->getRParenLoc()); 01002 Visit(E->getSubExpr()); 01003 } 01004 01005 // Map literals as tokens so that the macros like #define PI 3.14 01006 // won't generate coverage mapping regions. 01007 01008 void VisitIntegerLiteral(const IntegerLiteral *E) { 01009 mapToken(E->getLocStart()); 01010 } 01011 01012 void VisitFloatingLiteral(const FloatingLiteral *E) { 01013 mapToken(E->getLocStart()); 01014 } 01015 01016 void VisitCharacterLiteral(const CharacterLiteral *E) { 01017 mapToken(E->getLocStart()); 01018 } 01019 01020 void VisitStringLiteral(const StringLiteral *E) { 01021 mapToken(E->getLocStart()); 01022 } 01023 01024 void VisitImaginaryLiteral(const ImaginaryLiteral *E) { 01025 mapToken(E->getLocStart()); 01026 } 01027 01028 void VisitObjCMessageExpr(const ObjCMessageExpr *E) { 01029 mapToken(E->getLeftLoc()); 01030 for (Stmt::const_child_range I = static_cast<const Stmt*>(E)->children(); I; 01031 ++I) { 01032 if (*I) 01033 this->Visit(*I); 01034 } 01035 mapToken(E->getRightLoc()); 01036 } 01037 }; 01038 } 01039 01040 static bool isMachO(const CodeGenModule &CGM) { 01041 return CGM.getTarget().getTriple().isOSBinFormatMachO(); 01042 } 01043 01044 static StringRef getCoverageSection(const CodeGenModule &CGM) { 01045 return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap"; 01046 } 01047 01048 static void dump(llvm::raw_ostream &OS, const CoverageMappingRecord &Function) { 01049 OS << Function.FunctionName << ":\n"; 01050 CounterMappingContext Ctx(Function.Expressions); 01051 for (const auto &R : Function.MappingRegions) { 01052 OS.indent(2); 01053 switch (R.Kind) { 01054 case CounterMappingRegion::CodeRegion: 01055 break; 01056 case CounterMappingRegion::ExpansionRegion: 01057 OS << "Expansion,"; 01058 break; 01059 case CounterMappingRegion::SkippedRegion: 01060 OS << "Skipped,"; 01061 break; 01062 } 01063 01064 OS << "File " << R.FileID << ", " << R.LineStart << ":" 01065 << R.ColumnStart << " -> " << R.LineEnd << ":" << R.ColumnEnd 01066 << " = "; 01067 Ctx.dump(R.Count); 01068 OS << " (HasCodeBefore = " << R.HasCodeBefore; 01069 if (R.Kind == CounterMappingRegion::ExpansionRegion) 01070 OS << ", Expanded file = " << R.ExpandedFileID; 01071 01072 OS << ")\n"; 01073 } 01074 } 01075 01076 void CoverageMappingModuleGen::addFunctionMappingRecord( 01077 llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, 01078 uint64_t FunctionHash, const std::string &CoverageMapping) { 01079 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 01080 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 01081 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx); 01082 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx); 01083 if (!FunctionRecordTy) { 01084 llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty, Int64Ty}; 01085 FunctionRecordTy = 01086 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes)); 01087 } 01088 01089 llvm::Constant *FunctionRecordVals[] = { 01090 llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy), 01091 llvm::ConstantInt::get(Int32Ty, FunctionNameValue.size()), 01092 llvm::ConstantInt::get(Int32Ty, CoverageMapping.size()), 01093 llvm::ConstantInt::get(Int64Ty, FunctionHash)}; 01094 FunctionRecords.push_back(llvm::ConstantStruct::get( 01095 FunctionRecordTy, makeArrayRef(FunctionRecordVals))); 01096 CoverageMappings += CoverageMapping; 01097 01098 if (CGM.getCodeGenOpts().DumpCoverageMapping) { 01099 // Dump the coverage mapping data for this function by decoding the 01100 // encoded data. This allows us to dump the mapping regions which were 01101 // also processed by the CoverageMappingWriter which performs 01102 // additional minimization operations such as reducing the number of 01103 // expressions. 01104 std::vector<StringRef> Filenames; 01105 std::vector<CounterExpression> Expressions; 01106 std::vector<CounterMappingRegion> Regions; 01107 llvm::SmallVector<StringRef, 16> FilenameRefs; 01108 FilenameRefs.resize(FileEntries.size()); 01109 for (const auto &Entry : FileEntries) 01110 FilenameRefs[Entry.second] = Entry.first->getName(); 01111 RawCoverageMappingReader Reader(FunctionNameValue, CoverageMapping, 01112 FilenameRefs, 01113 Filenames, Expressions, Regions); 01114 CoverageMappingRecord FunctionRecord; 01115 if (Reader.read(FunctionRecord)) 01116 return; 01117 dump(llvm::outs(), FunctionRecord); 01118 } 01119 } 01120 01121 void CoverageMappingModuleGen::emit() { 01122 if (FunctionRecords.empty()) 01123 return; 01124 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 01125 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 01126 01127 // Create the filenames and merge them with coverage mappings 01128 llvm::SmallVector<std::string, 16> FilenameStrs; 01129 llvm::SmallVector<StringRef, 16> FilenameRefs; 01130 FilenameStrs.resize(FileEntries.size()); 01131 FilenameRefs.resize(FileEntries.size()); 01132 for (const auto &Entry : FileEntries) { 01133 llvm::SmallString<256> Path(Entry.first->getName()); 01134 llvm::sys::fs::make_absolute(Path); 01135 01136 auto I = Entry.second; 01137 FilenameStrs[I] = std::move(std::string(Path.begin(), Path.end())); 01138 FilenameRefs[I] = FilenameStrs[I]; 01139 } 01140 01141 std::string FilenamesAndCoverageMappings; 01142 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings); 01143 CoverageFilenamesSectionWriter(FilenameRefs).write(OS); 01144 OS << CoverageMappings; 01145 size_t CoverageMappingSize = CoverageMappings.size(); 01146 size_t FilenamesSize = OS.str().size() - CoverageMappingSize; 01147 // Append extra zeroes if necessary to ensure that the size of the filenames 01148 // and coverage mappings is a multiple of 8. 01149 if (size_t Rem = OS.str().size() % 8) { 01150 CoverageMappingSize += 8 - Rem; 01151 for (size_t I = 0, S = 8 - Rem; I < S; ++I) 01152 OS << '\0'; 01153 } 01154 auto *FilenamesAndMappingsVal = 01155 llvm::ConstantDataArray::getString(Ctx, OS.str(), false); 01156 01157 // Create the deferred function records array 01158 auto RecordsTy = 01159 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size()); 01160 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords); 01161 01162 // Create the coverage data record 01163 llvm::Type *CovDataTypes[] = {Int32Ty, Int32Ty, 01164 Int32Ty, Int32Ty, 01165 RecordsTy, FilenamesAndMappingsVal->getType()}; 01166 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes)); 01167 llvm::Constant *TUDataVals[] = { 01168 llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()), 01169 llvm::ConstantInt::get(Int32Ty, FilenamesSize), 01170 llvm::ConstantInt::get(Int32Ty, CoverageMappingSize), 01171 llvm::ConstantInt::get(Int32Ty, 01172 /*Version=*/CoverageMappingVersion1), 01173 RecordsVal, FilenamesAndMappingsVal}; 01174 auto CovDataVal = 01175 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals)); 01176 auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy, true, 01177 llvm::GlobalValue::InternalLinkage, 01178 CovDataVal, 01179 "__llvm_coverage_mapping"); 01180 01181 CovData->setSection(getCoverageSection(CGM)); 01182 CovData->setAlignment(8); 01183 01184 // Make sure the data doesn't get deleted. 01185 CGM.addUsedGlobal(CovData); 01186 } 01187 01188 unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) { 01189 auto It = FileEntries.find(File); 01190 if (It != FileEntries.end()) 01191 return It->second; 01192 unsigned FileID = FileEntries.size(); 01193 FileEntries.insert(std::make_pair(File, FileID)); 01194 return FileID; 01195 } 01196 01197 void CoverageMappingGen::emitCounterMapping(const Decl *D, 01198 llvm::raw_ostream &OS) { 01199 assert(CounterMap); 01200 CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts); 01201 Walker.VisitDecl(D); 01202 Walker.write(OS); 01203 } 01204 01205 void CoverageMappingGen::emitEmptyMapping(const Decl *D, 01206 llvm::raw_ostream &OS) { 01207 EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts); 01208 Walker.VisitDecl(D); 01209 Walker.write(OS); 01210 }