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(Name: Storage, Location: 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 | |