authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-22 11:45:29+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-23 12:04:17+02:00
log28d08dd8a679c009aef35070d3991cf38618938e
treec5030b9dd5db34502a0dbf8c997a8851c4bbe1bb
parent8fc0c7dce163cab311bd7f088b7a953584e24a1e

link/macho: test merging literals targeting ObjC


1 files changed, 91 insertions(+), 0 deletions(-)

test/link/macho.zig+91
......@@ -83,6 +83,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
8383 macho_step.dependOn(testDeadStripDylibs(b, .{ .target = b.host }));
8484 macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
8585 macho_step.dependOn(testLinkDirectlyCppTbd(b, .{ .target = b.host }));
86 macho_step.dependOn(testMergeLiteralsObjc(b, .{ .target = b.host }));
8687 macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
8788 macho_step.dependOn(testObjc(b, .{ .target = b.host }));
8889 macho_step.dependOn(testObjcpp(b, .{ .target = b.host }));
......@@ -1125,6 +1126,96 @@ fn testMergeLiterals2(b: *Build, opts: Options) *Step {
11251126 return test_step;
11261127}
11271128
1129fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {
1130 const test_step = addTestStep(b, "merge-literals-objc", opts);
1131
1132 const main_o = addObject(b, opts, .{ .name = "main", .objc_source_bytes =
1133 \\#import <Foundation/Foundation.h>;
1134 \\
1135 \\extern void foo();
1136 \\
1137 \\int main() {
1138 \\ NSString *thing = @"aaa";
1139 \\
1140 \\ SEL sel = @selector(lowercaseString);
1141 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
1142 \\ NSLog (@"Responds to lowercaseString: %@", lower);
1143 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")
1144 \\ NSLog(@"lowercaseString is: %@", [thing lowercaseString]);
1145 \\
1146 \\ foo();
1147 \\}
1148 });
1149
1150 const a_o = addObject(b, opts, .{ .name = "a", .objc_source_bytes =
1151 \\#import <Foundation/Foundation.h>;
1152 \\
1153 \\void foo() {
1154 \\ NSString *thing = @"aaa";
1155 \\ SEL sel = @selector(lowercaseString);
1156 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
1157 \\ NSLog (@"Responds to lowercaseString in foo(): %@", lower);
1158 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")
1159 \\ NSLog(@"lowercaseString in foo() is: %@", [thing lowercaseString]);
1160 \\ SEL sel2 = @selector(uppercaseString);
1161 \\ NSString *upper = (([thing respondsToSelector:sel2]) ? @"YES" : @"NO");
1162 \\ NSLog (@"Responds to uppercaseString in foo(): %@", upper);
1163 \\ if ([thing respondsToSelector:sel2]) //(upper == @"YES")
1164 \\ NSLog(@"uppercaseString in foo() is: %@", [thing uppercaseString]);
1165 \\}
1166 });
1167
1168 const runWithChecks = struct {
1169 fn runWithChecks(step: *Step, exe: *Compile) void {
1170 const builder = step.owner;
1171 const run = addRunArtifact(exe);
1172 run.addCheck(.{ .expect_stderr_match = builder.dupe("Responds to lowercaseString: YES") });
1173 run.addCheck(.{ .expect_stderr_match = builder.dupe("lowercaseString is: aaa") });
1174 run.addCheck(.{ .expect_stderr_match = builder.dupe("Responds to lowercaseString in foo(): YES") });
1175 run.addCheck(.{ .expect_stderr_match = builder.dupe("lowercaseString in foo() is: aaa") });
1176 run.addCheck(.{ .expect_stderr_match = builder.dupe("Responds to uppercaseString in foo(): YES") });
1177 run.addCheck(.{ .expect_stderr_match = builder.dupe("uppercaseString in foo() is: AAA") });
1178 step.dependOn(&run.step);
1179
1180 const check = exe.checkObject();
1181 check.dumpSection("__TEXT,__objc_methname");
1182 check.checkContains("lowercaseString\x00");
1183 check.dumpSection("__TEXT,__objc_methname");
1184 check.checkContains("uppercaseString\x00");
1185 step.dependOn(&check.step);
1186 }
1187 }.runWithChecks;
1188
1189 {
1190 const exe = addExecutable(b, opts, .{ .name = "main1" });
1191 exe.addObject(main_o);
1192 exe.addObject(a_o);
1193 exe.root_module.linkFramework("Foundation", .{});
1194 runWithChecks(test_step, exe);
1195 }
1196
1197 {
1198 const exe = addExecutable(b, opts, .{ .name = "main2" });
1199 exe.addObject(a_o);
1200 exe.addObject(main_o);
1201 exe.root_module.linkFramework("Foundation", .{});
1202 runWithChecks(test_step, exe);
1203 }
1204
1205 {
1206 const b_o = addObject(b, opts, .{ .name = "b" });
1207 b_o.addObject(a_o);
1208 b_o.addObject(main_o);
1209
1210 const exe = addExecutable(b, opts, .{ .name = "main3" });
1211 exe.addObject(b_o);
1212 exe.root_module.linkFramework("Foundation", .{});
1213 runWithChecks(test_step, exe);
1214 }
1215
1216 return test_step;
1217}
1218
11281219fn testMhExecuteHeader(b: *Build, opts: Options) *Step {
11291220 const test_step = addTestStep(b, "mh-execute-header", opts);
11301221