| // Tests that redefinitions in different TUs could be merged correctly and the | |
| // redefinitions in the same TUs could be merged diagnosticed correctly. | |
| // | |
| // RUN: rm -rf %t | |
| // RUN: mkdir %t | |
| // RUN: split-file %s %t | |
| // | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/normal.cpp -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/M1.cppm -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/M2.cppm -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/M3.cppm -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/M.cppm -emit-module-interface -o %t/M.pcm | |
| // RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use1.cpp -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use2.cpp -verify -fsyntax-only | |
| // / Test again with reduced BMI. | |
| // RUN: %clang_cc1 -std=c++20 -I%t %t/M.cppm -emit-reduced-module-interface -o %t/M.pcm | |
| // RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use1.cpp -verify -fsyntax-only | |
| // RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use2.cpp -verify -fsyntax-only | |
| // | |
| //--- foo.h | |
| #ifndef FOO | |
| #define FOO | |
| inline void func() {} | |
| template <typename T> | |
| T templ_func(T t) { return t; } | |
| struct S {}; | |
| template <class C> | |
| struct T { C c; }; | |
| inline int v = 43; | |
| #endif | |
| // If we copy foo.h directly, there are other warnings. | |
| //--- redef.h | |
| #ifndef REDEF | |
| #define REDEF | |
| inline void func() {} | |
| template <typename T> | |
| T templ_func(T t) { return t; } | |
| struct S {}; | |
| template <class C> | |
| struct T { C c; }; | |
| inline int v = 43; | |
| #endif | |
| //--- normal.cpp | |
| #include "foo.h" | |
| #include "redef.h" | |
| // expected-error@* {{redefinition of 'func'}} | |
| // expected-error@* {{redefinition of 'templ_func'}} | |
| // expected-error@* {{redefinition of 'S'}} | |
| // expected-error@* {{redefinition of 'T'}} | |
| // expected-error@* {{redefinition of 'v'}} | |
| // expected-note@* 1+{{previous definition is here}} | |
| //--- M1.cppm | |
| // These declarations are in the same TU. The compiler should complain. | |
| module; | |
| #include "foo.h" | |
| #include "redef.h" | |
| export module M1; | |
| // expected-error@* {{redefinition of 'func'}} | |
| // expected-error@* {{redefinition of 'templ_func'}} | |
| // expected-error@* {{redefinition of 'S'}} | |
| // expected-error@* {{redefinition of 'T'}} | |
| // expected-error@* {{redefinition of 'v'}} | |
| // expected-note@* 1+{{previous definition is here}} | |
| //--- M2.cppm | |
| // These declarations are in the same TU and the redefinitions are in the named modules. | |
| // The compiler should complain. | |
| module; | |
| #include "foo.h" | |
| export module M2; | |
| #include "redef.h" | |
| // FIXME: The diagnostic message looks not so good. | |
| // | |
| // expected-error@* {{declaration of 'func' in module M2 follows declaration in the global module}} | |
| // expected-error@* {{declaration of 'templ_func' in module M2 follows declaration in the global module}} | |
| // expected-error@* {{redefinition of 'S'}} | |
| // expected-error@* {{redefinition of 'T'}} | |
| // expected-error@* {{declaration of 'v' in module M2 follows declaration in the global module}} | |
| // expected-note@* 1+{{previous definition is here}} | |
| // expected-note@* 1+{{previous declaration is here}} | |
| //--- M3.cppm | |
| // These declarations are in the same TU. The compiler should complain. | |
| export module M3; | |
| #include "foo.h" | |
| #include "redef.h" | |
| // expected-error@* {{redefinition of 'func'}} | |
| // expected-error@* {{redefinition of 'templ_func'}} | |
| // expected-error@* {{redefinition of 'S'}} | |
| // expected-error@* {{redefinition of 'T'}} | |
| // expected-error@* {{redefinition of 'v'}} | |
| // expected-note@* 1+{{previous definition is here}} | |
| //--- M.cppm | |
| module; | |
| #include "foo.h" | |
| export module M; | |
| export using ::func; | |
| export using ::templ_func; | |
| export using ::S; | |
| export using ::T; | |
| export using ::v; | |
| //--- Use1.cpp | |
| // These declarations are not in the same TU. The compiler shouldn't complain. | |
| // expected-no-diagnostics | |
| #include "foo.h" | |
| import M; | |
| //--- Use2.cpp | |
| // These declarations are not in the same TU. The compiler shouldn't complain. | |
| // expected-no-diagnostics | |
| import M; | |
| #include "foo.h" |