From: Mike Crowe Date: Mon, 12 Jun 2023 06:09:17 +0000 (+0000) Subject: [clang-tidy] Move formatDereference to FixitHintUtils X-Git-Tag: upstream/17.0.6~5446 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=636c672751425f1c73c28bea57c1913043cd21b2;p=platform%2Fupstream%2Fllvm.git [clang-tidy] Move formatDereference to FixitHintUtils I'd like to use RedundantStringCStrCheck's formatDereference function from the up-coming modernize-use-std-print check. Let's move it to FixItHintUtils so that the implementation can be shared. Reviewed By: PiotrZSL Differential Revision: https://reviews.llvm.org/D150602 --- diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp index 27fa07e..5bf77bb 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "RedundantStringCStrCheck.h" +#include "../utils/FixItHintUtils.h" #include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/Lex/Lexer.h" @@ -22,49 +23,6 @@ namespace clang::tidy::readability { namespace { -// Return true if expr needs to be put in parens when it is an argument of a -// prefix unary operator, e.g. when it is a binary or ternary operator -// syntactically. -bool needParensAfterUnaryOperator(const Expr &ExprNode) { - if (isa(&ExprNode) || - isa(&ExprNode)) { - return true; - } - if (const auto *Op = dyn_cast(&ExprNode)) { - return Op->getNumArgs() == 2 && Op->getOperator() != OO_PlusPlus && - Op->getOperator() != OO_MinusMinus && Op->getOperator() != OO_Call && - Op->getOperator() != OO_Subscript; - } - return false; -} - -// Format a pointer to an expression: prefix with '*' but simplify -// when it already begins with '&'. Return empty string on failure. -std::string -formatDereference(const ast_matchers::MatchFinder::MatchResult &Result, - const Expr &ExprNode) { - if (const auto *Op = dyn_cast(&ExprNode)) { - if (Op->getOpcode() == UO_AddrOf) { - // Strip leading '&'. - return std::string(tooling::fixit::getText( - *Op->getSubExpr()->IgnoreParens(), *Result.Context)); - } - } - StringRef Text = tooling::fixit::getText(ExprNode, *Result.Context); - - if (Text.empty()) - return std::string(); - - // Remove remaining '->' from overloaded operator call - Text.consume_back("->"); - - // Add leading '*'. - if (needParensAfterUnaryOperator(ExprNode)) { - return (llvm::Twine("*(") + Text + ")").str(); - } - return (llvm::Twine("*") + Text).str(); -} - AST_MATCHER(MaterializeTemporaryExpr, isBoundToLValue) { return Node.isBoundToLvalueReference(); } @@ -217,7 +175,7 @@ void RedundantStringCStrCheck::check(const MatchFinder::MatchResult &Result) { // Replace the "call" node with the "arg" node, prefixed with '*' // if the call was using '->' rather than '.'. std::string ArgText = - Arrow ? formatDereference(Result, *Arg) + Arrow ? utils::fixit::formatDereference(*Arg, *Result.Context) : tooling::fixit::getText(*Arg, *Result.Context).str(); if (ArgText.empty()) return; diff --git a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp index 4f11c9b..a0758fc 100644 --- a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp @@ -9,7 +9,9 @@ #include "FixItHintUtils.h" #include "LexerUtils.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" +#include "clang/Tooling/FixIt.h" #include namespace clang::tidy::utils::fixit { @@ -221,4 +223,46 @@ std::optional addQualifierToVarDecl(const VarDecl &Var, return std::nullopt; } + +// Return true if expr needs to be put in parens when it is an argument of a +// prefix unary operator, e.g. when it is a binary or ternary operator +// syntactically. +static bool needParensAfterUnaryOperator(const Expr &ExprNode) { + if (isa(&ExprNode) || + isa(&ExprNode)) { + return true; + } + if (const auto *Op = dyn_cast(&ExprNode)) { + return Op->getNumArgs() == 2 && Op->getOperator() != OO_PlusPlus && + Op->getOperator() != OO_MinusMinus && Op->getOperator() != OO_Call && + Op->getOperator() != OO_Subscript; + } + return false; +} + +// Format a pointer to an expression: prefix with '*' but simplify +// when it already begins with '&'. Return empty string on failure. +std::string formatDereference(const Expr &ExprNode, const ASTContext &Context) { + if (const auto *Op = dyn_cast(&ExprNode)) { + if (Op->getOpcode() == UO_AddrOf) { + // Strip leading '&'. + return std::string( + tooling::fixit::getText(*Op->getSubExpr()->IgnoreParens(), Context)); + } + } + StringRef Text = tooling::fixit::getText(ExprNode, Context); + + if (Text.empty()) + return std::string(); + + // Remove remaining '->' from overloaded operator call + Text.consume_back("->"); + + // Add leading '*'. + if (needParensAfterUnaryOperator(ExprNode)) { + return (llvm::Twine("*(") + Text + ")").str(); + } + return (llvm::Twine("*") + Text).str(); +} + } // namespace clang::tidy::utils::fixit diff --git a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h index 6371f99..bb5410f 100644 --- a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h +++ b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h @@ -44,6 +44,9 @@ addQualifierToVarDecl(const VarDecl &Var, const ASTContext &Context, DeclSpec::TQ Qualifier, QualifierTarget CT = QualifierTarget::Pointee, QualifierPolicy CP = QualifierPolicy::Left); + +// \brief Format a pointer to an expression +std::string formatDereference(const Expr &ExprNode, const ASTContext &Context); } // namespace clang::tidy::utils::fixit #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FIXITHINTUTILS_H