[PATCH] PR16182 - Visit parameter declaration of implicitly declared copy assignment operator.

Michael Han fragmentshaders at gmail.com
Wed Sep 4 14:27:27 PDT 2013


  Sorry for long delay of this patch. Just had a chance to get back to this.

  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.

Hi klimek, rsmith,

http://llvm-reviews.chandlerc.com/D958

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D958?vs=2373&id=4045#toc

Files:
  include/clang/AST/RecursiveASTVisitor.h
  unittests/ASTMatchers/ASTMatchersTest.cpp
  unittests/Tooling/RecursiveASTVisitorTest.cpp
  unittests/Tooling/TestVisitor.h

Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1776,7 +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)) {
     // Constructor initializers.
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1361,8 +1361,10 @@
                       ReferenceClassX));
   EXPECT_TRUE(
       matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
+  // The match here is on the implicit copy assignment operator 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 {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
 }
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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D958.3.patch
Type: text/x-patch
Size: 3941 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130904/c995200e/attachment.bin>


More information about the cfe-commits mailing list