Show code coverage only for functions with the given name.
+.. option:: -name-whitelist=<FILE>
+
+ Show code coverage only for functions listed in the given file. Each line in
+ the file should start with `whitelist_fun:`, immediately followed by the name
+ of the function to accept. This name can be a wildcard expression.
+
.. option:: -name-regex=<PATTERN>
Show code coverage only for functions that match the given regular expression.
--- /dev/null
+int func1() {
+ return 1;
+}
+int func2() {
+ return 1;
+}
+int func3() {
+ return 1;
+}
+int func4() {
+ return 1;
+}
+int func5() {
+ return 1;
+}
+int func6() {
+ return 1;
+}
--- /dev/null
+_Z5func1v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z5func2v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z5func3v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z5func4v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+main
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+1
+
+_Z5func5v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z5func6v
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
--- /dev/null
+# Comment
+
+whitelist_fun:*func1*
+whitelist_fun:*func2*
--- /dev/null
+whitelist_fun:*func3*
+whitelist_fun:*func4*
--- /dev/null
+RUN: llvm-profdata merge %S/Inputs/name_whitelist.proftext -o %t.profdata
+
+RUN: llvm-cov show %S/Inputs/name_whitelist.covmapping -instr-profile=%t.profdata -path-equivalence=/tmp,%S/Inputs -name-whitelist=%S/Inputs/whitelist1.txt %S/Inputs/name_whitelist.cpp > %t.one_list
+RUN: FileCheck -input-file=%t.one_list -check-prefix=ONE_WHITELIST %s
+RUN: FileCheck -input-file=%t.one_list -check-prefix=ONE_WHITELIST_NEG %s
+ONE_WHITELIST: _Z5func1v:
+ONE_WHITELIST: _Z5func2v:
+ONE_WHITELIST_NEG-NOT: _Z5func3v:
+ONE_WHITELIST_NEG-NOT: _Z5func4v:
+ONE_WHITELIST_NEG-NOT: _Z5func5v:
+ONE_WHITELIST_NEG-NOT: _Z5func6v:
+
+RUN: llvm-cov show %S/Inputs/name_whitelist.covmapping -instr-profile=%t.profdata -path-equivalence=/tmp,%S/Inputs -name-whitelist=%S/Inputs/whitelist1.txt -name-whitelist=%S/Inputs/whitelist2.txt %S/Inputs/name_whitelist.cpp > %t.two_list
+RUN: FileCheck -input-file=%t.two_list -check-prefix=TWO_WHITELIST %s
+RUN: FileCheck -input-file=%t.two_list -check-prefix=TWO_WHITELIST_NEG %s
+TWO_WHITELIST: _Z5func1v:
+TWO_WHITELIST: _Z5func2v:
+TWO_WHITELIST: _Z5func3v:
+TWO_WHITELIST: _Z5func4v:
+TWO_WHITELIST_NEG-NOT: _Z5func5v:
+TWO_WHITELIST_NEG-NOT: _Z5func6v:
std::mutex LoadedSourceFilesLock;
std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>>
LoadedSourceFiles;
+
+ /// Whitelist from -name-whitelist to be used for filtering.
+ std::unique_ptr<SpecialCaseList> NameWhitelist;
};
}
cl::desc("Show code coverage only for functions with the given name"),
cl::ZeroOrMore, cl::cat(FilteringCategory));
+ cl::list<std::string> NameFilterFiles(
+ "name-whitelist", cl::Optional,
+ cl::desc("Show code coverage only for functions listed in the given "
+ "file"),
+ cl::ZeroOrMore, cl::cat(FilteringCategory));
+
cl::list<std::string> NameRegexFilters(
"name-regex", cl::Optional,
cl::desc("Show code coverage only for functions that match the given "
ViewOpts.DemanglerOpts.swap(DemanglerOpts);
}
+ // Read in -name-whitelist files.
+ if (!NameFilterFiles.empty()) {
+ std::string SpecialCaseListErr;
+ NameWhitelist =
+ SpecialCaseList::create(NameFilterFiles, SpecialCaseListErr);
+ if (!NameWhitelist)
+ error(SpecialCaseListErr);
+ }
+
// Create the function filters
- if (!NameFilters.empty() || !NameRegexFilters.empty()) {
+ if (!NameFilters.empty() || NameWhitelist || !NameRegexFilters.empty()) {
auto NameFilterer = llvm::make_unique<CoverageFilters>();
for (const auto &Name : NameFilters)
NameFilterer->push_back(llvm::make_unique<NameCoverageFilter>(Name));
+ if (NameWhitelist)
+ NameFilterer->push_back(
+ llvm::make_unique<NameWhitelistCoverageFilter>(*NameWhitelist));
for (const auto &Regex : NameRegexFilters)
NameFilterer->push_back(
llvm::make_unique<NameRegexCoverageFilter>(Regex));
return llvm::Regex(Regex).match(Function.Name);
}
+bool NameWhitelistCoverageFilter::matches(
+ const coverage::FunctionRecord &Function) {
+ return Whitelist.inSection("whitelist_fun", Function.Name);
+}
+
bool RegionCoverageFilter::matches(const coverage::FunctionRecord &Function) {
return PassesThreshold(FunctionCoverageSummary::get(Function)
.RegionCoverage.getPercentCovered());
#define LLVM_COV_COVERAGEFILTERS_H
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
+#include "llvm/Support/SpecialCaseList.h"
#include <memory>
#include <vector>
bool matches(const coverage::FunctionRecord &Function) override;
};
+/// \brief Matches functions whose name appears in a SpecialCaseList in the
+/// whitelist_fun section.
+class NameWhitelistCoverageFilter : public CoverageFilter {
+ const SpecialCaseList &Whitelist;
+
+public:
+ NameWhitelistCoverageFilter(const SpecialCaseList &Whitelist)
+ : Whitelist(Whitelist) {}
+
+ bool matches(const coverage::FunctionRecord &Function) override;
+};
+
/// \brief Matches numbers that pass a certain threshold.
template <typename T> class StatisticThresholdFilter {
public: