[cfe-commits] r158002 - in /cfe/trunk: include/clang/AST/RecursiveASTVisitor.h unittests/Tooling/RecursiveASTVisitorTest.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Jun 5 09:18:26 PDT 2012
Author: rsmith
Date: Tue Jun 5 11:18:26 2012
New Revision: 158002
URL: http://llvm.org/viewvc/llvm-project?rev=158002&view=rev
Log:
RecursiveASTVisitor: add ability to visit implicit declarations. Patch by
James Dennett!
Modified:
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=158002&r1=158001&r2=158002&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jun 5 11:18:26 2012
@@ -148,6 +148,10 @@
/// TypeLocs.
bool shouldWalkTypesOfTypeLocs() const { return true; }
+ /// \brief Return whether this visitor should recurse into implicit
+ /// declarations, e.g., implicit constructors and destructors.
+ bool shouldVisitImplicitDeclarations() const { return false; }
+
/// \brief Return whether \param S should be traversed using data recursion
/// to avoid a stack overflow with extreme cases.
bool shouldUseDataRecursionFor(Stmt *S) const {
@@ -601,10 +605,9 @@
if (!D)
return true;
- // As a syntax visitor, we want to ignore declarations for
- // implicitly-defined declarations (ones not typed explicitly by the
- // user).
- if (D->isImplicit())
+ // As a syntax visitor, by default we want to ignore declarations for
+ // implicit declarations (ones not typed explicitly by the user).
+ if (!getDerived().shouldVisitImplicitDeclarations() && D->isImplicit())
return true;
switch (D->getKind()) {
@@ -1697,7 +1700,9 @@
// FunctionNoProtoType or FunctionProtoType, or a typedef. This
// also covers the return type and the function parameters,
// including exception specifications.
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ if (clang::TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+ }
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
Modified: cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp?rev=158002&r1=158001&r2=158002&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RecursiveASTVisitorTest.cpp Tue Jun 5 11:18:26 2012
@@ -448,4 +448,31 @@
"template<template <typename> class T> class Y {};\n"));
}
+// A visitor that visits implicit declarations and matches constructors.
+class ImplicitCtorVisitor
+ : public ExpectedLocationVisitor<ImplicitCtorVisitor> {
+public:
+ bool shouldVisitImplicitDeclarations() const { return true; }
+
+ bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) {
+ if (Ctor->isImplicit()) { // Was not written in source code
+ if (const CXXRecordDecl* Class = Ctor->getParent()) {
+ Match(Class->getName(), Ctor->getLocation());
+ }
+ }
+ return true;
+ }
+};
+
+TEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) {
+ ImplicitCtorVisitor Visitor;
+ Visitor.ExpectMatch("Simple", 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
More information about the cfe-commits
mailing list