[clang-tools-extra] bbcb625 - [clang-tidy] Support member functions with modernize-use-std-print/format (#104675)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 18 08:46:23 PDT 2024
Author: Mike Crowe
Date: 2024-08-18T17:46:19+02:00
New Revision: bbcb625798514f1cd6ef04818381d38ea26b23e5
URL: https://github.com/llvm/llvm-project/commit/bbcb625798514f1cd6ef04818381d38ea26b23e5
DIFF: https://github.com/llvm/llvm-project/commit/bbcb625798514f1cd6ef04818381d38ea26b23e5.diff
LOG: [clang-tidy] Support member functions with modernize-use-std-print/format (#104675)
These checks can be made to work on member functions quite easily and
it's not unknown to have at least printf-style functions as members.
Let's remove the restriction.
Added:
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-member.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-member.cpp
Modified:
clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2a..cdb34aef1b0e61 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -50,8 +50,7 @@ void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(argumentCountAtLeast(1),
hasArgument(0, stringLiteral(isOrdinary())),
- callee(functionDecl(unless(cxxMethodDecl()),
- matchers::matchesAnyListedName(
+ callee(functionDecl(matchers::matchesAnyListedName(
StrFormatLikeFunctions))
.bind("func_decl")))
.bind("strformat"),
@@ -93,7 +92,8 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult &Result) {
diag(StrFormatCall->getBeginLoc(), "use '%0' instead of %1")
<< ReplacementFormatFunction << OldFunction->getIdentifier();
Diag << FixItHint::CreateReplacement(
- CharSourceRange::getTokenRange(StrFormatCall->getSourceRange()),
+ CharSourceRange::getTokenRange(StrFormatCall->getExprLoc(),
+ StrFormatCall->getEndLoc()),
ReplacementFormatFunction);
Converter.applyFixes(Diag, *Result.SourceManager);
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1d..16f2f4b3e7d1af 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -100,8 +100,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
unusedReturnValue(
callExpr(argumentCountAtLeast(1),
hasArgument(0, stringLiteral(isOrdinary())),
- callee(functionDecl(unless(cxxMethodDecl()),
- matchers::matchesAnyListedName(
+ callee(functionDecl(matchers::matchesAnyListedName(
PrintfLikeFunctions))
.bind("func_decl")))
.bind("printf")),
@@ -112,8 +111,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
unusedReturnValue(
callExpr(argumentCountAtLeast(2),
hasArgument(1, stringLiteral(isOrdinary())),
- callee(functionDecl(unless(cxxMethodDecl()),
- matchers::matchesAnyListedName(
+ callee(functionDecl(matchers::matchesAnyListedName(
FprintfLikeFunctions))
.bind("func_decl")))
.bind("fprintf")),
@@ -152,7 +150,7 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult &Result) {
<< ReplacementFunction << OldFunction->getIdentifier();
Diag << FixItHint::CreateReplacement(
- CharSourceRange::getTokenRange(PrintfCall->getBeginLoc(),
+ CharSourceRange::getTokenRange(PrintfCall->getExprLoc(),
PrintfCall->getEndLoc()),
ReplacementFunction);
Converter.applyFixes(Diag, *Result.SourceManager);
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 0f6b34cf400521..1b025e8f90f7ba 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -104,6 +104,14 @@ New check aliases
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Improved :doc:`modernize-use-std-format
+ <clang-tidy/checks/modernize/use-std-format>` check to support replacing
+ member function calls too.
+
+- Improved :doc:`modernize-use-std-print
+ <clang-tidy/checks/modernize/use-std-print>` check to support replacing
+ member function calls too.
+
- Improved :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability/redundant-smartptr-get>` check to
remove `->`, when redundant `get()` is removed.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
index a1599f0fc58fe6..1ec753ef090de1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
@@ -64,8 +64,9 @@ Options
A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
- immediately afterwards. The default value for this option is
- `absl::StrFormat`.
+ immediately afterwards. Qualified member function names are supported,
+ but the replacement function name must be unqualified. The default value
+ for this option is `absl::StrFormat`.
.. option:: ReplacementFormatFunction
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst
index 79648a1104bca2..59bb722e2c24fc 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst
@@ -121,9 +121,10 @@ Options
A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
- immediately afterwards. If neither this option nor
- `FprintfLikeFunctions` are set then the default value for this option
- is `printf; absl::PrintF`, otherwise it is empty.
+ immediately afterwards. Qualified member function names are supported,
+ but the replacement function name must be unqualified. If neither this
+ option nor `FprintfLikeFunctions` are set then the default value for
+ this option is `printf; absl::PrintF`, otherwise it is empty.
.. option:: FprintfLikeFunctions
@@ -131,9 +132,11 @@ Options
A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter is retained, the
second parameter contains the printf-style format string and the
- arguments to be formatted follow immediately afterwards. If neither this
- option nor `PrintfLikeFunctions` are set then the default value for
- this option is `fprintf; absl::FPrintF`, otherwise it is empty.
+ arguments to be formatted follow immediately afterwards. Qualified
+ member function names are supported, but the replacement function name
+ must be unqualified. If neither this option nor `PrintfLikeFunctions`
+ are set then the default value for this option is `fprintf;
+ absl::FPrintF`, otherwise it is empty.
.. option:: ReplacementPrintFunction
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-member.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-member.cpp
new file mode 100644
index 00000000000000..b4e1720e0a106d
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-member.cpp
@@ -0,0 +1,44 @@
+// RUN: %check_clang_tidy %s modernize-use-std-format %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: { \
+// RUN: modernize-use-std-format.StrFormatLikeFunctions: 'MyClass::StrFormat', \
+// RUN: modernize-use-std-format.ReplacementFormatFunction: 'format', \
+// RUN: } \
+// RUN: }" \
+// RUN: -- -isystem %clang_tidy_headers
+
+#include <cstdio>
+#include <string.h>
+#include <string>
+
+struct MyClass
+{
+ template <typename S, typename... Args>
+ std::string StrFormat(const S &format, const Args&... args);
+};
+
+std::string StrFormat_simple(MyClass &myclass, MyClass *pmyclass) {
+ std::string s;
+
+ s += myclass.StrFormat("MyClass::StrFormat dot %d", 42);
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
+ // CHECK-FIXES: s += myclass.format("MyClass::StrFormat dot {}", 42);
+
+ s += pmyclass->StrFormat("MyClass::StrFormat pointer %d", 43);
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
+ // CHECK-FIXES: s += pmyclass->format("MyClass::StrFormat pointer {}", 43);
+
+ s += (*pmyclass).StrFormat("MyClass::StrFormat deref pointer %d", 44);
+ // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
+ // CHECK-FIXES: s += (*pmyclass).format("MyClass::StrFormat deref pointer {}", 44);
+
+ return s;
+}
+
+struct MyDerivedClass : public MyClass {};
+
+std::string StrFormat_derived(MyDerivedClass &derived) {
+ return derived.StrFormat("MyDerivedClass::StrFormat dot %d", 42);
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
+ // CHECK-FIXES: return derived.format("MyDerivedClass::StrFormat dot {}", 42);
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-member.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-member.cpp
new file mode 100644
index 00000000000000..1d1ac4b369bbaa
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-member.cpp
@@ -0,0 +1,70 @@
+// RUN: %check_clang_tidy %s modernize-use-std-print %t -- \
+// RUN: -config="{CheckOptions: \
+// RUN: { \
+// RUN: modernize-use-std-print.PrintfLikeFunctions: 'MyClass::printf', \
+// RUN: modernize-use-std-print.FprintfLikeFunctions: 'MyClass::fprintf', \
+// RUN: modernize-use-std-print.ReplacementPrintFunction: 'print', \
+// RUN: modernize-use-std-print.ReplacementPrintlnFunction: 'println', \
+// RUN: } \
+// RUN: }" \
+// RUN: -- -isystem %clang_tidy_headers
+
+#include <cstdio>
+#include <string.h>
+
+struct MyStruct {};
+
+struct MyClass
+{
+ template <typename... Args>
+ void printf(const char *fmt, Args &&...);
+ template <typename... Args>
+ int fprintf(MyStruct *param1, const char *fmt, Args &&...);
+};
+
+void printf_simple(MyClass &myclass, MyClass *pmyclass) {
+ myclass.printf("printf dot %d", 42);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: myclass.print("printf dot {}", 42);
+
+ pmyclass->printf("printf pointer %d", 43);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: pmyclass->print("printf pointer {}", 43);
+
+ (*pmyclass).printf("printf deref pointer %d", 44);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: (*pmyclass).print("printf deref pointer {}", 44);
+}
+
+void printf_newline(MyClass &myclass, MyClass *pmyclass) {
+ myclass.printf("printf dot newline %c\n", 'A');
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'println' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: myclass.println("printf dot newline {}", 'A');
+
+ pmyclass->printf("printf pointer newline %c\n", 'B');
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'println' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: pmyclass->println("printf pointer newline {}", 'B');
+}
+
+void fprintf_simple(MyStruct *mystruct, MyClass &myclass, MyClass *pmyclass) {
+ myclass.fprintf(mystruct, "fprintf dot %d", 142);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
+ // CHECK-FIXES: myclass.print(mystruct, "fprintf dot {}", 142);
+
+ pmyclass->fprintf(mystruct, "fprintf pointer %d", 143);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
+ // CHECK-FIXES: pmyclass->print(mystruct, "fprintf pointer {}", 143);
+
+ (*pmyclass).fprintf(mystruct, "fprintf deref pointer %d", 144);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
+ // CHECK-FIXES: (*pmyclass).print(mystruct, "fprintf deref pointer {}", 144);
+}
+
+struct MyDerivedClass : public MyClass {};
+
+void printf_derived(MyDerivedClass &derived)
+{
+ derived.printf("printf on derived class %d", 42);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
+ // CHECK-FIXES: derived.print("printf on derived class {}", 42);
+}
More information about the cfe-commits
mailing list