1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00
llvm-mirror/tools/llvm-cov/CoverageSummaryInfo.h
Alan Phipps f85fa6973c [Coverage] Add support for Branch Coverage in LLVM Source-Based Code Coverage
This is an enhancement to LLVM Source-Based Code Coverage in clang to track how
many times individual branch-generating conditions are taken (evaluate to TRUE)
and not taken (evaluate to FALSE).  Individual conditions may comprise larger
boolean expressions using boolean logical operators.  This functionality is
very similar to what is supported by GCOV except that it is very closely
anchored to the ASTs.

Differential Revision: https://reviews.llvm.org/D84467
2021-01-05 09:51:51 -06:00

262 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;
}
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), RegionCoverage(), LineCoverage(),
BranchCoverage() {}
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), RegionCoverage(), LineCoverage(), FunctionCoverage(),
InstantiationCoverage() {}
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