diff options
Diffstat (limited to 'test/Modules/odr_hash-blocks.cpp')
-rw-r--r-- | test/Modules/odr_hash-blocks.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/test/Modules/odr_hash-blocks.cpp b/test/Modules/odr_hash-blocks.cpp new file mode 100644 index 000000000000..07dfa4ce2ac8 --- /dev/null +++ b/test/Modules/odr_hash-blocks.cpp @@ -0,0 +1,119 @@ +// Clear and create directories +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: mkdir %t/cache +// RUN: mkdir %t/Inputs + +// Build first header file +// RUN: echo "#define FIRST" >> %t/Inputs/first.h +// RUN: cat %s >> %t/Inputs/first.h + +// Build second header file +// RUN: echo "#define SECOND" >> %t/Inputs/second.h +// RUN: cat %s >> %t/Inputs/second.h + +// Test that each header can compile +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/first.h +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/second.h + +// Build module map file +// RUN: echo "module FirstModule {" >> %t/Inputs/module.map +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map +// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module SecondModule {" >> %t/Inputs/module.map +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map +// RUN: echo "}" >> %t/Inputs/module.map + +// Run test +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs \ +// RUN: -verify %s -std=c++11 -fblocks + +#if !defined(FIRST) && !defined(SECOND) +#include "first.h" +#include "second.h" +#endif + +// Used for testing +#if defined(FIRST) +#define ACCESS public: +#elif defined(SECOND) +#define ACCESS private: +#endif + +// TODO: S1, S2, and S3 should generate errors. +namespace Blocks { +#if defined(FIRST) +struct S1 { + void (^block)(int x) = ^(int x) { }; +}; +#elif defined(SECOND) +struct S1 { + void (^block)(int x) = ^(int y) { }; +}; +#else +S1 s1; +#endif + +#if defined(FIRST) +struct S2 { + int (^block)(int x) = ^(int x) { return x + 1; }; +}; +#elif defined(SECOND) +struct S2 { + int (^block)(int x) = ^(int x) { return x; }; +}; +#else +S2 s2; +#endif + +#if defined(FIRST) +struct S3 { + void run(int (^block)(int x)); +}; +#elif defined(SECOND) +struct S3 { + void run(int (^block)(int x, int y)); +}; +#else +S3 s3; +#endif + +#define DECLS \ + int (^block)(int x) = ^(int x) { return x + x; }; \ + void run(int (^block)(int x, int y)); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Blocks::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif + +#undef DECLS +} + +// Keep macros contained to one file. +#ifdef FIRST +#undef FIRST +#endif + +#ifdef SECOND +#undef SECOND +#endif + +#ifdef ACCESS +#undef ACCESS +#endif |