From: Craig Silverstein Date: Mon, 28 Jun 2010 15:37:14 +0000 (+0000) Subject: Add support for traversing initializer lists (in constructors), which X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f8c08843fc6c8abe03654f609e1e03fcc557855;p=clang Add support for traversing initializer lists (in constructors), which 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 --- diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0b6031058a..8512ccda28 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -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::TraverseTemplateArguments( return true; } +template +bool RecursiveASTVisitor::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