From 2a38ab6aeaab8fbe3c4c74ea3ed389ca5bd04c07 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Thu, 26 Jun 2014 01:42:24 +0000 Subject: RAV: visit copy expressions of captured variables in blocks (ObjC++11) 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 | 5 +++++ include/clang/AST/RecursiveASTVisitor.h | 5 +++++ unittests/Tooling/RecursiveASTVisitorTest.cpp | 10 ++++++++++ unittests/Tooling/TestVisitor.h | 13 ++++++++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h index 93a9d1d0d2..23c9ce554f 100644 --- a/include/clang/AST/DataRecursiveASTVisitor.h +++ b/include/clang/AST/DataRecursiveASTVisitor.h @@ -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. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index c9de9e318f..2877642be5 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -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. diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp index 6be734e6d4..a1a93a59c7 100644 --- a/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -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 { diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h index 2e64032cf4..ae02fb5ebb 100644 --- a/unittests/Tooling/TestVisitor.h +++ b/unittests/Tooling/TestVisitor.h @@ -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); } -- cgit v1.2.3