xref: /llvm-project/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp (revision 4e600751d2f7e8e7b85a71b7128b68444bdde91b)
1239f8b9eSHaojian Wu //===- unittest/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp -------===//
2239f8b9eSHaojian Wu //
3239f8b9eSHaojian Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4239f8b9eSHaojian Wu // See https://llvm.org/LICENSE.txt for license information.
5239f8b9eSHaojian Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6239f8b9eSHaojian Wu //
7239f8b9eSHaojian Wu //===----------------------------------------------------------------------===//
8239f8b9eSHaojian Wu 
9239f8b9eSHaojian Wu #include "TestVisitor.h"
10239f8b9eSHaojian Wu #include <string>
11239f8b9eSHaojian Wu 
12239f8b9eSHaojian Wu using namespace clang;
13239f8b9eSHaojian Wu 
14239f8b9eSHaojian Wu namespace {
15239f8b9eSHaojian Wu 
16*4e600751SSirraide class DeductionGuideVisitor : public ExpectedLocationVisitor {
17239f8b9eSHaojian Wu public:
18*4e600751SSirraide   DeductionGuideVisitor(bool VisitImplicitCode) {
19*4e600751SSirraide     ShouldVisitImplicitCode = VisitImplicitCode;
20*4e600751SSirraide     ShouldVisitTemplateInstantiations = false;
21*4e600751SSirraide   }
22*4e600751SSirraide 
23*4e600751SSirraide   bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) override {
24239f8b9eSHaojian Wu     std::string Storage;
25239f8b9eSHaojian Wu     llvm::raw_string_ostream Stream(Storage);
26239f8b9eSHaojian Wu     D->print(Stream);
27ac84ada9SYoungsuk Kim     Match(Storage, D->getLocation());
28239f8b9eSHaojian Wu     return true;
29239f8b9eSHaojian Wu   }
30239f8b9eSHaojian Wu };
31239f8b9eSHaojian Wu 
32239f8b9eSHaojian Wu TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
33239f8b9eSHaojian Wu   DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ false);
34239f8b9eSHaojian Wu   // Verify that the synthezied deduction guide for alias is not visited in
35239f8b9eSHaojian Wu   // RAV's implicit mode.
36239f8b9eSHaojian Wu   Visitor.ExpectMatch("Foo(T) -> Foo<int>", 11, 1);
372ef12b55SHaojian Wu   Visitor.DisallowMatch("Bar(T) -> Foo<int>", 14, 1);
38239f8b9eSHaojian Wu   EXPECT_TRUE(Visitor.runOver(
39239f8b9eSHaojian Wu       R"cpp(
40239f8b9eSHaojian Wu template <typename T>
41239f8b9eSHaojian Wu concept False = true;
42239f8b9eSHaojian Wu 
43239f8b9eSHaojian Wu template <typename T>
44239f8b9eSHaojian Wu struct Foo {
45239f8b9eSHaojian Wu   Foo(T);
46239f8b9eSHaojian Wu };
47239f8b9eSHaojian Wu 
48239f8b9eSHaojian Wu template<typename T> requires False<T>
49239f8b9eSHaojian Wu Foo(T) -> Foo<int>;
50239f8b9eSHaojian Wu 
51239f8b9eSHaojian Wu template <typename U>
52239f8b9eSHaojian Wu using Bar = Foo<U>;
53239f8b9eSHaojian Wu Bar s(1);
54239f8b9eSHaojian Wu    )cpp",
55239f8b9eSHaojian Wu       DeductionGuideVisitor::Lang_CXX2a));
56239f8b9eSHaojian Wu }
57239f8b9eSHaojian Wu 
58239f8b9eSHaojian Wu TEST(RecursiveASTVisitor, DeductionGuideImplicitMode) {
59239f8b9eSHaojian Wu   DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ true);
60239f8b9eSHaojian Wu   Visitor.ExpectMatch("Foo(T) -> Foo<int>", 11, 1);
612ef12b55SHaojian Wu   Visitor.ExpectMatch("Bar(T) -> Foo<int>", 14, 1);
62239f8b9eSHaojian Wu   EXPECT_TRUE(Visitor.runOver(
63239f8b9eSHaojian Wu       R"cpp(
64239f8b9eSHaojian Wu template <typename T>
65239f8b9eSHaojian Wu concept False = true;
66239f8b9eSHaojian Wu 
67239f8b9eSHaojian Wu template <typename T>
68239f8b9eSHaojian Wu struct Foo {
69239f8b9eSHaojian Wu   Foo(T);
70239f8b9eSHaojian Wu };
71239f8b9eSHaojian Wu 
72239f8b9eSHaojian Wu template<typename T> requires False<T>
73239f8b9eSHaojian Wu Foo(T) -> Foo<int>;
74239f8b9eSHaojian Wu 
75239f8b9eSHaojian Wu template <typename U>
76239f8b9eSHaojian Wu using Bar = Foo<U>;
77239f8b9eSHaojian Wu Bar s(1);
78239f8b9eSHaojian Wu    )cpp",
79239f8b9eSHaojian Wu       DeductionGuideVisitor::Lang_CXX2a));
80239f8b9eSHaojian Wu }
81239f8b9eSHaojian Wu 
82239f8b9eSHaojian Wu } // end anonymous namespace
83