1// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}} 2// RUN: rm -rf %t 3// RUN: split-file %s %t 4// RUN: %clang_cc1 -emit-llvm -o %t/test-compatible-extensions.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-compatible-extensions.m \ 5// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache -fmodule-name=InterfaceAndExtension 6// RUN: FileCheck --input-file=%t/test-compatible-extensions.ll %t/test-compatible-extensions.m 7 8// RUN: %clang_cc1 -emit-llvm -o %t/test-access-extension-ivar.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-access-extension-ivar.m \ 9// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache 10// RUN: FileCheck --input-file=%t/test-access-extension-ivar.ll %t/test-access-extension-ivar.m 11 12// RUN: %clang_cc1 -emit-llvm -o %t/test-synthesized-ivar.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-synthesized-ivar.m \ 13// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache 14// RUN: FileCheck --input-file=%t/test-synthesized-ivar.ll %t/test-synthesized-ivar.m 15// RUN: %clang_cc1 -emit-llvm -o %t/test-synthesized-ivar-extension.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-synthesized-ivar.m \ 16// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache \ 17// RUN: -DIMPORT_EXTENSION=1 18// RUN: FileCheck --input-file=%t/test-synthesized-ivar-extension.ll %t/test-synthesized-ivar.m 19 20// Test various scenarios where we can end up with the same-name ivars coming from multiple modules. 21// The goal is to avoid duplicate metadata for ivars because it can lead to miscompilations 22// with a wrong ivar offset. 23// 24// See specific .m tests for the details of various scenarios. 25 26//--- Frameworks/InterfaceAndExtension.framework/Headers/Interface.h 27@interface NSObject @end 28@interface ObjCInterface : NSObject 29@end 30 31//--- Frameworks/InterfaceAndExtension.framework/Headers/Extension.h 32#import <InterfaceAndExtension/Interface.h> 33@interface ObjCInterface() { 34 float ivarInExtension; 35 int bitfieldIvarInExtension: 3; 36} 37@end 38 39//--- Frameworks/InterfaceAndExtension.framework/Headers/InterfaceAndExtension.h 40#import <InterfaceAndExtension/Interface.h> 41#import <InterfaceAndExtension/Extension.h> 42 43//--- Frameworks/InterfaceAndExtension.framework/Modules/module.modulemap 44framework module InterfaceAndExtension { 45 umbrella header "InterfaceAndExtension.h" 46 export * 47 module * { export * } 48} 49 50//--- Frameworks/Redirecting.framework/Headers/Redirecting.h 51#import <InterfaceAndExtension/InterfaceAndExtension.h> 52 53//--- Frameworks/Redirecting.framework/Modules/module.modulemap 54framework module Redirecting { 55 header "Redirecting.h" 56 export * 57} 58 59//--- test-compatible-extensions.m 60// Test adding through deserialization an extension with already declared ivars. 61 62// First create `ObjCInterface()` extension by parsing corresponding code. 63#import <InterfaceAndExtension/InterfaceAndExtension.h> 64// Now add the same extension through deserialization from the imported module. 65#import <Redirecting/Redirecting.h> 66@implementation ObjCInterface { 67 int ivarInImplementation; 68} 69@end 70// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_ObjCInterface" 71// CHECK-SAME: [3 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.ivarInExtension", {{.*}} }, %struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.bitfieldIvarInExtension", {{.*}} }, %struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.ivarInImplementation", {{.*}} }] 72 73 74//--- Frameworks/WithInlineIvar.framework/Headers/WithInlineIvar.h 75#import <InterfaceAndExtension/InterfaceAndExtension.h> 76@interface ObjCInterface() { 77@public 78 int accessedIvar; 79} 80@end 81static inline void inlinedIvarAccessor(ObjCInterface *obj) { 82 obj->accessedIvar = 0; 83} 84 85//--- Frameworks/WithInlineIvar.framework/Modules/module.modulemap 86framework module WithInlineIvar { 87 header "WithInlineIvar.h" 88 export * 89} 90 91//--- test-access-extension-ivar.m 92// Test accessing ivars from extensions. 93#import <InterfaceAndExtension/InterfaceAndExtension.h> 94@interface ObjCInterface() { 95@public 96 int accessedIvar; 97} 98@end 99#import <WithInlineIvar/WithInlineIvar.h> 100@implementation ObjCInterface 101- (void)test { 102 inlinedIvarAccessor(self); 103 ivarInExtension = 0; 104} 105@end 106// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_ObjCInterface" 107// CHECK-SAME: [3 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.accessedIvar", {{.*}} }, %struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.ivarInExtension", {{.*}} }, %struct._ivar_t { ptr @"OBJC_IVAR_$_ObjCInterface.bitfieldIvarInExtension", {{.*}} }] 108 109 110//--- Frameworks/WithProperty.framework/Headers/WithProperty.h 111@interface NSObject @end 112@interface WithProperty: NSObject 113@property (assign) int propertyName; 114@end 115 116//--- Frameworks/WithProperty.framework/Modules/module.modulemap 117framework module WithProperty { 118 header "WithProperty.h" 119 export * 120} 121 122//--- Frameworks/BackingIvarInExtension.framework/Headers/BackingIvarInExtension.h 123#import <WithProperty/WithProperty.h> 124@interface WithProperty() { 125 int propertyBackingIvar; 126} 127@end 128 129//--- Frameworks/BackingIvarInExtension.framework/Modules/module.modulemap 130framework module BackingIvarInExtension { 131 header "BackingIvarInExtension.h" 132 export * 133} 134 135//--- test-synthesized-ivar.m 136// Test when an ivar is both synthesized and when declared in an extension. 137// Behavior with and without extension should be the same. 138#import <WithProperty/WithProperty.h> 139#ifdef IMPORT_EXTENSION 140#import <BackingIvarInExtension/BackingIvarInExtension.h> 141#endif 142@implementation WithProperty 143@synthesize propertyName = propertyBackingIvar; 144@end 145// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_WithProperty" 146// CHECK-SAME: [1 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_WithProperty.propertyBackingIvar", {{.*}} }] 147