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