9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
15 #include "clang/Basic/Diagnostic.h"
17 #include <type_traits>
31 static ArrayRef<std::pair<T, StringRef>>
getEnumMapping() =
delete;
91 Preprocessor *ModuleExpanderPP) {}
112 virtual void check(
const ast_matchers::MatchFinder::MatchResult &Result) {}
140 void diagnoseBadIntegerOption(
const Twine &Lookup,
141 StringRef Unparsed)
const;
142 void diagnoseBadBooleanOption(
const Twine &Lookup,
143 StringRef Unparsed)
const;
144 void diagnoseBadEnumOption(
const Twine &Lookup, StringRef Unparsed,
145 StringRef Suggestion = StringRef())
const;
158 std::optional<StringRef>
get(StringRef LocalName)
const;
165 StringRef
get(StringRef LocalName, StringRef Default)
const;
192 template <
typename T>
193 std::enable_if_t<std::is_integral<T>::value, std::optional<T>>
194 get(StringRef LocalName)
const {
195 if (std::optional<StringRef> Value =
get(LocalName)) {
197 if (!StringRef(*Value).getAsInteger(10, Result))
199 diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
213 template <
typename T>
214 std::enable_if_t<std::is_integral<T>::value, T>
get(StringRef LocalName,
216 return get<T>(LocalName).value_or(Default);
229 template <
typename T>
230 std::enable_if_t<std::is_integral<T>::value, std::optional<T>>
232 std::optional<StringRef> ValueOr =
get(LocalName);
233 bool IsGlobal =
false;
241 if (!StringRef(*ValueOr).getAsInteger(10, Result))
243 diagnoseBadIntegerOption(
244 IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
258 template <
typename T>
259 std::enable_if_t<std::is_integral<T>::value, T>
261 return getLocalOrGlobal<T>(LocalName).value_or(Default);
276 template <
typename T>
277 std::enable_if_t<std::is_enum<T>::value, std::optional<T>>
278 get(StringRef LocalName,
bool IgnoreCase =
false)
const {
279 if (std::optional<int64_t> ValueOr =
280 getEnumInt(LocalName, typeEraseMapping<T>(),
false, IgnoreCase))
281 return static_cast<T
>(*ValueOr);
297 template <
typename T>
298 std::enable_if_t<std::is_enum<T>::value, T>
299 get(StringRef LocalName, T Default,
bool IgnoreCase =
false)
const {
300 return get<T>(LocalName, IgnoreCase).value_or(Default);
316 template <
typename T>
317 std::enable_if_t<std::is_enum<T>::value, std::optional<T>>
319 if (std::optional<int64_t> ValueOr =
320 getEnumInt(LocalName, typeEraseMapping<T>(),
true, IgnoreCase))
321 return static_cast<T
>(*ValueOr);
338 template <
typename T>
339 std::enable_if_t<std::is_enum<T>::value, T>
341 bool IgnoreCase =
false)
const {
342 return getLocalOrGlobal<T>(LocalName, IgnoreCase).value_or(Default);
348 StringRef Value)
const;
352 template <
typename T>
353 std::enable_if_t<std::is_integral<T>::value>
356 storeInt(
Options, LocalName, Value);
364 template <
typename T>
365 std::enable_if_t<std::is_enum<T>::value>
368 ArrayRef<std::pair<T, StringRef>> Mapping =
370 auto Iter = llvm::find_if(
371 Mapping, [&](
const std::pair<T, StringRef> &NameAndEnum) {
372 return NameAndEnum.first == Value;
374 assert(Iter != Mapping.end() &&
"Unknown Case Value");
379 using NameAndValue = std::pair<int64_t, StringRef>;
381 std::optional<int64_t> getEnumInt(StringRef LocalName,
382 ArrayRef<NameAndValue> Mapping,
383 bool CheckGlobal,
bool IgnoreCase)
const;
385 template <
typename T>
386 std::enable_if_t<std::is_enum<T>::value, std::vector<NameAndValue>>
387 typeEraseMapping()
const {
388 ArrayRef<std::pair<T, StringRef>> Mapping =
390 std::vector<NameAndValue> Result;
391 Result.reserve(Mapping.size());
392 for (
auto &MappedItem : Mapping) {
393 Result.emplace_back(
static_cast<int64_t
>(MappedItem.first),
400 int64_t Value)
const;
403 std::string NamePrefix;
405 ClangTidyContext *Context;
409 void run(
const ast_matchers::MatchFinder::MatchResult &Result)
override;
410 StringRef getID()
const override {
return CheckName; }
411 std::string CheckName;
412 ClangTidyContext *Context;
419 const LangOptions &
getLangOpts()
const {
return Context->getLangOpts(); }
423 return Context->areDiagsSelfContained();
437 ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName)
const;
449 ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName)
const;
454 void ClangTidyCheck::OptionsView::store<bool>(
462 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H