llvm-project/llvm/tools/llvm-cov/CoverageSummaryInfo.h

264 lines
8.0 KiB
C++

//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These structures are used to represent code coverage metrics
// for functions/files.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_COV_COVERAGESUMMARYINFO_H
#define LLVM_COV_COVERAGESUMMARYINFO_H
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
/// Provides information about region coverage for a function/file.
class RegionCoverageInfo {
/// The number of regions that were executed at least once.
size_t Covered;
/// The total number of regions in a function/file.
size_t NumRegions;
public:
RegionCoverageInfo() : Covered(0), NumRegions(0) {}
RegionCoverageInfo(size_t Covered, size_t NumRegions)
: Covered(Covered), NumRegions(NumRegions) {
assert(Covered <= NumRegions && "Covered regions over-counted");
}
RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) {
Covered += RHS.Covered;
NumRegions += RHS.NumRegions;
return *this;
}
void merge(const RegionCoverageInfo &RHS) {
Covered = std::max(Covered, RHS.Covered);
NumRegions = std::max(NumRegions, RHS.NumRegions);
}
size_t getCovered() const { return Covered; }
size_t getNumRegions() const { return NumRegions; }
bool isFullyCovered() const { return Covered == NumRegions; }
double getPercentCovered() const {
assert(Covered <= NumRegions && "Covered regions over-counted");
if (NumRegions == 0)
return 0.0;
return double(Covered) / double(NumRegions) * 100.0;
}
};
/// Provides information about line coverage for a function/file.
class LineCoverageInfo {
/// The number of lines that were executed at least once.
size_t Covered;
/// The total number of lines in a function/file.
size_t NumLines;
public:
LineCoverageInfo() : Covered(0), NumLines(0) {}
LineCoverageInfo(size_t Covered, size_t NumLines)
: Covered(Covered), NumLines(NumLines) {
assert(Covered <= NumLines && "Covered lines over-counted");
}
LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) {
Covered += RHS.Covered;
NumLines += RHS.NumLines;
return *this;
}
void merge(const LineCoverageInfo &RHS) {
Covered = std::max(Covered, RHS.Covered);
NumLines = std::max(NumLines, RHS.NumLines);
}
size_t getCovered() const { return Covered; }
size_t getNumLines() const { return NumLines; }
bool isFullyCovered() const { return Covered == NumLines; }
double getPercentCovered() const {
assert(Covered <= NumLines && "Covered lines over-counted");
if (NumLines == 0)
return 0.0;
return double(Covered) / double(NumLines) * 100.0;
}
};
/// Provides information about branches coverage for a function/file.
class BranchCoverageInfo {
/// The number of branches that were executed at least once.
size_t Covered;
/// The total number of branches in a function/file.
size_t NumBranches;
public:
BranchCoverageInfo() : Covered(0), NumBranches(0) {}
BranchCoverageInfo(size_t Covered, size_t NumBranches)
: Covered(Covered), NumBranches(NumBranches) {
assert(Covered <= NumBranches && "Covered branches over-counted");
}
BranchCoverageInfo &operator+=(const BranchCoverageInfo &RHS) {
Covered += RHS.Covered;
NumBranches += RHS.NumBranches;
return *this;
}
void merge(const BranchCoverageInfo &RHS) {
Covered = std::max(Covered, RHS.Covered);
NumBranches = std::max(NumBranches, RHS.NumBranches);
}
size_t getCovered() const { return Covered; }
size_t getNumBranches() const { return NumBranches; }
bool isFullyCovered() const { return Covered == NumBranches; }
double getPercentCovered() const {
assert(Covered <= NumBranches && "Covered branches over-counted");
if (NumBranches == 0)
return 0.0;
return double(Covered) / double(NumBranches) * 100.0;
}
};
/// Provides information about function coverage for a file.
class FunctionCoverageInfo {
/// The number of functions that were executed.
size_t Executed;
/// The total number of functions in this file.
size_t NumFunctions;
public:
FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
: Executed(Executed), NumFunctions(NumFunctions) {}
FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {
Executed += RHS.Executed;
NumFunctions += RHS.NumFunctions;
return *this;
}
void addFunction(bool Covered) {
if (Covered)
++Executed;
++NumFunctions;
}
size_t getExecuted() const { return Executed; }
size_t getNumFunctions() const { return NumFunctions; }
bool isFullyCovered() const { return Executed == NumFunctions; }
double getPercentCovered() const {
assert(Executed <= NumFunctions && "Covered functions over-counted");
if (NumFunctions == 0)
return 0.0;
return double(Executed) / double(NumFunctions) * 100.0;
}
};
/// A summary of function's code coverage.
struct FunctionCoverageSummary {
std::string Name;
uint64_t ExecutionCount;
RegionCoverageInfo RegionCoverage;
LineCoverageInfo LineCoverage;
BranchCoverageInfo BranchCoverage;
FunctionCoverageSummary(const std::string &Name)
: Name(Name), ExecutionCount(0) {}
FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
const RegionCoverageInfo &RegionCoverage,
const LineCoverageInfo &LineCoverage,
const BranchCoverageInfo &BranchCoverage)
: Name(Name), ExecutionCount(ExecutionCount),
RegionCoverage(RegionCoverage), LineCoverage(LineCoverage),
BranchCoverage(BranchCoverage) {}
/// Compute the code coverage summary for the given function coverage
/// mapping record.
static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
const coverage::FunctionRecord &Function);
/// Compute the code coverage summary for an instantiation group \p Group,
/// given a list of summaries for each instantiation in \p Summaries.
static FunctionCoverageSummary
get(const coverage::InstantiationGroup &Group,
ArrayRef<FunctionCoverageSummary> Summaries);
};
/// A summary of file's code coverage.
struct FileCoverageSummary {
StringRef Name;
RegionCoverageInfo RegionCoverage;
LineCoverageInfo LineCoverage;
BranchCoverageInfo BranchCoverage;
FunctionCoverageInfo FunctionCoverage;
FunctionCoverageInfo InstantiationCoverage;
FileCoverageSummary(StringRef Name) : Name(Name) {}
FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
RegionCoverage += RHS.RegionCoverage;
LineCoverage += RHS.LineCoverage;
FunctionCoverage += RHS.FunctionCoverage;
BranchCoverage += RHS.BranchCoverage;
InstantiationCoverage += RHS.InstantiationCoverage;
return *this;
}
void addFunction(const FunctionCoverageSummary &Function) {
RegionCoverage += Function.RegionCoverage;
LineCoverage += Function.LineCoverage;
BranchCoverage += Function.BranchCoverage;
FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
}
void addInstantiation(const FunctionCoverageSummary &Function) {
InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
}
};
/// A cache for demangled symbols.
struct DemangleCache {
StringMap<std::string> DemangledNames;
/// Demangle \p Sym if possible. Otherwise, just return \p Sym.
StringRef demangle(StringRef Sym) const {
const auto DemangledName = DemangledNames.find(Sym);
if (DemangledName == DemangledNames.end())
return Sym;
return DemangledName->getValue();
}
};
} // namespace llvm
#endif // LLVM_COV_COVERAGESUMMARYINFO_H