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 /// Matches numbers that pass a certain threshold.
83 template <typename T> class StatisticThresholdFilter {
84 public:
85   enum Operation { LessThan, GreaterThan };
86 
87 protected:
88   Operation Op;
89   T Threshold;
90 
91   StatisticThresholdFilter(Operation Op, T Threshold)
92       : Op(Op), Threshold(Threshold) {}
93 
94   /// Return true if the given number is less than
95   /// or greater than the certain threshold.
96   bool PassesThreshold(T Value) const {
97     switch (Op) {
98     case LessThan:
99       return Value < Threshold;
100     case GreaterThan:
101       return Value > Threshold;
102     }
103     return false;
104   }
105 };
106 
107 /// Matches functions whose region coverage percentage
108 /// is above/below a certain percentage.
109 class RegionCoverageFilter : public CoverageFilter,
110                              public StatisticThresholdFilter<double> {
111 public:
112   RegionCoverageFilter(Operation Op, double Threshold)
113       : StatisticThresholdFilter(Op, Threshold) {}
114 
115   bool matches(const coverage::CoverageMapping &CM,
116                const coverage::FunctionRecord &Function) const override;
117 };
118 
119 /// Matches functions whose line coverage percentage
120 /// is above/below a certain percentage.
121 class LineCoverageFilter : public CoverageFilter,
122                            public StatisticThresholdFilter<double> {
123 public:
124   LineCoverageFilter(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 /// A collection of filters.
132 /// Matches functions that match any filters contained
133 /// in an instance of this class.
134 class CoverageFilters : public CoverageFilter {
135 protected:
136   std::vector<std::unique_ptr<CoverageFilter>> Filters;
137 
138 public:
139   /// Append a filter to this collection.
140   void push_back(std::unique_ptr<CoverageFilter> Filter);
141 
142   bool empty() const { return Filters.empty(); }
143 
144   bool matches(const coverage::CoverageMapping &CM,
145                const coverage::FunctionRecord &Function) const override;
146 
147   bool matchesFilename(StringRef Filename) const override;
148 };
149 
150 /// A collection of filters.
151 /// Matches functions that match all of the filters contained
152 /// in an instance of this class.
153 class CoverageFiltersMatchAll : public CoverageFilters {
154 public:
155   bool matches(const coverage::CoverageMapping &CM,
156                const coverage::FunctionRecord &Function) const override;
157 };
158 
159 } // namespace llvm
160 
161 #endif // LLVM_COV_COVERAGEFILTERS_H
162