xref: /aosp_15_r20/external/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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