1 //===- unittest/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "TestVisitor.h"
11 
12 using namespace clang;
13 
14 namespace {
15 
16 /// \brief A visitor that optionally includes implicit code and matches
17 /// CXXConstructExpr.
18 ///
19 /// The name recorded for the match is the name of the class whose constructor
20 /// is invoked by the CXXConstructExpr, not the name of the class whose
21 /// constructor the CXXConstructExpr is contained in.
22 class ConstructExprVisitor
23     : public ExpectedLocationVisitor<ConstructExprVisitor> {
24 public:
25   ConstructExprVisitor() : ShouldVisitImplicitCode(false) {}
26 
27   bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
28 
29   void setShouldVisitImplicitCode(bool NewValue) {
30     ShouldVisitImplicitCode = NewValue;
31   }
32 
33   bool VisitCXXConstructExpr(CXXConstructExpr* Expr) {
34     if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
35       if (const CXXRecordDecl* Class = Ctor->getParent()) {
36         Match(Class->getName(), Expr->getLocation());
37       }
38     }
39     return true;
40   }
41 
42  private:
43   bool ShouldVisitImplicitCode;
44 };
45 
46 TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
47   ConstructExprVisitor Visitor;
48   Visitor.setShouldVisitImplicitCode(true);
49   Visitor.ExpectMatch("WithCtor", 2, 8);
50   // Simple has a constructor that implicitly initializes 'w'.  Test
51   // that a visitor that visits implicit code visits that initialization.
52   // Note: Clang lazily instantiates implicit declarations, so we need
53   // to use them in order to force them to appear in the AST.
54   EXPECT_TRUE(Visitor.runOver(
55       "struct WithCtor { WithCtor(); }; \n"
56       "struct Simple { WithCtor w; }; \n"
57       "int main() { Simple s; }\n"));
58 }
59 
60 // The same as CanVisitImplicitMemberInitializations, but checking that the
61 // visits are omitted when the visitor does not include implicit code.
62 TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) {
63   ConstructExprVisitor Visitor;
64   Visitor.setShouldVisitImplicitCode(false);
65   Visitor.DisallowMatch("WithCtor", 2, 8);
66   // Simple has a constructor that implicitly initializes 'w'.  Test
67   // that a visitor that skips implicit code skips that initialization.
68   // Note: Clang lazily instantiates implicit declarations, so we need
69   // to use them in order to force them to appear in the AST.
70   EXPECT_TRUE(Visitor.runOver(
71       "struct WithCtor { WithCtor(); }; \n"
72       "struct Simple { WithCtor w; }; \n"
73       "int main() { Simple s; }\n"));
74 }
75 
76 } // end anonymous namespace
77