@@ -481,6 +481,8 @@ template <typename Derived> class RecursiveASTVisitor {
481
481
template <typename T>
482
482
bool TraverseDeclTemplateParameterLists (T *D);
483
483
484
+ bool TraverseTemplateTypeParamDeclConstraints (const TemplateTypeParmDecl *D);
485
+
484
486
bool TraverseTemplateArgumentLocsHelper (const TemplateArgumentLoc *TAL,
485
487
unsigned Count);
486
488
bool TraverseArrayTypeLocHelper (ArrayTypeLoc TL);
@@ -658,8 +660,14 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
658
660
659
661
// As a syntax visitor, by default we want to ignore declarations for
660
662
// implicit declarations (ones not typed explicitly by the user).
661
- if (!getDerived ().shouldVisitImplicitCode () && D->isImplicit ())
663
+ if (!getDerived ().shouldVisitImplicitCode () && D->isImplicit ()) {
664
+ // For an implicit template type parameter, its type constraints are not
665
+ // implicit and are not represented anywhere else. We still need to visit
666
+ // them.
667
+ if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D))
668
+ return TraverseTemplateTypeParamDeclConstraints (TTPD);
662
669
return true ;
670
+ }
663
671
664
672
switch (D->getKind ()) {
665
673
#define ABSTRACT_DECL (DECL )
@@ -1779,10 +1787,9 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1779
1787
TRY_TO (TraverseTemplateParameterListHelper (D->getTemplateParameters ()));
1780
1788
})
1781
1789
1782
- DEF_TRAVERSE_DECL (TemplateTypeParmDecl, {
1783
- // D is the "T" in something like "template<typename T> class vector;"
1784
- if (D->getTypeForDecl ())
1785
- TRY_TO (TraverseType (QualType (D->getTypeForDecl (), 0 )));
1790
+ template <typename Derived>
1791
+ bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
1792
+ const TemplateTypeParmDecl *D) {
1786
1793
if (const auto *TC = D->getTypeConstraint ()) {
1787
1794
if (Expr *IDC = TC->getImmediatelyDeclaredConstraint ()) {
1788
1795
TRY_TO (TraverseStmt (IDC));
@@ -1794,6 +1801,14 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
1794
1801
TRY_TO (TraverseConceptReference (*TC));
1795
1802
}
1796
1803
}
1804
+ return true ;
1805
+ }
1806
+
1807
+ DEF_TRAVERSE_DECL (TemplateTypeParmDecl, {
1808
+ // D is the "T" in something like "template<typename T> class vector;"
1809
+ if (D->getTypeForDecl ())
1810
+ TRY_TO (TraverseType (QualType (D->getTypeForDecl (), 0 )));
1811
+ TRY_TO (TraverseTemplateTypeParamDeclConstraints (D));
1797
1812
if (D->hasDefaultArgument () && !D->defaultArgumentWasInherited ())
1798
1813
TRY_TO (TraverseTypeLoc (D->getDefaultArgumentInfo ()->getTypeLoc ()));
1799
1814
})
0 commit comments