[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-05-07 Thread Piotr Zegar via cfe-commits

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-05-07 Thread Edwin Vane via cfe-commits

revane wrote:

@PiotrZSL I finally got a windows environment set up and fixed the windows 
build error. Would you merge for me since I don't have permission?

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-05-07 Thread Edwin Vane via cfe-commits

https://github.com/revane updated 
https://github.com/llvm/llvm-project/pull/88735

>From 64c1b5b7d6c29c86e0e7f26f0eff3b7a52f95e7e Mon Sep 17 00:00:00 2001
From: Edwin Vane 
Date: Thu, 28 Mar 2024 09:30:32 -0400
Subject: [PATCH] [clang-tidy] Refactor how NamedDecl are renamed

The handling of renaming failures and multiple usages related to those
failures is currently spread over several functions. Identifying the
failure NamedDecl for a given usage is also duplicated, once when
creating failures and again when identify usages. There are currently
two ways to a failed NamedDecl from a usage: use the canonical decl or
use the overridden method. With new methods about to be added, a cleanup
was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines
  potential new names based on that failure. Usages are registered using
  addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility
  is maintaining the integrity of the failure/usage map.
---
 .../bugprone/ReservedIdentifierCheck.cpp  |   5 +-
 .../readability/IdentifierNamingCheck.cpp |   4 +
 .../utils/RenamerClangTidyCheck.cpp   | 196 ++
 .../clang-tidy/utils/RenamerClangTidyCheck.h  |  14 +-
 4 files changed, 121 insertions(+), 98 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
index f6714d056518d..53956661d57d1 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
@@ -178,8 +178,11 @@ std::optional
 ReservedIdentifierCheck::getDeclFailureInfo(const NamedDecl *Decl,
 const SourceManager &) const {
   assert(Decl && Decl->getIdentifier() && !Decl->getName().empty() &&
- !Decl->isImplicit() &&
  "Decl must be an explicit identifier with a name.");
+  // Implicit identifiers cannot fail.
+  if (Decl->isImplicit())
+return std::nullopt;
+
   return getFailureInfoImpl(
   Decl->getName(), isa(Decl->getDeclContext()),
   /*IsMacro = */ false, getLangOpts(), Invert, AllowedIdentifiers);
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index dc30531ebda0e..27a12bfc58068 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -1374,6 +1374,10 @@ IdentifierNamingCheck::getFailureInfo(
 std::optional
 IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl *Decl,
   const SourceManager &SM) const {
+  // Implicit identifiers cannot be renamed.
+  if (Decl->isImplicit())
+return std::nullopt;
+
   SourceLocation Loc = Decl->getLocation();
   const FileStyle &FileStyle = getStyleForFile(SM.getFilename(Loc));
   if (!FileStyle.isActive())
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 962a243ce94d4..f5ed617365403 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -61,6 +61,7 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+
 class NameLookup {
   llvm::PointerIntPair Data;
 
@@ -78,6 +79,7 @@ class NameLookup {
   operator bool() const { return !hasMultipleResolutions(); }
   const NamedDecl *operator*() const { return getDecl(); }
 };
+
 } // namespace
 
 static const NamedDecl *findDecl(const RecordDecl &RecDecl,
@@ -91,6 +93,44 @@ static const NamedDecl *findDecl(const RecordDecl &RecDecl,
   return nullptr;
 }
 
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
+  if (Method->size_overridden_methods() != 1)
+return nullptr;
+
+  while (true) {
+Method = *Method->begin_overridden_methods();
+assert(Method && "Overridden method shouldn't be null");
+unsigned NumOverrides = Method->size_overridden_methods();
+if (NumOverrides == 0)
+  return Method;
+if (NumOverrides > 1)
+  return nullptr;
+  }
+}
+
+static bool hasNoName(const NamedDecl *Decl) {
+  return !Decl->getIdentifier() || Decl->getName().empty();
+}
+
+static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) {
+  const auto *Canonical = cast(ND->getCanonicalDecl());
+  if (Canonical != ND)
+return Canonical;
+
+  if (const auto *Method = dyn_cast(ND)) {
+if (const CXXMethodD

[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-23 Thread Edwin Vane via cfe-commits

https://github.com/revane updated 
https://github.com/llvm/llvm-project/pull/88735

>From 5be7a57838b8fe7042e0719911670f6f369db2e8 Mon Sep 17 00:00:00 2001
From: Edwin Vane 
Date: Thu, 28 Mar 2024 09:30:32 -0400
Subject: [PATCH] [clang-tidy] Refactor how NamedDecl are renamed

The handling of renaming failures and multiple usages related to those
failures is currently spread over several functions. Identifying the
failure NamedDecl for a given usage is also duplicated, once when
creating failures and again when identify usages. There are currently
two ways to a failed NamedDecl from a usage: use the canonical decl or
use the overridden method. With new methods about to be added, a cleanup
was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines
  potential new names based on that failure. Usages are registered using
  addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility
  is maintaining the integrity of the failure/usage map.
---
 .../utils/RenamerClangTidyCheck.cpp   | 196 ++
 .../clang-tidy/utils/RenamerClangTidyCheck.h  |  14 +-
 2 files changed, 113 insertions(+), 97 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 962a243ce94d48..f5ed617365403a 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -61,6 +61,7 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+
 class NameLookup {
   llvm::PointerIntPair Data;
 
@@ -78,6 +79,7 @@ class NameLookup {
   operator bool() const { return !hasMultipleResolutions(); }
   const NamedDecl *operator*() const { return getDecl(); }
 };
+
 } // namespace
 
 static const NamedDecl *findDecl(const RecordDecl &RecDecl,
@@ -91,6 +93,44 @@ static const NamedDecl *findDecl(const RecordDecl &RecDecl,
   return nullptr;
 }
 
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
+  if (Method->size_overridden_methods() != 1)
+return nullptr;
+
+  while (true) {
+Method = *Method->begin_overridden_methods();
+assert(Method && "Overridden method shouldn't be null");
+unsigned NumOverrides = Method->size_overridden_methods();
+if (NumOverrides == 0)
+  return Method;
+if (NumOverrides > 1)
+  return nullptr;
+  }
+}
+
+static bool hasNoName(const NamedDecl *Decl) {
+  return !Decl->getIdentifier() || Decl->getName().empty();
+}
+
+static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) {
+  const auto *Canonical = cast(ND->getCanonicalDecl());
+  if (Canonical != ND)
+return Canonical;
+
+  if (const auto *Method = dyn_cast(ND)) {
+if (const CXXMethodDecl *Overridden = getOverrideMethod(Method))
+  Canonical = cast(Overridden->getCanonicalDecl());
+
+if (Canonical != ND)
+  return Canonical;
+  }
+
+  return ND;
+}
+
 /// Returns a decl matching the \p DeclName in \p Parent or one of its base
 /// classes. If \p AggressiveTemplateLookup is `true` then it will check
 /// template dependent base classes as well.
@@ -132,24 +172,6 @@ static NameLookup findDeclInBases(const CXXRecordDecl 
&Parent,
   return NameLookup(Found); // If nullptr, decl wasn't found.
 }
 
-/// Returns the function that \p Method is overridding. If There are none or
-/// multiple overrides it returns nullptr. If the overridden function itself is
-/// overridding then it will recurse up to find the first decl of the function.
-static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
-  if (Method->size_overridden_methods() != 1)
-return nullptr;
-
-  while (true) {
-Method = *Method->begin_overridden_methods();
-assert(Method && "Overridden method shouldn't be null");
-unsigned NumOverrides = Method->size_overridden_methods();
-if (NumOverrides == 0)
-  return Method;
-if (NumOverrides > 1)
-  return nullptr;
-  }
-}
-
 namespace {
 
 /// Callback supplies macros to RenamerClangTidyCheck::checkMacro
@@ -192,10 +214,6 @@ class RenamerClangTidyVisitor
   : Check(Check), SM(SM),
 AggressiveDependentMemberLookup(AggressiveDependentMemberLookup) {}
 
-  static bool hasNoName(const NamedDecl *Decl) {
-return !Decl->getIdentifier() || Decl->getName().empty();
-  }
-
   bool shouldVisitTemplateInstantiations() const { return true; }
 
   bool shouldVisitImplicitCode() const { return false; }
@@ -246,29 +264,10 @@ class RenamerClangTidyVisitor
   }
 
   bool VisitNamedDecl(NamedDecl *Decl) {
-if (hasNoName(Decl))
- 

[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Edwin Vane via cfe-commits


@@ -61,6 +61,44 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {

revane wrote:

Ah. Good to know.

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Edwin Vane via cfe-commits

https://github.com/revane updated 
https://github.com/llvm/llvm-project/pull/88735

>From 2249f8c4e28297d72d6f5d36e883b921116f33e4 Mon Sep 17 00:00:00 2001
From: Edwin Vane 
Date: Thu, 28 Mar 2024 09:30:32 -0400
Subject: [PATCH] [clang-tidy] Refactor how NamedDecl are renamed

The handling of renaming failures and multiple usages related to those
failures is currently spread over several functions. Identifying the
failure NamedDecl for a given usage is also duplicated, once when
creating failures and again when identify usages. There are currently
two ways to a failed NamedDecl from a usage: use the canonical decl or
use the overridden method. With new methods about to be added, a cleanup
was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines
  potential new names based on that failure. Usages are registered using
  addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility
  is maintaining the integrity of the failure/usage map.
---
 .../utils/RenamerClangTidyCheck.cpp   | 196 ++
 .../clang-tidy/utils/RenamerClangTidyCheck.h  |  14 +-
 2 files changed, 113 insertions(+), 97 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 962a243ce94d48..f5ed617365403a 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -61,6 +61,7 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+
 class NameLookup {
   llvm::PointerIntPair Data;
 
@@ -78,6 +79,7 @@ class NameLookup {
   operator bool() const { return !hasMultipleResolutions(); }
   const NamedDecl *operator*() const { return getDecl(); }
 };
+
 } // namespace
 
 static const NamedDecl *findDecl(const RecordDecl &RecDecl,
@@ -91,6 +93,44 @@ static const NamedDecl *findDecl(const RecordDecl &RecDecl,
   return nullptr;
 }
 
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
+  if (Method->size_overridden_methods() != 1)
+return nullptr;
+
+  while (true) {
+Method = *Method->begin_overridden_methods();
+assert(Method && "Overridden method shouldn't be null");
+unsigned NumOverrides = Method->size_overridden_methods();
+if (NumOverrides == 0)
+  return Method;
+if (NumOverrides > 1)
+  return nullptr;
+  }
+}
+
+static bool hasNoName(const NamedDecl *Decl) {
+  return !Decl->getIdentifier() || Decl->getName().empty();
+}
+
+static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) {
+  const auto *Canonical = cast(ND->getCanonicalDecl());
+  if (Canonical != ND)
+return Canonical;
+
+  if (const auto *Method = dyn_cast(ND)) {
+if (const CXXMethodDecl *Overridden = getOverrideMethod(Method))
+  Canonical = cast(Overridden->getCanonicalDecl());
+
+if (Canonical != ND)
+  return Canonical;
+  }
+
+  return ND;
+}
+
 /// Returns a decl matching the \p DeclName in \p Parent or one of its base
 /// classes. If \p AggressiveTemplateLookup is `true` then it will check
 /// template dependent base classes as well.
@@ -132,24 +172,6 @@ static NameLookup findDeclInBases(const CXXRecordDecl 
&Parent,
   return NameLookup(Found); // If nullptr, decl wasn't found.
 }
 
-/// Returns the function that \p Method is overridding. If There are none or
-/// multiple overrides it returns nullptr. If the overridden function itself is
-/// overridding then it will recurse up to find the first decl of the function.
-static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
-  if (Method->size_overridden_methods() != 1)
-return nullptr;
-
-  while (true) {
-Method = *Method->begin_overridden_methods();
-assert(Method && "Overridden method shouldn't be null");
-unsigned NumOverrides = Method->size_overridden_methods();
-if (NumOverrides == 0)
-  return Method;
-if (NumOverrides > 1)
-  return nullptr;
-  }
-}
-
 namespace {
 
 /// Callback supplies macros to RenamerClangTidyCheck::checkMacro
@@ -192,10 +214,6 @@ class RenamerClangTidyVisitor
   : Check(Check), SM(SM),
 AggressiveDependentMemberLookup(AggressiveDependentMemberLookup) {}
 
-  static bool hasNoName(const NamedDecl *Decl) {
-return !Decl->getIdentifier() || Decl->getName().empty();
-  }
-
   bool shouldVisitTemplateInstantiations() const { return true; }
 
   bool shouldVisitImplicitCode() const { return false; }
@@ -246,29 +264,10 @@ class RenamerClangTidyVisitor
   }
 
   bool VisitNamedDecl(NamedDecl *Decl) {
-if (hasNoName(Decl))
- 

[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Piotr Zegar via cfe-commits


@@ -61,6 +61,44 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {

PiotrZSL wrote:

anyonymous namespace -> static (per llvm codding guidelines)
leave only NameLookup in anonymous namespace

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Piotr Zegar via cfe-commits

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Piotr Zegar via cfe-commits

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

For me looks fine.
Give it few days before merging, so others would have opportunity to review.

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Edwin Vane via cfe-commits

revane wrote:

@PiotrZSL Second-last in the sequence of PRs which fix another renaming issue.

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


[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: Edwin Vane (revane)


Changes

The handling of renaming failures and multiple usages related to those failures 
is currently spread over several functions. Identifying the failure NamedDecl 
for a given usage is also duplicated, once when creating failures and again 
when identify usages. There are currently two ways to a failed NamedDecl from a 
usage: use the canonical decl or use the overridden method. With new methods 
about to be added, a cleanup was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines potential 
new names based on that failure. Usages are registered using 
addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility is 
maintaining the integrity of the failure/usage map.

---
Full diff: https://github.com/llvm/llvm-project/pull/88735.diff


2 Files Affected:

- (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
(+103-91) 
- (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h (+8-6) 


``diff
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 962a243ce94d48..453d5a754f12fc 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -61,6 +61,44 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
+  if (Method->size_overridden_methods() != 1)
+return nullptr;
+
+  while (true) {
+Method = *Method->begin_overridden_methods();
+assert(Method && "Overridden method shouldn't be null");
+unsigned NumOverrides = Method->size_overridden_methods();
+if (NumOverrides == 0)
+  return Method;
+if (NumOverrides > 1)
+  return nullptr;
+  }
+}
+
+bool hasNoName(const NamedDecl *Decl) {
+  return !Decl->getIdentifier() || Decl->getName().empty();
+}
+
+const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) {
+  const auto *Canonical = cast(ND->getCanonicalDecl());
+  if (Canonical != ND)
+return Canonical;
+
+  if (const auto *Method = dyn_cast(ND)) {
+if (const CXXMethodDecl *Overridden = getOverrideMethod(Method))
+  Canonical = cast(Overridden->getCanonicalDecl());
+
+if (Canonical != ND)
+  return Canonical;
+  }
+
+  return ND;
+}
+
 class NameLookup {
   llvm::PointerIntPair Data;
 
@@ -132,24 +170,6 @@ static NameLookup findDeclInBases(const CXXRecordDecl 
&Parent,
   return NameLookup(Found); // If nullptr, decl wasn't found.
 }
 
-/// Returns the function that \p Method is overridding. If There are none or
-/// multiple overrides it returns nullptr. If the overridden function itself is
-/// overridding then it will recurse up to find the first decl of the function.
-static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
-  if (Method->size_overridden_methods() != 1)
-return nullptr;
-
-  while (true) {
-Method = *Method->begin_overridden_methods();
-assert(Method && "Overridden method shouldn't be null");
-unsigned NumOverrides = Method->size_overridden_methods();
-if (NumOverrides == 0)
-  return Method;
-if (NumOverrides > 1)
-  return nullptr;
-  }
-}
-
 namespace {
 
 /// Callback supplies macros to RenamerClangTidyCheck::checkMacro
@@ -192,10 +212,6 @@ class RenamerClangTidyVisitor
   : Check(Check), SM(SM),
 AggressiveDependentMemberLookup(AggressiveDependentMemberLookup) {}
 
-  static bool hasNoName(const NamedDecl *Decl) {
-return !Decl->getIdentifier() || Decl->getName().empty();
-  }
-
   bool shouldVisitTemplateInstantiations() const { return true; }
 
   bool shouldVisitImplicitCode() const { return false; }
@@ -246,29 +262,10 @@ class RenamerClangTidyVisitor
   }
 
   bool VisitNamedDecl(NamedDecl *Decl) {
-if (hasNoName(Decl))
-  return true;
-
-const auto *Canonical = cast(Decl->getCanonicalDecl());
-if (Canonical != Decl) {
-  Check->addUsage(Canonical, Decl->getLocation(), SM);
-  return true;
-}
-
-// Fix overridden methods
-if (const auto *Method = dyn_cast(Decl)) {
-  if (const CXXMethodDecl *Overridden = getOverrideMethod(Method)) {
-Check->addUsage(Overridden, Method->getLocation(), SM);
-return true; // Don't try to add the actual decl as a Failure.
-  }
-}
-
-// Ignore ClassTemplateSpecializationDecl which are creating duplicate
-// replacements with CXXRecordDecl.
-

[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)

2024-04-15 Thread Edwin Vane via cfe-commits

https://github.com/revane created 
https://github.com/llvm/llvm-project/pull/88735

The handling of renaming failures and multiple usages related to those failures 
is currently spread over several functions. Identifying the failure NamedDecl 
for a given usage is also duplicated, once when creating failures and again 
when identify usages. There are currently two ways to a failed NamedDecl from a 
usage: use the canonical decl or use the overridden method. With new methods 
about to be added, a cleanup was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines potential 
new names based on that failure. Usages are registered using 
addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility is 
maintaining the integrity of the failure/usage map.

>From 16271c2988994257d33a3f6b2b98254be2587b58 Mon Sep 17 00:00:00 2001
From: Edwin Vane 
Date: Thu, 28 Mar 2024 09:30:32 -0400
Subject: [PATCH] [clang-tidy] Refactor how NamedDecl are renamed

The handling of renaming failures and multiple usages related to those
failures is currently spread over several functions. Identifying the
failure NamedDecl for a given usage is also duplicated, once when
creating failures and again when identify usages. There are currently
two ways to a failed NamedDecl from a usage: use the canonical decl or
use the overridden method. With new methods about to be added, a cleanup
was in order.

The data flow is simplified as follows:
* The visitor always forwards NamedDecls to addUsage(NamedDecl).
* addUsage(NamedDecl) determines the failed NamedDecl and determines
  potential new names based on that failure. Usages are registered using
  addUsage(NamingCheckId).
* addUsage(NamingCheckId) is now protected and its single responsibility
  is maintaining the integrity of the failure/usage map.
---
 .../utils/RenamerClangTidyCheck.cpp   | 194 ++
 .../clang-tidy/utils/RenamerClangTidyCheck.h  |  14 +-
 2 files changed, 111 insertions(+), 97 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 962a243ce94d48..453d5a754f12fc 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -61,6 +61,44 @@ struct 
DenseMapInfo {
 namespace clang::tidy {
 
 namespace {
+/// Returns the function that \p Method is overridding. If There are none or
+/// multiple overrides it returns nullptr. If the overridden function itself is
+/// overridding then it will recurse up to find the first decl of the function.
+const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
+  if (Method->size_overridden_methods() != 1)
+return nullptr;
+
+  while (true) {
+Method = *Method->begin_overridden_methods();
+assert(Method && "Overridden method shouldn't be null");
+unsigned NumOverrides = Method->size_overridden_methods();
+if (NumOverrides == 0)
+  return Method;
+if (NumOverrides > 1)
+  return nullptr;
+  }
+}
+
+bool hasNoName(const NamedDecl *Decl) {
+  return !Decl->getIdentifier() || Decl->getName().empty();
+}
+
+const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) {
+  const auto *Canonical = cast(ND->getCanonicalDecl());
+  if (Canonical != ND)
+return Canonical;
+
+  if (const auto *Method = dyn_cast(ND)) {
+if (const CXXMethodDecl *Overridden = getOverrideMethod(Method))
+  Canonical = cast(Overridden->getCanonicalDecl());
+
+if (Canonical != ND)
+  return Canonical;
+  }
+
+  return ND;
+}
+
 class NameLookup {
   llvm::PointerIntPair Data;
 
@@ -132,24 +170,6 @@ static NameLookup findDeclInBases(const CXXRecordDecl 
&Parent,
   return NameLookup(Found); // If nullptr, decl wasn't found.
 }
 
-/// Returns the function that \p Method is overridding. If There are none or
-/// multiple overrides it returns nullptr. If the overridden function itself is
-/// overridding then it will recurse up to find the first decl of the function.
-static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
-  if (Method->size_overridden_methods() != 1)
-return nullptr;
-
-  while (true) {
-Method = *Method->begin_overridden_methods();
-assert(Method && "Overridden method shouldn't be null");
-unsigned NumOverrides = Method->size_overridden_methods();
-if (NumOverrides == 0)
-  return Method;
-if (NumOverrides > 1)
-  return nullptr;
-  }
-}
-
 namespace {
 
 /// Callback supplies macros to RenamerClangTidyCheck::checkMacro
@@ -192,10 +212,6 @@ class RenamerClangTidyVisitor
   : Check(Check), SM(SM),
 AggressiveDependentMemberLookup(AggressiveDependentMemberLookup) {}
 
-  static bool hasNoName(const NamedDecl *Decl) {
-return !Decl->getIdentifier() || Decl->getName