https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/103036
Close https://github.com/llvm/llvm-project/issues/102721 Previously we tried to merge lambdas between TUs. But we may still meet problems if we import and then include the headers containing the same lambda. The solution in this patch is, when we assigned a lambda numbering in a sema, try to see if there is already a same lambda imported. If yes, try to merge them. >From f7610cd9185e33643f9bb2012be9986d8606df63 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu <yedeng...@linux.alibaba.com> Date: Mon, 12 Aug 2024 15:08:26 +0800 Subject: [PATCH] [C++20] [Modules] Merge lambdas from Sema to imported one Close https://github.com/llvm/llvm-project/issues/102721 Previously we tried to merge lambdas between TUs. But we may still meet problems if we import and then include the headers containing the same lambda. The solution in this patch is, when we assigned a lambda numbering in a sema, try to see if there is already a same lambda imported. If yes, try to merge them. --- clang/lib/Serialization/ASTReader.cpp | 11 -------- clang/lib/Serialization/ASTReaderDecl.cpp | 28 +++++++++++++++++++ clang/test/Modules/pr102721.cppm | 33 +++++++++++++++++++++++ 3 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 clang/test/Modules/pr102721.cppm diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 511e2df7ad3230..4e4f1780003c5c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8962,17 +8962,6 @@ void ASTReader::ReadLateParsedTemplates( LateParsedTemplates.clear(); } -void ASTReader::AssignedLambdaNumbering(const CXXRecordDecl *Lambda) { - if (Lambda->getLambdaContextDecl()) { - // Keep track of this lambda so it can be merged with another lambda that - // is loaded later. - LambdaDeclarationsForMerging.insert( - {{Lambda->getLambdaContextDecl()->getCanonicalDecl(), - Lambda->getLambdaIndexInContext()}, - const_cast<CXXRecordDecl *>(Lambda)}); - } -} - void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a9199f7e50f5dc..c8a0791bb89502 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -4506,6 +4506,34 @@ void ASTReader::loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D, ModuleMgr.visit(Visitor); } +void ASTReader::AssignedLambdaNumbering(const CXXRecordDecl *Lambda) { + if (Lambda->getLambdaContextDecl()) { + auto ContextAndIndexPair = std::make_pair<const Decl *, unsigned>( + Lambda->getLambdaContextDecl()->getCanonicalDecl(), + Lambda->getLambdaIndexInContext()); + + auto Iter = LambdaDeclarationsForMerging.find(ContextAndIndexPair); + // If we import first and then include second, try to merge the second + // one with the first one. + if (Iter != LambdaDeclarationsForMerging.end() && + Iter->second->isFromASTFile()) { + NamedDecl *Slot = Iter->second; + ASTDeclMerger Merger(*this); + // The lambda shouldn't be a key declaration as the lambda wouldn't + // be a canonical decl for its owning module. + Merger.mergeRedeclarableImpl(const_cast<CXXRecordDecl *>(Lambda), + cast<TagDecl>(Slot), + /*KeyDeclID*/ GlobalDeclID()); + return; + } + + // Keep track of this lambda so it can be merged with another lambda that + // is loaded later. + LambdaDeclarationsForMerging.insert( + {ContextAndIndexPair, const_cast<CXXRecordDecl *>(Lambda)}); + } +} + template<typename DeclT, typename Fn> static void forAllLaterRedecls(DeclT *D, Fn F) { F(D); diff --git a/clang/test/Modules/pr102721.cppm b/clang/test/Modules/pr102721.cppm new file mode 100644 index 00000000000000..6a84393bcbd1f6 --- /dev/null +++ b/clang/test/Modules/pr102721.cppm @@ -0,0 +1,33 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-module-interface -o %t/b.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/test.cc -fsyntax-only -verify \ +// RUN: -fprebuilt-module-path=%t + +//--- foo.h +inline auto x = []{}; + +//--- a.cppm +module; +#include "foo.h" +export module a; +export using ::x; + +//--- b.cppm +module; +import a; +#include "foo.h" +export module b; +export using ::x; + +//--- test.cc +// expected-no-diagnostics +import a; +import b; +void test() { + x(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits