<div class="gmail_quote">On 28 July 2010 08:54, Craig Silverstein <span dir="ltr"><<a href="mailto:csilvers2000@yahoo.com">csilvers2000@yahoo.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Author: csilvers<br>
Date: Wed Jul 28 10:54:33 2010<br>
New Revision: 109590<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=109590&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=109590&view=rev</a><br>
Log:<br>
Add proper callbacks for DeclStmt -- we weren't recursing on<br>
the decls. This was just an oversight before; one we didn't<br>
catch because lots of information in a DeclStmt was also being<br>
traversed (redundantly) elsewhere.<br>
<br>
Once DeclStmt was cleaned up, I could clean up some of the<br>
redundant traversals found elswhere as well -- in particular,<br>
traversing the declarations inside a function as part of the<br>
function callback (instead of as part of the CompoundExpr<br>
callback that constitutes the body of the function). The old<br>
way was really weird, and led to some parts of local variable<br>
declarations (but not all) being visited twice. That is now<br>
resolved. I also was able to simplify the traversers for<br>
IfStmt/WhileStmt/etc, which used to have redundant calls to<br>
work around the fact DeclStmt wasn't working properly.<br>
<br>
While in the area, I fixed up a few more recursion-ordering<br>
issues. I try to hold to the principle that<br>
RecursiveASTVisitor visits objects in the source code in the<br>
same order they're typed. So the return-type of a variable<br>
comes before the variable-name. This still isn't perfect, but<br>
we're closer to that.<br>
<br>
Reviewed by chandlerc and wan.<br>
<br>
Modified:<br>
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=109590&r1=109589&r2=109590&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=109590&r1=109589&r2=109590&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Jul 28 10:54:33 2010<br>
@@ -1119,10 +1119,10 @@<br>
<br>
DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {<br>
// D is the "T" in something like "template<typename T> class vector;"<br>
- if (D->hasDefaultArgument())<br>
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));<br>
if (D->getTypeForDecl())<br>
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));<br>
+ if (D->hasDefaultArgument())<br>
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));<br>
})<br>
<br>
DEF_TRAVERSE_DECL(TypedefDecl, {<br>
@@ -1175,7 +1175,7 @@<br>
for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),<br>
E = D->bases_end();<br>
I != E; ++I) {<br>
- TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));<br>
+ TRY_TO(TraverseType(I->getType()));<br></blockquote><div><br></div><div>Why this change? This reverts part of the support I added for getting source location information of base declarations.</div><div><br></div>
<div>Nick</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
}<br>
// We don't traverse the friends or the conversions, as they are<br>
// already in decls_begin()/decls_end().<br>
@@ -1312,6 +1312,8 @@<br>
return true;<br>
}<br>
<br>
+ TRY_TO(TraverseType(D->getResultType()));<br>
+<br>
// If we're an explicit template specialization, iterate over the<br>
// template args that were explicitly specified.<br>
if (const FunctionTemplateSpecializationInfo *FTSI =<br>
@@ -1328,9 +1330,11 @@<br>
}<br>
}<br>
<br>
- TRY_TO(TraverseType(D->getResultType()));<br>
+ for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();<br>
+ I != E; ++I) {<br>
+ TRY_TO(TraverseDecl(*I));<br>
+ }<br>
<br>
- // FIXME: put this after the function parameters but before the body.<br>
if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) {<br>
if (D->isThisDeclarationADefinition()) {<br>
// This would be visited if we called TraverseType(D->getType())<br>
@@ -1349,8 +1353,6 @@<br>
}<br>
}<br>
<br>
- TRY_TO(TraverseDeclContextHelper(D)); // Parameters.<br>
-<br>
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {<br>
// Constructor initializers.<br>
for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),<br>
@@ -1401,9 +1403,6 @@<br>
template<typename Derived><br>
bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {<br>
TRY_TO(TraverseDeclaratorHelper(D));<br>
- // FIXME: This often double-counts -- for instance, for all local<br>
- // vars, though not for global vars -- because the initializer is<br>
- // also captured when the var-decl is in a DeclStmt.<br>
TRY_TO(TraverseStmt(D->getInit()));<br>
return true;<br>
}<br>
@@ -1418,11 +1417,13 @@<br>
<br>
DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {<br>
// A non-type template parameter, e.g. "S" in template<int S> class Foo ...<br>
- TRY_TO(TraverseStmt(D->getDefaultArgument()));<br>
TRY_TO(TraverseVarHelper(D));<br>
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));<br>
})<br>
<br>
DEF_TRAVERSE_DECL(ParmVarDecl, {<br>
+ TRY_TO(TraverseVarHelper(D));<br>
+<br>
if (D->hasDefaultArg() &&<br>
D->hasUninstantiatedDefaultArg() &&<br>
!D->hasUnparsedDefaultArg())<br>
@@ -1432,8 +1433,6 @@<br>
!D->hasUninstantiatedDefaultArg() &&<br>
!D->hasUnparsedDefaultArg())<br>
TRY_TO(TraverseStmt(D->getDefaultArg()));<br>
-<br>
- TRY_TO(TraverseVarHelper(D));<br>
})<br>
<br>
#undef DEF_TRAVERSE_DECL<br>
@@ -1476,35 +1475,36 @@<br>
})<br>
<br>
DEF_TRAVERSE_STMT(CXXCatchStmt, {<br>
- // We don't traverse S->getCaughtType(), as we are already<br>
- // traversing the exception object, which has this type.<br>
+ TRY_TO(TraverseDecl(S->getExceptionDecl()));<br>
// child_begin()/end() iterates over the handler block.<br>
})<br>
<br>
-DEF_TRAVERSE_STMT(ForStmt, {<br>
- TRY_TO(TraverseDecl(S->getConditionVariable()));<br>
- // child_begin()/end() iterates over init, cond, inc, and body stmts.<br>
- })<br>
-<br>
-DEF_TRAVERSE_STMT(IfStmt, {<br>
- TRY_TO(TraverseDecl(S->getConditionVariable()));<br>
- // child_begin()/end() iterates over cond, then, and else stmts.<br>
+DEF_TRAVERSE_STMT(DeclStmt, {<br>
+ for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();<br>
+ I != E; ++I) {<br>
+ TRY_TO(TraverseDecl(*I));<br>
+ }<br>
+ // Suppress the default iteration over child_begin/end by<br>
+ // returning. Here's why: A DeclStmt looks like 'type var [=<br>
+ // initializer]'. The decls above already traverse over the<br>
+ // initializers, so we don't have to do it again (which<br>
+ // child_begin/end would do).<br>
+ return true;<br>
})<br>
<br>
-DEF_TRAVERSE_STMT(WhileStmt, {<br>
- TRY_TO(TraverseDecl(S->getConditionVariable()));<br>
- // child_begin()/end() iterates over cond, then, and else stmts.<br>
- })<br>
<br>
// These non-expr stmts (most of them), do not need any action except<br>
// iterating over the children.<br>
DEF_TRAVERSE_STMT(BreakStmt, { })<br>
+DEF_TRAVERSE_STMT(CXXTryStmt, { })<br>
+DEF_TRAVERSE_STMT(CaseStmt, { })<br>
DEF_TRAVERSE_STMT(CompoundStmt, { })<br>
DEF_TRAVERSE_STMT(ContinueStmt, { })<br>
-DEF_TRAVERSE_STMT(CXXTryStmt, { })<br>
-DEF_TRAVERSE_STMT(DeclStmt, { })<br>
+DEF_TRAVERSE_STMT(DefaultStmt, { })<br>
DEF_TRAVERSE_STMT(DoStmt, { })<br>
+DEF_TRAVERSE_STMT(ForStmt, { })<br>
DEF_TRAVERSE_STMT(GotoStmt, { })<br>
+DEF_TRAVERSE_STMT(IfStmt, { })<br>
DEF_TRAVERSE_STMT(IndirectGotoStmt, { })<br>
DEF_TRAVERSE_STMT(LabelStmt, { })<br>
DEF_TRAVERSE_STMT(NullStmt, { })<br>
@@ -1515,10 +1515,10 @@<br>
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })<br>
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })<br>
DEF_TRAVERSE_STMT(ReturnStmt, { })<br>
-DEF_TRAVERSE_STMT(SwitchStmt, { })<br>
DEF_TRAVERSE_STMT(SwitchCase, { })<br>
-DEF_TRAVERSE_STMT(CaseStmt, { })<br>
-DEF_TRAVERSE_STMT(DefaultStmt, { })<br>
+DEF_TRAVERSE_STMT(SwitchStmt, { })<br>
+DEF_TRAVERSE_STMT(WhileStmt, { })<br>
+<br>
<br>
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {<br>
if (S->hasExplicitTemplateArgs()) {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>