clang  7.0.0
CoverageMappingGen.cpp
Go to the documentation of this file.
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/ADT/SmallSet.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
22 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
23 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
24 #include "llvm/ProfileData/InstrProfReader.h"
25 #include "llvm/Support/FileSystem.h"
26 #include "llvm/Support/Path.h"
27 
28 using namespace clang;
29 using namespace CodeGen;
30 using namespace llvm::coverage;
31 
33  SkippedRanges.push_back(Range);
34 }
35 
36 namespace {
37 
38 /// A region of source code that can be mapped to a counter.
39 class SourceMappingRegion {
40  Counter Count;
41 
42  /// The region's starting location.
43  Optional<SourceLocation> LocStart;
44 
45  /// The region's ending location.
47 
48  /// Whether this region should be emitted after its parent is emitted.
49  bool DeferRegion;
50 
51  /// Whether this region is a gap region. The count from a gap region is set
52  /// as the line execution count if there are no other regions on the line.
53  bool GapRegion;
54 
55 public:
56  SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
57  Optional<SourceLocation> LocEnd, bool DeferRegion = false,
58  bool GapRegion = false)
59  : Count(Count), LocStart(LocStart), LocEnd(LocEnd),
60  DeferRegion(DeferRegion), GapRegion(GapRegion) {}
61 
62  const Counter &getCounter() const { return Count; }
63 
64  void setCounter(Counter C) { Count = C; }
65 
66  bool hasStartLoc() const { return LocStart.hasValue(); }
67 
68  void setStartLoc(SourceLocation Loc) { LocStart = Loc; }
69 
70  SourceLocation getStartLoc() const LLVM_READONLY { return getBeginLoc(); }
71  SourceLocation getBeginLoc() const {
72  assert(LocStart && "Region has no start location");
73  return *LocStart;
74  }
75 
76  bool hasEndLoc() const { return LocEnd.hasValue(); }
77 
78  void setEndLoc(SourceLocation Loc) {
79  assert(Loc.isValid() && "Setting an invalid end location");
80  LocEnd = Loc;
81  }
82 
83  SourceLocation getEndLoc() const {
84  assert(LocEnd && "Region has no end location");
85  return *LocEnd;
86  }
87 
88  bool isDeferred() const { return DeferRegion; }
89 
90  void setDeferred(bool Deferred) { DeferRegion = Deferred; }
91 
92  bool isGap() const { return GapRegion; }
93 
94  void setGap(bool Gap) { GapRegion = Gap; }
95 };
96 
97 /// Spelling locations for the start and end of a source region.
98 struct SpellingRegion {
99  /// The line where the region starts.
100  unsigned LineStart;
101 
102  /// The column where the region starts.
103  unsigned ColumnStart;
104 
105  /// The line where the region ends.
106  unsigned LineEnd;
107 
108  /// The column where the region ends.
109  unsigned ColumnEnd;
110 
111  SpellingRegion(SourceManager &SM, SourceLocation LocStart,
112  SourceLocation LocEnd) {
113  LineStart = SM.getSpellingLineNumber(LocStart);
114  ColumnStart = SM.getSpellingColumnNumber(LocStart);
115  LineEnd = SM.getSpellingLineNumber(LocEnd);
116  ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
117  }
118 
119  SpellingRegion(SourceManager &SM, SourceMappingRegion &R)
120  : SpellingRegion(SM, R.getStartLoc(), R.getEndLoc()) {}
121 
122  /// Check if the start and end locations appear in source order, i.e
123  /// top->bottom, left->right.
124  bool isInSourceOrder() const {
125  return (LineStart < LineEnd) ||
126  (LineStart == LineEnd && ColumnStart <= ColumnEnd);
127  }
128 };
129 
130 /// Provides the common functionality for the different
131 /// coverage mapping region builders.
132 class CoverageMappingBuilder {
133 public:
135  SourceManager &SM;
136  const LangOptions &LangOpts;
137 
138 private:
139  /// Map of clang's FileIDs to IDs used for coverage mapping.
140  llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
141  FileIDMapping;
142 
143 public:
144  /// The coverage mapping regions for this function
146  /// The source mapping regions for this function.
147  std::vector<SourceMappingRegion> SourceRegions;
148 
149  /// A set of regions which can be used as a filter.
150  ///
151  /// It is produced by emitExpansionRegions() and is used in
152  /// emitSourceRegions() to suppress producing code regions if
153  /// the same area is covered by expansion regions.
154  typedef llvm::SmallSet<std::pair<SourceLocation, SourceLocation>, 8>
155  SourceRegionFilter;
156 
157  CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
158  const LangOptions &LangOpts)
159  : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
160 
161  /// Return the precise end location for the given token.
162  SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
163  // We avoid getLocForEndOfToken here, because it doesn't do what we want for
164  // macro locations, which we just treat as expanded files.
165  unsigned TokLen =
166  Lexer::MeasureTokenLength(SM.getSpellingLoc(Loc), SM, LangOpts);
167  return Loc.getLocWithOffset(TokLen);
168  }
169 
170  /// Return the start location of an included file or expanded macro.
171  SourceLocation getStartOfFileOrMacro(SourceLocation Loc) {
172  if (Loc.isMacroID())
173  return Loc.getLocWithOffset(-SM.getFileOffset(Loc));
174  return SM.getLocForStartOfFile(SM.getFileID(Loc));
175  }
176 
177  /// Return the end location of an included file or expanded macro.
178  SourceLocation getEndOfFileOrMacro(SourceLocation Loc) {
179  if (Loc.isMacroID())
180  return Loc.getLocWithOffset(SM.getFileIDSize(SM.getFileID(Loc)) -
181  SM.getFileOffset(Loc));
182  return SM.getLocForEndOfFile(SM.getFileID(Loc));
183  }
184 
185  /// Find out where the current file is included or macro is expanded.
186  SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc) {
187  return Loc.isMacroID() ? SM.getImmediateExpansionRange(Loc).getBegin()
188  : SM.getIncludeLoc(SM.getFileID(Loc));
189  }
190 
191  /// Return true if \c Loc is a location in a built-in macro.
192  bool isInBuiltin(SourceLocation Loc) {
193  return SM.getBufferName(SM.getSpellingLoc(Loc)) == "<built-in>";
194  }
195 
196  /// Check whether \c Loc is included or expanded from \c Parent.
197  bool isNestedIn(SourceLocation Loc, FileID Parent) {
198  do {
199  Loc = getIncludeOrExpansionLoc(Loc);
200  if (Loc.isInvalid())
201  return false;
202  } while (!SM.isInFileID(Loc, Parent));
203  return true;
204  }
205 
206  /// Get the start of \c S ignoring macro arguments and builtin macros.
207  SourceLocation getStart(const Stmt *S) {
208  SourceLocation Loc = S->getLocStart();
209  while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
210  Loc = SM.getImmediateExpansionRange(Loc).getBegin();
211  return Loc;
212  }
213 
214  /// Get the end of \c S ignoring macro arguments and builtin macros.
215  SourceLocation getEnd(const Stmt *S) {
216  SourceLocation Loc = S->getLocEnd();
217  while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
218  Loc = SM.getImmediateExpansionRange(Loc).getBegin();
219  return getPreciseTokenLocEnd(Loc);
220  }
221 
222  /// Find the set of files we have regions for and assign IDs
223  ///
224  /// Fills \c Mapping with the virtual file mapping needed to write out
225  /// coverage and collects the necessary file information to emit source and
226  /// expansion regions.
227  void gatherFileIDs(SmallVectorImpl<unsigned> &Mapping) {
228  FileIDMapping.clear();
229 
230  llvm::SmallSet<FileID, 8> Visited;
232  for (const auto &Region : SourceRegions) {
233  SourceLocation Loc = Region.getStartLoc();
234  FileID File = SM.getFileID(Loc);
235  if (!Visited.insert(File).second)
236  continue;
237 
238  // Do not map FileID's associated with system headers.
239  if (SM.isInSystemHeader(SM.getSpellingLoc(Loc)))
240  continue;
241 
242  unsigned Depth = 0;
243  for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
244  Parent.isValid(); Parent = getIncludeOrExpansionLoc(Parent))
245  ++Depth;
246  FileLocs.push_back(std::make_pair(Loc, Depth));
247  }
248  std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
249 
250  for (const auto &FL : FileLocs) {
251  SourceLocation Loc = FL.first;
252  FileID SpellingFile = SM.getDecomposedSpellingLoc(Loc).first;
253  auto Entry = SM.getFileEntryForID(SpellingFile);
254  if (!Entry)
255  continue;
256 
257  FileIDMapping[SM.getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
258  Mapping.push_back(CVM.getFileID(Entry));
259  }
260  }
261 
262  /// Get the coverage mapping file ID for \c Loc.
263  ///
264  /// If such file id doesn't exist, return None.
265  Optional<unsigned> getCoverageFileID(SourceLocation Loc) {
266  auto Mapping = FileIDMapping.find(SM.getFileID(Loc));
267  if (Mapping != FileIDMapping.end())
268  return Mapping->second.first;
269  return None;
270  }
271 
272  /// Gather all the regions that were skipped by the preprocessor
273  /// using the constructs like #if.
274  void gatherSkippedRegions() {
275  /// An array of the minimum lineStarts and the maximum lineEnds
276  /// for mapping regions from the appropriate source files.
278  FileLineRanges.resize(
279  FileIDMapping.size(),
280  std::make_pair(std::numeric_limits<unsigned>::max(), 0));
281  for (const auto &R : MappingRegions) {
282  FileLineRanges[R.FileID].first =
283  std::min(FileLineRanges[R.FileID].first, R.LineStart);
284  FileLineRanges[R.FileID].second =
285  std::max(FileLineRanges[R.FileID].second, R.LineEnd);
286  }
287 
288  auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
289  for (const auto &I : SkippedRanges) {
290  auto LocStart = I.getBegin();
291  auto LocEnd = I.getEnd();
292  assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
293  "region spans multiple files");
294 
295  auto CovFileID = getCoverageFileID(LocStart);
296  if (!CovFileID)
297  continue;
298  SpellingRegion SR{SM, LocStart, LocEnd};
299  auto Region = CounterMappingRegion::makeSkipped(
300  *CovFileID, SR.LineStart, SR.ColumnStart, SR.LineEnd, SR.ColumnEnd);
301  // Make sure that we only collect the regions that are inside
302  // the source code of this function.
303  if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
304  Region.LineEnd <= FileLineRanges[*CovFileID].second)
305  MappingRegions.push_back(Region);
306  }
307  }
308 
309  /// Generate the coverage counter mapping regions from collected
310  /// source regions.
311  void emitSourceRegions(const SourceRegionFilter &Filter) {
312  for (const auto &Region : SourceRegions) {
313  assert(Region.hasEndLoc() && "incomplete region");
314 
315  SourceLocation LocStart = Region.getStartLoc();
316  assert(SM.getFileID(LocStart).isValid() && "region in invalid file");
317 
318  // Ignore regions from system headers.
319  if (SM.isInSystemHeader(SM.getSpellingLoc(LocStart)))
320  continue;
321 
322  auto CovFileID = getCoverageFileID(LocStart);
323  // Ignore regions that don't have a file, such as builtin macros.
324  if (!CovFileID)
325  continue;
326 
327  SourceLocation LocEnd = Region.getEndLoc();
328  assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
329  "region spans multiple files");
330 
331  // Don't add code regions for the area covered by expansion regions.
332  // This not only suppresses redundant regions, but sometimes prevents
333  // creating regions with wrong counters if, for example, a statement's
334  // body ends at the end of a nested macro.
335  if (Filter.count(std::make_pair(LocStart, LocEnd)))
336  continue;
337 
338  // Find the spelling locations for the mapping region.
339  SpellingRegion SR{SM, LocStart, LocEnd};
340  assert(SR.isInSourceOrder() && "region start and end out of order");
341 
342  if (Region.isGap()) {
343  MappingRegions.push_back(CounterMappingRegion::makeGapRegion(
344  Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
345  SR.LineEnd, SR.ColumnEnd));
346  } else {
347  MappingRegions.push_back(CounterMappingRegion::makeRegion(
348  Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
349  SR.LineEnd, SR.ColumnEnd));
350  }
351  }
352  }
353 
354  /// Generate expansion regions for each virtual file we've seen.
355  SourceRegionFilter emitExpansionRegions() {
356  SourceRegionFilter Filter;
357  for (const auto &FM : FileIDMapping) {
358  SourceLocation ExpandedLoc = FM.second.second;
359  SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc);
360  if (ParentLoc.isInvalid())
361  continue;
362 
363  auto ParentFileID = getCoverageFileID(ParentLoc);
364  if (!ParentFileID)
365  continue;
366  auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
367  assert(ExpandedFileID && "expansion in uncovered file");
368 
369  SourceLocation LocEnd = getPreciseTokenLocEnd(ParentLoc);
370  assert(SM.isWrittenInSameFile(ParentLoc, LocEnd) &&
371  "region spans multiple files");
372  Filter.insert(std::make_pair(ParentLoc, LocEnd));
373 
374  SpellingRegion SR{SM, ParentLoc, LocEnd};
375  assert(SR.isInSourceOrder() && "region start and end out of order");
376  MappingRegions.push_back(CounterMappingRegion::makeExpansion(
377  *ParentFileID, *ExpandedFileID, SR.LineStart, SR.ColumnStart,
378  SR.LineEnd, SR.ColumnEnd));
379  }
380  return Filter;
381  }
382 };
383 
384 /// Creates unreachable coverage regions for the functions that
385 /// are not emitted.
386 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
387  EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
388  const LangOptions &LangOpts)
389  : CoverageMappingBuilder(CVM, SM, LangOpts) {}
390 
391  void VisitDecl(const Decl *D) {
392  if (!D->hasBody())
393  return;
394  auto Body = D->getBody();
395  SourceLocation Start = getStart(Body);
396  SourceLocation End = getEnd(Body);
397  if (!SM.isWrittenInSameFile(Start, End)) {
398  // Walk up to find the common ancestor.
399  // Correct the locations accordingly.
400  FileID StartFileID = SM.getFileID(Start);
401  FileID EndFileID = SM.getFileID(End);
402  while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
403  Start = getIncludeOrExpansionLoc(Start);
404  assert(Start.isValid() &&
405  "Declaration start location not nested within a known region");
406  StartFileID = SM.getFileID(Start);
407  }
408  while (StartFileID != EndFileID) {
409  End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
410  assert(End.isValid() &&
411  "Declaration end location not nested within a known region");
412  EndFileID = SM.getFileID(End);
413  }
414  }
415  SourceRegions.emplace_back(Counter(), Start, End);
416  }
417 
418  /// Write the mapping data to the output stream
419  void write(llvm::raw_ostream &OS) {
420  SmallVector<unsigned, 16> FileIDMapping;
421  gatherFileIDs(FileIDMapping);
422  emitSourceRegions(SourceRegionFilter());
423 
424  if (MappingRegions.empty())
425  return;
426 
427  CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
428  Writer.write(OS);
429  }
430 };
431 
432 /// A StmtVisitor that creates coverage mapping regions which map
433 /// from the source code locations to the PGO counters.
434 struct CounterCoverageMappingBuilder
435  : public CoverageMappingBuilder,
436  public ConstStmtVisitor<CounterCoverageMappingBuilder> {
437  /// The map of statements to count values.
438  llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
439 
440  /// A stack of currently live regions.
441  std::vector<SourceMappingRegion> RegionStack;
442 
443  /// The currently deferred region: its end location and count can be set once
444  /// its parent has been popped from the region stack.
445  Optional<SourceMappingRegion> DeferredRegion;
446 
447  CounterExpressionBuilder Builder;
448 
449  /// A location in the most recently visited file or macro.
450  ///
451  /// This is used to adjust the active source regions appropriately when
452  /// expressions cross file or macro boundaries.
453  SourceLocation MostRecentLocation;
454 
455  /// Location of the last terminated region.
456  Optional<std::pair<SourceLocation, size_t>> LastTerminatedRegion;
457 
458  /// Return a counter for the subtraction of \c RHS from \c LHS
459  Counter subtractCounters(Counter LHS, Counter RHS) {
460  return Builder.subtract(LHS, RHS);
461  }
462 
463  /// Return a counter for the sum of \c LHS and \c RHS.
464  Counter addCounters(Counter LHS, Counter RHS) {
465  return Builder.add(LHS, RHS);
466  }
467 
468  Counter addCounters(Counter C1, Counter C2, Counter C3) {
469  return addCounters(addCounters(C1, C2), C3);
470  }
471 
472  /// Return the region counter for the given statement.
473  ///
474  /// This should only be called on statements that have a dedicated counter.
475  Counter getRegionCounter(const Stmt *S) {
476  return Counter::getCounter(CounterMap[S]);
477  }
478 
479  /// Push a region onto the stack.
480  ///
481  /// Returns the index on the stack where the region was pushed. This can be
482  /// used with popRegions to exit a "scope", ending the region that was pushed.
483  size_t pushRegion(Counter Count, Optional<SourceLocation> StartLoc = None,
484  Optional<SourceLocation> EndLoc = None) {
485  if (StartLoc) {
486  MostRecentLocation = *StartLoc;
487  completeDeferred(Count, MostRecentLocation);
488  }
489  RegionStack.emplace_back(Count, StartLoc, EndLoc);
490 
491  return RegionStack.size() - 1;
492  }
493 
494  /// Complete any pending deferred region by setting its end location and
495  /// count, and then pushing it onto the region stack.
496  size_t completeDeferred(Counter Count, SourceLocation DeferredEndLoc) {
497  size_t Index = RegionStack.size();
498  if (!DeferredRegion)
499  return Index;
500 
501  // Consume the pending region.
502  SourceMappingRegion DR = DeferredRegion.getValue();
503  DeferredRegion = None;
504 
505  // If the region ends in an expansion, find the expansion site.
506  FileID StartFile = SM.getFileID(DR.getStartLoc());
507  if (SM.getFileID(DeferredEndLoc) != StartFile) {
508  if (isNestedIn(DeferredEndLoc, StartFile)) {
509  do {
510  DeferredEndLoc = getIncludeOrExpansionLoc(DeferredEndLoc);
511  } while (StartFile != SM.getFileID(DeferredEndLoc));
512  } else {
513  return Index;
514  }
515  }
516 
517  // The parent of this deferred region ends where the containing decl ends,
518  // so the region isn't useful.
519  if (DR.getStartLoc() == DeferredEndLoc)
520  return Index;
521 
522  // If we're visiting statements in non-source order (e.g switch cases or
523  // a loop condition) we can't construct a sensible deferred region.
524  if (!SpellingRegion(SM, DR.getStartLoc(), DeferredEndLoc).isInSourceOrder())
525  return Index;
526 
527  DR.setGap(true);
528  DR.setCounter(Count);
529  DR.setEndLoc(DeferredEndLoc);
530  handleFileExit(DeferredEndLoc);
531  RegionStack.push_back(DR);
532  return Index;
533  }
534 
535  /// Complete a deferred region created after a terminated region at the
536  /// top-level.
537  void completeTopLevelDeferredRegion(Counter Count,
538  SourceLocation DeferredEndLoc) {
539  if (DeferredRegion || !LastTerminatedRegion)
540  return;
541 
542  if (LastTerminatedRegion->second != RegionStack.size())
543  return;
544 
545  SourceLocation Start = LastTerminatedRegion->first;
546  if (SM.getFileID(Start) != SM.getMainFileID())
547  return;
548 
549  SourceMappingRegion DR = RegionStack.back();
550  DR.setStartLoc(Start);
551  DR.setDeferred(false);
552  DeferredRegion = DR;
553  completeDeferred(Count, DeferredEndLoc);
554  }
555 
556  /// Pop regions from the stack into the function's list of regions.
557  ///
558  /// Adds all regions from \c ParentIndex to the top of the stack to the
559  /// function's \c SourceRegions.
560  void popRegions(size_t ParentIndex) {
561  assert(RegionStack.size() >= ParentIndex && "parent not in stack");
562  bool ParentOfDeferredRegion = false;
563  while (RegionStack.size() > ParentIndex) {
564  SourceMappingRegion &Region = RegionStack.back();
565  if (Region.hasStartLoc()) {
566  SourceLocation StartLoc = Region.getStartLoc();
567  SourceLocation EndLoc = Region.hasEndLoc()
568  ? Region.getEndLoc()
569  : RegionStack[ParentIndex].getEndLoc();
570  while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) {
571  // The region ends in a nested file or macro expansion. Create a
572  // separate region for each expansion.
573  SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
574  assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
575 
576  if (!isRegionAlreadyAdded(NestedLoc, EndLoc))
577  SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
578 
579  EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
580  if (EndLoc.isInvalid())
581  llvm::report_fatal_error("File exit not handled before popRegions");
582  }
583  Region.setEndLoc(EndLoc);
584 
585  MostRecentLocation = EndLoc;
586  // If this region happens to span an entire expansion, we need to make
587  // sure we don't overlap the parent region with it.
588  if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
589  EndLoc == getEndOfFileOrMacro(EndLoc))
590  MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
591 
592  assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc));
593  assert(SpellingRegion(SM, Region).isInSourceOrder());
594  SourceRegions.push_back(Region);
595 
596  if (ParentOfDeferredRegion) {
597  ParentOfDeferredRegion = false;
598 
599  // If there's an existing deferred region, keep the old one, because
600  // it means there are two consecutive returns (or a similar pattern).
601  if (!DeferredRegion.hasValue() &&
602  // File IDs aren't gathered within macro expansions, so it isn't
603  // useful to try and create a deferred region inside of one.
604  !EndLoc.isMacroID())
605  DeferredRegion =
606  SourceMappingRegion(Counter::getZero(), EndLoc, None);
607  }
608  } else if (Region.isDeferred()) {
609  assert(!ParentOfDeferredRegion && "Consecutive deferred regions");
610  ParentOfDeferredRegion = true;
611  }
612  RegionStack.pop_back();
613 
614  // If the zero region pushed after the last terminated region no longer
615  // exists, clear its cached information.
616  if (LastTerminatedRegion &&
617  RegionStack.size() < LastTerminatedRegion->second)
618  LastTerminatedRegion = None;
619  }
620  assert(!ParentOfDeferredRegion && "Deferred region with no parent");
621  }
622 
623  /// Return the currently active region.
624  SourceMappingRegion &getRegion() {
625  assert(!RegionStack.empty() && "statement has no region");
626  return RegionStack.back();
627  }
628 
629  /// Propagate counts through the children of \c S.
630  Counter propagateCounts(Counter TopCount, const Stmt *S) {
631  SourceLocation StartLoc = getStart(S);
632  SourceLocation EndLoc = getEnd(S);
633  size_t Index = pushRegion(TopCount, StartLoc, EndLoc);
634  Visit(S);
635  Counter ExitCount = getRegion().getCounter();
636  popRegions(Index);
637 
638  // The statement may be spanned by an expansion. Make sure we handle a file
639  // exit out of this expansion before moving to the next statement.
640  if (SM.isBeforeInTranslationUnit(StartLoc, S->getLocStart()))
641  MostRecentLocation = EndLoc;
642 
643  return ExitCount;
644  }
645 
646  /// Check whether a region with bounds \c StartLoc and \c EndLoc
647  /// is already added to \c SourceRegions.
648  bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc) {
649  return SourceRegions.rend() !=
650  std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
651  [&](const SourceMappingRegion &Region) {
652  return Region.getStartLoc() == StartLoc &&
653  Region.getEndLoc() == EndLoc;
654  });
655  }
656 
657  /// Adjust the most recently visited location to \c EndLoc.
658  ///
659  /// This should be used after visiting any statements in non-source order.
660  void adjustForOutOfOrderTraversal(SourceLocation EndLoc) {
661  MostRecentLocation = EndLoc;
662  // The code region for a whole macro is created in handleFileExit() when
663  // it detects exiting of the virtual file of that macro. If we visited
664  // statements in non-source order, we might already have such a region
665  // added, for example, if a body of a loop is divided among multiple
666  // macros. Avoid adding duplicate regions in such case.
667  if (getRegion().hasEndLoc() &&
668  MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
669  isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
670  MostRecentLocation))
671  MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
672  }
673 
674  /// Adjust regions and state when \c NewLoc exits a file.
675  ///
676  /// If moving from our most recently tracked location to \c NewLoc exits any
677  /// files, this adjusts our current region stack and creates the file regions
678  /// for the exited file.
679  void handleFileExit(SourceLocation NewLoc) {
680  if (NewLoc.isInvalid() ||
681  SM.isWrittenInSameFile(MostRecentLocation, NewLoc))
682  return;
683 
684  // If NewLoc is not in a file that contains MostRecentLocation, walk up to
685  // find the common ancestor.
686  SourceLocation LCA = NewLoc;
687  FileID ParentFile = SM.getFileID(LCA);
688  while (!isNestedIn(MostRecentLocation, ParentFile)) {
689  LCA = getIncludeOrExpansionLoc(LCA);
690  if (LCA.isInvalid() || SM.isWrittenInSameFile(LCA, MostRecentLocation)) {
691  // Since there isn't a common ancestor, no file was exited. We just need
692  // to adjust our location to the new file.
693  MostRecentLocation = NewLoc;
694  return;
695  }
696  ParentFile = SM.getFileID(LCA);
697  }
698 
699  llvm::SmallSet<SourceLocation, 8> StartLocs;
700  Optional<Counter> ParentCounter;
701  for (SourceMappingRegion &I : llvm::reverse(RegionStack)) {
702  if (!I.hasStartLoc())
703  continue;
704  SourceLocation Loc = I.getStartLoc();
705  if (!isNestedIn(Loc, ParentFile)) {
706  ParentCounter = I.getCounter();
707  break;
708  }
709 
710  while (!SM.isInFileID(Loc, ParentFile)) {
711  // The most nested region for each start location is the one with the
712  // correct count. We avoid creating redundant regions by stopping once
713  // we've seen this region.
714  if (StartLocs.insert(Loc).second)
715  SourceRegions.emplace_back(I.getCounter(), Loc,
716  getEndOfFileOrMacro(Loc));
717  Loc = getIncludeOrExpansionLoc(Loc);
718  }
719  I.setStartLoc(getPreciseTokenLocEnd(Loc));
720  }
721 
722  if (ParentCounter) {
723  // If the file is contained completely by another region and doesn't
724  // immediately start its own region, the whole file gets a region
725  // corresponding to the parent.
726  SourceLocation Loc = MostRecentLocation;
727  while (isNestedIn(Loc, ParentFile)) {
728  SourceLocation FileStart = getStartOfFileOrMacro(Loc);
729  if (StartLocs.insert(FileStart).second) {
730  SourceRegions.emplace_back(*ParentCounter, FileStart,
731  getEndOfFileOrMacro(Loc));
732  assert(SpellingRegion(SM, SourceRegions.back()).isInSourceOrder());
733  }
734  Loc = getIncludeOrExpansionLoc(Loc);
735  }
736  }
737 
738  MostRecentLocation = NewLoc;
739  }
740 
741  /// Ensure that \c S is included in the current region.
742  void extendRegion(const Stmt *S) {
743  SourceMappingRegion &Region = getRegion();
744  SourceLocation StartLoc = getStart(S);
745 
746  handleFileExit(StartLoc);
747  if (!Region.hasStartLoc())
748  Region.setStartLoc(StartLoc);
749 
750  completeDeferred(Region.getCounter(), StartLoc);
751  }
752 
753  /// Mark \c S as a terminator, starting a zero region.
754  void terminateRegion(const Stmt *S) {
755  extendRegion(S);
756  SourceMappingRegion &Region = getRegion();
757  SourceLocation EndLoc = getEnd(S);
758  if (!Region.hasEndLoc())
759  Region.setEndLoc(EndLoc);
760  pushRegion(Counter::getZero());
761  auto &ZeroRegion = getRegion();
762  ZeroRegion.setDeferred(true);
763  LastTerminatedRegion = {EndLoc, RegionStack.size()};
764  }
765 
766  /// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
767  Optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc,
768  SourceLocation BeforeLoc) {
769  // If the start and end locations of the gap are both within the same macro
770  // file, the range may not be in source order.
771  if (AfterLoc.isMacroID() || BeforeLoc.isMacroID())
772  return None;
773  if (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc))
774  return None;
775  return {{AfterLoc, BeforeLoc}};
776  }
777 
778  /// Find the source range after \p AfterStmt and before \p BeforeStmt.
779  Optional<SourceRange> findGapAreaBetween(const Stmt *AfterStmt,
780  const Stmt *BeforeStmt) {
781  return findGapAreaBetween(getPreciseTokenLocEnd(getEnd(AfterStmt)),
782  getStart(BeforeStmt));
783  }
784 
785  /// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
786  void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc,
787  Counter Count) {
788  if (StartLoc == EndLoc)
789  return;
790  assert(SpellingRegion(SM, StartLoc, EndLoc).isInSourceOrder());
791  handleFileExit(StartLoc);
792  size_t Index = pushRegion(Count, StartLoc, EndLoc);
793  getRegion().setGap(true);
794  handleFileExit(EndLoc);
795  popRegions(Index);
796  }
797 
798  /// Keep counts of breaks and continues inside loops.
799  struct BreakContinue {
800  Counter BreakCount;
801  Counter ContinueCount;
802  };
803  SmallVector<BreakContinue, 8> BreakContinueStack;
804 
805  CounterCoverageMappingBuilder(
807  llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
808  const LangOptions &LangOpts)
809  : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
810  DeferredRegion(None) {}
811 
812  /// Write the mapping data to the output stream
813  void write(llvm::raw_ostream &OS) {
814  llvm::SmallVector<unsigned, 8> VirtualFileMapping;
815  gatherFileIDs(VirtualFileMapping);
816  SourceRegionFilter Filter = emitExpansionRegions();
817  assert(!DeferredRegion && "Deferred region never completed");
818  emitSourceRegions(Filter);
819  gatherSkippedRegions();
820 
821  if (MappingRegions.empty())
822  return;
823 
824  CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(),
825  MappingRegions);
826  Writer.write(OS);
827  }
828 
829  void VisitStmt(const Stmt *S) {
830  if (S->getLocStart().isValid())
831  extendRegion(S);
832  for (const Stmt *Child : S->children())
833  if (Child)
834  this->Visit(Child);
835  handleFileExit(getEnd(S));
836  }
837 
838  void VisitDecl(const Decl *D) {
839  assert(!DeferredRegion && "Deferred region never completed");
840 
841  Stmt *Body = D->getBody();
842 
843  // Do not propagate region counts into system headers.
844  if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
845  return;
846 
847  propagateCounts(getRegionCounter(Body), Body);
848  assert(RegionStack.empty() && "Regions entered but never exited");
849 
850  // Discard the last uncompleted deferred region in a decl, if one exists.
851  // This prevents lines at the end of a function containing only whitespace
852  // or closing braces from being marked as uncovered.
853  DeferredRegion = None;
854  }
855 
856  void VisitReturnStmt(const ReturnStmt *S) {
857  extendRegion(S);
858  if (S->getRetValue())
859  Visit(S->getRetValue());
860  terminateRegion(S);
861  }
862 
863  void VisitCXXThrowExpr(const CXXThrowExpr *E) {
864  extendRegion(E);
865  if (E->getSubExpr())
866  Visit(E->getSubExpr());
867  terminateRegion(E);
868  }
869 
870  void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
871 
872  void VisitLabelStmt(const LabelStmt *S) {
873  Counter LabelCount = getRegionCounter(S);
874  SourceLocation Start = getStart(S);
875  completeTopLevelDeferredRegion(LabelCount, Start);
876  completeDeferred(LabelCount, Start);
877  // We can't extendRegion here or we risk overlapping with our new region.
878  handleFileExit(Start);
879  pushRegion(LabelCount, Start);
880  Visit(S->getSubStmt());
881  }
882 
883  void VisitBreakStmt(const BreakStmt *S) {
884  assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
885  BreakContinueStack.back().BreakCount = addCounters(
886  BreakContinueStack.back().BreakCount, getRegion().getCounter());
887  // FIXME: a break in a switch should terminate regions for all preceding
888  // case statements, not just the most recent one.
889  terminateRegion(S);
890  }
891 
892  void VisitContinueStmt(const ContinueStmt *S) {
893  assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
894  BreakContinueStack.back().ContinueCount = addCounters(
895  BreakContinueStack.back().ContinueCount, getRegion().getCounter());
896  terminateRegion(S);
897  }
898 
899  void VisitCallExpr(const CallExpr *E) {
900  VisitStmt(E);
901 
902  // Terminate the region when we hit a noreturn function.
903  // (This is helpful dealing with switch statements.)
904  QualType CalleeType = E->getCallee()->getType();
905  if (getFunctionExtInfo(*CalleeType).getNoReturn())
906  terminateRegion(E);
907  }
908 
909  void VisitWhileStmt(const WhileStmt *S) {
910  extendRegion(S);
911 
912  Counter ParentCount = getRegion().getCounter();
913  Counter BodyCount = getRegionCounter(S);
914 
915  // Handle the body first so that we can get the backedge count.
916  BreakContinueStack.push_back(BreakContinue());
917  extendRegion(S->getBody());
918  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
919  BreakContinue BC = BreakContinueStack.pop_back_val();
920 
921  // Go back to handle the condition.
922  Counter CondCount =
923  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
924  propagateCounts(CondCount, S->getCond());
925  adjustForOutOfOrderTraversal(getEnd(S));
926 
927  // The body count applies to the area immediately after the increment.
928  auto Gap = findGapAreaBetween(S->getCond(), S->getBody());
929  if (Gap)
930  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
931 
932  Counter OutCount =
933  addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
934  if (OutCount != ParentCount)
935  pushRegion(OutCount);
936  }
937 
938  void VisitDoStmt(const DoStmt *S) {
939  extendRegion(S);
940 
941  Counter ParentCount = getRegion().getCounter();
942  Counter BodyCount = getRegionCounter(S);
943 
944  BreakContinueStack.push_back(BreakContinue());
945  extendRegion(S->getBody());
946  Counter BackedgeCount =
947  propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
948  BreakContinue BC = BreakContinueStack.pop_back_val();
949 
950  Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
951  propagateCounts(CondCount, S->getCond());
952 
953  Counter OutCount =
954  addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
955  if (OutCount != ParentCount)
956  pushRegion(OutCount);
957  }
958 
959  void VisitForStmt(const ForStmt *S) {
960  extendRegion(S);
961  if (S->getInit())
962  Visit(S->getInit());
963 
964  Counter ParentCount = getRegion().getCounter();
965  Counter BodyCount = getRegionCounter(S);
966 
967  // The loop increment may contain a break or continue.
968  if (S->getInc())
969  BreakContinueStack.emplace_back();
970 
971  // Handle the body first so that we can get the backedge count.
972  BreakContinueStack.emplace_back();
973  extendRegion(S->getBody());
974  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
975  BreakContinue BodyBC = BreakContinueStack.pop_back_val();
976 
977  // The increment is essentially part of the body but it needs to include
978  // the count for all the continue statements.
979  BreakContinue IncrementBC;
980  if (const Stmt *Inc = S->getInc()) {
981  propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc);
982  IncrementBC = BreakContinueStack.pop_back_val();
983  }
984 
985  // Go back to handle the condition.
986  Counter CondCount = addCounters(
987  addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
988  IncrementBC.ContinueCount);
989  if (const Expr *Cond = S->getCond()) {
990  propagateCounts(CondCount, Cond);
991  adjustForOutOfOrderTraversal(getEnd(S));
992  }
993 
994  // The body count applies to the area immediately after the increment.
995  auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
996  getStart(S->getBody()));
997  if (Gap)
998  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
999 
1000  Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
1001  subtractCounters(CondCount, BodyCount));
1002  if (OutCount != ParentCount)
1003  pushRegion(OutCount);
1004  }
1005 
1006  void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
1007  extendRegion(S);
1008  Visit(S->getLoopVarStmt());
1009  Visit(S->getRangeStmt());
1010 
1011  Counter ParentCount = getRegion().getCounter();
1012  Counter BodyCount = getRegionCounter(S);
1013 
1014  BreakContinueStack.push_back(BreakContinue());
1015  extendRegion(S->getBody());
1016  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1017  BreakContinue BC = BreakContinueStack.pop_back_val();
1018 
1019  // The body count applies to the area immediately after the range.
1020  auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
1021  getStart(S->getBody()));
1022  if (Gap)
1023  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1024 
1025  Counter LoopCount =
1026  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1027  Counter OutCount =
1028  addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
1029  if (OutCount != ParentCount)
1030  pushRegion(OutCount);
1031  }
1032 
1033  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
1034  extendRegion(S);
1035  Visit(S->getElement());
1036 
1037  Counter ParentCount = getRegion().getCounter();
1038  Counter BodyCount = getRegionCounter(S);
1039 
1040  BreakContinueStack.push_back(BreakContinue());
1041  extendRegion(S->getBody());
1042  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
1043  BreakContinue BC = BreakContinueStack.pop_back_val();
1044 
1045  // The body count applies to the area immediately after the collection.
1046  auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
1047  getStart(S->getBody()));
1048  if (Gap)
1049  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
1050 
1051  Counter LoopCount =
1052  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1053  Counter OutCount =
1054  addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
1055  if (OutCount != ParentCount)
1056  pushRegion(OutCount);
1057  }
1058 
1059  void VisitSwitchStmt(const SwitchStmt *S) {
1060  extendRegion(S);
1061  if (S->getInit())
1062  Visit(S->getInit());
1063  Visit(S->getCond());
1064 
1065  BreakContinueStack.push_back(BreakContinue());
1066 
1067  const Stmt *Body = S->getBody();
1068  extendRegion(Body);
1069  if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
1070  if (!CS->body_empty()) {
1071  // Make a region for the body of the switch. If the body starts with
1072  // a case, that case will reuse this region; otherwise, this covers
1073  // the unreachable code at the beginning of the switch body.
1074  size_t Index =
1075  pushRegion(Counter::getZero(), getStart(CS->body_front()));
1076  for (const auto *Child : CS->children())
1077  Visit(Child);
1078 
1079  // Set the end for the body of the switch, if it isn't already set.
1080  for (size_t i = RegionStack.size(); i != Index; --i) {
1081  if (!RegionStack[i - 1].hasEndLoc())
1082  RegionStack[i - 1].setEndLoc(getEnd(CS->body_back()));
1083  }
1084 
1085  popRegions(Index);
1086  }
1087  } else
1088  propagateCounts(Counter::getZero(), Body);
1089  BreakContinue BC = BreakContinueStack.pop_back_val();
1090 
1091  if (!BreakContinueStack.empty())
1092  BreakContinueStack.back().ContinueCount = addCounters(
1093  BreakContinueStack.back().ContinueCount, BC.ContinueCount);
1094 
1095  Counter ExitCount = getRegionCounter(S);
1096  SourceLocation ExitLoc = getEnd(S);
1097  pushRegion(ExitCount);
1098 
1099  // Ensure that handleFileExit recognizes when the end location is located
1100  // in a different file.
1101  MostRecentLocation = getStart(S);
1102  handleFileExit(ExitLoc);
1103  }
1104 
1105  void VisitSwitchCase(const SwitchCase *S) {
1106  extendRegion(S);
1107 
1108  SourceMappingRegion &Parent = getRegion();
1109 
1110  Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
1111  // Reuse the existing region if it starts at our label. This is typical of
1112  // the first case in a switch.
1113  if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
1114  Parent.setCounter(Count);
1115  else
1116  pushRegion(Count, getStart(S));
1117 
1118  if (const auto *CS = dyn_cast<CaseStmt>(S)) {
1119  Visit(CS->getLHS());
1120  if (const Expr *RHS = CS->getRHS())
1121  Visit(RHS);
1122  }
1123  Visit(S->getSubStmt());
1124  }
1125 
1126  void VisitIfStmt(const IfStmt *S) {
1127  extendRegion(S);
1128  if (S->getInit())
1129  Visit(S->getInit());
1130 
1131  // Extend into the condition before we propagate through it below - this is
1132  // needed to handle macros that generate the "if" but not the condition.
1133  extendRegion(S->getCond());
1134 
1135  Counter ParentCount = getRegion().getCounter();
1136  Counter ThenCount = getRegionCounter(S);
1137 
1138  // Emitting a counter for the condition makes it easier to interpret the
1139  // counter for the body when looking at the coverage.
1140  propagateCounts(ParentCount, S->getCond());
1141 
1142  // The 'then' count applies to the area immediately after the condition.
1143  auto Gap = findGapAreaBetween(S->getCond(), S->getThen());
1144  if (Gap)
1145  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount);
1146 
1147  extendRegion(S->getThen());
1148  Counter OutCount = propagateCounts(ThenCount, S->getThen());
1149 
1150  Counter ElseCount = subtractCounters(ParentCount, ThenCount);
1151  if (const Stmt *Else = S->getElse()) {
1152  // The 'else' count applies to the area immediately after the 'then'.
1153  Gap = findGapAreaBetween(S->getThen(), Else);
1154  if (Gap)
1155  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount);
1156  extendRegion(Else);
1157  OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
1158  } else
1159  OutCount = addCounters(OutCount, ElseCount);
1160 
1161  if (OutCount != ParentCount)
1162  pushRegion(OutCount);
1163  }
1164 
1165  void VisitCXXTryStmt(const CXXTryStmt *S) {
1166  extendRegion(S);
1167  // Handle macros that generate the "try" but not the rest.
1168  extendRegion(S->getTryBlock());
1169 
1170  Counter ParentCount = getRegion().getCounter();
1171  propagateCounts(ParentCount, S->getTryBlock());
1172 
1173  for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
1174  Visit(S->getHandler(I));
1175 
1176  Counter ExitCount = getRegionCounter(S);
1177  pushRegion(ExitCount);
1178  }
1179 
1180  void VisitCXXCatchStmt(const CXXCatchStmt *S) {
1181  propagateCounts(getRegionCounter(S), S->getHandlerBlock());
1182  }
1183 
1184  void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
1185  extendRegion(E);
1186 
1187  Counter ParentCount = getRegion().getCounter();
1188  Counter TrueCount = getRegionCounter(E);
1189 
1190  Visit(E->getCond());
1191 
1192  if (!isa<BinaryConditionalOperator>(E)) {
1193  // The 'then' count applies to the area immediately after the condition.
1194  auto Gap =
1195  findGapAreaBetween(E->getQuestionLoc(), getStart(E->getTrueExpr()));
1196  if (Gap)
1197  fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), TrueCount);
1198 
1199  extendRegion(E->getTrueExpr());
1200  propagateCounts(TrueCount, E->getTrueExpr());
1201  }
1202 
1203  extendRegion(E->getFalseExpr());
1204  propagateCounts(subtractCounters(ParentCount, TrueCount),
1205  E->getFalseExpr());
1206  }
1207 
1208  void VisitBinLAnd(const BinaryOperator *E) {
1209  extendRegion(E->getLHS());
1210  propagateCounts(getRegion().getCounter(), E->getLHS());
1211  handleFileExit(getEnd(E->getLHS()));
1212 
1213  extendRegion(E->getRHS());
1214  propagateCounts(getRegionCounter(E), E->getRHS());
1215  }
1216 
1217  void VisitBinLOr(const BinaryOperator *E) {
1218  extendRegion(E->getLHS());
1219  propagateCounts(getRegion().getCounter(), E->getLHS());
1220  handleFileExit(getEnd(E->getLHS()));
1221 
1222  extendRegion(E->getRHS());
1223  propagateCounts(getRegionCounter(E), E->getRHS());
1224  }
1225 
1226  void VisitLambdaExpr(const LambdaExpr *LE) {
1227  // Lambdas are treated as their own functions for now, so we shouldn't
1228  // propagate counts into them.
1229  }
1230 };
1231 
1232 std::string getCoverageSection(const CodeGenModule &CGM) {
1233  return llvm::getInstrProfSectionName(
1234  llvm::IPSK_covmap,
1235  CGM.getContext().getTargetInfo().getTriple().getObjectFormat());
1236 }
1237 
1238 std::string normalizeFilename(StringRef Filename) {
1239  llvm::SmallString<256> Path(Filename);
1240  llvm::sys::fs::make_absolute(Path);
1241  llvm::sys::path::remove_dots(Path, /*remove_dot_dots=*/true);
1242  return Path.str().str();
1243 }
1244 
1245 } // end anonymous namespace
1246 
1247 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
1248  ArrayRef<CounterExpression> Expressions,
1250  OS << FunctionName << ":\n";
1251  CounterMappingContext Ctx(Expressions);
1252  for (const auto &R : Regions) {
1253  OS.indent(2);
1254  switch (R.Kind) {
1255  case CounterMappingRegion::CodeRegion:
1256  break;
1257  case CounterMappingRegion::ExpansionRegion:
1258  OS << "Expansion,";
1259  break;
1260  case CounterMappingRegion::SkippedRegion:
1261  OS << "Skipped,";
1262  break;
1263  case CounterMappingRegion::GapRegion:
1264  OS << "Gap,";
1265  break;
1266  }
1267 
1268  OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
1269  << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = ";
1270  Ctx.dump(R.Count, OS);
1271  if (R.Kind == CounterMappingRegion::ExpansionRegion)
1272  OS << " (Expanded file = " << R.ExpandedFileID << ")";
1273  OS << "\n";
1274  }
1275 }
1276 
1278  llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
1279  const std::string &CoverageMapping, bool IsUsed) {
1280  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1281  if (!FunctionRecordTy) {
1282 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
1283  llvm::Type *FunctionRecordTypes[] = {
1284  #include "llvm/ProfileData/InstrProfData.inc"
1285  };
1286  FunctionRecordTy =
1287  llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
1288  /*isPacked=*/true);
1289  }
1290 
1291  #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
1292  llvm::Constant *FunctionRecordVals[] = {
1293  #include "llvm/ProfileData/InstrProfData.inc"
1294  };
1295  FunctionRecords.push_back(llvm::ConstantStruct::get(
1296  FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
1297  if (!IsUsed)
1298  FunctionNames.push_back(
1299  llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
1300  CoverageMappings.push_back(CoverageMapping);
1301 
1302  if (CGM.getCodeGenOpts().DumpCoverageMapping) {
1303  // Dump the coverage mapping data for this function by decoding the
1304  // encoded data. This allows us to dump the mapping regions which were
1305  // also processed by the CoverageMappingWriter which performs
1306  // additional minimization operations such as reducing the number of
1307  // expressions.
1308  std::vector<StringRef> Filenames;
1309  std::vector<CounterExpression> Expressions;
1310  std::vector<CounterMappingRegion> Regions;
1312  llvm::SmallVector<StringRef, 16> FilenameRefs;
1313  FilenameStrs.resize(FileEntries.size());
1314  FilenameRefs.resize(FileEntries.size());
1315  for (const auto &Entry : FileEntries) {
1316  auto I = Entry.second;
1317  FilenameStrs[I] = normalizeFilename(Entry.first->getName());
1318  FilenameRefs[I] = FilenameStrs[I];
1319  }
1320  RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
1321  Expressions, Regions);
1322  if (Reader.read())
1323  return;
1324  dump(llvm::outs(), NameValue, Expressions, Regions);
1325  }
1326 }
1327 
1329  if (FunctionRecords.empty())
1330  return;
1331  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1332  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1333 
1334  // Create the filenames and merge them with coverage mappings
1336  llvm::SmallVector<StringRef, 16> FilenameRefs;
1337  FilenameStrs.resize(FileEntries.size());
1338  FilenameRefs.resize(FileEntries.size());
1339  for (const auto &Entry : FileEntries) {
1340  auto I = Entry.second;
1341  FilenameStrs[I] = normalizeFilename(Entry.first->getName());
1342  FilenameRefs[I] = FilenameStrs[I];
1343  }
1344 
1345  std::string FilenamesAndCoverageMappings;
1346  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1347  CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1348  std::string RawCoverageMappings =
1349  llvm::join(CoverageMappings.begin(), CoverageMappings.end(), "");
1350  OS << RawCoverageMappings;
1351  size_t CoverageMappingSize = RawCoverageMappings.size();
1352  size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1353  // Append extra zeroes if necessary to ensure that the size of the filenames
1354  // and coverage mappings is a multiple of 8.
1355  if (size_t Rem = OS.str().size() % 8) {
1356  CoverageMappingSize += 8 - Rem;
1357  OS.write_zeros(8 - Rem);
1358  }
1359  auto *FilenamesAndMappingsVal =
1360  llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
1361 
1362  // Create the deferred function records array
1363  auto RecordsTy =
1364  llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1365  auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1366 
1367  llvm::Type *CovDataHeaderTypes[] = {
1368 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1369 #include "llvm/ProfileData/InstrProfData.inc"
1370  };
1371  auto CovDataHeaderTy =
1372  llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1373  llvm::Constant *CovDataHeaderVals[] = {
1374 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1375 #include "llvm/ProfileData/InstrProfData.inc"
1376  };
1377  auto CovDataHeaderVal = llvm::ConstantStruct::get(
1378  CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1379 
1380  // Create the coverage data record
1381  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1382  FilenamesAndMappingsVal->getType()};
1383  auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1384  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1385  FilenamesAndMappingsVal};
1386  auto CovDataVal =
1387  llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1388  auto CovData = new llvm::GlobalVariable(
1389  CGM.getModule(), CovDataTy, true, llvm::GlobalValue::InternalLinkage,
1390  CovDataVal, llvm::getCoverageMappingVarName());
1391 
1392  CovData->setSection(getCoverageSection(CGM));
1393  CovData->setAlignment(8);
1394 
1395  // Make sure the data doesn't get deleted.
1396  CGM.addUsedGlobal(CovData);
1397  // Create the deferred function records array
1398  if (!FunctionNames.empty()) {
1399  auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1400  FunctionNames.size());
1401  auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1402  // This variable will *NOT* be emitted to the object file. It is used
1403  // to pass the list of names referenced to codegen.
1404  new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true,
1406  llvm::getCoverageUnusedNamesVarName());
1407  }
1408 }
1409 
1411  auto It = FileEntries.find(File);
1412  if (It != FileEntries.end())
1413  return It->second;
1414  unsigned FileID = FileEntries.size();
1415  FileEntries.insert(std::make_pair(File, FileID));
1416  return FileID;
1417 }
1418 
1420  llvm::raw_ostream &OS) {
1421  assert(CounterMap);
1422  CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts);
1423  Walker.VisitDecl(D);
1424  Walker.write(OS);
1425 }
1426 
1428  llvm::raw_ostream &OS) {
1429  EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
1430  Walker.VisitDecl(D);
1431  Walker.write(OS);
1432 }
Expr * getInc()
Definition: Stmt.h:1290
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer...
const Stmt * getElse() const
Definition: Stmt.h:1014
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
A (possibly-)qualified type.
Definition: Type.h:655
const Expr * getSubExpr() const
Definition: ExprCXX.h:1050
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:195
Expr * getCond()
Definition: Stmt.h:1176
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:986
Stmt - This represents one statement.
Definition: Stmt.h:66
CXXCatchStmt * getHandler(unsigned i)
Definition: StmtCXX.h:108
IfStmt - This represents an if/then/else.
Definition: Stmt.h:974
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:941
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Stmt * getHandlerBlock() const
Definition: StmtCXX.h:54
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:679
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1028
void emit()
Emit the coverage mapping data for a translation unit.
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:875
Stmt * getBody()
Definition: Stmt.h:1226
SourceLocation getBegin() const
const Expr * getRetValue() const
Definition: Stmt.cpp:928
void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, uint64_t FunctionHash, const std::string &CoverageMapping, bool IsUsed=true)
Add a function&#39;s coverage mapping record to the collection of the function mapping records...
SourceLocation getQuestionLoc() const
Definition: Expr.h:3418
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
ForStmt - This represents a &#39;for (init;cond;inc)&#39; stmt.
Definition: Stmt.h:1256
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
SourceLocation getRParenLoc() const
Definition: StmtCXX.h:198
Stmt * getBody()
Definition: Stmt.h:1291
child_range children()
Definition: Stmt.cpp:227
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3143
Stmt * getInit()
Definition: Stmt.h:1270
CXXForRangeStmt - This represents C++0x [stmt.ranged]&#39;s ranged for statement, represented as &#39;for (ra...
Definition: StmtCXX.h:130
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Expr * getCond()
Definition: Stmt.h:1289
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1649
bool getNoReturn() const
Definition: Type.h:3282
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
Stmt * getInit()
Definition: Stmt.h:1007
NodeId Parent
Definition: ASTDiff.cpp:192
StringRef Filename
Definition: Format.cpp:1605
bool isValid() const
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
Expr - This represents one expression.
Definition: Expr.h:106
SourceLocation End
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
Definition: Lexer.cpp:436
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Organizes the cross-function state that is used while generating code coverage mapping data...
const Stmt * getThen() const
Definition: Stmt.h:1012
const Expr * getCallee() const
Definition: Expr.h:2356
Stmt * getBody()
Definition: Stmt.h:1179
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:67
int Depth
Definition: ASTDiff.cpp:191
QualType getType() const
Definition: Expr.h:128
void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override
Hook called when a source range is skipped.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1476
ASTContext & getContext() const
const SourceManager & SM
Definition: Format.cpp:1475
unsigned getFileID(const FileEntry *File)
Return the coverage mapping translation unit file id for the given file.
DoStmt - This represents a &#39;do/while&#39; stmt.
Definition: Stmt.h:1205
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
Definition: DeclBase.h:992
The l-value was considered opaque, so the alignment was determined from a type.
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Encodes a location in the source.
unsigned getNumHandlers() const
Definition: StmtCXX.h:107
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.h:401
ArrayRef< SourceRange > getSkippedRanges() const
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
CoverageSourceInfo & getSourceInfo() const
SourceLocation getLocEnd() const LLVM_READONLY
Definition: Stmt.h:403
Expr * getLHS() const
Definition: Expr.h:3187
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include&#39;d file otherwise it returns an invalid location...
FileID getMainFileID() const
Returns the FileID of the main source file.
FunctionType::ExtInfo getFunctionExtInfo(const Type &t)
Definition: Type.h:6014
const Stmt * getBody() const
Definition: Stmt.h:1093
SwitchStmt - This represents a &#39;switch&#39; stmt.
Definition: Stmt.h:1054
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getRParenLoc() const
Definition: StmtObjC.h:55
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument&#39;s expansion into the function-lik...
Represents Objective-C&#39;s collection statement.
Definition: StmtObjC.h:24
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:3387
Stmt * getInit()
Definition: Stmt.h:1089
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:32
Stmt * getSubStmt()
Definition: Stmt.cpp:886
SourceLocation getRParenLoc() const
Definition: Stmt.h:1307
DeclStmt * getRangeStmt()
Definition: StmtCXX.h:156
GotoStmt - This represents a direct goto.
Definition: Stmt.h:1329
Expr * getCond()
Definition: Stmt.h:1223
void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data which maps the regions of code to counters that will be used to find t...
ContinueStmt - This represents a continue.
Definition: Stmt.h:1410
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:29
WhileStmt - This represents a &#39;while&#39; stmt.
Definition: Stmt.h:1147
CompoundStmt * getTryBlock()
Definition: StmtCXX.h:100
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2316
__DEVICE__ int max(int __a, int __b)
Expr * getRHS() const
Definition: Expr.h:3189
BreakStmt - This represents a break.
Definition: Stmt.h:1438
__DEVICE__ int min(int __a, int __b)
Stmt * getSubStmt()
Definition: Stmt.h:895
DeclStmt * getLoopVarStmt()
Definition: StmtCXX.h:163
const Expr * getCond() const
Definition: Stmt.h:1010
A trivial tuple used to represent a source range.
void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data for an unused function.
const Expr * getCond() const
Definition: Stmt.h:1092
This class handles loading and caching of source files into memory.