[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