xref: /llvm-project/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp (revision 4e600751d2f7e8e7b85a71b7128b68444bdde91b)
1 //===- unittest/Tooling/RecursiveASTVisitorTests/DeductionGuide.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 <string>
11 
12 using namespace clang;
13 
14 namespace {
15 
16 class DeductionGuideVisitor : public ExpectedLocationVisitor {
17 public:
18   DeductionGuideVisitor(bool VisitImplicitCode) {
19     ShouldVisitImplicitCode = VisitImplicitCode;
20     ShouldVisitTemplateInstantiations = false;
21   }
22 
23   bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) override {
24     std::string Storage;
25     llvm::raw_string_ostream Stream(Storage);
26     D->print(Stream);
27     Match(Storage, D->getLocation());
28     return true;
29   }
30 };
31 
32 TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
33   DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ false);
34   // Verify that the synthezied deduction guide for alias is not visited in
35   // RAV's implicit mode.
36   Visitor.ExpectMatch("Foo(T) -> Foo<int>", 11, 1);
37   Visitor.DisallowMatch("Bar(T) -> Foo<int>", 14, 1);
38   EXPECT_TRUE(Visitor.runOver(
39       R"cpp(
40 template <typename T>
41 concept False = true;
42 
43 template <typename T>
44 struct Foo {
45   Foo(T);
46 };
47 
48 template<typename T> requires False<T>
49 Foo(T) -> Foo<int>;
50 
51 template <typename U>
52 using Bar = Foo<U>;
53 Bar s(1);
54    )cpp",
55       DeductionGuideVisitor::Lang_CXX2a));
56 }
57 
58 TEST(RecursiveASTVisitor, DeductionGuideImplicitMode) {
59   DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ true);
60   Visitor.ExpectMatch("Foo(T) -> Foo<int>", 11, 1);
61   Visitor.ExpectMatch("Bar(T) -> Foo<int>", 14, 1);
62   EXPECT_TRUE(Visitor.runOver(
63       R"cpp(
64 template <typename T>
65 concept False = true;
66 
67 template <typename T>
68 struct Foo {
69   Foo(T);
70 };
71 
72 template<typename T> requires False<T>
73 Foo(T) -> Foo<int>;
74 
75 template <typename U>
76 using Bar = Foo<U>;
77 Bar s(1);
78    )cpp",
79       DeductionGuideVisitor::Lang_CXX2a));
80 }
81 
82 } // end anonymous namespace
83