1 /** 2 * Copyright (c) 2021-2022 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 panda::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 Image()112 PandaString Image() const 113 { 114 PandaString result {"\n"}; 115 result += " Verifier messages config '" + name_ + "'\n"; 116 result += " Uplevel configs: "; 117 for (const auto &up : uplevel_) { 118 result += "'" + up.get().name_ + "' "; 119 } 120 result += "\n"; 121 result += " Show: "; 122 showInfo_.EnumerateFlags([&](auto flag) { 123 switch (flag) { 124 case MethodOption::InfoType::CONTEXT: 125 result += "'context' "; 126 break; 127 case MethodOption::InfoType::REG_CHANGES: 128 result += "'reg-changes' "; 129 break; 130 case MethodOption::InfoType::CFLOW: 131 result += "'cflow' "; 132 break; 133 case MethodOption::InfoType::JOBFILL: 134 result += "'jobfill' "; 135 break; 136 default: 137 result += "<unknown>("; 138 result += std::to_string(static_cast<size_t>(flag)); 139 result += ") "; 140 break; 141 } 142 return true; 143 }); 144 result += "\n"; 145 result += " Checks: "; 146 enabledCheck_.EnumerateValues([&](auto flag) { 147 switch (flag) { 148 case MethodOption::CheckType::TYPING: 149 result += "'typing' "; 150 break; 151 case MethodOption::CheckType::ABSINT: 152 result += "'absint' "; 153 break; 154 case MethodOption::CheckType::REG_USAGE: 155 result += "'reg-usage' "; 156 break; 157 case MethodOption::CheckType::CFLOW: 158 result += "'cflow' "; 159 break; 160 case MethodOption::CheckType::RESOLVE_ID: 161 result += "'resolve-id' "; 162 break; 163 default: 164 result += "<unknown>("; 165 result += std::to_string(static_cast<size_t>(flag)); 166 result += ") "; 167 break; 168 } 169 return true; 170 }); 171 172 result += "\n"; 173 result += ImageMessages(); 174 return result; 175 } 176 MethodOptions(PandaString paramName)177 explicit MethodOptions(PandaString paramName) : name_ {std::move(paramName)} {} 178 GetName()179 const PandaString &GetName() const 180 { 181 return name_; 182 } 183 Check()184 MethodOption::CheckEnum &Check() 185 { 186 return enabledCheck_; 187 } 188 Check()189 const MethodOption::CheckEnum &Check() const 190 { 191 return enabledCheck_; 192 } 193 194 private: ImageMessages()195 PandaString ImageMessages() const 196 { 197 PandaString result; 198 result += " Messages:\n"; 199 for (const auto &m : msgClasses_) { 200 const auto &msgNum = m.first; 201 const auto &klass = m.second; 202 result += " "; 203 result += VerifierMessageToString(msgNum); 204 result += " : "; 205 switch (klass) { 206 case MethodOption::MsgClass::ERROR: 207 result += "E"; 208 break; 209 case MethodOption::MsgClass::WARNING: 210 result += "W"; 211 break; 212 case MethodOption::MsgClass::HIDDEN: 213 result += "H"; 214 break; 215 default: 216 result += "<unknown>("; 217 result += std::to_string(static_cast<size_t>(klass)); 218 result += ")"; 219 break; 220 } 221 result += "\n"; 222 } 223 return result; 224 } 225 226 const PandaString name_; 227 PandaVector<std::reference_wrapper<const MethodOptions>> uplevel_; 228 PandaUnorderedMap<VerifierMessage, MethodOption::MsgClass> msgClasses_; 229 MethodOption::InfoTypeFlag showInfo_; 230 MethodOption::CheckEnum enabledCheck_; 231 232 // In verifier_messages_data.cpp 233 struct VerifierMessageDefault { 234 VerifierMessage msg; 235 MethodOption::MsgClass msgClass; 236 }; 237 238 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 239 static VerifierMessageDefault messageDefaults_[]; 240 }; 241 242 } // namespace panda::verifier 243 244 #endif // PANDA_VERIFIER_DEBUG_OPTIONS_METHOD_OPTIONS_H 245