[PATCH] PR16182 - Visit parameter declaration of implicitly declared copy assignment operator.
Michael Han
fragmentshaders at gmail.com
Tue Sep 10 15:41:12 PDT 2013
Update patch based on comments from Richard.
Hi klimek, rsmith,
http://llvm-reviews.chandlerc.com/D958
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D958?vs=4045&id=4182#toc
Files:
unittests/Tooling/RecursiveASTVisitorTest.cpp
unittests/Tooling/TestVisitor.h
unittests/ASTMatchers/ASTMatchersTest.cpp
include/clang/AST/RecursiveASTVisitor.h
Index: unittests/Tooling/RecursiveASTVisitorTest.cpp
===================================================================
--- unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -37,6 +37,17 @@
}
};
+class ParmVarDeclVisitorForImplicitCode :
+ public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> {
+public:
+ bool shouldVisitImplicitCode() const { return true; }
+
+ bool VisitParmVarDecl(ParmVarDecl *ParamVar) {
+ Match(ParamVar->getNameAsString(), ParamVar->getLocStart());
+ return true;
+ }
+};
+
class CXXMemberCallVisitor
: public ExpectedLocationVisitor<CXXMemberCallVisitor> {
public:
@@ -144,6 +155,20 @@
}
};
+// Test RAV visits parameter variable declaration of implicit
+// copy assignment operator.
+TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {
+ ParmVarDeclVisitorForImplicitCode Visitor;
+ // Match parameter variable name of implicit copy assignment operator.
+ // This parameter name does not have a valid IdentifierInfo, and shares
+ // same SourceLocation with its class declaration, so we match an empty name
+ // with class source location here.
+ Visitor.ExpectMatch("", 1, 7);
+ EXPECT_TRUE(Visitor.runOver(
+ "class X {};\n"
+ "void foo(X a, X b) {a = b;}"));
+}
+
TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) {
TypeLocVisitor Visitor;
Visitor.ExpectMatch("class X", 1, 30);
Index: unittests/Tooling/TestVisitor.h
===================================================================
--- unittests/Tooling/TestVisitor.h
+++ unittests/Tooling/TestVisitor.h
@@ -31,7 +31,7 @@
/// This is a drop-in replacement for RecursiveASTVisitor itself, with the
/// additional capability of running it over a snippet of code.
///
-/// Visits template instantiations (but not implicit code) by default.
+/// Visits template instantiations and implicit code by default.
template <typename T>
class TestVisitor : public RecursiveASTVisitor<T> {
public:
@@ -56,6 +56,10 @@
return true;
}
+ bool shouldVisitImplicitCode() const {
+ return true;
+ }
+
protected:
virtual ASTFrontendAction* CreateTestAction() {
return new TestAction(this);
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1361,9 +1361,13 @@
ReferenceClassX));
EXPECT_TRUE(
matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
+ // The match here is on the implicit copy constructor code for
+ // class X, not on code 'X x = y'.
EXPECT_TRUE(
- notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
+ matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
EXPECT_TRUE(
+ notMatches("class X {}; extern X x;", ReferenceClassX));
+ EXPECT_TRUE(
notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
}
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1776,6 +1776,14 @@
// including exception specifications.
if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+ } else if (getDerived().shouldVisitImplicitCode()) {
+ // Visit parameter variable declarations of the implicit function
+ // if the traverser is visiting implicit code. Parameter variable
+ // declarations do not have valid TypeSourceInfo, so to visit them
+ // we need to traverse the declarations explicitly.
+ for (FunctionDecl::param_const_iterator I = D->param_begin(),
+ E = D->param_end(); I != E; ++I)
+ TRY_TO(TraverseDecl(*I));
}
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D958.4.patch
Type: text/x-patch
Size: 3983 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130910/2b53a9ba/attachment.bin>
More information about the cfe-commits
mailing list