1 // UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
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
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
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
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.
24 // See specific .m tests for the details of various scenarios.
26 //--- Frameworks/InterfaceAndExtension.framework/Headers/Interface.h
27 @interface NSObject @end
28 @interface ObjCInterface : NSObject
31 //--- Frameworks/InterfaceAndExtension.framework/Headers/Extension.h
32 #import <InterfaceAndExtension/Interface.h>
33 @interface ObjCInterface() {
34 float ivarInExtension;
35 int bitfieldIvarInExtension: 3;
39 //--- Frameworks/InterfaceAndExtension.framework/Headers/InterfaceAndExtension.h
40 #import <InterfaceAndExtension/Interface.h>
41 #import <InterfaceAndExtension/Extension.h>
43 //--- Frameworks/InterfaceAndExtension.framework/Modules/module.modulemap
44 framework module InterfaceAndExtension {
45 umbrella header "InterfaceAndExtension.h"
50 //--- Frameworks/Redirecting.framework/Headers/Redirecting.h
51 #import <InterfaceAndExtension/InterfaceAndExtension.h>
53 //--- Frameworks/Redirecting.framework/Modules/module.modulemap
54 framework module Redirecting {
55 header "Redirecting.h"
59 //--- test-compatible-extensions.m
60 // Test adding through deserialization an extension with already declared ivars.
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;
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", {{.*}} }]
74 //--- Frameworks/WithInlineIvar.framework/Headers/WithInlineIvar.h
75 #import <InterfaceAndExtension/InterfaceAndExtension.h>
76 @interface ObjCInterface() {
81 static inline void inlinedIvarAccessor(ObjCInterface *obj) {
82 obj->accessedIvar = 0;
85 //--- Frameworks/WithInlineIvar.framework/Modules/module.modulemap
86 framework module WithInlineIvar {
87 header "WithInlineIvar.h"
91 //--- test-access-extension-ivar.m
92 // Test accessing ivars from extensions.
93 #import <InterfaceAndExtension/InterfaceAndExtension.h>
94 @interface ObjCInterface() {
99 #import <WithInlineIvar/WithInlineIvar.h>
100 @implementation ObjCInterface
102 inlinedIvarAccessor(self);
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", {{.*}} }]
110 //--- Frameworks/WithProperty.framework/Headers/WithProperty.h
111 @interface NSObject @end
112 @interface WithProperty: NSObject
113 @property (assign) int propertyName;
116 //--- Frameworks/WithProperty.framework/Modules/module.modulemap
117 framework module WithProperty {
118 header "WithProperty.h"
122 //--- Frameworks/BackingIvarInExtension.framework/Headers/BackingIvarInExtension.h
123 #import <WithProperty/WithProperty.h>
124 @interface WithProperty() {
125 int propertyBackingIvar;
129 //--- Frameworks/BackingIvarInExtension.framework/Modules/module.modulemap
130 framework module BackingIvarInExtension {
131 header "BackingIvarInExtension.h"
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>
142 @implementation WithProperty
143 @synthesize propertyName = propertyBackingIvar;
145 // CHECK: @"_OBJC_$_INSTANCE_VARIABLES_WithProperty"
146 // CHECK-SAME: [1 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_WithProperty.propertyBackingIvar", {{.*}} }]