147 lines · plain
1// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}2// RUN: rm -rf %t3// RUN: split-file %s %t4// 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=InterfaceAndExtension6// RUN: FileCheck --input-file=%t/test-compatible-extensions.ll %t/test-compatible-extensions.m7 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.cache10// RUN: FileCheck --input-file=%t/test-access-extension-ivar.ll %t/test-access-extension-ivar.m11 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.cache14// RUN: FileCheck --input-file=%t/test-synthesized-ivar.ll %t/test-synthesized-ivar.m15// 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=118// RUN: FileCheck --input-file=%t/test-synthesized-ivar-extension.ll %t/test-synthesized-ivar.m19 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 miscompilations22// with a wrong ivar offset.23//24// See specific .m tests for the details of various scenarios.25 26//--- Frameworks/InterfaceAndExtension.framework/Headers/Interface.h27@interface NSObject @end28@interface ObjCInterface : NSObject29@end30 31//--- Frameworks/InterfaceAndExtension.framework/Headers/Extension.h32#import <InterfaceAndExtension/Interface.h>33@interface ObjCInterface() {34 float ivarInExtension;35 int bitfieldIvarInExtension: 3;36}37@end38 39//--- Frameworks/InterfaceAndExtension.framework/Headers/InterfaceAndExtension.h40#import <InterfaceAndExtension/Interface.h>41#import <InterfaceAndExtension/Extension.h>42 43//--- Frameworks/InterfaceAndExtension.framework/Modules/module.modulemap44framework module InterfaceAndExtension {45 umbrella header "InterfaceAndExtension.h"46 export *47 module * { export * }48}49 50//--- Frameworks/Redirecting.framework/Headers/Redirecting.h51#import <InterfaceAndExtension/InterfaceAndExtension.h>52 53//--- Frameworks/Redirecting.framework/Modules/module.modulemap54framework module Redirecting {55 header "Redirecting.h"56 export *57}58 59//--- test-compatible-extensions.m60// 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@end70// 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.h75#import <InterfaceAndExtension/InterfaceAndExtension.h>76@interface ObjCInterface() {77@public78 int accessedIvar;79}80@end81static inline void inlinedIvarAccessor(ObjCInterface *obj) {82 obj->accessedIvar = 0;83}84 85//--- Frameworks/WithInlineIvar.framework/Modules/module.modulemap86framework module WithInlineIvar {87 header "WithInlineIvar.h"88 export *89}90 91//--- test-access-extension-ivar.m92// Test accessing ivars from extensions.93#import <InterfaceAndExtension/InterfaceAndExtension.h>94@interface ObjCInterface() {95@public96 int accessedIvar;97}98@end99#import <WithInlineIvar/WithInlineIvar.h>100@implementation ObjCInterface101- (void)test {102 inlinedIvarAccessor(self);103 ivarInExtension = 0;104}105@end106// 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.h111@interface NSObject @end112@interface WithProperty: NSObject113@property (assign) int propertyName;114@end115 116//--- Frameworks/WithProperty.framework/Modules/module.modulemap117framework module WithProperty {118 header "WithProperty.h"119 export *120}121 122//--- Frameworks/BackingIvarInExtension.framework/Headers/BackingIvarInExtension.h123#import <WithProperty/WithProperty.h>124@interface WithProperty() {125 int propertyBackingIvar;126}127@end128 129//--- Frameworks/BackingIvarInExtension.framework/Modules/module.modulemap130framework module BackingIvarInExtension {131 header "BackingIvarInExtension.h"132 export *133}134 135//--- test-synthesized-ivar.m136// 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_EXTENSION140#import <BackingIvarInExtension/BackingIvarInExtension.h>141#endif142@implementation WithProperty143@synthesize propertyName = propertyBackingIvar;144@end145// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_WithProperty"146// CHECK-SAME: [1 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_WithProperty.propertyBackingIvar", {{.*}} }]147