xref: /llvm-project/clang/test/Modules/redefinition-merges.cppm (revision da00c60dae0040185dc45039c4397f6e746548e9)
1// Tests that redefinitions in different TUs could be merged correctly and the
2// redefinitions in the same TUs could be merged diagnosticed correctly.
3//
4// RUN: rm -rf %t
5// RUN: mkdir %t
6// RUN: split-file %s %t
7//
8// RUN: %clang_cc1 -std=c++20 -I%t %t/normal.cpp -verify -fsyntax-only
9// RUN: %clang_cc1 -std=c++20 -I%t %t/M1.cppm -verify -fsyntax-only
10// RUN: %clang_cc1 -std=c++20 -I%t %t/M2.cppm -verify -fsyntax-only
11// RUN: %clang_cc1 -std=c++20 -I%t %t/M3.cppm -verify -fsyntax-only
12// RUN: %clang_cc1 -std=c++20 -I%t %t/M.cppm -emit-module-interface -o %t/M.pcm
13// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use1.cpp -verify -fsyntax-only
14// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use2.cpp -verify -fsyntax-only
15
16// / Test again with reduced BMI.
17// RUN: %clang_cc1 -std=c++20 -I%t %t/M.cppm -emit-reduced-module-interface -o %t/M.pcm
18// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use1.cpp -verify -fsyntax-only
19// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use2.cpp -verify -fsyntax-only
20
21//
22//--- foo.h
23#ifndef FOO
24#define FOO
25inline void func() {}
26template <typename T>
27T templ_func(T t) { return t; }
28struct S {};
29template <class C>
30struct T { C c; };
31inline int v = 43;
32#endif
33
34// If we copy foo.h directly, there are other warnings.
35//--- redef.h
36#ifndef REDEF
37#define REDEF
38inline void func() {}
39template <typename T>
40T templ_func(T t) { return t; }
41struct S {};
42template <class C>
43struct T { C c; };
44inline int v = 43;
45#endif
46
47//--- normal.cpp
48#include "foo.h"
49#include "redef.h"
50
51// expected-error@* {{redefinition of 'func'}}
52// expected-error@* {{redefinition of 'templ_func'}}
53// expected-error@* {{redefinition of 'S'}}
54// expected-error@* {{redefinition of 'T'}}
55// expected-error@* {{redefinition of 'v'}}
56// expected-note@* 1+{{previous definition is here}}
57
58//--- M1.cppm
59// These declarations are in the same TU. The compiler should complain.
60module;
61#include "foo.h"
62#include "redef.h"
63export module M1;
64
65// expected-error@* {{redefinition of 'func'}}
66// expected-error@* {{redefinition of 'templ_func'}}
67// expected-error@* {{redefinition of 'S'}}
68// expected-error@* {{redefinition of 'T'}}
69// expected-error@* {{redefinition of 'v'}}
70// expected-note@* 1+{{previous definition is here}}
71
72//--- M2.cppm
73// These declarations are in the same TU and the redefinitions are in the named modules.
74// The compiler should complain.
75module;
76#include "foo.h"
77export module M2;
78#include "redef.h"
79
80// FIXME: The diagnostic message looks not so good.
81//
82// expected-error@* {{declaration of 'func' in module M2 follows declaration in the global module}}
83// expected-error@* {{declaration of 'templ_func' in module M2 follows declaration in the global module}}
84// expected-error@* {{redefinition of 'S'}}
85// expected-error@* {{redefinition of 'T'}}
86// expected-error@* {{declaration of 'v' in module M2 follows declaration in the global module}}
87// expected-note@* 1+{{previous definition is here}}
88// expected-note@* 1+{{previous declaration is here}}
89
90//--- M3.cppm
91// These declarations are in the same TU. The compiler should complain.
92export module M3;
93#include "foo.h"
94#include "redef.h"
95
96// expected-error@* {{redefinition of 'func'}}
97// expected-error@* {{redefinition of 'templ_func'}}
98// expected-error@* {{redefinition of 'S'}}
99// expected-error@* {{redefinition of 'T'}}
100// expected-error@* {{redefinition of 'v'}}
101// expected-note@* 1+{{previous definition is here}}
102
103//--- M.cppm
104module;
105#include "foo.h"
106export module M;
107export using ::func;
108export using ::templ_func;
109export using ::S;
110export using ::T;
111export using ::v;
112
113//--- Use1.cpp
114// These declarations are not in the same TU. The compiler shouldn't complain.
115// expected-no-diagnostics
116#include "foo.h"
117import M;
118
119//--- Use2.cpp
120// These declarations are not in the same TU. The compiler shouldn't complain.
121// expected-no-diagnostics
122import M;
123#include "foo.h"
124