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