<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>