Bug Summary

File:tools/clang/lib/CodeGen/CoverageMappingGen.cpp
Warning:line 201, column 26
Called C++ object pointer is null

Annotated Source Code

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