[clang] bf9ab0b - [C++20] [Modules] Emit implicit Deduction Guide for implicit class specialization
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 19:41:05 PDT 2024
Author: Chuanqi Xu
Date: 2024-09-29T10:38:05+08:00
New Revision: bf9ab0b7c3ba1d4a89a3dd9b00909ad3cfab3d48
URL: https://github.com/llvm/llvm-project/commit/bf9ab0b7c3ba1d4a89a3dd9b00909ad3cfab3d48
DIFF: https://github.com/llvm/llvm-project/commit/bf9ab0b7c3ba1d4a89a3dd9b00909ad3cfab3d48.diff
LOG: [C++20] [Modules] Emit implicit Deduction Guide for implicit class specialization
Fixed a crash for the attached test case due to we missed to emit the
deduction guide. The reason is, the deduction guide is attached to the
export-decl in the imported module. So we won't emit it by traversing the
AST of the current TU.
Added:
clang/test/Modules/lambda-definitions.cppm
Modified:
clang/lib/Serialization/ASTWriterDecl.cpp
Removed:
################################################################################
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index b9222a1b33fd74..b71684569609ac 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1785,6 +1785,18 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
if (ArgsWritten)
Record.AddASTTemplateArgumentListInfo(ArgsWritten);
+ // Mention the implicitly generated C++ deduction guide to make sure the
+ // deduction guide will be rewritten as expected.
+ //
+ // FIXME: Would it be more efficient to add a callback register function
+ // in sema to register the deduction guide?
+ if (Writer.isWritingStdCXXNamedModules()) {
+ auto Name = Context.DeclarationNames.getCXXDeductionGuideName(
+ D->getSpecializedTemplate());
+ for (auto *DG : D->getDeclContext()->noload_lookup(Name))
+ Writer.GetDeclRef(DG->getCanonicalDecl());
+ }
+
Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
}
diff --git a/clang/test/Modules/lambda-definitions.cppm b/clang/test/Modules/lambda-definitions.cppm
new file mode 100644
index 00000000000000..fb4bb8d298f0f0
--- /dev/null
+++ b/clang/test/Modules/lambda-definitions.cppm
@@ -0,0 +1,45 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/invocable.cppm -emit-module-interface -o %t/invocable.pcm
+// RUN: %clang_cc1 -std=c++20 %t/lambda.cppm -emit-module-interface -o %t/lambda.pcm -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify
+//
+// RUN: %clang_cc1 -std=c++20 %t/invocable.cppm -emit-reduced-module-interface -o %t/invocable.pcm
+// RUN: %clang_cc1 -std=c++20 %t/lambda.cppm -emit-reduced-module-interface -o %t/lambda.pcm -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify
+
+//--- invocable.cppm
+export module invocable;
+export template <class _Fn, class... _Args>
+concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
+ _Fn(__args...);
+};
+
+export template <class _Fn, class _Args>
+constexpr bool is_callable(_Fn&& __fn, _Args&& __args) {
+ return invocable<_Fn, _Args>;
+}
+
+export template <class _Fn>
+struct Callable : _Fn {
+ constexpr explicit Callable(_Fn &&__fn) : _Fn(static_cast<_Fn&&>(__fn)) {}
+
+ template <class _Args>
+ constexpr auto operator()(_Args&& __args) {
+ return _Fn(__args);
+ }
+};
+
+//--- lambda.cppm
+export module lambda;
+import invocable;
+export constexpr auto l = Callable([](auto &&x){});
+
+//--- test.cc
+// expected-no-diagnostics
+import invocable;
+import lambda;
+
+static_assert(is_callable(l, 4) == true);
More information about the cfe-commits
mailing list