]> granicus.if.org Git - clang/commitdiff
RAV: visit copy expressions of captured variables in blocks (ObjC++11)
authorAlp Toker <alp@nuanti.com>
Thu, 26 Jun 2014 01:42:24 +0000 (01:42 +0000)
committerAlp Toker <alp@nuanti.com>
Thu, 26 Jun 2014 01:42:24 +0000 (01:42 +0000)
Patch by Mathieu Baudet.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211758 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DataRecursiveASTVisitor.h
include/clang/AST/RecursiveASTVisitor.h
unittests/Tooling/RecursiveASTVisitorTest.cpp
unittests/Tooling/TestVisitor.h

index 93a9d1d0d27f5c99f9c0b516b80cbfe00b3666cf..23c9ce554f665013ec8d1fb8120fb7b36eca1cab 100644 (file)
@@ -1207,6 +1207,11 @@ DEF_TRAVERSE_DECL(BlockDecl, {
   if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
   TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
   // This return statement makes sure the traversal of nodes in
   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
   // is skipped - don't remove it.
index c9de9e318f8355da28f2454b45e182bd42f634f0..2877642be582b428686151e3fdba2cf2fa5e1499 100644 (file)
@@ -1272,6 +1272,11 @@ DEF_TRAVERSE_DECL(BlockDecl, {
   if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
   TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
   // This return statement makes sure the traversal of nodes in
   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
   // is skipped - don't remove it.
index 6be734e6d4bc18f9f0e7a6a695109366722b8a48..a1a93a59c79b490499bc5d9566e852396fbc411a 100644 (file)
@@ -561,6 +561,16 @@ TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) {
                               LambdaDefaultCaptureVisitor::Lang_CXX11));
 }
 
+TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("x", 3, 24);
+  EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n"
+                              "void g() { \n"
+                              "  f([&](int x){ return x; }); \n"
+                              "}",
+                              DeclRefExprVisitor::Lang_OBJCXX11));
+}
+
 // Checks for lambda classes that are not marked as implicitly-generated.
 // (There should be none.)
 class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
index 2e64032cf4068e7ac07d065a20ebcd4f9f3fe5b9..ae02fb5ebbfd376066b2e4ee41fa28e83ca36c75 100644 (file)
@@ -39,7 +39,14 @@ public:
 
   virtual ~TestVisitor() { }
 
-  enum Language { Lang_C, Lang_CXX98, Lang_CXX11, Lang_OBJC, Lang_CXX=Lang_CXX98 };
+  enum Language {
+    Lang_C,
+    Lang_CXX98,
+    Lang_CXX11,
+    Lang_OBJC,
+    Lang_OBJCXX11,
+    Lang_CXX = Lang_CXX98
+  };
 
   /// \brief Runs the current AST visitor over the given code.
   bool runOver(StringRef Code, Language L = Lang_CXX) {
@@ -49,6 +56,10 @@ public:
       case Lang_CXX98: Args.push_back("-std=c++98"); break;
       case Lang_CXX11: Args.push_back("-std=c++11"); break;
       case Lang_OBJC: Args.push_back("-ObjC"); break;
+      case Lang_OBJCXX11:
+        Args.push_back("-ObjC++");
+        Args.push_back("-std=c++11");
+        break;
     }
     return tooling::runToolOnCodeWithArgs(CreateTestAction(), Code, Args);
   }