1//===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===//
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// These structures are used to represent code coverage metrics
11// for functions/files.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CoverageSummaryInfo.h"
16
17using namespace llvm;
18using namespace coverage;
19
20FunctionCoverageSummary
21FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) {
22  // Compute the region coverage
23  size_t NumCodeRegions = 0, CoveredRegions = 0;
24  for (auto &CR : Function.CountedRegions) {
25    if (CR.Kind != CounterMappingRegion::CodeRegion)
26      continue;
27    ++NumCodeRegions;
28    if (CR.ExecutionCount != 0)
29      ++CoveredRegions;
30  }
31
32  // Compute the line coverage
33  size_t NumLines = 0, CoveredLines = 0;
34  for (unsigned FileID = 0, E = Function.Filenames.size(); FileID < E;
35       ++FileID) {
36    // Find the line start and end of the function's source code
37    // in that particular file
38    unsigned LineStart = std::numeric_limits<unsigned>::max();
39    unsigned LineEnd = 0;
40    for (auto &CR : Function.CountedRegions) {
41      if (CR.FileID != FileID)
42        continue;
43      LineStart = std::min(LineStart, CR.LineStart);
44      LineEnd = std::max(LineEnd, CR.LineEnd);
45    }
46    unsigned LineCount = LineEnd - LineStart + 1;
47
48    // Get counters
49    llvm::SmallVector<uint64_t, 16> ExecutionCounts;
50    ExecutionCounts.resize(LineCount, 0);
51    for (auto &CR : Function.CountedRegions) {
52      if (CR.FileID != FileID)
53        continue;
54      // Ignore the lines that were skipped by the preprocessor.
55      auto ExecutionCount = CR.ExecutionCount;
56      if (CR.Kind == CounterMappingRegion::SkippedRegion) {
57        LineCount -= CR.LineEnd - CR.LineStart + 1;
58        ExecutionCount = 1;
59      }
60      for (unsigned I = CR.LineStart; I <= CR.LineEnd; ++I)
61        ExecutionCounts[I - LineStart] = ExecutionCount;
62    }
63    CoveredLines += LineCount - std::count(ExecutionCounts.begin(),
64                                           ExecutionCounts.end(), 0);
65    NumLines += LineCount;
66  }
67  return FunctionCoverageSummary(
68      Function.Name, Function.ExecutionCount,
69      RegionCoverageInfo(CoveredRegions, NumCodeRegions),
70      LineCoverageInfo(CoveredLines, 0, NumLines));
71}
72