massberg created this revision. massberg added a reviewer: ilya-biryukov. Herald added a project: All. massberg requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When a new init capture type for a lamdba expression is created, one has to pass whether it is a reference type or not. This information is stored in the old var decl type of the captured variable. However, if the type of the old var decl is a `PackExpansionType`, the information whether it is a refernece type is stored in the pattern stored at the type. Add test that lambda captures with var decls which are reference types are created in the AST. Fixes #49266 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D139125 Files: clang/lib/Sema/TreeTransform.h clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -2306,6 +2306,30 @@ hasName("cc"), hasInitializer(integerLiteral(equals(1)))))))))); } +TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfReferenceType) { + if (!GetParam().isCXX20OrLater()) { + return; + } + auto matcher = lambdaExpr(hasAnyCapture( + lambdaCapture(capturesVar(varDecl(hasType(referenceType())))))); + EXPECT_TRUE(matches("template <class ...T> void f(T &...args) {" + " [&...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); + EXPECT_FALSE(matches("template <class ...T> void f(T &...args) {" + " [...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); +} + TEST(ASTMatchersTestObjC, ObjCMessageCalees) { StatementMatcher MessagingFoo = objcMessageExpr(callee(objcMethodDecl(hasName("foo")))); Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -13145,9 +13145,15 @@ } Expr *NewExprInit = NewExprInitResult.get(); + bool isReferenceType = (isa<PackExpansionType>(OldVD->getType()) + ? cast<PackExpansionType>(OldVD->getType()) + ->getPattern() + ->isReferenceType() + : OldVD->getType()->isReferenceType()); + QualType NewInitCaptureType = getSema().buildLambdaInitCaptureInitialization( - C->getLocation(), OldVD->getType()->isReferenceType(), + C->getLocation(), isReferenceType, EllipsisLoc, NumExpansions, OldVD->getIdentifier(), cast<VarDecl>(C->getCapturedVar())->getInitStyle() != VarDecl::CInit,
Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -2306,6 +2306,30 @@ hasName("cc"), hasInitializer(integerLiteral(equals(1)))))))))); } +TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfReferenceType) { + if (!GetParam().isCXX20OrLater()) { + return; + } + auto matcher = lambdaExpr(hasAnyCapture( + lambdaCapture(capturesVar(varDecl(hasType(referenceType())))))); + EXPECT_TRUE(matches("template <class ...T> void f(T &...args) {" + " [&...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); + EXPECT_FALSE(matches("template <class ...T> void f(T &...args) {" + " [...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); +} + TEST(ASTMatchersTestObjC, ObjCMessageCalees) { StatementMatcher MessagingFoo = objcMessageExpr(callee(objcMethodDecl(hasName("foo")))); Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -13145,9 +13145,15 @@ } Expr *NewExprInit = NewExprInitResult.get(); + bool isReferenceType = (isa<PackExpansionType>(OldVD->getType()) + ? cast<PackExpansionType>(OldVD->getType()) + ->getPattern() + ->isReferenceType() + : OldVD->getType()->isReferenceType()); + QualType NewInitCaptureType = getSema().buildLambdaInitCaptureInitialization( - C->getLocation(), OldVD->getType()->isReferenceType(), + C->getLocation(), isReferenceType, EllipsisLoc, NumExpansions, OldVD->getIdentifier(), cast<VarDecl>(C->getCapturedVar())->getInitStyle() != VarDecl::CInit,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits