[cfe-commits] [PATCH] Allow RecursiveASTVisitor to visit implicit ctor initializers (for which isWritten() returns false)

James Dennett reviews at llvm-reviews.chandlerc.com
Thu Aug 23 13:03:00 PDT 2012


Hi klimek,

Now that we have RecursiveASTVisitor::shouldVisitImplicitCode(), it
would be good to allow RAV to visit CXXCtorInitializer objects for
which isWritten() returns false (i.e., the initializers that are
implicitly added -- in C++98 that can happen because the user didn't
mention a direct subobject that has a constructor, I'm not sure if it
can also happen in C++11 when NSDMIs are used).

The change to do this is a one-liner in
RecursiveASTVisitor<T>::TraverseConstructorInitializer.  This is the
only use of isWritten() in RAV.

The attached patch includes a test for the new functionality.

Comments on either style or substance would be appreciated.

http://llvm-reviews.chandlerc.com/D26

Files:
  include/clang/AST/RecursiveASTVisitor.h
  unittests/Tooling/RecursiveASTVisitorTest.cpp

Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -799,7 +799,7 @@
   if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
 
-  if (Init->isWritten())
+  if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
     TRY_TO(TraverseStmt(Init->getInit()));
   return true;
 }
Index: unittests/Tooling/RecursiveASTVisitorTest.cpp
===================================================================
--- unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -385,4 +385,35 @@
       "int main() { Simple s; Simple t(s); }\n"));
 }
 
+// \brief A visitor that visits 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:
+  bool shouldVisitImplicitCode() const { return true; }
+
+  bool VisitCXXConstructExpr(CXXConstructExpr* Expr) {
+    if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) {
+      if (const CXXRecordDecl* Class = Ctor->getParent()) {
+        Match(Class->getName(), Expr->getLocation());
+      }
+    }
+    return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, VisitsImplicitMemberInitializations) {
+  ConstructExprVisitor Visitor;
+  Visitor.ExpectMatch("WithCtor", 2, 8);
+  // 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 { Simple(); WithCtor w; }; \n"
+      "int main() { Simple s; Simple t(s); }\n"));
+}
+
 } // end namespace clang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26.1.patch
Type: text/x-patch
Size: 2008 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120823/b8bd0751/attachment.bin>


More information about the cfe-commits mailing list