Mercurial > hg > CbC > CbC_llvm
view clang/test/Modules/odr_hash.mm @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
// 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 objective-c++ %t/Inputs/first.h -fblocks -fobjc-arc // RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/second.h -fblocks -fobjc-arc // 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 objective-c++ -I%t/Inputs -verify %s -fblocks -fobjc-arc #if !defined(FIRST) && !defined(SECOND) #include "first.h" #include "second.h" #endif #if defined(FIRST) || defined(SECOND) @protocol P1 @end @protocol P2 @end @interface I1 @end @interface I2 : I1 @end @interface Interface1 <T : I1 *> { @public T<P1> x; } @end @interface Interface2 <T : I1 *> @end @interface Interface3 <T : I1 *> @end @interface EmptySelectorSlot - (void)method:(int)arg; - (void)method:(int)arg :(int)empty; - (void)multiple:(int)arg1 args:(int)arg2 :(int)arg3; - (void)multiple:(int)arg1 :(int)arg2 args:(int)arg3; @end #endif #if defined(FIRST) struct S { Interface1 *I; decltype(I->x) x; int y; }; #elif defined(SECOND) struct S { Interface1 *I; decltype(I->x) x; bool y; }; #else S s; // expected-error@second.h:* {{'S::y' from module 'SecondModule' is not present in definition of 'S' in module 'FirstModule'}} // expected-note@first.h:* {{declaration of 'y' does not match}} #endif namespace Types { namespace Attributed { #if defined(FIRST) void invalid1() { static double __attribute((objc_gc(strong))) *x; } void invalid2() { static int __attribute((objc_gc(strong))) *x; } void valid() { static int __attribute((objc_gc(strong))) *x; } #elif defined(SECOND) void invalid1() { static int __attribute((objc_gc(strong))) *x; } void invalid2() { static int __attribute((objc_gc(weak))) *x; } void valid() { static int __attribute((objc_gc(strong))) *x; } #else auto function1 = invalid1; // expected-error@second.h:* {{Types::Attributed::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} auto function2 = invalid2; auto function3 = valid; #endif } // namespace Attributed namespace BlockPointer { #if defined(FIRST) void invalid1() { void (^x)(int); } void invalid2() { void (^x)(int); } void invalid3() { void (^x)(int); } void invalid4() { void (^x)(int); } void valid() { void (^x1)(int); int (^x2)(int); void (^x3)(int, int); void (^x4)(short); } #elif defined(SECOND) void invalid1() { void (^x)(); } void invalid2() { void (^x)(int, int); } void invalid3() { int (^x)(int); } void invalid4() { void (^x)(float); } void valid() { void (^x1)(int); int (^x2)(int); void (^x3)(int, int); void (^x4)(short); } #else auto function1 = invalid1; // expected-error@second.h:* {{'Types::BlockPointer::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} auto function2 = invalid2; // expected-error@second.h:* {{'Types::BlockPointer::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} auto function3 = invalid3; // expected-error@second.h:* {{'Types::BlockPointer::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} auto function4 = invalid4; // expected-error@second.h:* {{'Types::BlockPointer::invalid4' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} auto function5 = valid; #endif } // namespace BlockPointer namespace ObjCObject { #if defined(FIRST) struct Invalid1 { using T = Interface2<I1*>; }; struct Invalid2 { using T = Interface2<I1*>; }; struct Invalid3 { using T = Interface2<P1, P1>; }; struct Invalid4 { using T = Interface2<P1>; }; struct Valid { using T1 = Interface2<I1*>; using T2 = Interface3<I1*>; using T3 = Interface2<P1>; using T4 = Interface3<P1, P2>; using T5 = __kindof Interface2; }; #elif defined(SECOND) struct Invalid1 { using T = Interface3<I1*>; }; struct Invalid2 { using T = Interface2<I2*>; }; struct Invalid3 { using T = Interface2<P1>; }; struct Invalid4 { using T = Interface2<P2>; }; struct Valid { using T1 = Interface2<I1*>; using T2 = Interface3<I1*>; using T3 = Interface2<P1>; using T4 = Interface3<P1, P2>; using T5 = __kindof Interface2; }; #else Invalid1 i1; // expected-error@first.h:* {{'Types::ObjCObject::Invalid1::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid1' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'T' does not match}} Invalid2 i2; // expected-error@first.h:* {{'Types::ObjCObject::Invalid2::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid2' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'T' does not match}} Invalid3 i3; // expected-error@second.h:* {{'Types::ObjCObject::Invalid3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'Interface2<P1>'}} // expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'Interface2<P1,P1>'}} Invalid4 i4; // expected-error@first.h:* {{'Types::ObjCObject::Invalid4::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid4' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'T' does not match}} Valid v; #endif } // namespace VisitObjCObject } // namespace Types #if defined(FIRST) @interface Interface4 <T : I1 *> { @public T<P1> x; } @end @interface Interface5 <T : I1 *> { @public T<P1> y; } @end @interface Interface6 <T1 : I1 *, T2 : I2 *> { @public T1 z; } @end #elif defined(SECOND) @interface Interface4 <T : I1 *> { @public T<P2> x; } @end @interface Interface5 <T : I1 *> { @public T<P1, P2> y; } @end @interface Interface6 <T1 : I1 *, T2 : I2 *> { @public T2 z; } @end #else #endif namespace Types { namespace ObjCTypeParam { #if defined(FIRST) || defined(SECOND) struct Invalid1 { Interface4 *I; decltype(I->x) x; }; struct Invalid2 { Interface5 *I; decltype(I->y) y; }; struct Invalid3 { Interface6 *I; decltype(I->z) z; }; #else Invalid1 i1; Invalid2 i2; Invalid3 i3; // FIXME: We should reject to merge these structs and diagnose for the // different definitions for Interface4/Interface5/Interface6. #endif } // namespace ObjCTypeParam } // namespace Types namespace CallMethods { #if defined(FIRST) void invalid1(EmptySelectorSlot *obj) { [obj method:0]; } void invalid2(EmptySelectorSlot *obj) { [obj multiple:0 args:0 :0]; } #elif defined(SECOND) void invalid1(EmptySelectorSlot *obj) { [obj method:0 :0]; } void invalid2(EmptySelectorSlot *obj) { [obj multiple:0 :0 args:0]; } #endif // expected-error@second.h:* {{'CallMethods::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} // expected-error@second.h:* {{'CallMethods::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} } // namespace CallMethods // Keep macros contained to one file. #ifdef FIRST #undef FIRST #endif #ifdef SECOND #undef SECOND #endif