12#include "clang/AST/Expr.h"
13#include "clang/ASTMatchers/ASTMatchFinder.h"
14#include "clang/ASTMatchers/ASTMatchers.h"
15#include "clang/ASTMatchers/ASTMatchersMacros.h"
16#include "clang/Lex/Lexer.h"
25AST_MATCHER_P(ParenExpr, subExpr, ast_matchers::internal::Matcher<Expr>,
27 return InnerMatcher.matches(*Node.getSubExpr(), Finder, Builder);
31 const Expr *E = Node.getSubExpr();
32 return Node.getLParen().isMacroID() || Node.getRParen().isMacroID() ||
33 E->getBeginLoc().isMacroID() || E->getEndLoc().isMacroID();
39 const SourceManager &SM,
40 const LangOptions &LangOpts) {
41 if (Loc.isValid() && !Loc.isMacroID()) {
42 auto LocInfo = SM.getDecomposedLoc(Loc);
44 StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
45 if (!Invalid && LocInfo.second > 0 && LocInfo.second + 1 < Buffer.size() &&
46 Lexer::isAsciiIdentifierContinueChar(Buffer[LocInfo.second - 1],
48 Lexer::isAsciiIdentifierContinueChar(Buffer[LocInfo.second + 1],
50 return FixItHint::CreateReplacement(SourceRange(Loc, Loc),
" ");
52 return FixItHint::CreateRemoval(Loc);
58 AllowedDecls(
utils::options::parseStringList(
59 Options.get(
"AllowedDecls",
"std::max;std::min"))) {}
63 Options.store(Opts,
"AllowedDecls",
68 const auto ConstantExpr =
69 expr(anyOf(integerLiteral(), floatLiteral(), characterLiteral(),
70 cxxBoolLiteral(), stringLiteral(), cxxNullPtrLiteralExpr()));
72 parenExpr(subExpr(anyOf(
73 parenExpr(), ConstantExpr,
74 declRefExpr(to(namedDecl(unless(
77 callExpr(unless(cxxOperatorCallExpr(
78 unless(hasAnyOperatorName(
"()",
"[]"))))),
79 arraySubscriptExpr())),
80 unless(anyOf(isInMacro(),
82 hasParent(unaryExprOrTypeTraitExpr()))))
88 const auto *PE = Result.Nodes.getNodeAs<ParenExpr>(
"dup");
89 diag(PE->getBeginLoc(),
"redundant parentheses around expression")
92 << FixItHint::CreateRemoval(PE->getRParen());
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context)
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
AST_MATCHER_P(Stmt, isStatementIdenticalToBoundNode, std::string, ID)
AST_MATCHER(BinaryOperator, isRelationalOperator)
inline ::clang::ast_matchers::internal::Matcher< NamedDecl > matchesAnyListedRegexName(llvm::ArrayRef< StringRef > NameList)
static FixItHint createSpacedRemoval(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
std::string serializeStringList(ArrayRef< StringRef > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
llvm::StringMap< ClangTidyValue > OptionMap