<div dir="ltr">Ping. OK to commit this one?<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Sep 4, 2013 at 2:27 PM, Michael Han <span dir="ltr"><<a href="mailto:fragmentshaders@gmail.com" target="_blank">fragmentshaders@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  Sorry for long delay of this patch. Just had a chance to get back to this.<br>
<br>
  As Richard suggested, RAV now traverses function parameter variable declarations instead of relying on TypeSourceInfo of the function type to visit the parameter variable declarations of a function when RAV is set to visit implicit code. A test case of ASTMatcher is also updated because of this change.<br>

<div class="im"><br>
Hi klimek, rsmith,<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D958" target="_blank">http://llvm-reviews.chandlerc.com/D958</a><br>
<br>
CHANGE SINCE LAST DIFF<br>
</div>  <a href="http://llvm-reviews.chandlerc.com/D958?vs=2373&id=4045#toc" target="_blank">http://llvm-reviews.chandlerc.com/D958?vs=2373&id=4045#toc</a><br>
<br>
Files:<br>
  include/clang/AST/RecursiveASTVisitor.h<br>
  unittests/ASTMatchers/ASTMatchersTest.cpp<br>
  unittests/Tooling/RecursiveASTVisitorTest.cpp<br>
  unittests/Tooling/TestVisitor.h<br>
<br>
Index: include/clang/AST/RecursiveASTVisitor.h<br>
===================================================================<br>
--- include/clang/AST/RecursiveASTVisitor.h<br>
+++ include/clang/AST/RecursiveASTVisitor.h<br>
@@ -1776,7 +1776,14 @@<br>
   // including exception specifications.<br>
   if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {<br>
     TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));<br>
-  }<br>
+  } else if (getDerived().shouldVisitImplicitCode())<br>
+    // Visit parameter variable declarations of the implicit function<br>
+    // if the traverser is visiting implicit code. Parameter variable<br>
+    // declarations do not have valid TypeSourceInfo, so to visit them<br>
+    // we need to traverse the declarations explicitly.<br>
+    for (FunctionDecl::param_const_iterator I = D->param_begin(),<br>
+                                            E = D->param_end(); I != E; ++I)<br>
+      TRY_TO(TraverseDecl(*I));<br>
<br>
   if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {<br>
     // Constructor initializers.<br>
Index: unittests/ASTMatchers/ASTMatchersTest.cpp<br>
===================================================================<br>
--- unittests/ASTMatchers/ASTMatchersTest.cpp<br>
+++ unittests/ASTMatchers/ASTMatchersTest.cpp<br>
@@ -1361,8 +1361,10 @@<br>
                       ReferenceClassX));<br>
   EXPECT_TRUE(<br>
       matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));<br>
+  // The match here is on the implicit copy assignment operator code for<br>
+  // class X, not on code 'X x = y'.<br>
   EXPECT_TRUE(<br>
-      notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));<br>
+      matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));<br>
   EXPECT_TRUE(<br>
       notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));<br>
<div class="im"> }<br>
Index: unittests/Tooling/RecursiveASTVisitorTest.cpp<br>
===================================================================<br>
--- unittests/Tooling/RecursiveASTVisitorTest.cpp<br>
+++ unittests/Tooling/RecursiveASTVisitorTest.cpp<br>
</div>@@ -37,6 +37,17 @@<br>
<div class="im">  }<br>
 };<br>
<br>
+class ParmVarDeclVisitorForImplicitCode :<br>
+  public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> {<br>
+public:<br>
</div>+  bool shouldVisitImplicitCode() const { return true; }<br>
<div class="im">+<br>
+  bool VisitParmVarDecl(ParmVarDecl *ParamVar) {<br>
+    Match(ParamVar->getNameAsString(), ParamVar->getLocStart());<br>
+    return true;<br>
+  }<br>
+};<br>
+<br>
 class CXXMemberCallVisitor<br>
   : public ExpectedLocationVisitor<CXXMemberCallVisitor> {<br>
 public:<br>
</div>@@ -144,6 +155,20 @@<br>
<div class="im">   }<br>
 };<br>
<br>
+// Test RAV visits parameter variable declaration of implicit<br>
+// copy assignment operator.<br>
+TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {<br>
+  ParmVarDeclVisitorForImplicitCode Visitor;<br>
+  // Match parameter variable name of implicit copy assignment operator.<br>
+  // This parameter name does not have a valid IdentifierInfo, and shares<br>
+  // same SourceLocation with its class declaration, so we match an empty name<br>
+  // with class source location here.<br>
</div><div class="im">+  Visitor.ExpectMatch("", 1, 7);<br>
+  EXPECT_TRUE(Visitor.runOver(<br>
+    "class X {};\n"<br>
+    "void foo(X a, X b) {a = b;}"));<br>
+}<br>
+<br>
 TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) {<br>
   TypeLocVisitor Visitor;<br>
   Visitor.ExpectMatch("class X", 1, 30);<br>
</div><div class="im">Index: unittests/Tooling/TestVisitor.h<br>
===================================================================<br>
--- unittests/Tooling/TestVisitor.h<br>
+++ unittests/Tooling/TestVisitor.h<br>
@@ -31,7 +31,7 @@<br>
 /// This is a drop-in replacement for RecursiveASTVisitor itself, with the<br>
 /// additional capability of running it over a snippet of code.<br>
 ///<br>
-/// Visits template instantiations (but not implicit code) by default.<br>
+/// Visits template instantiations and implicit code by default.<br>
 template <typename T><br>
 class TestVisitor : public RecursiveASTVisitor<T> {<br>
 public:<br>
</div>@@ -56,6 +56,10 @@<br>
<div class="HOEnZb"><div class="h5">     return true;<br>
   }<br>
<br>
+  bool shouldVisitImplicitCode() const {<br>
+    return true;<br>
+  }<br>
+<br>
 protected:<br>
   virtual ASTFrontendAction* CreateTestAction() {<br>
     return new TestAction(this);<br>
</div></div></blockquote></div><br></div>