| //===- unittest/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp --------===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "TestVisitor.h" | 
 |  | 
 | using namespace clang; | 
 |  | 
 | namespace { | 
 |  | 
 | /// \brief A visitor that optionally includes implicit code and matches | 
 | /// CXXConstructExpr. | 
 | /// | 
 | /// The name recorded for the match is the name of the class whose constructor | 
 | /// is invoked by the CXXConstructExpr, not the name of the class whose | 
 | /// constructor the CXXConstructExpr is contained in. | 
 | class ConstructExprVisitor | 
 |     : public ExpectedLocationVisitor<ConstructExprVisitor> { | 
 | public: | 
 |   ConstructExprVisitor() : ShouldVisitImplicitCode(false) {} | 
 |  | 
 |   bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } | 
 |  | 
 |   void setShouldVisitImplicitCode(bool NewValue) { | 
 |     ShouldVisitImplicitCode = NewValue; | 
 |   } | 
 |  | 
 |   bool VisitCXXConstructExpr(CXXConstructExpr* Expr) { | 
 |     if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) { | 
 |       if (const CXXRecordDecl* Class = Ctor->getParent()) { | 
 |         Match(Class->getName(), Expr->getLocation()); | 
 |       } | 
 |     } | 
 |     return true; | 
 |   } | 
 |  | 
 |  private: | 
 |   bool ShouldVisitImplicitCode; | 
 | }; | 
 |  | 
 | TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { | 
 |   ConstructExprVisitor Visitor; | 
 |   Visitor.setShouldVisitImplicitCode(true); | 
 |   Visitor.ExpectMatch("WithCtor", 2, 8); | 
 |   // Simple has a constructor that implicitly initializes 'w'.  Test | 
 |   // that a visitor that visits implicit code visits that initialization. | 
 |   // Note: Clang lazily instantiates implicit declarations, so we need | 
 |   // to use them in order to force them to appear in the AST. | 
 |   EXPECT_TRUE(Visitor.runOver( | 
 |       "struct WithCtor { WithCtor(); }; \n" | 
 |       "struct Simple { WithCtor w; }; \n" | 
 |       "int main() { Simple s; }\n")); | 
 | } | 
 |  | 
 | // The same as CanVisitImplicitMemberInitializations, but checking that the | 
 | // visits are omitted when the visitor does not include implicit code. | 
 | TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) { | 
 |   ConstructExprVisitor Visitor; | 
 |   Visitor.setShouldVisitImplicitCode(false); | 
 |   Visitor.DisallowMatch("WithCtor", 2, 8); | 
 |   // Simple has a constructor that implicitly initializes 'w'.  Test | 
 |   // that a visitor that skips implicit code skips that initialization. | 
 |   // Note: Clang lazily instantiates implicit declarations, so we need | 
 |   // to use them in order to force them to appear in the AST. | 
 |   EXPECT_TRUE(Visitor.runOver( | 
 |       "struct WithCtor { WithCtor(); }; \n" | 
 |       "struct Simple { WithCtor w; }; \n" | 
 |       "int main() { Simple s; }\n")); | 
 | } | 
 |  | 
 | } // end anonymous namespace |