Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- CoverageMapping.cpp - Code coverage mapping support ----------------===//
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
// This file contains support for clang's and llvm's instrumentation based
11
// code coverage.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/ADT/DenseMap.h"
18
#include "llvm/ADT/None.h"
19
#include "llvm/ADT/Optional.h"
20
#include "llvm/ADT/SmallBitVector.h"
21
#include "llvm/ADT/SmallVector.h"
22
#include "llvm/ADT/StringRef.h"
23
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
24
#include "llvm/ProfileData/InstrProfReader.h"
25
#include "llvm/Support/Debug.h"
26
#include "llvm/Support/Errc.h"
27
#include "llvm/Support/Error.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/ManagedStatic.h"
30
#include "llvm/Support/MemoryBuffer.h"
31
#include "llvm/Support/raw_ostream.h"
32
#include <algorithm>
33
#include <cassert>
34
#include <cstdint>
35
#include <iterator>
36
#include <memory>
37
#include <string>
38
#include <system_error>
39
#include <utility>
40
#include <vector>
41
42
using namespace llvm;
43
using namespace coverage;
44
45
#define DEBUG_TYPE "coverage-mapping"
46
47
1.03k
Counter CounterExpressionBuilder::get(const CounterExpression &E) {
48
1.03k
  auto It = ExpressionIndices.find(E);
49
1.03k
  if (It != ExpressionIndices.end())
50
468
    return Counter::getExpression(It->second);
51
567
  unsigned I = Expressions.size();
52
567
  Expressions.push_back(E);
53
567
  ExpressionIndices[E] = I;
54
567
  return Counter::getExpression(I);
55
567
}
56
57
void CounterExpressionBuilder::extractTerms(Counter C, int Factor,
58
2.49k
                                            SmallVectorImpl<Term> &Terms) {
59
2.49k
  switch (C.getKind()) {
60
237
  case Counter::Zero:
61
237
    break;
62
1.29k
  case Counter::CounterValueReference:
63
1.29k
    Terms.emplace_back(C.getCounterID(), Factor);
64
1.29k
    break;
65
962
  case Counter::Expression:
66
962
    const auto &E = Expressions[C.getExpressionID()];
67
962
    extractTerms(E.LHS, Factor, Terms);
68
962
    extractTerms(
69
962
        E.RHS, E.Kind == CounterExpression::Subtract ? 
-Factor422
:
Factor540
, Terms);
70
962
    break;
71
2.49k
  }
72
2.49k
}
73
74
566
Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {
75
566
  // Gather constant terms.
76
566
  SmallVector<Term, 32> Terms;
77
566
  extractTerms(ExpressionTree, +1, Terms);
78
566
79
566
  // If there are no terms, this is just a zero. The algorithm below assumes at
80
566
  // least one term.
81
566
  if (Terms.size() == 0)
82
5
    return Counter::getZero();
83
561
84
561
  // Group the terms by counter ID.
85
561
  
std::sort(Terms.begin(), Terms.end(), [](const Term &LHS, const Term &RHS) 561
{
86
846
    return LHS.CounterID < RHS.CounterID;
87
846
  });
88
561
89
561
  // Combine terms by counter ID to eliminate counters that sum to zero.
90
561
  auto Prev = Terms.begin();
91
1.29k
  for (auto I = Prev + 1, E = Terms.end(); 
I != E1.29k
;
++I730
) {
92
730
    if (
I->CounterID == Prev->CounterID730
) {
93
131
      Prev->Factor += I->Factor;
94
131
      continue;
95
131
    }
96
599
    ++Prev;
97
599
    *Prev = *I;
98
599
  }
99
561
  Terms.erase(++Prev, Terms.end());
100
561
101
561
  Counter C;
102
561
  // Create additions. We do this before subtractions to avoid constructs like
103
561
  // ((0 - X) + Y), as opposed to (Y - X).
104
1.16k
  for (auto T : Terms) {
105
1.16k
    if (T.Factor <= 0)
106
422
      continue;
107
1.47k
    
for (int I = 0; 738
I < T.Factor1.47k
;
++I738
)
108
738
      
if (738
C.isZero()738
)
109
560
        C = Counter::getCounter(T.CounterID);
110
738
      else
111
178
        C = get(CounterExpression(CounterExpression::Add, C,
112
178
                                  Counter::getCounter(T.CounterID)));
113
1.16k
  }
114
561
115
561
  // Create subtractions.
116
1.16k
  for (auto T : Terms) {
117
1.16k
    if (T.Factor >= 0)
118
869
      continue;
119
582
    
for (int I = 0; 291
I < -T.Factor582
;
++I291
)
120
291
      C = get(CounterExpression(CounterExpression::Subtract, C,
121
291
                                Counter::getCounter(T.CounterID)));
122
1.16k
  }
123
566
  return C;
124
566
}
125
126
381
Counter CounterExpressionBuilder::add(Counter LHS, Counter RHS) {
127
381
  return simplify(get(CounterExpression(CounterExpression::Add, LHS, RHS)));
128
381
}
129
130
185
Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS) {
131
185
  return simplify(
132
185
      get(CounterExpression(CounterExpression::Subtract, LHS, RHS)));
133
185
}
134
135
1.58k
void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
136
1.58k
  switch (C.getKind()) {
137
53
  case Counter::Zero:
138
53
    OS << '0';
139
53
    return;
140
1.23k
  case Counter::CounterValueReference:
141
1.23k
    OS << '#' << C.getCounterID();
142
1.23k
    break;
143
298
  case Counter::Expression: {
144
298
    if (C.getExpressionID() >= Expressions.size())
145
0
      return;
146
298
    const auto &E = Expressions[C.getExpressionID()];
147
298
    OS << '(';
148
298
    dump(E.LHS, OS);
149
298
    OS << (E.Kind == CounterExpression::Subtract ? 
" - "194
:
" + "104
);
150
298
    dump(E.RHS, OS);
151
298
    OS << ')';
152
298
    break;
153
298
  }
154
1.52k
  }
155
1.52k
  
if (1.52k
CounterValues.empty()1.52k
)
156
1.52k
    return;
157
0
  Expected<int64_t> Value = evaluate(C);
158
0
  if (auto 
E0
= Value.takeError()) {
159
0
    consumeError(std::move(E));
160
0
    return;
161
0
  }
162
0
  OS << '[' << *Value << ']';
163
0
}
164
165
1.46k
Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
166
1.46k
  switch (C.getKind()) {
167
52
  case Counter::Zero:
168
52
    return 0;
169
1.19k
  case Counter::CounterValueReference:
170
1.19k
    if (C.getCounterID() >= CounterValues.size())
171
0
      return errorCodeToError(errc::argument_out_of_domain);
172
1.19k
    return CounterValues[C.getCounterID()];
173
221
  case Counter::Expression: {
174
221
    if (C.getExpressionID() >= Expressions.size())
175
0
      return errorCodeToError(errc::argument_out_of_domain);
176
221
    const auto &E = Expressions[C.getExpressionID()];
177
221
    Expected<int64_t> LHS = evaluate(E.LHS);
178
221
    if (!LHS)
179
0
      return LHS;
180
221
    Expected<int64_t> RHS = evaluate(E.RHS);
181
221
    if (!RHS)
182
0
      return RHS;
183
221
    
return E.Kind == CounterExpression::Subtract ? 221
*LHS - *RHS142
:
*LHS + *RHS79
;
184
1.19k
  }
185
0
  }
186
0
  
llvm_unreachable0
("Unhandled CounterKind");
187
0
}
188
189
779
void FunctionRecordIterator::skipOtherFiles() {
190
799
  while (
Current != Records.end() && 799
!Filename.empty()579
&&
191
87
         Filename != Current->Filenames[0])
192
20
    ++Current;
193
779
  if (Current == Records.end())
194
220
    *this = FunctionRecordIterator();
195
779
}
196
197
Error CoverageMapping::loadFunctionRecord(
198
    const CoverageMappingRecord &Record,
199
325
    IndexedInstrProfReader &ProfileReader) {
200
325
  StringRef OrigFuncName = Record.FunctionName;
201
325
  if (OrigFuncName.empty())
202
4
    return make_error<CoverageMapError>(coveragemap_error::malformed);
203
321
204
321
  
if (321
Record.Filenames.empty()321
)
205
4
    OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName);
206
321
  else
207
317
    OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
208
321
209
321
  // Don't load records for functions we've already seen.
210
321
  if (!FunctionNames.insert(OrigFuncName).second)
211
7
    return Error::success();
212
314
213
314
  CounterMappingContext Ctx(Record.Expressions);
214
314
215
314
  std::vector<uint64_t> Counts;
216
314
  if (Error E = ProfileReader.getFunctionCounts(Record.FunctionName,
217
32
                                                Record.FunctionHash, Counts)) {
218
32
    instrprof_error IPE = InstrProfError::take(std::move(E));
219
32
    if (
IPE == instrprof_error::hash_mismatch32
) {
220
1
      FuncHashMismatches.emplace_back(Record.FunctionName, Record.FunctionHash);
221
1
      return Error::success();
222
31
    } else 
if (31
IPE != instrprof_error::unknown_function31
)
223
0
      return make_error<InstrProfError>(IPE);
224
31
    Counts.assign(Record.MappingRegions.size(), 0);
225
31
  }
226
313
  Ctx.setCounts(Counts);
227
313
228
313
  assert(!Record.MappingRegions.empty() && "Function has no regions");
229
313
230
313
  FunctionRecord Function(OrigFuncName, Record.Filenames);
231
1.02k
  for (const auto &Region : Record.MappingRegions) {
232
1.02k
    Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
233
1.02k
    if (auto 
E1.02k
= ExecutionCount.takeError()) {
234
0
      consumeError(std::move(E));
235
0
      return Error::success();
236
0
    }
237
1.02k
    Function.pushRegion(Region, *ExecutionCount);
238
1.02k
  }
239
313
  
if (313
Function.CountedRegions.size() != Record.MappingRegions.size()313
) {
240
0
    FuncCounterMismatches.emplace_back(Record.FunctionName,
241
0
                                       Function.CountedRegions.size());
242
0
    return Error::success();
243
0
  }
244
313
245
313
  Functions.push_back(std::move(Function));
246
313
  return Error::success();
247
313
}
248
249
Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
250
    ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
