[PATCH] D141892: Implement modernize-use-constraints

2023-07-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 545332.
ccotter added a comment.

- Fix ReleaseNotes again


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,726 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if 

[PATCH] D141892: Implement modernize-use-constraints

2023-07-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 545331.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,726 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// 

[PATCH] D141892: Implement modernize-use-constraints

2023-05-21 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

bump - @njames93 let me know if you have any further feedback. thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-05-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Addressed all comments except for the `handleReturnType` one which I responded 
to - let me know your thoughts, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-05-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 520125.
ccotter added a comment.

- Better handling for ctor inits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,726 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if 

[PATCH] D141892: Implement modernize-use-constraints

2023-05-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:247-248
+ParamsRange.getEnd(), SM, LangOpts, tok::r_paren, tok::r_paren);
+return utils::lexer::findNextAnyTokenKind(EndParens, SM, LangOpts,
+  tok::equal, tok::equal);
+  }

njames93 wrote:
> Super contrived, but looking for the `= delete` like this could be problematic
> ```lang=c++
> template
> std::enable_if_t> Foo() noexcept(requires (T a) { a = 4; 
> }) = delete;
> ```
> Here I'd imagine it would return the `=` in the noexcept requires clause.
> I'd imagine the safest bet would be to work from the function end loc looking 
> for the delete, then the equals.
Good catch. Added a test case for this. Looks like getSourceRange() returns the 
location after the parameter list and noexcept (if any), but before the `= 
delete`, so I went with that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-05-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 520104.
ccotter marked 3 inline comments as done.
ccotter added a comment.

Fix bug, other cleanups, rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,699 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires 

[PATCH] D141892: Implement modernize-use-constraints

2023-04-15 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:63-65
+std::string Name = TheType.getType().getAsString();
+if (Name.find("enable_if<") == std::string::npos)
+  return std::nullopt;

This string manipulation is unfortunate, check 
https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp#L208
 for a way to do it without that.
Could extract it out to its own function to use it below as well



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:222
+
+return std::move(Text);
+  }

No need for move here.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:235-237
+  const CXXCtorInitializer *FirstInit = *Constructor->init_begin();
+  return 
utils::lexer::findPreviousTokenKind(FirstInit->getSourceLocation(),
+ SM, LangOpts, tok::colon);

This seems dangerous, `CXXCtorInitializer` also contains in class initializers
```lang=cpp
struct Foo : Base { // < The first implicit constructor initializer - 
SourceOrder: -1
  Foo() : 
Bat(0),  // <- The fourth constructor initializer - SourceOrder: -0
Baz(0){} // <- The third constructor initializer - SourceOrder: 1
  int Bar = 5; // <- The second (implicit) constructor initializer - 
SourceOrder: -1
  int Baz = 6;
  int Bat;
};
```
Off the top of my head I can remember if the implicit initializers have a valid 
source location.
I think tbh the safest way to approach this would actually be to loop through 
the initializers and check their `GetSourceOrder` for the first item that 
returns `0`. In the example I have tried to demonstrate the possibilities.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:247-248
+ParamsRange.getEnd(), SM, LangOpts, tok::r_paren, tok::r_paren);
+return utils::lexer::findNextAnyTokenKind(EndParens, SM, LangOpts,
+  tok::equal, tok::equal);
+  }

Super contrived, but looking for the `= delete` like this could be problematic
```lang=c++
template
std::enable_if_t> Foo() noexcept(requires (T a) { a = 4; }) 
= delete;
```
Here I'd imagine it would return the `=` in the noexcept requires clause.
I'd imagine the safest bet would be to work from the function end loc looking 
for the delete, then the equals.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 512315.
ccotter added a comment.

arc diff properly


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if 

