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