251
178
    IndexedInstrProfReader &ProfileReader) {
252
178
  auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
253
178
254
187
  for (const auto &CoverageReader : CoverageReaders) {
255
326
    for (auto RecordOrErr : *CoverageReader) {
256
326
      if (Error E = RecordOrErr.takeError())
257
1
        return std::move(E);
258
325
      const auto &Record = *RecordOrErr;
259
325
      if (Error E = Coverage->loadFunctionRecord(Record, ProfileReader))
260
4
        return std::move(E);
261
173
    }
262
187
  }
263
173
264
173
  return std::move(Coverage);
265
173
}
266
267
Expected<std::unique_ptr<CoverageMapping>>
268
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
269
87
                      StringRef ProfileFilename, ArrayRef<StringRef> Arches) {
270
87
  auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
271
87
  if (Error E = ProfileReaderOrErr.takeError())
272
0
    return std::move(E);
273
87
  auto ProfileReader = std::move(ProfileReaderOrErr.get());
274
87
275
87
  SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
276
87
  SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
277
90
  for (const auto &File : llvm::enumerate(ObjectFilenames)) {
278
90
    auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(File.value());
279
90
    if (std::error_code EC = CovMappingBufOrErr.getError())
280
0
      return errorCodeToError(EC);
281
90
    
StringRef Arch = Arches.empty() ? 90
StringRef()85
:
Arches[File.index()]5
;
282
90
    auto CoverageReaderOrErr =
283
90
        BinaryCoverageReader::create(CovMappingBufOrErr.get(), Arch);
284
90
    if (Error E = CoverageReaderOrErr.takeError())
285
1
      return std::move(E);
286
89
    Readers.push_back(std::move(CoverageReaderOrErr.get()));
287
89
    Buffers.push_back(std::move(CovMappingBufOrErr.get()));
288
89
  }
289
86
  return load(Readers, *ProfileReader);
290
87
}
291
292
namespace {
293
294
/// \brief Distributes functions into instantiation sets.
295
///
296
/// An instantiation set is a collection of functions that have the same source
297
/// code, ie, template functions specializations.
298
class FunctionInstantiationSetCollector {
299
  using MapT = DenseMap<LineColPair, std::vector<const FunctionRecord *>>;
300
  MapT InstantiatedFunctions;
301
302
public:
303
173
  void insert(const FunctionRecord &Function, unsigned FileID) {
304
173
    auto I = Function.CountedRegions.begin(), E = Function.CountedRegions.end();
305
173
    while (
I != E && 173
I->FileID != FileID173
)
306
0
      ++I;
307
173
    assert(I != E && "function does not cover the given file");
308
173
    auto &Functions = InstantiatedFunctions[I->startLoc()];
309
173
    Functions.push_back(&Function);
310
173
  }
311
312
106
  MapT::iterator begin() { return InstantiatedFunctions.begin(); }
313
106
  MapT::iterator end() { return InstantiatedFunctions.end(); }
314
};
315
316
class SegmentBuilder {
317
  std::vector<CoverageSegment> &Segments;
318
  SmallVector<const CountedRegion *, 8> ActiveRegions;
319
320
277
  SegmentBuilder(std::vector<CoverageSegment> &Segments) : Segments(Segments) {}
321
322
  /// Emit a segment with the count from \p Region starting at \p StartLoc.
323
  //
324
  /// \p IsRegionEntry: The segment is at the start of a new non-gap region.
325
  /// \p EmitSkippedRegion: The segment must be emitted as a skipped region.
326
  void startSegment(const CountedRegion &Region, LineColPair StartLoc,
327
1.97k
                    bool IsRegionEntry, bool EmitSkippedRegion = false) {
328
1.97k
    bool HasCount = !EmitSkippedRegion &&
329
1.65k
                    (Region.Kind != CounterMappingRegion::SkippedRegion);
330
1.97k
331
1.97k
    // If the new segment wouldn't affect coverage rendering, skip it.
332
1.97k
    if (
!Segments.empty() && 1.97k
!IsRegionEntry1.70k
&&
!EmitSkippedRegion956
) {
333
652
      const auto &Last = Segments.back();
334
652
      if (
Last.HasCount == HasCount && 652
Last.Count == Region.ExecutionCount648
&&
335
250
          !Last.IsRegionEntry)
336
11
        return;
337
1.96k
    }
338
1.96k
339
1.96k
    
if (1.96k
HasCount1.96k
)
340
1.63k
      Segments.emplace_back(StartLoc.first, StartLoc.second,
341
1.63k
                            Region.ExecutionCount, IsRegionEntry,
342
1.63k
                            Region.Kind == CounterMappingRegion::GapRegion);
343
1.96k
    else
344
328
      Segments.emplace_back(StartLoc.first, StartLoc.second, IsRegionEntry);
345
1.96k
346
1.96k
    DEBUG({
347
1.97k
      const auto &Last = Segments.back();
348
1.97k
      dbgs() << "Segment at " << Last.Line << ":" << Last.Col
349
1.97k
             << " (count = " << Last.Count << ")"
350
1.97k
             << (Last.IsRegionEntry ? ", RegionEntry" : "")
351
1.97k
             << (!Last.HasCount ? ", Skipped" : "")
352
1.97k
             << (Last.IsGapRegion ? ", Gap" : "") << "\n";
353
1.97k
    });
354
1.97k
  }
355
356
  /// Emit segments for active regions which end before \p Loc.
357
  ///
358
  /// \p Loc: The start location of the next region. If None, all active
359
  /// regions are completed.
360
  /// \p FirstCompletedRegion: Index of the first completed region.
361
  void completeRegionsUntil(Optional<LineColPair> Loc,
362
795
                            unsigned FirstCompletedRegion) {
363
795
    // Sort the completed regions by end location. This makes it simple to
364
795
    // emit closing segments in sorted order.
365
795
    auto CompletedRegionsIt = ActiveRegions.begin() + FirstCompletedRegion;
366
795
    std::stable_sort(CompletedRegionsIt, ActiveRegions.end(),
367
269
                      [](const CountedRegion *L, const CountedRegion *R) {
368
269
                        return L->endLoc() < R->endLoc();
369
269
                      });
370
795
371
795
    // Emit segments for all completed regions.
372
1.02k
    for (unsigned I = FirstCompletedRegion + 1, E = ActiveRegions.size(); I < E;
373
795
         
++I225
) {
374
229
      const auto *CompletedRegion = ActiveRegions[I];
375
229
      assert((!Loc || CompletedRegion->endLoc() <= *Loc) &&
376
229
             "Completed region ends after start of new region");
377
229
378
229
      const auto *PrevCompletedRegion = ActiveRegions[I - 1];
379
229
      auto CompletedSegmentLoc = PrevCompletedRegion->endLoc();
380
229
381
229
      // Don't emit any more segments if they start where the new region begins.
382
229
      if (
Loc && 229
CompletedSegmentLoc == *Loc80
)
383
4
        break;
384
225
385
225
      // Don't emit a segment if the next completed region ends at the same
386
225
      // location as this one.
387
225
      
if (225
CompletedSegmentLoc == CompletedRegion->endLoc()225
)
388
40
        continue;
389
185
390
185
      startSegment(*CompletedRegion, CompletedSegmentLoc, false);
391
185
    }
392
795
393
795
    auto Last = ActiveRegions.back();
394
795
    if (
FirstCompletedRegion && 795
Last->endLoc() != *Loc487
) {
395
457
      // If there's a gap after the end of the last completed region and the
396
457
      // start of the new region, use the last active region to fill the gap.
397
457
      startSegment(*ActiveRegions[FirstCompletedRegion - 1], Last->endLoc(),
398
457
                   false);
399
795
    } else 
if (338
!FirstCompletedRegion && 338
(!Loc || 308
*Loc != Last->endLoc()47
)) {
400
304
      // Emit a skipped segment if there are no more active regions. This
401
304
      // ensures that gaps between functions are marked correctly.
402
304
      startSegment(*Last, Last->endLoc(), false, true);
403
304
    }
404
795
405
795
    // Pop the completed regions.
406
795
    ActiveRegions.erase(CompletedRegionsIt, ActiveRegions.end());
407
795
  }
408
409
277
  void buildSegmentsImpl(ArrayRef<CountedRegion> Regions) {
410
1.04k
    for (const auto &CR : enumerate(Regions)) {
411
1.04k
      auto CurStartLoc = CR.value().startLoc();
412
1.04k
413
1.04k
      // Active regions which end before the current region need to be popped.
414
1.04k
      auto CompletedRegions =
415
1.04k
          std::stable_partition(ActiveRegions.begin(), ActiveRegions.end(),
416
1.52k
                                [&](const CountedRegion *Region) {
417
1.52k
                                  return !(Region->endLoc() <= CurStartLoc);
418
1.52k
                                });
419
1.04k
      if (
CompletedRegions != ActiveRegions.end()1.04k
) {
420
534
        unsigned FirstCompletedRegion =
421
534
            std::distance(ActiveRegions.begin(), CompletedRegions);
422
534
        completeRegionsUntil(CurStartLoc, FirstCompletedRegion);
423
534
      }
424
1.04k
425
1.04k
      bool GapRegion = CR.value().Kind == CounterMappingRegion::GapRegion;
426
1.04k
427
1.04k
      // Try to emit a segment for the current region.
428
1.04k
      if (
CurStartLoc == CR.value().endLoc()1.04k
) {
429
20
        // Avoid making zero-length regions active. If it's the last region,
430
20
        // emit a skipped segment. Otherwise use its predecessor's count.
431
20
        const bool Skipped = (CR.index() + 1) == Regions.size();
432
20
        startSegment(ActiveRegions.empty() ? 
CR.value()16
:
*ActiveRegions.back()4
,
433
20
                     CurStartLoc, !GapRegion, Skipped);
434
20
        continue;
435
20
      }
436
1.02k
      
if (1.02k
CR.index() + 1 == Regions.size() ||
437
1.02k
          
CurStartLoc != Regions[CR.index() + 1].startLoc()767
) {
438
1.01k
        // Emit a segment if the next region doesn't start at the same location
439
1.01k
        // as this one.
440
1.01k
        startSegment(CR.value(), CurStartLoc, !GapRegion);
441
1.01k
      }
442
1.04k
443
1.04k
      // This region is active (i.e not completed).
444
1.04k
      ActiveRegions.push_back(&CR.value());
445
1.04k
    }
446
277
447
277
    // Complete any remaining active regions.
448
277
    if (!ActiveRegions.empty())
449
261
      completeRegionsUntil(None, 0);
450
277
  }
451
452
  /// Sort a nested sequence of regions from a single file.
453
277
  static void sortNestedRegions(MutableArrayRef<CountedRegion> Regions) {
454
277
    std::sort(Regions.begin(), Regions.end(), [](const CountedRegion &LHS,
455
1.25k
                                                 const CountedRegion &RHS) {
456
1.25k
      if (LHS.startLoc() != RHS.startLoc())
457
1.14k
        return LHS.startLoc() < RHS.startLoc();
458
107
      
if (107
LHS.endLoc() != RHS.endLoc()107
)
459
107
        // When LHS completely contains RHS, we sort LHS first.
460
16
        return RHS.endLoc() < LHS.endLoc();
461
91
      // If LHS and RHS cover the same area, we need to sort them according
462
91
      // to their kinds so that the most suitable region will become "active"
463
91
      // in combineRegions(). Because we accumulate counter values only from
464
91
      // regions of the same kind as the first region of the area, prefer
465
91
      // CodeRegion to ExpansionRegion and ExpansionRegion to SkippedRegion.
466
91
      static_assert(CounterMappingRegion::CodeRegion <
467
91
                            CounterMappingRegion::ExpansionRegion &&
468
91
                        CounterMappingRegion::ExpansionRegion <
469
91
                            CounterMappingRegion::SkippedRegion,
470
91
                    "Unexpected order of region kind values");
471
91
      return LHS.Kind < RHS.Kind;
472
91
    });
473
277
  }
474
475
  /// Combine counts of regions which cover the same area.
476
  static ArrayRef<CountedRegion>
477
277
  combineRegions(MutableArrayRef<CountedRegion> Regions) {
478
277
    if (Regions.empty())
479
0
      return Regions;
480
277
    auto Active = Regions.begin();
481
277
    auto End = Regions.end();
482
1.13k
    for (auto I = Regions.begin() + 1; 
I != End1.13k
;
++I860
) {
483
860
      if (Active->startLoc() != I->startLoc() ||
484
860
          
Active->endLoc() != I->endLoc()105
) {
485
771
        // Shift to the next region.
486
771
        ++Active;
487
771
        if (Active != I)
488
53
          *Active = *I;
489
771
        continue;
490
771
      }
491
89
      // Merge duplicate region.
492
89
      // If CodeRegions and ExpansionRegions cover the same area, it's probably
493
89
      // a macro which is fully expanded to another macro. In that case, we need
494
89
      // to accumulate counts only from CodeRegions, or else the area will be
495
89
      // counted twice.
496
89
      // On the other hand, a macro may have a nested macro in its body. If the
497
89
      // outer macro is used several times, the ExpansionRegion for the nested
498
89
      // macro will also be added several times. These ExpansionRegions cover
499
89
      // the same source locations and have to be combined to reach the correct
500
89
      // value for that area.
501
89
      // We add counts of the regions of the same kind as the active region
502
89
      // to handle the both situations.
503
89
      
if (89
I->Kind == Active->Kind89
)
504
85
        Active->ExecutionCount += I->ExecutionCount;
505
860
    }
506
277
    return Regions.drop_back(std::distance(++Active, End));
507
277
  }
508
509
public:
510
  /// Build a sorted list of CoverageSegments from a list of Regions.
511
  static std::vector<CoverageSegment>
512
277
  buildSegments(MutableArrayRef<CountedRegion> Regions) {
513
277
    std::vector<CoverageSegment> Segments;
514
277
    SegmentBuilder Builder(Segments);
515
277
516
277
    sortNestedRegions(Regions);
517
277
    ArrayRef<CountedRegion> CombinedRegions = combineRegions(Regions);
518
277
519
277
    DEBUG({
520
277
      dbgs() << "Combined regions:\n";
521
277
      for (const auto &CR : CombinedRegions)
522
277
        dbgs() << "  " << CR.LineStart << ":" << CR.ColumnStart << " -> "
523
277
               << CR.LineEnd << ":" << CR.ColumnEnd
524
277
               << " (count=" << CR.ExecutionCount << ")\n";
525
277
    });
526
277
527
277
    Builder.buildSegmentsImpl(CombinedRegions);
528
277
529
#ifndef NDEBUG
530
    for (unsigned I = 1, E = Segments.size(); I < E; ++I) {
531
      const auto &L = Segments[I - 1];
532
      const auto &R = Segments[I];
533
      if (!(L.Line < R.Line) && !(L.Line == R.Line && L.Col < R.Col)) {
534
        DEBUG(dbgs() << " ! Segment " << L.Line << ":" << L.Col
535
                     << " followed by " << R.Line << ":" << R.Col << "\n");
536
        assert(false && "Coverage segments not unique or sorted");
537
      }
538
    }
539
#endif
540
541
277
    return Segments;
542
277
  }
543
};
544
545
} // end anonymous namespace
546
547
159
std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
548
159
  std::vector<StringRef> Filenames;
