]> granicus.if.org Git - clang/commitdiff
Add support for traversing initializer lists (in constructors), which
authorCraig Silverstein <csilvers2000@yahoo.com>
Mon, 28 Jun 2010 15:37:14 +0000 (15:37 +0000)
committerCraig Silverstein <csilvers2000@yahoo.com>
Mon, 28 Jun 2010 15:37:14 +0000 (15:37 +0000)
we ignoring before.  To give access to the names on the initializer,
which aren't a type or an expr or a decl, I've introduced a new
TraverseInitializer.  By default, it just traverses on the expr that
the name is being initialized to.

Reviewed by chandlerc.  Tested via clang's 'make test'.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107008 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecursiveASTVisitor.h

index 0b6031058add1e54031dd3b7d8ba560d7dd7096b..8512ccda281db99f6f35d6889313fe1249492a33 100644 (file)
@@ -179,6 +179,14 @@ public:
   bool TraverseTemplateArguments(const TemplateArgument *Args,
                                  unsigned NumArgs);
 
+  /// \brief Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the nam.e
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseInitializer(clang::CXXBaseOrMemberInitializer* Init);
+
   // ---- Methods on Stmts ----
 
   // Declare Traverse*() for all concrete Stmt classes.
@@ -460,6 +468,16 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
   return true;
 }
 
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitializer(
+                                    clang::CXXBaseOrMemberInitializer* Init) {
+  // FIXME: recurse on TypeLoc of the base initializer if isBaseInitializer()?
+  if (Init->isWritten())
+    TRY_TO(TraverseStmt(Init->getInit()));
+  return true;
+}
+
+
 // ----------------- Type traversal -----------------
 
 // This macro makes available a variable T, the passed-in type.
@@ -803,7 +821,6 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
   })
 
 DEF_TRAVERSE_DECL(TypedefDecl, {
-    // FIXME: I *think* this returns the right type (D's immediate typedef)
     TRY_TO(TraverseType(D->getUnderlyingType()));
     // We shouldn't traverse D->getTypeForDecl(); it's a result of
     // declaring the typedef, not something that was written in the
@@ -880,6 +897,8 @@ DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
     for (unsigned I = 0; I < TAL.size(); ++I) {
       TRY_TO(TraverseTemplateArgument(TAL.get(I)));
     }
+    // FIXME: I think we only want to traverse this if it's an explicit
+    // specialization.
     TRY_TO(TraverseCXXRecordHelper(D));
   })
 
@@ -995,7 +1014,7 @@ DEF_TRAVERSE_DECL(CXXConstructorDecl, {
     for (CXXConstructorDecl::init_iterator I = D->init_begin(),
                                            E = D->init_end();
          I != E; ++I) {
-      // FIXME: figure out how to recurse on the initializers
+      TRY_TO(TraverseInitializer(*I));
     }
 
     // We skip decls_begin/decls_end, which are already covered by