blob: 9900ebc014e8de48d763e69d9f34bc78d650641c [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"
18#include "llvm/ProfileData/InstrProfReader.h"
19#include "llvm/ProfileData/CoverageMapping.h"
20#include "llvm/ProfileData/CoverageMappingWriter.h"
Alex Lorenzf2cf38e2014-08-08 23:41:24 +000021#include "llvm/ProfileData/CoverageMappingReader.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
120/// \brief The state of the coverage mapping builder.
121struct SourceMappingState {
122 Counter CurrentRegionCount;
123 const Stmt *CurrentSourceGroup;
124 const Stmt *CurrentUnreachableRegionInitiator;
125
126 SourceMappingState(Counter CurrentRegionCount, const Stmt *CurrentSourceGroup,
127 const Stmt *CurrentUnreachableRegionInitiator)
128 : CurrentRegionCount(CurrentRegionCount),
129 CurrentSourceGroup(CurrentSourceGroup),
130 CurrentUnreachableRegionInitiator(CurrentUnreachableRegionInitiator) {}
131};
132
133/// \brief Provides the common functionality for the different
134/// coverage mapping region builders.
135class CoverageMappingBuilder {
136public:
137 CoverageMappingModuleGen &CVM;
138 SourceManager &SM;
139 const LangOptions &LangOpts;
140
141private:
142 struct FileInfo {
143 /// \brief The file id that will be used by the coverage mapping system.
144 unsigned CovMappingFileID;
145 const FileEntry *Entry;
146
147 FileInfo(unsigned CovMappingFileID, const FileEntry *Entry)
148 : CovMappingFileID(CovMappingFileID), Entry(Entry) {}
149 };
150
151 /// \brief This mapping maps clang's FileIDs to file ids used
152 /// by the coverage mapping system and clang's file entries.
153 llvm::SmallDenseMap<FileID, FileInfo, 8> FileIDMapping;
154
155public:
156 /// \brief The statement that corresponds to the current source group.
157 const Stmt *CurrentSourceGroup;
158
159 /// \brief The statement the initiated the current unreachable region.
160 const Stmt *CurrentUnreachableRegionInitiator;
161
162 /// \brief The coverage mapping regions for this function
163 llvm::SmallVector<CounterMappingRegion, 32> MappingRegions;
164 /// \brief The source mapping regions for this function.
Justin Bognerf59329b2014-10-01 03:33:52 +0000165 std::vector<SourceMappingRegion> SourceRegions;
Alex Lorenzee024992014-08-04 18:41:51 +0000166
167 CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
168 const LangOptions &LangOpts)
169 : CVM(CVM), SM(SM), LangOpts(LangOpts),
170 CurrentSourceGroup(nullptr),
171 CurrentUnreachableRegionInitiator(nullptr) {}
172
173 /// \brief Return the precise end location for the given token.
174 SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
175 return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM, LangOpts);
176 }
177
178 /// \brief Create the mapping that maps from the function's file ids to
179 /// the indices for the translation unit's filenames.
180 void createFileIDMapping(SmallVectorImpl<unsigned> &Mapping) {
181 Mapping.resize(FileIDMapping.size(), 0);
182 for (const auto &I : FileIDMapping)
183 Mapping[I.second.CovMappingFileID] = CVM.getFileID(I.second.Entry);
184 }
185
186 /// \brief Get the coverage mapping file id that corresponds to the given
187 /// clang file id. If such file id doesn't exist, it gets added to the
188 /// mapping that maps from clang's file ids to coverage mapping file ids.
189 /// Return true if there was an error getting the coverage mapping file id.
190 /// An example of an when this function fails is when the region tries
191 /// to get a coverage file id for a location in a built-in macro.
192 bool getCoverageFileID(SourceLocation LocStart, FileID File,
193 FileID SpellingFile, unsigned &Result) {
194 auto Mapping = FileIDMapping.find(File);
195 if (Mapping != FileIDMapping.end()) {
196 Result = Mapping->second.CovMappingFileID;
197 return false;
198 }
199
200 auto Entry = SM.getFileEntryForID(SpellingFile);
201 if (!Entry)
202 return true;
203
204 Result = FileIDMapping.size();
205 FileIDMapping.insert(std::make_pair(File, FileInfo(Result, Entry)));
206 createFileExpansionRegion(LocStart, File);
207 return false;
208 }
209
210 /// \brief Get the coverage mapping file id that corresponds to the given
211 /// clang file id.
212 /// Return true if there was an error getting the coverage mapping file id.
213 bool getExistingCoverageFileID(FileID File, unsigned &Result) {
214 // Make sure that the file is valid.
215 if (File.isInvalid())
216 return true;
217 auto Mapping = FileIDMapping.find(File);
218 if (Mapping != FileIDMapping.end()) {
219 Result = Mapping->second.CovMappingFileID;
220 return false;
221 }
222 return true;
223 }
224
225 /// \brief Return true if the given clang's file id has a corresponding
226 /// coverage file id.
227 bool hasExistingCoverageFileID(FileID File) const {
228 return FileIDMapping.count(File);
229 }
230
231 /// \brief Gather all the regions that were skipped by the preprocessor
232 /// using the constructs like #if.
233 void gatherSkippedRegions() {
234 /// An array of the minimum lineStarts and the maximum lineEnds
235 /// for mapping regions from the appropriate source files.
236 llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges;
237 FileLineRanges.resize(
238 FileIDMapping.size(),
239 std::make_pair(std::numeric_limits<unsigned>::max(), 0));
240 for (const auto &R : MappingRegions) {
241 FileLineRanges[R.FileID].first =
242 std::min(FileLineRanges[R.FileID].first, R.LineStart);
243 FileLineRanges[R.FileID].second =
244 std::max(FileLineRanges[R.FileID].second, R.LineEnd);
245 }
246
247 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
248 for (const auto &I : SkippedRanges) {
249 auto LocStart = I.getBegin();
250 auto LocEnd = I.getEnd();
251 auto FileStart = SM.getFileID(LocStart);
252 if (!hasExistingCoverageFileID(FileStart))
253 continue;
254 auto ActualFileStart = SM.getDecomposedSpellingLoc(LocStart).first;
255 if (ActualFileStart != SM.getDecomposedSpellingLoc(LocEnd).first)
256 // Ignore regions that span across multiple files.
257 continue;
258
259 unsigned CovFileID;
260 if (getCoverageFileID(LocStart, FileStart, ActualFileStart, CovFileID))
261 continue;
262 unsigned LineStart = SM.getSpellingLineNumber(LocStart);
263 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
264 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
265 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
266 CounterMappingRegion Region(Counter(), CovFileID, LineStart, ColumnStart,
267 LineEnd, ColumnEnd, false,
268 CounterMappingRegion::SkippedRegion);
269 // Make sure that we only collect the regions that are inside
270 // the souce code of this function.
271 if (Region.LineStart >= FileLineRanges[CovFileID].first &&
272 Region.LineEnd <= FileLineRanges[CovFileID].second)
273 MappingRegions.push_back(Region);
274 }
275 }
276
277 /// \brief Create a mapping region that correponds to an expansion of
278 /// a macro or an embedded include.
279 void createFileExpansionRegion(SourceLocation Loc, FileID ExpandedFile) {
280 SourceLocation LocStart;
281 if (Loc.isMacroID())
282 LocStart = SM.getImmediateExpansionRange(Loc).first;
283 else {
284 LocStart = SM.getIncludeLoc(ExpandedFile);
285 if (LocStart.isInvalid())
286 return; // This file has no expansion region.
287 }
288
289 auto File = SM.getFileID(LocStart);
290 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first;
291 unsigned CovFileID, ExpandedFileID;
292 if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID))
293 return;
294 if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID))
295 return;
296 unsigned LineStart = SM.getSpellingLineNumber(LocStart);
297 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
298 unsigned LineEnd = LineStart;
299 // Compute the end column manually as Lexer::getLocForEndOfToken doesn't
300 // give the correct result in all cases.
301 unsigned ColumnEnd =
302 ColumnStart +
303 Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM, LangOpts);
304
305 MappingRegions.push_back(CounterMappingRegion(
306 Counter(), CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd,
307 false, CounterMappingRegion::ExpansionRegion));
308 MappingRegions.back().ExpandedFileID = ExpandedFileID;
309 }
310
311 /// \brief Enter a source region group that is identified by the given
312 /// statement.
313 /// It's not possible to enter a group when there is already
314 /// another group present.
315 void beginSourceRegionGroup(const Stmt *Group) {
316 assert(!CurrentSourceGroup);
317 CurrentSourceGroup = Group;
318 }
319
320 /// \brief Exit the current source region group.
321 void endSourceRegionGroup() { CurrentSourceGroup = nullptr; }
322
Alex Lorenzee024992014-08-04 18:41:51 +0000323 /// \brief Associate a counter with a given source code range.
324 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd,
325 Counter Count, const Stmt *UnreachableInitiator,
326 const Stmt *SourceGroup, unsigned Flags = 0,
327 FileID MacroArgumentFile = FileID()) {
328 if (SM.isMacroArgExpansion(LocStart)) {
329 // Map the code range with the macro argument's value.
330 mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart),
331 SM.getImmediateSpellingLoc(LocEnd), Count,
332 UnreachableInitiator, SourceGroup, Flags,
333 SM.getFileID(LocStart));
334 // Map the code range where the macro argument is referenced.
335 SourceLocation RefLocStart(SM.getImmediateExpansionRange(LocStart).first);
336 SourceLocation RefLocEnd(RefLocStart);
337 if (SM.isMacroArgExpansion(RefLocStart))
338 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator,
339 SourceGroup, 0, SM.getFileID(RefLocStart));
340 else
341 mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator,
342 SourceGroup);
343 return;
344 }
345 auto File = SM.getFileID(LocStart);
346 // Make sure that the file id is valid.
347 if (File.isInvalid())
348 return;
Justin Bognerf59329b2014-10-01 03:33:52 +0000349 SourceRegions.emplace_back(File, MacroArgumentFile, Count,
350 UnreachableInitiator, SourceGroup, LocStart,
351 LocEnd, Flags);
Alex Lorenzee024992014-08-04 18:41:51 +0000352 }
353
354 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd,
355 Counter Count, unsigned Flags = 0) {
356 mapSourceCodeRange(LocStart, LocEnd, Count,
357 CurrentUnreachableRegionInitiator, CurrentSourceGroup,
358 Flags);
359 }
360
361 void mapSourceCodeRange(const SourceMappingState &State,
362 SourceLocation LocStart, SourceLocation LocEnd,
363 unsigned Flags = 0) {
364 mapSourceCodeRange(LocStart, LocEnd, State.CurrentRegionCount,
365 State.CurrentUnreachableRegionInitiator,
366 State.CurrentSourceGroup, Flags);
367 }
368
369 /// \brief Generate the coverage counter mapping regions from collected
370 /// source regions.
371 void emitSourceRegions() {
Justin Bognerf59329b2014-10-01 03:33:52 +0000372 std::sort(SourceRegions.begin(), SourceRegions.end());
Alex Lorenzee024992014-08-04 18:41:51 +0000373
Justin Bognerf59329b2014-10-01 03:33:52 +0000374 for (auto I = SourceRegions.begin(), E = SourceRegions.end(); I != E; ++I) {
375 // Keep the original start location of this region.
376 SourceLocation LocStart = I->getStartLoc();
377 SourceLocation LocEnd = I->getEndLoc(SM);
378
379 bool Ignore = I->hasFlag(SourceMappingRegion::IgnoreIfNotExtended);
380 // We need to handle mergeable regions together.
381 for (auto Next = I + 1; Next != E && Next->isMergeable(*I); ++Next) {
382 ++I;
383 LocStart = std::min(LocStart, I->getStartLoc());
384 LocEnd = std::max(LocEnd, I->getEndLoc(SM));
385 // FIXME: Should we && together the Ignore flag of multiple regions?
386 Ignore = false;
387 }
388 if (Ignore)
Alex Lorenzee024992014-08-04 18:41:51 +0000389 continue;
390
Justin Bognerf59329b2014-10-01 03:33:52 +0000391 // Find the spilling locations for the mapping region.
Alex Lorenzee024992014-08-04 18:41:51 +0000392 LocEnd = getPreciseTokenLocEnd(LocEnd);
393 unsigned LineStart = SM.getSpellingLineNumber(LocStart);
394 unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
395 unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
396 unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
397
Justin Bogner09c71792014-10-01 03:33:49 +0000398 auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first;
Alex Lorenzee024992014-08-04 18:41:51 +0000399 unsigned CovFileID;
Justin Bognerf59329b2014-10-01 03:33:52 +0000400 if (getCoverageFileID(LocStart, I->getFile(), SpellingFile, CovFileID))
Alex Lorenzee024992014-08-04 18:41:51 +0000401 continue;
402
403 assert(LineStart <= LineEnd);
404 MappingRegions.push_back(CounterMappingRegion(
Justin Bognerf59329b2014-10-01 03:33:52 +0000405 I->getCounter(), CovFileID, LineStart, ColumnStart, LineEnd,
406 ColumnEnd, false, CounterMappingRegion::CodeRegion));
Alex Lorenzee024992014-08-04 18:41:51 +0000407 }
408 }
409};
410
411/// \brief Creates unreachable coverage regions for the functions that
412/// are not emitted.
413struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
414 EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
415 const LangOptions &LangOpts)
416 : CoverageMappingBuilder(CVM, SM, LangOpts) {}
417
418 void VisitDecl(const Decl *D) {
419 if (!D->hasBody())
420 return;
421 auto Body = D->getBody();
422 mapSourceCodeRange(Body->getLocStart(), Body->getLocEnd(), Counter());
423 }
424
425 /// \brief Write the mapping data to the output stream
426 void write(llvm::raw_ostream &OS) {
427 emitSourceRegions();
428 SmallVector<unsigned, 16> FileIDMapping;
429 createFileIDMapping(FileIDMapping);
430
Craig Topper5fc8fc22014-08-27 06:28:36 +0000431 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
Alex Lorenzee024992014-08-04 18:41:51 +0000432 Writer.write(OS);
433 }
434};
435
436/// \brief A StmtVisitor that creates coverage mapping regions which map
437/// from the source code locations to the PGO counters.
438struct CounterCoverageMappingBuilder
439 : public CoverageMappingBuilder,
440 public ConstStmtVisitor<CounterCoverageMappingBuilder> {
441 /// \brief The map of statements to count values.
442 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
443
444 Counter CurrentRegionCount;
445
446 CounterExpressionBuilder Builder;
447
448 /// \brief Return a counter that represents the
449 /// expression that subracts rhs from lhs.
450 Counter subtractCounters(Counter LHS, Counter RHS) {
451 return Builder.subtract(LHS, RHS);
452 }
453
454 /// \brief Return a counter that represents the
455 /// the exression that adds lhs and rhs.
456 Counter addCounters(Counter LHS, Counter RHS) {
457 return Builder.add(LHS, RHS);
458 }
459
460 /// \brief Return the region counter for the given statement.
461 /// This should only be called on statements that have a dedicated counter.
462 unsigned getRegionCounter(const Stmt *S) { return CounterMap[S]; }
463
464 /// \brief Return the region count for the counter at the given index.
465 Counter getRegionCount(unsigned CounterId) {
466 return Counter::getCounter(CounterId);
467 }
468
469 /// \brief Return the counter value of the current region.
470 Counter getCurrentRegionCount() { return CurrentRegionCount; }
471
472 /// \brief Set the counter value for the current region.
473 /// This is used to keep track of changes to the most recent counter
474 /// from control flow and non-local exits.
475 void setCurrentRegionCount(Counter Count) {
476 CurrentRegionCount = Count;
477 CurrentUnreachableRegionInitiator = nullptr;
478 }
479
480 /// \brief Indicate that the current region is never reached,
481 /// and thus should have a counter value of zero.
482 /// This is important so that subsequent regions can correctly track
483 /// their parent counts.
484 void setCurrentRegionUnreachable(const Stmt *Initiator) {
485 CurrentRegionCount = Counter::getZero();
486 CurrentUnreachableRegionInitiator = Initiator;
487 }
488
489 /// \brief A counter for a particular region.
490 /// This is the primary interface through
491 /// which the coverage mapping builder manages counters and their values.
492 class RegionMapper {
493 CounterCoverageMappingBuilder &Mapping;
494 Counter Count;
495 Counter ParentCount;
496 Counter RegionCount;
497 Counter Adjust;
498
499 public:
500 RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt *S)
501 : Mapping(*Mapper),
502 Count(Mapper->getRegionCount(Mapper->getRegionCounter(S))),
503 ParentCount(Mapper->getCurrentRegionCount()) {}
504
505 /// Get the value of the counter. In most cases this is the number of times
506 /// the region of the counter was entered, but for switch labels it's the
507 /// number of direct jumps to that label.
508 Counter getCount() const { return Count; }
509
510 /// Get the value of the counter with adjustments applied. Adjustments occur
511 /// when control enters or leaves the region abnormally; i.e., if there is a
512 /// jump to a label within the region, or if the function can return from
513 /// within the region. The adjusted count, then, is the value of the counter
514 /// at the end of the region.
515 Counter getAdjustedCount() const {
516 return Mapping.addCounters(Count, Adjust);
517 }
518
519 /// Get the value of the counter in this region's parent, i.e., the region
520 /// that was active when this region began. This is useful for deriving
521 /// counts in implicitly counted regions, like the false case of a condition
522 /// or the normal exits of a loop.
523 Counter getParentCount() const { return ParentCount; }
524
525 /// Activate the counter by emitting an increment and starting to track
526 /// adjustments. If AddIncomingFallThrough is true, the current region count
527 /// will be added to the counter for the purposes of tracking the region.
528 void beginRegion(bool AddIncomingFallThrough = false) {
529 RegionCount = Count;
530 if (AddIncomingFallThrough)
531 RegionCount =
532 Mapping.addCounters(RegionCount, Mapping.getCurrentRegionCount());
533 Mapping.setCurrentRegionCount(RegionCount);
534 }
535
536 /// For counters on boolean branches, begins tracking adjustments for the
537 /// uncounted path.
538 void beginElseRegion() {
539 RegionCount = Mapping.subtractCounters(ParentCount, Count);
540 Mapping.setCurrentRegionCount(RegionCount);
541 }
542
543 /// Reset the current region count.
544 void setCurrentRegionCount(Counter CurrentCount) {
545 RegionCount = CurrentCount;
546 Mapping.setCurrentRegionCount(RegionCount);
547 }
548
549 /// Adjust for non-local control flow after emitting a subexpression or
550 /// substatement. This must be called to account for constructs such as
551 /// gotos,
552 /// labels, and returns, so that we can ensure that our region's count is
553 /// correct in the code that follows.
554 void adjustForControlFlow() {
555 Adjust = Mapping.addCounters(
556 Adjust, Mapping.subtractCounters(Mapping.getCurrentRegionCount(),
557 RegionCount));
558 // Reset the region count in case this is called again later.
559 RegionCount = Mapping.getCurrentRegionCount();
560 }
561
562 /// Commit all adjustments to the current region. If the region is a loop,
563 /// the LoopAdjust value should be the count of all the breaks and continues
564 /// from the loop, to compensate for those counts being deducted from the
565 /// adjustments for the body of the loop.
566 void applyAdjustmentsToRegion() {
567 Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount, Adjust));
568 }
569 void applyAdjustmentsToRegion(Counter LoopAdjust) {
570 Mapping.setCurrentRegionCount(Mapping.addCounters(
571 Mapping.addCounters(ParentCount, Adjust), LoopAdjust));
572 }
573 };
574
575 /// \brief Keep counts of breaks and continues inside loops.
576 struct BreakContinue {
577 Counter BreakCount;
578 Counter ContinueCount;
579 };
580 SmallVector<BreakContinue, 8> BreakContinueStack;
581
582 CounterCoverageMappingBuilder(
583 CoverageMappingModuleGen &CVM,
Justin Bognere5ee6c52014-10-02 16:44:01 +0000584 llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
Alex Lorenzee024992014-08-04 18:41:51 +0000585 const LangOptions &LangOpts)
Justin Bognere5ee6c52014-10-02 16:44:01 +0000586 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
Alex Lorenzee024992014-08-04 18:41:51 +0000587
588 /// \brief Write the mapping data to the output stream
589 void write(llvm::raw_ostream &OS) {
590 emitSourceRegions();
591 llvm::SmallVector<unsigned, 8> VirtualFileMapping;
592 createFileIDMapping(VirtualFileMapping);
593 gatherSkippedRegions();
594
595 CoverageMappingWriter Writer(
596 VirtualFileMapping, Builder.getExpressions(), MappingRegions);
597 Writer.write(OS);
598 }
599
600 /// \brief Return the current source mapping state.
601 SourceMappingState getCurrentState() const {
602 return SourceMappingState(CurrentRegionCount, CurrentSourceGroup,
603 CurrentUnreachableRegionInitiator);
604 }
605
606 /// \brief Associate the source code range with the current region count.
607 void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd,
608 unsigned Flags = 0) {
609 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd,
610 CurrentRegionCount, Flags);
611 }
612
613 void mapSourceCodeRange(SourceLocation LocStart) {
614 CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart,
615 CurrentRegionCount);
616 }
617
618 /// \brief Associate the source range of a token with the current region
619 /// count.
620 /// Ignore the source range for this token if it produces a distinct
621 /// mapping region with no other source ranges.
622 void mapToken(SourceLocation LocStart) {
623 CoverageMappingBuilder::mapSourceCodeRange(
624 LocStart, LocStart, CurrentRegionCount,
625 SourceMappingRegion::IgnoreIfNotExtended);
626 }
627
628 void mapToken(const SourceMappingState &State, SourceLocation LocStart) {
629 CoverageMappingBuilder::mapSourceCodeRange(
630 State, LocStart, LocStart, SourceMappingRegion::IgnoreIfNotExtended);
631 }
632
633 void VisitStmt(const Stmt *S) {
634 mapSourceCodeRange(S->getLocStart());
635 for (Stmt::const_child_range I = S->children(); I; ++I) {
636 if (*I)
637 this->Visit(*I);
638 }
639 }
640
641 /// \brief If the given statement is a compound statement,
642 /// map '}' with the same count as '{'.
643 void VisitSubStmtRBraceState(const Stmt *S) {
644 if (!isa<CompoundStmt>(S))
645 return Visit(S);
646 const auto *CS = cast<CompoundStmt>(S);
647 auto State = getCurrentState();
648 mapSourceCodeRange(CS->getLBracLoc());
649 for (Stmt::const_child_range I = S->children(); I; ++I) {
650 if (*I)
651 this->Visit(*I);
652 }
653 CoverageMappingBuilder::mapSourceCodeRange(State, CS->getRBracLoc(),
654 CS->getRBracLoc());
655 }
656
657 void VisitDecl(const Decl *D) {
658 if (!D->hasBody())
659 return;
660 // Counter tracks entry to the function body.
661 auto Body = D->getBody();
662 RegionMapper Cnt(this, Body);
663 Cnt.beginRegion();
664 VisitSubStmtRBraceState(Body);
665 }
666
667 void VisitDeclStmt(const DeclStmt *S) {
668 mapSourceCodeRange(S->getLocStart());
669 for (Stmt::const_child_range I = static_cast<const Stmt *>(S)->children();
670 I; ++I) {
671 if (*I)
672 this->Visit(*I);
673 }
674 }
675
676 void VisitCompoundStmt(const CompoundStmt *S) {
677 mapSourceCodeRange(S->getLBracLoc());
678 for (Stmt::const_child_range I = S->children(); I; ++I) {
679 if (*I)
680 this->Visit(*I);
681 }
682 mapSourceCodeRange(S->getRBracLoc(), S->getRBracLoc());
683 }
684
685 void VisitReturnStmt(const ReturnStmt *S) {
686 mapSourceCodeRange(S->getLocStart());
687 if (S->getRetValue())
688 Visit(S->getRetValue());
689 setCurrentRegionUnreachable(S);
690 }
691
692 void VisitGotoStmt(const GotoStmt *S) {
693 mapSourceCodeRange(S->getLocStart());
694 mapToken(S->getLabelLoc());
695 setCurrentRegionUnreachable(S);
696 }
697
698 void VisitLabelStmt(const LabelStmt *S) {
699 // Counter tracks the block following the label.
700 RegionMapper Cnt(this, S);
701 Cnt.beginRegion();
702 mapSourceCodeRange(S->getLocStart());
703 // Can't map the ':' token as its location isn't known.
704 Visit(S->getSubStmt());
705 }
706
707 void VisitBreakStmt(const BreakStmt *S) {
708 mapSourceCodeRange(S->getLocStart());
709 assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
710 BreakContinueStack.back().BreakCount = addCounters(
711 BreakContinueStack.back().BreakCount, getCurrentRegionCount());
712 setCurrentRegionUnreachable(S);
713 }
714
715 void VisitContinueStmt(const ContinueStmt *S) {
716 mapSourceCodeRange(S->getLocStart());
717 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
718 BreakContinueStack.back().ContinueCount = addCounters(
719 BreakContinueStack.back().ContinueCount, getCurrentRegionCount());
720 setCurrentRegionUnreachable(S);
721 }
722
723 void VisitWhileStmt(const WhileStmt *S) {
724 mapSourceCodeRange(S->getLocStart());
725 // Counter tracks the body of the loop.
726 RegionMapper Cnt(this, S);
727 BreakContinueStack.push_back(BreakContinue());
728 // Visit the body region first so the break/continue adjustments can be
729 // included when visiting the condition.
730 Cnt.beginRegion();
731 VisitSubStmtRBraceState(S->getBody());
732 Cnt.adjustForControlFlow();
733
734 // ...then go back and propagate counts through the condition. The count
735 // at the start of the condition is the sum of the incoming edges,
736 // the backedge from the end of the loop body, and the edges from
737 // continue statements.
738 BreakContinue BC = BreakContinueStack.pop_back_val();
739 Cnt.setCurrentRegionCount(
740 addCounters(Cnt.getParentCount(),
741 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount)));
742 beginSourceRegionGroup(S->getCond());
743 Visit(S->getCond());
744 endSourceRegionGroup();
745 Cnt.adjustForControlFlow();
746 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount));
747 }
748
749 void VisitDoStmt(const DoStmt *S) {
750 mapSourceCodeRange(S->getLocStart());
751 // Counter tracks the body of the loop.
752 RegionMapper Cnt(this, S);
753 BreakContinueStack.push_back(BreakContinue());
754 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
755 VisitSubStmtRBraceState(S->getBody());
756 Cnt.adjustForControlFlow();
757
758 BreakContinue BC = BreakContinueStack.pop_back_val();
759 // The count at the start of the condition is equal to the count at the
760 // end of the body. The adjusted count does not include either the
761 // fall-through count coming into the loop or the continue count, so add
762 // both of those separately. This is coincidentally the same equation as
763 // with while loops but for different reasons.
764 Cnt.setCurrentRegionCount(
765 addCounters(Cnt.getParentCount(),
766 addCounters(Cnt.getAdjustedCount(), BC.ContinueCount)));
767 Visit(S->getCond());
768 Cnt.adjustForControlFlow();
769 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount));
770 }
771
772 void VisitForStmt(const ForStmt *S) {
773 mapSourceCodeRange(S->getLocStart());
774 if (S->getInit())
775 Visit(S->getInit());
776
777 // Counter tracks the body of the loop.
778 RegionMapper Cnt(this, S);
779 BreakContinueStack.push_back(BreakContinue());
780 // Visit the body region first. (This is basically the same as a while
781 // loop; see further comments in VisitWhileStmt.)
782 Cnt.beginRegion();
783 VisitSubStmtRBraceState(S->getBody());
784 Cnt.adjustForControlFlow();
785
786 // The increment is essentially part of the body but it needs to include
787 // the count for all the continue statements.
788 if (S->getInc()) {
789 Cnt.setCurrentRegionCount(addCounters(
790 getCurrentRegionCount(), BreakContinueStack.back().ContinueCount));
791 beginSourceRegionGroup(S->getInc());
792 Visit(S->getInc());
793 endSourceRegionGroup();
794 Cnt.adjustForControlFlow();
795 }
796
797 BreakContinue BC = BreakContinueStack.pop_back_val();
798
799 // ...then go back and propagate counts through the condition.
800 if (S->getCond()) {
801 Cnt.setCurrentRegionCount(
802 addCounters(addCounters(Cnt.getParentCount(), Cnt.getAdjustedCount()),
803 BC.ContinueCount));
804 beginSourceRegionGroup(S->getCond());
805 Visit(S->getCond());
806 endSourceRegionGroup();
807 Cnt.adjustForControlFlow();
808 }
809 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount));
810 }
811
812 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
813 mapSourceCodeRange(S->getLocStart());
814 Visit(S->getRangeStmt());
815 Visit(S->getBeginEndStmt());
816 // Counter tracks the body of the loop.
817 RegionMapper Cnt(this, S);
818 BreakContinueStack.push_back(BreakContinue());
819 // Visit the body region first. (This is basically the same as a while
820 // loop; see further comments in VisitWhileStmt.)
821 Cnt.beginRegion();
822 VisitSubStmtRBraceState(S->getBody());
823 Cnt.adjustForControlFlow();
824 BreakContinue BC = BreakContinueStack.pop_back_val();
825 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount));
826 }
827
828 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
829 mapSourceCodeRange(S->getLocStart());
830 Visit(S->getElement());
831 // Counter tracks the body of the loop.
832 RegionMapper Cnt(this, S);
833 BreakContinueStack.push_back(BreakContinue());
Alex Lorenzfdd769e2014-08-20 17:11:53 +0000834 Cnt.beginRegion();
Alex Lorenzee024992014-08-04 18:41:51 +0000835 VisitSubStmtRBraceState(S->getBody());
836 BreakContinue BC = BreakContinueStack.pop_back_val();
837 Cnt.adjustForControlFlow();
838 Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, BC.ContinueCount));
839 }
840
841 void VisitSwitchStmt(const SwitchStmt *S) {
842 mapSourceCodeRange(S->getLocStart());
843 Visit(S->getCond());
844 BreakContinueStack.push_back(BreakContinue());
845 // Map the '}' for the body to have the same count as the regions after
846 // the switch.
847 SourceLocation RBracLoc;
848 if (const auto *CS = dyn_cast<CompoundStmt>(S->getBody())) {
849 mapSourceCodeRange(CS->getLBracLoc());
850 setCurrentRegionUnreachable(S);
851 for (Stmt::const_child_range I = CS->children(); I; ++I) {
852 if (*I)
853 this->Visit(*I);
854 }
855 RBracLoc = CS->getRBracLoc();
856 } else {
857 setCurrentRegionUnreachable(S);
858 Visit(S->getBody());
859 }
860 // If the switch is inside a loop, add the continue counts.
861 BreakContinue BC = BreakContinueStack.pop_back_val();
862 if (!BreakContinueStack.empty())
863 BreakContinueStack.back().ContinueCount = addCounters(
864 BreakContinueStack.back().ContinueCount, BC.ContinueCount);
865 // Counter tracks the exit block of the switch.
866 RegionMapper ExitCnt(this, S);
867 ExitCnt.beginRegion();
868 if (RBracLoc.isValid())
869 mapSourceCodeRange(RBracLoc);
870 }
871
872 void VisitCaseStmt(const CaseStmt *S) {
873 // Counter for this particular case. This counts only jumps from the
874 // switch header and does not include fallthrough from the case before
875 // this one.
876 RegionMapper Cnt(this, S);
877 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
878 mapSourceCodeRange(S->getLocStart());
879 mapToken(S->getColonLoc());
880 Visit(S->getSubStmt());
881 }
882
883 void VisitDefaultStmt(const DefaultStmt *S) {
884 // Counter for this default case. This does not include fallthrough from
885 // the previous case.
886 RegionMapper Cnt(this, S);
887 Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
888 mapSourceCodeRange(S->getLocStart());
889 mapToken(S->getColonLoc());
890 Visit(S->getSubStmt());
891 }
892
893 void VisitIfStmt(const IfStmt *S) {
894 mapSourceCodeRange(S->getLocStart());
895 Visit(S->getCond());
896 mapToken(S->getElseLoc());
897
898 // Counter tracks the "then" part of an if statement. The count for
899 // the "else" part, if it exists, will be calculated from this counter.
900 RegionMapper Cnt(this, S);
901 Cnt.beginRegion();
902 VisitSubStmtRBraceState(S->getThen());
903 Cnt.adjustForControlFlow();
904
905 if (S->getElse()) {
906 Cnt.beginElseRegion();
907 VisitSubStmtRBraceState(S->getElse());
908 Cnt.adjustForControlFlow();
909 }
910 Cnt.applyAdjustmentsToRegion();
911 }
912
913 void VisitCXXTryStmt(const CXXTryStmt *S) {
914 mapSourceCodeRange(S->getLocStart());
915 Visit(S->getTryBlock());
916 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
917 Visit(S->getHandler(I));
918 // Counter tracks the continuation block of the try statement.
919 RegionMapper Cnt(this, S);
920 Cnt.beginRegion();
921 }
922
923 void VisitCXXCatchStmt(const CXXCatchStmt *S) {
924 mapSourceCodeRange(S->getLocStart());
925 // Counter tracks the catch statement's handler block.
926 RegionMapper Cnt(this, S);
927 Cnt.beginRegion();
928 VisitSubStmtRBraceState(S->getHandlerBlock());
929 }
930
931 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
932 Visit(E->getCond());
933 mapToken(E->getQuestionLoc());
934 auto State = getCurrentState();
935
936 // Counter tracks the "true" part of a conditional operator. The
937 // count in the "false" part will be calculated from this counter.
938 RegionMapper Cnt(this, E);
939 Cnt.beginRegion();
940 Visit(E->getTrueExpr());
941 Cnt.adjustForControlFlow();
942
943 mapToken(State, E->getColonLoc());
944
945 Cnt.beginElseRegion();
946 Visit(E->getFalseExpr());
947 Cnt.adjustForControlFlow();
948
949 Cnt.applyAdjustmentsToRegion();
950 }
951
952 void VisitBinLAnd(const BinaryOperator *E) {
953 Visit(E->getLHS());
954 mapToken(E->getOperatorLoc());
955 // Counter tracks the right hand side of a logical and operator.
956 RegionMapper Cnt(this, E);
957 Cnt.beginRegion();
958 Visit(E->getRHS());
959 Cnt.adjustForControlFlow();
960 Cnt.applyAdjustmentsToRegion();
961 }
962
963 void VisitBinLOr(const BinaryOperator *E) {
964 Visit(E->getLHS());
965 mapToken(E->getOperatorLoc());
966 // Counter tracks the right hand side of a logical or operator.
967 RegionMapper Cnt(this, E);
968 Cnt.beginRegion();
969 Visit(E->getRHS());
970 Cnt.adjustForControlFlow();
971 Cnt.applyAdjustmentsToRegion();
972 }
973
974 void VisitParenExpr(const ParenExpr *E) {
975 mapToken(E->getLParen());
976 Visit(E->getSubExpr());
977 mapToken(E->getRParen());
978 }
979
980 void VisitBinaryOperator(const BinaryOperator *E) {
981 Visit(E->getLHS());
982 mapToken(E->getOperatorLoc());
983 Visit(E->getRHS());
984 }
985
986 void VisitUnaryOperator(const UnaryOperator *E) {
987 bool Postfix = E->isPostfix();
988 if (!Postfix)
989 mapToken(E->getOperatorLoc());
990 Visit(E->getSubExpr());
991 if (Postfix)
992 mapToken(E->getOperatorLoc());
993 }
994
995 void VisitMemberExpr(const MemberExpr *E) {
996 Visit(E->getBase());
997 mapToken(E->getMemberLoc());
998 }
999
1000 void VisitCallExpr(const CallExpr *E) {
1001 Visit(E->getCallee());
1002 for (const auto &Arg : E->arguments())
1003 Visit(Arg);
1004 mapToken(E->getRParenLoc());
1005 }
1006
1007 void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
1008 Visit(E->getLHS());
1009 Visit(E->getRHS());
1010 mapToken(E->getRBracketLoc());
1011 }
1012
1013 void VisitCStyleCastExpr(const CStyleCastExpr *E) {
1014 mapToken(E->getLParenLoc());
1015 mapToken(E->getRParenLoc());
1016 Visit(E->getSubExpr());
1017 }
1018
1019 // Map literals as tokens so that the macros like #define PI 3.14
1020 // won't generate coverage mapping regions.
1021
1022 void VisitIntegerLiteral(const IntegerLiteral *E) {
1023 mapToken(E->getLocStart());
1024 }
1025
1026 void VisitFloatingLiteral(const FloatingLiteral *E) {
1027 mapToken(E->getLocStart());
1028 }
1029
1030 void VisitCharacterLiteral(const CharacterLiteral *E) {
1031 mapToken(E->getLocStart());
1032 }
1033
1034 void VisitStringLiteral(const StringLiteral *E) {
1035 mapToken(E->getLocStart());
1036 }
1037
1038 void VisitImaginaryLiteral(const ImaginaryLiteral *E) {
1039 mapToken(E->getLocStart());
1040 }
Alex Lorenz01a0d062014-08-20 17:10:56 +00001041
1042 void VisitObjCMessageExpr(const ObjCMessageExpr *E) {
1043 mapToken(E->getLeftLoc());
1044 for (Stmt::const_child_range I = static_cast<const Stmt*>(E)->children(); I;
1045 ++I) {
1046 if (*I)
1047 this->Visit(*I);
1048 }
1049 mapToken(E->getRightLoc());
1050 }
Alex Lorenzee024992014-08-04 18:41:51 +00001051};
1052}
1053
1054static bool isMachO(const CodeGenModule &CGM) {
1055 return CGM.getTarget().getTriple().isOSBinFormatMachO();
1056}
1057
1058static StringRef getCoverageSection(const CodeGenModule &CGM) {
1059 return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap";
1060}
1061
Alex Lorenzf2cf38e2014-08-08 23:41:24 +00001062static void dump(llvm::raw_ostream &OS, const CoverageMappingRecord &Function) {
1063 OS << Function.FunctionName << ":\n";
1064 CounterMappingContext Ctx(Function.Expressions);
1065 for (const auto &R : Function.MappingRegions) {
1066 OS.indent(2);
1067 switch (R.Kind) {
1068 case CounterMappingRegion::CodeRegion:
1069 break;
1070 case CounterMappingRegion::ExpansionRegion:
1071 OS << "Expansion,";
1072 break;
1073 case CounterMappingRegion::SkippedRegion:
1074 OS << "Skipped,";
1075 break;
1076 }
1077
1078 OS << "File " << R.FileID << ", " << R.LineStart << ":"
1079 << R.ColumnStart << " -> " << R.LineEnd << ":" << R.ColumnEnd
1080 << " = ";
1081 Ctx.dump(R.Count);
1082 OS << " (HasCodeBefore = " << R.HasCodeBefore;
1083 if (R.Kind == CounterMappingRegion::ExpansionRegion)
1084 OS << ", Expanded file = " << R.ExpandedFileID;
1085
1086 OS << ")\n";
1087 }
1088}
1089
Alex Lorenzee024992014-08-04 18:41:51 +00001090void CoverageMappingModuleGen::addFunctionMappingRecord(
Alex Lorenzf2cf38e2014-08-08 23:41:24 +00001091 llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue,
Alex Lorenz1d45c5b2014-08-21 19:25:27 +00001092 uint64_t FunctionHash, const std::string &CoverageMapping) {
Alex Lorenzee024992014-08-04 18:41:51 +00001093 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1094 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
Alex Lorenz1d45c5b2014-08-21 19:25:27 +00001095 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
Alex Lorenzee024992014-08-04 18:41:51 +00001096 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
1097 if (!FunctionRecordTy) {
Alex Lorenz1d45c5b2014-08-21 19:25:27 +00001098 llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty, Int64Ty};
Alex Lorenzee024992014-08-04 18:41:51 +00001099 FunctionRecordTy =
1100 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes));
1101 }
1102
1103 llvm::Constant *FunctionRecordVals[] = {
1104 llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy),
Alex Lorenzf2cf38e2014-08-08 23:41:24 +00001105 llvm::ConstantInt::get(Int32Ty, FunctionNameValue.size()),
Alex Lorenz1d45c5b2014-08-21 19:25:27 +00001106 llvm::ConstantInt::get(Int32Ty, CoverageMapping.size()),
1107 llvm::ConstantInt::get(Int64Ty, FunctionHash)};
Alex Lorenzee024992014-08-04 18:41:51 +00001108 FunctionRecords.push_back(llvm::ConstantStruct::get(
1109 FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
1110 CoverageMappings += CoverageMapping;
Alex Lorenzf2cf38e2014-08-08 23:41:24 +00001111
1112 if (CGM.getCodeGenOpts().DumpCoverageMapping) {
1113 // Dump the coverage mapping data for this function by decoding the
1114 // encoded data. This allows us to dump the mapping regions which were
1115 // also processed by the CoverageMappingWriter which performs
1116 // additional minimization operations such as reducing the number of
1117 // expressions.
1118 std::vector<StringRef> Filenames;
1119 std::vector<CounterExpression> Expressions;
1120 std::vector<CounterMappingRegion> Regions;
1121 llvm::SmallVector<StringRef, 16> FilenameRefs;
1122 FilenameRefs.resize(FileEntries.size());
1123 for (const auto &Entry : FileEntries)
1124 FilenameRefs[Entry.second] = Entry.first->getName();
1125 RawCoverageMappingReader Reader(FunctionNameValue, CoverageMapping,
1126 FilenameRefs,
1127 Filenames, Expressions, Regions);
1128 CoverageMappingRecord FunctionRecord;
1129 if (Reader.read(FunctionRecord))
1130 return;
1131 dump(llvm::outs(), FunctionRecord);
1132 }
Alex Lorenzee024992014-08-04 18:41:51 +00001133}
1134
1135void CoverageMappingModuleGen::emit() {
1136 if (FunctionRecords.empty())
1137 return;
1138 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1139 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1140
1141 // Create the filenames and merge them with coverage mappings
1142 llvm::SmallVector<std::string, 16> FilenameStrs;
1143 llvm::SmallVector<StringRef, 16> FilenameRefs;
1144 FilenameStrs.resize(FileEntries.size());
1145 FilenameRefs.resize(FileEntries.size());
1146 for (const auto &Entry : FileEntries) {
1147 llvm::SmallString<256> Path(Entry.first->getName());
1148 llvm::sys::fs::make_absolute(Path);
1149
1150 auto I = Entry.second;
1151 FilenameStrs[I] = std::move(std::string(Path.begin(), Path.end()));
1152 FilenameRefs[I] = FilenameStrs[I];
1153 }
1154
1155 std::string FilenamesAndCoverageMappings;
1156 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1157 CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1158 OS << CoverageMappings;
1159 size_t CoverageMappingSize = CoverageMappings.size();
1160 size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1161 // Append extra zeroes if necessary to ensure that the size of the filenames
1162 // and coverage mappings is a multiple of 8.
1163 if (size_t Rem = OS.str().size() % 8) {
1164 CoverageMappingSize += 8 - Rem;
1165 for (size_t I = 0, S = 8 - Rem; I < S; ++I)
1166 OS << '\0';
1167 }
1168 auto *FilenamesAndMappingsVal =
1169 llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
1170
1171 // Create the deferred function records array
1172 auto RecordsTy =
1173 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1174 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1175
1176 // Create the coverage data record
1177 llvm::Type *CovDataTypes[] = {Int32Ty, Int32Ty,
1178 Int32Ty, Int32Ty,
1179 RecordsTy, FilenamesAndMappingsVal->getType()};
1180 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1181 llvm::Constant *TUDataVals[] = {
1182 llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()),
1183 llvm::ConstantInt::get(Int32Ty, FilenamesSize),
1184 llvm::ConstantInt::get(Int32Ty, CoverageMappingSize),
1185 llvm::ConstantInt::get(Int32Ty,
1186 /*Version=*/CoverageMappingVersion1),
1187 RecordsVal, FilenamesAndMappingsVal};
1188 auto CovDataVal =
1189 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1190 auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy, true,
1191 llvm::GlobalValue::InternalLinkage,
1192 CovDataVal,
1193 "__llvm_coverage_mapping");
1194
1195 CovData->setSection(getCoverageSection(CGM));
1196 CovData->setAlignment(8);
1197
1198 // Make sure the data doesn't get deleted.
1199 CGM.addUsedGlobal(CovData);
1200}
1201
1202unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {
1203 auto It = FileEntries.find(File);
1204 if (It != FileEntries.end())
1205 return It->second;
1206 unsigned FileID = FileEntries.size();
1207 FileEntries.insert(std::make_pair(File, FileID));
1208 return FileID;
1209}
1210
1211void CoverageMappingGen::emitCounterMapping(const Decl *D,
1212 llvm::raw_ostream &OS) {
1213 assert(CounterMap);
Justin Bognere5ee6c52014-10-02 16:44:01 +00001214 CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts);
Alex Lorenzee024992014-08-04 18:41:51 +00001215 Walker.VisitDecl(D);
1216 Walker.write(OS);
1217}
1218
1219void CoverageMappingGen::emitEmptyMapping(const Decl *D,
1220 llvm::raw_ostream &OS) {
1221 EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
1222 Walker.VisitDecl(D);
1223 Walker.write(OS);
1224}