================
@@ -165,6 +166,53 @@ bool BugSuppression::isSuppressed(const BugReport &R) {
          isSuppressed(UniqueingLocation, DeclWithIssue, {});
 }
 
+static const ClassTemplateDecl *
+walkInstantiatedFromChain(const ClassTemplateDecl *Tmpl) {
+  // For nested member templates (e.g., S2 inside S1<T>), getInstantiatedFrom
+  // may return the member template as instantiated within an outer
+  // specialization (e.g., S2 as it appears in S1<int>).  That instantiated
+  // member template has no definition redeclaration itself; we need to walk
+  // up the member template chain to reach the primary template definition.
+  // \code
+  //   template <class> struct S1 {
+  //     template <class> struct S2 {
+  //       int i;
+  //       template <class T> int m(const S2<T>& s2) {
+  //         return s2.i;
+  //       }
+  //     };
+  //   }
+  // /code
+  while (auto *MemberTmpl = Tmpl->getInstantiatedFromMemberTemplate()) {
+    if (Tmpl->isMemberSpecialization())
+      break;
+    Tmpl = MemberTmpl;
+  }
+  return Tmpl;
+}
+
+static const ClassTemplatePartialSpecializationDecl *walkInstantiatedFromChain(
+    const ClassTemplatePartialSpecializationDecl *PartialSpec) {
+  while (auto *MemberPS = PartialSpec->getInstantiatedFromMember()) {
----------------
NagyDonat wrote:

Consider writing
```c++
LongAndUnwieldyTypeName *MemberPS;
while (MemberPS = PartialSpec->getInstantiatedFromMember()) { /* ... */ }
```
I know this is less modern, but extending the scope of the variable is less 
problematic than hiding the type name.

https://github.com/llvm/llvm-project/pull/183727
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to