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 "llvm/ADT/StringRef.h"
17 #include <memory>
18 #include <vector>
19 
20 namespace llvm {
21 class SpecialCaseList;
22 
23 namespace coverage {
24 class CoverageMapping;
25 struct FunctionRecord;
26 } // namespace coverage
27 
28 /// Matches specific functions that pass the requirement of this filter.
29 class CoverageFilter {
30 public:
31   virtual ~CoverageFilter() {}
32 
33   /// Return true if the function passes the requirements of this filter.
34   virtual bool matches(const coverage::CoverageMapping &CM,
35                        const coverage::FunctionRecord &Function) const {
36     return true;
37   }
38 
39   /// Return true if the filename passes the requirements of this filter.
40   virtual bool matchesFilename(StringRef Filename) const {
41     return true;
42   }
43 };
44 
45 /// Matches functions that contain a specific string in their name.
46 class NameCoverageFilter : public CoverageFilter {
47   StringRef Name;
48 
49 public:
50   NameCoverageFilter(StringRef Name) : Name(Name) {}
51 
52   bool matches(const coverage::CoverageMapping &CM,
53                const coverage::FunctionRecord &Function) const override;
54 };
55 
56 /// Matches functions whose name matches a certain regular expression.
57 class NameRegexCoverageFilter : public CoverageFilter {
58   StringRef Regex;
59 
60 public:
61   NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {}
62 
63   bool matches(const coverage::CoverageMapping &CM,
64                const coverage::FunctionRecord &Function) const override;
65 
66   bool matchesFilename(StringRef Filename) const override;
67 };
68 
69 /// Matches functions whose name appears in a SpecialCaseList in the
70 /// allowlist_fun section.
71 class NameAllowlistCoverageFilter : public CoverageFilter {
72   const SpecialCaseList &Allowlist;
73 
74 public:
75   NameAllowlistCoverageFilter(const SpecialCaseList &Allowlist)
76       : Allowlist(Allowlist) {}
77 
78   bool matches(const coverage::CoverageMapping &CM,
79                const coverage::FunctionRecord &Function) const override;
80 };
81 
82 // TODO: Remove this class when -name-whitelist option is removed.
83 class NameWhitelistCoverageFilter : public CoverageFilter {
84   const SpecialCaseList &Whitelist;
85 
86 public:
87   NameWhitelistCoverageFilter(const SpecialCaseList &Whitelist)
88       : Whitelist(Whitelist) {}
89 
90   bool matches(const coverage::CoverageMapping &CM,
91                const coverage::FunctionRecord &Function) const override;
92 };
93 
94 /// Matches numbers that pass a certain threshold.
95 template <typename T> class StatisticThresholdFilter {
96 public:
97   enum Operation { LessThan, GreaterThan };
98 
99 protected:
100   Operation Op;
101   T Threshold;
102 
103   StatisticThresholdFilter(Operation Op, T Threshold)
104       : Op(Op), Threshold(Threshold) {}
105 
106   /// Return true if the given number is less than
107   /// or greater than the certain threshold.
108   bool PassesThreshold(T Value) const {
109     switch (Op) {
110     case LessThan:
111       return Value < Threshold;
112     case GreaterThan:
113       return Value > Threshold;
114     }
115     return false;
116   }
117 };
118 
119 /// Matches functions whose region coverage percentage
120 /// is above/below a certain percentage.
121 class RegionCoverageFilter : public CoverageFilter,
122                              public StatisticThresholdFilter<double> {
123 public:
124   RegionCoverageFilter(Operation Op, double Threshold)
125       : StatisticThresholdFilter(Op, Threshold) {}
126 
127   bool matches(const coverage::CoverageMapping &CM,
128                const coverage::FunctionRecord &Function) const override;
129 };
130 
131 /// Matches functions whose line coverage percentage
132 /// is above/below a certain percentage.
133 class LineCoverageFilter : public CoverageFilter,
134                            public StatisticThresholdFilter<double> {
135 public:
136   LineCoverageFilter(Operation Op, double Threshold)
137       : StatisticThresholdFilter(Op, Threshold) {}
138 
139   bool matches(const coverage::CoverageMapping &CM,
140                const coverage::FunctionRecord &Function) const override;
141 };
142 
143 /// A collection of filters.
144 /// Matches functions that match any filters contained
145 /// in an instance of this class.
146 class CoverageFilters : public CoverageFilter {
147 protected:
148   std::vector<std::unique_ptr<CoverageFilter>> Filters;
149 
150 public:
151   /// Append a filter to this collection.
152   void push_back(std::unique_ptr<CoverageFilter> Filter);
153 
154   bool empty() const { return Filters.empty(); }
155 
156   bool matches(const coverage::CoverageMapping &CM,
157                const coverage::FunctionRecord &Function) const override;
158 
159   bool matchesFilename(StringRef Filename) const override;
160 };
161 
162 /// A collection of filters.
163 /// Matches functions that match all of the filters contained
164 /// in an instance of this class.
165 class CoverageFiltersMatchAll : public CoverageFilters {
166 public:
167   bool matches(const coverage::CoverageMapping &CM,
168                const coverage::FunctionRecord &Function) const override;
169 };
170 
171 } // namespace llvm
172 
173 #endif // LLVM_COV_COVERAGEFILTERS_H
174