1 // Clear and create directories 2 // RUN: rm -rf %t 3 // RUN: mkdir %t 4 // RUN: mkdir %t/cache 5 // RUN: mkdir %t/Inputs 6 7 // Build first header file 8 // RUN: echo "#define FIRST" >> %t/Inputs/first.h 9 // RUN: cat %s >> %t/Inputs/first.h 10 11 // Build second header file 12 // RUN: echo "#define SECOND" >> %t/Inputs/second.h 13 // RUN: cat %s >> %t/Inputs/second.h 14 15 // Test that each header can compile 16 // RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/first.h 17 // RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/second.h 18 19 // Build module map file 20 // RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap 21 // RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap 22 // RUN: echo "}" >> %t/Inputs/module.modulemap 23 // RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap 24 // RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap 25 // RUN: echo "}" >> %t/Inputs/module.modulemap 26 27 // Run test 28 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=gnu++11 29 30 #if !defined(FIRST) && !defined(SECOND) 31 #include "first.h" 32 #include "second.h" 33 #endif 34 35 namespace Types { 36 namespace TypeOfExpr { 37 #if defined(FIRST) 38 struct Invalid1 { 39 typeof(1 + 2) x; 40 }; 41 double global; 42 struct Invalid2 { 43 typeof(global) x; 44 }; 45 struct Valid { 46 typeof(3) x; 47 typeof(x) y; 48 typeof(Valid*) self; 49 }; 50 #elif defined(SECOND) 51 struct Invalid1 { 52 typeof(3) x; 53 }; 54 int global; 55 struct Invalid2 { 56 typeof(global) x; 57 }; 58 struct Valid { 59 typeof(3) x; 60 typeof(x) y; 61 typeof(Valid*) self; 62 }; 63 #else 64 Invalid1 i1; 65 // expected-error@first.h:* {{'Types::TypeOfExpr::Invalid1' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof (1 + 2)' (aka 'int')}} 66 // expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof (3)' (aka 'int')}} 67 Invalid2 i2; 68 69 Valid v; 70 71 // FIXME: We should diagnose the different definitions of `global`. 72 #endif 73 } // namespace TypeOfExpr 74 75 namespace TypeOf { 76 #if defined(FIRST) 77 struct Invalid1 { 78 typeof(int) x; 79 }; 80 struct Invalid2 { 81 typeof(int) x; 82 }; 83 using T = int; 84 struct Invalid3 { 85 typeof(T) x; 86 }; 87 struct Valid { 88 typeof(int) x; 89 using T = typeof(double); 90 typeof(T) y; 91 }; 92 #elif defined(SECOND) 93 struct Invalid1 { 94 typeof(double) x; 95 }; 96 using I = int; 97 struct Invalid2 { 98 typeof(I) x; 99 }; 100 using T = short; 101 struct Invalid3 { 102 typeof(T) x; 103 }; 104 struct Valid { 105 typeof(int) x; 106 using T = typeof(double); 107 typeof(T) y; 108 }; 109 #else 110 Invalid1 i1; 111 // expected-error@second.h:* {{'Types::TypeOf::Invalid1::x' from module 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid1' in module 'FirstModule'}} 112 // expected-note@first.h:* {{declaration of 'x' does not match}} 113 Invalid2 i2; 114 // expected-error@first.h:* {{'Types::TypeOf::Invalid2' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof(int)' (aka 'int')}} 115 // expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof(I)' (aka 'int')}} 116 Invalid3 i3; 117 118 // FIXME: We should reject the `Invalid3` due to the inconsistent definition of `T`. 119 120 Valid v; 121 #endif 122 } // namespace TypeOf 123 } // namespace Types 124 125 // Keep macros contained to one file. 126 #ifdef FIRST 127 #undef FIRST 128 #endif 129 130 #ifdef SECOND 131 #undef SECOND 132 #endif 133