Author: martong Date: Mon Jul 8 05:49:13 2019 New Revision: 365315 URL: http://llvm.org/viewvc/llvm-project?rev=365315&view=rev Log: [ASTImporter] Fix import of lambda in function param
Summary: The current import implementation fails to import the definition of a lambda class if the lambda class is defined in a function param. E.g., the lambda class below will be imported without any methods: ``` template <typename F> void f(F L = [](){}) {} ``` Reviewers: a_sidorin, a.sidorin, shafik Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64073 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=365315&r1=365314&r2=365315&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jul 8 05:49:13 2019 @@ -1708,8 +1708,18 @@ static Error setTypedefNameForAnonDecl(T Error ASTNodeImporter::ImportDefinition( RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) { if (To->getDefinition() || To->isBeingDefined()) { - if (Kind == IDK_Everything) - return ImportDeclContext(From, /*ForceImport=*/true); + if (Kind == IDK_Everything || + // In case of lambdas, the class already has a definition ptr set, but + // the contained decls are not imported yet. Also, isBeingDefined was + // set in CXXRecordDecl::CreateLambda. We must import the contained + // decls here and finish the definition. + (To->isLambda() && shouldForceImportDeclContext(Kind))) { + Error Result = ImportDeclContext(From, /*ForceImport=*/true); + // Finish the definition of the lambda, set isBeingDefined to false. + if (To->isLambda()) + To->completeDefinition(); + return Result; + } return Error::success(); } @@ -7422,19 +7432,10 @@ ExpectedStmt ASTNodeImporter::VisitLambd return ToClassOrErr.takeError(); CXXRecordDecl *ToClass = *ToClassOrErr; - // NOTE: lambda classes are created with BeingDefined flag set up. - // It means that ImportDefinition doesn't work for them and we should fill it - // manually. - if (ToClass->isBeingDefined()) - if (Error Err = ImportDeclContext(FromClass, /*ForceImport = */ true)) - return std::move(Err); - auto ToCallOpOrErr = import(E->getCallOperator()); if (!ToCallOpOrErr) return ToCallOpOrErr.takeError(); - ToClass->completeDefinition(); - SmallVector<LambdaCapture, 8> ToCaptures; ToCaptures.reserve(E->capture_size()); for (const auto &FromCapture : E->captures()) { Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=365315&r1=365314&r2=365315&view=diff ============================================================================== --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jul 8 05:49:13 2019 @@ -5083,6 +5083,45 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTes INSTANTIATE_TEST_CASE_P(ParameterizedTests, CanonicalRedeclChain, ::testing::Values(ArgVector()), ); +TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) { + Decl *FromTU = getTuDecl( + R"( + void f() { + auto L = [](){}; + } + )", + Lang_CXX11, "input0.cc"); + auto Pattern = lambdaExpr(); + CXXRecordDecl *FromL = + FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); + + auto ToL = Import(FromL, Lang_CXX11); + unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); + unsigned FromLSize = + std::distance(FromL->decls().begin(), FromL->decls().end()); + EXPECT_NE(ToLSize, 0u); + EXPECT_EQ(ToLSize, FromLSize); +} + +TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) { + Decl *FromTU = getTuDecl( + R"( + template <typename F> + void f(F L = [](){}) {} + )", + Lang_CXX11, "input0.cc"); + auto Pattern = lambdaExpr(); + CXXRecordDecl *FromL = + FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); + + auto ToL = Import(FromL, Lang_CXX11); + unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end()); + unsigned FromLSize = + std::distance(FromL->decls().begin(), FromL->decls().end()); + EXPECT_NE(ToLSize, 0u); + EXPECT_EQ(ToLSize, FromLSize); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits