xref: /llvm-project/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp (revision 4e600751d2f7e8e7b85a71b7128b68444bdde91b)
1 //===- unittest/Tooling/RecursiveASTVisitorTests/ConstructExpr.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 
11 using namespace clang;
12 
13 namespace {
14 
15 /// \brief A visitor that optionally includes implicit code and matches
16 /// CXXConstructExpr.
17 ///
18 /// The name recorded for the match is the name of the class whose constructor
19 /// is invoked by the CXXConstructExpr, not the name of the class whose
20 /// constructor the CXXConstructExpr is contained in.
21 class ConstructExprVisitor : public ExpectedLocationVisitor {
22 public:
23   ConstructExprVisitor() { ShouldVisitImplicitCode = false; }
24 
25   bool VisitCXXConstructExpr(CXXConstructExpr *Expr) override {
26     if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
27       if (const CXXRecordDecl* Class = Ctor->getParent()) {
28         Match(Class->getName(), Expr->getLocation());
29       }
30     }
31     return true;
32   }
33 };
34 
35 TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
36   ConstructExprVisitor Visitor;
37   Visitor.ShouldVisitImplicitCode = true;
38   Visitor.ExpectMatch("WithCtor", 2, 8);
39   // Simple has a constructor that implicitly initializes 'w'.  Test
40   // that a visitor that visits implicit code visits that initialization.
41   // Note: Clang lazily instantiates implicit declarations, so we need
42   // to use them in order to force them to appear in the AST.
43   EXPECT_TRUE(Visitor.runOver(
44       "struct WithCtor { WithCtor(); }; \n"
45       "struct Simple { WithCtor w; }; \n"
46       "int main() { Simple s; }\n"));
47 }
48 
49 // The same as CanVisitImplicitMemberInitializations, but checking that the
50 // visits are omitted when the visitor does not include implicit code.
51 TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) {
52   ConstructExprVisitor Visitor;
53   Visitor.ShouldVisitImplicitCode = false;
54   Visitor.DisallowMatch("WithCtor", 2, 8);
55   // Simple has a constructor that implicitly initializes 'w'.  Test
56   // that a visitor that skips implicit code skips that initialization.
57   // Note: Clang lazily instantiates implicit declarations, so we need
58   // to use them in order to force them to appear in the AST.
59   EXPECT_TRUE(Visitor.runOver(
60       "struct WithCtor { WithCtor(); }; \n"
61       "struct Simple { WithCtor w; }; \n"
62       "int main() { Simple s; }\n"));
63 }
64 
65 } // end anonymous namespace
66