1313#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
1414#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
1515
16+ #include " clang/AST/ASTConcept.h"
1617#include " clang/AST/Attr.h"
1718#include " clang/AST/Decl.h"
18- #include " clang/AST/DeclarationName.h"
1919#include " clang/AST/DeclBase.h"
2020#include " clang/AST/DeclCXX.h"
2121#include " clang/AST/DeclFriend.h"
2222#include " clang/AST/DeclObjC.h"
2323#include " clang/AST/DeclOpenMP.h"
2424#include " clang/AST/DeclTemplate.h"
25+ #include " clang/AST/DeclarationName.h"
2526#include " clang/AST/Expr.h"
26- #include " clang/AST/ExprConcepts.h"
2727#include " clang/AST/ExprCXX.h"
28+ #include " clang/AST/ExprConcepts.h"
2829#include " clang/AST/ExprObjC.h"
2930#include " clang/AST/ExprOpenMP.h"
3031#include " clang/AST/LambdaCapture.h"
@@ -319,11 +320,6 @@ template <typename Derived> class RecursiveASTVisitor {
319320 bool TraverseSynOrSemInitListExpr (InitListExpr *S,
320321 DataRecursionQueue *Queue = nullptr );
321322
322- // / Recursively visit a reference to a concept with potential arguments.
323- // /
324- // / \returns false if the visitation was terminated early, true otherwise.
325- bool TraverseConceptReference (const ConceptReference &C);
326-
327323 // / Recursively visit an Objective-C protocol reference with location
328324 // / information.
329325 // /
@@ -475,11 +471,21 @@ template <typename Derived> class RecursiveASTVisitor {
475471 DEF_TRAVERSE_TMPL_INST (Function)
476472#undef DEF_TRAVERSE_TMPL_INST
477473
474+ bool TraverseTypeConstraint (const TypeConstraint *C);
475+
476+ bool TraverseConceptRequirement (concepts::Requirement *R);
477+ bool TraverseConceptTypeRequirement (concepts::TypeRequirement *R);
478+ bool TraverseConceptExprRequirement (concepts::ExprRequirement *R);
479+ bool TraverseConceptNestedRequirement (concepts::NestedRequirement *R);
480+
478481 bool dataTraverseNode (Stmt *S, DataRecursionQueue *Queue);
479482
480483private:
481484 // These are helper methods used by more than one Traverse* method.
482485 bool TraverseTemplateParameterListHelper (TemplateParameterList *TPL);
486+ // / Traverses the qualifier, name and template arguments of a concept
487+ // / reference.
488+ bool TraverseConceptReferenceHelper (const ConceptReference &C);
483489
484490 // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
485491 template <typename T>
@@ -511,6 +517,54 @@ template <typename Derived> class RecursiveASTVisitor {
511517 bool PostVisitStmt (Stmt *S);
512518};
513519
520+ template <typename Derived>
521+ bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
522+ const TypeConstraint *C) {
523+ if (!getDerived ().shouldVisitImplicitCode ()) {
524+ TRY_TO (TraverseConceptReferenceHelper (*C));
525+ return true ;
526+ }
527+ if (Expr *IDC = C->getImmediatelyDeclaredConstraint ()) {
528+ TRY_TO (TraverseStmt (IDC));
529+ } else {
530+ // Avoid traversing the ConceptReference in the TypeConstraint
531+ // if we have an immediately-declared-constraint, otherwise
532+ // we'll end up visiting the concept and the arguments in
533+ // the TC twice.
534+ TRY_TO (TraverseConceptReferenceHelper (*C));
535+ }
536+ return true ;
537+ }
538+
539+ template <typename Derived>
540+ bool RecursiveASTVisitor<Derived>::TraverseConceptRequirement(
541+ concepts::Requirement *R) {
542+ switch (R->getKind ()) {
543+ case concepts::Requirement::RK_Type:
544+ return getDerived ().TraverseConceptTypeRequirement (
545+ cast<concepts::TypeRequirement>(R));
546+ case concepts::Requirement::RK_Simple:
547+ case concepts::Requirement::RK_Compound:
548+ return getDerived ().TraverseConceptExprRequirement (
549+ cast<concepts::ExprRequirement>(R));
550+ case concepts::Requirement::RK_Nested:
551+ return getDerived ().TraverseConceptNestedRequirement (
552+ cast<concepts::NestedRequirement>(R));
553+ }
554+ }
555+
556+ template <typename Derived>
557+ bool RecursiveASTVisitor<Derived>::TraverseConceptReferenceHelper(
558+ const ConceptReference &C) {
559+ TRY_TO (TraverseNestedNameSpecifierLoc (C.getNestedNameSpecifierLoc ()));
560+ TRY_TO (TraverseDeclarationNameInfo (C.getConceptNameInfo ()));
561+ if (C.hasExplicitTemplateArgs ())
562+ TRY_TO (TraverseTemplateArgumentLocsHelper (
563+ C.getTemplateArgsAsWritten ()->getTemplateArgs (),
564+ C.getTemplateArgsAsWritten ()->NumTemplateArgs ));
565+ return true ;
566+ }
567+
514568template <typename Derived>
515569bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
516570 DataRecursionQueue *Queue) {
@@ -530,6 +584,40 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
530584
531585#undef DISPATCH_STMT
532586
587+ template <typename Derived>
588+ bool RecursiveASTVisitor<Derived>::TraverseConceptTypeRequirement(
589+ concepts::TypeRequirement *R) {
590+ if (R->isSubstitutionFailure ())
591+ return true ;
592+ return getDerived ().TraverseTypeLoc (R->getType ()->getTypeLoc ());
593+ }
594+
595+ template <typename Derived>
596+ bool RecursiveASTVisitor<Derived>::TraverseConceptExprRequirement(
597+ concepts::ExprRequirement *R) {
598+ if (!R->isExprSubstitutionFailure ())
599+ TRY_TO (TraverseStmt (R->getExpr ()));
600+ auto &RetReq = R->getReturnTypeRequirement ();
601+ if (RetReq.isTypeConstraint ()) {
602+ if (getDerived ().shouldVisitImplicitCode ()) {
603+ TRY_TO (TraverseTemplateParameterListHelper (
604+ RetReq.getTypeConstraintTemplateParameterList ()));
605+ } else {
606+ // Template parameter list is implicit, visit constraint directly.
607+ TRY_TO (TraverseTypeConstraint (RetReq.getTypeConstraint ()));
608+ }
609+ }
610+ return true ;
611+ }
612+
613+ template <typename Derived>
614+ bool RecursiveASTVisitor<Derived>::TraverseConceptNestedRequirement(
615+ concepts::NestedRequirement *R) {
616+ if (!R->isSubstitutionFailure ())
617+ return getDerived ().TraverseStmt (R->getConstraintExpr ());
618+ return true ;
619+ }
620+
533621template <typename Derived>
534622bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
535623 // In pre-order traversal mode, each Traverse##STMT method is responsible for
@@ -1007,7 +1095,6 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
10071095DEF_TRAVERSE_TYPE (AutoType, {
10081096 TRY_TO (TraverseType (T->getDeducedType ()));
10091097 if (T->isConstrained ()) {
1010- TRY_TO (TraverseDecl (T->getTypeConstraintConcept ()));
10111098 TRY_TO (TraverseTemplateArguments (T->getArgs (), T->getNumArgs ()));
10121099 }
10131100})
@@ -1838,17 +1925,8 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
18381925template <typename Derived>
18391926bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
18401927 const TemplateTypeParmDecl *D) {
1841- if (const auto *TC = D->getTypeConstraint ()) {
1842- if (Expr *IDC = TC->getImmediatelyDeclaredConstraint ()) {
1843- TRY_TO (TraverseStmt (IDC));
1844- } else {
1845- // Avoid traversing the ConceptReference in the TypeCosntraint
1846- // if we have an immediately-declared-constraint, otherwise
1847- // we'll end up visiting the concept and the arguments in
1848- // the TC twice.
1849- TRY_TO (TraverseConceptReference (*TC));
1850- }
1851- }
1928+ if (const auto *TC = D->getTypeConstraint ())
1929+ TRY_TO (TraverseTypeConstraint (TC));
18521930 return true ;
18531931}
18541932
@@ -2435,18 +2513,6 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
24352513 return true ;
24362514}
24372515
2438- template <typename Derived>
2439- bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
2440- const ConceptReference &C) {
2441- TRY_TO (TraverseNestedNameSpecifierLoc (C.getNestedNameSpecifierLoc ()));
2442- TRY_TO (TraverseDeclarationNameInfo (C.getConceptNameInfo ()));
2443- if (C.hasExplicitTemplateArgs ())
2444- TRY_TO (TraverseTemplateArgumentLocsHelper (
2445- C.getTemplateArgsAsWritten ()->getTemplateArgs (),
2446- C.getTemplateArgsAsWritten ()->NumTemplateArgs ));
2447- return true ;
2448- }
2449-
24502516template <typename Derived>
24512517bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
24522518 ObjCProtocolLoc ProtocolLoc) {
@@ -2825,31 +2891,15 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
28252891 }
28262892})
28272893
2828- DEF_TRAVERSE_STMT (ConceptSpecializationExpr, {
2829- TRY_TO (TraverseConceptReference (*S));
2830- })
2894+ DEF_TRAVERSE_STMT (ConceptSpecializationExpr,
2895+ { TRY_TO (TraverseConceptReferenceHelper (*S)); })
28312896
28322897DEF_TRAVERSE_STMT (RequiresExpr, {
28332898 TRY_TO (TraverseDecl (S->getBody ()));
28342899 for (ParmVarDecl *Parm : S->getLocalParameters ())
28352900 TRY_TO (TraverseDecl (Parm));
28362901 for (concepts::Requirement *Req : S->getRequirements ())
2837- if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2838- if (!TypeReq->isSubstitutionFailure ())
2839- TRY_TO (TraverseTypeLoc (TypeReq->getType ()->getTypeLoc ()));
2840- } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2841- if (!ExprReq->isExprSubstitutionFailure ())
2842- TRY_TO (TraverseStmt (ExprReq->getExpr ()));
2843- auto &RetReq = ExprReq->getReturnTypeRequirement ();
2844- if (RetReq.isTypeConstraint ()) {
2845- TRY_TO (TraverseStmt (
2846- RetReq.getTypeConstraint ()->getImmediatelyDeclaredConstraint ()));
2847- }
2848- } else {
2849- auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2850- if (!NestedReq->isSubstitutionFailure ())
2851- TRY_TO (TraverseStmt (NestedReq->getConstraintExpr ()));
2852- }
2902+ TRY_TO (TraverseConceptRequirement (Req));
28532903})
28542904
28552905// These literals (all of them) do not need any action.
0 commit comments