[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 512314.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h

Index: clang-tools-extra/clang-tidy/utils/LexerUtils.h
===
--- clang-tools-extra/clang-tidy/utils/LexerUtils.h
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.h
@@ -13,6 +13,7 @@
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Lexer.h"
 #include 
+#include 
 
 namespace clang {
 
@@ -23,6 +24,9 @@
 /// Returns previous token or ``tok::unknown`` if not found.
 Token getPreviousToken(SourceLocation Location, const SourceManager ,
const LangOptions , bool SkipComments = true);
+std::pair
+getPreviousTokenAndStart(SourceLocation Location, const SourceManager ,
+ const LangOptions , bool SkipComments = true);
 
 SourceLocation findPreviousTokenStart(SourceLocation Start,
   const SourceManager ,
Index: clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
===
--- clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
@@ -10,17 +10,19 @@
 #include "clang/AST/AST.h"
 #include "clang/Basic/SourceManager.h"
 #include 
+#include 
 
 namespace clang::tidy::utils::lexer {
 
-Token getPreviousToken(SourceLocation Location, const SourceManager ,
-   const LangOptions , bool SkipComments) {
+std::pair
+getPreviousTokenAndStart(SourceLocation Location, const SourceManager ,
+ const LangOptions , bool SkipComments) {
   Token Token;
   Token.setKind(tok::unknown);
 
   Location = Location.getLocWithOffset(-1);
   if (Location.isInvalid())
-  return Token;
+return {Token, Location};
 
   auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location));
   while (Location != StartOfFile) {
@@ -31,6 +33,13 @@
 }
 Location = Location.getLocWithOffset(-1);
   }
+  return {Token, Location};
+}
+
+Token getPreviousToken(SourceLocation Location, const SourceManager ,
+   const LangOptions , bool SkipComments) {
+  auto [Token, Start] =
+  getPreviousTokenAndStart(Location, SM, LangOpts, SkipComments);
   return Token;
 }
 
Index: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -254,28 +254,6 @@
   return Body->getBeginLoc();
 }
 
-static Token getPreviousToken(SourceLocation , const SourceManager ,
-  const LangOptions ,
-  bool SkipComments = false) {
-  Token Token;
-  Token.setKind(tok::unknown);
-
-  Location = Location.getLocWithOffset(-1);
-  if (Location.isInvalid())
-return Token;
-
-  auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location));
-  while (Location != StartOfFile) {
-Location = Lexer::GetBeginningOfToken(Location, SM, LangOpts);
-if (!Lexer::getRawToken(Location, Token, SM, LangOpts) &&
-(!SkipComments || !Token.is(tok::comment))) {
-  break;
-}
-Location = Location.getLocWithOffset(-1);
-  }
-  return Token;
-}
-
 bool isPrimaryExpression(const Expr *Expression) {
   // This function is an incomplete approximation of checking whether
   // an Expr is a primary expression. In particular, if this function
@@ -300,7 +278,10 @@
   if (PrevTokenLoc.isInvalid())
 return std::nullopt;
 
-  Token PrevToken = getPreviousToken(PrevTokenLoc, SM, LangOpts);
+  const bool SkipComments = false;
+  Token PrevToken;
+  std::tie(PrevToken, PrevTokenLoc) = utils::lexer::getPreviousTokenAndStart(
+  PrevTokenLoc, SM, LangOpts, SkipComments);
   bool EndsWithDoubleSlash =
   PrevToken.is(tok::comment) &&
   Lexer::getSourceText(CharSourceRange::getCharRange(
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 512313.
ccotter added a comment.

refactor


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h

Index: clang-tools-extra/clang-tidy/utils/LexerUtils.h
===
--- clang-tools-extra/clang-tidy/utils/LexerUtils.h
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.h
@@ -13,6 +13,7 @@
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Lexer.h"
 #include 
+#include 
 
 namespace clang {
 
@@ -23,6 +24,9 @@
 /// Returns previous token or ``tok::unknown`` if not found.
 Token getPreviousToken(SourceLocation Location, const SourceManager ,
const LangOptions , bool SkipComments = true);
+std::pair
+getPreviousTokenAndStart(SourceLocation Location, const SourceManager ,
+ const LangOptions , bool SkipComments = true);
 
 SourceLocation findPreviousTokenStart(SourceLocation Start,
   const SourceManager ,
Index: clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
===
--- clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
@@ -10,17 +10,19 @@
 #include "clang/AST/AST.h"
 #include "clang/Basic/SourceManager.h"
 #include 
+#include 
 
 namespace clang::tidy::utils::lexer {
 
-Token getPreviousToken(SourceLocation Location, const SourceManager ,
-   const LangOptions , bool SkipComments) {
+std::pair
+getPreviousTokenAndStart(SourceLocation Location, const SourceManager ,
+ const LangOptions , bool SkipComments) {
   Token Token;
   Token.setKind(tok::unknown);
 
   Location = Location.getLocWithOffset(-1);
   if (Location.isInvalid())
-  return Token;
+return {Token, Location};
 
   auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location));
   while (Location != StartOfFile) {
@@ -31,6 +33,13 @@
 }
 Location = Location.getLocWithOffset(-1);
   }
+  return {Token, Location};
+}
+
+Token getPreviousToken(SourceLocation Location, const SourceManager ,
+   const LangOptions , bool SkipComments) {
+  auto [Token, Start] =
+  getPreviousTokenAndStart(Location, SM, LangOpts, SkipComments);
   return Token;
 }
 
Index: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -254,28 +254,6 @@
   return Body->getBeginLoc();
 }
 
-static Token getPreviousToken(SourceLocation , const SourceManager ,
-  const LangOptions ,
-  bool SkipComments = false) {
-  Token Token;
-  Token.setKind(tok::unknown);
-
-  Location = Location.getLocWithOffset(-1);
-  if (Location.isInvalid())
-return Token;
-
-  auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location));
-  while (Location != StartOfFile) {
-Location = Lexer::GetBeginningOfToken(Location, SM, LangOpts);
-if (!Lexer::getRawToken(Location, Token, SM, LangOpts) &&
-(!SkipComments || !Token.is(tok::comment))) {
-  break;
-}
-Location = Location.getLocWithOffset(-1);
-  }
-  return Token;
-}
-
 bool isPrimaryExpression(const Expr *Expression) {
   // This function is an incomplete approximation of checking whether
   // an Expr is a primary expression. In particular, if this function
@@ -300,7 +278,10 @@
   if (PrevTokenLoc.isInvalid())
 return std::nullopt;
 
-  Token PrevToken = getPreviousToken(PrevTokenLoc, SM, LangOpts);
+  const bool SkipComments = false;
+  Token PrevToken;
+  std::tie(PrevToken, PrevTokenLoc) = utils::lexer::getPreviousTokenAndStart(
+  PrevTokenLoc, SM, LangOpts, SkipComments);
   bool EndsWithDoubleSlash =
   PrevToken.is(tok::comment) &&
   Lexer::getSourceText(CharSourceRange::getCharRange(
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

> Would you consider supporting enable_if via parameters

I was planning to support those too, but in a subsequent commit / review since 
this review is rather large. Is that OK?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:157-160
+return std::make_tuple(
+matchEnableIfSpecialization(
+LastTemplateParam->getTypeSourceInfo()->getTypeLoc()),
+LastTemplateParam);

njames93 wrote:
> Prefer braced initialization rather than the factory make_tuple(or 
> make_pair). Same goes below.
I've seen this feedback twice now - is this (or others, like preferring tuple 
over pair) written down somewhere? I didn't see anything on 
https://llvm.org/docs/CodingStandards.htm (or it wasn't obvious to me). Thanks!



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:266
+
+static Token getPreviousToken(SourceLocation , const SourceManager 
,
+  const LangOptions ,

njames93 wrote:
> Isn't there a copy of this function in `clang::tidy::utils`?
Ah, this version that I copied takes the `Location` by modifiable reference so 
it can be updated. I will update the original version



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:462-466
+std::vector FixIts =
+handleReturnType(Function, *ReturnType, *EnableIf, *Result.Context);
+diag(ReturnType->getBeginLoc(),
+ "use C++20 requires constraints instead of enable_if")
+<< FixIts;

njames93 wrote:
> Though a different approach of passing the `DiagnosticBuilder` to the 
> `handleReturnType` function and just appending the fixits in place would be a 
> nicer solution.
> Maybe change the function name to `addReturnTypeFixes(DiagnosticBuilder&, 
> const FunctionDecl *, const TypeLoc &, const EnableIfData &, ASTContext &);`
> 
> Same transformation can be made below.
Updated to apply your first suggestion.

For the `addReturnTypeFixes` suggestion, I find that `handleReturnType` 
returning the `vector` of `FixItHints` simpler since it has less responsibility 
or knowledge about how the `FixItHints` are to be applied - it's main purpose 
is to compute them, so why have the function also know how to apply them? 
Practically speaking, maybe this is not really useful since this function is 
not say, exposed as a library function to other code (it's just used as an 
implementation detail of this check).

Can you clarify what makes the application in place a nicer solution? 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 512308.
ccotter marked 12 inline comments as done.
ccotter added a comment.

feedback+rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp

Index: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -14,7 +14,7 @@
 #include "../utils/LexerUtils.h"
 
 #include 
-#include 
+#include 
 
 using namespace clang::ast_matchers;
 
@@ -68,7 +68,7 @@
 if (NumArgs != 1 && NumArgs != 2)
   return std::nullopt;
 
-return std::make_optional(Specialization);
+return Specialization;
   }
   return std::nullopt;
 }
@@ -86,7 +86,7 @@
 if (!Specialization.getTypePtr()->isTypeAlias())
   return std::nullopt;
 
-if (const auto *AliasedType = llvm::dyn_cast(
+if (const auto *AliasedType = dyn_cast(
 Specialization.getTypePtr()->getAliasedType())) {
   if (AliasedType->getIdentifier()->getName() != "type" ||
   AliasedType->getKeyword() != ETK_Typename) {
@@ -99,16 +99,14 @@
 if (NumArgs != 1 && NumArgs != 2)
   return std::nullopt;
 
-return std::make_optional(Specialization);
+return Specialization;
   }
   return std::nullopt;
 }
 
 static std::optional
 matchEnableIfSpecializationImpl(TypeLoc TheType) {
-  std::optional EnableIf;
-  EnableIf = matchEnableIfSpecializationImplTypename(TheType);
-  if (EnableIf)
+  if (auto EnableIf = matchEnableIfSpecializationImplTypename(TheType))
 return EnableIf;
   return matchEnableIfSpecializationImplTrait(TheType);
 }
@@ -122,15 +120,12 @@
   if (const auto Qualified = TheType.getAs())
 TheType = Qualified.getUnqualifiedLoc();
 
-  std::optional EnableIf =
-  matchEnableIfSpecializationImpl(TheType);
-  if (EnableIf)
-return std::make_optional(EnableIfData{std::move(*EnableIf), TheType});
-  else
-return std::nullopt;
+  if (auto EnableIf = matchEnableIfSpecializationImpl(TheType))
+return EnableIfData{std::move(*EnableIf), TheType};
+  return std::nullopt;
 }
 
-static std::tuple, const Decl *>
+static std::pair, const Decl *>
 matchTrailingTemplateParam(const FunctionTemplateDecl *FunctionTemplate) {
   // For non-type trailing param, match very specifically
   // 'template <..., enable_if_type = Default>' where
@@ -148,24 +143,22 @@
   const NamedDecl *LastParam =
   TemplateParams->getParam(TemplateParams->size() - 1);
   if (const auto *LastTemplateParam =
-  llvm::dyn_cast(LastParam)) {
+  dyn_cast(LastParam)) {
 
 if (!LastTemplateParam->hasDefaultArgument() ||
 !LastTemplateParam->getName().empty())
   return {};
 
-return std::make_tuple(
-matchEnableIfSpecialization(
-LastTemplateParam->getTypeSourceInfo()->getTypeLoc()),
-LastTemplateParam);
+return {matchEnableIfSpecialization(
+LastTemplateParam->getTypeSourceInfo()->getTypeLoc()),
+LastTemplateParam};
   } else if (const auto *LastTemplateParam =
- llvm::dyn_cast(LastParam)) {
+ dyn_cast(LastParam)) {
 if (LastTemplateParam->hasDefaultArgument() &&
 LastTemplateParam->getIdentifier() == nullptr) {
-  return std::make_tuple(
-  matchEnableIfSpecialization(
-  LastTemplateParam->getDefaultArgumentInfo()->getTypeLoc()),
-  LastTemplateParam);
+  return {matchEnableIfSpecialization(
+  LastTemplateParam->getDefaultArgumentInfo()->getTypeLoc()),
+  LastTemplateParam};
 }
   }
   return {};
@@ -212,26 +205,24 @@
   getRAngleFileLoc(SM, EnableIf));
 }
 
-static std::optional
+static std::optional
 getTypeText(ASTContext ,
 const TemplateSpecializationTypeLoc ) {
   if (EnableIf.getNumArgs() > 1) {
 const LangOptions  = Context.getLangOpts();
 const SourceManager  = Context.getSourceManager();
 bool Invalid = false;
-std::string Text =
-Lexer::getSourceText(
-CharSourceRange::getCharRange(getTypeRange(Context, EnableIf)), SM,
-LangOpts, )
-.trim()
-.str();
+StringRef Text = Lexer::getSourceText(CharSourceRange::getCharRange(
+  getTypeRange(Context, EnableIf)),
+  SM, LangOpts, )
+ .trim();
 if (Invalid)
   return std::nullopt;
 
-return std::make_optional(std::move(Text));
-  } else {
-return std::make_optional("void");
+return std::move(Text);
   }
+
+  return "void";
 }
 
 static std::optional
@@ -239,7 +230,7 @@
   SourceManager  = Context.getSourceManager();
   const LangOptions  = 

[PATCH] D141892: Implement modernize-use-constraints

2023-04-10 Thread Nathan James via Phabricator via cfe-commits
njames93 added a reviewer: carlosgalvezp.
njames93 added a comment.

Would you consider supporting enable_if via parameters

  template
  void doStuff(T&, std::enable_if_t = nullptr) {}




Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:71
+
+return std::make_optional(Specialization);
+  }

nit: Don't need to explicitly call make_optional here, the implicit conversion 
will handle that for you, same goes for everywhere else.



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:89
+
+if (const auto *AliasedType = llvm::dyn_cast(
+Specialization.getTypePtr()->getAliasedType())) {

`dyn_cast` is brought into clangs namespace so the `llvm::` qualifier is 
unnecessary here



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:109-112
+  std::optional EnableIf;
+  EnableIf = matchEnableIfSpecializationImplTypename(TheType);
+  if (EnableIf)
+return EnableIf;

Nit



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:125-128
+  std::optional EnableIf =
+  matchEnableIfSpecializationImpl(TheType);
+  if (EnableIf)
+return std::make_optional(EnableIfData{std::move(*EnableIf), TheType});

Ditto as above



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:129-130
+return std::make_optional(EnableIfData{std::move(*EnableIf), TheType});
+  else
+return std::nullopt;
+}

Don't use else after a return.
Same goes for anywhere else that this pattern occurs



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:133
+
+static std::tuple, const Decl *>
+matchTrailingTemplateParam(const FunctionTemplateDecl *FunctionTemplate) {

Prefer pair over tuple when only 2 elements



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:157-160
+return std::make_tuple(
+matchEnableIfSpecialization(
+LastTemplateParam->getTypeSourceInfo()->getTypeLoc()),
+LastTemplateParam);

Prefer braced initialization rather than the factory make_tuple(or make_pair). 
Same goes below.



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:215
+
+static std::optional
+getTypeText(ASTContext ,

This can return a std::optional if you remove the call the `.str()` 
and assignment to `std::string` below.



Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:266
+
+static Token getPreviousToken(SourceLocation , const SourceManager 
,
+  const LangOptions ,

Isn't there a copy of this function in `clang::tidy::utils`?



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:296-299
+  if (llvm::dyn_cast(Expression))
+return true;
+  if (llvm::dyn_cast(Expression))
+return true;





Comment at: clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:335
+  if (EndsWithDoubleSlash)
+return std::make_optional(AddParens(ConditionText.str()));
+  else

No need to call `.str()` here if the lambda expects a `StringRef`, also removed 
`std::make_optional`.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:459-461
+  std::optional EnableIf;
+  EnableIf = matchEnableIfSpecialization(*ReturnType);
+  if (EnableIf.has_value()) {





Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:462-466
+std::vector FixIts =
+handleReturnType(Function, *ReturnType, *EnableIf, *Result.Context);
+diag(ReturnType->getBeginLoc(),
+ "use C++20 requires constraints instead of enable_if")
+<< FixIts;

Though a different approach of passing the `DiagnosticBuilder` to the 
`handleReturnType` function and just appending the fixits in place would be a 
nicer solution.
Maybe change the function name to `addReturnTypeFixes(DiagnosticBuilder&, const 
FunctionDecl *, const TypeLoc &, const EnableIfData &, ASTContext &);`

Same transformation can be made below.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp:471-474
+  const Decl *LastTemplateParam = nullptr;
+  std::tie(EnableIf, LastTemplateParam) =
+  matchTrailingTemplateParam(FunctionTemplate);
+  if (EnableIf.has_value() && LastTemplateParam) {




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D141892: Implement modernize-use-constraints

2023-03-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 509544.
ccotter added a comment.

- format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& reference_of_enable_if_t() requires 

[PATCH] D141892: Implement modernize-use-constraints

2023-03-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 509543.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& reference_of_enable_if_t() requires 

[PATCH] D141892: Implement modernize-use-constraints

2023-03-26 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 508452.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& reference_of_enable_if_t() requires 

[PATCH] D141892: Implement modernize-use-constraints

2023-03-18 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 506339.
ccotter added a comment.
Herald added a subscriber: PiotrZSL.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& 

[PATCH] D141892: Implement modernize-use-constraints

2023-02-02 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

This is more or less ready for review (not planning on making any further 
changes; there are more features to be added, but I was thinking of handling 
those in follow up changesets). I know it's a relatively large review, but let 
me know if anyone can take a first pass. Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 493050.
ccotter added a comment.

Rebase + Simplify match logic


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& 

[PATCH] D141892: Implement modernize-use-constraints

2023-01-22 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 491201.
ccotter added a comment.

- Use nested namespaces


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& 

[PATCH] D141892: Implement modernize-use-constraints

2023-01-21 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 491127.
ccotter added a comment.

- Add fno-delayed-template-parsing


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& 

[PATCH] D141892: Implement modernize-use-constraints

2023-01-17 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

In D141892#4058273 , @njames93 wrote:

> In D141892#4057722 , @ccotter wrote:
>
>> 2. replace the non `_v` templates to the `_v` variants `is_same` -> 
>> `is_same_v` or the equivalent concept `same_as`
>
> See D137302 

Awesome!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-17 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D141892#4057722 , @ccotter wrote:

> 2. replace the non `_v` templates to the `_v` variants `is_same` -> 
> `is_same_v` or the equivalent concept `same_as`

See D137302 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-16 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Overall, we could eventually upgrade code in three stages, each a separate 
reusable check.

1. enable_if -> requires clauses
2. replace the non `_v` templates to the `_v` variants `is_same` -> `is_same_v` 
or the equivalent concept `same_as`
3. replace requires clause on declarations to be template type constraint 
(replace `template  void foo() requires std::same_as void 
foo() {}` to `template  T> void foo() {}`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-16 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

For the sake of demonstration, 
https://github.com/llvm/llvm-project/commit/9c556ce59edf5a4293d4497d5815544afc0eb878
 is the result of running this tool on all headers under clang/include/clang 
and llvm/include/llvm.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141892/new/

https://reviews.llvm.org/D141892

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-16 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: carlosgalvezp.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Add new check to replace enable_if with C++20 constraints


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if