================
@@ -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