// 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 'B' (aka 'int')}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type '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 'A' (aka 'int')}} #endif } // namespace Field // 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