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"
91 Preprocessor *ModuleExpanderPP) {}
112 virtual void check(
const ast_matchers::MatchFinder::MatchResult &Result) {}
115 DiagnosticBuilder
diag(SourceLocation
Loc, StringRef Description,
116 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
119 DiagnosticBuilder
diag(StringRef Description,
120 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
125 DiagnosticIDs::Level Level = DiagnosticIDs::Warning)
const;
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_v<T>, 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);
214 template <
typename T>
215 std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
216 get(StringRef LocalName, std::optional<T> Default)
const {
217 if (std::optional<StringRef> Value =
get(LocalName)) {
218 if (Value ==
"" || Value ==
"none" || Value ==
"null" ||
219 (std::is_unsigned_v<T> && Value ==
"-1"))
222 if (!StringRef(*Value).getAsInteger(10, Result))
224 diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
238 template <
typename T>
239 std::enable_if_t<std::is_integral_v<T>, T>
get(StringRef LocalName,
241 return get<T>(LocalName).value_or(Default);
254 template <
typename T>
255 std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
257 std::optional<StringRef> ValueOr =
get(LocalName);
258 bool IsGlobal =
false;
266 if (!StringRef(*ValueOr).getAsInteger(10, Result))
268 diagnoseBadIntegerOption(
269 IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
284 template <
typename T>
285 std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
287 std::optional<StringRef> ValueOr =
get(LocalName);
288 bool IsGlobal =
false;
296 if (ValueOr ==
"" || ValueOr ==
"none" || ValueOr ==
"null" ||
297 (std::is_unsigned_v<T> && ValueOr ==
"-1"))
299 if (!StringRef(*ValueOr).getAsInteger(10, Result))
301 diagnoseBadIntegerOption(
302 IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
316 template <
typename T>
317 std::enable_if_t<std::is_integral_v<T>, T>
319 return getLocalOrGlobal<T>(LocalName).value_or(Default);
334 template <
typename T>
335 std::enable_if_t<std::is_enum_v<T>, std::optional<T>>
336 get(StringRef LocalName,
bool IgnoreCase =
false)
const {
337 if (std::optional<int64_t> ValueOr =
338 getEnumInt(LocalName, typeEraseMapping<T>(),
false, IgnoreCase))
339 return static_cast<T
>(*ValueOr);
355 template <
typename T>
356 std::enable_if_t<std::is_enum_v<T>, T>
get(StringRef LocalName, T Default,
357 bool IgnoreCase =
false)
const {
358 return get<T>(LocalName, IgnoreCase).value_or(Default);
374 template <
typename T>
375 std::enable_if_t<std::is_enum_v<T>, std::optional<T>>
377 if (std::optional<int64_t> ValueOr =
378 getEnumInt(LocalName, typeEraseMapping<T>(),
true, IgnoreCase))
379 return static_cast<T
>(*ValueOr);
396 template <
typename T>
397 std::enable_if_t<std::is_enum_v<T>, T>
399 bool IgnoreCase =
false)
const {
400 return getLocalOrGlobal<T>(LocalName, IgnoreCase).value_or(Default);
406 StringRef Value)
const;
410 template <
typename T>
411 std::enable_if_t<std::is_integral_v<T>>
414 if constexpr (std::is_signed_v<T>)
415 storeInt(
Options, LocalName, Value);
417 storeUnsigned(
Options, LocalName, Value);
423 template <
typename T>
424 std::enable_if_t<std::is_integral_v<T>>
426 std::optional<T> Value)
const {
438 template <
typename T>
439 std::enable_if_t<std::is_enum_v<T>>
442 ArrayRef<std::pair<T, StringRef>> Mapping =
444 auto Iter = llvm::find_if(
445 Mapping, [&](
const std::pair<T, StringRef> &NameAndEnum) {
446 return NameAndEnum.first == Value;
448 assert(Iter != Mapping.end() &&
"Unknown Case Value");
453 using NameAndValue = std::pair<int64_t, StringRef>;
455 std::optional<int64_t> getEnumInt(StringRef LocalName,
456 ArrayRef<NameAndValue> Mapping,
457 bool CheckGlobal,
bool IgnoreCase)
const;
459 template <
typename T>
460 std::enable_if_t<std::is_enum_v<T>, std::vector<NameAndValue>>
461 typeEraseMapping()
const {
462 ArrayRef<std::pair<T, StringRef>> Mapping =
464 std::vector<NameAndValue> Result;
465 Result.reserve(Mapping.size());
466 for (
auto &MappedItem : Mapping) {
467 Result.emplace_back(
static_cast<int64_t
>(MappedItem.first),
474 int64_t Value)
const;
477 StringRef LocalName, uint64_t Value)
const;
479 std::string NamePrefix;
481 ClangTidyContext *Context;
485 void run(
const ast_matchers::MatchFinder::MatchResult &Result)
override;
486 std::string CheckName;
487 ClangTidyContext *Context;
494 const LangOptions &
getLangOpts()
const {
return Context->getLangOpts(); }
498 return Context->areDiagsSelfContained();
500 StringRef
getID()
const override {
return CheckName; }
513ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName)
const;
525ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName)
const;
530void ClangTidyCheck::OptionsView::store<bool>(
Provides access to the ClangTidyCheck options via check-local names.
std::enable_if_t< std::is_integral_v< T > > store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) const
Stores an option with the check-local name LocalName with integer value Value to Options.
std::enable_if_t< std::is_integral_v< T > > store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, std::optional< T > Value) const
Stores an option with the check-local name LocalName with integer value Value to Options.
std::optional< StringRef > get(StringRef LocalName) const
Read a named option from the Context.
std::enable_if_t< std::is_integral_v< T >, std::optional< T > > getLocalOrGlobal(StringRef LocalName) const
Read a named option from the Context and parse it as an integral type T.
std::enable_if_t< std::is_enum_v< T >, T > getLocalOrGlobal(StringRef LocalName, T Default, bool IgnoreCase=false) const
Read a named option from the Context and parse it as an enum type T.
std::enable_if_t< std::is_enum_v< T >, T > get(StringRef LocalName, T Default, bool IgnoreCase=false) const
Read a named option from the Context and parse it as an enum type T.
std::enable_if_t< std::is_integral_v< T >, std::optional< T > > getLocalOrGlobal(StringRef LocalName, std::optional< T > Default) const
Read a named option from the Context and parse it as an integral type T.
std::optional< StringRef > getLocalOrGlobal(StringRef LocalName) const
Read a named option from the Context.
std::enable_if_t< std::is_integral_v< T >, std::optional< T > > get(StringRef LocalName, std::optional< T > Default) const
Read a named option from the Context and parse it as an integral type T.
std::enable_if_t< std::is_integral_v< T >, T > get(StringRef LocalName, T Default) const
Read a named option from the Context and parse it as an integral type T.
std::enable_if_t< std::is_integral_v< T >, T > getLocalOrGlobal(StringRef LocalName, T Default) const
Read a named option from the Context and parse it as an integral type T.
std::enable_if_t< std::is_enum_v< T > > store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) const
Stores an option with the check-local name LocalName as the string representation of the Enum Value t...
std::enable_if_t< std::is_enum_v< T >, std::optional< T > > getLocalOrGlobal(StringRef LocalName, bool IgnoreCase=false) const
Read a named option from the Context and parse it as an enum type T.
std::enable_if_t< std::is_integral_v< T >, std::optional< T > > get(StringRef LocalName) const
Read a named option from the Context and parse it as an integral type T.
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
std::enable_if_t< std::is_enum_v< T >, std::optional< T > > get(StringRef LocalName, bool IgnoreCase=false) const
Read a named option from the Context and parse it as an enum type T.
Base class for all clang-tidy checks.
virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
Override this to register PPCallbacks in the preprocessor.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
virtual void storeOptions(ClangTidyOptions::OptionMap &Options)
Should store all options supported by this check with their current values or default values for opti...
DiagnosticBuilder configurationDiag(StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning) const
Adds a diagnostic to report errors in the check's configuration.
StringRef getID() const override
bool areDiagsSelfContained() const
Returns true when the check is run in a use case when only 1 fix will be applied at a time.
StringRef getCurrentMainFile() const
Returns the main file name of the current translation unit.
virtual bool isLanguageVersionSupported(const LangOptions &LangOpts) const
Override this to disable registering matchers and PP callbacks if an invalid language version is bein...
virtual void registerMatchers(ast_matchers::MatchFinder *Finder)
Override this to register AST matchers with Finder.
const LangOptions & getLangOpts() const
Returns the language options from the context.
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result)
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::StringMap< ClangTidyValue > OptionMap
This class should be specialized by any enum type that needs to be converted to and from an llvm::Str...
static ArrayRef< std::pair< T, StringRef > > getEnumMapping()=delete