@@ -1716,79 +1716,98 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
17161716
17171717namespace {
17181718class ConstraintRefersToContainingTemplateChecker
1719- : public TreeTransform<ConstraintRefersToContainingTemplateChecker> {
1719+ : public ConstDynamicRecursiveASTVisitor {
1720+ using inherited = ConstDynamicRecursiveASTVisitor;
17201721 bool Result = false ;
17211722 const FunctionDecl *Friend = nullptr ;
17221723 unsigned TemplateDepth = 0 ;
17231724
17241725 // Check a record-decl that we've seen to see if it is a lexical parent of the
17251726 // Friend, likely because it was referred to without its template arguments.
1726- void CheckIfContainingRecord (const CXXRecordDecl *CheckingRD) {
1727+ bool CheckIfContainingRecord (const CXXRecordDecl *CheckingRD) {
17271728 CheckingRD = CheckingRD->getMostRecentDecl ();
17281729 if (!CheckingRD->isTemplated ())
1729- return ;
1730+ return true ;
17301731
17311732 for (const DeclContext *DC = Friend->getLexicalDeclContext ();
17321733 DC && !DC->isFileContext (); DC = DC->getParent ())
17331734 if (const auto *RD = dyn_cast<CXXRecordDecl>(DC))
1734- if (CheckingRD == RD->getMostRecentDecl ())
1735+ if (CheckingRD == RD->getMostRecentDecl ()) {
17351736 Result = true ;
1737+ return false ;
1738+ }
1739+
1740+ return true ;
17361741 }
17371742
1738- void CheckNonTypeTemplateParmDecl (NonTypeTemplateParmDecl *D) {
1743+ bool CheckNonTypeTemplateParmDecl (const NonTypeTemplateParmDecl *D) {
17391744 if (D->getDepth () < TemplateDepth)
17401745 Result = true ;
17411746
17421747 // Necessary because the type of the NTTP might be what refers to the parent
17431748 // constriant.
1744- TransformType (D->getType ());
1749+ return TraverseType (D->getType ());
17451750 }
17461751
17471752public:
1748- using inherited = TreeTransform<ConstraintRefersToContainingTemplateChecker>;
1749-
1750- ConstraintRefersToContainingTemplateChecker (Sema &SemaRef,
1751- const FunctionDecl *Friend,
1753+ ConstraintRefersToContainingTemplateChecker (const FunctionDecl *Friend,
17521754 unsigned TemplateDepth)
1753- : inherited(SemaRef), Friend(Friend), TemplateDepth(TemplateDepth) {}
1755+ : Friend(Friend), TemplateDepth(TemplateDepth) {}
1756+
17541757 bool getResult () const { return Result; }
17551758
17561759 // This should be the only template parm type that we have to deal with.
1757- // SubstTempalteTypeParmPack , SubstNonTypeTemplateParmPack, and
1760+ // SubstTemplateTypeParmPack , SubstNonTypeTemplateParmPack, and
17581761 // FunctionParmPackExpr are all partially substituted, which cannot happen
17591762 // with concepts at this point in translation.
1760- using inherited::TransformTemplateTypeParmType;
1761- QualType TransformTemplateTypeParmType (TypeLocBuilder &TLB,
1762- TemplateTypeParmTypeLoc TL, bool ) {
1763- if (TL.getDecl ()->getDepth () < TemplateDepth)
1763+ bool VisitTemplateTypeParmType (const TemplateTypeParmType *Type) override {
1764+ if (Type->getDecl ()->getDepth () < TemplateDepth) {
17641765 Result = true ;
1765- return inherited::TransformTemplateTypeParmType (
1766- TLB, TL,
1767- /* SuppressObjCLifetime= */ false ) ;
1766+ return false ;
1767+ }
1768+ return true ;
17681769 }
17691770
1770- Decl *TransformDecl (SourceLocation Loc, Decl *D) {
1771- if (!D)
1772- return D;
1771+ bool TraverseDeclRefExpr (const DeclRefExpr *E) override {
1772+ return TraverseDecl (E->getDecl ());
1773+ }
1774+
1775+ bool TraverseTypedefType (const TypedefType *TT,
1776+ bool /* TraverseQualifier*/ ) override {
1777+ return TraverseType (TT->desugar ());
1778+ }
1779+
1780+ bool TraverseTypeLoc (TypeLoc TL, bool TraverseQualifier) override {
1781+ // We don't care about TypeLocs. So traverse Types instead.
1782+ return TraverseType (TL.getType (), TraverseQualifier);
1783+ }
1784+
1785+ bool VisitTagType (const TagType *T) override {
1786+ return TraverseDecl (T->getOriginalDecl ());
1787+ }
1788+
1789+ bool TraverseDecl (const Decl *D) override {
1790+ assert (D);
17731791 // FIXME : This is possibly an incomplete list, but it is unclear what other
17741792 // Decl kinds could be used to refer to the template parameters. This is a
17751793 // best guess so far based on examples currently available, but the
17761794 // unreachable should catch future instances/cases.
17771795 if (auto *TD = dyn_cast<TypedefNameDecl>(D))
1778- TransformType (TD->getUnderlyingType ());
1779- else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D))
1780- CheckNonTypeTemplateParmDecl (NTTPD);
1781- else if (auto *VD = dyn_cast<ValueDecl>(D))
1782- TransformType (VD->getType ());
1783- else if (auto *TD = dyn_cast<TemplateDecl>(D))
1784- TransformTemplateParameterList (TD->getTemplateParameters ());
1785- else if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1786- CheckIfContainingRecord (RD);
1787- else if (isa<NamedDecl>(D)) {
1796+ return TraverseType (TD->getUnderlyingType ());
1797+ if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D))
1798+ return CheckNonTypeTemplateParmDecl (NTTPD);
1799+ if (auto *VD = dyn_cast<ValueDecl>(D))
1800+ return TraverseType (VD->getType ());
1801+ if (isa<TemplateDecl>(D))
1802+ return true ;
1803+ if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1804+ return CheckIfContainingRecord (RD);
1805+
1806+ if (isa<NamedDecl, RequiresExprBodyDecl>(D)) {
17881807 // No direct types to visit here I believe.
17891808 } else
17901809 llvm_unreachable (" Don't know how to handle this declaration type yet" );
1791- return D ;
1810+ return true ;
17921811 }
17931812};
17941813} // namespace
@@ -1797,9 +1816,8 @@ bool Sema::ConstraintExpressionDependsOnEnclosingTemplate(
17971816 const FunctionDecl *Friend, unsigned TemplateDepth,
17981817 const Expr *Constraint) {
17991818 assert (Friend->getFriendObjectKind () && " Only works on a friend" );
1800- ConstraintRefersToContainingTemplateChecker Checker (*this , Friend,
1801- TemplateDepth);
1802- Checker.TransformExpr (const_cast <Expr *>(Constraint));
1819+ ConstraintRefersToContainingTemplateChecker Checker (Friend, TemplateDepth);
1820+ Checker.TraverseStmt (Constraint);
18031821 return Checker.getResult ();
18041822}
18051823
0 commit comments