// Clear and create directories // RUN: rm -rf %t // RUN: mkdir %t // RUN: mkdir %t/cache // RUN: mkdir %t/Inputs // Build first header file // RUN: echo "#define FIRST" >> %t/Inputs/first.h // RUN: cat %s >> %t/Inputs/first.h // Build second header file // RUN: echo "#define SECOND" >> %t/Inputs/second.h // RUN: cat %s >> %t/Inputs/second.h // Build module map file // RUN: echo "module FirstModule {" >> %t/Inputs/module.map // RUN: echo " header \"first.h\"" >> %t/Inputs/module.map // RUN: echo "}" >> %t/Inputs/module.map // RUN: echo "module SecondModule {" >> %t/Inputs/module.map // RUN: echo " header \"second.h\"" >> %t/Inputs/module.map // RUN: echo "}" >> %t/Inputs/module.map // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z #if !defined(FIRST) && !defined(SECOND) #include "first.h" #include "second.h" #endif namespace AccessSpecifiers { #if defined(FIRST) struct S1 { }; #elif defined(SECOND) struct S1 { private: }; #else S1 s1; // expected-error@second.h:* {{'AccessSpecifiers::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found end of class}} #endif #if defined(FIRST) struct S2 { public: }; #elif defined(SECOND) struct S2 { protected: }; #else S2 s2; // expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif } // namespace AccessSpecifiers namespace StaticAssert { #if defined(FIRST) struct S1 { static_assert(1 == 1, "First"); }; #elif defined(SECOND) struct S1 { static_assert(1 == 1, "Second"); }; #else S1 s1; // expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}} // expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}} #endif #if defined(FIRST) struct S2 { static_assert(2 == 2, "Message"); }; #elif defined(SECOND) struct S2 { static_assert(2 == 2); }; #else S2 s2; // expected-error@second.h:* {{'StaticAssert::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with no message}} // expected-note@first.h:* {{but in 'FirstModule' found static assert with message}} #endif #if defined(FIRST) struct S3 { static_assert(3 == 3, "Message"); }; #elif defined(SECOND) struct S3 { static_assert(3 != 4, "Message"); }; #else S3 s3; // expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}} // expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}} #endif #if defined(FIRST) struct S4 { static_assert(4 == 4, "Message"); }; #elif defined(SECOND) struct S4 { public: }; #else S4 s4; // expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found static assert}} #endif } namespace Field { #if defined(FIRST) struct S1 { int x; private: int y; }; #elif defined(SECOND) struct S1 { int x; int y; }; #else S1 s1; // expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}} // expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} #endif #if defined(FIRST) struct S2 { int x; int y; }; #elif defined(SECOND) struct S2 { int y; int x; }; #else S2 s2; // expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x'}} #endif #if defined(FIRST) struct S3 { double x; }; #elif defined(SECOND) struct S3 { int x; }; #else S3 s3; // expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif #if defined(FIRST) typedef int A; struct S4 { A x; }; struct S5 { A x; }; #elif defined(SECOND) typedef int B; struct S4 { B x; }; struct S5 { int x; }; #else S4 s4; // expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'Field::B' (aka 'int')}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}} S5 s5; // expected-error@second.h:* {{'Field::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}} #endif #if defined(FIRST) struct S6 { unsigned x; }; #elif defined(SECOND) struct S6 { unsigned x : 1; }; #else S6 s6; // expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}} // expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}} #endif #if defined(FIRST) struct S7 { unsigned x : 2; }; #elif defined(SECOND) struct S7 { unsigned x : 1; }; #else S7 s7; // expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}} // expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}} #endif #if defined(FIRST) struct S8 { unsigned x : 2; }; #elif defined(SECOND) struct S8 { unsigned x : 1 + 1; }; #else S8 s8; // expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}} // expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}} #endif #if defined(FIRST) struct S9 { mutable int x; }; #elif defined(SECOND) struct S9 { int x; }; #else S9 s9; // expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}} // expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}} #endif #if defined(FIRST) struct S10 { unsigned x = 5; }; #elif defined(SECOND) struct S10 { unsigned x; }; #else S10 s10; // expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}} #endif #if defined(FIRST) struct S11 { unsigned x = 5; }; #elif defined(SECOND) struct S11 { unsigned x = 7; }; #else S11 s11; // expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}} #endif #if defined(FIRST) struct S12 { unsigned x[5]; }; #elif defined(SECOND) struct S12 { unsigned x[7]; }; #else S12 s12; // expected-error@first.h:* {{'Field::S12::x' from module 'FirstModule' is not present in definition of 'Field::S12' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif #if defined(FIRST) struct S13 { unsigned x[7]; }; #elif defined(SECOND) struct S13 { double x[7]; }; #else S13 s13; // expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif } // namespace Field namespace Method { #if defined(FIRST) struct S1 { void A() {} }; #elif defined(SECOND) struct S1 { private: void A() {} }; #else S1 s1; // expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found method}} #endif #if defined(FIRST) struct S2 { void A() {} void B() {} }; #elif defined(SECOND) struct S2 { void B() {} void A() {} }; #else S2 s2; // expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A'}} #endif #if defined(FIRST) struct S3 { static void A() {} void A(int) {} }; #elif defined(SECOND) struct S3 { void A(int) {} static void A() {} }; #else S3 s3; // expected-error@second.h:* {{'Method::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not static}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}} #endif #if defined(FIRST) struct S4 { virtual void A() {} void B() {} }; #elif defined(SECOND) struct S4 { void A() {} virtual void B() {} }; #else S4 s4; // expected-error@second.h:* {{'Method::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not virtual}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}} #endif #if defined(FIRST) struct S5 { virtual void A() = 0; virtual void B() {}; }; #elif defined(SECOND) struct S5 { virtual void A() {} virtual void B() = 0; }; #else S5 *s5; // expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}} #endif #if defined(FIRST) struct S6 { inline void A() {} }; #elif defined(SECOND) struct S6 { void A() {} }; #else S6 s6; // expected-error@second.h:* {{'Method::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not inline}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}} #endif #if defined(FIRST) struct S7 { void A() volatile {} void A() {} }; #elif defined(SECOND) struct S7 { void A() {} void A() volatile {} }; #else S7 s7; // expected-error@second.h:* {{'Method::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not volatile}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}} #endif #if defined(FIRST) struct S8 { void A() const {} void A() {} }; #elif defined(SECOND) struct S8 { void A() {} void A() const {} }; #else S8 s8; // expected-error@second.h:* {{'Method::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not const}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}} #endif #if defined(FIRST) struct S9 { void A(int x) {} void A(int x, int y) {} }; #elif defined(SECOND) struct S9 { void A(int x, int y) {} void A(int x) {} }; #else S9 s9; // expected-error@second.h:* {{'Method::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' that has 2 parameters}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' that has 1 parameter}} #endif #if defined(FIRST) struct S10 { void A(int x) {} void A(float x) {} }; #elif defined(SECOND) struct S10 { void A(float x) {} void A(int x) {} }; #else S10 s10; // expected-error@second.h:* {{'Method::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'float'}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int'}} #endif #if defined(FIRST) struct S11 { void A(int x) {} }; #elif defined(SECOND) struct S11 { void A(int y) {} }; #else S11 s11; // expected-error@second.h:* {{'Method::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter named 'y'}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter named 'x'}} #endif #if defined(FIRST) struct S12 { void A(int x) {} }; #elif defined(SECOND) struct S12 { void A(int x = 1) {} }; #else S12 s12; // expected-error@second.h:* {{'Method::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter without a default argument}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a default argument}} #endif #if defined(FIRST) struct S13 { void A(int x = 1 + 0) {} }; #elif defined(SECOND) struct S13 { void A(int x = 1) {} }; #else S13 s13; // expected-error@second.h:* {{'Method::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter with a default argument}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a different default argument}} #endif #if defined(FIRST) struct S14 { void A(int x[2]) {} }; #elif defined(SECOND) struct S14 { void A(int x[3]) {} }; #else S14 s14; // expected-error@second.h:* {{'Method::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [3]'}} // expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [2]'}} #endif #if defined(FIRST) struct S15 { int A() { return 0; } }; #elif defined(SECOND) struct S15 { long A() { return 0; } }; #else S15 s15; // expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'A' does not match}} #endif } // namespace Method namespace Constructor { #if defined(FIRST) struct S1 { S1() {} void foo() {} }; #elif defined(SECOND) struct S1 { void foo() {} S1() {} }; #else S1 s1; // expected-error@second.h:* {{'Constructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo'}} // expected-note@first.h:* {{but in 'FirstModule' found constructor}} #endif #if defined(FIRST) struct S2 { S2(int) {} S2(int, int) {} }; #elif defined(SECOND) struct S2 { S2(int, int) {} S2(int) {} }; #else S2* s2; // expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}} // expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}} #endif } // namespace Constructor namespace Destructor { #if defined(FIRST) struct S1 { ~S1() {} S1() {} }; #elif defined(SECOND) struct S1 { S1() {} ~S1() {} }; #else S1 s1; // expected-error@second.h:* {{'Destructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor}} // expected-note@first.h:* {{but in 'FirstModule' found destructor}} #endif #if defined(FIRST) struct S2 { virtual ~S2() {} void foo() {} }; #elif defined(SECOND) struct S2 { ~S2() {} virtual void foo() {} }; #else S2 s2; // expected-error@second.h:* {{'Destructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found destructor is not virtual}} // expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}} #endif } // namespace Destructor // Naive parsing of AST can lead to cycles in processing. Ensure // self-references don't trigger an endless cycles of AST node processing. namespace SelfReference { #if defined(FIRST) template