1 //=------ unittest/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.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 "clang/AST/Expr.h"
11 
12 using namespace clang;
13 
14 namespace {
15 
16 class CXXMethodDeclVisitor
17     : public ExpectedLocationVisitor<CXXMethodDeclVisitor> {
18 public:
CXXMethodDeclVisitor(bool VisitImplicitCode)19   CXXMethodDeclVisitor(bool VisitImplicitCode)
20       : VisitImplicitCode(VisitImplicitCode) {}
21 
shouldVisitImplicitCode() const22   bool shouldVisitImplicitCode() const { return VisitImplicitCode; }
23 
VisitDeclRefExpr(DeclRefExpr * D)24   bool VisitDeclRefExpr(DeclRefExpr *D) {
25     Match("declref", D->getLocation());
26     return true;
27   }
VisitParmVarDecl(ParmVarDecl * P)28   bool VisitParmVarDecl(ParmVarDecl *P) {
29     Match("parm", P->getLocation());
30     return true;
31   }
32 
33 private:
34   bool VisitImplicitCode;
35 };
36 
TEST(RecursiveASTVisitor,CXXMethodDeclNoDefaultBodyVisited)37 TEST(RecursiveASTVisitor, CXXMethodDeclNoDefaultBodyVisited) {
38   for (bool VisitImplCode : {false, true}) {
39     CXXMethodDeclVisitor Visitor(VisitImplCode);
40     if (VisitImplCode)
41       Visitor.ExpectMatch("declref", 8, 28);
42     else
43       Visitor.DisallowMatch("declref", 8, 28);
44 
45     Visitor.ExpectMatch("parm", 8, 27);
46     llvm::StringRef Code = R"cpp(
47       struct B {};
48       struct A {
49         B BB;
50         A &operator=(A &&O);
51       };
52 
53       A &A::operator=(A &&O) = default;
54     )cpp";
55     EXPECT_TRUE(Visitor.runOver(Code, CXXMethodDeclVisitor::Lang_CXX11));
56   }
57 }
58 
TEST(RecursiveASTVisitor,FunctionDeclNoDefaultBodyVisited)59 TEST(RecursiveASTVisitor, FunctionDeclNoDefaultBodyVisited) {
60   for (bool VisitImplCode : {false, true}) {
61     CXXMethodDeclVisitor Visitor(VisitImplCode);
62     if (VisitImplCode)
63       Visitor.ExpectMatch("declref", 4, 58, /*Times=*/2);
64     else
65       Visitor.DisallowMatch("declref", 4, 58);
66     llvm::StringRef Code = R"cpp(
67       struct s {
68         int x;
69         friend auto operator==(s a, s b) -> bool = default;
70       };
71       bool k = s() == s(); // make sure clang generates the "==" definition.
72     )cpp";
73     EXPECT_TRUE(Visitor.runOver(Code, CXXMethodDeclVisitor::Lang_CXX2a));
74   }
75 }
76 } // end anonymous namespace
77