File: merge-extension-ivars.m

package info (click to toggle)
llvm-toolchain-15 1%3A15.0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,554,644 kB
  • sloc: cpp: 5,922,452; ansic: 1,012,136; asm: 674,362; python: 191,568; objc: 73,855; f90: 42,327; lisp: 31,913; pascal: 11,973; javascript: 10,144; sh: 9,421; perl: 7,447; ml: 5,527; awk: 3,523; makefile: 2,520; xml: 885; cs: 573; fortran: 567
file content (146 lines) | stat: -rw-r--r-- 5,765 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// UNSUPPORTED: -zos, -aix
// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: %clang_cc1 -emit-llvm -o %t/test-compatible-extensions.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-compatible-extensions.m \
// RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache -fmodule-name=InterfaceAndExtension
// RUN: FileCheck --input-file=%t/test-compatible-extensions.ll %t/test-compatible-extensions.m

// 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 \
// RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
// RUN: FileCheck --input-file=%t/test-access-extension-ivar.ll %t/test-access-extension-ivar.m

// RUN: %clang_cc1 -emit-llvm -o %t/test-synthesized-ivar.ll -fobjc-runtime=macosx-10.9 -F%t/Frameworks %t/test-synthesized-ivar.m \
// RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
// RUN: FileCheck --input-file=%t/test-synthesized-ivar.ll %t/test-synthesized-ivar.m
// 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 \
// RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache \
// RUN:            -DIMPORT_EXTENSION=1
// RUN: FileCheck --input-file=%t/test-synthesized-ivar-extension.ll %t/test-synthesized-ivar.m

// Test various scenarios where we can end up with the same-name ivars coming from multiple modules.
// The goal is to avoid duplicate metadata for ivars because it can lead to miscompilations
// with a wrong ivar offset.
//
// See specific .m tests for the details of various scenarios.

//--- Frameworks/InterfaceAndExtension.framework/Headers/Interface.h
@interface NSObject @end
@interface ObjCInterface : NSObject
@end

//--- Frameworks/InterfaceAndExtension.framework/Headers/Extension.h
#import <InterfaceAndExtension/Interface.h>
@interface ObjCInterface() {
  float ivarInExtension;
  int bitfieldIvarInExtension: 3;
}
@end

//--- Frameworks/InterfaceAndExtension.framework/Headers/InterfaceAndExtension.h
#import <InterfaceAndExtension/Interface.h>
#import <InterfaceAndExtension/Extension.h>

//--- Frameworks/InterfaceAndExtension.framework/Modules/module.modulemap
framework module InterfaceAndExtension {
  umbrella header "InterfaceAndExtension.h"
  export *
  module * { export * }
}

//--- Frameworks/Redirecting.framework/Headers/Redirecting.h
#import <InterfaceAndExtension/InterfaceAndExtension.h>

//--- Frameworks/Redirecting.framework/Modules/module.modulemap
framework module Redirecting {
  header "Redirecting.h"
  export *
}

//--- test-compatible-extensions.m
// Test adding through deserialization an extension with already declared ivars.

// First create `ObjCInterface()` extension by parsing corresponding code.
#import <InterfaceAndExtension/InterfaceAndExtension.h>
// Now add the same extension through deserialization from the imported module.
#import <Redirecting/Redirecting.h>
@implementation ObjCInterface {
  int ivarInImplementation;
}
@end
// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_ObjCInterface"
// 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", {{.*}} }]


//--- Frameworks/WithInlineIvar.framework/Headers/WithInlineIvar.h
#import <InterfaceAndExtension/InterfaceAndExtension.h>
@interface ObjCInterface() {
@public
  int accessedIvar;
}
@end
static inline void inlinedIvarAccessor(ObjCInterface *obj) {
  obj->accessedIvar = 0;
}

//--- Frameworks/WithInlineIvar.framework/Modules/module.modulemap
framework module WithInlineIvar {
  header "WithInlineIvar.h"
  export *
}

//--- test-access-extension-ivar.m
// Test accessing ivars from extensions.
#import <InterfaceAndExtension/InterfaceAndExtension.h>
@interface ObjCInterface() {
@public
  int accessedIvar;
}
@end
#import <WithInlineIvar/WithInlineIvar.h>
@implementation ObjCInterface
- (void)test {
  inlinedIvarAccessor(self);
  ivarInExtension = 0;
}
@end
// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_ObjCInterface"
// 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", {{.*}} }]


//--- Frameworks/WithProperty.framework/Headers/WithProperty.h
@interface NSObject @end
@interface WithProperty: NSObject
@property (assign) int propertyName;
@end

//--- Frameworks/WithProperty.framework/Modules/module.modulemap
framework module WithProperty {
  header "WithProperty.h"
  export *
}

//--- Frameworks/BackingIvarInExtension.framework/Headers/BackingIvarInExtension.h
#import <WithProperty/WithProperty.h>
@interface WithProperty() {
  int propertyBackingIvar;
}
@end

//--- Frameworks/BackingIvarInExtension.framework/Modules/module.modulemap
framework module BackingIvarInExtension {
  header "BackingIvarInExtension.h"
  export *
}

//--- test-synthesized-ivar.m
// Test when an ivar is both synthesized and when declared in an extension.
// Behavior with and without extension should be the same.
#import <WithProperty/WithProperty.h>
#ifdef IMPORT_EXTENSION
#import <BackingIvarInExtension/BackingIvarInExtension.h>
#endif
@implementation WithProperty
@synthesize propertyName = propertyBackingIvar;
@end
// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_WithProperty"
// CHECK-SAME: [1 x %struct._ivar_t] [%struct._ivar_t { ptr @"OBJC_IVAR_$_WithProperty.propertyBackingIvar", {{.*}} }]