[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/72283

As per title. A small improvement to this check, `string_view` should work out 
of the box.

I am slowly looking into adding an option to this check to recommend C++20's 
API `starts_with`, and move it to `modernize`.
Possibly would like to use it as a codemod on our code.


>From 6854521facebbe13368b8638ade0c8636dcf9941 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  4 +++-
 .../abseil/string-find-startswith.cpp | 22 ++-
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..31b5c3d9951409b 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,13 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses = "::std::basic_string; 
::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
index e51568077eda151..69dc61e6a73e32f 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
-// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::basic_string'}}"
+// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::std::basic_string_view;::basic_string'}}"
 
 using size_t = decltype(sizeof(int));
 
@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;
+
 struct cxx_string {
   int find(const char *s, int pos = 0);
   int rfind(const char *s, int pos = npos);
@@ -96,6 +111,11 @@ void tests(std::string s, global_string s2) {
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
 
+  std::string_view sv;
+  sv.find("a") == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(sv, "a");{{$}}
+
   // expressions that don't trigger the check are here.
   A_MACRO(s.find("a"), 0);
   A_MACRO(s.rfind("a", 0), 0);

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits


@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;

nicovank wrote:

https://github.com/llvm/llvm-project/blob/57dd23bc0a2f7b4f7b68162923b3267c1f303de9/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-str-contains.cpp#L24-L37

https://github.com/llvm/llvm-project/pull/72283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From 3abdf06b2128fbd6ccc03f804a8d3bdde6d772c9 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  4 +++-
 .../abseil/string-find-startswith.cpp | 23 +--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..31b5c3d9951409b 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,13 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses = "::std::basic_string; 
::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
index e51568077eda151..ae8d2daf736e979 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
-// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::basic_string'}}"
+// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::std::basic_string_view;::basic_string'}}"
 
 using size_t = decltype(sizeof(int));
 
@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;
+
 struct cxx_string {
   int find(const char *s, int pos = 0);
   int rfind(const char *s, int pos = npos);
@@ -39,7 +54,7 @@ std::string bar();
 
 #define A_MACRO(x, y) ((x) == (y))
 
-void tests(std::string s, global_string s2) {
+void tests(std::string s, global_string s2, std::string_view sv) {
   s.find("a") == 0;
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of 
find() == 0 [abseil-string-find-startswith]
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}}
@@ -96,6 +111,10 @@ void tests(std::string s, global_string s2) {
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
 
+  sv.find("a") == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(sv, "a");{{$}}
+
   // expressions that don't trigger the check are here.
   A_MACRO(s.find("a"), 0);
   A_MACRO(s.rfind("a", 0), 0);

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From dc890dc762a3400937a6a5d91963dead024c3569 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  5 +++-
 .../abseil/string-find-startswith.cpp | 23 +--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..d0527cba22a917d 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,14 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses =
+"::std::basic_string; ::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
index e51568077eda151..ae8d2daf736e979 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
-// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::basic_string'}}"
+// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::std::basic_string_view;::basic_string'}}"
 
 using size_t = decltype(sizeof(int));
 
@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;
+
 struct cxx_string {
   int find(const char *s, int pos = 0);
   int rfind(const char *s, int pos = npos);
@@ -39,7 +54,7 @@ std::string bar();
 
 #define A_MACRO(x, y) ((x) == (y))
 
-void tests(std::string s, global_string s2) {
+void tests(std::string s, global_string s2, std::string_view sv) {
   s.find("a") == 0;
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of 
find() == 0 [abseil-string-find-startswith]
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}}
@@ -96,6 +111,10 @@ void tests(std::string s, global_string s2) {
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
 
+  sv.find("a") == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(sv, "a");{{$}}
+
   // expressions that don't trigger the check are here.
   A_MACRO(s.find("a"), 0);
   A_MACRO(s.rfind("a", 0), 0);

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank ready_for_review 
https://github.com/llvm/llvm-project/pull/72283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

First time with LLVM GitHub PR workflow. Am I supposed to tag potential 
reviewers? @gribozavr @hokein @njames93 

https://github.com/llvm/llvm-project/pull/72283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From a7361968b8a1acc48c4ef563c70f5c56f2633eac Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  5 +++-
 .../abseil/string-find-startswith.cpp | 23 +--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..d0527cba22a917d 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,14 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses =
+"::std::basic_string; ::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
index e51568077eda151..ae8d2daf736e979 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
-// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::basic_string'}}"
+// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::std::basic_string_view;::basic_string'}}"
 
 using size_t = decltype(sizeof(int));
 
@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;
+
 struct cxx_string {
   int find(const char *s, int pos = 0);
   int rfind(const char *s, int pos = npos);
@@ -39,7 +54,7 @@ std::string bar();
 
 #define A_MACRO(x, y) ((x) == (y))
 
-void tests(std::string s, global_string s2) {
+void tests(std::string s, global_string s2, std::string_view sv) {
   s.find("a") == 0;
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of 
find() == 0 [abseil-string-find-startswith]
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}}
@@ -96,6 +111,10 @@ void tests(std::string s, global_string s2) {
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
 
+  sv.find("a") == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(sv, "a");{{$}}
+
   // expressions that don't trigger the check are here.
   A_MACRO(s.find("a"), 0);
   A_MACRO(s.rfind("a", 0), 0);

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From 1761f02f54f125948b10d2321807af2154dbbc3f Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  5 +++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 
 .../checks/abseil/string-find-startswith.rst  |  6 ++---
 .../abseil/string-find-startswith.cpp | 23 +--
 4 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..d0527cba22a917d 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,14 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses =
+"::std::basic_string; ::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index f49c412118e7d98..bb5b29a1d38f928 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -208,6 +208,10 @@ New check aliases
 Changes in existing checks
 ^^
 
+- Improved :doc:`abseil-string-find-startswith
+  ` check to also consider
+  ``std::basic_string_view`` in addition to ``std::basic_string`` by default.
+
 - Improved :doc:`bugprone-dangling-handle
   ` check to support functional
   casting during type conversions at variable initialization, now with improved
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst 
b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
index 8224c37a087b8bc..6f65b71d830ef51 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
@@ -28,9 +28,9 @@ Options
 
 .. option:: StringLikeClasses
 
-   Semicolon-separated list of names of string-like classes. By default only
-   ``std::basic_string`` is considered. The list of methods to considered is
-   fixed.
+   Semicolon-separated list of names of string-like classes. By default both
+   ``std::basic_string`` and ``std::basic_string_view`` are considered. The 
list
+   of methods to be considered is fixed.
 
 .. option:: IncludeStyle
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
index e51568077eda151..ae8d2daf736e979 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil/string-find-startswith.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \
-// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::basic_string'}}"
+// RUN:   -config="{CheckOptions: 
{abseil-string-find-startswith.StringLikeClasses: 
'::std::basic_string;::std::basic_string_view;::basic_string'}}"
 
 using size_t = decltype(sizeof(int));
 
@@ -22,6 +22,21 @@ struct basic_string {
 typedef basic_string string;
 typedef basic_string wstring;
 
+template 
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &);
+  basic_string_view(const C *);
+  ~basic_string_view();
+  int find(basic_string_view s, int pos = 0);
+  int find(const C *s, int pos = 0);
+  int find(const C *s, int pos, int n);
+  int find(char c, int pos = 0);
+  static constexpr size_t npos = -1;
+};
+typedef basic_string_view string_view;
+
 struct cxx_string {
   int find(const char *s, int pos = 0);
   int rfind(const char *s, int pos = npos);
@@ -39,7 +54,7 @@ std::string bar();
 
 #define A_MACRO(x, y) ((x) == (y))
 
-void tests(std::string s, global_string s2) {
+void tests(std::string s, global_string s2, std::string_view sv) {
   s.find("a") == 0;
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of 
find() == 0 [abseil-string-find-startswith]
   // CHECK-FI

[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From 42364ebb6f3e5771947133599a1142522c511337 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  5 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +++
 .../checks/abseil/string-find-startswith.rst  |  6 ++--
 .../clang-tidy/checkers/Inputs/Headers/string | 15 +
 .../abseil/string-find-startswith.cpp | 31 +++
 5 files changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..d0527cba22a917d 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,14 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses =
+"::std::basic_string; ::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index f49c412118e7d98..bb5b29a1d38f928 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -208,6 +208,10 @@ New check aliases
 Changes in existing checks
 ^^
 
+- Improved :doc:`abseil-string-find-startswith
+  ` check to also consider
+  ``std::basic_string_view`` in addition to ``std::basic_string`` by default.
+
 - Improved :doc:`bugprone-dangling-handle
   ` check to support functional
   casting during type conversions at variable initialization, now with improved
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst 
b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
index 8224c37a087b8bc..6f65b71d830ef51 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
@@ -28,9 +28,9 @@ Options
 
 .. option:: StringLikeClasses
 
-   Semicolon-separated list of names of string-like classes. By default only
-   ``std::basic_string`` is considered. The list of methods to considered is
-   fixed.
+   Semicolon-separated list of names of string-like classes. By default both
+   ``std::basic_string`` and ``std::basic_string_view`` are considered. The 
list
+   of methods to be considered is fixed.
 
 .. option:: IncludeStyle
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
index 6f569655e6762a9..2704d234f771c8d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
@@ -43,6 +43,11 @@ struct basic_string {
   size_type find(const C* s, size_type pos = 0) const;
   size_type find(const C* s, size_type pos, size_type n) const;
 
+  size_type rfind(const _Type& str, size_type pos = npos) const;
+  size_type rfind(const C* s, size_type pos, size_type count) const;
+  size_type rfind(const C* s, size_type pos = npos) const;
+  size_type rfind(C ch, size_type pos = npos) const;
+
   _Type& insert(size_type pos, const _Type& str);
   _Type& insert(size_type pos, const C* s);
   _Type& insert(size_type pos, const C* s, size_type n);
@@ -54,6 +59,8 @@ struct basic_string {
   _Type& operator+=(const C* s);
   _Type& operator=(const _Type& str);
   _Type& operator=(const C* s);
+
+  static constexpr size_t npos = -1;
 };
 
 typedef basic_string string;
@@ -63,8 +70,16 @@ typedef basic_string u32string;
 
 template >
 struct basic_string_view {
+  typedef size_t size_type;
+  typedef basic_string_view _Type;
+
   const C *str;
   constexpr basic_string_view(const C* s) : str(s) {}
+
+  size_type find(_Type v, size_type pos = 0) const;
+  size_type find(C ch, size_type pos = 0) const;
+  size_type find(const C* s, size_type pos, size_type count) const;
+  size_type find(const C* s, size_type pos = 0) const;
 };
 typedef basic_string_view string_view;
 typedef basic_string_view wstring_view;
diff --git 
a/clang-tools-extra/test/clang

[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

> Copy this check.

Got it. Thanks for the pointer!

> Documentation, string header.

I think I covered everything, had to add a couple of skeletons to that `string` 
common header.

https://github.com/llvm/llvm-project/pull/72283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72283

>From cf4a78c252c5aac820581b90c28c6581c6e41cfb Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Tue, 14 Nov 2023 08:31:05 -0800
Subject: [PATCH] [clang-tidy][abseil-string-find-startswith] Add string_view
 to default string-like classes

---
 .../abseil/StringFindStartswithCheck.cpp  |  5 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +++
 .../checks/abseil/string-find-startswith.rst  | 13 +++
 .../clang-tidy/checkers/Inputs/Headers/string | 22 
 .../abseil/string-find-startswith.cpp | 35 ---
 5 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
index b36144d1912fce0..221e924c10f621d 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -19,11 +19,14 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::abseil {
 
+const auto DefaultStringLikeClasses =
+"::std::basic_string;::std::basic_string_view";
+
 StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   StringLikeClasses(utils::options::parseStringList(
-  Options.get("StringLikeClasses", "::std::basic_string"))),
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))),
   IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
   areDiagsSelfContained()),
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index f49c412118e7d98..bb5b29a1d38f928 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -208,6 +208,10 @@ New check aliases
 Changes in existing checks
 ^^
 
+- Improved :doc:`abseil-string-find-startswith
+  ` check to also consider
+  ``std::basic_string_view`` in addition to ``std::basic_string`` by default.
+
 - Improved :doc:`bugprone-dangling-handle
   ` check to support functional
   casting during type conversions at variable initialization, now with improved
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst 
b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
index 8224c37a087b8bc..c82c38772a5c9a8 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/abseil/string-find-startswith.rst
@@ -3,9 +3,10 @@
 abseil-string-find-startswith
 =
 
-Checks whether a ``std::string::find()`` or ``std::string::rfind()`` result is
-compared with 0, and suggests replacing with ``absl::StartsWith()``. This is
-both a readability and performance issue.
+Checks whether a ``std::string::find()`` or ``std::string::rfind()`` (and
+corresponding ``std::string_view`` methods) result is compared with 0, and
+suggests replacing with ``absl::StartsWith()``. This is both a readability and
+performance issue.
 
 .. code-block:: c++
 
@@ -28,9 +29,9 @@ Options
 
 .. option:: StringLikeClasses
 
-   Semicolon-separated list of names of string-like classes. By default only
-   ``std::basic_string`` is considered. The list of methods to considered is
-   fixed.
+   Semicolon-separated list of names of string-like classes. By default both
+   ``std::basic_string`` and ``std::basic_string_view`` are considered. The 
list
+   of methods to be considered is fixed.
 
 .. option:: IncludeStyle
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
index 6f569655e6762a9..d0aac7b78ec939b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
@@ -43,6 +43,11 @@ struct basic_string {
   size_type find(const C* s, size_type pos = 0) const;
   size_type find(const C* s, size_type pos, size_type n) const;
 
+  size_type rfind(const _Type& str, size_type pos = npos) const;
+  size_type rfind(const C* s, size_type pos, size_type count) const;
+  size_type rfind(const C* s, size_type pos = npos) const;
+  size_type rfind(C ch, size_type pos = npos) const;
+
   _Type& insert(size_type pos, const _Type& str);
   _Type& insert(size_type pos, const C* s);
   _Type& insert(size_type pos, const C* s, size_type n);
@@ -54,6 +59,8 @@ struct basic_string {
   _Type& operator+=(const C* s);
   _Type& operator=(const _Type& str);
   _Type& operator=(const C* s);
+
+  static constexpr size_t npos = -1;
 };
 
 typedef basic_string string;
@@ -63,8 +70,23 @@ typedef

[clang-tools-extra] [clang-tidy][abseil-string-find-startswith] Add string_view to default string-like classes (PR #72283)

2023-11-14 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Addressed feedback.

I do not have commit access, can you please merge after CI is green?
Assuming GitHub will properly populate information, if not you can use `Nicolas 
van Kempen `.

https://github.com/llvm/llvm-project/pull/72283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/72385

Matchers are copied over from abseil-string-find-startswith, only the error 
message is different and suggests `std::{string|string_view}::starts_with` 
instead of the Abseil equivalent.

>From 5e5a2bac0f7373e6b1830fddc609e97dc61df9d4 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/StringFindStartswithCheck.cpp   | 111 ++
 .../modernize/StringFindStartswithCheck.h |  41 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   8 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../modernize/string-find-startswith.rst  |  32 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/string-find-startswith.cpp  |  77 
 11 files changed, 283 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/string-find-startswith.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/string-find-startswith.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..5019b7000f1d062 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-string-find-startswith when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..541f58304119856 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyModernizeModule
   ReplaceRandomShuffleCheck.cpp
   ReturnBracedInitListCheck.cpp
   ShrinkToFitCheck.cpp
+  StringFindStartswithCheck.cpp
   TypeTraitsCheck.cpp
   UnaryStaticAssertCheck.cpp
   UseAutoCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..1fcbff79ddc6f96 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -26,6 +26,7 @@
 #include "ReplaceRandomShuffleCheck.h"
 #include "ReturnBracedInitListCheck.h"
 #include "ShrinkToFitCheck.h"
+#include "StringFindStartswithCheck.h"
 #include "TypeTraitsCheck.h"
 #include "UnaryStaticAssertCheck.h"
 #include "UseAutoCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-string-find-startswith");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git 
a/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
new file mode 100644
index 000..7b992d77d0e7bb5
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
@@ -0,0 +1,111 @@
+//===--- StringFindStartswithCheck.cpp - clang-tidy 
---

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 58e1392e140f0d5b932fce683a07fb799ef6b89f Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/StringFindStartswithCheck.cpp   | 111 ++
 .../modernize/StringFindStartswithCheck.h |  41 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   8 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../modernize/string-find-startswith.rst  |  32 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/string-find-startswith.cpp  |  77 
 11 files changed, 283 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/string-find-startswith.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/string-find-startswith.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..5019b7000f1d062 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-string-find-startswith when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..541f58304119856 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyModernizeModule
   ReplaceRandomShuffleCheck.cpp
   ReturnBracedInitListCheck.cpp
   ShrinkToFitCheck.cpp
+  StringFindStartswithCheck.cpp
   TypeTraitsCheck.cpp
   UnaryStaticAssertCheck.cpp
   UseAutoCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..1fcbff79ddc6f96 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -26,6 +26,7 @@
 #include "ReplaceRandomShuffleCheck.h"
 #include "ReturnBracedInitListCheck.h"
 #include "ShrinkToFitCheck.h"
+#include "StringFindStartswithCheck.h"
 #include "TypeTraitsCheck.h"
 #include "UnaryStaticAssertCheck.h"
 #include "UseAutoCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-string-find-startswith");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git 
a/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
new file mode 100644
index 000..74f59b9fcea1982
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
@@ -0,0 +1,111 @@
+//===--- StringFindStartswithCheck.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-Lice

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank ready_for_review 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 2b01f9d8cb945d8332a271947492ec0fe7a6f7c0 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/StringFindStartswithCheck.cpp   | 110 ++
 .../modernize/StringFindStartswithCheck.h |  41 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   8 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../modernize/string-find-startswith.rst  |  32 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/string-find-startswith.cpp  |  77 
 11 files changed, 282 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/string-find-startswith.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/string-find-startswith.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..5019b7000f1d062 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-string-find-startswith when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..541f58304119856 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyModernizeModule
   ReplaceRandomShuffleCheck.cpp
   ReturnBracedInitListCheck.cpp
   ShrinkToFitCheck.cpp
+  StringFindStartswithCheck.cpp
   TypeTraitsCheck.cpp
   UnaryStaticAssertCheck.cpp
   UseAutoCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..1fcbff79ddc6f96 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -26,6 +26,7 @@
 #include "ReplaceRandomShuffleCheck.h"
 #include "ReturnBracedInitListCheck.h"
 #include "ShrinkToFitCheck.h"
+#include "StringFindStartswithCheck.h"
 #include "TypeTraitsCheck.h"
 #include "UnaryStaticAssertCheck.h"
 #include "UseAutoCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-string-find-startswith");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git 
a/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
new file mode 100644
index 000..1d9e3ac25c785a9
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
@@ -0,0 +1,110 @@
+//===--- StringFindStartswithCheck.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-Lice

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From d9995b339e787374452b65fcffa8b3acf4aade3d Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/StringFindStartswithCheck.cpp   | 112 ++
 .../modernize/StringFindStartswithCheck.h |  41 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   8 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../modernize/string-find-startswith.rst  |  32 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/string-find-startswith.cpp  |  77 
 11 files changed, 284 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/string-find-startswith.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/string-find-startswith.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..5019b7000f1d062 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-string-find-startswith when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..541f58304119856 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyModernizeModule
   ReplaceRandomShuffleCheck.cpp
   ReturnBracedInitListCheck.cpp
   ShrinkToFitCheck.cpp
+  StringFindStartswithCheck.cpp
   TypeTraitsCheck.cpp
   UnaryStaticAssertCheck.cpp
   UseAutoCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..1fcbff79ddc6f96 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -26,6 +26,7 @@
 #include "ReplaceRandomShuffleCheck.h"
 #include "ReturnBracedInitListCheck.h"
 #include "ShrinkToFitCheck.h"
+#include "StringFindStartswithCheck.h"
 #include "TypeTraitsCheck.h"
 #include "UnaryStaticAssertCheck.h"
 #include "UseAutoCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-string-find-startswith");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git 
a/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
new file mode 100644
index 000..f9a7ce7479099dc
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
@@ -0,0 +1,112 @@
+//===--- StringFindStartswithCheck.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-Lice

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From d31148a9d99004f1a64dc6dc1bce85a58985aa0f Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/StringFindStartswithCheck.cpp   | 105 ++
 .../modernize/StringFindStartswithCheck.h |  41 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   8 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../modernize/string-find-startswith.rst  |  32 ++
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/string-find-startswith.cpp  |  77 +
 11 files changed, 277 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/string-find-startswith.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/string-find-startswith.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..5019b7000f1d062 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-string-find-startswith when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..541f58304119856 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyModernizeModule
   ReplaceRandomShuffleCheck.cpp
   ReturnBracedInitListCheck.cpp
   ShrinkToFitCheck.cpp
+  StringFindStartswithCheck.cpp
   TypeTraitsCheck.cpp
   UnaryStaticAssertCheck.cpp
   UseAutoCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..1fcbff79ddc6f96 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -26,6 +26,7 @@
 #include "ReplaceRandomShuffleCheck.h"
 #include "ReturnBracedInitListCheck.h"
 #include "ShrinkToFitCheck.h"
+#include "StringFindStartswithCheck.h"
 #include "TypeTraitsCheck.h"
 #include "UnaryStaticAssertCheck.h"
 #include "UseAutoCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-string-find-startswith");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git 
a/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
new file mode 100644
index 000..ea569f924416dff
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/StringFindStartswithCheck.cpp
@@ -0,0 +1,105 @@
+//===--- StringFindStartswithCheck.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-Li

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits


@@ -0,0 +1,105 @@
+//===--- StringFindStartswithCheck.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 "StringFindStartswithCheck.h"
+
+#include "../utils/OptionsUtils.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+const auto DefaultStringLikeClasses =
+"::std::basic_string;::std::basic_string_view";
+
+StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StringLikeClasses(utils::options::parseStringList(
+  Options.get("StringLikeClasses", DefaultStringLikeClasses))) {}
+
+void StringFindStartswithCheck::registerMatchers(MatchFinder *Finder) {
+  const auto ZeroLiteral = integerLiteral(equals(0));
+  const auto StringClassMatcher = cxxRecordDecl(hasAnyName(StringLikeClasses));
+  const auto StringType = hasUnqualifiedDesugaredType(
+  recordType(hasDeclaration(StringClassMatcher)));
+
+  const auto StringFind = cxxMemberCallExpr(
+  // .find()-call on a string...
+  callee(cxxMethodDecl(hasName("find")).bind("findfun")),
+  on(hasType(StringType)),
+  // ... with some search expression ...
+  hasArgument(0, expr().bind("needle")),
+  // ... and either "0" as second argument or the default argument (also 
0).
+  anyOf(hasArgument(1, ZeroLiteral), hasArgument(1, cxxDefaultArgExpr(;
+
+  const auto StringRFind = cxxMemberCallExpr(
+  // .rfind()-call on a string...
+  callee(cxxMethodDecl(hasName("rfind")).bind("findfun")),
+  on(hasType(StringType)),
+  // ... with some search expression ...
+  hasArgument(0, expr().bind("needle")),
+  // ... and "0" as second argument.
+  hasArgument(1, ZeroLiteral));
+
+  Finder->addMatcher(
+  // Match [=!]= with a zero on one side and a string.(r?)find on the 
other.
+  binaryOperator(
+  hasAnyOperatorName("==", "!="),
+  hasOperands(ignoringParenImpCasts(ZeroLiteral),
+  ignoringParenImpCasts(
+  cxxMemberCallExpr(anyOf(StringFind, StringRFind))
+  .bind("findexpr"
+  .bind("expr"),
+  this);
+}
+
+void StringFindStartswithCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto &Context = *Result.Context;
+  const auto &Source = Context.getSourceManager();
+
+  const auto *ComparisonExpr = Result.Nodes.getNodeAs("expr");
+  const auto *Needle = Result.Nodes.getNodeAs("needle");
+  const auto *Haystack = Result.Nodes.getNodeAs("findexpr")
+ ->getImplicitObjectArgument();
+  const auto *FindFun = Result.Nodes.getNodeAs("findfun");
+
+  if (ComparisonExpr->getBeginLoc().isMacroID()) {
+return;
+  }
+
+  const auto Rev = FindFun->getName().contains("rfind");
+  const auto Neg = ComparisonExpr->getOpcode() == BO_NE;
+
+  const auto NeedleExprCode = Lexer::getSourceText(
+  CharSourceRange::getTokenRange(Needle->getSourceRange()), Source,
+  Context.getLangOpts());
+  const auto HaystackExprCode = Lexer::getSourceText(
+  CharSourceRange::getTokenRange(Haystack->getSourceRange()), Source,

nicovank wrote:

I thought that lines 73-75 were checking and ignoring macro expansions?

```
if (ComparisonExpr->getBeginLoc().isMacroID()) {
  return;
}
```

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

> Detect the `str.compare("marker", 0, 6) == 0` pattern.

This is actually in my notes for making this check / codemod. No performance 
impact so not tackling yet, maybe in the future.

> Support `ends_with` in same check.

Similar as above, matching for that length argument is a bit trickier than just 
looking for 0. Not tackling for now. Any thoughts on open-ended check name 
instead? `modernize-string-find-affix` (affix = prefix | suffix)?

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits


@@ -0,0 +1,41 @@
+//===--- StringFindStartswithCheck.h - clang-tidy ---*- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_STRINGFINDSTARTSWITHCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_STRINGFINDSTARTSWITHCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+#include 
+
+namespace clang::tidy::modernize {
+
+/// Checks whether a ``std::string::find()`` or ``std::string::rfind()`` (and
+/// corresponding ``std::string_view`` methods) result is compared with 0, and
+/// suggests replacing with ``starts_with()``. This is both a readability and a
+/// performance issue.
+///
+/// For the user-facing documentation see:
+/// 
http://clang.llvm.org/extra/clang-tidy/checks/modernize/string-find-startswith.html
+class StringFindStartswithCheck : public ClangTidyCheck {
+public:
+  StringFindStartswithCheck(StringRef Name, ClangTidyContext *Context);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+return LangOpts.CPlusPlus20;
+  }
+

nicovank wrote:

Was this always recommended? Maybe it should be added to the `add_new_check` 
template... Along with `isLanguageVersionSupported`.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

I like `XXX-use-starts-ends-with`. I would rather move it to `performance` than 
`readability` if not `modernize`. @PiotrZSL thoughts before I go ahead and do 
the renaming? Also move it somewhere else?

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 35a78d8fa7d16c60f7b40b3f0b53cc38c26b58b9 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 107 ++
 .../performance/UseStartsEndsWithCheck.h  |  44 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |   6 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  |  77 +
 11 files changed, 255 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..b8e09984c8f950a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,107 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.h"
+#

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 9c6123e91f6a075a6a4cc7c2aba8c76152539ae2 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 107 ++
 .../performance/UseStartsEndsWithCheck.h  |  44 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  30 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  |  77 +
 11 files changed, 279 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..b8e09984c8f950a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,107 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.h

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 5d66e404d9b6536814f004a64e1c7f0d27bd1f03 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 107 ++
 .../performance/UseStartsEndsWithCheck.h  |  44 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  31 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  |  77 +
 11 files changed, 280 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..b8e09984c8f950a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,107 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.h

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From fd3e09fddae97549c327cf224d66de144221fe83 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-string-find-startswith check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 106 ++
 .../performance/UseStartsEndsWithCheck.h  |  44 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  31 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  |  77 +
 11 files changed, 279 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..988eb7da008fb71
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,106 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.

[clang-tools-extra] [clang-tidy] Add new modernize-string-find-startswith check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Addressed feedback, renamed to `performance-use-starts-ends-with`, relaxed use 
of `auto`.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 96e00378116ca5fbfad6edb220e86326dc4f9897 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Matchers are copied over from abseil-string-find-startswith, only the error
message is different and suggests `std::{string|string_view}::starts_with`
instead of the Abseil equivalent.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 106 ++
 .../performance/UseStartsEndsWithCheck.h  |  44 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 ++
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  31 +
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  |  77 +
 11 files changed, 279 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..988eb7da008fb71
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,106 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-17 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From ddac6dc91c443bf81d4b6cc3f75686ea56801094 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 109 +
 .../performance/UseStartsEndsWithCheck.h  |  37 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  | 151 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 358 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..74cba350663b0a6
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,109 @@
+//===--- UseStartsEndsWithCheck.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
+//
+//===--===//
+
+

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-17 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Major changes:
 -  Now matching on any class that has a `starts_with`, `startsWith`, or 
`startswith` function. This is done in order (prioritising functions in 
subclasses, but this could be changed). Experimenting on making this an option, 
not sure it's worth it without controlling class names as well.
 -  Not using `Lexer::getSourceText` anymore.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-17 Thread Nicolas van Kempen via cfe-commits


@@ -12,4 +12,4 @@
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
 typedef __SIZE_TYPE__ size_t;
 
-#endif _STDDEF_H_
+#endif // _STDDEF_H_

nicovank wrote:

This was just issuing a warning in some tests.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-17 Thread Nicolas van Kempen via cfe-commits


@@ -0,0 +1,109 @@
+//===--- UseStartsEndsWithCheck.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 "UseStartsEndsWithCheck.h"
+
+#include "../utils/OptionsUtils.h"
+#include "clang/Lex/Lexer.h"
+
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
+   ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context) {}
+
+void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) {
+  const auto ZeroLiteral = integerLiteral(equals(0));
+  const auto HasStartsWithMethod = anyOf(
+  hasMethod(cxxMethodDecl(hasName("starts_with")).bind("starts_with_fun")),
+  hasMethod(cxxMethodDecl(hasName("startsWith")).bind("starts_with_fun")),
+  hasMethod(cxxMethodDecl(hasName("startswith")).bind("starts_with_fun")));

nicovank wrote:

Using `hasAnyName` will match the first declared function. With this setup 
there is a precedence, I thought this was better. IIRC `llvm::StringRef` has 
`startswith` and `starts_with` and the latter is preferred.

This could maybe be an option, e.g. `OrderedStartsWithFunctions`. The code gets 
a bit trickier because this is the opposite of `mapAnyOf`, and AFAIK `anyOf` 
doesn't take a vector or other kind of collection, only varargs. Suggestions 
welcome.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-17 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 7a9703f27897af0846d272ca7393bc72eff11e55 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 109 +
 .../performance/UseStartsEndsWithCheck.h  |  37 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  | 151 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 358 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..74cba350663b0a6
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,109 @@
+//===--- UseStartsEndsWithCheck.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
+//
+//===--===//
+
+

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-22 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 22caf9b39e927e61eaef0499266dd7ab8e252ba0 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 114 
 .../performance/UseStartsEndsWithCheck.h  |  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  | 163 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..9251a41f5b1f407
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,114 @@
+//===--- UseStartsEndsWithCheck.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
+//
+//===--===//
+
+#i

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-22 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From e0074d270f2b78f8202c822a61a0d723e1adb2a3 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 114 
 .../performance/UseStartsEndsWithCheck.h  |  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  | 163 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..3167423419358a3
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,114 @@
+//===--- UseStartsEndsWithCheck.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
+//
+//===--===//
+
+#i

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-22 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Updates. I've been running into issues when the begin location of the entire 
expression is a macro. The prefix removal, which should include the macro text, 
is not working as I expect it to. If you know of any checks that have similar 
logic I can take a look and copy. I just disabled it if 
`ComparisonExpr->getBeginLoc().isMacroID()`. This is what the original check 
also did so I imagine they had a similar issue.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-22 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 0dc3f43049ca8558442ee2a6fbaf15da1510a9a3 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new performance-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/PerformanceTidyModule.cpp |   3 +
 .../performance/UseStartsEndsWithCheck.cpp| 113 
 .../performance/UseStartsEndsWithCheck.h  |  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../performance/use-starts-ends-with.rst  |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../performance/use-starts-ends-with.cpp  | 167 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 378 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..09773139daa1d66 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer performance-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021ed..fc88156d8c5f395 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangTidyPerformanceModule
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitialization.cpp
   UnnecessaryValueParamCheck.cpp
+  UseStartsEndsWithCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 9e0fa6f88b36a00..3405b5514cbce44 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitialization.h"
 #include "UnnecessaryValueParamCheck.h"
+#include "UseStartsEndsWithCheck.h"
 
 namespace clang::tidy {
 namespace performance {
@@ -70,6 +71,8 @@ class PerformanceModule : public ClangTidyModule {
 "performance-unnecessary-copy-initialization");
 CheckFactories.registerCheck(
 "performance-unnecessary-value-param");
+CheckFactories.registerCheck(
+"performance-use-starts-ends-with");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..d048705e1faa8a2
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,113 @@
+//===--- UseStartsEndsWithCheck.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
+//
+//===--===//
+
+#i

[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-22 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

@EugeneZelenko We've had this discussion, see here and the couple comments 
below: https://github.com/llvm/llvm-project/pull/72385#issuecomment-1812801402. 
I guess I can rename one more time if there is consensus.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-11-28 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Ping. @carlosgalvezp could you please weigh in? modernize / performance? Anyone 
else?

I have no real preference either way. Now that modernize is fully integrated in 
Clang-Tidy, I don't think historical reasons should lead to modernize 
overbloat. If this check was only replacing `strncmp` with `starts_with` it 
would definitely belong in modernize, as-is it sits in-between.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new performance-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 316b45d612c63f8eea8f847d1cd39992898516f3 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/UseStartsEndsWithCheck.cpp  | 113 
 .../modernize/UseStartsEndsWithCheck.h|  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-starts-ends-with.rst |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/use-starts-ends-with.cpp| 167 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 378 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..de3bd4d42220009 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..c40065358d2dc3d 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -38,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
+  UseStartsEndsWithCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
   UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..e994ffd2a75c857 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -39,6 +39,7 @@
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
+#include "UseStartsEndsWithCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
 #include "UseTransparentFunctorsCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-use-starts-ends-with");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..83451e09e26eaa8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,113 @@
+//===--- UseStartsEndsWithCheck.cpp - clang-tidy 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.t

[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Thank you!!
Modernize wins the vote, I've renamed the check.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 86292b1489a6e3998afb52e0625f0c38ff7657a5 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/UseStartsEndsWithCheck.cpp  | 113 
 .../modernize/UseStartsEndsWithCheck.h|  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-starts-ends-with.rst |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/use-starts-ends-with.cpp| 167 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 378 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece5439b..de3bd4d42220009 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c4790330..c40065358d2dc3d 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -38,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
+  UseStartsEndsWithCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
   UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf2705068d..e994ffd2a75c857 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -39,6 +39,7 @@
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
+#include "UseStartsEndsWithCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
 #include "UseTransparentFunctorsCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-use-starts-ends-with");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
new file mode 100644
index 000..83451e09e26eaa8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,113 @@
+//===--- UseStartsEndsWithCheck.cpp - clang-tidy 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.t

[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-01 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

> Support for `ends_with`.

Planning to look into it and other `starts_with` patterns.

I do not have commit access, please merge for me (`Nicolas van Kempen 
`).

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-04 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Thanks! There should be no more warning.

I tried to edit my GitHub settings, great if it worked, otherwise GitHub or 
personal email is fine.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-04 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From c6b5aac2b5a3d90d11a8fc0d092c2e794cff5856 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/UseStartsEndsWithCheck.cpp  | 109 
 .../modernize/UseStartsEndsWithCheck.h|  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-starts-ends-with.rst |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/use-starts-ends-with.cpp| 167 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 374 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece543..de3bd4d422200 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c47903..c40065358d2dc 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -38,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
+  UseStartsEndsWithCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
   UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf270506..e994ffd2a75c8 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -39,6 +39,7 @@
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
+#include "UseStartsEndsWithCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
 #include "UseTransparentFunctorsCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-use-starts-ends-with");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
new file mode 100644
index 0..062f6e9911dbe
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,109 @@
+//===--- UseStartsEndsWithCheck.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 i

[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-04 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

I've made it my primary email, if it's not an option, `@fb`, `@gmail`, or the 
GitHub indirection is fine.

https://github.com/llvm/llvm-project/assets/7906725/6ae684b4-429b-4f09-bb97-f4525422da39";>


https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-04 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/72385

>From 2b7748352281eb1dfa85cc8e4672488dfadee277 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 15 Nov 2023 01:13:10 -0800
Subject: [PATCH] [clang-tidy] Add new modernize-use-starts-ends-with check

Match .find() and .rfind() calls compared to 0, and suggests replacing them with
starts_with.
---
 .../abseil/StringFindStartswithCheck.h|   5 +-
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   3 +
 .../modernize/UseStartsEndsWithCheck.cpp  | 109 
 .../modernize/UseStartsEndsWithCheck.h|  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   7 +
 .../checks/abseil/string-find-startswith.rst  |   4 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-starts-ends-with.rst |  22 +++
 .../checkers/Inputs/Headers/stddef.h  |   2 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  16 +-
 .../abseil/string-find-startswith.cpp |   2 +-
 .../modernize/use-starts-ends-with.cpp| 167 ++
 .../readability/container-size-empty.cpp  |   4 +-
 14 files changed, 374 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h 
b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
index 923b5caece543..de3bd4d422200 100644
--- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -21,7 +21,6 @@ namespace clang::tidy::abseil {
 
 // Find string.find(...) == 0 comparisons and suggest replacing with 
StartsWith.
 // FIXME(niko): Add similar check for EndsWith
-// FIXME(niko): Add equivalent modernize checks for C++20's std::starts_With
 class StringFindStartswithCheck : public ClangTidyCheck {
 public:
   using ClangTidyCheck::ClangTidyCheck;
@@ -31,6 +30,10 @@ class StringFindStartswithCheck : public ClangTidyCheck {
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+// Prefer modernize-use-starts-ends-with when C++20 is available.
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus20;
+  }
 
 private:
   const std::vector StringLikeClasses;
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c47903..c40065358d2dc 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -38,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
+  UseStartsEndsWithCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
   UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf270506..e994ffd2a75c8 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -39,6 +39,7 @@
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
+#include "UseStartsEndsWithCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
 #include "UseTransparentFunctorsCheck.h"
@@ -66,6 +67,8 @@ class ModernizeModule : public ClangTidyModule {
 CheckFactories.registerCheck("modernize-make-shared");
 CheckFactories.registerCheck("modernize-make-unique");
 CheckFactories.registerCheck("modernize-pass-by-value");
+CheckFactories.registerCheck(
+"modernize-use-starts-ends-with");
 CheckFactories.registerCheck("modernize-use-std-print");
 CheckFactories.registerCheck(
 "modernize-raw-string-literal");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
new file mode 100644
index 0..062f6e9911dbe
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -0,0 +1,109 @@
+//===--- UseStartsEndsWithCheck.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 i

[clang-tools-extra] [clang-tidy] Add new modernize-use-starts-ends-with check (PR #72385)

2023-12-04 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Changed author to `@meta` in latest push, hopefully this fixes it... Didn't 
realise `@fb` was still default on my server.

https://github.com/llvm/llvm-project/pull/72385
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Avoid repeated hash lookups (NFC) (PR #107490)

2024-09-05 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank approved this pull request.

Are you finding those automatically with a tool? Or just stumbled upon it?

https://github.com/llvm/llvm-project/pull/107490
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][readability-container-contains] Extend to any class with contains (PR #107521)

2024-09-05 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/107521


This check will now work out of the box with other containers that have a
`contains` method, such as `folly::F14` or Abseil containers.

It will also work with strings, which are basically just weird containers.
`std::string` and `std::string_view` will have a `contains` method starting with
C++23. `llvm::StringRef` and `folly::StringPiece` are examples of existing
implementations with a `contains` method.


>From d7b62cdcbd48da6c286af7b113ceeadd8a507558 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Fri, 6 Sep 2024 01:18:40 -0400
Subject: [PATCH] [clang-tidy][readability-container-contains] Extend to any
 class with contains

This check will now work out of the box with other containers that have a
`contains` method, such as `folly::F14` or Abseil containers.

It will also work with strings, which are basically just weird containers.
`std::string` and `std::string_view` will have a `contains` method starting with
C++23. `llvm::StringRef` and `folly::StringPiece` are examples of existing
implementations with a `contains` method.
---
 .../readability/ContainerContainsCheck.cpp| 17 -
 .../readability/ContainerContainsCheck.h  |  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  6 ++-
 .../checks/readability/container-contains.rst | 38 +++
 .../readability/container-contains.cpp| 37 +-
 5 files changed, 64 insertions(+), 38 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
index dbb50a060e5960..9fe5fbae32173a 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
@@ -15,26 +15,25 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::readability {
 
 void ContainerContainsCheck::registerMatchers(MatchFinder *Finder) {
-  const auto SupportedContainers = hasType(
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasAnyName("::std::set", "::std::unordered_set", "::std::map",
- "::std::unordered_map", "::std::multiset",
- "::std::unordered_multiset", "::std::multimap",
- "::std::unordered_multimap"));
+  const auto HasContainsMethod = hasMethod(cxxMethodDecl(hasName("contains")));
+  const auto ContainerWithContains = hasType(
+  
hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(anyOf(
+  HasContainsMethod, 
hasAnyBase(hasType(hasCanonicalType(hasDeclaration(
+ cxxRecordDecl(HasContainsMethod)));
 
   const auto CountCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("count"))),
 argumentCountIs(1))
   .bind("call");
 
   const auto FindCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("find"))),
 argumentCountIs(1))
   .bind("call");
 
-  const auto EndCall = cxxMemberCallExpr(on(SupportedContainers),
+  const auto EndCall = cxxMemberCallExpr(on(ContainerWithContains),
  callee(cxxMethodDecl(hasName("end"))),
  argumentCountIs(0));
 
diff --git a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
index 2e8276d684cd79..de9fb862f49c7a 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
@@ -24,10 +24,8 @@ class ContainerContainsCheck : public ClangTidyCheck {
   : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
-
-protected:
   bool isLanguageVersionSupported(const LangOptions &LO) const final {
-return LO.CPlusPlus20;
+return LO.CPlusPlus;
   }
 };
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 6999c1ef2ea4b0..ccf7ace1811dc3 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -116,7 +116,11 @@ Changes in existing checks
   ` check to support replacing
   member function calls too.
 
-- Improved :doc:`readablility-implicit-bool-conversion
+- Improved :doc:`readability-container-contains
+  ` check
+  to let it work on any class that has a `contains` method.
+
+- Improved :doc:`readability-implicit-bool-conversion
   ` check
   by adding the option `UseUpperCaseLiteralSuffix` to select

[clang-tools-extra] [clang-tidy][readability-container-contains] Extend to any class with contains (PR #107521)

2024-09-05 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Pinging @vogelsgesang, @PiotrZSL, @5chmidti, @HerrCai0907, @carlosgalvezp for 
review.

I applied this modified version to llvm-project root, **554 files changed**, 
`check-all` passes. Almost all cases are moving from `count` to `contains`. How 
do you suggest putting up this PR for easier review? Split it up by top-level 
directory?

https://github.com/llvm/llvm-project/pull/107521
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][readability-container-contains] Extend to any class with contains (PR #107521)

2024-09-06 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/107521

>From f0f305a3deabafa9874f8b63325750bd3b1b831d Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Fri, 6 Sep 2024 10:30:22 -0400
Subject: [PATCH] [clang-tidy][readability-container-contains] Extend to any
 class with contains

This check will now work out of the box with other containers that have a
`contains` method, such as `folly::F14` or Abseil containers.

It will also work with strings, which are basically just weird containers.
`std::string` and `std::string_view` will have a `contains` method starting with
C++23. `llvm::StringRef` and `folly::StringPiece` are examples of existing
implementations with a `contains` method.
---
 .../readability/ContainerContainsCheck.cpp| 18 -
 .../readability/ContainerContainsCheck.h  |  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  6 ++-
 .../checks/readability/container-contains.rst | 38 +++
 .../readability/container-contains.cpp| 37 +-
 5 files changed, 65 insertions(+), 38 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
index dbb50a060e5960..a120a491ba53a9 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
@@ -15,26 +15,26 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::readability {
 
 void ContainerContainsCheck::registerMatchers(MatchFinder *Finder) {
-  const auto SupportedContainers = hasType(
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasAnyName("::std::set", "::std::unordered_set", "::std::map",
- "::std::unordered_map", "::std::multiset",
- "::std::unordered_multiset", "::std::multimap",
- "::std::unordered_multimap"));
+  const auto HasContainsMethod = hasMethod(
+  cxxMethodDecl(isConst(), returns(booleanType()), hasName("contains")));
+  const auto ContainerWithContains = hasType(
+  
hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(anyOf(
+  HasContainsMethod, 
hasAnyBase(hasType(hasCanonicalType(hasDeclaration(
+ cxxRecordDecl(HasContainsMethod)));
 
   const auto CountCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("count"))),
 argumentCountIs(1))
   .bind("call");
 
   const auto FindCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("find"))),
 argumentCountIs(1))
   .bind("call");
 
-  const auto EndCall = cxxMemberCallExpr(on(SupportedContainers),
+  const auto EndCall = cxxMemberCallExpr(on(ContainerWithContains),
  callee(cxxMethodDecl(hasName("end"))),
  argumentCountIs(0));
 
diff --git a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
index 2e8276d684cd79..de9fb862f49c7a 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
@@ -24,10 +24,8 @@ class ContainerContainsCheck : public ClangTidyCheck {
   : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
-
-protected:
   bool isLanguageVersionSupported(const LangOptions &LO) const final {
-return LO.CPlusPlus20;
+return LO.CPlusPlus;
   }
 };
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 6999c1ef2ea4b0..8e1b51824636f3 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -116,7 +116,11 @@ Changes in existing checks
   ` check to support replacing
   member function calls too.
 
-- Improved :doc:`readablility-implicit-bool-conversion
+- Improved :doc:`readability-container-contains
+  ` check
+  to let it work on any class that has a ``contains`` method.
+
+- Improved :doc:`readability-implicit-bool-conversion
   ` check
   by adding the option `UseUpperCaseLiteralSuffix` to select the
   case of the literal suffix in fixes.
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst 
b/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst
index b28daecf7a2cf3..86aac019359ff9 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst
+++ 
b/clang-tools-extra/do

[clang-tools-extra] [clang-tidy][readability-container-contains] Extend to any class with contains (PR #107521)

2024-09-06 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/107521

>From f0f305a3deabafa9874f8b63325750bd3b1b831d Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Fri, 6 Sep 2024 10:30:22 -0400
Subject: [PATCH] [clang-tidy][readability-container-contains] Extend to any
 class with contains

This check will now work out of the box with other containers that have a
`contains` method, such as `folly::F14` or Abseil containers.

It will also work with strings, which are basically just weird containers.
`std::string` and `std::string_view` will have a `contains` method starting with
C++23. `llvm::StringRef` and `folly::StringPiece` are examples of existing
implementations with a `contains` method.
---
 .../readability/ContainerContainsCheck.cpp| 18 -
 .../readability/ContainerContainsCheck.h  |  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  6 ++-
 .../checks/readability/container-contains.rst | 38 +++
 .../readability/container-contains.cpp| 37 +-
 5 files changed, 65 insertions(+), 38 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
index dbb50a060e5960..a120a491ba53a9 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp
@@ -15,26 +15,26 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::readability {
 
 void ContainerContainsCheck::registerMatchers(MatchFinder *Finder) {
-  const auto SupportedContainers = hasType(
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasAnyName("::std::set", "::std::unordered_set", "::std::map",
- "::std::unordered_map", "::std::multiset",
- "::std::unordered_multiset", "::std::multimap",
- "::std::unordered_multimap"));
+  const auto HasContainsMethod = hasMethod(
+  cxxMethodDecl(isConst(), returns(booleanType()), hasName("contains")));
+  const auto ContainerWithContains = hasType(
+  
hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(anyOf(
+  HasContainsMethod, 
hasAnyBase(hasType(hasCanonicalType(hasDeclaration(
+ cxxRecordDecl(HasContainsMethod)));
 
   const auto CountCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("count"))),
 argumentCountIs(1))
   .bind("call");
 
   const auto FindCall =
-  cxxMemberCallExpr(on(SupportedContainers),
+  cxxMemberCallExpr(on(ContainerWithContains),
 callee(cxxMethodDecl(hasName("find"))),
 argumentCountIs(1))
   .bind("call");
 
-  const auto EndCall = cxxMemberCallExpr(on(SupportedContainers),
+  const auto EndCall = cxxMemberCallExpr(on(ContainerWithContains),
  callee(cxxMethodDecl(hasName("end"))),
  argumentCountIs(0));
 
diff --git a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h 
b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
index 2e8276d684cd79..de9fb862f49c7a 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.h
@@ -24,10 +24,8 @@ class ContainerContainsCheck : public ClangTidyCheck {
   : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
-
-protected:
   bool isLanguageVersionSupported(const LangOptions &LO) const final {
-return LO.CPlusPlus20;
+return LO.CPlusPlus;
   }
 };
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 6999c1ef2ea4b0..8e1b51824636f3 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -116,7 +116,11 @@ Changes in existing checks
   ` check to support replacing
   member function calls too.
 
-- Improved :doc:`readablility-implicit-bool-conversion
+- Improved :doc:`readability-container-contains
+  ` check
+  to let it work on any class that has a ``contains`` method.
+
+- Improved :doc:`readability-implicit-bool-conversion
   ` check
   by adding the option `UseUpperCaseLiteralSuffix` to select the
   case of the literal suffix in fixes.
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst 
b/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst
index b28daecf7a2cf3..86aac019359ff9 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/readability/container-contains.rst
+++ 
b/clang-tools-extra/do

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for two ends_with patterns (PR #105366)

2024-09-06 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/105366

>From 7e734f7c2e5e487bb3c6f9e30ff92f0ef129f409 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Fri, 6 Sep 2024 10:34:49 -0400
Subject: [PATCH] [clang-tidy][modernize-use-starts-ends-with] Add support for
 two ends_with patterns

Add support for the following two patterns:
```
haystack.compare(haystack.length() - needle.length(), needle.length(), needle) 
== 0;
haystack.rfind(needle) == (haystack.size() - needle.size());
```
---
 .../modernize/UseStartsEndsWithCheck.cpp  | 226 +++---
 .../modernize/UseStartsEndsWithCheck.h|   2 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   4 +
 .../checks/modernize/use-starts-ends-with.rst |  12 +-
 .../clang-tidy/checkers/Inputs/Headers/string |   8 +
 .../modernize/use-starts-ends-with.cpp|  57 +
 6 files changed, 215 insertions(+), 94 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 89ee45faecd7f3..5eb3267adb0799 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseStartsEndsWithCheck.h"
 
+#include "../utils/ASTUtils.h"
 #include "../utils/OptionsUtils.h"
 #include "clang/Lex/Lexer.h"
 
@@ -16,6 +17,63 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+struct NotLengthExprForStringNode {
+  NotLengthExprForStringNode(std::string ID, DynTypedNode Node,
+ ASTContext *Context)
+  : ID(std::move(ID)), Node(std::move(Node)), Context(Context) {}
+  bool operator()(const internal::BoundNodesMap &Nodes) const {
+// Match a string literal and an integer size or strlen() call.
+if (const auto *StringLiteralNode = Nodes.getNodeAs(ID)) {
+  if (const auto *IntegerLiteralSizeNode = Node.get()) {
+return StringLiteralNode->getLength() !=
+   IntegerLiteralSizeNode->getValue().getZExtValue();
+  }
+
+  if (const auto *StrlenNode = Node.get()) {
+if (StrlenNode->getDirectCallee()->getName() != "strlen" ||
+StrlenNode->getNumArgs() != 1) {
+  return true;
+}
+
+if (const auto *StrlenArgNode = dyn_cast(
+StrlenNode->getArg(0)->IgnoreParenImpCasts())) {
+  return StrlenArgNode->getLength() != StringLiteralNode->getLength();
+}
+  }
+}
+
+// Match a string variable and a call to length() or size().
+if (const auto *ExprNode = Nodes.getNodeAs(ID)) {
+  if (const auto *MemberCallNode = Node.get()) {
+const CXXMethodDecl *MethodDeclNode = MemberCallNode->getMethodDecl();
+const StringRef Name = MethodDeclNode->getName();
+if (!MethodDeclNode->isConst() || MethodDeclNode->getNumParams() != 0 
||
+(Name != "size" && Name != "length")) {
+  return true;
+}
+
+if (const auto *OnNode =
+dyn_cast(MemberCallNode->getImplicitObjectArgument())) {
+  return !utils::areStatementsIdentical(OnNode->IgnoreParenImpCasts(),
+
ExprNode->IgnoreParenImpCasts(),
+*Context);
+}
+  }
+}
+
+return true;
+  }
+
+private:
+  std::string ID;
+  DynTypedNode Node;
+  ASTContext *Context;
+};
+
+AST_MATCHER_P(Expr, lengthExprForStringNode, std::string, ID) {
+  return Builder->removeBindings(NotLengthExprForStringNode(
+  ID, DynTypedNode::create(Node), &(Finder->getASTContext(;
+}
 
 UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
ClangTidyContext *Context)
@@ -23,6 +81,7 @@ UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
 
 void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) {
   const auto ZeroLiteral = integerLiteral(equals(0));
+
   const auto HasStartsWithMethodWithName = [](const std::string &Name) {
 return hasMethod(
 cxxMethodDecl(hasName(Name), isConst(), parameterCountIs(1))
@@ -32,119 +91,104 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   anyOf(HasStartsWithMethodWithName("starts_with"),
 HasStartsWithMethodWithName("startsWith"),
 HasStartsWithMethodWithName("startswith"));
-  const auto ClassWithStartsWithFunction = cxxRecordDecl(anyOf(
-  HasStartsWithMethod, hasAnyBase(hasType(hasCanonicalType(hasDeclaration(
-   cxxRecordDecl(HasStartsWithMethod)));
+  const auto OnClassWithStartsWithFunction =
+  on(hasType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
+  anyOf(HasStartsWithMethod,
+hasAnyBase(hasType(hasCanonicalType(
+
hasDeclaration(cxxRecordDecl(HasStartsWithMethod)))

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for two ends_with patterns (PR #105366)

2024-09-06 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Rebase to resolve merge conflict. Ping.

https://github.com/llvm/llvm-project/pull/105366
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-08 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/107764


Fix #107724.


>From a43b9b74ac253c0072498007cf56ed57d8255143 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 8 Sep 2024 11:52:28 -0400
Subject: [PATCH] [clang][analyzer] Fix #embed crash

Fix #107724.
---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 5 +
 clang/test/Analysis/embed.c  | 9 +
 2 files changed, 10 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/Analysis/embed.c

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 315d85319a85a9..fdabba46992b08 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1938,6 +1938,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
 case Stmt::CXXRewrittenBinaryOperatorClass:
 case Stmt::RequiresExprClass:
 case Expr::CXXParenListInitExprClass:
+case Stmt::EmbedExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
@@ -2440,10 +2441,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   Bldr.addNodes(Dst);
   break;
 }
-
-case Stmt::EmbedExprClass:
-  llvm::report_fatal_error("Support for EmbedExpr is not implemented.");
-  break;
   }
 }
 
diff --git a/clang/test/Analysis/embed.c b/clang/test/Analysis/embed.c
new file mode 100644
index 00..7201bb30386fb7
--- /dev/null
+++ b/clang/test/Analysis/embed.c
@@ -0,0 +1,9 @@
+// RUN: %clang_analyze_cc1 -std=c23 
-analyzer-checker=core,debug.ExprInspection -verify %s
+
+// expected-no-diagnostics
+
+int main() {
+const unsigned char SelfBytes[] = {
+#embed "embed.c"
+};
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-08 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

PS: Should this be cherry-picked into 19?

https://github.com/llvm/llvm-project/pull/107764
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank commented:

I commented in issue but I think the problem is with `re.Match` not Tuple. 
[Python docs](https://docs.python.org/3.5/library/typing.html#typing.Tuple) 
seem to show Tuple had subscripting from its introduction in 3.5.

The script currently passes a strict mypy check which requires all parameters 
annotated, would be nice to keep it.

```
python3 -m mypy --strict ./clang-tools-extra/clang-tidy/add_new_check.py
```

https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits


@@ -526,7 +526,7 @@ def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]
 # Is it a redirect?
 return check_name, match
 
-def format_link(doc_file: Tuple[str, str]) -> str:
+def format_link(doc_file) -> str:

nicovank wrote:

I believe this can stay.

https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits


@@ -538,7 +538,7 @@ def format_link(doc_file: Tuple[str, str]) -> str:
 else:
 return ""
 
-def format_link_alias(doc_file: Tuple[str, str]) -> str:
+def format_link_alias(doc_file) -> str:

nicovank wrote:

So can this.

https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits


@@ -511,7 +511,7 @@ def has_auto_fix(check_name: str) -> str:
 
 return ""
 
-def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]]:
+def process_doc(doc_file):

nicovank wrote:

Change the `re.Match[str]` to `typing.Any`? Plus maybe a `FIXME Python 3.9` 
comment?

https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank approved this pull request.

Thanks!

https://github.com/llvm/llvm-project/pull/107850
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][NFC] fix add_new_check python3.8 incompatibility (PR #107871)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

I see `typing.Match` will be [removed in 
3.13](https://docs.python.org/3/library/typing.html#typing.Match). I'm not sure 
if that means it won't work altogether with 3.13 or just the typecheck.

![image](https://github.com/user-attachments/assets/c3d77647-356d-43ba-b344-da8822a0ddf7)

My vote goes to `Any` and switch back to `re.Match` when LLVM minimum is bumped 
>= 3.9 (#107850).


https://github.com/llvm/llvm-project/pull/107871
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][run-clang-tidy] Fix minor shutdown noise (PR #105724)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

I'm going to go ahead and merge this. IMO this doesn't need backporting because 
1. it only happens on abnormal exit where users probably wouldn't be surprised 
to see a stacktrace anyway, and 2. there is no regression really (check prior 
to asyncio change also had some noise after Ctrl+C message). But if someone 
thinks otherwise I'll stamp it 👍.

https://github.com/llvm/llvm-project/pull/105724
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][run-clang-tidy] Fix minor shutdown noise (PR #105724)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank closed 
https://github.com/llvm/llvm-project/pull/105724
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][NFC] fix add_new_check python3.8 incompatibility (PR #107871)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Update: I misread the docs, `typing.re` is what's going to be removed, 
`typing.Match` is only deprecated but not planned for removal yet. Still think 
`Any` is the way to go to avoid introducing the deprecated type but either 
solution is actually fine.

https://github.com/llvm/llvm-project/pull/107871
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][NFC] fix add_new_check python3.8 incompatibility (PR #107871)

2024-09-09 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Exactly, IMO the move to 3.9 minimum should be in 6-12 months to leave a bit of 
time after EOL. 3.9 also has subscriptable `tuple`, `list` and `dict` which is 
nice. 

https://github.com/llvm/llvm-project/pull/107871
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/104148

`hasOperands` does not always execute matchers in the order they are written. 
This can cause issue in code using bindings when one operand matcher is relying 
on a binding set by the other. With this change, the first matcher present in 
the code is always executed first and any binding it sets are available to the 
second matcher.

Simple example with current version (1 match) and new version (2 matches):
```bash
> cat tmp.cpp
int a = 13;
int b = ((int) a) - a;
int c = a - ((int) a);

> clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
int a = 13;
^~
tmp.cpp:2:9: note: "root" binds here
int b = ((int)a) - a;
^~~~
1 match.

> ./build/bin/clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:2:9: note: "root" binds here
2 | int b = ((int)a) - a;
  | ^~~~

Match #2:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:3:9: note: "root" binds here
3 | int c = a - ((int)a);
  | ^~~~
2 matches.
```

If this should be documented or regression tested anywhere please let me know 
where.

>From 6391d7d4a4ebe6132ef465ddab00c3b88d3c1719 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:34:43 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

`hasOperands` does not always execute matchers in the order they are written.
This can cause issue in code using bindings when one operand matcher is relying
on a binding set by the other. With this change, the first matcher present in
the code is always executed first and any binding it sets are available to the
second matcher.

Simple example with current version (1 match) and new version (2 matches):
```bash
> cat tmp.cpp
int a = 13;
int b = ((int) a) - a;
int c = a - ((int) a);

> clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
int a = 13;
^~
tmp.cpp:2:9: note: "root" binds here
int b = ((int)a) - a;
^~~~
1 match.

> ./build/bin/clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:2:9: note: "root" binds here
2 | int b = ((int)a) - a;
  | ^~~~

Match #2:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:3:9: note: "root" binds here
3 | int c = a - ((int)a);
  | ^~~~
2 matches.
```
---
 clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 6429dd6935343b343ce3082c13e772425caea15a Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:47:52 -0400
Subject: [PATCH 1/2] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

`hasOperands` does not always execute matchers in the order they are written.
This can cause issue in code using bindings when one operand matcher is relying
on a binding set by the other. With this change, the first matcher present in
the code is always executed first and any binding it sets are available to the
second matcher.

Simple example with current version (1 match) and new version (2 matches):
```
> cat tmp.cpp
int a = 13;
int b = ((int) a) - a;
int c = a - ((int) a);

> clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
int a = 13;
^~
tmp.cpp:2:9: note: "root" binds here
int b = ((int)a) - a;
^~~~
1 match.

> ./build/bin/clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:2:9: note: "root" binds here
2 | int b = ((int)a) - a;
  | ^~~~

Match #2:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:3:9: note: "root" binds here
3 | int c = a - ((int)a);
  | ^~~~
2 matches.
```
---
 clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 

>From 20b4cbaba593ef82dfaa74f468d78e4f162e544e Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:47:52 -0400
Subject: [PATCH 2/2] [clang-tidy][modernize-use-starts-ends-with] Add support
 for two ends_with patterns

Add support for the following two patterns:
```
haystack.compare(haystack.length() - needle.length(), needle.length(), needle) 
== 0;
haystack.rfind(needle) == (haystack.size() - needle.size());
```
---
 .../modernize/UseStartsEndsWithCheck.cpp  | 222 +++---
 .../clang-tidy/checkers/Inputs/Headers/string |   8 +
 .../modernize/use-starts-ends-with.cpp|  57 +
 3 files changed, 196 insertions(+), 91 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 89ee45faecd7f3..11c8d60933aacf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseStartsEndsWithCheck.h"
 
+#include "../utils/ASTUtils.h"
 #include "../utils/OptionsUtils.h"
 #include "clang/Lex/Lexer.h"
 
@@ -16,6 +17,59 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+struct NotLengthExprForStringNode {
+  NotLengthExprForStringNode(std::string ID, DynTypedNode Node,
+ ASTContext *Context)
+  : ID(std::move(ID)), Node(std::move(Node)), Context(Context) {}
+  bool operator()(const internal::BoundNodesMap &Nodes) const {
+if (const auto *StringLiteralNode = Nodes.getNodeAs(ID)) {
+  if (const auto *IntegerLiteralSizeNode = Node.get()) {
+return StringLiteralNode->getLength() !=
+   IntegerLiteralSizeNode->getValue().getZExtValue();
+  }
+
+  if (const auto *StrlenNode = Node.get()) {
+if (StrlenNode->getDirectCallee()->getName() != "strlen" ||
+StrlenNode->getNumArgs() != 1) {
+  return true;
+}
+
+if (const auto *StrlenArgNode = dyn_cast(
+StrlenNode->getArg(0)->IgnoreParenImpCasts())) {
+  return StrlenArgNode->getLength() != StringLiteralNode->getLength();
+}
+  }
+} else if (const auto *ExprNode = Nodes.getNodeAs(ID)) {
+  if (const auto *MemberCallNode = Node.get()) {
+const CXXMeth

[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 6429dd6935343b343ce3082c13e772425caea15a Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:47:52 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

`hasOperands` does not always execute matchers in the order they are written.
This can cause issue in code using bindings when one operand matcher is relying
on a binding set by the other. With this change, the first matcher present in
the code is always executed first and any binding it sets are available to the
second matcher.

Simple example with current version (1 match) and new version (2 matches):
```
> cat tmp.cpp
int a = 13;
int b = ((int) a) - a;
int c = a - ((int) a);

> clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
int a = 13;
^~
tmp.cpp:2:9: note: "root" binds here
int b = ((int)a) - a;
^~~~
1 match.

> ./build/bin/clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:2:9: note: "root" binds here
2 | int b = ((int)a) - a;
  | ^~~~

Match #2:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:3:9: note: "root" binds here
3 | int c = a - ((int)a);
  | ^~~~
2 matches.
```
---
 clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 3ee431b27ac1d20cc6446fc6a8c663f33dd17d12 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:48:57 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

The `hasOperands` matcher does not always execute matchers in the order they are
written. This can cause issue in code using bindings when one operand matcher is
relying on a binding set by the other. With this change, the first matcher
present in the code is always executed first and any binding it sets are
available to the second matcher.

Simple example with current version (1 match) and new version (2 matches):
```
> cat tmp.cpp
int a = 13;
int b = ((int) a) - a;
int c = a - ((int) a);

> clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
int a = 13;
^~
tmp.cpp:2:9: note: "root" binds here
int b = ((int)a) - a;
^~~~
1 match.

> ./build/bin/clang-query tmp.cpp
clang-query> set traversal IgnoreUnlessSpelledInSource
clang-query> m 
binaryOperator(hasOperands(cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))

Match #1:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:2:9: note: "root" binds here
2 | int b = ((int)a) - a;
  | ^~~~

Match #2:

tmp.cpp:1:1: note: "d" binds here
1 | int a = 13;
  | ^~
tmp.cpp:3:9: note: "root" binds here
3 | int c = a - ((int)a);
  | ^~~~
2 matches.
```
---
 clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-14 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 168f812b5817ea2a9a80e0a6b52b2005e57d327c Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 14 Aug 2024 14:54:20 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

The `hasOperands` matcher does not always execute matchers in the order they are
written. This can cause issue in code using bindings when one operand matcher is
relying on a binding set by the other. With this change, the first matcher
present in the code is always executed first and any binding it sets are
available to the second matcher.
---
 clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 631dce009698938a5fc380ae0af054fbc6d741ea Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Thu, 15 Aug 2024 10:49:53 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

The `hasOperands` matcher does not always execute matchers in the order they are
written. This can cause issue in code using bindings when one operand matcher is
relying on a binding set by the other. With this change, the first matcher
present in the code is always executed first and any binding it sets are
available to the second matcher.
---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/include/clang/ASTMatchers/ASTMatchers.h|  2 +-
 .../ASTMatchers/ASTMatchersTraversalTest.cpp | 12 
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b1864901e7bddb..9a547db6595e73 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -352,6 +352,9 @@ AST Matchers
 - Fixed an issue with the `hasName` and `hasAnyName` matcher when matching
   inline namespaces with an enclosing namespace of the same name.
 
+- Fixed an ordering issue with the `hasOperands` matcher occuring when setting 
a
+  binding in the first matcher and using it in the second matcher.
+
 clang-format
 
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 47a71134d50273..028392f499da3b 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1745,6 +1745,18 @@ TEST(MatchBinaryOperator, HasOperands) {
   EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
 }
 
+TEST(MatchBinaryOperator, HasOperandsEnsureOrdering) {
+  StatementMatcher HasOperandsWithBindings = binaryOperator(hasOperands(
+  cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
+  declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"));
+  EXPECT_TRUE(matches(
+  "int a; int b = ((int) a) + a;",
+  traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
+  EXPECT_TRUE(matches(
+  "int a; int b = a + ((int) a);",
+  traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
+}
+
 TEST(Matcher, BinaryOperatorTypes) {
   // Integration test that verifies the AST provides all binary operators in
   // a way we expect.

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-15 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/104148

>From 462fc6fff523496bee9ffc5516315d6622ec3ee3 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Thu, 15 Aug 2024 11:02:36 -0400
Subject: [PATCH] [clang][ASTMatcher] Fix execution order of hasOperands
 submatchers

The `hasOperands` matcher does not always execute matchers in the order they are
written. This can cause issues in code using bindings when one operand matcher
is relying on a binding set by the other. With this change, the first matcher
present in the code is always executed first and any binding it sets are
available to the second matcher.
---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/include/clang/ASTMatchers/ASTMatchers.h|  2 +-
 .../ASTMatchers/ASTMatchersTraversalTest.cpp | 12 
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f5696d6ce15dc7..d9660e6a8b82fe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -350,6 +350,9 @@ AST Matchers
 - Fixed an issue with the `hasName` and `hasAnyName` matcher when matching
   inline namespaces with an enclosing namespace of the same name.
 
+- Fixed an ordering issue with the `hasOperands` matcher occuring when setting 
a
+  binding in the first matcher and using it in the second matcher.
+
 clang-format
 
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ca44c3ee085654..f1c72efc238784 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
 internal::Matcher, Matcher1, internal::Matcher, Matcher2) {
   return internal::VariadicDynCastAllOfMatcher()(
  anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
-   allOf(hasLHS(Matcher2), hasRHS(Matcher1
+   allOf(hasRHS(Matcher1), hasLHS(Matcher2
   .matches(Node, Finder, Builder);
 }
 
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 47a71134d50273..028392f499da3b 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1745,6 +1745,18 @@ TEST(MatchBinaryOperator, HasOperands) {
   EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
 }
 
+TEST(MatchBinaryOperator, HasOperandsEnsureOrdering) {
+  StatementMatcher HasOperandsWithBindings = binaryOperator(hasOperands(
+  cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"),
+  declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"));
+  EXPECT_TRUE(matches(
+  "int a; int b = ((int) a) + a;",
+  traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
+  EXPECT_TRUE(matches(
+  "int a; int b = a + ((int) a);",
+  traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
+}
+
 TEST(Matcher, BinaryOperatorTypes) {
   // Integration test that verifies the AST provides all binary operators in
   // a way we expect.

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Fix execution order of hasOperands submatchers (PR #104148)

2024-08-15 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Thanks a lot for the pointers! Added a test and a note 👍. Let me know if this 
is adequate.
If/when CI passes if everything looks in order you can press the merge button, 
I don't have commit access.

https://github.com/llvm/llvm-project/pull/104148
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] My Commit, Second commit. (PR #96115)

2024-06-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/96115

My Commit, Second commit.


>From 3a4de668b952c4db849f41b34c0f9e7869506c96 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 19 Jun 2024 16:40:37 -0400
Subject: [PATCH] My Commit, Second commit.

---
 clang-tools-extra/docs/ReleaseNotes.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 16fdc20eafd62..4b5b45104279a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -2,10 +2,14 @@
 Extra Clang Tools |release| |ReleaseNotesTitle|
 
 
+This is a test!
+
 .. contents::
:local:
:depth: 3
 
+   I'm the best!
+
 Written by the `LLVM Team `_
 
 .. only:: PreRelease

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] My Commit, Second commit. (PR #96115)

2024-06-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank closed 
https://github.com/llvm/llvm-project/pull/96115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] My Commit, Second commit. (PR #96115)

2024-06-19 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Oops, was demoing something. Closing.

https://github.com/llvm/llvm-project/pull/96115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [Ignore] (PR #96115)

2024-06-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/96115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [Ignore] (PR #96115)

2024-06-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank edited 
https://github.com/llvm/llvm-project/pull/96115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)

2024-05-28 Thread Nicolas van Kempen via cfe-commits


@@ -501,70 +506,72 @@ def main():
 
 # Build up a big regexy filter from all command line arguments.
 file_name_re = re.compile("|".join(args.files))
+files = {f for f in files if file_name_re.search(f)}
 
-return_code = 0
+returncode = 0
 try:
-# Spin up a bunch of tidy-launching threads.
-task_queue = queue.Queue(max_task)
-# List of files with a non-zero return code.
-failed_files = []
-lock = threading.Lock()
-for _ in range(max_task):
-t = threading.Thread(
-target=run_tidy,
-args=(
-args,
-clang_tidy_binary,
-export_fixes_dir,
-build_path,
-task_queue,
-lock,
-failed_files,
-),
+semaphore = asyncio.Semaphore(max_task)
+tasks = [
+run_with_semaphore(
+semaphore,
+run_tidy,
+args,
+f,
+clang_tidy_binary,
+export_fixes_dir,
+build_path,
 )
-t.daemon = True
-t.start()
-
-# Fill the queue with files.
-for name in files:
-if file_name_re.search(name):
-task_queue.put(name)
-
-# Wait for all threads to be done.
-task_queue.join()
-if len(failed_files):
-return_code = 1
-
+for f in files
+]
+
+for i, coro in enumerate(asyncio.as_completed(tasks)):
+name, process_returncode, stdout, stderr = await coro
+if process_returncode != 0:
+returncode = 1
+if process_returncode < 0:
+stderr += f"{name}: terminated by signal 
{-process_returncode}\n"
+print(f"[{i + 1}/{len(files)}] {name}")
+if stdout:
+print(stdout)
+if stderr:
+print(stderr, file=sys.stderr)
 except KeyboardInterrupt:
 # This is a sad hack. Unfortunately subprocess goes
 # bonkers with ctrl-c and we start forking merrily.
 print("\nCtrl-C detected, goodbye.")
 if delete_fixes_dir:
+assert export_fixes_dir
 shutil.rmtree(export_fixes_dir)
 os.kill(0, 9)
 
 if combine_fixes:
-print("Writing fixes to " + args.export_fixes + " ...")
+print(f"Writing fixes to {args.export_fixes} ...")
 try:
+assert export_fixes_dir
 merge_replacement_files(export_fixes_dir, args.export_fixes)
 except:
 print("Error exporting fixes.\n", file=sys.stderr)
 traceback.print_exc()
-return_code = 1
+returncode = 1
 
 if args.fix:
 print("Applying fixes ...")
 try:
+assert export_fixes_dir
 apply_fixes(args, clang_apply_replacements_binary, 
export_fixes_dir)
 except:
 print("Error applying fixes.\n", file=sys.stderr)
 traceback.print_exc()
-return_code = 1
+returncode = 1
 
 if delete_fixes_dir:
+assert export_fixes_dir
 shutil.rmtree(export_fixes_dir)
-sys.exit(return_code)
+sys.exit(returncode)
 
 
 if __name__ == "__main__":
-main()
+# FIXME Python 3.7: This can be simplified by asyncio.run(main()).
+loop = asyncio.new_event_loop()
+loop.run_until_complete(main())
+loop.close()

nicovank wrote:

If you call main or any other `async` function without special handling you get 
some
```
RuntimeWarning: coroutine 'main' was never awaited
```

Since `await` can only be used in `async` functions, it's common to use 
[`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run)
 and wrap `main`. That is Python 3.7 and above, we get compatibility with 3.6 
by using those 3 lines instead.

https://github.com/llvm/llvm-project/pull/89490
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)

2024-05-28 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89490

>From 33485bf2ab3c683897f1381f3f4ab8294bdb0b72 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sat, 20 Apr 2024 02:58:25 +
Subject: [PATCH] [run-clang-tidy.py] Refactor, add progress indicator, add
 type hints

---
 .../clang-tidy/tool/run-clang-tidy.py | 314 ++
 clang-tools-extra/docs/ReleaseNotes.rst   |   2 +
 2 files changed, 182 insertions(+), 134 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py 
b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 4dd20bec81d3b..106632428d131 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -34,29 +34,31 @@
 http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
 """
 
-from __future__ import print_function
-
 import argparse
+import asyncio
 import glob
 import json
 import multiprocessing
 import os
-import queue
 import re
 import shutil
 import subprocess
 import sys
 import tempfile
-import threading
+import time
 import traceback
+from types import ModuleType
+from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar
+
 
+yaml: Optional[ModuleType] = None
 try:
 import yaml
 except ImportError:
 yaml = None
 
 
-def strtobool(val):
+def strtobool(val: str) -> bool:
 """Convert a string representation of truth to a bool following LLVM's CLI 
argument parsing."""
 
 val = val.lower()
@@ -67,11 +69,11 @@ def strtobool(val):
 
 # Return ArgumentTypeError so that argparse does not substitute its own 
error message
 raise argparse.ArgumentTypeError(
-"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
+f"'{val}' is invalid value for boolean argument! Try 0 or 1."
 )
 
 
-def find_compilation_database(path):
+def find_compilation_database(path: str) -> str:
 """Adjusts the directory until a compilation database is found."""
 result = os.path.realpath("./")
 while not os.path.isfile(os.path.join(result, path)):
@@ -83,48 +85,42 @@ def find_compilation_database(path):
 return result
 
 
-def make_absolute(f, directory):
-if os.path.isabs(f):
-return f
-return os.path.normpath(os.path.join(directory, f))
-
-
 def get_tidy_invocation(
-f,
-clang_tidy_binary,
-checks,
-tmpdir,
-build_path,
-header_filter,
-allow_enabling_alpha_checkers,
-extra_arg,
-extra_arg_before,
-quiet,
-config_file_path,
-config,
-line_filter,
-use_color,
-plugins,
-warnings_as_errors,
-exclude_header_filter,
-):
+f: str,
+clang_tidy_binary: str,
+checks: str,
+tmpdir: Optional[str],
+build_path: str,
+header_filter: Optional[str],
+allow_enabling_alpha_checkers: bool,
+extra_arg: List[str],
+extra_arg_before: List[str],
+quiet: bool,
+config_file_path: str,
+config: str,
+line_filter: Optional[str],
+use_color: bool,
+plugins: List[str],
+warnings_as_errors: Optional[str],
+exclude_header_filter: Optional[str],
+) -> List[str]:
 """Gets a command line for clang-tidy."""
 start = [clang_tidy_binary]
 if allow_enabling_alpha_checkers:
 start.append("-allow-enabling-analyzer-alpha-checkers")
 if exclude_header_filter is not None:
-start.append("--exclude-header-filter=" + exclude_header_filter)
+start.append(f"--exclude-header-filter={exclude_header_filter}")
 if header_filter is not None:
-start.append("-header-filter=" + header_filter)
+start.append(f"-header-filter={header_filter}")
 if line_filter is not None:
-start.append("-line-filter=" + line_filter)
+start.append(f"-line-filter={line_filter}")
 if use_color is not None:
 if use_color:
 start.append("--use-color")
 else:
 start.append("--use-color=false")
 if checks:
-start.append("-checks=" + checks)
+start.append(f"-checks={checks}")
 if tmpdir is not None:
 start.append("-export-fixes")
 # Get a temporary file. We immediately close the handle so clang-tidy 
can
@@ -133,26 +129,27 @@ def get_tidy_invocation(
 os.close(handle)
 start.append(name)
 for arg in extra_arg:
-start.append("-extra-arg=%s" % arg)
+start.append(f"-extra-arg={arg}")
 for arg in extra_arg_before:
-start.append("-extra-arg-before=%s" % arg)
-start.append("-p=" + build_path)
+start.append(f"-extra-arg-before={arg}")
+start.append(f"-p={build_path}")
 if quiet:
 start.append("-quiet")
 if config_file_path:
-start.append("--config-file=" + config_file_path)
+start.append(f"--config-file={config_file_path}")
 elif config:
-start.append("-config=" + config)
+start.append(f"-config={config}")
 for plugin in plugins:

[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)

2024-05-28 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

 -  Minor change to progress indicator to stay aligned.
 -  Go back to printing command line. I'm fine with leaving this as-is.
 -  I think I pruned some changes by accident on rebase, thanks @5chmidti! 
Restored runtime number and initial message.

--

> More graceful shutdown would be welcome.

@PiotrZSL I can't reproduce on my setup (MacOS/3.12). What OS/Python version 
does this occur on? Will look into better shutdown.


https://github.com/llvm/llvm-project/pull/89490
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] Apply modernize-use-starts-ends-with on llvm-project (PR #89140)

2024-04-17 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/89140

Run `modernize-use-starts-ends-with` on llvm-project. Two instances are 
flagged, minor readability improvements, extremely minor performance 
improvements.

```
python3 clang-tools-extra/clang-tidy/tool/run-clang-tidy.py \
-clang-tidy-binary="build/bin/clang-tidy" \
-clang-apply-replacements-binary="build/bin/clang-apply-replacements" \
-checks="-*,modernize-use-starts-ends-with" \
-header-filter=".*" \
-fix -format
```

I am working on some additions to this check, but they don't seem to flag any 
additional cases anyway.

>From 4f28eccd28878683c75f17e0114d1b3b2380190c Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 17 Apr 2024 14:27:42 -0400
Subject: [PATCH] Apply modernize-use-starts-ends-with on llvm-project

---
 clang-tools-extra/clang-doc/Representation.cpp   | 4 ++--
 llvm/unittests/Support/VirtualFileSystemTest.cpp | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index 84233c36e15d98..2afff2929cf79c 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -380,8 +380,8 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext 
*ECtx,
   this->SourceRoot = std::string(SourceRootDir);
   if (!RepositoryUrl.empty()) {
 this->RepositoryUrl = std::string(RepositoryUrl);
-if (!RepositoryUrl.empty() && RepositoryUrl.find("http://";) != 0 &&
-RepositoryUrl.find("https://";) != 0)
+if (!RepositoryUrl.empty() && !RepositoryUrl.starts_with("http://";) &&
+!RepositoryUrl.starts_with("https://";))
   this->RepositoryUrl->insert(0, "https://";);
   }
 }
diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp 
b/llvm/unittests/Support/VirtualFileSystemTest.cpp
index e9b4ac3d92e1dd..e9fd9671ea6ab5 100644
--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -101,7 +101,7 @@ class DummyFileSystem : public vfs::FileSystem {
 std::map::iterator I;
 std::string Path;
 bool isInPath(StringRef S) {
-  if (Path.size() < S.size() && S.find(Path) == 0) {
+  if (Path.size() < S.size() && S.starts_with(Path)) {
 auto LastSep = S.find_last_of('/');
 if (LastSep == Path.size() || LastSep == Path.size() - 1)
   return true;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] Apply modernize-use-starts-ends-with on llvm-project (PR #89140)

2024-04-17 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

`std::string::starts_with` is only available from C++20, and LLVM is limited to 
C++17 as far as I know. However, the two objects here are `StringRef` so this 
is safe.

https://github.com/llvm/llvm-project/pull/89140
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [lldb] [llvm] Apply modernize-use-starts-ends-with on llvm-project (PR #89140)

2024-04-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89140

>From 2c82316a0f6641b93c666143211a87f06de8feab Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Wed, 17 Apr 2024 14:27:42 -0400
Subject: [PATCH] Apply modernize-use-starts-ends-with on llvm-project

---
 clang-tools-extra/clang-doc/Representation.cpp   | 4 ++--
 lldb/unittests/Host/FileSystemTest.cpp   | 2 +-
 llvm/unittests/Support/VirtualFileSystemTest.cpp | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index 84233c36e15d98..2afff2929cf79c 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -380,8 +380,8 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext 
*ECtx,
   this->SourceRoot = std::string(SourceRootDir);
   if (!RepositoryUrl.empty()) {
 this->RepositoryUrl = std::string(RepositoryUrl);
-if (!RepositoryUrl.empty() && RepositoryUrl.find("http://";) != 0 &&
-RepositoryUrl.find("https://";) != 0)
+if (!RepositoryUrl.empty() && !RepositoryUrl.starts_with("http://";) &&
+!RepositoryUrl.starts_with("https://";))
   this->RepositoryUrl->insert(0, "https://";);
   }
 }
diff --git a/lldb/unittests/Host/FileSystemTest.cpp 
b/lldb/unittests/Host/FileSystemTest.cpp
index 3b5ee7c8bc2237..58887f6b2467e0 100644
--- a/lldb/unittests/Host/FileSystemTest.cpp
+++ b/lldb/unittests/Host/FileSystemTest.cpp
@@ -93,7 +93,7 @@ class DummyFileSystem : public vfs::FileSystem {
 std::map::iterator I;
 std::string Path;
 bool isInPath(StringRef S) {
-  if (Path.size() < S.size() && S.find(Path) == 0) {
+  if (Path.size() < S.size() && S.starts_with(Path)) {
 auto LastSep = S.find_last_of('/');
 if (LastSep == Path.size() || LastSep == Path.size() - 1)
   return true;
diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp 
b/llvm/unittests/Support/VirtualFileSystemTest.cpp
index e9b4ac3d92e1dd..e9fd9671ea6ab5 100644
--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -101,7 +101,7 @@ class DummyFileSystem : public vfs::FileSystem {
 std::map::iterator I;
 std::string Path;
 bool isInPath(StringRef S) {
-  if (Path.size() < S.size() && S.find(Path) == 0) {
+  if (Path.size() < S.size() && S.starts_with(Path)) {
 auto LastSep = S.find_last_of('/');
 if (LastSep == Path.size() || LastSep == Path.size() - 1)
   return true;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [lldb] [llvm] Apply modernize-use-starts-ends-with on llvm-project (PR #89140)

2024-04-19 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Added one missed instance due to CMake configuration options.

https://github.com/llvm/llvm-project/pull/89140
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [lldb] [llvm] Apply modernize-use-starts-ends-with on llvm-project (PR #89140)

2024-04-19 Thread Nicolas van Kempen via cfe-commits

nicovank wrote:

Maybe @kazutakahirata (or anyone else) can stamp the minor `clang-doc` change?

I don't have commit access, feel free to hit merge when everything is in order 
👍 .

https://github.com/llvm/llvm-project/pull/89140
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)

2024-04-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/89490

[There is 
work](https://discourse.llvm.org/t/rfc-upgrading-llvms-minimum-required-python-version/67571)
 to make Python 3.8 the minimum Python version for LLVM.

I edited this script because I wanted some indicator of progress while going 
through files.
It now outputs `[XX/YYY]` with the number of processed and total files after 
each completion.

The current version of this script is compatible downto Python 3.6 (this is 
PyYAML's minimum version).
It would probably work with older Python 3 versions with an older PyYAML or 
when YAML is disabled.

With the updates here, it is compatible downto Python 3.7. Python 3.7 was 
released June 2018.

https://github.com/llvm/llvm-project/pull/89302 is also touching this file, I 
don't mind rebasing on top of that work if needed.

### Summary

 -  Add type annotations.
 -  Replace `threading` + `queue` with `asyncio`.
 -  **Add indicator of processed files over total files**. This is what I set 
out to do initially.
 -  Only print the filename after completion, not the entire Clang-Tidy 
invocation command. I find this neater but the behavior can easily be restored.

### MyPy

```
% python3 -m mypy --strict clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
Success: no issues found in 1 source file
```

### Performance

Just to make sure the `asyncio` change didn't introduce a regression, I ran the 
previous version and this version 5 times with the following command.

```
time python3 ~/llvm-project/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py 
\
-clang-tidy-binary="~/llvm-project/build/bin/clang-tidy" \

-clang-apply-replacements-binary="~/llvm-project/build/bin/clang-apply-replacements"
 \
-checks="-*,modernize-use-starts-ends-with" \
-source-filter ".*clang-tools-extra/clang-tidy.*" \
-fix -format
```

Runtimes are identical, no performance regression detected on my setup.

| Version | Time (s)   |
|-||
| Old | 92.0 ± 1.4 |
| New | 92.2 ± 1.5 |

>From 8decb15cb6a1734b01e31277d4698677564b227e Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sat, 20 Apr 2024 02:58:25 +
Subject: [PATCH] [run-clang-tidy.py] Refactor, add progress indicator, add
 type hints

---
 .../clang-tidy/tool/run-clang-tidy.py | 248 +-
 1 file changed, 126 insertions(+), 122 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py 
b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 1bd4a5b283091c..530f2425322495 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -34,29 +34,30 @@
 http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
 """
 
-from __future__ import print_function
-
 import argparse
+import asyncio
 import glob
 import json
 import multiprocessing
 import os
-import queue
 import re
 import shutil
 import subprocess
 import sys
 import tempfile
-import threading
 import traceback
+from types import ModuleType
+from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar
+
 
+yaml: Optional[ModuleType] = None
 try:
 import yaml
 except ImportError:
-yaml = None
+pass
 
 
-def strtobool(val):
+def strtobool(val: str) -> bool:
 """Convert a string representation of truth to a bool following LLVM's CLI 
argument parsing."""
 
 val = val.lower()
@@ -67,11 +68,11 @@ def strtobool(val):
 
 # Return ArgumentTypeError so that argparse does not substitute its own 
error message
 raise argparse.ArgumentTypeError(
-"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
+f"'{val}' is invalid value for boolean argument! Try 0 or 1."
 )
 
 
-def find_compilation_database(path):
+def find_compilation_database(path: str) -> str:
 """Adjusts the directory until a compilation database is found."""
 result = os.path.realpath("./")
 while not os.path.isfile(os.path.join(result, path)):
@@ -83,30 +84,24 @@ def find_compilation_database(path):
 return result
 
 
-def make_absolute(f, directory):
-if os.path.isabs(f):
-return f
-return os.path.normpath(os.path.join(directory, f))
-
-
 def get_tidy_invocation(
-f,
-clang_tidy_binary,
-checks,
-tmpdir,
-build_path,
-header_filter,
-allow_enabling_alpha_checkers,
-extra_arg,
-extra_arg_before,
-quiet,
-config_file_path,
-config,
-line_filter,
-use_color,
-plugins,
-warnings_as_errors,
-):
+f: str,
+clang_tidy_binary: str,
+checks: str,
+tmpdir: Optional[str],
+build_path: str,
+header_filter: Optional[str],
+allow_enabling_alpha_checkers: bool,
+extra_arg: List[str],
+extra_arg_before: List[str],
+quiet: bool,
+config_file_path: str,
+config: str,
+line_filter: Optional[str],
+use_color: bool,
+plugins: List[str],
+warnings_as_errors: Opt

[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)

2024-04-19 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89490

>From 8b52200a0ccfa801471e7326859276ef9b46 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sat, 20 Apr 2024 02:58:25 +
Subject: [PATCH] [run-clang-tidy.py] Refactor, add progress indicator, add
 type hints

---
 .../clang-tidy/tool/run-clang-tidy.py | 248 +-
 1 file changed, 126 insertions(+), 122 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py 
b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 1bd4a5b283091c..faab4876daa898 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -34,29 +34,30 @@
 http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
 """
 
-from __future__ import print_function
-
 import argparse
+import asyncio
 import glob
 import json
 import multiprocessing
 import os
-import queue
 import re
 import shutil
 import subprocess
 import sys
 import tempfile
-import threading
 import traceback
+from types import ModuleType
+from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar
+
 
+yaml: Optional[ModuleType] = None
 try:
 import yaml
 except ImportError:
-yaml = None
+pass
 
 
-def strtobool(val):
+def strtobool(val: str) -> bool:
 """Convert a string representation of truth to a bool following LLVM's CLI 
argument parsing."""
 
 val = val.lower()
@@ -67,11 +68,11 @@ def strtobool(val):
 
 # Return ArgumentTypeError so that argparse does not substitute its own 
error message
 raise argparse.ArgumentTypeError(
-"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
+f"'{val}' is invalid value for boolean argument! Try 0 or 1."
 )
 
 
-def find_compilation_database(path):
+def find_compilation_database(path: str) -> str:
 """Adjusts the directory until a compilation database is found."""
 result = os.path.realpath("./")
 while not os.path.isfile(os.path.join(result, path)):
@@ -83,30 +84,24 @@ def find_compilation_database(path):
 return result
 
 
-def make_absolute(f, directory):
-if os.path.isabs(f):
-return f
-return os.path.normpath(os.path.join(directory, f))
-
-
 def get_tidy_invocation(
-f,
-clang_tidy_binary,
-checks,
-tmpdir,
-build_path,
-header_filter,
-allow_enabling_alpha_checkers,
-extra_arg,
-extra_arg_before,
-quiet,
-config_file_path,
-config,
-line_filter,
-use_color,
-plugins,
-warnings_as_errors,
-):
+f: str,
+clang_tidy_binary: str,
+checks: str,
+tmpdir: Optional[str],
+build_path: str,
+header_filter: Optional[str],
+allow_enabling_alpha_checkers: bool,
+extra_arg: List[str],
+extra_arg_before: List[str],
+quiet: bool,
+config_file_path: str,
+config: str,
+line_filter: Optional[str],
+use_color: bool,
+plugins: List[str],
+warnings_as_errors: Optional[str],
+) -> List[str]:
 """Gets a command line for clang-tidy."""
 start = [clang_tidy_binary]
 if allow_enabling_alpha_checkers:
@@ -130,9 +125,9 @@ def get_tidy_invocation(
 os.close(handle)
 start.append(name)
 for arg in extra_arg:
-start.append("-extra-arg=%s" % arg)
+start.append(f"-extra-arg={arg}")
 for arg in extra_arg_before:
-start.append("-extra-arg-before=%s" % arg)
+start.append(f"-extra-arg-before={arg}")
 start.append("-p=" + build_path)
 if quiet:
 start.append("-quiet")
@@ -148,8 +143,9 @@ def get_tidy_invocation(
 return start
 
 
-def merge_replacement_files(tmpdir, mergefile):
+def merge_replacement_files(tmpdir: str, mergefile: str) -> None:
 """Merge all replacement files in a directory into a single file"""
+assert yaml
 # The fixes suggested by clang-tidy >= 4.0.0 are given under
 # the top level key 'Diagnostics' in the output yaml files
 mergekey = "Diagnostics"
@@ -173,16 +169,14 @@ def merge_replacement_files(tmpdir, mergefile):
 open(mergefile, "w").close()
 
 
-def find_binary(arg, name, build_path):
+def find_binary(arg: str, name: str, build_path: str) -> str:
 """Get the path for a binary or exit"""
 if arg:
 if shutil.which(arg):
 return arg
 else:
 raise SystemExit(
-"error: passed binary '{}' was not found or is not 
executable".format(
-arg
-)
+f"error: passed binary '{arg}' was not found or is not 
executable"
 )
 
 built_path = os.path.join(build_path, "bin", name)
@@ -190,12 +184,12 @@ def find_binary(arg, name, build_path):
 if binary:
 return binary
 else:
-raise SystemExit(
-"error: failed to find {} in $PATH or at {}".format(name, 
built_path)
-)
+raise SystemExit(f"error: failed to find {name} in $PATH

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for compare() (PR #89530)

2024-04-20 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank created 
https://github.com/llvm/llvm-project/pull/89530

Using `compare` is the next most common roundabout way to express `starts_with` 
before it was added to the standard. In this case, using `starts_with` is a 
readability improvement. Extend existing `modernize-use-starts-ends-with` to 
cover this case.

```
// The following will now be replaced by starts_with().
string.compare(0, strlen("prefix"), "prefix") == 0;
string.compare(0, 6, "prefix") == 0;
string.compare(0, prefix.length(), prefix) == 0;
string.compare(0, prefix.size(), prefix) == 0;
```

There are no such instances in llvm-project, maybe more will surface when the 
C++ default is changed to 20 for `std::string`. Other build issues come up when 
trying to override it.

Running this on llvm-project and dolphin:
 -  https://github.com/llvm/llvm-project/pull/89140 (no additional instances)
 -  https://github.com/dolphin-emu/dolphin/pull/12718

>From decc4b58c4d899e619ea63c50fa873c7bc605baf Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 21 Apr 2024 05:17:19 +
Subject: [PATCH] [clang-tidy][modernize-use-starts-ends-with] Add support for
 compare()

---
 .../modernize/UseStartsEndsWithCheck.cpp  | 92 ---
 .../modernize/UseStartsEndsWithCheck.h|  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checks/modernize/use-starts-ends-with.rst |  6 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  4 +
 .../checkers/Inputs/Headers/string.h  |  1 +
 .../modernize/use-starts-ends-with.cpp| 45 +
 7 files changed, 137 insertions(+), 19 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 062f6e9911dbed..38fe1984ac494e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -16,6 +16,49 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+namespace {
+// Given two argument indices X and Y, matches when a call expression has a
+// string at index X with an expression representing that string's length at
+// index Y. The string can be a string literal or a variable. The length can be
+// matched via an integer literal or a call to strlen() in the case of a string
+// literal, and by a call to size() or length() in the string variable case.
+AST_POLYMORPHIC_MATCHER_P2(HasStringAndLengthArguments,
+   AST_POLYMORPHIC_SUPPORTED_TYPES(
+   CallExpr, CXXConstructExpr,
+   CXXUnresolvedConstructExpr, ObjCMessageExpr),
+   unsigned, StringArgIndex, unsigned, LengthArgIndex) 
{
+  if (StringArgIndex >= Node.getNumArgs() ||
+  LengthArgIndex >= Node.getNumArgs()) {
+return false;
+  }
+
+  const Expr *StringArgExpr =
+  Node.getArg(StringArgIndex)->IgnoreParenImpCasts();
+  const Expr *LengthArgExpr =
+  Node.getArg(LengthArgIndex)->IgnoreParenImpCasts();
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match an integer literal equal to the string length or a call to strlen.
+const auto Matcher = expr(anyOf(
+integerLiteral(equals(StringArg->getLength())),
+callExpr(
+callee(functionDecl(hasName("strlen"))), argumentCountIs(1),
+hasArgument(0, stringLiteral(hasSize(StringArg->getLength()));
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match a call to size() or length() on the same variable.
+const auto Matcher = cxxMemberCallExpr(
+on(declRefExpr(to(varDecl(equalsNode(StringArg->getDecl()),
+callee(cxxMethodDecl(hasAnyName("size", "length"), isConst(),
+ parameterCountIs(0;
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  return false;
+}
+} // namespace
 
 UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
ClangTidyContext *Context)
@@ -43,7 +86,9 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("find")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
 
   const auto RFindExpr = cxxMemberCallExpr(
   // A method call with a second argument of zero...
@@ -52,15 +97,30 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasTy

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for compare() (PR #89530)

2024-04-20 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89530

>From 5f20627f74103d3b2b5adf484c902b85228006dd Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 21 Apr 2024 05:17:19 +
Subject: [PATCH] [clang-tidy][modernize-use-starts-ends-with] Add support for
 compare()

---
 .../modernize/UseStartsEndsWithCheck.cpp  | 92 ---
 .../modernize/UseStartsEndsWithCheck.h|  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checks/modernize/use-starts-ends-with.rst |  6 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  4 +
 .../checkers/Inputs/Headers/string.h  |  1 +
 .../modernize/use-starts-ends-with.cpp| 45 +
 7 files changed, 137 insertions(+), 19 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 062f6e9911dbed..38fe1984ac494e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -16,6 +16,49 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+namespace {
+// Given two argument indices X and Y, matches when a call expression has a
+// string at index X with an expression representing that string's length at
+// index Y. The string can be a string literal or a variable. The length can be
+// matched via an integer literal or a call to strlen() in the case of a string
+// literal, and by a call to size() or length() in the string variable case.
+AST_POLYMORPHIC_MATCHER_P2(HasStringAndLengthArguments,
+   AST_POLYMORPHIC_SUPPORTED_TYPES(
+   CallExpr, CXXConstructExpr,
+   CXXUnresolvedConstructExpr, ObjCMessageExpr),
+   unsigned, StringArgIndex, unsigned, LengthArgIndex) 
{
+  if (StringArgIndex >= Node.getNumArgs() ||
+  LengthArgIndex >= Node.getNumArgs()) {
+return false;
+  }
+
+  const Expr *StringArgExpr =
+  Node.getArg(StringArgIndex)->IgnoreParenImpCasts();
+  const Expr *LengthArgExpr =
+  Node.getArg(LengthArgIndex)->IgnoreParenImpCasts();
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match an integer literal equal to the string length or a call to strlen.
+const auto Matcher = expr(anyOf(
+integerLiteral(equals(StringArg->getLength())),
+callExpr(
+callee(functionDecl(hasName("strlen"))), argumentCountIs(1),
+hasArgument(0, stringLiteral(hasSize(StringArg->getLength()));
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match a call to size() or length() on the same variable.
+const auto Matcher = cxxMemberCallExpr(
+on(declRefExpr(to(varDecl(equalsNode(StringArg->getDecl()),
+callee(cxxMethodDecl(hasAnyName("size", "length"), isConst(),
+ parameterCountIs(0;
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  return false;
+}
+} // namespace
 
 UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
ClangTidyContext *Context)
@@ -43,7 +86,9 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("find")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
 
   const auto RFindExpr = cxxMemberCallExpr(
   // A method call with a second argument of zero...
@@ -52,15 +97,30 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
-
-  const auto FindOrRFindExpr =
-  cxxMemberCallExpr(anyOf(FindExpr, RFindExpr)).bind("find_expr");
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
+
+  const auto CompareExpr = cxxMemberCallExpr(
+  // A method call with a first argument of zero...
+  hasArgument(0, ZeroLiteral),
+  // ... named compare...
+  callee(cxxMethodDecl(hasName("compare")).bind("find_fun")),
+  // ... on a class with a starts_with function...
+  on(hasType(
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // ... where the third argument is some string and the second its length.
+  HasStringAndLengthArguments(2, 1),

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for compare() (PR #89530)

2024-04-20 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89530

>From 7a2ff84f113959bc89f50b6eef7ee9762e6f5d2f Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 21 Apr 2024 05:17:19 +
Subject: [PATCH] [clang-tidy][modernize-use-starts-ends-with] Add support for
 compare()

---
 .../modernize/UseStartsEndsWithCheck.cpp  | 92 ---
 .../modernize/UseStartsEndsWithCheck.h|  4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checks/modernize/use-starts-ends-with.rst |  6 +-
 .../clang-tidy/checkers/Inputs/Headers/string |  4 +
 .../checkers/Inputs/Headers/string.h  |  1 +
 .../abseil/redundant-strcat-calls.cpp |  2 -
 .../modernize/use-starts-ends-with.cpp| 45 +
 8 files changed, 137 insertions(+), 21 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 062f6e9911dbed..38fe1984ac494e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -16,6 +16,49 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+namespace {
+// Given two argument indices X and Y, matches when a call expression has a
+// string at index X with an expression representing that string's length at
+// index Y. The string can be a string literal or a variable. The length can be
+// matched via an integer literal or a call to strlen() in the case of a string
+// literal, and by a call to size() or length() in the string variable case.
+AST_POLYMORPHIC_MATCHER_P2(HasStringAndLengthArguments,
+   AST_POLYMORPHIC_SUPPORTED_TYPES(
+   CallExpr, CXXConstructExpr,
+   CXXUnresolvedConstructExpr, ObjCMessageExpr),
+   unsigned, StringArgIndex, unsigned, LengthArgIndex) 
{
+  if (StringArgIndex >= Node.getNumArgs() ||
+  LengthArgIndex >= Node.getNumArgs()) {
+return false;
+  }
+
+  const Expr *StringArgExpr =
+  Node.getArg(StringArgIndex)->IgnoreParenImpCasts();
+  const Expr *LengthArgExpr =
+  Node.getArg(LengthArgIndex)->IgnoreParenImpCasts();
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match an integer literal equal to the string length or a call to strlen.
+const auto Matcher = expr(anyOf(
+integerLiteral(equals(StringArg->getLength())),
+callExpr(
+callee(functionDecl(hasName("strlen"))), argumentCountIs(1),
+hasArgument(0, stringLiteral(hasSize(StringArg->getLength()));
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match a call to size() or length() on the same variable.
+const auto Matcher = cxxMemberCallExpr(
+on(declRefExpr(to(varDecl(equalsNode(StringArg->getDecl()),
+callee(cxxMethodDecl(hasAnyName("size", "length"), isConst(),
+ parameterCountIs(0;
+return Matcher.matches(*LengthArgExpr, Finder, Builder);
+  }
+
+  return false;
+}
+} // namespace
 
 UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
ClangTidyContext *Context)
@@ -43,7 +86,9 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("find")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
 
   const auto RFindExpr = cxxMemberCallExpr(
   // A method call with a second argument of zero...
@@ -52,15 +97,30 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
-
-  const auto FindOrRFindExpr =
-  cxxMemberCallExpr(anyOf(FindExpr, RFindExpr)).bind("find_expr");
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
+
+  const auto CompareExpr = cxxMemberCallExpr(
+  // A method call with a first argument of zero...
+  hasArgument(0, ZeroLiteral),
+  // ... named compare...
+  callee(cxxMethodDecl(hasName("compare")).bind("find_fun")),
+  // ... on a class with a starts_with function...
+  on(hasType(
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // ... where the third argument is some string and the second 

[clang-tools-extra] [clang-tidy][modernize-use-starts-ends-with] Add support for compare() (PR #89530)

2024-04-21 Thread Nicolas van Kempen via cfe-commits

https://github.com/nicovank updated 
https://github.com/llvm/llvm-project/pull/89530

>From ff7ebb3086d5467685e54435f3eabe86c76c24b0 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 21 Apr 2024 05:17:19 +
Subject: [PATCH] [clang-tidy][modernize-use-starts-ends-with] Add support for
 compare()

---
 .../modernize/UseStartsEndsWithCheck.cpp  | 118 +++---
 .../modernize/UseStartsEndsWithCheck.h|   4 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   4 +
 .../checks/modernize/use-starts-ends-with.rst |   6 +-
 .../clang-tidy/checkers/Inputs/Headers/string |   4 +
 .../checkers/Inputs/Headers/string.h  |   1 +
 .../abseil/redundant-strcat-calls.cpp |   2 -
 .../modernize/use-starts-ends-with.cpp|  45 +++
 8 files changed, 163 insertions(+), 21 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
index 062f6e9911dbed..2374213911beb4 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp
@@ -16,6 +16,75 @@
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
+namespace {
+// Given two argument indices X and Y, matches when a call expression has a
+// string at index X with an expression representing that string's length at
+// index Y. The string can be a string literal or a variable. The length can be
+// matched via an integer literal or a call to strlen() in the case of a string
+// literal, and by a call to size() or length() in the string variable case.
+AST_POLYMORPHIC_MATCHER_P2(hasStringAndLengthArguments,
+   AST_POLYMORPHIC_SUPPORTED_TYPES(
+   CallExpr, CXXConstructExpr,
+   CXXUnresolvedConstructExpr, ObjCMessageExpr),
+   unsigned, StringArgIndex, unsigned, LengthArgIndex) 
{
+  if (StringArgIndex >= Node.getNumArgs() ||
+  LengthArgIndex >= Node.getNumArgs()) {
+return false;
+  }
+
+  const Expr *StringArgExpr =
+  Node.getArg(StringArgIndex)->IgnoreParenImpCasts();
+  const Expr *LengthArgExpr =
+  Node.getArg(LengthArgIndex)->IgnoreParenImpCasts();
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match an integer literal equal to the string length or a call to strlen.
+
+static const auto Matcher = expr(anyOf(
+integerLiteral().bind("integer_literal_size"),
+callExpr(callee(functionDecl(hasName("strlen"))), argumentCountIs(1),
+ hasArgument(0, stringLiteral().bind("strlen_arg");
+
+if (!Matcher.matches(*LengthArgExpr, Finder, Builder)) {
+  return false;
+}
+
+return Builder->removeBindings(
+[&](const ast_matchers::internal::BoundNodesMap &Nodes) {
+  const auto *IntegerLiteralSize =
+  Nodes.getNodeAs("integer_literal_size");
+  const auto *StrlenArg = Nodes.getNodeAs("strlen_arg");
+  if (IntegerLiteralSize) {
+return IntegerLiteralSize->getValue().getZExtValue() !=
+   StringArg->getLength();
+  }
+  return StrlenArg->getLength() != StringArg->getLength();
+});
+  }
+
+  if (const auto *StringArg = dyn_cast(StringArgExpr)) {
+// Match a call to size() or length() on the same variable.
+
+static const auto Matcher = cxxMemberCallExpr(
+on(declRefExpr(to(varDecl().bind("string_var_decl",
+callee(cxxMethodDecl(hasAnyName("size", "length"), isConst(),
+ parameterCountIs(0;
+
+if (!Matcher.matches(*LengthArgExpr, Finder, Builder)) {
+  return false;
+}
+
+return Builder->removeBindings(
+[&](const ast_matchers::internal::BoundNodesMap &Nodes) {
+  const auto *StringVarDecl =
+  Nodes.getNodeAs("string_var_decl");
+  return StringVarDecl != StringArg->getDecl();
+});
+  }
+
+  return false;
+}
+} // namespace
 
 UseStartsEndsWithCheck::UseStartsEndsWithCheck(StringRef Name,
ClangTidyContext *Context)
@@ -43,7 +112,9 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("find")).bind("find_fun")),
   // ... on a class with a starts_with function.
   on(hasType(
-  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction);
+  hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction,
+  // Bind search expression.
+  hasArgument(0, expr().bind("search_expr")));
 
   const auto RFindExpr = cxxMemberCallExpr(
   // A method call with a second argument of zero...
@@ -52,15 +123,30 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder 
*Finder) {
   callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")),
   // ... on a class with a starts_wi

  1   2   3   >