549
159
  for (const auto &Function : getCoveredFunctions())
550
407
    Filenames.insert(Filenames.end(), Function.Filenames.begin(),
551
407
                     Function.Filenames.end());
552
159
  std::sort(Filenames.begin(), Filenames.end());
553
159
  auto Last = std::unique(Filenames.begin(), Filenames.end());
554
159
  Filenames.erase(Last, Filenames.end());
555
159
  return Filenames;
556
159
}
557
558
static SmallBitVector gatherFileIDs(StringRef SourceFile,
559
136
                                    const FunctionRecord &Function) {
560
136
  SmallBitVector FilenameEquivalence(Function.Filenames.size(), false);
561
324
  for (unsigned I = 0, E = Function.Filenames.size(); 
I < E324
;
++I188
)
562
188
    
if (188
SourceFile == Function.Filenames[I]188
)
563
141
      FilenameEquivalence[I] = true;
564
136
  return FilenameEquivalence;
565
136
}
566
567
/// Return the ID of the file where the definition of the function is located.
568
620
static Optional<unsigned> findMainViewFileID(const FunctionRecord &Function) {
569
620
  SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
570
620
  for (const auto &CR : Function.CountedRegions)
571
2.19k
    
if (2.19k
CR.Kind == CounterMappingRegion::ExpansionRegion2.19k
)
572
65
      IsNotExpandedFile[CR.ExpandedFileID] = false;
573
620
  int I = IsNotExpandedFile.find_first();
574
620
  if (I == -1)
575
0
    return None;
576
620
  return I;
577
620
}
578
579
/// Check if SourceFile is the file that contains the definition of
580
/// the Function. Return the ID of the file in that case or None otherwise.
581
static Optional<unsigned> findMainViewFileID(StringRef SourceFile,
582
438
                                             const FunctionRecord &Function) {
583
438
  Optional<unsigned> I = findMainViewFileID(Function);
584
438
  if (
I && 438
SourceFile == Function.Filenames[*I]438
)
585
290
    return I;
586
148
  return None;
587
148
}
588
589
1.11k
static bool isExpansion(const CountedRegion &R, unsigned FileID) {
590
31
  return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
591
1.11k
}
592
593
92
CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
594
92
  CoverageData FileCoverage(Filename);
