1 //===- CoverageFilters.h - Function coverage mapping filters --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // These classes provide filtering for function coverage mapping records.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_COV_COVERAGEFILTERS_H
14 #define LLVM_COV_COVERAGEFILTERS_H
15 
16 #include "CoverageSummaryInfo.h"
17 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
18 #include "llvm/Support/SpecialCaseList.h"
19 #include <memory>
20 #include <vector>
21 
22 namespace llvm {
23 
24 /// Matches specific functions that pass the requirement of this filter.
25 class CoverageFilter {
26 public:
27   virtual ~CoverageFilter() {}
28 
29   /// Return true if the function passes the requirements of this filter.
30   virtual bool matches(const coverage::CoverageMapping &CM,
31                        const coverage::FunctionRecord &Function) const {
32     return true;
33   }
34 
35   /// Return true if the filename passes the requirements of this filter.
36   virtual bool matchesFilename(StringRef Filename) const {
37     return true;
38   }
39 };
40 
41 /// Matches functions that contain a specific string in their name.
42 class NameCoverageFilter : public CoverageFilter {
43   StringRef Name;
44 
45 public:
46   NameCoverageFilter(StringRef Name) : Name(Name) {}
47 
48   bool matches(const coverage::CoverageMapping &CM,
49                const coverage::FunctionRecord &Function) const override;
50 };
51 
52 /// Matches functions whose name matches a certain regular expression.
53 class NameRegexCoverageFilter : public CoverageFilter {
54   StringRef Regex;
55 
56 public:
57   NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {}
58 
59   bool matches(const coverage::CoverageMapping &CM,
60                const coverage::FunctionRecord &Function) const override;
61 
62   bool matchesFilename(StringRef Filename) const override;
63 };
64 
65 /// Matches functions whose name appears in a SpecialCaseList in the
66 /// whitelist_fun section.
67 class NameWhitelistCoverageFilter : public CoverageFilter {
68   const SpecialCaseList &Whitelist;
69 
70 public:
71   NameWhitelistCoverageFilter(const SpecialCaseList &Whitelist)
72       : Whitelist(Whitelist) {}
73 
74   bool matches(const coverage::CoverageMapping &CM,
75                const coverage::FunctionRecord &Function) const override;
76 };
77 
78 /// Matches numbers that pass a certain threshold.
79 template <typename T> class StatisticThresholdFilter {
80 public:
81   enum Operation { LessThan, GreaterThan };
82 
83 protected:
84   Operation Op;
85   T Threshold;
86 
87   StatisticThresholdFilter(Operation Op, T Threshold)
88       : Op(Op), Threshold(Threshold) {}
89 
90   /// Return true if the given number is less than
91   /// or greater than the certain threshold.
92   bool PassesThreshold(T Value) const {
93     switch (Op) {
94     case LessThan:
95       return Value < Threshold;
96     case GreaterThan:
97       return Value > Threshold;
98     }
99     return false;
100   }
101 };
102 
103 /// Matches functions whose region coverage percentage
104 /// is above/below a certain percentage.
105 class RegionCoverageFilter : public CoverageFilter,
106                              public StatisticThresholdFilter<double> {
107 public:
108   RegionCoverageFilter(Operation Op, double Threshold)
109       : StatisticThresholdFilter(Op, Threshold) {}
110 
111   bool matches(const coverage::CoverageMapping &CM,
112                const coverage::FunctionRecord &Function) const override;
113 };
114 
115 /// Matches functions whose line coverage percentage
116 /// is above/below a certain percentage.
117 class LineCoverageFilter : public CoverageFilter,
118                            public StatisticThresholdFilter<double> {
119 public:
120   LineCoverageFilter(Operation Op, double Threshold)
121       : StatisticThresholdFilter(Op, Threshold) {}
122 
123   bool matches(const coverage::CoverageMapping &CM,
124                const coverage::FunctionRecord &Function) const override;
125 };
126 
127 /// A collection of filters.
128 /// Matches functions that match any filters contained
129 /// in an instance of this class.
130 class CoverageFilters : public CoverageFilter {
131 protected:
132   std::vector<std::unique_ptr<CoverageFilter>> Filters;
133 
134 public:
135   /// Append a filter to this collection.
136   void push_back(std::unique_ptr<CoverageFilter> Filter);
137 
138   bool empty() const { return Filters.empty(); }
139 
140   bool matches(const coverage::CoverageMapping &CM,
141                const coverage::FunctionRecord &Function) const override;
142 
143   bool matchesFilename(StringRef Filename) const override;
144 };
145 
146 /// A collection of filters.
147 /// Matches functions that match all of the filters contained
148 /// in an instance of this class.
149 class CoverageFiltersMatchAll : public CoverageFilters {
150 public:
151   bool matches(const coverage::CoverageMapping &CM,
152                const coverage::FunctionRecord &Function) const override;
153 };
154 
155 } // namespace llvm
156 
157 #endif // LLVM_COV_COVERAGEFILTERS_H
158