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