================ @@ -0,0 +1,284 @@ +//===--- UseStdNumbersCheck.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 "UseStdNumbersCheck.h" +#include "../ClangTidyDiagnosticConsumer.h" +#include "../utils/TransformerClangTidyCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/MathExtras.h" +#include <cstdint> +#include <cstdlib> +#include <string> +#include <utility> + +namespace { +using namespace clang::ast_matchers; +using clang::ast_matchers::internal::Matcher; +using clang::transformer::addInclude; +using clang::transformer::applyFirst; +using clang::transformer::ASTEdit; +using clang::transformer::cat; +using clang::transformer::changeTo; +using clang::transformer::edit; +using clang::transformer::EditGenerator; +using clang::transformer::flattenVector; +using clang::transformer::RewriteRuleWith; +using llvm::StringRef; + +constexpr auto DiffThreshold = 0.001; + +AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) { + return std::abs(Node.getValueAsApproximateDouble() - Value) < DiffThreshold; +} + +AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified, + Matcher<clang::QualType>, InnerMatcher) { + return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder, + Builder); +} + +AST_MATCHER(clang::QualType, isArithmetic) { return Node->isArithmeticType(); } +AST_MATCHER(clang::QualType, isFloating) { return Node->isFloatingType(); } + +auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) { + return expr( + ignoringImplicit(expr(hasType(qualType(isArithmetic())), + ignoringParenCasts(ignoringImplicit(Matcher))))); +} + +auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) { + return expr( + ignoringImplicit(expr(hasType(qualType(isFloating())), + ignoringParenCasts(ignoringImplicit(Matcher))))); +} + +auto matchMathCall(const StringRef FunctionName, + const Matcher<clang::Expr> ArgumentMatcher) { + return callExpr( + callee(functionDecl(hasName(FunctionName), + hasParameter(0, hasType(isArithmetic())))), + hasArgument(0, ArgumentMatcher)); +} + +auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) { + return matchMathCall("sqrt", ArgumentMatcher); +} + +// Used for top-level matchers (i.e. the match that replaces Val with its +// constant). +// +// E.g. The matcher of `std::numbers::pi` uses this matcher to look to +// floatLiterals that have the value of pi. +// +// We only care about the literal if the match is for a top-level match +auto matchFloatLiteralNear(const double Val) { + return expr(ignoreImplicitAndFloatingCasting(floatLiteral(near(Val)))); +} + +// Used for non-top-level matchers (i.e. matchers that are used as inner +// matchers for top-level matchers). +// +// E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if `e` +// of `log2(e)` is declared constant and initialized with the value for eulers +// number. +// +// Here, we do care about literals and about DeclRefExprs to variable +// declarations that are constant and initialized with `Val`. This allows +// top-level matchers to see through declared constants for their inner matches +// like the `std::numbers::log2e` matcher. +auto matchFloatValueNear(const double Val) { + const auto Float = floatLiteral(near(Val)); + + const auto Dref = declRefExpr(to(varDecl( + anyOf(isConstexpr(), + varDecl(hasType(qualType(isConstQualified(), isArithmetic())))), ---------------- PiotrZSL wrote:
Consier checking here CanonicalType to ignore all typedefs https://github.com/llvm/llvm-project/pull/66583 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits