1 //===- unittest/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.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 "llvm/ADT/StringRef.h" 11 12 using namespace clang; 13 14 namespace { 15 16 class MemberPointerTypeLocVisitor : public ExpectedLocationVisitor { 17 public: 18 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override { 19 if (!TL) 20 return true; 21 Match(TL.getDecl()->getName(), TL.getNameLoc()); 22 return true; 23 } 24 bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { 25 if (!RTL) 26 return true; 27 Match(RTL.getDecl()->getName(), RTL.getNameLoc()); 28 return true; 29 } 30 }; 31 32 TEST(RecursiveASTVisitor, VisitTypeLocInMemberPointerTypeLoc) { 33 MemberPointerTypeLocVisitor Visitor; 34 Visitor.ExpectMatch("Bar", 4, 36); 35 Visitor.ExpectMatch("T", 7, 23); 36 llvm::StringLiteral Code = R"cpp( 37 class Bar { void func(int); }; 38 class Foo { 39 void bind(const char*, void(Bar::*Foo)(int)) {} 40 41 template<typename T> 42 void test(void(T::*Foo)()); 43 }; 44 )cpp"; 45 EXPECT_TRUE(Visitor.runOver(Code)); 46 } 47 48 TEST(RecursiveASTVisitor, NoCrash) { 49 MemberPointerTypeLocVisitor Visitor; 50 llvm::StringLiteral Code = R"cpp( 51 // MemberPointerTypeLoc.getClassTInfo() is null. 52 class a(b(a::*)) class 53 )cpp"; 54 EXPECT_FALSE(Visitor.runOver(Code)); 55 } 56 57 } // end anonymous namespace 58