595
92
  std::vector<CountedRegion> Regions;
596
92
597
136
  for (const auto &Function : Functions) {
598
136
    auto MainFileID = findMainViewFileID(Filename, Function);
599
136
    auto FileIDs = gatherFileIDs(Filename, Function);
600
136
    for (const auto &CR : Function.CountedRegions)
601
575
      
if (575
FileIDs.test(CR.FileID)575
) {
602
523
        Regions.push_back(CR);
603
523
        if (
MainFileID && 523
isExpansion(CR, *MainFileID)505
)
604
16
          FileCoverage.Expansions.emplace_back(CR, Function);
605
575
      }
606
136
  }
607
92
608
92
  DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
609
92
  FileCoverage.Segments = SegmentBuilder::buildSegments(Regions);
610
92
611
92
  return FileCoverage;
612
92
}
613
614
std::vector<InstantiationGroup>
615
106
CoverageMapping::getInstantiationGroups(StringRef Filename) const {
616
106
  FunctionInstantiationSetCollector InstantiationSetCollector;
617
302
  for (const auto &Function : Functions) {
618
302
    auto MainFileID = findMainViewFileID(Filename, Function);
619
302
    if (!MainFileID)
620
129
      continue;
621
173
    InstantiationSetCollector.insert(Function, *MainFileID);
622
173
  }
623
106
624
106
  std::vector<InstantiationGroup> Result;
625
151
  for (const auto &InstantiationSet : InstantiationSetCollector) {
626
151
    InstantiationGroup IG{InstantiationSet.first.first,
627
151
                          InstantiationSet.first.second,
628
151
                          std::move(InstantiationSet.second)};
629
151
    Result.emplace_back(std::move(IG));
630
151
  }
631
106
  return Result;
632
106
}
633
634
CoverageData
635
182
CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
636
182
  auto MainFileID = findMainViewFileID(Function);
