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=c++11 -fblocks %t/Inputs/first.h 17 // RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/second.h 18 19 // Build module map file 20 // RUN: echo "module FirstModule {" >> %t/Inputs/module.map 21 // RUN: echo " header \"first.h\"" >> %t/Inputs/module.map 22 // RUN: echo "}" >> %t/Inputs/module.map 23 // RUN: echo "module SecondModule {" >> %t/Inputs/module.map 24 // RUN: echo " header \"second.h\"" >> %t/Inputs/module.map 25 // RUN: echo "}" >> %t/Inputs/module.map 26 27 // Run test 28 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ 29 // RUN: -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs \ 30 // RUN: -verify %s -std=c++11 -fblocks 31 32 #if !defined(FIRST) && !defined(SECOND) 33 #include "first.h" 34 #include "second.h" 35 #endif 36 37 // Used for testing 38 #if defined(FIRST) 39 #define ACCESS public: 40 #elif defined(SECOND) 41 #define ACCESS private: 42 #endif 43 44 // TODO: S1 and S2 should generate errors. 45 namespace Blocks { 46 #if defined(FIRST) 47 struct S1 { 48 void (^block)(int x) = ^(int x) { }; 49 }; 50 #elif defined(SECOND) 51 struct S1 { 52 void (^block)(int x) = ^(int y) { }; 53 }; 54 #else 55 S1 s1; 56 #endif 57 58 #if defined(FIRST) 59 struct S2 { 60 int (^block)(int x) = ^(int x) { return x + 1; }; 61 }; 62 #elif defined(SECOND) 63 struct S2 { 64 int (^block)(int x) = ^(int x) { return x; }; 65 }; 66 #else 67 S2 s2; 68 #endif 69 70 #if defined(FIRST) 71 struct S3 { 72 void run(int (^block)(int x)); 73 }; 74 #elif defined(SECOND) 75 struct S3 { 76 void run(int (^block)(int x, int y)); 77 }; 78 #else 79 S3 s3; 80 // expected-error@first.h:* {{'Blocks::S3::run' from module 'FirstModule' is not present in definition of 'Blocks::S3' in module 'SecondModule'}} 81 // expected-note@second.h:* {{declaration of 'run' does not match}} 82 #endif 83 84 #define DECLS \ 85 int (^block)(int x) = ^(int x) { return x + x; }; \ 86 void run(int (^block)(int x, int y)); 87 88 #if defined(FIRST) || defined(SECOND) 89 struct Valid1 { 90 DECLS 91 }; 92 #else 93 Valid1 v1; 94 #endif 95 96 #if defined(FIRST) || defined(SECOND) 97 struct Invalid1 { 98 DECLS 99 ACCESS 100 }; 101 #else 102 Invalid1 i1; 103 // expected-error@second.h:* {{'Blocks::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} 104 // expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} 105 #endif 106 107 #undef DECLS 108 } 109 110 // Keep macros contained to one file. 111 #ifdef FIRST 112 #undef FIRST 113 #endif 114 115 #ifdef SECOND 116 #undef SECOND 117 #endif 118 119 #ifdef ACCESS 120 #undef ACCESS 121 #endif 122