ConstructExpr.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. #include "TestVisitor.h"
  9. using namespace clang;
  10. namespace {
  11. /// \brief A visitor that optionally includes implicit code and matches
  12. /// CXXConstructExpr.
  13. ///
  14. /// The name recorded for the match is the name of the class whose constructor
  15. /// is invoked by the CXXConstructExpr, not the name of the class whose
  16. /// constructor the CXXConstructExpr is contained in.
  17. class ConstructExprVisitor
  18. : public ExpectedLocationVisitor<ConstructExprVisitor> {
  19. public:
  20. ConstructExprVisitor() : ShouldVisitImplicitCode(false) {}
  21. bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; }
  22. void setShouldVisitImplicitCode(bool NewValue) {
  23. ShouldVisitImplicitCode = NewValue;
  24. }
  25. bool VisitCXXConstructExpr(CXXConstructExpr* Expr) {
  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. private:
  34. bool ShouldVisitImplicitCode;
  35. };
  36. TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) {
  37. ConstructExprVisitor Visitor;
  38. Visitor.setShouldVisitImplicitCode(true);
  39. Visitor.ExpectMatch("WithCtor", 2, 8);
  40. // Simple has a constructor that implicitly initializes 'w'. Test
  41. // that a visitor that visits implicit code visits that initialization.
  42. // Note: Clang lazily instantiates implicit declarations, so we need
  43. // to use them in order to force them to appear in the AST.
  44. EXPECT_TRUE(Visitor.runOver(
  45. "struct WithCtor { WithCtor(); }; \n"
  46. "struct Simple { WithCtor w; }; \n"
  47. "int main() { Simple s; }\n"));
  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.setShouldVisitImplicitCode(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. } // end anonymous namespace