[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