• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_VERIFIER_DEBUG_OPTIONS_METHOD_OPTIONS_H_
17 #define PANDA_VERIFIER_DEBUG_OPTIONS_METHOD_OPTIONS_H_
18 
19 #include "runtime/include/mem/panda_containers.h"
20 #include "runtime/include/mem/panda_string.h"
21 #include "verification/util/flags.h"
22 #include "verification/util/saturated_enum.h"
23 #include "verifier_messages.h"
24 
25 #include <functional>
26 
27 namespace ark::verifier {
28 
29 struct MethodOption {
30     enum class InfoType { CONTEXT, REG_CHANGES, CFLOW, JOBFILL };
31     enum class MsgClass { ERROR, WARNING, HIDDEN };
32     enum class CheckType { CFLOW, RESOLVE_ID, REG_USAGE, TYPING, ABSINT };
33     using InfoTypeFlag =
34         FlagsForEnum<unsigned, InfoType, InfoType::CONTEXT, InfoType::REG_CHANGES, InfoType::CFLOW, InfoType::JOBFILL>;
35     using MsgClassFlag = FlagsForEnum<unsigned, MsgClass, MsgClass::ERROR, MsgClass::WARNING, MsgClass::HIDDEN>;
36     using CheckEnum = SaturatedEnum<CheckType, CheckType::ABSINT, CheckType::TYPING, CheckType::REG_USAGE,
37                                     CheckType::RESOLVE_ID, CheckType::CFLOW>;
38 };
39 
40 class MethodOptions {
41 public:
ShowContext()42     bool ShowContext() const
43     {
44         return showInfo_[MethodOption::InfoType::CONTEXT];
45     }
46 
ShowRegChanges()47     bool ShowRegChanges() const
48     {
49         return showInfo_[MethodOption::InfoType::REG_CHANGES];
50     }
51 
ShowCflow()52     bool ShowCflow() const
53     {
54         return showInfo_[MethodOption::InfoType::CFLOW];
55     }
56 
ShowJobFill()57     bool ShowJobFill() const
58     {
59         return showInfo_[MethodOption::InfoType::JOBFILL];
60     }
61 
SetShow(MethodOption::InfoType info)62     void SetShow(MethodOption::InfoType info)
63     {
64         showInfo_[info] = true;
65     }
66 
SetMsgClass(VerifierMessage msgNum,MethodOption::MsgClass klass)67     void SetMsgClass(VerifierMessage msgNum, MethodOption::MsgClass klass)
68     {
69         msgClasses_[msgNum] = klass;
70     }
71 
72     template <typename Validator>
SetMsgClass(Validator validator,size_t msgNum,MethodOption::MsgClass klass)73     void SetMsgClass(Validator validator, size_t msgNum, MethodOption::MsgClass klass)
74     {
75         if (validator(static_cast<VerifierMessage>(msgNum))) {
76             msgClasses_[static_cast<VerifierMessage>(msgNum)] = klass;
77         }
78     }
79 
AddUpLevel(const MethodOptions & up)80     void AddUpLevel(const MethodOptions &up)
81     {
82         uplevel_.push_back(std::cref(up));
83     }
84 
CanHandleMsg(VerifierMessage msgNum)85     bool CanHandleMsg(VerifierMessage msgNum) const
86     {
87         return msgClasses_.count(msgNum) > 0;
88     }
89 
90     MethodOption::MsgClass MsgClassFor(VerifierMessage msgNum) const;
91 
IsInMsgClass(VerifierMessage msgNum,MethodOption::MsgClass klass)92     bool IsInMsgClass(VerifierMessage msgNum, MethodOption::MsgClass klass) const
93     {
94         return MsgClassFor(msgNum) == klass;
95     }
96 
IsHidden(VerifierMessage msgNum)97     bool IsHidden(VerifierMessage msgNum) const
98     {
99         return IsInMsgClass(msgNum, MethodOption::MsgClass::HIDDEN);
100     }
101 
IsWarning(VerifierMessage msgNum)102     bool IsWarning(VerifierMessage msgNum) const
103     {
104         return IsInMsgClass(msgNum, MethodOption::MsgClass::WARNING);
105     }
106 
IsError(VerifierMessage msgNum)107     bool IsError(VerifierMessage msgNum) const
108     {
109         return IsInMsgClass(msgNum, MethodOption::MsgClass::ERROR);
110     }
111 
112     template <typename Flag>
EnumerateFlagsHandler(PandaString & result,Flag flag)113     static bool EnumerateFlagsHandler(PandaString &result, Flag flag)
114     {
115         switch (flag) {
116             case MethodOption::InfoType::CONTEXT:
117                 result += "'context' ";
118                 break;
119             case MethodOption::InfoType::REG_CHANGES:
120                 result += "'reg-changes' ";
121                 break;
122             case MethodOption::InfoType::CFLOW:
123                 result += "'cflow' ";
124                 break;
125             case MethodOption::InfoType::JOBFILL:
126                 result += "'jobfill' ";
127                 break;
128             default:
129                 result += "<unknown>(";
130                 result += std::to_string(static_cast<size_t>(flag));
131                 result += ") ";
132                 break;
133         }
134         return true;
135     }
136 
Image()137     PandaString Image() const
138     {
139         PandaString result {"\n"};
140         result += " Verifier messages config '" + name_ + "'\n";
141         result += "  Uplevel configs: ";
142         for (const auto &up : uplevel_) {
143             result += "'" + up.get().name_ + "' ";
144         }
145         result += "\n";
146         result += "  Show: ";
147         showInfo_.EnumerateFlags([&](auto flag) { return MethodOptions::EnumerateFlagsHandler(result, flag); });
148         result += "\n";
149         result += "  Checks: ";
150         enabledCheck_.EnumerateValues([&](auto flag) {
151             switch (flag) {
152                 case MethodOption::CheckType::TYPING:
153                     result += "'typing' ";
154                     break;
155                 case MethodOption::CheckType::ABSINT:
156                     result += "'absint' ";
157                     break;
158                 case MethodOption::CheckType::REG_USAGE:
159                     result += "'reg-usage' ";
160                     break;
161                 case MethodOption::CheckType::CFLOW:
162                     result += "'cflow' ";
163                     break;
164                 case MethodOption::CheckType::RESOLVE_ID:
165                     result += "'resolve-id' ";
166                     break;
167                 default:
168                     result += "<unknown>(";
169                     result += std::to_string(static_cast<size_t>(flag));
170                     result += ") ";
171                     break;
172             }
173             return true;
174         });
175 
176         result += "\n";
177         result += ImageMessages();
178         return result;
179     }
180 
MethodOptions(PandaString paramName)181     explicit MethodOptions(PandaString paramName) : name_ {std::move(paramName)} {}
182 
GetName()183     const PandaString &GetName() const
184     {
185         return name_;
186     }
187 
Check()188     MethodOption::CheckEnum &Check()
189     {
190         return enabledCheck_;
191     }
192 
Check()193     const MethodOption::CheckEnum &Check() const
194     {
195         return enabledCheck_;
196     }
197 
198 private:
ImageMessages()199     PandaString ImageMessages() const
200     {
201         PandaString result;
202         result += "  Messages:\n";
203         for (const auto &m : msgClasses_) {
204             const auto &msgNum = m.first;
205             const auto &klass = m.second;
206             result += "    ";
207             result += VerifierMessageToString(msgNum);
208             result += " : ";
209             switch (klass) {
210                 case MethodOption::MsgClass::ERROR:
211                     result += "E";
212                     break;
213                 case MethodOption::MsgClass::WARNING:
214                     result += "W";
215                     break;
216                 case MethodOption::MsgClass::HIDDEN:
217                     result += "H";
218                     break;
219                 default:
220                     result += "<unknown>(";
221                     result += std::to_string(static_cast<size_t>(klass));
222                     result += ")";
223                     break;
224             }
225             result += "\n";
226         }
227         return result;
228     }
229 
230     const PandaString name_;
231     PandaVector<std::reference_wrapper<const MethodOptions>> uplevel_;
232     PandaUnorderedMap<VerifierMessage, MethodOption::MsgClass> msgClasses_;
233     MethodOption::InfoTypeFlag showInfo_;
234     MethodOption::CheckEnum enabledCheck_;
235 
236     // In verifier_messages_data.cpp
237     struct VerifierMessageDefault {
238         VerifierMessage msg;
239         MethodOption::MsgClass msgClass;
240     };
241 
242     // NOLINTNEXTLINE(modernize-avoid-c-arrays)
243     static VerifierMessageDefault messageDefaults_[];
244 };
245 
246 }  // namespace ark::verifier
247 
248 #endif  // PANDA_VERIFIER_DEBUG_OPTIONS_METHOD_OPTIONS_H_
249