13
13
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
14
14
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
15
15
16
+ #include " clang/AST/ASTConcept.h"
16
17
#include " clang/AST/Attr.h"
17
18
#include " clang/AST/Decl.h"
18
- #include " clang/AST/DeclarationName.h"
19
19
#include " clang/AST/DeclBase.h"
20
20
#include " clang/AST/DeclCXX.h"
21
21
#include " clang/AST/DeclFriend.h"
22
22
#include " clang/AST/DeclObjC.h"
23
23
#include " clang/AST/DeclOpenMP.h"
24
24
#include " clang/AST/DeclTemplate.h"
25
+ #include " clang/AST/DeclarationName.h"
25
26
#include " clang/AST/Expr.h"
26
- #include " clang/AST/ExprConcepts.h"
27
27
#include " clang/AST/ExprCXX.h"
28
+ #include " clang/AST/ExprConcepts.h"
28
29
#include " clang/AST/ExprObjC.h"
29
30
#include " clang/AST/ExprOpenMP.h"
30
31
#include " clang/AST/LambdaCapture.h"
@@ -319,11 +320,6 @@ template <typename Derived> class RecursiveASTVisitor {
319
320
bool TraverseSynOrSemInitListExpr (InitListExpr *S,
320
321
DataRecursionQueue *Queue = nullptr );
321
322
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
-
327
323
// / Recursively visit an Objective-C protocol reference with location
328
324
// / information.
329
325
// /
@@ -475,11 +471,21 @@ template <typename Derived> class RecursiveASTVisitor {
475
471
DEF_TRAVERSE_TMPL_INST (Function)
476
472
#undef DEF_TRAVERSE_TMPL_INST
477
473
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
+
478
481
bool dataTraverseNode (Stmt *S, DataRecursionQueue *Queue);
479
482
480
483
private:
481
484
// These are helper methods used by more than one Traverse* method.
482
485
bool TraverseTemplateParameterListHelper (TemplateParameterList *TPL);
486
+ // / Traverses the qualifier, name and template arguments of a concept
487
+ // / reference.
488
+ bool TraverseConceptReferenceHelper (const ConceptReference &C);
483
489
484
490
// Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
485
491
template <typename T>
@@ -511,6 +517,54 @@ template <typename Derived> class RecursiveASTVisitor {
511
517
bool PostVisitStmt (Stmt *S);
512
518
};
513
519
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
+
514
568
template <typename Derived>
515
569
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
516
570
DataRecursionQueue *Queue) {
@@ -530,6 +584,40 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
530
584
531
585
#undef DISPATCH_STMT
532
586
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
+
533
621
template <typename Derived>
534
622
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
535
623
// In pre-order traversal mode, each Traverse##STMT method is responsible for
@@ -1007,7 +1095,6 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
1007
1095
DEF_TRAVERSE_TYPE (AutoType, {
1008
1096
TRY_TO (TraverseType (T->getDeducedType ()));
1009
1097
if (T->isConstrained ()) {
1010
- TRY_TO (TraverseDecl (T->getTypeConstraintConcept ()));
1011
1098
TRY_TO (TraverseTemplateArguments (T->getArgs (), T->getNumArgs ()));
1012
1099
}
1013
1100
})
@@ -1838,17 +1925,8 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1838
1925
template <typename Derived>
1839
1926
bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
1840
1927
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));
1852
1930
return true ;
1853
1931
}
1854
1932
@@ -2435,18 +2513,6 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
2435
2513
return true ;
2436
2514
}
2437
2515
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
-
2450
2516
template <typename Derived>
2451
2517
bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
2452
2518
ObjCProtocolLoc ProtocolLoc) {
@@ -2825,31 +2891,15 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
2825
2891
}
2826
2892
})
2827
2893
2828
- DEF_TRAVERSE_STMT (ConceptSpecializationExpr, {
2829
- TRY_TO (TraverseConceptReference (*S));
2830
- })
2894
+ DEF_TRAVERSE_STMT (ConceptSpecializationExpr,
2895
+ { TRY_TO (TraverseConceptReferenceHelper (*S)); })
2831
2896
2832
2897
DEF_TRAVERSE_STMT (RequiresExpr, {
2833
2898
TRY_TO (TraverseDecl (S->getBody ()));
2834
2899
for (ParmVarDecl *Parm : S->getLocalParameters ())
2835
2900
TRY_TO (TraverseDecl (Parm));
2836
2901
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));
2853
2903
})
2854
2904
2855
2905
// These literals (all of them) do not need any action.
0 commit comments