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