Coverage Report

Created: 2020-09-22 08:39

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