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