[NFC] [C++20] [Modules] Add merge-records test for C++20 Modules
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>
Thu, 15 Dec 2022 07:22:44 +0000 (15:22 +0800)
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>
Thu, 15 Dec 2022 07:32:46 +0000 (15:32 +0800)
Merging declarations and checking ODR violations are a big part in the
implementation of modules. Currently, the implementation of C++20
Modules share a big part with the Clang modules and the ObjC modules for
the clang's serializer/deserailizer.

This is good. We saved a lot of time by this. And a lot of C++20
Modules's codes can run due to reuse it. However, the bad side is that
we lack a lot of tests about merging declarations and ODR checks for
C++20 Modules. It is not stable on the long run. So the patch tries to
add a test for it. This should be a long-term goal for C++20 modules.
(To add the test we shoudl add).

clang/test/Modules/merge-records.cppm [new file with mode: 0644]

diff --git a/clang/test/Modules/merge-records.cppm b/clang/test/Modules/merge-records.cppm
new file mode 100644 (file)
index 0000000..dee41bd
--- /dev/null
@@ -0,0 +1,97 @@
+// 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 -fprebuilt-module-path=%t %t/Use.cpp \
+// RUN:     -fsyntax-only -verify
+//
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -emit-module-interface -o %t/B.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use.cpp \
+// RUN:     -fsyntax-only -verify -DIMPORT_MODULE_B
+
+//--- records.h
+struct A {
+    int a;
+    int b;
+    int c;
+};
+
+struct NoNameEntity {
+    struct {
+        int a;
+        int b;
+        int c;
+    };
+};
+
+union U {
+    int a;
+    int b;
+    int c;
+};
+
+//--- another_records.h
+struct A {
+    int a;
+    double b;
+    float c;
+};
+
+struct NoNameEntity {
+    struct {
+        int a;
+        unsigned b;
+        long c;
+    };
+};
+
+union U {
+    int a;
+    double b;
+    short c;
+};
+
+//--- A.cppm
+module;
+#include "records.h"
+export module A;
+export using ::A;
+export using ::NoNameEntity;
+export using ::U;
+export constexpr A a_a{};
+export constexpr NoNameEntity NoName_a{};
+export constexpr U u_a{};
+
+//--- B.cppm
+module;
+#include "records.h"
+export module B;
+export using ::A;
+export using ::NoNameEntity;
+export using ::U;
+export constexpr A a_b{};
+export constexpr NoNameEntity NoName_b{};
+export constexpr U u_b{};
+
+//--- Use.cpp
+// expected-no-diagnostics
+import A;
+#ifdef IMPORT_MODULE_B
+import B;
+static_assert(__is_same(decltype(a_a), decltype(a_b)));
+static_assert(__is_same(decltype(NoName_a), decltype(NoName_b)));
+static_assert(__is_same(decltype(u_a), decltype(u_b)));
+#endif
+void use1() {
+    A a; // Shouldn't be ambiguous after import B;
+    a.a = 43;
+    a.b = 44;
+    a.c = 45;
+    NoNameEntity Anonymous;
+    Anonymous.a = 46;
+    Anonymous.b = 47;
+    Anonymous.c = 48;
+    U u;
+    u.a = 43;
+}