637
182
  if (!MainFileID)
638
0
    return CoverageData();
639
182
640
182
  CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
641
182
  std::vector<CountedRegion> Regions;
642
182
  for (const auto &CR : Function.CountedRegions)
643
632
    
if (632
CR.FileID == *MainFileID632
) {
644
602
      Regions.push_back(CR);
645
602
      if (isExpansion(CR, *MainFileID))
646
7
        FunctionCoverage.Expansions.emplace_back(CR, Function);
647
632
    }
648
182
649
182
  DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n");
650
182
  FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions);
651
182
652
182
  return FunctionCoverage;
653
182
}
654
655
CoverageData CoverageMapping::getCoverageForExpansion(
656
3
    const ExpansionRecord &Expansion) const {
657
3
  CoverageData ExpansionCoverage(
658
3
      Expansion.Function.Filenames[Expansion.FileID]);
659
3
  std::vector<CountedRegion> Regions;
660
3
  for (const auto &CR : Expansion.Function.CountedRegions)
661
48
    
if (48
CR.FileID == Expansion.FileID48
) {
662
12
      Regions.push_back(CR);
663
12
      if (isExpansion(CR, Expansion.FileID))
664
2
        ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function);
665
48
    }
666
3
667
3
  DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID
668
3
               << "\n");
669
3
  ExpansionCoverage.Segments = SegmentBuilder::buildSegments(Regions);
670
3
671
3
  return ExpansionCoverage;
672
3
}
673
674
5
static std::string getCoverageMapErrString(coveragemap_error Err) {
675
5
  switch (Err) {
676
0
  case coveragemap_error::success:
677
0
    return "Success";
678
0
  case coveragemap_error::eof:
679
0
    return "End of File";
680
0
  case coveragemap_error::no_data_found:
681
0
    return "No coverage data found";
682
0
  case coveragemap_error::unsupported_version:
683
0
    return "Unsupported coverage format version";
684
0
  case coveragemap_error::truncated:
685
0
    return "Truncated coverage data";
686
5
  case coveragemap_error::malformed:
687
5
    return "Malformed coverage data";
688
0
  }
689
0
  
llvm_unreachable0
("A value of coveragemap_error has no message.");
690
0
}
691
692
namespace {
693
694
// FIXME: This class is only here to support the transition to llvm::Error. It
695
// will be removed once this transition is complete. Clients should prefer to
696
// deal with the Error value directly, rather than converting to error_code.
697
class CoverageMappingErrorCategoryType : public std::error_category {
698
0
  const char *name() const noexcept override { return "llvm.coveragemap"; }
699
0
  std::string message(int IE) const override {
700
0
    return getCoverageMapErrString(static_cast<coveragemap_error>(IE));
701
0
  }
702
};
703
704
} // end anonymous namespace
705
706
5
std::string CoverageMapError::message() const {
707
5
  return getCoverageMapErrString(Err);
708
5
}
709
710
static ManagedStatic<CoverageMappingErrorCategoryType> ErrorCategory;
711
712
0
const std::error_category &llvm::coverage::coveragemap_category() {
713
0
  return *ErrorCategory;
714
0
}
715
716
char CoverageMapError::ID = 0;