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