Index: cfe/trunk/lib/AST/ASTImporter.cpp =================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp +++ cfe/trunk/lib/AST/ASTImporter.cpp @@ -2633,7 +2633,7 @@ // We may already have a record of the same name; try to find and match it. RecordDecl *PrevDecl = nullptr; - if (!DC->isFunctionOrMethod()) { + if (!DC->isFunctionOrMethod() && !D->isLambda()) { SmallVector ConflictingDecls; auto FoundDecls = Importer.findDeclsInToCtx(DC, SearchName); Index: cfe/trunk/unittests/AST/ASTImporterTest.cpp =================================================================== --- cfe/trunk/unittests/AST/ASTImporterTest.cpp +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp @@ -5644,6 +5644,117 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, CanonicalRedeclChain, ::testing::Values(ArgVector()), ); +TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) { + Decl *FromTU = getTuDecl( + R"( + void f() { + auto L0 = [](){}; + auto L1 = [](){}; + } + )", + Lang_CXX11, "input0.cc"); + auto Pattern = lambdaExpr(); + CXXRecordDecl *FromL0 = + FirstDeclMatcher().match(FromTU, Pattern)->getLambdaClass(); + CXXRecordDecl *FromL1 = + LastDeclMatcher().match(FromTU, Pattern)->getLambdaClass(); + ASSERT_NE(FromL0, FromL1); + + CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); + CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); + EXPECT_NE(ToL0, ToL1); +} + +TEST_P(ASTImporterOptionSpecificTestBase, + LambdasInFunctionParamsAreDifferentiated) { + Decl *FromTU = getTuDecl( + R"( + template + void f(F0 L0 = [](){}, F1 L1 = [](){}) {} + )", + Lang_CXX11, "input0.cc"); + auto Pattern = cxxRecordDecl(isLambda()); + CXXRecordDecl *FromL0 = + FirstDeclMatcher().match(FromTU, Pattern); + CXXRecordDecl *FromL1 = + LastDeclMatcher().match(FromTU, Pattern); + ASSERT_NE(FromL0, FromL1); + + CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); + CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); + ASSERT_NE(ToL0, ToL1); +} + +TEST_P(ASTImporterOptionSpecificTestBase, + LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) { + Decl *FromTU = getTuDecl( + R"( + #define LAMBDA [](){} + template + void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} + )", + Lang_CXX11, "input0.cc"); + auto Pattern = cxxRecordDecl(isLambda()); + CXXRecordDecl *FromL0 = + FirstDeclMatcher().match(FromTU, Pattern); + CXXRecordDecl *FromL1 = + LastDeclMatcher().match(FromTU, Pattern); + ASSERT_NE(FromL0, FromL1); + + Import(FromL0, Lang_CXX11); + Import(FromL1, Lang_CXX11); + CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11); + CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11); + ASSERT_NE(ToL0, ToL1); +} + +TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) { + Decl *FromTU = getTuDecl( + R"( + void f() { + auto x = []{} = {}; auto x2 = x; + } + )", + Lang_CXX2a, "input0.cc"); + auto FromF = FirstDeclMatcher().match( + FromTU, functionDecl(hasName("f"))); + // We have only one lambda class. + ASSERT_EQ( + DeclCounter().match(FromTU, cxxRecordDecl(isLambda())), + 1u); + + FunctionDecl *ToF = Import(FromF, Lang_CXX2a); + EXPECT_TRUE(ToF); + TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); + // We have only one lambda class after the import. + EXPECT_EQ(DeclCounter().match(ToTU, cxxRecordDecl(isLambda())), + 1u); +} + +TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) { + Decl *FromTU = getTuDecl( + R"( + void f() { + auto x = []{} = {}; + auto xb = []{} = {}; + } + )", + Lang_CXX2a, "input0.cc"); + auto FromF = FirstDeclMatcher().match( + FromTU, functionDecl(hasName("f"))); + // We have two lambda classes. + ASSERT_EQ( + DeclCounter().match(FromTU, cxxRecordDecl(isLambda())), + 2u); + + FunctionDecl *ToF = Import(FromF, Lang_CXX2a); + EXPECT_TRUE(ToF); + TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl(); + // We have two lambda classes after the import. + EXPECT_EQ(DeclCounter().match(ToTU, cxxRecordDecl(isLambda())), + 2u); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, );