martong created this revision. martong added a reviewer: a_sidorin. Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp, rnkovacs. Herald added a reviewer: a.sidorin. Herald added a reviewer: shafik. Herald added a project: clang.
Currently we do not differentiate lambda classes based on their source location, so during the import we will create only one lambda class for lambdas which are defined on different slocs. We should create two distinct classes though, this commit fixes it. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D64078 Files: clang/lib/AST/ASTStructuralEquivalence.cpp clang/unittests/AST/ASTImporterTest.cpp clang/unittests/AST/StructuralEquivalenceTest.cpp
Index: clang/unittests/AST/StructuralEquivalenceTest.cpp =================================================================== --- clang/unittests/AST/StructuralEquivalenceTest.cpp +++ clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -849,6 +849,33 @@ EXPECT_TRUE(testStructuralMatch(L0, L1)); } +TEST_F(StructuralEquivalenceLambdaTest, + LambdaClassesWithDifferentSpellingLocations) { + auto t = makeDecls<LambdaExpr>("void f() { auto L = [](int){}; }", + "void f() { auto L = [](int){}; }", + Lang_CXX11, lambdaExpr(), lambdaExpr()); + CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); + CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); + EXPECT_FALSE(testStructuralMatch(L0, L1)); +} + +TEST_F(StructuralEquivalenceLambdaTest, + LambdaClassesWithDifferentExpansionLocations) { + auto t = makeDecls<LambdaExpr>( + R"( + #define LAMBDA [](){} + void f() { auto L = LAMBDA; } + )", + R"( + #define LAMBDA [](){} + void f() { auto L = LAMBDA; } + )", + Lang_CXX11, lambdaExpr(), lambdaExpr()); + CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); + CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); + EXPECT_FALSE(testStructuralMatch(L0, L1)); +} + TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) { auto t = makeNamedDecls( "struct A{ }; struct B{ }; void foo(A a, A b);", Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -5083,6 +5083,70 @@ 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<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass(); + CXXRecordDecl *FromL1 = + LastDeclMatcher<LambdaExpr>().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 <typename F0, typename F1> + void f(F0 L0 = [](){}, F1 L1 = [](){}) {} + )", + Lang_CXX11, "input0.cc"); + auto Pattern = cxxRecordDecl(isLambda()); + CXXRecordDecl *FromL0 = + FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); + CXXRecordDecl *FromL1 = + LastDeclMatcher<CXXRecordDecl>().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 <typename F0, typename F1> + void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {} + )", + Lang_CXX11, "input0.cc"); + auto Pattern = cxxRecordDecl(isLambda()); + CXXRecordDecl *FromL0 = + FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern); + CXXRecordDecl *FromL1 = + LastDeclMatcher<CXXRecordDecl>().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); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); Index: clang/lib/AST/ASTStructuralEquivalence.cpp =================================================================== --- clang/lib/AST/ASTStructuralEquivalence.cpp +++ clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1095,6 +1095,17 @@ D2->getLambdaCallOperator())) return false; + auto &SM1 = Context.FromCtx.getSourceManager(); + auto &SM2 = Context.ToCtx.getSourceManager(); + auto Loc1 = SM1.getSpellingLoc(SM1.getExpansionLoc(D1->getLocation())); + auto Loc2 = SM2.getSpellingLoc(SM2.getExpansionLoc(D2->getLocation())); + if (SM1.getSpellingLineNumber(Loc1) != SM2.getSpellingLineNumber(Loc2)) + return false; + if (SM1.getSpellingColumnNumber(Loc1) != SM2.getSpellingColumnNumber(Loc2)) + return false; + if (SM1.getFilename(Loc1) != SM2.getFilename(Loc2)) + return false; + return true; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits