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
11using namespace clang;
12
13namespace {
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.
21class ConstructExprVisitor
22 : public ExpectedLocationVisitor<ConstructExprVisitor> {
23public:
24 ConstructExprVisitor() : ShouldVisitImplicitCode(false) {}
25
26 bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
27
28 void setShouldVisitImplicitCode(bool NewValue) {
29 ShouldVisitImplicitCode = NewValue;
30 }
31
32 bool VisitCXXConstructExpr(CXXConstructExpr* Expr) {
33 if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
34 if (const CXXRecordDecl* Class = Ctor->getParent()) {
35 Match(Name: Class->getName(), Location: Expr->getLocation());
36 }
37 }
38 return true;
39 }
40
41 private:
42 bool ShouldVisitImplicitCode;
43};
44
45TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
46 ConstructExprVisitor Visitor;
47 Visitor.setShouldVisitImplicitCode(true);
48 Visitor.ExpectMatch(Match: "WithCtor", Line: 2, Column: 8);
49 // Simple has a constructor that implicitly initializes 'w'. Test
50 // that a visitor that visits implicit code visits that initialization.
51 // Note: Clang lazily instantiates implicit declarations, so we need
52 // to use them in order to force them to appear in the AST.
53 EXPECT_TRUE(Visitor.runOver(
54 "struct WithCtor { WithCtor(); }; \n"
55 "struct Simple { WithCtor w; }; \n"
56 "int main() { Simple s; }\n"));
57}
58
59// The same as CanVisitImplicitMemberInitializations, but checking that the
60// visits are omitted when the visitor does not include implicit code.
61TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) {
62 ConstructExprVisitor Visitor;
63 Visitor.setShouldVisitImplicitCode(false);
64 Visitor.DisallowMatch(Match: "WithCtor", Line: 2, Column: 8);
65 // Simple has a constructor that implicitly initializes 'w'. Test
66 // that a visitor that skips implicit code skips that initialization.
67 // Note: Clang lazily instantiates implicit declarations, so we need
68 // to use them in order to force them to appear in the AST.
69 EXPECT_TRUE(Visitor.runOver(
70 "struct WithCtor { WithCtor(); }; \n"
71 "struct Simple { WithCtor w; }; \n"
72 "int main() { Simple s; }\n"));
73}
74
75} // end anonymous namespace
76

source code of clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp