xref: /llvm-project/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp (revision 4e600751d2f7e8e7b85a71b7128b68444bdde91b)
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