================ @@ -0,0 +1,163 @@ +//===--- UseToUnderlyingCheck.cpp - clang-tidy ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "UseToUnderlyingCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy { + +template <> +struct OptionEnumMapping<modernize::UseToUnderlyingCheck::ImpreciseCastsKind> { + static llvm::ArrayRef< + std::pair<modernize::UseToUnderlyingCheck::ImpreciseCastsKind, StringRef>> + getEnumMapping() { + using ImpreciseCastsKind = + modernize::UseToUnderlyingCheck::ImpreciseCastsKind; + static constexpr std::pair<ImpreciseCastsKind, StringRef> Mapping[] = { + {ImpreciseCastsKind::Ignore, "Ignore"}, + {ImpreciseCastsKind::Warn, "Warn"}, + {ImpreciseCastsKind::PreserveType, "PreserveType"}, + {ImpreciseCastsKind::UseUnderlyingType, "UseUnderlyingType"}, + }; + return {Mapping}; + } +}; + +} // namespace clang::tidy + +namespace clang::tidy::modernize { + +UseToUnderlyingCheck::UseToUnderlyingCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + ImpreciseCasts(Options.get("ImpreciseCasts", ImpreciseCastsKind::Warn)), + ReplacementFunction( + Options.get("ReplacementFunction", "std::to_underlying")), + IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", + utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()), + MaybeHeaderToInclude(Options.get("ReplacementFunctionHeader")) { + if (!MaybeHeaderToInclude && ReplacementFunction == "std::to_underlying") + MaybeHeaderToInclude = "<utility>"; +} + +bool UseToUnderlyingCheck::isLanguageVersionSupported( + const LangOptions &LangOpts) const { + // std::to_underlying is a C++23 library facility, but a user-provided + // replacement (e.g. llvm::to_underlying) only requires scoped enumerations, + // which are available since C++11. + if (ReplacementFunction == "std::to_underlying") + return LangOpts.CPlusPlus23; + return LangOpts.CPlusPlus11; +} + +void UseToUnderlyingCheck::registerPPCallbacks(const SourceManager &SM, + Preprocessor *PP, + Preprocessor *ModuleExpanderPP) { + IncludeInserter.registerPreprocessor(PP); +} + +void UseToUnderlyingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "ImpreciseCasts", ImpreciseCasts); + Options.store(Opts, "ReplacementFunction", ReplacementFunction); + Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); + if (MaybeHeaderToInclude) + Options.store(Opts, "ReplacementFunctionHeader", *MaybeHeaderToInclude); +} + +void UseToUnderlyingCheck::registerMatchers(MatchFinder *Finder) { + // Match an explicit cast (``static_cast``, C-style or functional) whose + // operand is an expression of scoped-enumeration type. The destination type + // is validated in check() so that the same code path handles precise and + // imprecise conversions. + Finder->addMatcher( + explicitCastExpr( + unless(isInTemplateInstantiation()), ---------------- zwuis wrote:
This is redundant because of `TK_IgnoreUnlessSpelledInSource`. https://github.com/llvm/llvm-project/pull/210459 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
