133 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=gnu++11 %t/Inputs/first.h17// RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %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 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=gnu++1129 30#if !defined(FIRST) && !defined(SECOND)31#include "first.h"32#include "second.h"33#endif34 35namespace Types {36namespace TypeOfExpr {37#if defined(FIRST)38struct Invalid1 {39 typeof(1 + 2) x;40};41double global;42struct Invalid2 {43 typeof(global) x;44};45struct Valid {46 typeof(3) x;47 typeof(x) y;48 typeof(Valid*) self;49};50#elif defined(SECOND)51struct Invalid1 {52 typeof(3) x;53};54int global;55struct Invalid2 {56 typeof(global) x;57};58struct Valid {59 typeof(3) x;60 typeof(x) y;61 typeof(Valid*) self;62};63#else64Invalid1 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')}}67Invalid2 i2;68 69Valid v;70 71// FIXME: We should diagnose the different definitions of `global`.72#endif73} // namespace TypeOfExpr74 75namespace TypeOf {76#if defined(FIRST)77struct Invalid1 {78 typeof(int) x;79};80struct Invalid2 {81 typeof(int) x;82};83using T = int;84struct Invalid3 {85 typeof(T) x;86};87struct Valid {88 typeof(int) x;89 using T = typeof(double);90 typeof(T) y;91};92#elif defined(SECOND)93struct Invalid1 {94 typeof(double) x;95};96using I = int;97struct Invalid2 {98 typeof(I) x;99};100using T = short;101struct Invalid3 {102 typeof(T) x;103};104struct Valid {105 typeof(int) x;106 using T = typeof(double);107 typeof(T) y;108};109#else110Invalid1 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}}113Invalid2 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')}}116Invalid3 i3;117 118// FIXME: We should reject the `Invalid3` due to the inconsistent definition of `T`.119 120Valid v;121#endif122} // namespace TypeOf123} // namespace Types124 125// Keep macros contained to one file.126#ifdef FIRST127#undef FIRST128#endif129 130#ifdef SECOND131#undef SECOND132#endif133