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