1 //===- unittest/Tooling/RecursiveASTVisitorTests/Concept.cpp----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TestVisitor.h"
10 #include "clang/AST/ExprConcepts.h"
11 
12 using namespace clang;
13 
14 namespace {
15 
16 struct ConceptVisitor : ExpectedLocationVisitor<ConceptVisitor> {
VisitConceptSpecializationExpr__anondb863baf0111::ConceptVisitor17   bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
18     ++ConceptSpecializationExprsVisited;
19     return true;
20   }
TraverseConceptReference__anondb863baf0111::ConceptVisitor21   bool TraverseConceptReference(const ConceptReference &R) {
22     ++ConceptReferencesTraversed;
23     return true;
24   }
25 
26   int ConceptSpecializationExprsVisited = 0;
27   int ConceptReferencesTraversed = 0;
28 };
29 
TEST(RecursiveASTVisitor,ConstrainedParameter)30 TEST(RecursiveASTVisitor, ConstrainedParameter) {
31   ConceptVisitor Visitor;
32   EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n"
33                               "template <Fooable T> void bar(T);",
34                               ConceptVisitor::Lang_CXX2a));
35   // Check that we visit the "Fooable T" template parameter's TypeConstraint's
36   // ImmediatelyDeclaredConstraint, which is a ConceptSpecializationExpr.
37   EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited);
38   // There are two ConceptReference objects in the AST: the base subobject
39   // of the ConceptSpecializationExpr, and the base subobject of the
40   // TypeConstraint itself. To avoid traversing the concept and arguments
41   // multiple times, we only traverse one.
42   EXPECT_EQ(1, Visitor.ConceptReferencesTraversed);
43 }
44 
45 } // end anonymous namespace
46