brintos

brintos / llvm-project-archived public Read only

0
0
Text · 138.0 KiB · f22f3c7 Raw
5202 lines · cpp
1// Clear and create directories2// RUN: rm -rf %t3// RUN: mkdir %t4// RUN: mkdir %t/cache5// RUN: mkdir %t/Inputs6 7// Build first header file8// RUN: echo "#define FIRST" >> %t/Inputs/first.h9// RUN: cat %s               >> %t/Inputs/first.h10 11// Build second header file12// RUN: echo "#define SECOND" >> %t/Inputs/second.h13// RUN: cat %s                >> %t/Inputs/second.h14 15// Test that each header can compile16// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++20 %t/Inputs/first.h17// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++20 %t/Inputs/second.h18 19// Build module map file20// RUN: echo "module FirstModule {"     >> %t/Inputs/module.modulemap21// RUN: echo "    header \"first.h\""   >> %t/Inputs/module.modulemap22// RUN: echo "}"                        >> %t/Inputs/module.modulemap23// RUN: echo "module SecondModule {"    >> %t/Inputs/module.modulemap24// RUN: echo "    header \"second.h\""  >> %t/Inputs/module.modulemap25// RUN: echo "}"                        >> %t/Inputs/module.modulemap26 27// Run test28// RUN: %clang_cc1 -triple x86_64-linux-gnu -x c++ -std=c++20 \29// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \30// RUN:   -I%t/Inputs -verify %s31 32#if !defined(FIRST) && !defined(SECOND)33#include "first.h"34#include "second.h"35#endif36 37// Used for testing38#if defined(FIRST)39#define ACCESS public:40#elif defined(SECOND)41#define ACCESS private:42#endif43 44namespace AccessSpecifiers {45#if defined(FIRST)46struct S1 {47};48#elif defined(SECOND)49struct S1 {50  private:51};52#else53S1 s1;54// expected-error@second.h:* {{'AccessSpecifiers::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}55// expected-note@first.h:* {{but in 'FirstModule' found end of class}}56#endif57 58#if defined(FIRST)59struct S2 {60  public:61};62#elif defined(SECOND)63struct S2 {64  protected:65};66#else67S2 s2;68// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}69// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}70#endif71 72#define DECLS \73public:       \74private:      \75protected:76 77#if defined(FIRST) || defined(SECOND)78struct Valid1 {79  DECLS80};81#else82Valid1 v1;83#endif84 85#if defined(FIRST) || defined(SECOND)86struct Invalid1 {87  DECLS88  ACCESS89};90#else91Invalid1 i1;92// expected-error@second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}93// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}94#endif95 96#undef DECLS97} // namespace AccessSpecifiers98 99namespace StaticAssert {100#if defined(FIRST)101struct S1 {102  static_assert(1 == 1, "First");103};104#elif defined(SECOND)105struct S1 {106  static_assert(1 == 1, "Second");107};108#else109S1 s1;110// expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}}111// expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}}112#endif113 114#if defined(FIRST)115struct S2 {116  static_assert(2 == 2, "Message");117};118#elif defined(SECOND)119struct S2 {120  static_assert(2 == 2);121};122#else123S2 s2;124// 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}}125// expected-note@first.h:* {{but in 'FirstModule' found static assert with message}}126#endif127 128#if defined(FIRST)129struct S3 {130  static_assert(3 == 3, "Message");131};132#elif defined(SECOND)133struct S3 {134  static_assert(3 != 4, "Message");135};136#else137S3 s3;138// expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}}139// expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}}140#endif141 142#if defined(FIRST)143struct S4 {144  static_assert(4 == 4, "Message");145};146#elif defined(SECOND)147struct S4 {148  public:149};150#else151S4 s4;152// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}153// expected-note@first.h:* {{but in 'FirstModule' found static assert}}154#endif155 156#define DECLS                       \157  static_assert(4 == 4, "Message"); \158  static_assert(5 == 5);159 160#if defined(FIRST) || defined(SECOND)161struct Valid1 {162  DECLS163};164#else165Valid1 v1;166#endif167 168#if defined(FIRST) || defined(SECOND)169struct Invalid1 {170  DECLS171  ACCESS172};173#else174Invalid1 i1;175// expected-error@second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}176// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}177#endif178#undef DECLS179}  // namespace StaticAssert180 181namespace Field {182#if defined(FIRST)183struct S1 {184  int x;185  private:186  int y;187};188#elif defined(SECOND)189struct S1 {190  int x;191  int y;192};193#else194S1 s1;195// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}196// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}197#endif198 199#if defined(FIRST)200struct S2 {201  int x;202  int y;203};204#elif defined(SECOND)205struct S2 {206  int y;207  int x;208};209#else210S2 s2;211// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}212// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}213#endif214 215#if defined(FIRST)216struct S3 {217  double x;218};219#elif defined(SECOND)220struct S3 {221  int x;222};223#else224S3 s3;225// expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}}226// expected-note@second.h:* {{declaration of 'x' does not match}}227#endif228 229#if defined(FIRST)230typedef int A;231struct S4 {232  A x;233};234 235struct S5 {236  A x;237};238#elif defined(SECOND)239typedef int B;240struct S4 {241  B x;242};243 244struct S5 {245  int x;246};247#else248S4 s4;249// 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')}}250// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'A' (aka 'int')}}251 252S5 s5;253// 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'}}254// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'A' (aka 'int')}}255#endif256 257#if defined(FIRST)258struct S6 {259  unsigned x;260};261#elif defined(SECOND)262struct S6 {263  unsigned x : 1;264};265#else266S6 s6;267// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bit-field 'x'}}268// expected-note@first.h:* {{but in 'FirstModule' found non-bit-field 'x'}}269#endif270 271#if defined(FIRST)272struct S7 {273  unsigned x : 2;274};275#elif defined(SECOND)276struct S7 {277  unsigned x : 1;278};279#else280S7 s7;281// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bit-field 'x' with one width expression}}282// expected-note@first.h:* {{but in 'FirstModule' found bit-field 'x' with different width expression}}283#endif284 285#if defined(FIRST)286struct S8 {287  unsigned x : 2;288};289#elif defined(SECOND)290struct S8 {291  unsigned x : 1 + 1;292};293#else294S8 s8;295// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bit-field 'x' with one width expression}}296// expected-note@first.h:* {{but in 'FirstModule' found bit-field 'x' with different width expression}}297#endif298 299#if defined(FIRST)300struct S9 {301  mutable int x;302};303#elif defined(SECOND)304struct S9 {305  int x;306};307#else308S9 s9;309// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}310// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}311#endif312 313#if defined(FIRST)314struct S9b {315  mutable int x : 2;316};317#elif defined(SECOND)318struct S9b {319  int x : 2;320};321#else322S9b s9b;323// expected-error@second.h:* {{'Field::S9b' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}324// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}325#endif326 327#if defined(FIRST)328struct S10 {329  unsigned x = 5;330};331#elif defined(SECOND)332struct S10 {333  unsigned x;334};335#else336S10 s10;337// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initializer}}338// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}}339#endif340 341#if defined(FIRST)342struct S11 {343  unsigned x = 5;344};345#elif defined(SECOND)346struct S11 {347  unsigned x = 7;348};349#else350S11 s11;351// 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}}352// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}353#endif354 355#if defined(FIRST)356struct S12 {357  unsigned x[5];358};359#elif defined(SECOND)360struct S12 {361  unsigned x[7];362};363#else364S12 s12;365// expected-error@first.h:* {{'Field::S12::x' from module 'FirstModule' is not present in definition of 'Field::S12' in module 'SecondModule'}}366// expected-note@second.h:* {{declaration of 'x' does not match}}367#endif368 369#if defined(FIRST)370struct S13 {371  unsigned x[7];372};373#elif defined(SECOND)374struct S13 {375  double x[7];376};377#else378S13 s13;379// expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}380// expected-note@second.h:* {{declaration of 'x' does not match}}381#endif382 383#define DECLS         \384  int a;              \385  int b : 3;          \386  unsigned c : 1 + 2; \387  s d;                \388  double e = 1.0;     \389  long f[5];          \390  mutable int g;      \391  mutable int h : 5;392 393#if defined(FIRST) || defined(SECOND)394typedef short s;395#endif396 397#if defined(FIRST) || defined(SECOND)398struct Valid1 {399  DECLS400};401#else402Valid1 v1;403#endif404 405#if defined(FIRST) || defined(SECOND)406struct Invalid1 {407  DECLS408  ACCESS409};410#else411Invalid1 i1;412// expected-error@second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}413// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}414#endif415#undef DECLS416}  // namespace Field417 418namespace Method {419#if defined(FIRST)420struct S1 {421  void A() {}422};423#elif defined(SECOND)424struct S1 {425  private:426  void A() {}427};428#else429S1 s1;430// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}431// expected-note@first.h:* {{but in 'FirstModule' found method}}432#endif433 434#if defined(FIRST)435struct S2 {436  void A() {}437  void B() {}438};439#elif defined(SECOND)440struct S2 {441  void B() {}442  void A() {}443};444#else445S2 s2;446// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}447// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}448#endif449 450#if defined(FIRST)451struct S3 {452  static void A() {}453  void A(int) {}454};455#elif defined(SECOND)456struct S3 {457  void A(int) {}458  static void A() {}459};460#else461S3 s3;462// 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}}463// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}464#endif465 466#if defined(FIRST)467struct S4 {468  virtual void A() {}469  void B() {}470};471#elif defined(SECOND)472struct S4 {473  void A() {}474  virtual void B() {}475};476#else477S4 s4;478// 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}}479// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}480#endif481 482#if defined(FIRST)483struct S5 {484  virtual void A() = 0;485  virtual void B() {};486};487#elif defined(SECOND)488struct S5 {489  virtual void A() {}490  virtual void B() = 0;491};492#else493S5 *s5;494// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}495// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}496#endif497 498#if defined(FIRST)499struct S6 {500  inline void A() {}501};502#elif defined(SECOND)503struct S6 {504  void A() {}505};506#else507S6 s6;508// 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}}509// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}510#endif511 512#if defined(FIRST)513struct S7 {514  void A() volatile {}515  void A() {}516};517#elif defined(SECOND)518struct S7 {519  void A() {}520  void A() volatile {}521};522#else523S7 s7;524// 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}}525// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}526#endif527 528#if defined(FIRST)529struct S8 {530  void A() const {}531  void A() {}532};533#elif defined(SECOND)534struct S8 {535  void A() {}536  void A() const {}537};538#else539S8 s8;540// 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}}541// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}542#endif543 544#if defined(FIRST)545struct S9 {546  void A(int x) {}547  void A(int x, int y) {}548};549#elif defined(SECOND)550struct S9 {551  void A(int x, int y) {}552  void A(int x) {}553};554#else555S9 s9;556// 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}}557// expected-note@first.h:* {{but in 'FirstModule' found method 'A' that has 1 parameter}}558#endif559 560#if defined(FIRST)561struct S10 {562  void A(int x) {}563  void A(float x) {}564};565#elif defined(SECOND)566struct S10 {567  void A(float x) {}568  void A(int x) {}569};570#else571S10 s10;572// 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'}}573// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int'}}574#endif575 576#if defined(FIRST)577struct S11 {578  void A(int x);579};580#elif defined(SECOND)581struct S11 {582  void A(int y);583};584#else585S11 s11;586// 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'}}587// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter named 'x'}}588#endif589 590#if defined(FIRST)591struct S12 {592  void A(int x);593};594#elif defined(SECOND)595struct S12 {596  void A(int x = 1);597};598#else599S12 s12;600// 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}}601// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a default argument}}602#endif603 604#if defined(FIRST)605struct S13 {606  void A(int x = 1 + 0);607};608#elif defined(SECOND)609struct S13 {610  void A(int x = 1);611};612#else613S13 s13;614// 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}}615// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a different default argument}}616#endif617 618#if defined(FIRST)619struct S14 {620  void A(int x[2]);621};622#elif defined(SECOND)623struct S14 {624  void A(int x[3]);625};626#else627S14 s14;628// 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]'}}629// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int[2]'}}630#endif631 632#if defined(FIRST)633struct S15 {634  int A() { return 0; }635};636#elif defined(SECOND)637struct S15 {638  long A() { return 0; }639};640#else641S15 s15;642// expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}643// expected-note@second.h:* {{declaration of 'A' does not match}}644#endif645 646#define DECLS            \647  void A();              \648  static void B();       \649  virtual void C();      \650  virtual void D() = 0;  \651  inline void E();       \652  void F() const;        \653  void G() volatile;     \654  void H(int x);         \655  void I(int x = 5 + 5); \656  void J(int);           \657  void K(int x[2]);      \658  int L();659 660#if defined(FIRST) || defined(SECOND)661struct Valid1 {662  DECLS663};664#else665Valid1* v1;666#endif667 668#if defined(FIRST) || defined(SECOND)669struct Invalid1 {670  DECLS671  ACCESS672};673#else674Invalid1* i1;675// expected-error@second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}676// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}677#endif678#undef DECLS679}  // namespace Method680 681namespace MethodBody {682#if defined(FIRST)683struct S1 {684  int A() { return 0; }685};686#elif defined(SECOND)687struct S1 {688  int A() { return 0; }689};690#else691S1 s1;692#endif693 694#if defined(FIRST)695struct S2 {696  int BothBodies() { return 0; }697};698#elif defined(SECOND)699struct S2 {700  int BothBodies() { return 1; }701};702#else703S2 s2;704// expected-error@first.h:* {{'MethodBody::S2' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'BothBodies' with body}}705// expected-note@second.h:* {{but in 'SecondModule' found method 'BothBodies' with different body}}706#endif707 708#if defined(FIRST)709struct S3 {710  int FirstBody() { return 0; }711};712#elif defined(SECOND)713struct S3 {714  int FirstBody();715};716#else717S3 s3;718// expected-error@first.h:* {{'MethodBody::S3' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstBody' with body}}719// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstBody' with no body}}720#endif721 722#if defined(FIRST)723struct S4 {724  int SecondBody();725};726#elif defined(SECOND)727struct S4 {728  int SecondBody() { return 0; }729};730#else731S4 s4;732// expected-error@first.h:* {{'MethodBody::S4' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'SecondBody' with no body}}733// expected-note@second.h:* {{but in 'SecondModule' found method 'SecondBody' with body}}734#endif735 736#if defined(FIRST)737struct S5 {738  int FirstBodySecondOutOfLine() { return 0; }739};740#elif defined(SECOND)741struct S5 {742  int FirstBodySecondOutOfLine();743};744int S5::FirstBodySecondOutOfLine() { return 0; }745#else746S5 s5;747// expected-error@second.h:* {{'MethodBody::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'FirstBodySecondOutOfLine' with no body}}748// expected-note@first.h:* {{but in 'FirstModule' found method 'FirstBodySecondOutOfLine' with body}}749#endif750 751#if defined(FIRST)752struct S6 {753  int FirstOutOfLineSecondBody();754};755int S6::FirstOutOfLineSecondBody() { return 0; }756#elif defined(SECOND)757struct S6 {758  int FirstOutOfLineSecondBody() { return 0; }759};760#else761S6 s6;762// expected-error@first.h:* {{'MethodBody::S6' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstOutOfLineSecondBody' with no body}}763// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstOutOfLineSecondBody' with body}}764#endif765 766#if defined(FIRST)767struct S7 {768  int BothOutOfLine();769};770int S7::BothOutOfLine() { return 1; }771#elif defined(SECOND)772struct S7 {773  int BothOutOfLine();774};775int S7::BothOutOfLine() { return 0; }776#else777S7 s7;778// expected-error@second.h:* {{'MethodBody::S7::BothOutOfLine' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}779// expected-note@first.h:* {{but in 'FirstModule' found a different body}}780#endif781 782#if defined(FIRST)783struct S8 {784  int FirstBodySecondOutOfLine() { return 0; }785};786#elif defined(SECOND)787struct S8 {788  int FirstBodySecondOutOfLine();789};790int S8::FirstBodySecondOutOfLine() { return 1; }791#else792S8 s8;793// expected-error@second.h:* {{'MethodBody::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'FirstBodySecondOutOfLine' with no body}}794// expected-note@first.h:* {{but in 'FirstModule' found method 'FirstBodySecondOutOfLine' with body}}795#endif796 797#if defined(FIRST)798struct S9 {799  int FirstOutOfLineSecondBody();800};801int S9::FirstOutOfLineSecondBody() { return 1; }802#elif defined(SECOND)803struct S9 {804  int FirstOutOfLineSecondBody() { return 0; }805};806#else807S9 s9;808// expected-error@first.h:* {{'MethodBody::S9' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstOutOfLineSecondBody' with no body}}809// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstOutOfLineSecondBody' with body}}810#endif811 812#if defined(FIRST)813struct S10 {814  S10(int);815  S10() = delete;816};817#elif defined(SECOND)818struct S10 {819  S10(int);820  S10();821};822#else823S10 s10(10);824// expected-error@first.h:* {{'MethodBody::S10' has different definitions in different modules; first difference is definition in module 'FirstModule' found constructor is deleted}}825// expected-note@second.h:* {{but in 'SecondModule' found constructor is not deleted}}826#endif827 828#if defined(FIRST)829struct S11 {830  S11() = default;831};832#elif defined(SECOND)833struct S11 {834  S11();835};836#else837S11 s11;838// expected-error@first.h:* {{'MethodBody::S11' has different definitions in different modules; first difference is definition in module 'FirstModule' found constructor is defaulted}}839// expected-note@second.h:* {{but in 'SecondModule' found constructor is not defaulted}}840#endif841 842#define DECLS(CLASSNAME) \843  CLASSNAME() = default; \844  ~CLASSNAME() = delete; \845  void A();              \846  void B() { return; };  \847  void C();              \848  void D();849 850#define OUTOFLINEDEFS(CLASSNAME) \851  void CLASSNAME::C() {}         \852  void CLASSNAME::D() { return; }853 854#if defined(FIRST) || defined(SECOND)855struct Valid1 {856  DECLS(Valid1)857};858OUTOFLINEDEFS(Valid1)859#else860Valid1* v1;861#endif862 863#if defined(FIRST) || defined(SECOND)864struct Invalid1 {865  DECLS(Invalid1)866  ACCESS867};868OUTOFLINEDEFS(Invalid1)869#else870Invalid1* i1;871// expected-error@first.h:* {{'MethodBody::Invalid1' has different definitions in different modules; first difference is definition in module 'FirstModule' found public access specifier}}872// expected-note@second.h:* {{but in 'SecondModule' found private access specifier}}873#endif874#undef DECLS875}  // namespace MethodBody876 877namespace Constructor {878#if defined(FIRST)879struct S1 {880  S1() {}881  void foo() {}882};883#elif defined(SECOND)884struct S1 {885  void foo() {}886  S1() {}887};888#else889S1 s1;890// expected-error@second.h:* {{'Constructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo'}}891// expected-note@first.h:* {{but in 'FirstModule' found constructor}}892#endif893 894#if defined(FIRST)895struct S2 {896  S2(int) {}897  S2(int, int) {}898};899#elif defined(SECOND)900struct S2 {901  S2(int, int) {}902  S2(int) {}903};904#else905S2* s2;906// 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}}907// expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}908#endif909 910#define DECLS(CLASS) \911  CLASS(int);        \912  CLASS(double);     \913  CLASS(int, int);914 915#if defined(FIRST) || defined(SECOND)916struct Valid1 {917  DECLS(Valid1)918};919#else920Valid1* v1;921#endif922 923#if defined(FIRST) || defined(SECOND)924struct Invalid1 {925  DECLS(Invalid1)926  ACCESS927};928#else929Invalid1* i1;930// expected-error@second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}931// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}932#endif933#undef DECLS934}  // namespace Constructor935 936namespace Destructor {937#if defined(FIRST)938struct S1 {939  ~S1() {}940  S1() {}941};942#elif defined(SECOND)943struct S1 {944  S1() {}945  ~S1() {}946};947#else948S1 s1;949// expected-error@second.h:* {{'Destructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor}}950// expected-note@first.h:* {{but in 'FirstModule' found destructor}}951#endif952 953#if defined(FIRST)954struct S2 {955  virtual ~S2() {}956  void foo() {}957};958#elif defined(SECOND)959struct S2 {960  ~S2() {}961  virtual void foo() {}962};963#else964S2 s2;965// expected-error@second.h:* {{'Destructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found destructor is not virtual}}966// expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}}967#endif968 969#if defined(FIRST) || defined(SECOND)970struct Valid1 {971  ~Valid1();972};973#else974Valid1 v1;975#endif976 977#if defined(FIRST) || defined(SECOND)978struct Invalid1 {979  ~Invalid1();980  ACCESS981};982#else983Invalid1 i1;984// expected-error@second.h:* {{'Destructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}985// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}986#endif987 988#if defined(FIRST) || defined(SECOND)989struct Valid2 {990  virtual ~Valid2();991};992#else993Valid2 v2;994#endif995 996#if defined(FIRST) || defined(SECOND)997struct Invalid2 {998  virtual ~Invalid2();999  ACCESS1000};1001#else1002Invalid2 i2;1003// expected-error@second.h:* {{'Destructor::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1004// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1005#endif1006}  // namespace Destructor1007 1008namespace TypeDef {1009#if defined(FIRST)1010struct S1 {1011  typedef int a;1012};1013#elif defined(SECOND)1014struct S1 {1015  typedef double a;1016};1017#else1018S1 s1;1019// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}1020// expected-note@second.h:* {{declaration of 'a' does not match}}1021#endif1022 1023#if defined(FIRST)1024struct S2 {1025  typedef int a;1026};1027#elif defined(SECOND)1028struct S2 {1029  typedef int b;1030};1031#else1032S2 s2;1033// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}1034// expected-note@second.h:* {{definition has no member 'a'}}1035#endif1036 1037#if defined(FIRST)1038typedef int T;1039struct S3 {1040  typedef T a;1041};1042#elif defined(SECOND)1043typedef double T;1044struct S3 {1045  typedef T a;1046};1047#else1048S3 s3;1049// FIXME: We should reject the merge of `S3` due to the inconsistent definition of `T`.1050#endif1051 1052#if defined(FIRST)1053struct S4 {1054  typedef int a;1055  typedef int b;1056};1057#elif defined(SECOND)1058struct S4 {1059  typedef int b;1060  typedef int a;1061};1062#else1063S4 s4;1064// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}1065// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}}1066#endif1067 1068#if defined(FIRST)1069struct S5 {1070  typedef int a;1071  typedef int b;1072  int x;1073};1074#elif defined(SECOND)1075struct S5 {1076  int x;1077  typedef int b;1078  typedef int a;1079};1080#else1081S5 s5;1082// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}1083// expected-note@first.h:* {{but in 'FirstModule' found typedef}}1084#endif1085 1086#if defined(FIRST)1087typedef float F;1088struct S6 {1089  typedef int a;1090  typedef F b;1091};1092#elif defined(SECOND)1093struct S6 {1094  typedef int a;1095  typedef float b;1096};1097#else1098S6 s6;1099// expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}1100// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'F' (aka 'float')}}1101#endif1102 1103#define DECLS       \1104  typedef int A;    \1105  typedef double B; \1106  typedef I C;1107 1108#if defined(FIRST) || defined(SECOND)1109typedef int I;1110#endif1111 1112#if defined(FIRST) || defined(SECOND)1113struct Valid1 {1114  DECLS1115};1116#else1117Valid1 v1;1118#endif1119 1120#if defined(FIRST) || defined(SECOND)1121struct Invalid1 {1122  DECLS1123  ACCESS1124};1125#else1126Invalid1 i1;1127// expected-error@second.h:* {{'TypeDef::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1128// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1129#endif1130#undef DECLS1131}  // namespace TypeDef1132 1133namespace Using {1134#if defined(FIRST)1135struct S1 {1136  using a = int;1137};1138#elif defined(SECOND)1139struct S1 {1140  using a = double;1141};1142#else1143S1 s1;1144// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}1145// expected-note@second.h:* {{declaration of 'a' does not match}}1146#endif1147 1148#if defined(FIRST)1149struct S2 {1150  using a = int;1151};1152#elif defined(SECOND)1153struct S2 {1154  using b = int;1155};1156#else1157S2 s2;1158// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}1159// expected-note@second.h:* {{definition has no member 'a'}}1160#endif1161 1162#if defined(FIRST)1163typedef int T;1164struct S3 {1165  using a = T;1166};1167#elif defined(SECOND)1168typedef double T;1169struct S3 {1170  using a = T;1171};1172#else1173S3 s3;1174// FIXME: We should reject the merge of `S3` due to the inconsistent definition of `T`.1175#endif1176 1177#if defined(FIRST)1178struct S4 {1179  using a = int;1180  using b = int;1181};1182#elif defined(SECOND)1183struct S4 {1184  using b = int;1185  using a = int;1186};1187#else1188S4 s4;1189// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}1190// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}}1191#endif1192 1193#if defined(FIRST)1194struct S5 {1195  using a = int;1196  using b = int;1197  int x;1198};1199#elif defined(SECOND)1200struct S5 {1201  int x;1202  using b = int;1203  using a = int;1204};1205#else1206S5 s5;1207// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}1208// expected-note@first.h:* {{but in 'FirstModule' found type alias}}1209#endif1210 1211#if defined(FIRST)1212typedef float F;1213struct S6 {1214  using a = int;1215  using b = F;1216};1217#elif defined(SECOND)1218struct S6 {1219  using a = int;1220  using b = float;1221};1222#else1223S6 s6;1224// expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}1225// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'F' (aka 'float')}}1226#endif1227 1228#if defined(FIRST) || defined(SECOND)1229using I = int;1230#endif1231 1232#define DECLS       \1233  using A = int;    \1234  using B = double; \1235  using C = I;1236 1237#if defined(FIRST) || defined(SECOND)1238struct Valid1 {1239  DECLS1240};1241#else1242Valid1 v1;1243#endif1244 1245#if defined(FIRST) || defined(SECOND)1246struct Invalid1 {1247  DECLS1248  ACCESS1249};1250#else1251Invalid1 i1;1252// expected-error@second.h:* {{'Using::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1253// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1254#endif1255#undef DECLS1256}  // namespace Using1257 1258namespace RecordType {1259#if defined(FIRST)1260struct B1 {};1261struct S1 {1262  B1 x;1263};1264#elif defined(SECOND)1265struct A1 {};1266struct S1 {1267  A1 x;1268};1269#else1270S1 s1;1271// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}1272// expected-note@second.h:* {{declaration of 'x' does not match}}1273#endif1274 1275#define DECLS \1276  Foo F;1277 1278#if defined(FIRST) || defined(SECOND)1279struct Foo {};1280#endif1281 1282#if defined(FIRST) || defined(SECOND)1283struct Valid1 {1284  DECLS1285};1286#else1287Valid1 v1;1288#endif1289 1290#if defined(FIRST) || defined(SECOND)1291struct Invalid1 {1292  DECLS1293  ACCESS1294};1295#else1296Invalid1 i1;1297// expected-error@second.h:* {{'RecordType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1298// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1299#endif1300#undef DECLS1301}  // namespace RecordType1302 1303namespace DependentType {1304#if defined(FIRST)1305template <class T>1306class S1 {1307  typename T::typeA x;1308};1309#elif defined(SECOND)1310template <class T>1311class S1 {1312  typename T::typeB x;1313};1314#else1315template<class T>1316using U1 = S1<T>;1317// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'DependentType::S1<T>' in module 'SecondModule'}}1318// expected-note@second.h:* {{declaration of 'x' does not match}}1319#endif1320 1321#define DECLS \1322  typename T::typeA x;1323 1324#if defined(FIRST) || defined(SECOND)1325template <class T>1326struct Valid1 {1327  DECLS1328};1329#else1330template <class T>1331using V1 = Valid1<T>;1332#endif1333 1334#if defined(FIRST) || defined(SECOND)1335template <class T>1336struct Invalid1 {1337  DECLS1338  ACCESS1339};1340#else1341template <class T>1342using I1 = Invalid1<T>;1343// expected-error@second.h:* {{'DependentType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1344// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1345#endif1346#undef DECLS1347}  // namespace DependentType1348 1349namespace ElaboratedType {1350#if defined(FIRST)1351namespace N1 { using type = double; }1352struct S1 {1353  N1::type x;1354};1355#elif defined(SECOND)1356namespace N1 { using type = int; }1357struct S1 {1358  N1::type x;1359};1360#else1361S1 s1;1362#endif1363 1364#define DECLS \1365  NS::type x;1366 1367#if defined(FIRST) || defined(SECOND)1368namespace NS { using type = float; }1369#endif1370 1371#if defined(FIRST) || defined(SECOND)1372struct Valid1 {1373  DECLS1374};1375#else1376Valid1 v1;1377#endif1378 1379#if defined(FIRST) || defined(SECOND)1380struct Invalid1 {1381  DECLS1382  ACCESS1383};1384#else1385Invalid1 i1;1386// expected-error@second.h:* {{'ElaboratedType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1387// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1388#endif1389#undef DECLS1390}  // namespace ElaboratedType1391 1392namespace Enum {1393#if defined(FIRST)1394enum A1 {};1395struct S1 {1396  A1 x;1397};1398#elif defined(SECOND)1399enum A2 {};1400struct S1 {1401  A2 x;1402};1403#else1404S1 s1;1405// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}1406// expected-note@second.h:* {{declaration of 'x' does not match}}1407#endif1408 1409#define DECLS \1410  E e = E1;1411 1412#if defined(FIRST) || defined(SECOND)1413enum E { E1, E2 };1414#endif1415 1416#if defined(FIRST) || defined(SECOND)1417struct Valid1 {1418  DECLS1419};1420#else1421Valid1 v1;1422#endif1423 1424#if defined(FIRST) || defined(SECOND)1425struct Invalid1 {1426  DECLS1427  ACCESS1428};1429#else1430Invalid1 i1;1431// expected-error@second.h:* {{'Enum::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1432// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1433#endif1434#undef DECLS1435}1436 1437namespace NestedNamespaceSpecifier {1438#if defined(FIRST)1439namespace LevelA1 {1440using Type = int;1441}1442 1443struct S1 {1444  LevelA1::Type x;1445};1446# elif defined(SECOND)1447namespace LevelB1 {1448namespace LevelC1 {1449using Type = int;1450}1451}1452 1453struct S1 {1454  LevelB1::LevelC1::Type x;1455};1456#else1457S1 s1;1458// expected-error@second.h:* {{'NestedNamespaceSpecifier::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB1::LevelC1::Type' (aka 'int')}}1459// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA1::Type' (aka 'int')}}1460#endif1461 1462#if defined(FIRST)1463namespace LevelA2 { using Type = int; }1464struct S2 {1465  LevelA2::Type x;1466};1467# elif defined(SECOND)1468struct S2 {1469  int x;1470};1471#else1472S2 s2;1473// expected-error@second.h:* {{'NestedNamespaceSpecifier::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}}1474// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA2::Type' (aka 'int')}}1475#endif1476 1477namespace LevelA3 { using Type = int; }1478namespace LevelB3 { using Type = int; }1479#if defined(FIRST)1480struct S3 {1481  LevelA3::Type x;1482};1483# elif defined(SECOND)1484struct S3 {1485  LevelB3::Type x;1486};1487#else1488S3 s3;1489// expected-error@second.h:* {{'NestedNamespaceSpecifier::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB3::Type' (aka 'int')}}1490// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA3::Type' (aka 'int')}}1491#endif1492 1493#if defined(FIRST)1494struct TA4 { using Type = int; };1495struct S4 {1496  TA4::Type x;1497};1498# elif defined(SECOND)1499struct TB4 { using Type = int; };1500struct S4 {1501  TB4::Type x;1502};1503#else1504S4 s4;1505// expected-error@second.h:* {{'NestedNamespaceSpecifier::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'TB4::Type' (aka 'int')}}1506// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'TA4::Type' (aka 'int')}}1507#endif1508 1509#if defined(FIRST)1510struct T5 { using Type = int; };1511struct S5 {1512  T5::Type x;1513};1514# elif defined(SECOND)1515namespace T5 { using Type = int; };1516struct S5 {1517  T5::Type x;1518};1519#else1520S5 s5;1521// expected-error@second.h:* {{'NestedNamespaceSpecifier::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'T5::Type' (aka 'int')}}1522// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'T5::Type' (aka 'int')}}1523#endif1524 1525#if defined(FIRST)1526namespace N6 {using I = int;}1527struct S6 {1528  NestedNamespaceSpecifier::N6::I x;1529};1530# elif defined(SECOND)1531using I = int;1532struct S6 {1533  ::NestedNamespaceSpecifier::I x;1534};1535#else1536S6 s6;1537// expected-error@second.h:* {{'NestedNamespaceSpecifier::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '::NestedNamespaceSpecifier::I' (aka 'int')}}1538// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'NestedNamespaceSpecifier::N6::I' (aka 'int')}}1539#endif1540 1541#if defined(FIRST)1542template <class T, class U>1543class S7 {1544  typename T::type *x = {};1545  int z = x->T::foo();1546};1547#elif defined(SECOND)1548template <class T, class U>1549class S7 {1550  typename T::type *x = {};1551  int z = x->U::foo();1552};1553#else1554template <class T, class U>1555using U7 = S7<T, U>;1556// expected-error@second.h:* {{'NestedNamespaceSpecifier::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'z' with an initializer}}1557// expected-note@first.h:* {{but in 'FirstModule' found field 'z' with a different initializer}}1558#endif1559 1560#if defined(FIRST)1561template <class T>1562class S8 {1563  int x = T::template X<int>::value;1564};1565#elif defined(SECOND)1566template <class T>1567class S8 {1568  int x = T::template Y<int>::value;1569};1570#else1571template <class T>1572using U8 = S8<T>;1573// expected-error@second.h:* {{'NestedNamespaceSpecifier::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}1574// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}1575#endif1576 1577#if defined(FIRST)1578namespace N9 { using I = int; }1579namespace O9 = N9;1580struct S9 {1581  O9::I x;1582};1583#elif defined(SECOND)1584namespace N9 { using I = int; }1585namespace P9 = N9;1586struct S9 {1587  P9::I x;1588};1589#else1590S9 s9;1591// expected-error@second.h:* {{'NestedNamespaceSpecifier::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'P9::I' (aka 'int')}}1592// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'O9::I' (aka 'int')}}1593#endif1594 1595namespace N10 {1596#if defined(FIRST)1597inline namespace A { struct X {}; }1598struct S10 {1599  A::X x;1600};1601#elif defined(SECOND)1602inline namespace B { struct X {}; }1603struct S10 {1604  B::X x;1605};1606#else1607S10 s10;1608// expected-error@second.h:* {{'NestedNamespaceSpecifier::N10::S10::x' from module 'SecondModule' is not present in definition of 'NestedNamespaceSpecifier::N10::S10' in module 'FirstModule'}}1609// expected-note@first.h:* {{declaration of 'x' does not match}}1610#endif1611}1612 1613#define DECLS       \1614  NS1::Type a;      \1615  NS1::NS2::Type b; \1616  NS1::S c;         \1617  NS3::Type d;1618 1619#if defined(FIRST) || defined(SECOND)1620namespace NS1 {1621  using Type = int;1622  namespace NS2 {1623    using Type = double;1624  }1625  struct S {};1626}1627namespace NS3 = NS1;1628#endif1629 1630#if defined(FIRST) || defined(SECOND)1631struct Valid1 {1632  DECLS1633};1634#else1635Valid1 v1;1636#endif1637 1638#if defined(FIRST) || defined(SECOND)1639struct Invalid1 {1640  DECLS1641  ACCESS1642};1643#else1644Invalid1 i1;1645// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1646// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1647#endif1648#undef DECLS1649 1650#define DECLS               \1651  typename T::type *x = {}; \1652  int y = x->T::foo();      \1653  int z = U::template X<int>::value;1654 1655#if defined(FIRST) || defined(SECOND)1656template <class T, class U>1657struct Valid2 {1658  DECLS1659};1660#else1661template <class T, class U>1662using V2 = Valid2<T, U>;1663#endif1664 1665#if defined(FIRST) || defined(SECOND)1666template <class T, class U>1667struct Invalid2 {1668  DECLS1669  ACCESS1670};1671#else1672template <class T, class U>1673using I2 = Invalid2<T, U>;1674// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1675// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1676#endif1677#undef DECLS1678}  // namespace NestedNamespaceSpecifier1679 1680namespace TemplateSpecializationType {1681#if defined(FIRST)1682template <class T1> struct U1 {};1683struct S1 {1684  U1<int> u;1685};1686#elif defined(SECOND)1687template <class T1, class T2> struct U1 {};1688struct S1 {1689  U1<int, int> u;1690};1691#else1692S1 s1;1693// expected-error@first.h:* {{'TemplateSpecializationType::S1::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S1' in module 'SecondModule'}}1694// expected-note@second.h:* {{declaration of 'u' does not match}}1695#endif1696 1697#if defined(FIRST)1698template <class T1> struct U2 {};1699struct S2 {1700  U2<int> u;1701};1702#elif defined(SECOND)1703template <class T1> struct V1 {};1704struct S2 {1705  V1<int> u;1706};1707#else1708S2 s2;1709// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}1710// expected-note@second.h:* {{declaration of 'u' does not match}}1711#endif1712 1713#define DECLS                       \1714  OneTemplateArg<int> x;            \1715  OneTemplateArg<double> y;         \1716  OneTemplateArg<char *> z;         \1717  TwoTemplateArgs<int, int> a;      \1718  TwoTemplateArgs<double, float> b; \1719  TwoTemplateArgs<short *, char> c;1720 1721#if defined(FIRST) || defined(SECOND)1722template <class T> struct OneTemplateArg {};1723template <class T, class U> struct TwoTemplateArgs {};1724#endif1725 1726#if defined(FIRST) || defined(SECOND)1727struct Valid1 {1728DECLS1729};1730#else1731Valid1 v1;1732#endif1733 1734#if defined(FIRST) || defined(SECOND)1735struct Invalid1 {1736DECLS1737ACCESS1738};1739#else1740Invalid1 i1;1741// expected-error@second.h:* {{'TemplateSpecializationType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}1742// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}1743#endif1744#undef DECLS1745}  // namespace TemplateSpecializationType1746 1747namespace TemplateArgument {1748#if defined(FIRST)1749template <class> struct U1{};1750struct S1 {1751  U1<int> x;1752};1753#elif defined(SECOND)1754template <int> struct U1{};1755struct S1 {1756  U1<1> x;1757};1758#else1759S1 s1;1760// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}}1761// expected-note@second.h:* {{declaration of 'x' does not match}}1762#endif1763 1764#if defined(FIRST)1765template <int> struct U2{};1766struct S2 {1767  using T = U2<2>;1768};1769#elif defined(SECOND)1770template <int> struct U2{};1771struct S2 {1772  using T = U2<(2)>;1773};1774#else1775S2 s2;1776// expected-error@second.h:* {{'TemplateArgument::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U2<(2)>'}}1777// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}}1778#endif1779 1780#if defined(FIRST)1781template <int> struct U3{};1782struct S3 {1783  using T = U3<2>;1784};1785#elif defined(SECOND)1786template <int> struct U3{};1787struct S3 {1788  using T = U3<1 + 1>;1789};1790#else1791S3 s3;1792// expected-error@second.h:* {{'TemplateArgument::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U3<1 + 1>'}}1793// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}}1794#endif1795 1796#if defined(FIRST)1797template<class> struct T4a {};1798template <template <class> class T> struct U4 {};1799struct S4 {1800  U4<T4a> x;1801};1802#elif defined(SECOND)1803template<class> struct T4b {};1804template <template <class> class T> struct U4 {};1805struct S4 {1806  U4<T4b> x;1807};1808#else1809S4 s4;1810// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}}1811// expected-note@second.h:* {{declaration of 'x' does not match}}1812#endif1813 1814#if defined(FIRST)1815template <class T> struct U5 {};1816struct S5 {1817  U5<int> x;1818};1819#elif defined(SECOND)1820template <class T> struct U5 {};1821struct S5 {1822  U5<short> x;1823};1824#else1825S5 s5;1826// expected-error@first.h:* {{'TemplateArgument::S5::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S5' in module 'SecondModule'}}1827// expected-note@second.h:* {{declaration of 'x' does not match}}1828#endif1829 1830#if defined(FIRST)1831template <class T> struct U6 {};1832struct S6 {1833  U6<int> x;1834  U6<short> y;1835};1836#elif defined(SECOND)1837template <class T> struct U6 {};1838struct S6 {1839  U6<short> y;1840  U6<int> x;1841};1842#else1843S6 s6;1844// expected-error@second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}1845// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}1846#endif1847 1848#if defined(FIRST)1849struct S7 {1850  template<int> void run() {}1851  template<> void run<1>() {}1852};1853#elif defined(SECOND)1854struct S7 {1855  template<int> void run() {}1856  void run() {}1857};1858#else1859S7 s7;1860// expected-error@second.h:* {{'TemplateArgument::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with no template arguments}}1861// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with template arguments}}1862#endif1863 1864#if defined(FIRST)1865struct S8 {1866  static int a, b;1867  template<int&> void run() {}1868  template<int&, int&> void run() {}1869  template<> void run<a>() {}1870};1871#elif defined(SECOND)1872struct S8 {1873  static int a, b;1874  template<int&> void run() {}1875  template<int&, int&> void run() {}1876  template<> void run<a, b>() {}1877};1878#else1879S8 s8;1880// expected-error@second.h:* {{'TemplateArgument::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 2 template arguments}}1881// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 1 template argument}}1882#endif1883 1884#if defined(FIRST)1885struct S9 {1886  static int a, b;1887  template<int&> void run() {}1888  template<> void run<a>() {}1889};1890#elif defined(SECOND)1891struct S9 {1892  static int a, b;1893  template<int&> void run() {}1894  template<> void run<b>() {}1895};1896#else1897S9 s9;1898// expected-error@second.h:* {{'TemplateArgument::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 'b' for 1st template argument}}1899// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 'a' for 1st template argument}}1900#endif1901 1902#if defined(FIRST)1903struct S10 {1904  static int a, b;1905  template<int, int&...> void run() {}1906  template<> void run<1, a>() {}1907};1908#elif defined(SECOND)1909struct S10 {1910  static int a, b;1911  template<int, int&...> void run() {}1912  template<> void run<1, b>() {}1913};1914#else1915S10 s10;1916// expected-error@second.h:* {{'TemplateArgument::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 'b' for 2nd template argument}}1917// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 'a' for 2nd template argument}}1918#endif1919 1920#if defined(FIRST)1921struct S11 {1922  static int a, b;1923  template<int, int&...> void run() {}1924  template<> void run<1, a>() {}1925};1926#elif defined(SECOND)1927struct S11 {1928  static int a, b;1929  template<int, int&...> void run() {}1930  template<> void run<1, a, a>() {}1931};1932#else1933S11 s11;1934// expected-error@second.h:* {{'TemplateArgument::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 3 template arguments}}1935// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 2 template arguments}}1936#endif1937 1938#if defined(FIRST)1939struct S12 {1940  template <int> void f(){};1941  template <> void f<1>(){};1942};1943#elif defined(SECOND)1944struct S12 {1945  template <int> void f(){};1946  template <> void f<2>(){};1947};1948#else1949S12 s12;1950// expected-error@second.h:* {{'TemplateArgument::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 2 for 1st template argument}}1951// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}}1952#endif1953 1954#if defined(FIRST)1955struct S13 {1956  template <int> void f(){};1957  template <> void f<10>(){};1958};1959#elif defined(SECOND)1960struct S13 {1961  template <int> void f(){};1962  template <> void f<10>(){};1963};1964#else1965S13 s13;1966#endif1967 1968#if defined(FIRST)1969struct S14 {1970  template <bool, bool> void f(){};1971  template <> void f<true, false>(){};1972};1973#elif defined(SECOND)1974struct S14 {1975  template <bool, bool> void f(){};1976  template <> void f<false, true>(){};1977};1978#else1979S14 s14;1980// expected-error@second.h:* {{'TemplateArgument::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 0 for 1st template argument}}1981// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}}1982#endif1983 1984#if defined(FIRST)1985struct S15 {1986  template <bool, bool> void f(){};1987  template <> void f<true, true>(){};1988};1989#elif defined(SECOND)1990struct S15 {1991  template <bool, bool> void f(){};1992  template <> void f<true, true>(){};1993};1994#else1995S15 s15;1996#endif1997 1998#if defined(FIRST)1999struct S16 {2000  template <int *> void f(){};2001  template <> void f<nullptr>(){};2002};2003#elif defined(SECOND)2004struct S16 {2005  template <int *> void f(){};2006  template <> void f<nullptr>(){};2007};2008#else2009S16 s16;2010#endif2011 2012#if defined(FIRST)2013struct S17 {2014  static int x;2015  template <int *> void f(){};2016  template <> void f<&x>(){};2017};2018#elif defined(SECOND)2019struct S17 {2020  static int x;2021  template <int *> void f(){};2022  template <> void f<nullptr>(){};2023};2024#else2025S17 s17;2026// expected-error@second.h:* {{'TemplateArgument::S17' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with nullptr for 1st template argument}}2027// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 'x' for 1st template argument}}2028#endif2029 2030#if defined(FIRST)2031struct S18 {2032  static int x;2033  template <int *> void f(){};2034  template <> void f<&x>(){};2035};2036#elif defined(SECOND)2037struct S18 {2038  static int x;2039  template <int *> void f(){};2040  template <> void f<&x>(){};2041};2042#else2043S18 s18;2044#endif2045 2046#if defined(FIRST)2047struct S19 {2048  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2049  template <_BitInt(128)> void f(){};2050  template <> void f<x + x>(){};2051};2052#elif defined(SECOND)2053struct S19 {2054  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2055  template <_BitInt(128)> void f(){};2056  template <> void f<x + x>(){};2057};2058#else2059S19 s19;2060#endif2061 2062#if defined(FIRST)2063struct S20 {2064  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2065  template <_BitInt(128)> void f(){};2066  template <> void f<x + x>(){};2067};2068#elif defined(SECOND)2069struct S20 {2070  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2071  template <_BitInt(128)> void f(){};2072  template <> void f<x>(){};2073};2074#else2075S20 s20;2076// expected-error@second.h:* {{'TemplateArgument::S20' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 18446744073709551615 for 1st template argument}}2077// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 36893488147419103230 for 1st template argument}}2078#endif2079 2080#if defined(FIRST)2081struct S21 {2082  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2083  template <_BitInt(128)> void f(){};2084  template <> void f<x + 0>(){};2085};2086#elif defined(SECOND)2087struct S21 {2088  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);2089  template <_BitInt(128)> void f(){};2090  template <> void f<(unsigned long long)-1>(){};2091};2092#else2093S21 s21;2094#endif2095 2096#if defined(FIRST)2097struct S22 {2098  template <double> void f(){};2099  template <> void f<1.5>(){};2100};2101#elif defined(SECOND)2102struct S22 {2103  template <double> void f(){};2104  template <> void f<1.7>(){};2105};2106#else2107S22 s22;2108// expected-error@second.h:* {{'TemplateArgument::S22' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with 1.700000e+00 for 1st template argument}}2109// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with 1.500000e+00 for 1st template argument}}2110#endif2111 2112#if defined(FIRST)2113struct S23 {2114  template <double> void f(){};2115  template <> void f<2.7>(){};2116};2117#elif defined(SECOND)2118struct S23 {2119  template <double> void f(){};2120  template <> void f<2.7>(){};2121};2122#else2123S23 s23;2124#endif2125 2126#if defined(FIRST) || defined(SECOND)2127struct Composite {2128  int n1[4];2129  int n2[4];2130};2131extern Composite composite;2132#endif2133 2134#if defined(FIRST)2135struct S24 {2136  template <int&> void f(){};2137  template <> void f<composite.n1[1]>(){};2138};2139#elif defined(SECOND)2140struct S24 {2141  template <int&> void f(){};2142  template <> void f<composite.n1[2]>(){};2143};2144#else2145S24 s24;2146// expected-error@second.h:* {{'TemplateArgument::S24' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with composite.n1[2] for 1st template argument}}2147// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with composite.n1[1] for 1st template argument}}2148#endif2149 2150#if defined(FIRST) || defined(SECOND)2151struct S25 {2152  template <int&> void f();2153  template <> void f<composite.n1[2]>();2154};2155#else2156S25 s25;2157#endif2158 2159#if defined(FIRST)2160struct S26 {2161  template <int*> void f(){};2162  template <> void f<&composite.n1[4]>(){}; // Past-the-end pointer.2163};2164#elif defined(SECOND)2165struct S26 {2166  template <int*> void f(){};2167  template <> void f<&composite.n2[0]>(){};2168};2169#else2170S26 s26;2171// expected-error@second.h:* {{'TemplateArgument::S26' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with &composite.n2[0] for 1st template argument}}2172// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with &composite.n1[4] for 1st template argument}}2173#endif2174 2175#if defined(FIRST) || defined(SECOND)2176union Union {2177  int i1;2178  int i2;2179};2180extern Union u;2181#endif2182 2183#if defined(FIRST)2184struct S27 {2185  template <int&> void f(){};2186  template <> void f<u.i1>(){};2187};2188#elif defined(SECOND)2189struct S27 {2190  template <int&> void f(){};2191  template <> void f<u.i2>(){};2192};2193#else2194S27 s27;2195// expected-error@second.h:* {{'TemplateArgument::S27' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with u.i2 for 1st template argument}}2196// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with u.i1 for 1st template argument}}2197#endif2198 2199#if defined(FIRST) || defined(SECOND)2200struct S28 {2201  template <int&> void f(){};2202  template <> void f<u.i1>(){};2203};2204#else2205S28 s28;2206#endif2207 2208#if defined(FIRST) || defined(SECOND)2209struct A {2210  int a;2211};2212struct B : A {};2213struct C : A {};2214struct D : B, C {};2215#endif2216 2217#if defined(FIRST)2218struct S29 {2219  template <int D::*> void f(){};2220  template <> void f<(int D::*)(int B::*)&A::a>(){};2221};2222#elif defined(SECOND)2223struct S29 {2224  template <int D::*> void f(){};2225  template <> void f<(int D::*)(int C::*)&A::a>(){};2226};2227#else2228S29 s29;2229// expected-error@second.h:* {{'TemplateArgument::S29' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with &A::a for 1st template argument}}2230// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with &A::a for 1st template argument}}2231#endif2232 2233#if defined(FIRST) || defined(SECOND)2234struct S30 {2235  template <int D::*> void f(){};2236  template <> void f<(int D::*)(int B::*)&A::a>(){};2237};2238#else2239S30 s30;2240#endif2241 2242#if defined(FIRST)2243struct S31 {2244  template <auto*> void f(){};2245  template <> void f<&composite.n1[2]>(){};2246};2247#elif defined(SECOND)2248struct S31 {2249  template <auto*> void f(){};2250  template <> void f<(void*)&composite.n1[2]>(){};2251};2252#else2253S31 s31;2254// expected-error@second.h:* {{'TemplateArgument::S31' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with &composite.n1[2] for 1st template argument}}2255// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with &composite.n1[2] for 1st template argument}}2256#endif2257 2258#if defined(FIRST)2259struct S32 {2260  template <int*> void f(){};2261  template <> void f<__builtin_constant_p(0) ? (int*)1 : (int*)1>(){};2262};2263#elif defined(SECOND)2264struct S32 {2265  template <int*> void f(){};2266  template <> void f<__builtin_constant_p(0) ? (int*)2 : (int*)2>(){};2267};2268#else2269S32 s32;2270// expected-error@second.h:* {{'TemplateArgument::S32' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'f' with (int *)2 for 1st template argument}}2271// expected-note@first.h:* {{but in 'FirstModule' found method 'f' with (int *)1 for 1st template argument}}2272#endif2273 2274#if defined(FIRST) || defined(SECOND)2275struct S33 {2276  template <int*> void f(){};2277  template <> void f<__builtin_constant_p(0) ? (int*)1 : (int*)1>(){};2278};2279#else2280S33 s33;2281#endif2282 2283#define DECLS                   \2284  OneClass<int> a;              \2285  OneInt<1> b;                  \2286  using c = OneClass<float>;    \2287  using d = OneInt<2>;          \2288  using e = OneInt<2 + 2>;      \2289  OneTemplateClass<OneClass> f; \2290  OneTemplateInt<OneInt> g;     \2291  static int i1, i2;            \2292  template <int &>              \2293  void Function() {}            \2294  template <int &, int &>       \2295  void Function() {}            \2296  template <>                   \2297  void Function<i1>() {}        \2298  template <>                   \2299  void Function<i2>() {}        \2300  template <>                   \2301  void Function<i1, i2>() {}    \2302  template <>                   \2303  void Function<i2, i1>() {}2304 2305#if defined(FIRST) || defined(SECOND)2306template <class> struct OneClass{};2307template <int> struct OneInt{};2308template <template <class> class> struct OneTemplateClass{};2309template <template <int> class> struct OneTemplateInt{};2310#endif2311 2312#if defined(FIRST) || defined(SECOND)2313struct Valid1 {2314DECLS2315};2316#else2317Valid1 v1;2318#endif2319 2320#if defined(FIRST) || defined(SECOND)2321struct Invalid1 {2322DECLS2323ACCESS2324};2325#else2326Invalid1 i1;2327// expected-error@second.h:* {{'TemplateArgument::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}2328// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2329#endif2330#undef DECLS2331}  // namespace TemplateArgument2332 2333namespace TemplateTypeParmType {2334#if defined(FIRST)2335template <class T1, class T2>2336struct S1 {2337  T1 x;2338};2339#elif defined(SECOND)2340template <class T1, class T2>2341struct S1 {2342  T2 x;2343};2344#else2345using TemplateTypeParmType::S1;2346// expected-error@first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S1<T1, T2>' in module 'SecondModule'}}2347// expected-note@second.h:* {{declaration of 'x' does not match}}2348#endif2349 2350#if defined(FIRST)2351template <int ...Ts>2352struct U2 {};2353template <int T, int U>2354class S2 {2355  typedef U2<U, T> type;2356  type x;2357};2358#elif defined(SECOND)2359template <int ...Ts>2360struct U2 {};2361template <int T, int U>2362class S2 {2363  typedef U2<T, U> type;2364  type x;2365};2366#else2367using TemplateTypeParmType::S2;2368// expected-error@first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S2<T, U>' in module 'SecondModule'}}2369// expected-note@second.h:* {{declaration of 'x' does not match}}2370// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S2<T, U>' in module 'SecondModule'}}2371// expected-note@second.h:* {{declaration of 'type' does not match}}2372#endif2373 2374#define DECLS            \2375  T t;                   \2376  U u;                   \2377  ParameterPack<T> a;    \2378  ParameterPack<T, U> b; \2379  ParameterPack<U> c;    \2380  ParameterPack<U, T> d;2381 2382#if defined(FIRST) || defined(SECOND)2383template <class ...Ts> struct ParameterPack {};2384#endif2385 2386#if defined(FIRST) || defined(SECOND)2387template <class T, class U>2388struct Valid1 {2389  DECLS2390};2391#else2392using TemplateTypeParmType::Valid1;2393#endif2394 2395#if defined(FIRST) || defined(SECOND)2396template <class T, class U>2397struct Invalid1 {2398  DECLS2399  ACCESS2400};2401#else2402using TemplateTypeParmType::Invalid1;2403// expected-error@second.h:* {{'TemplateTypeParmType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}2404// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2405#endif2406#undef DECLS2407}  // namespace TemplateTypeParmType2408 2409namespace VarDecl {2410#if defined(FIRST)2411struct S1 {2412  static int x;2413  static int y;2414};2415#elif defined(SECOND)2416struct S1 {2417  static int y;2418  static int x;2419};2420#else2421S1 s1;2422// expected-error@second.h:* {{'VarDecl::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member with name 'y'}}2423// expected-note@first.h:* {{but in 'FirstModule' found data member with name 'x'}}2424#endif2425 2426#if defined(FIRST)2427struct S2 {2428  static int x;2429};2430#elif defined(SECOND)2431using I = int;2432struct S2 {2433  static I x;2434};2435#else2436S2 s2;2437// expected-error@second.h:* {{'VarDecl::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with type 'I' (aka 'int')}}2438// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with different type 'int'}}2439#endif2440 2441#if defined(FIRST)2442struct S3 {2443  static const int x = 1;2444};2445#elif defined(SECOND)2446struct S3 {2447  static const int x;2448};2449#else2450S3 s3;2451// expected-error@second.h:* {{'VarDecl::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}}2452// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' without an initializer}}2453#endif2454 2455#if defined(FIRST)2456struct S4 {2457  static const int x = 1;2458};2459#elif defined(SECOND)2460struct S4 {2461  static const int x = 2;2462};2463#else2464S4 s4;2465// expected-error@second.h:* {{'VarDecl::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}}2466// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with a different initializer}}2467#endif2468 2469#if defined(FIRST)2470struct S5 {2471  static const int x = 1;2472};2473#elif defined(SECOND)2474struct S5 {2475  static constexpr int x = 1;2476};2477#else2478S5 s5;2479// expected-error@second.h:* {{'VarDecl::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' is not constexpr}}2480// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' is constexpr}}2481#endif2482 2483#if defined(FIRST)2484struct S6 {2485  static const int x = 1;2486};2487#elif defined(SECOND)2488struct S6 {2489  static const int y = 1;2490};2491#else2492S6 s6;2493// expected-error@first.h:* {{'VarDecl::S6::x' from module 'FirstModule' is not present in definition of 'VarDecl::S6' in module 'SecondModule'}}2494// expected-note@second.h:* {{definition has no member 'x'}}2495#endif2496 2497#if defined(FIRST)2498struct S7 {2499  static const int x = 1;2500};2501#elif defined(SECOND)2502struct S7 {2503  static const unsigned x = 1;2504};2505#else2506S7 s7;2507// expected-error@first.h:* {{'VarDecl::S7::x' from module 'FirstModule' is not present in definition of 'VarDecl::S7' in module 'SecondModule'}}2508// expected-note@second.h:* {{declaration of 'x' does not match}}2509#endif2510 2511#if defined(FIRST)2512struct S8 {2513public:2514  static const int x = 1;2515};2516#elif defined(SECOND)2517struct S8 {2518  static const int x = 1;2519public:2520};2521#else2522S8 s8;2523// expected-error@second.h:* {{'VarDecl::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member}}2524// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2525#endif2526 2527#if defined(FIRST)2528struct S9 {2529  static const int x = 1;2530};2531#elif defined(SECOND)2532struct S9 {2533  static int x;2534};2535#else2536S9 s9;2537// expected-error@first.h:* {{'VarDecl::S9::x' from module 'FirstModule' is not present in definition of 'VarDecl::S9' in module 'SecondModule'}}2538// expected-note@second.h:* {{declaration of 'x' does not match}}2539#endif2540 2541#define DECLS             \2542  static int a;           \2543  static I b;             \2544  static const int c = 1; \2545  static constexpr int d = 5;2546 2547#if defined(FIRST) || defined(SECOND)2548using I = int;2549#endif2550 2551#if defined(FIRST) || defined(SECOND)2552struct Valid1 {2553  DECLS2554};2555#else2556Valid1 v1;2557#endif2558 2559#if defined(FIRST) || defined(SECOND)2560struct Invalid1 {2561  DECLS2562  ACCESS2563};2564#else2565Invalid1 i1;2566// expected-error@second.h:* {{'VarDecl::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}2567// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2568#endif2569#undef DECLS2570}  // namespace VarDecl2571 2572namespace Friend {2573#if defined(FIRST)2574struct T1 {};2575struct S1 {2576  friend class T1;2577};2578#elif defined(SECOND)2579struct T1 {};2580struct S1 {2581  friend T1;2582};2583#else2584S1 s1;2585// expected-error@second.h:* {{'Friend::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'T1'}}2586// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T1'}}2587#endif2588 2589#if defined(FIRST)2590struct T2 {};2591struct S2 {2592  friend class T2;2593};2594#elif defined(SECOND)2595struct T2 {};2596struct S2 {2597  friend struct T2;2598};2599#else2600S2 s2;2601// expected-error@second.h:* {{'Friend::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'struct T2'}}2602// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T2'}}2603#endif2604 2605#if defined(FIRST)2606struct T4 {};2607struct S4 {2608  friend T4;2609};2610#elif defined(SECOND)2611struct S4 {2612  friend void T4();2613};2614#else2615S4 s4;2616// expected-error@second.h:* {{'Friend::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function}}2617// expected-note@first.h:* {{but in 'FirstModule' found friend class}}2618#endif2619 2620#if defined(FIRST)2621struct S5 {2622  friend void T5a();2623};2624#elif defined(SECOND)2625struct S5 {2626  friend void T5b();2627};2628#else2629S5 s5;2630// expected-error@second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}2631// expected-note@first.h:* {{but in 'FirstModule' found friend function 'T5a'}}2632#endif2633 2634#define DECLS            \2635  friend class FriendA;  \2636  friend struct FriendB; \2637  friend FriendC;        \2638  friend void Function();2639 2640#if defined(FIRST) || defined(SECOND)2641class FriendA {};2642class FriendB {};2643class FriendC {};2644#endif2645 2646#if defined(FIRST) || defined(SECOND)2647struct Valid1 {2648  DECLS2649};2650#else2651Valid1 v1;2652#endif2653 2654#if defined(FIRST) || defined(SECOND)2655struct Invalid1 {2656  DECLS2657  ACCESS2658};2659#else2660Invalid1 i1;2661// expected-error@second.h:* {{'Friend::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}2662// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2663#endif2664#undef DECLS2665}  // namespace Friend2666 2667namespace TemplateParameters {2668#if defined(FIRST)2669template <class A>2670struct S1 {};2671#elif defined(SECOND)2672template <class B>2673struct S1 {};2674#else2675using TemplateParameters::S1;2676// expected-error@second.h:* {{'TemplateParameters::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter 'B'}}2677// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}2678#endif2679 2680#if defined(FIRST)2681template <class A = double>2682struct S2 {};2683#elif defined(SECOND)2684template <class A = int>2685struct S2 {};2686#else2687using TemplateParameters::S2;2688// expected-error@second.h:* {{'TemplateParameters::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}2689// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}2690#endif2691 2692#if defined(FIRST)2693template <class A = int>2694struct S3 {};2695#elif defined(SECOND)2696template <class A>2697struct S3 {};2698#else2699using TemplateParameters::S3;2700// expected-error@second.h:* {{'TemplateParameters::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with no default argument}}2701// expected-note@first.h:* {{but in 'FirstModule' found template parameter with default argument}}2702#endif2703 2704#if defined(FIRST)2705template <int A>2706struct S4 {};2707#elif defined(SECOND)2708template <int A = 2>2709struct S4 {};2710#else2711using TemplateParameters::S4;2712// expected-error@second.h:* {{'TemplateParameters::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}2713// expected-note@first.h:* {{but in 'FirstModule' found template parameter with no default argument}}2714#endif2715 2716#if defined(FIRST)2717template <int> class S5_first {};2718template <template<int> class A = S5_first>2719struct S5 {};2720#elif defined(SECOND)2721template <int> class S5_second {};2722template <template<int> class A = S5_second>2723struct S5 {};2724#else2725using TemplateParameters::S5;2726// expected-error@second.h:* {{'TemplateParameters::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}2727// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}2728#endif2729 2730#if defined(FIRST)2731template <class A>2732struct S6 {};2733#elif defined(SECOND)2734template <class>2735struct S6 {};2736#else2737using TemplateParameters::S6;2738// expected-error@second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}}2739// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}2740#endif2741 2742#if defined(FIRST)2743template <int A = 7>2744struct S7 {};2745#elif defined(SECOND)2746template <int A = 8>2747struct S7 {};2748#else2749using TemplateParameters::S7;2750// expected-error@second.h:* {{'TemplateParameters::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}2751// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}2752#endif2753 2754#if defined(FIRST)2755template <int* A = nullptr>2756struct S8 {};2757#elif defined(SECOND)2758inline int S8_default_arg = 0x12345;2759template <int* A = &S8_default_arg>2760struct S8 {};2761#else2762using TemplateParameters::S8;2763// expected-error@second.h:* {{'TemplateParameters::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}2764// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}2765#endif2766 2767#if defined(FIRST)2768template <int A = 43>2769struct S9 {};2770#elif defined(SECOND)2771template <int A = 43>2772struct S9 {};2773#else2774using TemplateParameters::S9;2775#endif2776 2777#if defined(FIRST)2778template <class A = double>2779struct S10 {};2780#elif defined(SECOND)2781template <class A = double>2782struct S10 {};2783#else2784using TemplateParameters::S10;2785#endif2786 2787#if defined(FIRST)2788template <template<int> class A = S9>2789struct S11 {};2790#elif defined(SECOND)2791template <template<int> class A = S9>2792struct S11 {};2793#else2794using TemplateParameters::S11;2795#endif2796 2797// FIXME: It looks like we didn't implement ODR check for template variables.2798// S12, S13 and S14 show this.2799#if defined(FIRST)2800template <int A = 43>2801int S12 {};2802#elif defined(SECOND)2803template <int A = 44>2804int S12 {};2805#else2806using TemplateParameters::S12;2807#endif2808 2809#if defined(FIRST)2810template <class A = double>2811int S13 {};2812#elif defined(SECOND)2813template <class A = int>2814int S13 {};2815#else2816using TemplateParameters::S13;2817#endif2818 2819#if defined(FIRST)2820template <class A>2821int S14 {};2822#elif defined(SECOND)2823template <class B>2824int S14 {};2825#else2826using TemplateParameters::S14;2827#endif2828 2829#define DECLS2830 2831#if defined(FIRST) || defined(SECOND)2832template <class> class DefaultArg;2833#endif2834 2835#if defined(FIRST) || defined(SECOND)2836template <int, class, template <class> class,2837          int A, class B, template <int> class C,2838          int D = 1, class E = int, template <class F> class = DefaultArg>2839struct Valid1 {2840  DECLS2841};2842#else2843using TemplateParameters::Valid1;2844#endif2845 2846#if defined(FIRST) || defined(SECOND)2847template <int, class, template <class> class,2848          int A, class B, template <int> class C,2849          int D = 1, class E = int, template <class F> class = DefaultArg>2850struct Invalid1 {2851  DECLS2852  ACCESS2853};2854#else2855using TemplateParameters::Invalid1;2856// expected-error@second.h:* {{'TemplateParameters::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}2857// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}2858#endif2859#undef DECLS2860}  // namespace TemplateParameters2861 2862namespace BaseClass {2863#if defined(FIRST)2864struct B1 {};2865struct S1 : B1 {};2866#elif defined(SECOND)2867struct S1 {};2868#else2869S1 s1;2870// expected-error@second.h:* {{'BaseClass::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 base classes}}2871// expected-note@first.h:* {{but in 'FirstModule' found 1 base class}}2872#endif2873 2874#if defined(FIRST)2875struct S2 {};2876#elif defined(SECOND)2877struct B2 {};2878struct S2 : virtual B2 {};2879#else2880S2 s2;2881// expected-error@second.h:* {{'BaseClass::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 base class}}2882// expected-note@first.h:* {{but in 'FirstModule' found 0 base classes}}2883#endif2884 2885#if defined(FIRST)2886struct B3a {};2887struct S3 : B3a {};2888#elif defined(SECOND)2889struct B3b {};2890struct S3 : virtual B3b {};2891#else2892S3 s3;2893// expected-error@second.h:* {{'BaseClass::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}2894// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}2895#endif2896 2897#if defined(FIRST)2898struct B4a {};2899struct S4 : B4a {};2900#elif defined(SECOND)2901struct B4b {};2902struct S4 : B4b {};2903#else2904S4 s4;2905// expected-error@second.h:* {{'BaseClass::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class with type 'B4b'}}2906// expected-note@first.h:* {{but in 'FirstModule' found 1st base class with different type 'B4a'}}2907#endif2908 2909#if defined(FIRST)2910struct B5a {};2911struct S5 : virtual B5a {};2912#elif defined(SECOND)2913struct B5a {};2914struct S5 : B5a {};2915#else2916S5 s5;2917// expected-error@second.h:* {{'BaseClass::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 virtual base classes}}2918// expected-note@first.h:* {{but in 'FirstModule' found 1 virtual base class}}2919#endif2920 2921#if defined(FIRST)2922struct B6a {};2923struct S6 : B6a {};2924#elif defined(SECOND)2925struct B6a {};2926struct S6 : virtual B6a {};2927#else2928S6 s6;2929// expected-error@second.h:* {{'BaseClass::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}2930// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}2931#endif2932 2933#if defined(FIRST)2934struct B7a {};2935struct S7 : protected B7a {};2936#elif defined(SECOND)2937struct B7a {};2938struct S7 : B7a {};2939#else2940S7 s7;2941// expected-error@second.h:* {{'BaseClass::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'B7a' with no access specifier}}2942// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'B7a' with protected access specifier}}2943#endif2944 2945#if defined(FIRST)2946struct B8a {};2947struct S8 : public B8a {};2948#elif defined(SECOND)2949struct B8a {};2950struct S8 : private B8a {};2951#else2952S8 s8;2953// expected-error@second.h:* {{'BaseClass::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'B8a' with private access specifier}}2954// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'B8a' with public access specifier}}2955#endif2956 2957#if defined(FIRST)2958struct B9a {};2959struct S9 : private B9a {};2960#elif defined(SECOND)2961struct B9a {};2962struct S9 : public B9a {};2963#else2964S9 s9;2965// expected-error@second.h:* {{'BaseClass::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'B9a' with public access specifier}}2966// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'B9a' with private access specifier}}2967#endif2968 2969#if defined(FIRST)2970struct B10a {};2971struct S10 : B10a {};2972#elif defined(SECOND)2973struct B10a {};2974struct S10 : protected B10a {};2975#else2976S10 s10;2977// expected-error@second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'B10a' with protected access specifier}}2978// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'B10a' with no access specifier}}2979#endif2980 2981#define DECLS2982 2983#if defined(FIRST) || defined(SECOND)2984struct Base1 {};2985struct Base2 {};2986struct Base3 {};2987struct Base4 {};2988struct Base5 {};2989#endif2990 2991#if defined(FIRST) || defined(SECOND)2992struct Valid1 :2993  Base1, virtual Base2, protected Base3, public Base4, private Base5 {2994 2995  DECLS2996};2997#else2998Valid1 v1;2999#endif3000 3001#if defined(FIRST) || defined(SECOND)3002struct Invalid1 :3003  Base1, virtual Base2, protected Base3, public Base4, private Base5 {3004 3005  DECLS3006  ACCESS3007};3008#else3009Invalid1 i1;3010// expected-error@second.h:* {{'BaseClass::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}3011// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}3012#endif3013#undef DECLS3014}  // namespace BaseClass3015 3016namespace PointersAndReferences {3017#if defined(FIRST) || defined(SECOND)3018template<typename> struct Wrapper{};3019#endif3020 3021#if defined(FIRST)3022struct S1 {3023  Wrapper<int*> x;3024};3025#elif defined(SECOND)3026struct S1 {3027  Wrapper<float*> x;3028};3029#else3030S1 s1;3031// expected-error@first.h:* {{PointersAndReferences::S1::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S1' in module 'SecondModule'}}3032// expected-note@second.h:* {{declaration of 'x' does not match}}3033#endif3034 3035#if defined(FIRST)3036struct S2 {3037  Wrapper<int &&> x;3038};3039#elif defined(SECOND)3040struct S2 {3041  Wrapper<float &&> x;3042};3043#else3044S2 s2;3045// expected-error@first.h:* {{PointersAndReferences::S2::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S2' in module 'SecondModule'}}3046// expected-note@second.h:* {{declaration of 'x' does not match}}3047#endif3048 3049#if defined(FIRST)3050struct S3 {3051  Wrapper<int *> x;3052};3053#elif defined(SECOND)3054struct S3 {3055  Wrapper<float *> x;3056};3057#else3058S3 s3;3059// expected-error@first.h:* {{PointersAndReferences::S3::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S3' in module 'SecondModule'}}3060// expected-note@second.h:* {{declaration of 'x' does not match}}3061#endif3062 3063#if defined(FIRST)3064struct S4 {3065  Wrapper<int &> x;3066};3067#elif defined(SECOND)3068struct S4 {3069  Wrapper<float &> x;3070};3071#else3072S4 s4;3073// expected-error@first.h:* {{PointersAndReferences::S4::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S4' in module 'SecondModule'}}3074// expected-note@second.h:* {{declaration of 'x' does not match}}3075#endif3076 3077#if defined(FIRST)3078struct S5 {3079  Wrapper<S5 *> x;3080};3081#elif defined(SECOND)3082struct S5 {3083  Wrapper<const S5 *> x;3084};3085#else3086S5 s5;3087// expected-error@first.h:* {{'PointersAndReferences::S5::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S5' in module 'SecondModule'}}3088// expected-note@second.h:* {{declaration of 'x' does not match}}3089#endif3090 3091#if defined(FIRST)3092struct S6 {3093  Wrapper<int &> x;3094};3095#elif defined(SECOND)3096struct S6 {3097  Wrapper<const int &> x;3098};3099#else3100S6 s6;3101// expected-error@first.h:* {{PointersAndReferences::S6::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S6' in module 'SecondModule'}}3102// expected-note@second.h:* {{declaration of 'x' does not match}}3103#endif3104 3105#define DECLS                \3106  Wrapper<int *> x1;         \3107  Wrapper<float *> x2;       \3108  Wrapper<const float *> x3; \3109  Wrapper<int &> x4;         \3110  Wrapper<int &&> x5;        \3111  Wrapper<const int &> x6;   \3112  Wrapper<S1 *> x7;          \3113  Wrapper<S1 &> x8;          \3114  Wrapper<S1 &&> x9;3115 3116#if defined(FIRST) || defined(SECOND)3117struct Valid1 {3118  DECLS3119};3120#else3121Valid1 v1;3122#endif3123 3124#if defined(FIRST) || defined(SECOND)3125struct Invalid1 {3126  DECLS3127  ACCESS3128};3129#else3130Invalid1 i1;3131// expected-error@second.h:* {{'PointersAndReferences::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}3132// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}3133#endif3134#undef DECLS3135}  // namespace PointersAndReferences3136 3137namespace FunctionTemplate {3138#if defined(FIRST)3139struct S1 {3140  template <int, int> void foo();3141};3142#elif defined(SECOND)3143struct S1 {3144  template <int> void foo();3145};3146#else3147S1 s1;3148// expected-error@first.h:* {{'FunctionTemplate::S1::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S1' in module 'SecondModule'}}3149// expected-note@second.h:* {{declaration of 'foo' does not match}}3150#endif3151 3152#if defined(FIRST)3153struct S2 {3154  template <char> void foo();3155};3156#elif defined(SECOND)3157struct S2 {3158  template <int> void foo();3159};3160#else3161S2 s2;3162// expected-error@first.h:* {{'FunctionTemplate::S2::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S2' in module 'SecondModule'}}3163// expected-note@second.h:* {{declaration of 'foo' does not match}}3164#endif3165 3166#if defined(FIRST)3167struct S3 {3168  template <int x> void foo();3169};3170#elif defined(SECOND)3171struct S3 {3172  template <int y> void foo();3173};3174#else3175S3 s3;3176// expected-error@second.h:* {{'FunctionTemplate::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter named 'y'}}3177// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter named 'x'}}3178#endif3179 3180#if defined(FIRST)3181struct S4 {3182  template <int x> void foo();3183};3184#elif defined(SECOND)3185struct S4 {3186  template <int x> void bar();3187};3188#else3189S4 s4;3190// expected-error@first.h:* {{'FunctionTemplate::S4::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S4' in module 'SecondModule'}}3191// expected-note@second.h:* {{definition has no member 'foo'}}3192#endif3193 3194#if defined(FIRST)3195struct S5 {3196  template <int x> void foo();3197};3198#elif defined(SECOND)3199struct S5 {3200 public:3201  template <int x> void foo();3202};3203#else3204S5 s5;3205// expected-error@second.h:* {{'FunctionTemplate::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}3206// expected-note@first.h:* {{but in 'FirstModule' found function template}}3207#endif3208 3209#if defined(FIRST)3210struct S6 {3211  template <typename x = int> void foo();3212};3213#elif defined(SECOND)3214struct S6 {3215  template <typename x> void foo();3216};3217#else3218S6 s6;3219// expected-error@second.h:* {{'FunctionTemplate::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}}3220// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}}3221#endif3222 3223#if defined(FIRST)3224struct S7 {3225  template <typename x = void> void foo();3226};3227#elif defined(SECOND)3228struct S7 {3229  template <typename x = int> void foo();3230};3231#else3232S7 s7;3233// expected-error@second.h:* {{'FunctionTemplate::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'int'}}3234// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'void'}}3235#endif3236 3237#if defined(FIRST)3238template <int>3239struct U8 {};3240struct S8 {3241  template <template<int> class x = U8> void foo();3242};3243#elif defined(SECOND)3244template <int>3245struct T8 {};3246struct S8{3247  template <template<int> class x = T8> void foo();3248};3249#else3250S8 s8;3251// expected-error@second.h:* {{'FunctionTemplate::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'T8'}}3252// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'U8'}}3253#endif3254 3255#if defined(FIRST)3256template <int>3257struct U9 {};3258struct S9 { S9();3259  template <template<int> class x = U9> void foo();3260};3261#elif defined(SECOND)3262struct S9 { S9();3263  template <template<int> class x> void foo();3264};3265#else3266S9 s9;3267// expected-error@second.h:* {{'FunctionTemplate::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}}3268// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}}3269#endif3270 3271#if defined(FIRST)3272struct S10 {3273  template <template<int> class x> void foo();3274  template <template<typename> class x> void foo();3275};3276#elif defined(SECOND)3277struct S10 {3278  template <template<typename> class x> void foo();3279  template <template<int> class x> void foo();3280};3281#else3282S10 s10;3283// expected-error@second.h:* {{'FunctionTemplate::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with one type}}3284// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with different type}}3285#endif3286 3287#if defined(FIRST)3288struct S11 {3289  template <template<int> class x> void foo();3290};3291#elif defined(SECOND)3292struct S11 {3293  template <template<int> class> void foo();3294};3295#else3296S11 s11;3297// expected-error@second.h:* {{'FunctionTemplate::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no name}}3298// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter named 'x'}}3299#endif3300 3301#if defined(FIRST)3302struct S12 {3303  template <class> void foo();3304  template <class, class> void foo();3305};3306#elif defined(SECOND)3307struct S12 {3308  template <class, class> void foo();3309  template <class> void foo();3310};3311#else3312S12 s12;3313// expected-error@second.h:* {{'FunctionTemplate::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 2 template parameters}}3314// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1 template parameter}}3315#endif3316 3317#if defined(FIRST)3318struct S13 {3319  template <class = int> void foo();3320};3321#elif defined(SECOND)3322struct S13 {3323  template <class = void> void foo();3324};3325#else3326S13 s13;3327// expected-error@second.h:* {{'FunctionTemplate::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'void'}}3328// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'int'}}3329#endif3330 3331#if defined(FIRST)3332struct S14 {3333  template <class = void> void foo();3334};3335#elif defined(SECOND)3336struct S14 {3337  template <class> void foo();3338};3339#else3340S14 s14;3341// expected-error@second.h:* {{'FunctionTemplate::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}}3342// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}}3343#endif3344 3345#if defined(FIRST)3346struct S15 {3347  template <class> void foo();3348};3349#elif defined(SECOND)3350struct S15 {3351  template <class = void> void foo();3352};3353#else3354S15 s15;3355// expected-error@second.h:* {{'FunctionTemplate::S15' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument}}3356// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with no default argument}}3357#endif3358 3359#if defined(FIRST)3360struct S16 {3361  template <short> void foo();3362};3363#elif defined(SECOND)3364struct S16 {3365  template <short = 1> void foo();3366};3367#else3368S16 s16;3369// expected-error@second.h:* {{'FunctionTemplate::S16' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument}}3370// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with no default argument}}3371#endif3372 3373#if defined(FIRST)3374struct S17 {3375  template <short = 2> void foo();3376};3377#elif defined(SECOND)3378struct S17 {3379  template <short = 1 + 1> void foo();3380};3381#else3382S17 s17;3383// expected-error@second.h:* {{'FunctionTemplate::S17' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument '1 + 1'}}3384// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument '2'}}3385#endif3386 3387#if defined(FIRST)3388struct S18 {3389  template <short> void foo();3390  template <int> void foo();3391};3392#elif defined(SECOND)3393struct S18 {3394  template <int> void foo();3395  template <short> void foo();3396};3397#else3398S18 s18;3399// expected-error@second.h:* {{'FunctionTemplate::S18' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with one type}}3400// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with different type}}3401#endif3402 3403#if defined(FIRST)3404struct S19 {3405  template <short> void foo();3406  template <short...> void foo();3407};3408#elif defined(SECOND)3409struct S19 {3410  template <short...> void foo();3411  template <short> void foo();3412};3413#else3414S19 s19;3415// expected-error@second.h:* {{'FunctionTemplate::S19' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template parameter pack}}3416// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter not being a template parameter pack}}3417#endif3418 3419#if defined(FIRST)3420struct S20 {3421  template <class> void foo();3422  template <class...> void foo();3423};3424#elif defined(SECOND)3425struct S20 {3426  template <class...> void foo();3427  template <class> void foo();3428};3429#else3430S20 s20;3431// expected-error@second.h:* {{'FunctionTemplate::S20' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template parameter pack}}3432// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter not being a template parameter pack}}3433#endif3434 3435#if defined(FIRST)3436struct S21 {3437  template <template<class> class...> void foo();3438  template <template<class> class> void foo();3439};3440#elif defined(SECOND)3441struct S21 {3442  template <template<class> class> void foo();3443  template <template<class> class...> void foo();3444};3445#else3446S21 s21;3447// expected-error@second.h:* {{'FunctionTemplate::S21' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter not being a template parameter pack}}3448// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter being a template parameter pack}}3449#endif3450 3451#if defined(FIRST)3452struct S22 {3453  template <template<class> class> void foo();3454  template <class> void foo();3455  template <int> void foo();3456};3457#elif defined(SECOND)3458struct S22 {3459  template <class> void foo();3460  template <int> void foo();3461  template <template<class> class> void foo();3462};3463#else3464S22 s22;3465// expected-error@second.h:* {{'FunctionTemplate::S22' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a type template parameter}}3466// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a template template parameter}}3467#endif3468 3469#if defined(FIRST)3470struct S23 {3471  template <class> void foo();3472  template <int> void foo();3473  template <template<class> class> void foo();3474};3475#elif defined(SECOND)3476struct S23 {3477  template <int> void foo();3478  template <template<class> class> void foo();3479  template <class> void foo();3480};3481#else3482S23 s23;3483// expected-error@second.h:* {{'FunctionTemplate::S23' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a non-type template parameter}}3484// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a type template parameter}}3485#endif3486 3487#if defined(FIRST)3488struct S24 {3489  template <int> void foo();3490  template <template<class> class> void foo();3491  template <class> void foo();3492};3493#elif defined(SECOND)3494struct S24 {3495  template <template<class> class> void foo();3496  template <class> void foo();3497  template <int> void foo();3498};3499#else3500S24 s24;3501// expected-error@second.h:* {{'FunctionTemplate::S24' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template template parameter}}3502// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a non-type template parameter}}3503#endif3504 3505#if defined(FIRST)3506struct S25 {3507  template <int> void foo();3508};3509#elif defined(SECOND)3510struct S25 {3511 public:3512  template <int> void foo();3513};3514#else3515S25 s25;3516// expected-error@second.h:* {{'FunctionTemplate::S25' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}3517// expected-note@first.h:* {{but in 'FirstModule' found function template}}3518#endif3519 3520#define DECLS                                           \3521  template <int>                                        \3522  void nontype1();                                      \3523  template <int x>                                      \3524  void nontype2();                                      \3525  template <int, int>                                   \3526  void nontype3();                                      \3527  template <int x = 5>                                  \3528  void nontype4();                                      \3529  template <int... x>                                   \3530  void nontype5();                                      \3531                                                        \3532  template <class>                                      \3533  void type1();                                         \3534  template <class x>                                    \3535  void type2();                                         \3536  template <class, class>                               \3537  void type3();                                         \3538  template <class x = int>                              \3539  void type4();                                         \3540  template <class... x>                                 \3541  void type5();                                         \3542                                                        \3543  template <template <int> class>                       \3544  void template1();                                     \3545  template <template <int> class x>                     \3546  void template2();                                     \3547  template <template <int> class, template <int> class> \3548  void template3();                                     \3549  template <template <int> class x = U>                 \3550  void template4();                                     \3551  template <template <int> class... x>                  \3552  void template5();3553 3554#if defined(FIRST) || defined(SECOND)3555template<int>3556struct U {};3557struct Valid1 {3558  DECLS3559};3560#else3561Valid1 v1;3562#endif3563 3564#if defined(FIRST) || defined(SECOND)3565struct Invalid1 {3566  DECLS3567  ACCESS3568};3569#else3570Invalid1 i1;3571// expected-error@second.h:* {{'FunctionTemplate::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}3572// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}3573#endif3574#undef DECLS3575}3576 3577namespace Enums {3578#if defined(FIRST)3579enum E1 { x11 };3580#elif defined(SECOND)3581enum E1 {};3582#else3583E1 e1;3584// expected-error@first.h:* {{'Enums::x11' from module 'FirstModule' is not present in definition of 'Enums::E1' in module 'SecondModule'}}3585// expected-note@second.h:* {{definition has no member 'x11'}}3586#endif3587 3588#if defined(FIRST)3589enum E2 {};3590#elif defined(SECOND)3591enum E2 { x21 };3592#else3593E2 e2;3594// expected-error@second.h:* {{'Enums::E2' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with 1 element}}3595// expected-note@first.h:* {{but in 'FirstModule' found enum with 0 elements}}3596#endif3597 3598#if defined(FIRST)3599enum E3 { x31 };3600#elif defined(SECOND)3601enum E3 { x32 };3602#else3603E3 e3;3604// expected-error@first.h:* {{'Enums::x31' from module 'FirstModule' is not present in definition of 'Enums::E3' in module 'SecondModule'}}3605// expected-note@second.h:* {{definition has no member 'x31'}}3606#endif3607 3608#if defined(FIRST)3609enum E4 { x41 };3610#elif defined(SECOND)3611enum E4 { x41, x42 };3612#else3613E4 e4;3614// expected-error@second.h:* {{'Enums::E4' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with 2 elements}}3615// expected-note@first.h:* {{but in 'FirstModule' found enum with 1 element}}3616#endif3617 3618#if defined(FIRST)3619enum E5 { x51, x52 };3620#elif defined(SECOND)3621enum E5 { x51 };3622#else3623E5 e5;3624// expected-error@first.h:* {{'Enums::x52' from module 'FirstModule' is not present in definition of 'Enums::E5' in module 'SecondModule'}}3625// expected-note@second.h:* {{definition has no member 'x52'}}3626#endif3627 3628#if defined(FIRST)3629enum E6 { x61, x62 };3630#elif defined(SECOND)3631enum E6 { x62, x61 };3632#else3633E6 e6;3634// expected-error@second.h:* {{'Enums::E6' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element has name 'x62'}}3635// expected-note@first.h:* {{but in 'FirstModule' found 1st element has name 'x61'}}3636#endif3637 3638#if defined(FIRST)3639enum E7 { x71 = 0 };3640#elif defined(SECOND)3641enum E7 { x71 };3642#else3643E7 e7;3644// expected-error@second.h:* {{'Enums::E7' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element 'x71' has an initializer}}3645// expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x71' does not have an initializer}}3646#endif3647 3648#if defined(FIRST)3649enum E8 { x81 };3650#elif defined(SECOND)3651enum E8 { x81 = 0 };3652#else3653E8 e8;3654// expected-error@second.h:* {{'Enums::E8' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element 'x81' does not have an initializer}}3655// expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x81' has an initializer}}3656#endif3657 3658#if defined(FIRST)3659enum E9 { x91 = 0, x92 = 1 };3660#elif defined(SECOND)3661enum E9 { x91 = 0, x92 = 2 - 1 };3662#else3663E9 e9;3664// expected-error@second.h:* {{'Enums::E9' has different definitions in different modules; definition in module 'SecondModule' first difference is 2nd element 'x92' has an initializer}}3665// expected-note@first.h:* {{but in 'FirstModule' found 2nd element 'x92' has different initializer}}3666#endif3667 3668#if defined(FIRST)3669enum class E10 : int {};3670#elif defined(SECOND)3671enum class E10 {};3672#else3673E10 e10;3674// expected-error@second.h:* {{'Enums::E10' has different definitions in different modules; definition in module 'SecondModule' first difference is enum without specified type}}3675// expected-note@first.h:* {{but in 'FirstModule' found enum with specified type}}3676#endif3677 3678#if defined(FIRST)3679enum E11 {};3680#elif defined(SECOND)3681enum E11 : int {};3682#else3683E11 e11;3684// expected-error@second.h:* {{'Enums::E11' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with specified type}}3685// expected-note@first.h:* {{but in 'FirstModule' found enum without specified type}}3686#endif3687 3688#if defined(FIRST)3689enum struct E12 : long {};3690#elif defined(SECOND)3691enum struct E12 : int {};3692#else3693E12 e12;3694// expected-error@second.h:* {{'Enums::E12' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with specified type 'int'}}3695// expected-note@first.h:* {{but in 'FirstModule' found enum with specified type 'long'}}3696#endif3697 3698#if defined(FIRST)3699enum struct E13 {};3700#elif defined(SECOND)3701enum E13 {};3702#else3703E13 e13;3704// expected-error@second.h:* {{'Enums::E13' has different definitions in different modules; definition in module 'SecondModule' first difference is enum that is not scoped}}3705// expected-note@first.h:* {{but in 'FirstModule' found enum that is scoped}}3706#endif3707 3708#if defined(FIRST)3709enum E14 {};3710#elif defined(SECOND)3711enum struct E14 {};3712#else3713E14 e14;3714// expected-error@second.h:* {{'Enums::E14' has different definitions in different modules; definition in module 'SecondModule' first difference is enum that is scoped}}3715// expected-note@first.h:* {{but in 'FirstModule' found enum that is not scoped}}3716#endif3717 3718#if defined(FIRST)3719enum class E15 {};3720#elif defined(SECOND)3721enum struct E15 {};3722#else3723E15 e15;3724// expected-error@second.h:* {{'Enums::E15' has different definitions in different modules; definition in module 'SecondModule' first difference is enum scoped with keyword struct}}3725// expected-note@first.h:* {{but in 'FirstModule' found enum scoped with keyword class}}3726#endif3727 3728#if defined(FIRST)3729enum struct E16 {};3730#elif defined(SECOND)3731enum class E16 {};3732#else3733E16 e16;3734// expected-error@second.h:* {{'Enums::E16' has different definitions in different modules; definition in module 'SecondModule' first difference is enum scoped with keyword class}}3735// expected-note@first.h:* {{but in 'FirstModule' found enum scoped with keyword struct}}3736#endif3737 3738#if defined(FIRST)3739enum Valid { v1 = (struct S*)0 == (struct S*)0 };3740#elif defined(SECOND)3741struct S {};3742enum Valid { v1 = (struct S*)0 == (struct S*)0 };3743#else3744Valid V;3745#endif3746}  // namespace Enums3747 3748namespace Types {3749namespace Complex {3750#if defined(FIRST)3751void invalid() {3752  _Complex float x;3753}3754void valid() {3755  _Complex float x;3756}3757#elif defined(SECOND)3758void invalid() {3759  _Complex double x;3760}3761void valid() {3762  _Complex float x;3763}3764#else3765auto function1 = invalid;3766// expected-error@second.h:* {{'Types::Complex::invalid' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3767// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3768auto function2 = valid;3769#endif3770}  // namespace Complex3771 3772namespace Decltype {3773#if defined(FIRST)3774void invalid1() {3775  decltype(1 + 1) x;3776}3777int global;3778void invalid2() {3779  decltype(global) x;3780}3781void valid() {3782  decltype(1.5) x;3783  decltype(x) y;3784}3785#elif defined(SECOND)3786void invalid1() {3787  decltype(2) x;3788}3789float global;3790void invalid2() {3791  decltype(global) x;3792}3793void valid() {3794  decltype(1.5) x;3795  decltype(x) y;3796}3797#else3798auto function1 = invalid1;3799// expected-error@second.h:* {{'Types::Decltype::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3800// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3801auto function2 = invalid2;3802// FIXME: We should reject the merge of `invalid2` and diagnose about the3803// inconsistent definition of `global`.3804auto function3 = valid;3805#endif3806}  // namespace Decltype3807 3808namespace Auto {3809#if defined(FIRST)3810void invalid1() {3811  decltype(auto) x = 1;3812}3813void invalid2() {3814  auto x = 1;3815}3816void invalid3() {3817  __auto_type x = 1;3818}3819void valid() {3820  decltype(auto) x = 1;3821  auto y = 1;3822  __auto_type z = 1;3823}3824#elif defined(SECOND)3825void invalid1() {3826  auto x = 1;3827}3828void invalid2() {3829  __auto_type x = 1;3830}3831void invalid3() {3832  decltype(auto) x = 1;3833}3834void valid() {3835  decltype(auto) x = 1;3836  auto y = 1;3837  __auto_type z = 1;3838}3839#else3840auto function1 = invalid1;3841// expected-error@second.h:* {{'Types::Auto::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3842// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3843auto function2 = invalid3;3844// expected-error@second.h:* {{'Types::Auto::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3845// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3846auto function3 = invalid2;3847// expected-error@second.h:* {{'Types::Auto::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3848// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3849auto function4 = valid;3850#endif3851}  // namespace Auto3852 3853namespace DeducedTemplateSpecialization {3854#if defined(FIRST)3855template<typename T> struct A {};3856A() -> A<int>;3857template<typename T> struct B {};3858B() -> B<int>;3859 3860void invalid1() {3861  A a{};3862}3863void invalid2() {3864  A a{};3865}3866void valid() {3867  B b{};3868}3869#elif defined(SECOND)3870template<typename T> struct A {};3871A() -> A<float>;3872template<typename T> struct B {};3873B() -> B<int>;3874 3875void invalid1() {3876  A a{};3877}3878void invalid2() {3879  B a{};3880}3881void valid() {3882  B b{};3883}3884#else3885auto function1 = invalid1;3886// FIXME: We should reject the merge of `invalid1` due to the inconsistent definition.3887auto function2 = invalid2;3888// expected-error@second.h:* {{'Types::DeducedTemplateSpecialization::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}3889// expected-note@first.h:* {{but in 'FirstModule' found a different body}}3890auto function3 = valid;3891#endif3892}  // namespace DeducedTemplateSpecialization3893 3894namespace DependentAddressSpace {3895#if defined(FIRST)3896template <int A1, int A2>3897void invalid1() {3898  using type = int __attribute__((address_space(A1)));3899}3900template <int A1>3901void invalid2() {3902  using type = float __attribute__((address_space(A1)));3903}3904template <int A1, int A2>3905void valid() {3906  using type1 = float __attribute__((address_space(A1)));3907  using type2 = int __attribute__((address_space(A2)));3908  using type3 = int __attribute__((address_space(A1 + A2)));3909}3910#elif defined(SECOND)3911template <int A1, int A2>3912void invalid1() {3913  using type = int __attribute__((address_space(A2)));3914}3915template <int A1>3916void invalid2() {3917  using type = int __attribute__((address_space(A1)));3918}3919template <int A1, int A2>3920void valid() {3921  using type1 = float __attribute__((address_space(A1)));3922  using type2 = int __attribute__((address_space(A2)));3923  using type3 = int __attribute__((address_space(A1 + A2)));3924}3925#else3926template <int A, int B>3927class S {3928  static auto function1 = invalid1<A, B>;3929  // expected-error@first.h:* {{'Types::DependentAddressSpace::invalid1' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}3930  // expected-note@second.h:* {{but in 'SecondModule' found a different body}}3931  static auto function2 = invalid2<B>;3932  // expected-error@first.h:* {{'Types::DependentAddressSpace::invalid2' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}3933  // expected-note@second.h:* {{but in 'SecondModule' found a different body}}3934  static auto function3 = valid<A, B>;3935};3936#endif3937}  // namespace DependentAddressSpace3938 3939namespace DependentSizedExtVector {3940#if defined(FIRST)3941template<int Size>3942void invalid1() {3943  typedef int __attribute__((ext_vector_type(Size))) type;3944}3945template<int Size>3946void invalid2() {3947  typedef int __attribute__((ext_vector_type(Size + 0))) type;3948}3949template<int Size>3950void valid() {3951  typedef int __attribute__((ext_vector_type(Size))) type;3952}3953#elif defined(SECOND)3954template<int Size>3955void invalid1() {3956  typedef float __attribute__((ext_vector_type(Size))) type;3957}3958template<int Size>3959void invalid2() {3960  typedef int __attribute__((ext_vector_type(Size + 1))) type;3961}3962template<int Size>3963void valid() {3964  typedef int __attribute__((ext_vector_type(Size))) type;3965}3966#else3967template <int Num>3968class S {3969  static auto Function1 = invalid1<Num>;3970  // expected-error@first.h:* {{'Types::DependentSizedExtVector::invalid1' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}3971  // expected-note@second.h:* {{but in 'SecondModule' found a different body}}3972  static auto Function2 = invalid2<Num>;3973  // expected-error@first.h:* {{'Types::DependentSizedExtVector::invalid2' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}3974  // expected-note@second.h:* {{but in 'SecondModule' found a different body}}3975  static auto Function3 = valid<Num>;3976};3977#endif3978}  // namespace DependentSizedExtVector3979 3980namespace InjectedClassName {3981#if defined(FIRST)3982struct Invalid {3983  template <int>3984  struct L2 {3985    template <int>3986    struct L3 {3987      L3 *x;3988    };3989  };3990};3991struct Valid {3992  template <int>3993  struct L2 {3994    template <int>3995    struct L3 {3996      L2 *x;3997      L3 *y;3998    };3999  };4000};4001#elif defined(SECOND)4002struct Invalid {4003  template <int>4004  struct L2 {4005    template <int>4006    struct L3 {4007      L2 *x;4008    };4009  };4010};4011struct Valid {4012  template <int>4013  struct L2 {4014    template <int>4015    struct L3 {4016      L2 *x;4017      L3 *y;4018    };4019  };4020};4021#else4022Invalid::L2<1>::L3<1> invalid;4023// expected-error@second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'Types::InjectedClassName::Invalid::L2::L3<value-parameter-1-0>' in module 'FirstModule'}}4024// expected-note@first.h:* {{declaration of 'x' does not match}}4025Valid::L2<1>::L3<1> valid;4026#endif4027}  // namespace InjectedClassName4028 4029namespace MemberPointer {4030#if defined(FIRST)4031struct A {};4032struct B {};4033 4034void Invalid1() {4035  int A::*x;4036};4037void Invalid2() {4038  int A::*x;4039}4040void Invalid3() {4041  int (A::*x)(int);4042}4043void Valid() {4044  int A::*x;4045  float A::*y;4046  bool B::*z;4047  void (A::*fun1)();4048  int (A::*fun2)();4049  void (B::*fun3)(int);4050  void (B::*fun4)(bool*, int);4051}4052#elif defined(SECOND)4053struct A {};4054struct B {};4055 4056void Invalid1() {4057  float A::*x;4058};4059void Invalid2() {4060  int B::*x;4061}4062void Invalid3() {4063  int (A::*x)(int, int);4064}4065void Valid() {4066  int A::*x;4067  float A::*y;4068  bool B::*z;4069  void (A::*fun1)();4070  int (A::*fun2)();4071  void (B::*fun3)(int);4072  void (B::*fun4)(bool*, int);4073}4074#else4075auto function1 = Invalid1;4076// expected-error@second.h:* {{'Types::MemberPointer::Invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}4077// expected-note@first.h:* {{but in 'FirstModule' found a different body}}4078auto function2 = Invalid2;4079// expected-error@second.h:* {{'Types::MemberPointer::Invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}4080// expected-note@first.h:* {{but in 'FirstModule' found a different body}}4081auto function3 = Invalid3;4082// expected-error@second.h:* {{'Types::MemberPointer::Invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}4083// expected-note@first.h:* {{but in 'FirstModule' found a different body}}4084auto function4 = Valid;4085#endif4086 4087}  // namespace MemberPointer4088 4089namespace PackExpansion {4090#if defined(FIRST)4091struct Invalid {4092  template <class... A>4093  struct L2 {4094    template <class... B>4095    struct L3 {4096      void run(A...);4097      void run(B...);4098    };4099  };4100};4101struct Valid {4102  template <class... A>4103  struct L2 {4104    template <class... B>4105    struct L3 {4106      void run(A...);4107      void run(B...);4108    };4109  };4110};4111#elif defined(SECOND)4112struct Invalid {4113  template <class... A>4114  struct L2 {4115    template <class... B>4116    struct L3 {4117      void run(B...);4118      void run(A...);4119    };4120  };4121};4122struct Valid {4123  template <class... A>4124  struct L2 {4125    template <class... B>4126    struct L3 {4127      void run(A...);4128      void run(B...);4129    };4130  };4131};4132#else4133Invalid::L2<int>::L3<short, bool> invalid;4134// expected-error@first.h:* {{'Types::PackExpansion::Invalid::L2::L3' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'run' with 1st parameter of type 'A...'}}4135// expected-note@second.h:* {{but in 'SecondModule' found method 'run' with 1st parameter of type 'B...'}}4136Valid::L2<int>::L3<short, bool> valid;4137#endif4138 4139}  // namespace PackExpansion4140 4141namespace Paren {4142#if defined(FIRST)4143void invalid() {4144  int (*x);4145}4146void valid() {4147  int (*x);4148}4149#elif defined(SECOND)4150void invalid() {4151  float (*x);4152}4153void valid() {4154  int (*x);4155}4156#else4157auto function1 = invalid;4158// expected-error@second.h:* {{'Types::Paren::invalid' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}4159// expected-note@first.h:* {{but in 'FirstModule' found a different body}}4160auto function2 = valid;4161#endif4162}  // namespace Paren4163 4164namespace SubstTemplateTypeParm {4165#if defined(FIRST)4166template <class> struct wrapper {};4167template <class, class, class> struct triple {};4168struct Valid {4169  template <class T,4170           template <class _T, class _U, class = wrapper<_T>> class A = triple>4171  struct L2 {4172    A<T, T> x;4173  };4174};4175#elif defined(SECOND)4176template <class> struct wrapper {};4177template <class, class, class> struct triple {};4178struct Valid {4179  template <class T,4180           template <class _T, class _U, class = wrapper<_T>> class A = triple>4181  struct L2 {4182    A<T, T> x;4183  };4184};4185#else4186template <class T,4187          template <class _T, class _U, class = wrapper<_T>> class A = triple>4188using V = Valid::L2<T, A>;4189#endif4190}  // namespace SubstTemplateTypeParm4191 4192namespace SubstTemplateTypeParmPack {4193}  // namespace SubstTemplateTypeParmPack4194 4195namespace UnaryTransform {4196#if defined(FIRST)4197enum class E1a : unsigned {};4198struct Invalid1 {4199  __underlying_type(E1a) x;4200};4201enum E2a : unsigned {};4202struct Invalid2 {4203  __underlying_type(E2a) x;4204};4205enum E3a {};4206struct Invalid3 {4207  __underlying_type(E3a) x;4208};4209enum E4a {};4210struct Invalid4 {4211  __underlying_type(E4a) x;4212};4213enum E1 {};4214struct Valid1 {4215  __underlying_type(E1) x;4216};4217enum E2 : unsigned {};4218struct Valid2 {4219  __underlying_type(E2) x;4220};4221enum class E3 {};4222struct Valid3 {4223  __underlying_type(E3) x;4224};4225#elif defined(SECOND)4226enum class E1b : signed {};4227struct Invalid1 {4228  __underlying_type(E1b) x;4229};4230enum class E2b : unsigned {};4231struct Invalid2 {4232  __underlying_type(E2b) x;4233};4234enum E3b : int {};4235struct Invalid3 {4236  __underlying_type(E3b) x;4237};4238enum E4b {};4239struct Invalid4 {4240  __underlying_type(E4b) x;4241};4242#else4243Invalid1 i1;4244// expected-error@first.h:* {{'Types::UnaryTransform::Invalid1::x' from module 'FirstModule' is not present in definition of 'Types::UnaryTransform::Invalid1' in module 'SecondModule'}}4245// expected-note@second.h:* {{declaration of 'x' does not match}}4246Invalid2 i2;4247// expected-error@second.h:* {{'Types::UnaryTransform::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '__underlying_type(E2b)' (aka 'unsigned int')}}4248// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type '__underlying_type(E2a)' (aka 'unsigned int')}}4249Invalid3 i3;4250// expected-error@first.h:* {{'Types::UnaryTransform::Invalid3::x' from module 'FirstModule' is not present in definition of 'Types::UnaryTransform::Invalid3' in module 'SecondModule'}}4251// expected-note@second.h:* {{declaration of 'x' does not match}}4252Invalid4 i4;4253// expected-error@second.h:* {{'Types::UnaryTransform::Invalid4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '__underlying_type(E4b)' (aka 'unsigned int')}}4254// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type '__underlying_type(E4a)' (aka 'unsigned int')}}4255Valid1 v1;4256Valid2 v2;4257Valid3 v3;4258#endif4259}  // namespace UnaryTransform4260 4261namespace UnresolvedUsing {4262#if defined(FIRST)4263template <class T> struct wrapper {};4264template <class T>4265struct Invalid {4266  using typename wrapper<T>::T1;4267  using typename wrapper<T>::T2;4268  T1 x;4269};4270template <class T>4271struct Valid {4272  using typename wrapper<T>::T1;4273  using typename wrapper<T>::T2;4274  T1 x;4275  T2 y;4276};4277#elif defined(SECOND)4278template <class T> struct wrapper {};4279template <class T>4280struct Invalid {4281  using typename wrapper<T>::T1;4282  using typename wrapper<T>::T2;4283  T2 x;4284};4285template <class T>4286struct Valid {4287  using typename wrapper<T>::T1;4288  using typename wrapper<T>::T2;4289  T1 x;4290  T2 y;4291};4292#else4293template <class T> using I = Invalid<T>;4294// expected-error@first.h:* {{'Types::UnresolvedUsing::Invalid::x' from module 'FirstModule' is not present in definition of 'Types::UnresolvedUsing::Invalid<T>' in module 'SecondModule'}}4295// expected-note@second.h:* {{declaration of 'x' does not match}}4296 4297template <class T> using V = Valid<T>;4298#endif4299 4300}  // namespace UnresolvedUsing4301 4302// Vector4303// void invalid1() {4304//  __attribute((vector_size(8))) int *x1;4305//}4306 4307}  // namespace Types4308 4309// Collection of interesting cases below.4310 4311// Naive parsing of AST can lead to cycles in processing.  Ensure4312// self-references don't trigger an endless cycles of AST node processing.4313namespace SelfReference {4314#if defined(FIRST)4315template <template <int> class T> class Wrapper {};4316 4317template <int N> class S {4318  S(Wrapper<::SelfReference::S> &Ref) {}4319};4320 4321struct Xx {4322  struct Yy {4323  };4324};4325 4326Xx::Xx::Xx::Yy yy;4327 4328namespace NNS {4329template <typename> struct Foo;4330template <template <class> class T = NNS::Foo>4331struct NestedNamespaceSpecifier {};4332}4333#endif4334}  // namespace SelfReference4335 4336namespace FriendFunction {4337#if defined(FIRST)4338void F(int = 0);4339struct S { friend void F(int); };4340#elif defined(SECOND)4341void F(int);4342struct S { friend void F(int); };4343#else4344S s;4345#endif4346 4347#if defined(FIRST)4348void G(int = 0);4349struct T {4350  friend void G(int);4351 4352  private:4353};4354#elif defined(SECOND)4355void G(int);4356struct T {4357  friend void G(int);4358 4359  public:4360};4361#else4362T t;4363// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}4364// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}4365#endif4366}  // namespace FriendFunction4367 4368namespace ImplicitDecl {4369#if defined(FIRST)4370struct S { };4371void S_Constructors() {4372  // Trigger creation of implicit contructors4373  S foo;4374  S bar = foo;4375  S baz(bar);4376}4377#elif defined(SECOND)4378struct S { };4379#else4380S s;4381#endif4382 4383#if defined(FIRST)4384struct T {4385  private:4386};4387void T_Constructors() {4388  // Trigger creation of implicit contructors4389  T foo;4390  T bar = foo;4391  T baz(bar);4392}4393#elif defined(SECOND)4394struct T {4395  public:4396};4397#else4398T t;4399// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}4400// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}4401#endif4402 4403}  // namespace ImplicitDecl4404 4405namespace TemplatedClass {4406#if defined(FIRST)4407template <class>4408struct S {};4409#elif defined(SECOND)4410template <class>4411struct S {};4412#else4413S<int> s;4414#endif4415 4416#if defined(FIRST)4417template <class>4418struct T {4419  private:4420};4421#elif defined(SECOND)4422template <class>4423struct T {4424  public:4425};4426#else4427T<int> t;4428// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}4429// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}4430#endif4431}  // namespace TemplatedClass4432 4433namespace TemplateClassWithField {4434#if defined(FIRST)4435template <class A>4436struct S {4437  A a;4438};4439#elif defined(SECOND)4440template <class A>4441struct S {4442  A a;4443};4444#else4445S<int> s;4446#endif4447 4448#if defined(FIRST)4449template <class A>4450struct T {4451  A a;4452 4453  private:4454};4455#elif defined(SECOND)4456template <class A>4457struct T {4458  A a;4459 4460  public:4461};4462#else4463T<int> t;4464// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}4465// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}4466#endif4467}  // namespace TemplateClassWithField4468 4469namespace TemplateClassWithTemplateField {4470#if defined(FIRST)4471template <class A>4472class WrapperS;4473template <class A>4474struct S {4475  WrapperS<A> a;4476};4477#elif defined(SECOND)4478template <class A>4479class WrapperS;4480template <class A>4481struct S {4482  WrapperS<A> a;4483};4484#else4485template <class A>4486class WrapperS{};4487S<int> s;4488#endif4489 4490#if defined(FIRST)4491template <class A>4492class WrapperT;4493template <class A>4494struct T {4495  WrapperT<A> a;4496 4497  public:4498};4499#elif defined(SECOND)4500template <class A>4501class WrapperT;4502template <class A>4503struct T {4504  WrapperT<A> a;4505 4506  private:4507};4508#else4509template <class A>4510class WrapperT{};4511T<int> t;4512// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}4513// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}4514#endif4515}  // namespace TemplateClassWithTemplateField4516 4517namespace EnumWithForwardDeclaration {4518#if defined(FIRST)4519enum E : int;4520struct S {4521  void get(E) {}4522};4523#elif defined(SECOND)4524enum E : int { A, B };4525struct S {4526  void get(E) {}4527};4528#else4529S s;4530#endif4531 4532#if defined(FIRST)4533struct T {4534  void get(E) {}4535  public:4536};4537#elif defined(SECOND)4538struct T {4539  void get(E) {}4540  private:4541};4542#else4543T t;4544// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}4545// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}4546#endif4547}  // namespace EnumWithForwardDeclaration4548 4549namespace StructWithForwardDeclaration {4550#if defined(FIRST)4551struct P {};4552struct S {4553  struct P *ptr;4554};4555#elif defined(SECOND)4556struct S {4557  struct P *ptr;4558};4559#else4560S s;4561#endif4562 4563#if defined(FIRST)4564struct Q {};4565struct T {4566  struct Q *ptr;4567  public:4568};4569#elif defined(SECOND)4570struct T {4571  struct Q *ptr;4572  private:4573};4574#else4575T t;4576// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}4577// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}4578#endif4579}  // namespace StructWithForwardDeclaration4580 4581namespace StructWithForwardDeclarationNoDefinition {4582#if defined(FIRST)4583struct P;4584struct S {4585  struct P *ptr;4586};4587#elif defined(SECOND)4588struct S {4589  struct P *ptr;4590};4591#else4592S s;4593#endif4594 4595#if defined(FIRST)4596struct Q;4597struct T {4598  struct Q *ptr;4599 4600  public:4601};4602#elif defined(SECOND)4603struct T {4604  struct Q *ptr;4605 4606  private:4607};4608#else4609T t;4610// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}4611// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}4612#endif4613}  // namespace StructWithForwardDeclarationNoDefinition4614 4615namespace LateParsedDefaultArgument {4616#if defined(FIRST)4617template <typename T>4618struct S {4619  struct R {4620    void foo(T x = 0) {}4621  };4622};4623#elif defined(SECOND)4624#else4625void run() {4626  S<int>::R().foo();4627}4628#endif4629}  // namespace LateParsedDefaultArgument4630 4631namespace LateParsedDefaultArgument {4632#if defined(FIRST)4633template <typename alpha> struct Bravo {4634  void charlie(bool delta = false) {}4635};4636typedef Bravo<char> echo;4637echo foxtrot;4638 4639Bravo<char> golf;4640#elif defined(SECOND)4641#else4642#endif4643}  // LateParsedDefaultArgument4644 4645namespace DifferentParameterNameInTemplate {4646#if defined(FIRST) || defined(SECOND)4647template <typename T>4648struct S {4649  typedef T Type;4650 4651  static void Run(const Type *name_one);4652};4653 4654template <typename T>4655void S<T>::Run(const T *name_two) {}4656 4657template <typename T>4658struct Foo {4659  ~Foo() { Handler::Run(nullptr); }4660  Foo() {}4661 4662  class Handler : public S<T> {};4663 4664  void Get(typename Handler::Type *x = nullptr) {}4665  void Add() { Handler::Run(nullptr); }4666};4667#endif4668 4669#if defined(FIRST)4670struct Beta;4671 4672struct Alpha {4673  Alpha();4674  void Go() { betas.Get(); }4675  Foo<Beta> betas;4676};4677 4678#elif defined(SECOND)4679struct Beta {};4680 4681struct BetaHelper {4682  void add_Beta() { betas.Add(); }4683  Foo<Beta> betas;4684};4685 4686#else4687Alpha::Alpha() {}4688#endif4689}  // DifferentParameterNameInTemplate4690 4691namespace ParameterTest {4692#if defined(FIRST)4693class X {};4694template <typename G>4695class S {4696  public:4697   typedef G Type;4698   static inline G *Foo(const G *a, int * = nullptr);4699};4700 4701template<typename G>4702G* S<G>::Foo(const G* aaaa, int*) {}4703#elif defined(SECOND)4704template <typename G>4705class S {4706  public:4707   typedef G Type;4708   static inline G *Foo(const G *a, int * = nullptr);4709};4710 4711template<typename G>4712G* S<G>::Foo(const G* asdf, int*) {}4713#else4714S<X> s;4715// expected-error@first.h:* {{'ParameterTest::S::Foo' has different definitions in different modules; definition in module 'FirstModule' first difference is 1st parameter with name 'aaaa'}}4716// expected-note@second.h:* {{but in 'SecondModule' found 1st parameter with name 'asdf'}}4717#endif4718}  // ParameterTest4719 4720namespace MultipleTypedefs {4721#if defined(FIRST)4722typedef int B1;4723typedef B1 A1;4724struct S1 {4725  A1 x;4726};4727#elif defined(SECOND)4728typedef int A1;4729struct S1 {4730  A1 x;4731};4732#else4733S1 s1;4734#endif4735 4736#if defined(FIRST)4737struct T2 { int x; };4738typedef T2 B2;4739typedef B2 A2;4740struct S2 {4741  T2 x;4742};4743#elif defined(SECOND)4744struct T2 { int x; };4745typedef T2 A2;4746struct S2 {4747  T2 x;4748};4749#else4750S2 s2;4751#endif4752 4753#if defined(FIRST)4754using A3 = const int;4755using B3 = volatile A3;4756struct S3 {4757  B3 x = 1;4758};4759#elif defined(SECOND)4760using A3 = volatile const int;4761using B3 = A3;4762struct S3 {4763  B3 x = 1;4764};4765#else4766S3 s3;4767#endif4768 4769#if defined(FIRST)4770using A4 = int;4771using B4 = A4;4772struct S4 {4773  B4 x;4774};4775#elif defined(SECOND)4776using A4 = int;4777using B4 = ::MultipleTypedefs::A4;4778struct S4 {4779  B4 x;4780};4781#else4782S4 s4;4783#endif4784 4785#if defined(FIRST)4786using A5 = int;4787using B5 = MultipleTypedefs::A5;4788struct S5 {4789  B5 x;4790};4791#elif defined(SECOND)4792using A5 = int;4793using B5 = ::MultipleTypedefs::A5;4794struct S5 {4795  B5 x;4796};4797#else4798S5 s5;4799#endif4800}  // MultipleTypedefs4801 4802namespace DefaultArguments {4803#if defined(FIRST)4804template <typename T>4805struct S {4806  struct R {4807    void foo(T x = 0);4808  };4809};4810#elif defined(SECOND)4811template <typename T>4812struct S {4813  struct R {4814    void foo(T x = 1);4815  };4816};4817#else4818void run() {4819  S<int>::R().foo();4820}4821// expected-error@second.h:* {{'DefaultArguments::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}4822// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}4823#endif4824 4825#if defined(FIRST)4826template <typename alpha> struct Bravo {4827  void charlie(bool delta = false);4828};4829typedef Bravo<char> echo;4830echo foxtrot;4831#elif defined(SECOND)4832template <typename alpha> struct Bravo {4833  void charlie(bool delta = (false));4834};4835typedef Bravo<char> echo;4836echo foxtrot;4837#else4838Bravo<char> golf;4839// expected-error@second.h:* {{'DefaultArguments::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}4840// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}4841#endif4842}  // namespace DefaultArguments4843 4844namespace FunctionDecl {4845#if defined(FIRST)4846struct S1 {};4847S1 s1a;4848#elif defined(SECOND)4849struct S1 {};4850#else4851S1 s1;4852#endif4853 4854#if defined(FIRST)4855struct S2 {4856  S2() = default;4857};4858S2 s2a = S2();4859#elif defined(SECOND)4860struct S2 {4861  S2() = default;4862};4863#else4864S2 s2;4865#endif4866 4867#if defined(FIRST)4868struct S3 {4869  S3() = delete;4870};4871S3* s3c;4872#elif defined(SECOND)4873struct S3 {4874  S3() = delete;4875};4876#else4877S3* s3;4878#endif4879 4880#if defined(FIRST) || defined(SECOND)4881int F1(int x, float y = 2.7) { return 1; }4882#else4883int I1 = F1(1);4884#endif4885 4886#if defined(FIRST)4887int F2() { return 1; }4888#elif defined(SECOND)4889double F2() { return 1; }4890#else4891int I2 = F2();4892// expected-error@-1 {{call to 'F2' is ambiguous}}4893// expected-note@first.h:* {{candidate function}}4894// expected-note@second.h:* {{candidate function}}4895#endif4896 4897#if defined(FIRST)4898int F3(float) { return 1; }4899#elif defined(SECOND)4900int F3(double) { return 1; }4901#else4902int I3 = F3(1);4903// expected-error@-1 {{call to 'F3' is ambiguous}}4904// expected-note@first.h:* {{candidate function}}4905// expected-note@second.h:* {{candidate function}}4906#endif4907 4908#if defined(FIRST)4909int F4(int x) { return 1; }4910#elif defined(SECOND)4911int F4(int y) { return 1; }4912#else4913int I4 = F4(1);4914// expected-error@second.h:* {{'FunctionDecl::F4' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with name 'y'}}4915// expected-note@first.h:* {{but in 'FirstModule' found 1st parameter with name 'x'}}4916#endif4917 4918#if defined(FIRST)4919int F5(int x) { return 1; }4920#elif defined(SECOND)4921int F5(int x = 1) { return 1; }4922#else4923int I5 = F6(1);4924// expected-error@second.h:* {{'FunctionDecl::F5' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter without a default argument}}4925// expected-note@first.h:* {{but in 'FirstModule' found 1st parameter with a default argument}}4926#endif4927 4928#if defined(FIRST)4929int F6(int x = 2) { return 1; }4930#elif defined(SECOND)4931int F6(int x = 1) { return 1; }4932#else4933int I6 = F6(1);4934// expected-error@second.h:* {{'FunctionDecl::F6' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with a default argument}}4935// expected-note@first.h:* {{but in 'FirstModule' found 1st parameter with a different default argument}}4936#endif4937 4938using I = int;4939#if defined(FIRST)4940I F7() { return 0; }4941#elif defined(SECOND)4942int F7() { return 0; }4943#else4944int I7 = F7();4945// expected-error@second.h:* {{'FunctionDecl::F7' has different definitions in different modules; definition in module 'SecondModule' first difference is return type is 'int'}}4946// expected-note@first.h:* {{but in 'FirstModule' found different return type 'I' (aka 'int')}}4947#endif4948 4949#if defined(FIRST)4950int F8(int) { return 0; }4951#elif defined(SECOND)4952int F8(I) { return 0; }4953#else4954int I8 = F8(1);4955// expected-error@second.h:* {{'FunctionDecl::F8' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with type 'I' (aka 'int')}}4956// expected-note@first.h:* {{but in 'FirstModule' found 1st parameter with type 'int'}}4957#endif4958 4959#if defined(FIRST)4960int F9(int[1]) { return 0; }4961#elif defined(SECOND)4962int F9(int[2]) { return 0; }4963#else4964int I9 = F9(nullptr);4965// expected-error@second.h:* {{'FunctionDecl::F9' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with type 'int *' decayed from 'int[2]'}}4966// expected-note@first.h:* {{but in 'FirstModule' found 1st parameter with type 'int *' decayed from 'int[1]'}}4967#endif4968 4969#if defined(FIRST)4970int F10() { return 1; }4971#elif defined(SECOND)4972int F10() { return 2; }4973#else4974int I10 = F10();4975#endif4976// expected-error@second.h:* {{'FunctionDecl::F10' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}4977// expected-note@first.h:* {{but in 'FirstModule' found a different body}}4978 4979#if defined(FIRST)4980struct S11 {4981  template <int> void foo();4982};4983#elif defined(SECOND)4984struct S11 {4985  template <int> void foo();4986};4987template <int> void S11::foo() {}4988#else4989S11 s11;4990#endif4991 4992#if defined(FIRST)4993struct S12 {4994  void foo(int x);4995};4996#elif defined(SECOND)4997struct S12 {4998  void foo(int x);4999};5000void S12::foo(int y) {}5001#else5002S12 s12;5003#endif5004 5005#if defined(FIRST)5006struct S13 {5007  void foo(int x);5008};5009void S13::foo(int y) {}5010#elif defined(SECOND)5011struct S13 {5012  void foo(int x);5013};5014void S13::foo(int y) {}5015#else5016S13 s13;5017#endif5018}  // namespace FunctionDecl5019 5020namespace DeclTemplateArguments {5021#if defined(FIRST)5022int foo() { return 1; }5023int bar() { return foo(); }5024#elif defined(SECOND)5025template <class T = int>5026int foo() { return 2; }5027int bar() { return foo<>(); }5028#else5029int num = bar();5030// expected-error@second.h:* {{'DeclTemplateArguments::bar' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}5031// expected-note@first.h:* {{but in 'FirstModule' found a different body}}5032#endif5033}5034 5035namespace FunctionProtoTypeDecay {5036#if defined(FIRST)5037struct S1 {5038  struct X {};5039  using Y = X(X());5040};5041#elif defined(SECOND)5042struct S1 {5043  struct X {};5044  using Y = X(X(X()));5045};5046#else5047S1 s1;5048// expected-error@first.h:* {{'FunctionProtoTypeDecay::S1::Y' from module 'FirstModule' is not present in definition of 'FunctionProtoTypeDecay::S1' in module 'SecondModule'}}5049// expected-note@second.h:* {{declaration of 'Y' does not match}}5050#endif5051 5052#if defined(FIRST)5053struct S2 {5054  struct X {};5055  using Y =5056      X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(5057      X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(5058      X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(5059      X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(5060      ))))))))))))))))5061      ))))))))))))))))5062      ))))))))))))))))5063      ))))))))))))))));5064};5065#elif defined(SECOND)5066#else5067S2 s2;5068#endif5069}5070 5071namespace TypedefStruct {5072#if defined(FIRST)5073struct T1;5074class S1 {5075  T1* t;5076};5077#elif defined(SECOND)5078typedef struct T1 {} T1;5079class S1 {5080  T1* t;5081};5082#else5083S1 s1;5084#endif5085 5086#if defined(FIRST)5087struct T2;5088class S2 {5089  const T2* t = nullptr;5090};5091#elif defined(SECOND)5092typedef struct T2 {} T2;5093class S2 {5094  const T2* t = nullptr;5095};5096#else5097S2 s2;5098#endif5099 5100#if defined(FIRST)5101struct T3;5102class S3 {5103  T3* const t = nullptr;5104};5105#elif defined(SECOND)5106typedef struct T3 {} T3;5107class S3 {5108  T3* const t = nullptr;5109};5110#else5111S3 s3;5112#endif5113 5114#if defined(FIRST)5115namespace NS4 {5116struct T4;5117} // namespace NS45118class S4 {5119  NS4::T4* t = 0;5120};5121#elif defined(SECOND)5122namespace NS4 {5123typedef struct T4 {} T4;5124} // namespace NS45125class S4 {5126  NS4::T4* t = 0;5127};5128#else5129S4 s4;5130#endif5131 5132#if defined(FIRST)5133namespace NS5 {5134struct T5;5135} // namespace NS55136class S5 {5137  NS5::T5* t = 0;5138};5139#elif defined(SECOND)5140namespace NS5 {5141typedef struct T5_Other {} T5;5142} // namespace NS45143class S5 {5144  NS5::T5* t = 0;5145};5146#else5147S5 s5;5148// expected-error@first.h:* {{'TypedefStruct::S5::t' from module 'FirstModule' is not present in definition of 'TypedefStruct::S5' in module 'SecondModule'}}5149// expected-note@second.h:* {{declaration of 't' does not match}}5150#endif5151} // namespace TypedefStruct5152 5153#if defined (FIRST)5154typedef int T;5155namespace A {5156  struct X { T n; };5157}5158#elif defined(SECOND)5159namespace A {5160  typedef int T;5161  struct X { T n; };5162}5163#else5164A::X x;5165#endif5166 5167namespace TemplateDecltypeOperator {5168 5169#if defined(FIRST) || defined(SECOND)5170template <class T6>5171T6 func();5172#endif5173 5174#if defined(SECOND)5175template <class UnrelatedT>5176using UnrelatedAlias = decltype(func<UnrelatedT>())();5177#endif5178 5179#if defined(FIRST) || defined(SECOND)5180class A {5181  template <class T6>5182  operator decltype(func<T6>()) () {}5183};5184#else5185A a;5186#endif5187 5188}5189 5190// Keep macros contained to one file.5191#ifdef FIRST5192#undef FIRST5193#endif5194 5195#ifdef SECOND5196#undef SECOND5197#endif5198 5199#ifdef ACCESS5200#undef ACCESS5201#endif5202