clang  3.9.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 
27 using namespace clang;
28 using namespace CodeGen;
29 using namespace llvm::coverage;
30 
32  SkippedRanges.push_back(Range);
33 }
34 
35 namespace {
36 
37 /// \brief A region of source code that can be mapped to a counter.
38 class SourceMappingRegion {
39  Counter Count;
40 
41  /// \brief The region's starting location.
42  Optional<SourceLocation> LocStart;
43 
44  /// \brief The region's ending location.
46 
47 public:
48  SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
50  : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
51 
52  const Counter &getCounter() const { return Count; }
53 
54  void setCounter(Counter C) { Count = C; }
55 
56  bool hasStartLoc() const { return LocStart.hasValue(); }
57 
58  void setStartLoc(SourceLocation Loc) { LocStart = Loc; }
59 
60  SourceLocation getStartLoc() const {
61  assert(LocStart && "Region has no start location");
62  return *LocStart;
63  }
64 
65  bool hasEndLoc() const { return LocEnd.hasValue(); }
66 
67  void setEndLoc(SourceLocation Loc) { LocEnd = Loc; }
68 
69  SourceLocation getEndLoc() const {
70  assert(LocEnd && "Region has no end location");
71  return *LocEnd;
72  }
73 };
74 
75 /// \brief Provides the common functionality for the different
76 /// coverage mapping region builders.
77 class CoverageMappingBuilder {
78 public:
81  const LangOptions &LangOpts;
82 
83 private:
84  /// \brief Map of clang's FileIDs to IDs used for coverage mapping.
85  llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
86  FileIDMapping;
87 
88 public:
89  /// \brief The coverage mapping regions for this function
91  /// \brief The source mapping regions for this function.
92  std::vector<SourceMappingRegion> SourceRegions;
93 
94  CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
95  const LangOptions &LangOpts)
96  : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
97 
98  /// \brief Return the precise end location for the given token.
99  SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
100  // We avoid getLocForEndOfToken here, because it doesn't do what we want for
101  // macro locations, which we just treat as expanded files.
102  unsigned TokLen =
104  return Loc.getLocWithOffset(TokLen);
105  }
106 
107  /// \brief Return the start location of an included file or expanded macro.
108  SourceLocation getStartOfFileOrMacro(SourceLocation Loc) {
109  if (Loc.isMacroID())
110  return Loc.getLocWithOffset(-SM.getFileOffset(Loc));
111  return SM.getLocForStartOfFile(SM.getFileID(Loc));
112  }
113 
114  /// \brief Return the end location of an included file or expanded macro.
115  SourceLocation getEndOfFileOrMacro(SourceLocation Loc) {
116  if (Loc.isMacroID())
117  return Loc.getLocWithOffset(SM.getFileIDSize(SM.getFileID(Loc)) -
118  SM.getFileOffset(Loc));
119  return SM.getLocForEndOfFile(SM.getFileID(Loc));
120  }
121 
122  /// \brief Find out where the current file is included or macro is expanded.
123  SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc) {
124  return Loc.isMacroID() ? SM.getImmediateExpansionRange(Loc).first
125  : SM.getIncludeLoc(SM.getFileID(Loc));
126  }
127 
128  /// \brief Return true if \c Loc is a location in a built-in macro.
129  bool isInBuiltin(SourceLocation Loc) {
130  return strcmp(SM.getBufferName(SM.getSpellingLoc(Loc)), "<built-in>") == 0;
131  }
132 
133  /// \brief Check whether \c Loc is included or expanded from \c Parent.
134  bool isNestedIn(SourceLocation Loc, FileID Parent) {
135  do {
136  Loc = getIncludeOrExpansionLoc(Loc);
137  if (Loc.isInvalid())
138  return false;
139  } while (!SM.isInFileID(Loc, Parent));
140  return true;
141  }
142 
143  /// \brief Get the start of \c S ignoring macro arguments and builtin macros.
144  SourceLocation getStart(const Stmt *S) {
145  SourceLocation Loc = S->getLocStart();
146  while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
147  Loc = SM.getImmediateExpansionRange(Loc).first;
148  return Loc;
149  }
150 
151  /// \brief Get the end of \c S ignoring macro arguments and builtin macros.
152  SourceLocation getEnd(const Stmt *S) {
153  SourceLocation Loc = S->getLocEnd();
154  while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
155  Loc = SM.getImmediateExpansionRange(Loc).first;
156  return getPreciseTokenLocEnd(Loc);
157  }
158 
159  /// \brief Find the set of files we have regions for and assign IDs
160  ///
161  /// Fills \c Mapping with the virtual file mapping needed to write out
162  /// coverage and collects the necessary file information to emit source and
163  /// expansion regions.
164  void gatherFileIDs(SmallVectorImpl<unsigned> &Mapping) {
165  FileIDMapping.clear();
166 
167  llvm::SmallSet<FileID, 8> Visited;
169  for (const auto &Region : SourceRegions) {
170  SourceLocation Loc = Region.getStartLoc();
171  FileID File = SM.getFileID(Loc);
172  if (!Visited.insert(File).second)
173  continue;
174 
175  // Do not map FileID's associated with system headers.
177  continue;
178 
179  unsigned Depth = 0;
180  for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
181  Parent.isValid(); Parent = getIncludeOrExpansionLoc(Parent))
182  ++Depth;
183  FileLocs.push_back(std::make_pair(Loc, Depth));
184  }
185  std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
186 
187  for (const auto &FL : FileLocs) {
188  SourceLocation Loc = FL.first;
189  FileID SpellingFile = SM.getDecomposedSpellingLoc(Loc).first;
190  auto Entry = SM.getFileEntryForID(SpellingFile);
191  if (!Entry)
192  continue;
193 
194  FileIDMapping[SM.getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
195  Mapping.push_back(CVM.getFileID(Entry));
196  }
197  }
198 
199  /// \brief Get the coverage mapping file ID for \c Loc.
200  ///
201  /// If such file id doesn't exist, return None.
202  Optional<unsigned> getCoverageFileID(SourceLocation Loc) {
203  auto Mapping = FileIDMapping.find(SM.getFileID(Loc));
204  if (Mapping != FileIDMapping.end())
205  return Mapping->second.first;
206  return None;
207  }
208 
209  /// \brief Gather all the regions that were skipped by the preprocessor
210  /// using the constructs like #if.
211  void gatherSkippedRegions() {
212  /// An array of the minimum lineStarts and the maximum lineEnds
213  /// for mapping regions from the appropriate source files.
215  FileLineRanges.resize(
216  FileIDMapping.size(),
217  std::make_pair(std::numeric_limits<unsigned>::max(), 0));
218  for (const auto &R : MappingRegions) {
219  FileLineRanges[R.FileID].first =
220  std::min(FileLineRanges[R.FileID].first, R.LineStart);
221  FileLineRanges[R.FileID].second =
222  std::max(FileLineRanges[R.FileID].second, R.LineEnd);
223  }
224 
225  auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
226  for (const auto &I : SkippedRanges) {
227  auto LocStart = I.getBegin();
228  auto LocEnd = I.getEnd();
229  assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
230  "region spans multiple files");
231 
232  auto CovFileID = getCoverageFileID(LocStart);
233  if (!CovFileID)
234  continue;
235  unsigned LineStart = SM.getSpellingLineNumber(LocStart);
236  unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
237  unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
238  unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
239  auto Region = CounterMappingRegion::makeSkipped(
240  *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
241  // Make sure that we only collect the regions that are inside
242  // the souce code of this function.
243  if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
244  Region.LineEnd <= FileLineRanges[*CovFileID].second)
245  MappingRegions.push_back(Region);
246  }
247  }
248 
249  /// \brief Generate the coverage counter mapping regions from collected
250  /// source regions.
251  void emitSourceRegions() {
252  for (const auto &Region : SourceRegions) {
253  assert(Region.hasEndLoc() && "incomplete region");
254 
255  SourceLocation LocStart = Region.getStartLoc();
256  assert(SM.getFileID(LocStart).isValid() && "region in invalid file");
257 
258  // Ignore regions from system headers.
259  if (SM.isInSystemHeader(SM.getSpellingLoc(LocStart)))
260  continue;
261 
262  auto CovFileID = getCoverageFileID(LocStart);
263  // Ignore regions that don't have a file, such as builtin macros.
264  if (!CovFileID)
265  continue;
266 
267  SourceLocation LocEnd = Region.getEndLoc();
268  assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
269  "region spans multiple files");
270 
271  // Find the spilling locations for the mapping region.
272  unsigned LineStart = SM.getSpellingLineNumber(LocStart);
273  unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
274  unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
275  unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
276 
277  assert(LineStart <= LineEnd && "region start and end out of order");
278  MappingRegions.push_back(CounterMappingRegion::makeRegion(
279  Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
280  ColumnEnd));
281  }
282  }
283 
284  /// \brief Generate expansion regions for each virtual file we've seen.
285  void emitExpansionRegions() {
286  for (const auto &FM : FileIDMapping) {
287  SourceLocation ExpandedLoc = FM.second.second;
288  SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc);
289  if (ParentLoc.isInvalid())
290  continue;
291 
292  auto ParentFileID = getCoverageFileID(ParentLoc);
293  if (!ParentFileID)
294  continue;
295  auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
296  assert(ExpandedFileID && "expansion in uncovered file");
297 
298  SourceLocation LocEnd = getPreciseTokenLocEnd(ParentLoc);
299  assert(SM.isWrittenInSameFile(ParentLoc, LocEnd) &&
300  "region spans multiple files");
301 
302  unsigned LineStart = SM.getSpellingLineNumber(ParentLoc);
303  unsigned ColumnStart = SM.getSpellingColumnNumber(ParentLoc);
304  unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
305  unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
306 
307  MappingRegions.push_back(CounterMappingRegion::makeExpansion(
308  *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
309  ColumnEnd));
310  }
311  }
312 };
313 
314 /// \brief Creates unreachable coverage regions for the functions that
315 /// are not emitted.
316 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
317  EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
318  const LangOptions &LangOpts)
319  : CoverageMappingBuilder(CVM, SM, LangOpts) {}
320 
321  void VisitDecl(const Decl *D) {
322  if (!D->hasBody())
323  return;
324  auto Body = D->getBody();
325  SourceLocation Start = getStart(Body);
326  SourceLocation End = getEnd(Body);
327  if (!SM.isWrittenInSameFile(Start, End)) {
328  // Walk up to find the common ancestor.
329  // Correct the locations accordingly.
330  FileID StartFileID = SM.getFileID(Start);
331  FileID EndFileID = SM.getFileID(End);
332  while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
333  Start = getIncludeOrExpansionLoc(Start);
334  assert(Start.isValid() &&
335  "Declaration start location not nested within a known region");
336  StartFileID = SM.getFileID(Start);
337  }
338  while (StartFileID != EndFileID) {
339  End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
340  assert(End.isValid() &&
341  "Declaration end location not nested within a known region");
342  EndFileID = SM.getFileID(End);
343  }
344  }
345  SourceRegions.emplace_back(Counter(), Start, End);
346  }
347 
348  /// \brief Write the mapping data to the output stream
349  void write(llvm::raw_ostream &OS) {
350  SmallVector<unsigned, 16> FileIDMapping;
351  gatherFileIDs(FileIDMapping);
352  emitSourceRegions();
353 
354  if (MappingRegions.empty())
355  return;
356 
357  CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
358  Writer.write(OS);
359  }
360 };
361 
362 /// \brief A StmtVisitor that creates coverage mapping regions which map
363 /// from the source code locations to the PGO counters.
364 struct CounterCoverageMappingBuilder
365  : public CoverageMappingBuilder,
366  public ConstStmtVisitor<CounterCoverageMappingBuilder> {
367  /// \brief The map of statements to count values.
368  llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
369 
370  /// \brief A stack of currently live regions.
371  std::vector<SourceMappingRegion> RegionStack;
372 
373  CounterExpressionBuilder Builder;
374 
375  /// \brief A location in the most recently visited file or macro.
376  ///
377  /// This is used to adjust the active source regions appropriately when
378  /// expressions cross file or macro boundaries.
379  SourceLocation MostRecentLocation;
380 
381  /// \brief Return a counter for the subtraction of \c RHS from \c LHS
382  Counter subtractCounters(Counter LHS, Counter RHS) {
383  return Builder.subtract(LHS, RHS);
384  }
385 
386  /// \brief Return a counter for the sum of \c LHS and \c RHS.
387  Counter addCounters(Counter LHS, Counter RHS) {
388  return Builder.add(LHS, RHS);
389  }
390 
391  Counter addCounters(Counter C1, Counter C2, Counter C3) {
392  return addCounters(addCounters(C1, C2), C3);
393  }
394 
395  /// \brief Return the region counter for the given statement.
396  ///
397  /// This should only be called on statements that have a dedicated counter.
398  Counter getRegionCounter(const Stmt *S) {
399  return Counter::getCounter(CounterMap[S]);
400  }
401 
402  /// \brief Push a region onto the stack.
403  ///
404  /// Returns the index on the stack where the region was pushed. This can be
405  /// used with popRegions to exit a "scope", ending the region that was pushed.
406  size_t pushRegion(Counter Count, Optional<SourceLocation> StartLoc = None,
407  Optional<SourceLocation> EndLoc = None) {
408  if (StartLoc)
409  MostRecentLocation = *StartLoc;
410  RegionStack.emplace_back(Count, StartLoc, EndLoc);
411 
412  return RegionStack.size() - 1;
413  }
414 
415  /// \brief Pop regions from the stack into the function's list of regions.
416  ///
417  /// Adds all regions from \c ParentIndex to the top of the stack to the
418  /// function's \c SourceRegions.
419  void popRegions(size_t ParentIndex) {
420  assert(RegionStack.size() >= ParentIndex && "parent not in stack");
421  while (RegionStack.size() > ParentIndex) {
422  SourceMappingRegion &Region = RegionStack.back();
423  if (Region.hasStartLoc()) {
424  SourceLocation StartLoc = Region.getStartLoc();
425  SourceLocation EndLoc = Region.hasEndLoc()
426  ? Region.getEndLoc()
427  : RegionStack[ParentIndex].getEndLoc();
428  while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) {
429  // The region ends in a nested file or macro expansion. Create a
430  // separate region for each expansion.
431  SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
432  assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
433 
434  SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
435 
436  EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
437  if (EndLoc.isInvalid())
438  llvm::report_fatal_error("File exit not handled before popRegions");
439  }
440  Region.setEndLoc(EndLoc);
441 
442  MostRecentLocation = EndLoc;
443  // If this region happens to span an entire expansion, we need to make
444  // sure we don't overlap the parent region with it.
445  if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
446  EndLoc == getEndOfFileOrMacro(EndLoc))
447  MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
448 
449  assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc));
450  SourceRegions.push_back(Region);
451  }
452  RegionStack.pop_back();
453  }
454  }
455 
456  /// \brief Return the currently active region.
457  SourceMappingRegion &getRegion() {
458  assert(!RegionStack.empty() && "statement has no region");
459  return RegionStack.back();
460  }
461 
462  /// \brief Propagate counts through the children of \c S.
463  Counter propagateCounts(Counter TopCount, const Stmt *S) {
464  size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
465  Visit(S);
466  Counter ExitCount = getRegion().getCounter();
467  popRegions(Index);
468 
469  // The statement may be spanned by an expansion. Make sure we handle a file
470  // exit out of this expansion before moving to the next statement.
471  if (SM.isBeforeInTranslationUnit(getStart(S), S->getLocStart()))
472  MostRecentLocation = getEnd(S);
473 
474  return ExitCount;
475  }
476 
477  /// \brief Check whether a region with bounds \c StartLoc and \c EndLoc
478  /// is already added to \c SourceRegions.
479  bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc) {
480  return SourceRegions.rend() !=
481  std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
482  [&](const SourceMappingRegion &Region) {
483  return Region.getStartLoc() == StartLoc &&
484  Region.getEndLoc() == EndLoc;
485  });
486  }
487 
488  /// \brief Adjust the most recently visited location to \c EndLoc.
489  ///
490  /// This should be used after visiting any statements in non-source order.
491  void adjustForOutOfOrderTraversal(SourceLocation EndLoc) {
492  MostRecentLocation = EndLoc;
493  // The code region for a whole macro is created in handleFileExit() when
494  // it detects exiting of the virtual file of that macro. If we visited
495  // statements in non-source order, we might already have such a region
496  // added, for example, if a body of a loop is divided among multiple
497  // macros. Avoid adding duplicate regions in such case.
498  if (getRegion().hasEndLoc() &&
499  MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
500  isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
501  MostRecentLocation))
502  MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
503  }
504 
505  /// \brief Adjust regions and state when \c NewLoc exits a file.
506  ///
507  /// If moving from our most recently tracked location to \c NewLoc exits any
508  /// files, this adjusts our current region stack and creates the file regions
509  /// for the exited file.
510  void handleFileExit(SourceLocation NewLoc) {
511  if (NewLoc.isInvalid() ||
512  SM.isWrittenInSameFile(MostRecentLocation, NewLoc))
513  return;
514 
515  // If NewLoc is not in a file that contains MostRecentLocation, walk up to
516  // find the common ancestor.
517  SourceLocation LCA = NewLoc;
518  FileID ParentFile = SM.getFileID(LCA);
519  while (!isNestedIn(MostRecentLocation, ParentFile)) {
520  LCA = getIncludeOrExpansionLoc(LCA);
521  if (LCA.isInvalid() || SM.isWrittenInSameFile(LCA, MostRecentLocation)) {
522  // Since there isn't a common ancestor, no file was exited. We just need
523  // to adjust our location to the new file.
524  MostRecentLocation = NewLoc;
525  return;
526  }
527  ParentFile = SM.getFileID(LCA);
528  }
529 
530  llvm::SmallSet<SourceLocation, 8> StartLocs;
531  Optional<Counter> ParentCounter;
532  for (SourceMappingRegion &I : llvm::reverse(RegionStack)) {
533  if (!I.hasStartLoc())
534  continue;
535  SourceLocation Loc = I.getStartLoc();
536  if (!isNestedIn(Loc, ParentFile)) {
537  ParentCounter = I.getCounter();
538  break;
539  }
540 
541  while (!SM.isInFileID(Loc, ParentFile)) {
542  // The most nested region for each start location is the one with the
543  // correct count. We avoid creating redundant regions by stopping once
544  // we've seen this region.
545  if (StartLocs.insert(Loc).second)
546  SourceRegions.emplace_back(I.getCounter(), Loc,
547  getEndOfFileOrMacro(Loc));
548  Loc = getIncludeOrExpansionLoc(Loc);
549  }
550  I.setStartLoc(getPreciseTokenLocEnd(Loc));
551  }
552 
553  if (ParentCounter) {
554  // If the file is contained completely by another region and doesn't
555  // immediately start its own region, the whole file gets a region
556  // corresponding to the parent.
557  SourceLocation Loc = MostRecentLocation;
558  while (isNestedIn(Loc, ParentFile)) {
559  SourceLocation FileStart = getStartOfFileOrMacro(Loc);
560  if (StartLocs.insert(FileStart).second)
561  SourceRegions.emplace_back(*ParentCounter, FileStart,
562  getEndOfFileOrMacro(Loc));
563  Loc = getIncludeOrExpansionLoc(Loc);
564  }
565  }
566 
567  MostRecentLocation = NewLoc;
568  }
569 
570  /// \brief Ensure that \c S is included in the current region.
571  void extendRegion(const Stmt *S) {
572  SourceMappingRegion &Region = getRegion();
573  SourceLocation StartLoc = getStart(S);
574 
575  handleFileExit(StartLoc);
576  if (!Region.hasStartLoc())
577  Region.setStartLoc(StartLoc);
578  }
579 
580  /// \brief Mark \c S as a terminator, starting a zero region.
581  void terminateRegion(const Stmt *S) {
582  extendRegion(S);
583  SourceMappingRegion &Region = getRegion();
584  if (!Region.hasEndLoc())
585  Region.setEndLoc(getEnd(S));
586  pushRegion(Counter::getZero());
587  }
588 
589  /// \brief Keep counts of breaks and continues inside loops.
590  struct BreakContinue {
591  Counter BreakCount;
592  Counter ContinueCount;
593  };
594  SmallVector<BreakContinue, 8> BreakContinueStack;
595 
596  CounterCoverageMappingBuilder(
598  llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
599  const LangOptions &LangOpts)
600  : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
601 
602  /// \brief Write the mapping data to the output stream
603  void write(llvm::raw_ostream &OS) {
604  llvm::SmallVector<unsigned, 8> VirtualFileMapping;
605  gatherFileIDs(VirtualFileMapping);
606  emitSourceRegions();
607  emitExpansionRegions();
608  gatherSkippedRegions();
609 
610  if (MappingRegions.empty())
611  return;
612 
613  CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(),
614  MappingRegions);
615  Writer.write(OS);
616  }
617 
618  void VisitStmt(const Stmt *S) {
619  if (S->getLocStart().isValid())
620  extendRegion(S);
621  for (const Stmt *Child : S->children())
622  if (Child)
623  this->Visit(Child);
624  handleFileExit(getEnd(S));
625  }
626 
627  void VisitDecl(const Decl *D) {
628  Stmt *Body = D->getBody();
629 
630  // Do not propagate region counts into system headers.
631  if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
632  return;
633 
634  propagateCounts(getRegionCounter(Body), Body);
635  }
636 
637  void VisitReturnStmt(const ReturnStmt *S) {
638  extendRegion(S);
639  if (S->getRetValue())
640  Visit(S->getRetValue());
641  terminateRegion(S);
642  }
643 
644  void VisitCXXThrowExpr(const CXXThrowExpr *E) {
645  extendRegion(E);
646  if (E->getSubExpr())
647  Visit(E->getSubExpr());
648  terminateRegion(E);
649  }
650 
651  void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
652 
653  void VisitLabelStmt(const LabelStmt *S) {
654  SourceLocation Start = getStart(S);
655  // We can't extendRegion here or we risk overlapping with our new region.
656  handleFileExit(Start);
657  pushRegion(getRegionCounter(S), Start);
658  Visit(S->getSubStmt());
659  }
660 
661  void VisitBreakStmt(const BreakStmt *S) {
662  assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
663  BreakContinueStack.back().BreakCount = addCounters(
664  BreakContinueStack.back().BreakCount, getRegion().getCounter());
665  terminateRegion(S);
666  }
667 
668  void VisitContinueStmt(const ContinueStmt *S) {
669  assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
670  BreakContinueStack.back().ContinueCount = addCounters(
671  BreakContinueStack.back().ContinueCount, getRegion().getCounter());
672  terminateRegion(S);
673  }
674 
675  void VisitWhileStmt(const WhileStmt *S) {
676  extendRegion(S);
677 
678  Counter ParentCount = getRegion().getCounter();
679  Counter BodyCount = getRegionCounter(S);
680 
681  // Handle the body first so that we can get the backedge count.
682  BreakContinueStack.push_back(BreakContinue());
683  extendRegion(S->getBody());
684  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
685  BreakContinue BC = BreakContinueStack.pop_back_val();
686 
687  // Go back to handle the condition.
688  Counter CondCount =
689  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
690  propagateCounts(CondCount, S->getCond());
691  adjustForOutOfOrderTraversal(getEnd(S));
692 
693  Counter OutCount =
694  addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
695  if (OutCount != ParentCount)
696  pushRegion(OutCount);
697  }
698 
699  void VisitDoStmt(const DoStmt *S) {
700  extendRegion(S);
701 
702  Counter ParentCount = getRegion().getCounter();
703  Counter BodyCount = getRegionCounter(S);
704 
705  BreakContinueStack.push_back(BreakContinue());
706  extendRegion(S->getBody());
707  Counter BackedgeCount =
708  propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
709  BreakContinue BC = BreakContinueStack.pop_back_val();
710 
711  Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
712  propagateCounts(CondCount, S->getCond());
713 
714  Counter OutCount =
715  addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
716  if (OutCount != ParentCount)
717  pushRegion(OutCount);
718  }
719 
720  void VisitForStmt(const ForStmt *S) {
721  extendRegion(S);
722  if (S->getInit())
723  Visit(S->getInit());
724 
725  Counter ParentCount = getRegion().getCounter();
726  Counter BodyCount = getRegionCounter(S);
727 
728  // Handle the body first so that we can get the backedge count.
729  BreakContinueStack.push_back(BreakContinue());
730  extendRegion(S->getBody());
731  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
732  BreakContinue BC = BreakContinueStack.pop_back_val();
733 
734  // The increment is essentially part of the body but it needs to include
735  // the count for all the continue statements.
736  if (const Stmt *Inc = S->getInc())
737  propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
738 
739  // Go back to handle the condition.
740  Counter CondCount =
741  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
742  if (const Expr *Cond = S->getCond()) {
743  propagateCounts(CondCount, Cond);
744  adjustForOutOfOrderTraversal(getEnd(S));
745  }
746 
747  Counter OutCount =
748  addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
749  if (OutCount != ParentCount)
750  pushRegion(OutCount);
751  }
752 
753  void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
754  extendRegion(S);
755  Visit(S->getLoopVarStmt());
756  Visit(S->getRangeStmt());
757 
758  Counter ParentCount = getRegion().getCounter();
759  Counter BodyCount = getRegionCounter(S);
760 
761  BreakContinueStack.push_back(BreakContinue());
762  extendRegion(S->getBody());
763  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
764  BreakContinue BC = BreakContinueStack.pop_back_val();
765 
766  Counter LoopCount =
767  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
768  Counter OutCount =
769  addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
770  if (OutCount != ParentCount)
771  pushRegion(OutCount);
772  }
773 
774  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
775  extendRegion(S);
776  Visit(S->getElement());
777 
778  Counter ParentCount = getRegion().getCounter();
779  Counter BodyCount = getRegionCounter(S);
780 
781  BreakContinueStack.push_back(BreakContinue());
782  extendRegion(S->getBody());
783  Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
784  BreakContinue BC = BreakContinueStack.pop_back_val();
785 
786  Counter LoopCount =
787  addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
788  Counter OutCount =
789  addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
790  if (OutCount != ParentCount)
791  pushRegion(OutCount);
792  }
793 
794  void VisitSwitchStmt(const SwitchStmt *S) {
795  extendRegion(S);
796  Visit(S->getCond());
797 
798  BreakContinueStack.push_back(BreakContinue());
799 
800  const Stmt *Body = S->getBody();
801  extendRegion(Body);
802  if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
803  if (!CS->body_empty()) {
804  // The body of the switch needs a zero region so that fallthrough counts
805  // behave correctly, but it would be misleading to include the braces of
806  // the compound statement in the zeroed area, so we need to handle this
807  // specially.
808  size_t Index =
809  pushRegion(Counter::getZero(), getStart(CS->body_front()),
810  getEnd(CS->body_back()));
811  for (const auto *Child : CS->children())
812  Visit(Child);
813  popRegions(Index);
814  }
815  } else
816  propagateCounts(Counter::getZero(), Body);
817  BreakContinue BC = BreakContinueStack.pop_back_val();
818 
819  if (!BreakContinueStack.empty())
820  BreakContinueStack.back().ContinueCount = addCounters(
821  BreakContinueStack.back().ContinueCount, BC.ContinueCount);
822 
823  Counter ExitCount = getRegionCounter(S);
824  SourceLocation ExitLoc = getEnd(S);
825  pushRegion(ExitCount, getStart(S), ExitLoc);
826  handleFileExit(ExitLoc);
827  }
828 
829  void VisitSwitchCase(const SwitchCase *S) {
830  extendRegion(S);
831 
832  SourceMappingRegion &Parent = getRegion();
833 
834  Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
835  // Reuse the existing region if it starts at our label. This is typical of
836  // the first case in a switch.
837  if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
838  Parent.setCounter(Count);
839  else
840  pushRegion(Count, getStart(S));
841 
842  if (const auto *CS = dyn_cast<CaseStmt>(S)) {
843  Visit(CS->getLHS());
844  if (const Expr *RHS = CS->getRHS())
845  Visit(RHS);
846  }
847  Visit(S->getSubStmt());
848  }
849 
850  void VisitIfStmt(const IfStmt *S) {
851  extendRegion(S);
852  // Extend into the condition before we propagate through it below - this is
853  // needed to handle macros that generate the "if" but not the condition.
854  extendRegion(S->getCond());
855 
856  Counter ParentCount = getRegion().getCounter();
857  Counter ThenCount = getRegionCounter(S);
858 
859  // Emitting a counter for the condition makes it easier to interpret the
860  // counter for the body when looking at the coverage.
861  propagateCounts(ParentCount, S->getCond());
862 
863  extendRegion(S->getThen());
864  Counter OutCount = propagateCounts(ThenCount, S->getThen());
865 
866  Counter ElseCount = subtractCounters(ParentCount, ThenCount);
867  if (const Stmt *Else = S->getElse()) {
868  extendRegion(S->getElse());
869  OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
870  } else
871  OutCount = addCounters(OutCount, ElseCount);
872 
873  if (OutCount != ParentCount)
874  pushRegion(OutCount);
875  }
876 
877  void VisitCXXTryStmt(const CXXTryStmt *S) {
878  extendRegion(S);
879  // Handle macros that generate the "try" but not the rest.
880  extendRegion(S->getTryBlock());
881 
882  Counter ParentCount = getRegion().getCounter();
883  propagateCounts(ParentCount, S->getTryBlock());
884 
885  for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
886  Visit(S->getHandler(I));
887 
888  Counter ExitCount = getRegionCounter(S);
889  pushRegion(ExitCount);
890  }
891 
892  void VisitCXXCatchStmt(const CXXCatchStmt *S) {
893  propagateCounts(getRegionCounter(S), S->getHandlerBlock());
894  }
895 
896  void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
897  extendRegion(E);
898 
899  Counter ParentCount = getRegion().getCounter();
900  Counter TrueCount = getRegionCounter(E);
901 
902  Visit(E->getCond());
903 
904  if (!isa<BinaryConditionalOperator>(E)) {
905  extendRegion(E->getTrueExpr());
906  propagateCounts(TrueCount, E->getTrueExpr());
907  }
908  extendRegion(E->getFalseExpr());
909  propagateCounts(subtractCounters(ParentCount, TrueCount),
910  E->getFalseExpr());
911  }
912 
913  void VisitBinLAnd(const BinaryOperator *E) {
914  extendRegion(E);
915  Visit(E->getLHS());
916 
917  extendRegion(E->getRHS());
918  propagateCounts(getRegionCounter(E), E->getRHS());
919  }
920 
921  void VisitBinLOr(const BinaryOperator *E) {
922  extendRegion(E);
923  Visit(E->getLHS());
924 
925  extendRegion(E->getRHS());
926  propagateCounts(getRegionCounter(E), E->getRHS());
927  }
928 
929  void VisitLambdaExpr(const LambdaExpr *LE) {
930  // Lambdas are treated as their own functions for now, so we shouldn't
931  // propagate counts into them.
932  }
933 };
934 }
935 
936 static bool isMachO(const CodeGenModule &CGM) {
937  return CGM.getTarget().getTriple().isOSBinFormatMachO();
938 }
939 
940 static StringRef getCoverageSection(const CodeGenModule &CGM) {
941  return llvm::getInstrProfCoverageSectionName(isMachO(CGM));
942 }
943 
944 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
945  ArrayRef<CounterExpression> Expressions,
947  OS << FunctionName << ":\n";
948  CounterMappingContext Ctx(Expressions);
949  for (const auto &R : Regions) {
950  OS.indent(2);
951  switch (R.Kind) {
952  case CounterMappingRegion::CodeRegion:
953  break;
954  case CounterMappingRegion::ExpansionRegion:
955  OS << "Expansion,";
956  break;
957  case CounterMappingRegion::SkippedRegion:
958  OS << "Skipped,";
959  break;
960  }
961 
962  OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
963  << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = ";
964  Ctx.dump(R.Count, OS);
965  if (R.Kind == CounterMappingRegion::ExpansionRegion)
966  OS << " (Expanded file = " << R.ExpandedFileID << ")";
967  OS << "\n";
968  }
969 }
970 
972  llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
973  const std::string &CoverageMapping, bool IsUsed) {
974  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
975  if (!FunctionRecordTy) {
976 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
977  llvm::Type *FunctionRecordTypes[] = {
978  #include "llvm/ProfileData/InstrProfData.inc"
979  };
980  FunctionRecordTy =
981  llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
982  /*isPacked=*/true);
983  }
984 
985  #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
986  llvm::Constant *FunctionRecordVals[] = {
987  #include "llvm/ProfileData/InstrProfData.inc"
988  };
989  FunctionRecords.push_back(llvm::ConstantStruct::get(
990  FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
991  if (!IsUsed)
992  FunctionNames.push_back(
993  llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
994  CoverageMappings.push_back(CoverageMapping);
995 
996  if (CGM.getCodeGenOpts().DumpCoverageMapping) {
997  // Dump the coverage mapping data for this function by decoding the
998  // encoded data. This allows us to dump the mapping regions which were
999  // also processed by the CoverageMappingWriter which performs
1000  // additional minimization operations such as reducing the number of
1001  // expressions.
1002  std::vector<StringRef> Filenames;
1003  std::vector<CounterExpression> Expressions;
1004  std::vector<CounterMappingRegion> Regions;
1005  llvm::SmallVector<StringRef, 16> FilenameRefs;
1006  FilenameRefs.resize(FileEntries.size());
1007  for (const auto &Entry : FileEntries)
1008  FilenameRefs[Entry.second] = Entry.first->getName();
1009  RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
1010  Expressions, Regions);
1011  if (Reader.read())
1012  return;
1013  dump(llvm::outs(), NameValue, Expressions, Regions);
1014  }
1015 }
1016 
1018  if (FunctionRecords.empty())
1019  return;
1020  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1021  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1022 
1023  // Create the filenames and merge them with coverage mappings
1025  llvm::SmallVector<StringRef, 16> FilenameRefs;
1026  FilenameStrs.resize(FileEntries.size());
1027  FilenameRefs.resize(FileEntries.size());
1028  for (const auto &Entry : FileEntries) {
1029  llvm::SmallString<256> Path(Entry.first->getName());
1030  llvm::sys::fs::make_absolute(Path);
1031 
1032  auto I = Entry.second;
1033  FilenameStrs[I] = std::string(Path.begin(), Path.end());
1034  FilenameRefs[I] = FilenameStrs[I];
1035  }
1036 
1037  std::string FilenamesAndCoverageMappings;
1038  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1039  CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1040  std::string RawCoverageMappings =
1041  llvm::join(CoverageMappings.begin(), CoverageMappings.end(), "");
1042  OS << RawCoverageMappings;
1043  size_t CoverageMappingSize = RawCoverageMappings.size();
1044  size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1045  // Append extra zeroes if necessary to ensure that the size of the filenames
1046  // and coverage mappings is a multiple of 8.
1047  if (size_t Rem = OS.str().size() % 8) {
1048  CoverageMappingSize += 8 - Rem;
1049  for (size_t I = 0, S = 8 - Rem; I < S; ++I)
1050  OS << '\0';
1051  }
1052  auto *FilenamesAndMappingsVal =
1053  llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
1054 
1055  // Create the deferred function records array
1056  auto RecordsTy =
1057  llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1058  auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1059 
1060  llvm::Type *CovDataHeaderTypes[] = {
1061 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1062 #include "llvm/ProfileData/InstrProfData.inc"
1063  };
1064  auto CovDataHeaderTy =
1065  llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1066  llvm::Constant *CovDataHeaderVals[] = {
1067 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1068 #include "llvm/ProfileData/InstrProfData.inc"
1069  };
1070  auto CovDataHeaderVal = llvm::ConstantStruct::get(
1071  CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1072 
1073  // Create the coverage data record
1074  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1075  FilenamesAndMappingsVal->getType()};
1076  auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1077  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1078  FilenamesAndMappingsVal};
1079  auto CovDataVal =
1080  llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1081  auto CovData = new llvm::GlobalVariable(
1082  CGM.getModule(), CovDataTy, true, llvm::GlobalValue::InternalLinkage,
1083  CovDataVal, llvm::getCoverageMappingVarName());
1084 
1085  CovData->setSection(getCoverageSection(CGM));
1086  CovData->setAlignment(8);
1087 
1088  // Make sure the data doesn't get deleted.
1089  CGM.addUsedGlobal(CovData);
1090  // Create the deferred function records array
1091  if (!FunctionNames.empty()) {
1092  auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1093  FunctionNames.size());
1094  auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1095  // This variable will *NOT* be emitted to the object file. It is used
1096  // to pass the list of names referenced to codegen.
1097  new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true,
1099  llvm::getCoverageUnusedNamesVarName());
1100  }
1101 }
1102 
1104  auto It = FileEntries.find(File);
1105  if (It != FileEntries.end())
1106  return It->second;
1107  unsigned FileID = FileEntries.size();
1108  FileEntries.insert(std::make_pair(File, FileID));
1109  return FileID;
1110 }
1111 
1113  llvm::raw_ostream &OS) {
1114  assert(CounterMap);
1115  CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts);
1116  Walker.VisitDecl(D);
1117  Walker.write(OS);
1118 }
1119 
1121  llvm::raw_ostream &OS) {
1122  EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
1123  Walker.VisitDecl(D);
1124  Walker.write(OS);
1125 }
Expr * getInc()
Definition: Stmt.h:1187
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
bool isMacroID() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:187
Expr * getCond()
Definition: Stmt.h:1075
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
CXXCatchStmt * getHandler(unsigned i)
Definition: StmtCXX.h:104
IfStmt - This represents an if/then/else.
Definition: Stmt.h:881
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static bool isMachO(const CodeGenModule &CGM)
const Stmt * getElse() const
Definition: Stmt.h:921
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:913
void emit()
Emit the coverage mapping data for a translation unit.
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:789
Stmt * getBody()
Definition: Stmt.h:1123
void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, uint64_t FunctionHash, const std::string &CoverageMapping, bool IsUsed=true)
Add a function's coverage mapping record to the collection of the function mapping records...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
Expr * getLHS() const
Definition: Expr.h:2943
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:1153
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
Expr * getTrueExpr() const
Definition: Expr.h:3326
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Stmt * getHandlerBlock() const
Definition: StmtCXX.h:52
Stmt * getBody()
Definition: Stmt.h:1188
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2897
Stmt * getInit()
Definition: Stmt.h:1167
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:128
Expr * getCond()
Definition: Stmt.h:1186
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1503
detail::InMemoryDirectory::const_iterator I
bool isInvalid() const
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
const TargetInfo & getTarget() const
const SmallVectorImpl< AnnotatedLine * >::const_iterator End
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...
int * Depth
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer...
Expr - This represents one expression.
Definition: Expr.h:105
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
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:406
Organizes the cross-function state that is used while generating code coverage mapping data...
const char * getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
Stmt * getBody()
Definition: Stmt.h:1078
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:65
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1366
const SourceManager & SM
Definition: Format.cpp:1184
unsigned getFileID(const FileEntry *File)
Return the coverage mapping translation unit file id for the given file.
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:1102
The l-value was considered opaque, so the alignment was determined from a type.
static StringRef getCoverageSection(const CodeGenModule &CGM)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
const Expr * getCond() const
Definition: Stmt.h:994
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void SourceRangeSkipped(SourceRange Range) override
Hook called when a source range is skipped.
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.
const Expr * getSubExpr() const
Definition: ExprCXX.h:933
const Stmt * getBody() const
Definition: Stmt.h:995
std::pair< SourceLocation, SourceLocation > getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
unsigned getNumHandlers() const
Definition: StmtCXX.h:103
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
detail::InMemoryDirectory::const_iterator E
const Expr * getRetValue() const
Definition: Stmt.cpp:899
const Stmt * getThen() const
Definition: Stmt.h:919
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:957
Expr * getFalseExpr() const
Definition: Expr.h:3332
Represents Objective-C's collection statement.
Definition: StmtObjC.h:24
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:3128
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:33
Stmt * getSubStmt()
Definition: Stmt.cpp:856
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
DeclStmt * getRangeStmt()
Definition: StmtCXX.h:154
GotoStmt - This represents a direct goto.
Definition: Stmt.h:1224
Expr * getCond()
Definition: Stmt.h:1120
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...
BoundNodesTreeBuilder *const Builder
ContinueStmt - This represents a continue.
Definition: Stmt.h:1302
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:29
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:1047
const Expr * getCond() const
Definition: Stmt.h:917
CompoundStmt * getTryBlock()
Definition: StmtCXX.h:96
Expr * getRHS() const
Definition: Expr.h:2945
BreakStmt - This represents a break.
Definition: Stmt.h:1328
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
Stmt * getSubStmt()
Definition: Stmt.h:809
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
DeclStmt * getLoopVarStmt()
Definition: StmtCXX.h:161
A trivial tuple used to represent a source range.
bool isValid() const
void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data for an unused function.
This class handles loading and caching of source files into memory.