1//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides Objective-C code generation targeting the Apple runtime.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGBlocks.h"
14#include "CGCleanup.h"
15#include "CGObjCMacConstantLiteralUtil.h"
16#include "CGObjCRuntime.h"
17#include "CGRecordLayout.h"
18#include "CodeGenFunction.h"
19#include "CodeGenModule.h"
20#include "clang/AST/ASTContext.h"
21#include "clang/AST/Attr.h"
22#include "clang/AST/Decl.h"
23#include "clang/AST/DeclObjC.h"
24#include "clang/AST/Mangle.h"
25#include "clang/AST/RecordLayout.h"
26#include "clang/AST/StmtObjC.h"
27#include "clang/Basic/CodeGenOptions.h"
28#include "clang/Basic/LangOptions.h"
29#include "clang/CodeGen/CodeGenABITypes.h"
30#include "clang/CodeGen/ConstantInitBuilder.h"
31#include "llvm/ADT/CachedHashString.h"
32#include "llvm/ADT/DenseSet.h"
33#include "llvm/ADT/SetVector.h"
34#include "llvm/ADT/SmallPtrSet.h"
35#include "llvm/ADT/SmallString.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InlineAsm.h"
38#include "llvm/IR/IntrinsicInst.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/Module.h"
41#include "llvm/Support/ScopedPrinter.h"
42#include "llvm/Support/raw_ostream.h"
43#include <cstdio>
44#include <numeric>
45
46using namespace clang;
47using namespace CodeGen;
48
49namespace {
50
51// FIXME: We should find a nicer way to make the labels for metadata, string
52// concatenation is lame.
53
54class ObjCCommonTypesHelper {
55protected:
56 llvm::LLVMContext &VMContext;
57
58private:
59 // The types of these functions don't really matter because we
60 // should always bitcast before calling them.
61
62 /// id objc_msgSend (id, SEL, ...)
63 ///
64 /// The default messenger, used for sends whose ABI is unchanged from
65 /// the all-integer/pointer case.
66 llvm::FunctionCallee getMessageSendFn() const {
67 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
68 // be called a lot.
69 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
70 return CGM.CreateRuntimeFunction(
71 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true), Name: "objc_msgSend",
72 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
73 Index: llvm::AttributeList::FunctionIndex,
74 Kinds: llvm::Attribute::NonLazyBind));
75 }
76
77 /// void objc_msgSend_stret (id, SEL, ...)
78 ///
79 /// The messenger used when the return value is an aggregate returned
80 /// by indirect reference in the first argument, and therefore the
81 /// self and selector parameters are shifted over by one.
82 llvm::FunctionCallee getMessageSendStretFn() const {
83 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
84 return CGM.CreateRuntimeFunction(
85 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
86 Name: "objc_msgSend_stret");
87 }
88
89 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
90 ///
91 /// The messenger used when the return value is returned on the x87
92 /// floating-point stack; without a special entrypoint, the nil case
93 /// would be unbalanced.
94 llvm::FunctionCallee getMessageSendFpretFn() const {
95 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
96 return CGM.CreateRuntimeFunction(
97 Ty: llvm::FunctionType::get(Result: CGM.DoubleTy, Params: params, isVarArg: true),
98 Name: "objc_msgSend_fpret");
99 }
100
101 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
102 ///
103 /// The messenger used when the return value is returned in two values on the
104 /// x87 floating point stack; without a special entrypoint, the nil case
105 /// would be unbalanced. Only used on 64-bit X86.
106 llvm::FunctionCallee getMessageSendFp2retFn() const {
107 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
108 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(C&: VMContext);
109 llvm::Type *resultType =
110 llvm::StructType::get(elt1: longDoubleType, elts: longDoubleType);
111
112 return CGM.CreateRuntimeFunction(
113 Ty: llvm::FunctionType::get(Result: resultType, Params: params, isVarArg: true),
114 Name: "objc_msgSend_fp2ret");
115 }
116
117 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
118 ///
119 /// The messenger used for super calls, which have different dispatch
120 /// semantics. The class passed is the superclass of the current
121 /// class.
122 llvm::FunctionCallee getMessageSendSuperFn() const {
123 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
124 return CGM.CreateRuntimeFunction(
125 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
126 Name: "objc_msgSendSuper");
127 }
128
129 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
130 ///
131 /// A slightly different messenger used for super calls. The class
132 /// passed is the current class.
133 llvm::FunctionCallee getMessageSendSuperFn2() const {
134 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
135 return CGM.CreateRuntimeFunction(
136 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
137 Name: "objc_msgSendSuper2");
138 }
139
140 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
141 /// SEL op, ...)
142 ///
143 /// The messenger used for super calls which return an aggregate indirectly.
144 llvm::FunctionCallee getMessageSendSuperStretFn() const {
145 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
146 return CGM.CreateRuntimeFunction(
147 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
148 Name: "objc_msgSendSuper_stret");
149 }
150
151 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
152 /// SEL op, ...)
153 ///
154 /// objc_msgSendSuper_stret with the super2 semantics.
155 llvm::FunctionCallee getMessageSendSuperStretFn2() const {
156 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
157 return CGM.CreateRuntimeFunction(
158 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
159 Name: "objc_msgSendSuper2_stret");
160 }
161
162 llvm::FunctionCallee getMessageSendSuperFpretFn() const {
163 // There is no objc_msgSendSuper_fpret? How can that work?
164 return getMessageSendSuperFn();
165 }
166
167 llvm::FunctionCallee getMessageSendSuperFpretFn2() const {
168 // There is no objc_msgSendSuper_fpret? How can that work?
169 return getMessageSendSuperFn2();
170 }
171
172protected:
173 CodeGen::CodeGenModule &CGM;
174
175public:
176 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
177 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
178 llvm::PointerType *Int8PtrProgramASTy;
179 llvm::Type *IvarOffsetVarTy;
180
181 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
182 llvm::PointerType *ObjectPtrTy;
183
184 /// PtrObjectPtrTy - LLVM type for id *
185 llvm::PointerType *PtrObjectPtrTy;
186
187 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
188 llvm::PointerType *SelectorPtrTy;
189
190 // SuperCTy - clang type for struct objc_super.
191 QualType SuperCTy;
192 // SuperPtrCTy - clang type for struct objc_super *.
193 QualType SuperPtrCTy;
194
195 /// SuperTy - LLVM type for struct objc_super.
196 llvm::StructType *SuperTy;
197 /// SuperPtrTy - LLVM type for struct objc_super *.
198 llvm::PointerType *SuperPtrTy;
199
200 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
201 /// in GCC parlance).
202 llvm::StructType *PropertyTy;
203
204 /// PropertyListTy - LLVM type for struct objc_property_list
205 /// (_prop_list_t in GCC parlance).
206 llvm::StructType *PropertyListTy;
207 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
208 llvm::PointerType *PropertyListPtrTy;
209
210 // MethodTy - LLVM type for struct objc_method.
211 llvm::StructType *MethodTy;
212
213 /// CacheTy - LLVM type for struct objc_cache.
214 llvm::Type *CacheTy;
215 /// CachePtrTy - LLVM type for struct objc_cache *.
216 llvm::PointerType *CachePtrTy;
217
218 llvm::FunctionCallee getGetPropertyFn() {
219 CodeGen::CodeGenTypes &Types = CGM.getTypes();
220 ASTContext &Ctx = CGM.getContext();
221 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
222 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
223 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
224 CanQualType Params[] = {
225 IdType, SelType,
226 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};
227 llvm::FunctionType *FTy = Types.GetFunctionType(
228 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: IdType, argTypes: Params));
229 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_getProperty");
230 }
231
232 llvm::FunctionCallee getSetPropertyFn() {
233 CodeGen::CodeGenTypes &Types = CGM.getTypes();
234 ASTContext &Ctx = CGM.getContext();
235 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
236 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
237 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
238 CanQualType Params[] = {
239 IdType,
240 SelType,
241 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),
242 IdType,
243 Ctx.BoolTy,
244 Ctx.BoolTy};
245 llvm::FunctionType *FTy = Types.GetFunctionType(
246 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
247 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_setProperty");
248 }
249
250 llvm::FunctionCallee getOptimizedSetPropertyFn(bool atomic, bool copy) {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
253 // void objc_setProperty_atomic(id self, SEL _cmd,
254 // id newValue, ptrdiff_t offset);
255 // void objc_setProperty_nonatomic(id self, SEL _cmd,
256 // id newValue, ptrdiff_t offset);
257 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
258 // id newValue, ptrdiff_t offset);
259 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
260 // id newValue, ptrdiff_t offset);
261
262 SmallVector<CanQualType, 4> Params;
263 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
264 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
265 Params.push_back(Elt: IdType);
266 Params.push_back(Elt: SelType);
267 Params.push_back(Elt: IdType);
268 Params.push_back(Elt: Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
269 llvm::FunctionType *FTy = Types.GetFunctionType(
270 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
271 const char *name;
272 if (atomic && copy)
273 name = "objc_setProperty_atomic_copy";
274 else if (atomic && !copy)
275 name = "objc_setProperty_atomic";
276 else if (!atomic && copy)
277 name = "objc_setProperty_nonatomic_copy";
278 else
279 name = "objc_setProperty_nonatomic";
280
281 return CGM.CreateRuntimeFunction(Ty: FTy, Name: name);
282 }
283
284 llvm::FunctionCallee getCopyStructFn() {
285 CodeGen::CodeGenTypes &Types = CGM.getTypes();
286 ASTContext &Ctx = CGM.getContext();
287 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
288 SmallVector<CanQualType, 5> Params;
289 Params.push_back(Elt: Ctx.VoidPtrTy);
290 Params.push_back(Elt: Ctx.VoidPtrTy);
291 Params.push_back(Elt: Ctx.getCanonicalSizeType());
292 Params.push_back(Elt: Ctx.BoolTy);
293 Params.push_back(Elt: Ctx.BoolTy);
294 llvm::FunctionType *FTy = Types.GetFunctionType(
295 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
296 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_copyStruct");
297 }
298
299 /// This routine declares and returns address of:
300 /// void objc_copyCppObjectAtomic(
301 /// void *dest, const void *src,
302 /// void (*copyHelper) (void *dest, const void *source));
303 llvm::FunctionCallee getCppAtomicObjectFunction() {
304 CodeGen::CodeGenTypes &Types = CGM.getTypes();
305 ASTContext &Ctx = CGM.getContext();
306 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void
307 /// *helper);
308 SmallVector<CanQualType, 3> Params;
309 Params.push_back(Elt: Ctx.VoidPtrTy);
310 Params.push_back(Elt: Ctx.VoidPtrTy);
311 Params.push_back(Elt: Ctx.VoidPtrTy);
312 llvm::FunctionType *FTy = Types.GetFunctionType(
313 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
314 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_copyCppObjectAtomic");
315 }
316
317 llvm::FunctionCallee getEnumerationMutationFn() {
318 CodeGen::CodeGenTypes &Types = CGM.getTypes();
319 ASTContext &Ctx = CGM.getContext();
320 // void objc_enumerationMutation (id)
321 SmallVector<CanQualType, 1> Params;
322 Params.push_back(Elt: Ctx.getCanonicalParamType(T: Ctx.getObjCIdType()));
323 llvm::FunctionType *FTy = Types.GetFunctionType(
324 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
325 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_enumerationMutation");
326 }
327
328 llvm::FunctionCallee getLookUpClassFn() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
331 // Class objc_lookUpClass (const char *)
332 SmallVector<CanQualType, 1> Params;
333 Params.push_back(
334 Elt: Ctx.getCanonicalType(T: Ctx.getPointerType(T: Ctx.CharTy.withConst())));
335 llvm::FunctionType *FTy =
336 Types.GetFunctionType(Info: Types.arrangeBuiltinFunctionDeclaration(
337 resultType: Ctx.getCanonicalType(T: Ctx.getObjCClassType()), argTypes: Params));
338 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_lookUpClass");
339 }
340
341 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
342 llvm::FunctionCallee getGcReadWeakFn() {
343 // id objc_read_weak (id *)
344 llvm::Type *args[] = {CGM.DefaultPtrTy};
345 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
346 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_read_weak");
347 }
348
349 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
350 llvm::FunctionCallee getGcAssignWeakFn() {
351 // id objc_assign_weak (id, id *)
352 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
353 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
354 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_assign_weak");
355 }
356
357 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
358 llvm::FunctionCallee getGcAssignGlobalFn() {
359 // id objc_assign_global(id, id *)
360 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
361 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
362 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_assign_global");
363 }
364
365 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
366 llvm::FunctionCallee getGcAssignThreadLocalFn() {
367 // id objc_assign_threadlocal(id src, id * dest)
368 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
369 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
370 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_assign_threadlocal");
371 }
372
373 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
374 llvm::FunctionCallee getGcAssignIvarFn() {
375 // id objc_assign_ivar(id, id *, ptrdiff_t)
376 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy, CGM.PtrDiffTy};
377 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
378 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_assign_ivar");
379 }
380
381 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
382 llvm::FunctionCallee GcMemmoveCollectableFn() {
383 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
384 llvm::Type *args[] = {Int8PtrTy, Int8PtrTy, LongTy};
385 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int8PtrTy, Params: args, isVarArg: false);
386 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_memmove_collectable");
387 }
388
389 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
390 llvm::FunctionCallee getGcAssignStrongCastFn() {
391 // id objc_assign_strongCast(id, id *)
392 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
393 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: ObjectPtrTy, Params: args, isVarArg: false);
394 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_assign_strongCast");
395 }
396
397 /// ExceptionThrowFn - LLVM objc_exception_throw function.
398 llvm::FunctionCallee getExceptionThrowFn() {
399 // void objc_exception_throw(id)
400 llvm::Type *args[] = {ObjectPtrTy};
401 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: CGM.VoidTy, Params: args, isVarArg: false);
402 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_exception_throw");
403 }
404
405 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
406 llvm::FunctionCallee getExceptionRethrowFn() {
407 // void objc_exception_rethrow(void)
408 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: CGM.VoidTy, isVarArg: false);
409 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_exception_rethrow");
410 }
411
412 /// SyncEnterFn - LLVM object_sync_enter function.
413 llvm::FunctionCallee getSyncEnterFn() {
414 // int objc_sync_enter (id)
415 llvm::Type *args[] = {ObjectPtrTy};
416 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: CGM.IntTy, Params: args, isVarArg: false);
417 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_sync_enter");
418 }
419
420 /// SyncExitFn - LLVM object_sync_exit function.
421 llvm::FunctionCallee getSyncExitFn() {
422 // int objc_sync_exit (id)
423 llvm::Type *args[] = {ObjectPtrTy};
424 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: CGM.IntTy, Params: args, isVarArg: false);
425 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_sync_exit");
426 }
427
428 llvm::FunctionCallee getSendFn(bool IsSuper) const {
429 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
430 }
431
432 llvm::FunctionCallee getSendFn2(bool IsSuper) const {
433 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
434 }
435
436 llvm::FunctionCallee getSendStretFn(bool IsSuper) const {
437 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
438 }
439
440 llvm::FunctionCallee getSendStretFn2(bool IsSuper) const {
441 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
442 }
443
444 llvm::FunctionCallee getSendFpretFn(bool IsSuper) const {
445 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
446 }
447
448 llvm::FunctionCallee getSendFpretFn2(bool IsSuper) const {
449 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
450 }
451
452 llvm::FunctionCallee getSendFp2retFn(bool IsSuper) const {
453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
454 }
455
456 llvm::FunctionCallee getSendFp2RetFn2(bool IsSuper) const {
457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
458 }
459
460 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
461};
462
463/// ObjCTypesHelper - Helper class that encapsulates lazy
464/// construction of varies types used during ObjC generation.
465class ObjCTypesHelper : public ObjCCommonTypesHelper {
466public:
467 /// SymtabTy - LLVM type for struct objc_symtab.
468 llvm::StructType *SymtabTy;
469 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
470 llvm::PointerType *SymtabPtrTy;
471 /// ModuleTy - LLVM type for struct objc_module.
472 llvm::StructType *ModuleTy;
473
474 /// ProtocolTy - LLVM type for struct objc_protocol.
475 llvm::StructType *ProtocolTy;
476 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
477 llvm::PointerType *ProtocolPtrTy;
478 /// ProtocolExtensionTy - LLVM type for struct
479 /// objc_protocol_extension.
480 llvm::StructType *ProtocolExtensionTy;
481 /// ProtocolExtensionTy - LLVM type for struct
482 /// objc_protocol_extension *.
483 llvm::PointerType *ProtocolExtensionPtrTy;
484 /// MethodDescriptionTy - LLVM type for struct
485 /// objc_method_description.
486 llvm::StructType *MethodDescriptionTy;
487 /// MethodDescriptionListTy - LLVM type for struct
488 /// objc_method_description_list.
489 llvm::StructType *MethodDescriptionListTy;
490 /// MethodDescriptionListPtrTy - LLVM type for struct
491 /// objc_method_description_list *.
492 llvm::PointerType *MethodDescriptionListPtrTy;
493 /// ProtocolListTy - LLVM type for struct objc_property_list.
494 llvm::StructType *ProtocolListTy;
495 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
496 llvm::PointerType *ProtocolListPtrTy;
497 /// CategoryTy - LLVM type for struct objc_category.
498 llvm::StructType *CategoryTy;
499 /// ClassTy - LLVM type for struct objc_class.
500 llvm::StructType *ClassTy;
501 /// ClassPtrTy - LLVM type for struct objc_class *.
502 llvm::PointerType *ClassPtrTy;
503 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
504 llvm::StructType *ClassExtensionTy;
505 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
506 llvm::PointerType *ClassExtensionPtrTy;
507 // IvarTy - LLVM type for struct objc_ivar.
508 llvm::StructType *IvarTy;
509 /// IvarListTy - LLVM type for struct objc_ivar_list.
510 llvm::StructType *IvarListTy;
511 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
512 llvm::PointerType *IvarListPtrTy;
513 /// MethodListTy - LLVM type for struct objc_method_list.
514 llvm::StructType *MethodListTy;
515 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
516 llvm::PointerType *MethodListPtrTy;
517
518 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
519 llvm::StructType *ExceptionDataTy;
520
521 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
522 llvm::FunctionCallee getExceptionTryEnterFn() {
523 llvm::Type *params[] = {CGM.DefaultPtrTy};
524 return CGM.CreateRuntimeFunction(
525 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: false),
526 Name: "objc_exception_try_enter");
527 }
528
529 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
530 llvm::FunctionCallee getExceptionTryExitFn() {
531 llvm::Type *params[] = {CGM.DefaultPtrTy};
532 return CGM.CreateRuntimeFunction(
533 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: false),
534 Name: "objc_exception_try_exit");
535 }
536
537 /// ExceptionExtractFn - LLVM objc_exception_extract function.
538 llvm::FunctionCallee getExceptionExtractFn() {
539 llvm::Type *params[] = {CGM.DefaultPtrTy};
540 return CGM.CreateRuntimeFunction(
541 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: false),
542 Name: "objc_exception_extract");
543 }
544
545 /// ExceptionMatchFn - LLVM objc_exception_match function.
546 llvm::FunctionCallee getExceptionMatchFn() {
547 llvm::Type *params[] = {ClassPtrTy, ObjectPtrTy};
548 return CGM.CreateRuntimeFunction(
549 Ty: llvm::FunctionType::get(Result: CGM.Int32Ty, Params: params, isVarArg: false),
550 Name: "objc_exception_match");
551 }
552
553 /// SetJmpFn - LLVM _setjmp function.
554 llvm::FunctionCallee getSetJmpFn() {
555 // This is specifically the prototype for x86.
556 llvm::Type *params[] = {CGM.DefaultPtrTy};
557 return CGM.CreateRuntimeFunction(
558 Ty: llvm::FunctionType::get(Result: CGM.Int32Ty, Params: params, isVarArg: false), Name: "_setjmp",
559 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
560 Index: llvm::AttributeList::FunctionIndex,
561 Kinds: llvm::Attribute::NonLazyBind));
562 }
563
564public:
565 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
566};
567
568/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
569/// modern abi
570class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
571public:
572 // MethodListnfABITy - LLVM for struct _method_list_t
573 llvm::StructType *MethodListnfABITy;
574
575 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
576 llvm::PointerType *MethodListnfABIPtrTy;
577
578 // ProtocolnfABITy = LLVM for struct _protocol_t
579 llvm::StructType *ProtocolnfABITy;
580
581 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
582 llvm::PointerType *ProtocolnfABIPtrTy;
583
584 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
585 llvm::StructType *ProtocolListnfABITy;
586
587 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
588 llvm::PointerType *ProtocolListnfABIPtrTy;
589
590 // ClassnfABITy - LLVM for struct _class_t
591 llvm::StructType *ClassnfABITy;
592
593 // ClassnfABIPtrTy - LLVM for struct _class_t*
594 llvm::PointerType *ClassnfABIPtrTy;
595
596 // IvarnfABITy - LLVM for struct _ivar_t
597 llvm::StructType *IvarnfABITy;
598
599 // IvarListnfABITy - LLVM for struct _ivar_list_t
600 llvm::StructType *IvarListnfABITy;
601
602 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
603 llvm::PointerType *IvarListnfABIPtrTy;
604
605 // ClassRonfABITy - LLVM for struct _class_ro_t
606 llvm::StructType *ClassRonfABITy;
607
608 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
609 llvm::PointerType *ImpnfABITy;
610
611 // CategorynfABITy - LLVM for struct _category_t
612 llvm::StructType *CategorynfABITy;
613
614 // New types for nonfragile abi messaging.
615
616 // MessageRefTy - LLVM for:
617 // struct _message_ref_t {
618 // IMP messenger;
619 // SEL name;
620 // };
621 llvm::StructType *MessageRefTy;
622 // MessageRefCTy - clang type for struct _message_ref_t
623 QualType MessageRefCTy;
624
625 // MessageRefPtrTy - LLVM for struct _message_ref_t*
626 llvm::Type *MessageRefPtrTy;
627 // MessageRefCPtrTy - clang type for struct _message_ref_t*
628 QualType MessageRefCPtrTy;
629
630 // SuperMessageRefTy - LLVM for:
631 // struct _super_message_ref_t {
632 // SUPER_IMP messenger;
633 // SEL name;
634 // };
635 llvm::StructType *SuperMessageRefTy;
636
637 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
638 llvm::PointerType *SuperMessageRefPtrTy;
639
640 llvm::FunctionCallee getMessageSendFixupFn() {
641 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
642 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
643 return CGM.CreateRuntimeFunction(
644 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
645 Name: "objc_msgSend_fixup");
646 }
647
648 llvm::FunctionCallee getMessageSendFpretFixupFn() {
649 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
650 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
651 return CGM.CreateRuntimeFunction(
652 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
653 Name: "objc_msgSend_fpret_fixup");
654 }
655
656 llvm::FunctionCallee getMessageSendStretFixupFn() {
657 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
658 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
659 return CGM.CreateRuntimeFunction(
660 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
661 Name: "objc_msgSend_stret_fixup");
662 }
663
664 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
665 // id objc_msgSendSuper2_fixup (struct objc_super *,
666 // struct _super_message_ref_t*, ...)
667 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
668 return CGM.CreateRuntimeFunction(
669 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
670 Name: "objc_msgSendSuper2_fixup");
671 }
672
673 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
674 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
675 // struct _super_message_ref_t*, ...)
676 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
677 return CGM.CreateRuntimeFunction(
678 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
679 Name: "objc_msgSendSuper2_stret_fixup");
680 }
681
682 llvm::FunctionCallee getObjCEndCatchFn() {
683 return CGM.CreateRuntimeFunction(Ty: llvm::FunctionType::get(Result: CGM.VoidTy, isVarArg: false),
684 Name: "objc_end_catch");
685 }
686
687 llvm::FunctionCallee getObjCBeginCatchFn() {
688 llvm::Type *params[] = {Int8PtrTy};
689 return CGM.CreateRuntimeFunction(
690 Ty: llvm::FunctionType::get(Result: Int8PtrTy, Params: params, isVarArg: false), Name: "objc_begin_catch");
691 }
692
693 /// Class objc_loadClassref (void *)
694 ///
695 /// Loads from a classref. For Objective-C stub classes, this invokes the
696 /// initialization callback stored inside the stub. For all other classes
697 /// this simply dereferences the pointer.
698 llvm::FunctionCallee getLoadClassrefFn() const {
699 // Add the non-lazy-bind attribute, since objc_loadClassref is likely to
700 // be called a lot.
701 //
702 // Also it is safe to make it readnone, since we never load or store the
703 // classref except by calling this function.
704 llvm::Type *params[] = {Int8PtrPtrTy};
705 llvm::LLVMContext &C = CGM.getLLVMContext();
706 llvm::AttributeSet AS = llvm::AttributeSet::get(
707 C, Attrs: {
708 llvm::Attribute::get(Context&: C, Kind: llvm::Attribute::NonLazyBind),
709 llvm::Attribute::getWithMemoryEffects(
710 Context&: C, ME: llvm::MemoryEffects::none()),
711 llvm::Attribute::get(Context&: C, Kind: llvm::Attribute::NoUnwind),
712 });
713 llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
714 Ty: llvm::FunctionType::get(Result: ClassnfABIPtrTy, Params: params, isVarArg: false),
715 Name: "objc_loadClassref",
716 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
717 Index: llvm::AttributeList::FunctionIndex, Attrs: AS));
718 if (!CGM.getTriple().isOSBinFormatCOFF())
719 cast<llvm::Function>(Val: F.getCallee())
720 ->setLinkage(llvm::Function::ExternalWeakLinkage);
721
722 return F;
723 }
724
725 llvm::StructType *EHTypeTy;
726 llvm::Type *EHTypePtrTy;
727
728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
729};
730
731enum class ObjCLabelType {
732 ClassName,
733 MethodVarName,
734 MethodVarType,
735 PropertyName,
736 LayoutBitMap,
737};
738
739using namespace CGObjCMacConstantLiteralUtil;
740
741class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
742
743public:
744 class SKIP_SCAN {
745 public:
746 unsigned skip;
747 unsigned scan;
748 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
749 : skip(_skip), scan(_scan) {}
750 };
751
752 // clang-format off
753 /// opcode for captured block variables layout 'instructions'.
754 /// In the following descriptions, 'I' is the value of the immediate field.
755 /// (field following the opcode).
756 ///
757 enum BLOCK_LAYOUT_OPCODE {
758 /// An operator which affects how the following layout should be
759 /// interpreted.
760 /// I == 0: Halt interpretation and treat everything else as
761 /// a non-pointer. Note that this instruction is equal
762 /// to '\0'.
763 /// I != 0: Currently unused.
764 BLOCK_LAYOUT_OPERATOR = 0,
765
766 /// The next I+1 bytes do not contain a value of object pointer type.
767 /// Note that this can leave the stream unaligned, meaning that
768 /// subsequent word-size instructions do not begin at a multiple of
769 /// the pointer size.
770 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
771
772 /// The next I+1 words do not contain a value of object pointer type.
773 /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
774 /// when the required skip quantity is a multiple of the pointer size.
775 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
776
777 /// The next I+1 words are __strong pointers to Objective-C
778 /// objects or blocks.
779 BLOCK_LAYOUT_STRONG = 3,
780
781 /// The next I+1 words are pointers to __block variables.
782 BLOCK_LAYOUT_BYREF = 4,
783
784 /// The next I+1 words are __weak pointers to Objective-C
785 /// objects or blocks.
786 BLOCK_LAYOUT_WEAK = 5,
787
788 /// The next I+1 words are __unsafe_unretained pointers to
789 /// Objective-C objects or blocks.
790 BLOCK_LAYOUT_UNRETAINED = 6
791
792 /// The next I+1 words are block or object pointers with some
793 /// as-yet-unspecified ownership semantics. If we add more
794 /// flavors of ownership semantics, values will be taken from
795 /// this range.
796 ///
797 /// This is included so that older tools can at least continue
798 /// processing the layout past such things.
799 // BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
800
801 /// All other opcodes are reserved. Halt interpretation and
802 /// treat everything else as opaque.
803 };
804 // clang-format on
805
806 class RUN_SKIP {
807 public:
808 enum BLOCK_LAYOUT_OPCODE opcode;
809 CharUnits block_var_bytepos;
810 CharUnits block_var_size;
811 RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
812 CharUnits BytePos = CharUnits::Zero(),
813 CharUnits Size = CharUnits::Zero())
814 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
815
816 // Allow sorting based on byte pos.
817 bool operator<(const RUN_SKIP &b) const {
818 return block_var_bytepos < b.block_var_bytepos;
819 }
820 };
821
822protected:
823 llvm::LLVMContext &VMContext;
824 // FIXME! May not be needing this after all.
825 unsigned ObjCABI;
826
827 // arc/mrr layout of captured block literal variables.
828 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
829
830 /// LazySymbols - Symbols to generate a lazy reference for. See
831 /// DefinedSymbols and FinishModule().
832 llvm::SetVector<IdentifierInfo *> LazySymbols;
833
834 /// DefinedSymbols - External symbols which are defined by this
835 /// module. The symbols in this list and LazySymbols are used to add
836 /// special linker symbols which ensure that Objective-C modules are
837 /// linked properly.
838 llvm::SetVector<IdentifierInfo *> DefinedSymbols;
839
840 /// ClassNames - uniqued class names.
841 llvm::StringMap<llvm::GlobalVariable *> ClassNames;
842
843 /// MethodVarNames - uniqued method variable names.
844 llvm::DenseMap<Selector, llvm::GlobalVariable *> MethodVarNames;
845
846 /// DefinedCategoryNames - list of category names in form Class_Category.
847 llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
848
849 /// MethodVarTypes - uniqued method type signatures. We have to use
850 /// a StringMap here because have no other unique reference.
851 llvm::StringMap<llvm::GlobalVariable *> MethodVarTypes;
852
853 /// MethodDefinitions - map of methods which have been defined in
854 /// this translation unit.
855 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *> MethodDefinitions;
856
857 /// Information about a direct method definition
858 struct DirectMethodInfo {
859 llvm::Function
860 *Implementation; // The true implementation (where body is emitted)
861 llvm::Function *Thunk; // The nil-check thunk (nullptr if not generated)
862
863 DirectMethodInfo(llvm::Function *Impl, llvm::Function *Thunk = nullptr)
864 : Implementation(Impl), Thunk(Thunk) {}
865 };
866
867 /// DirectMethodDefinitions - map of direct methods which have been defined in
868 /// this translation unit.
869 llvm::DenseMap<const ObjCMethodDecl *, DirectMethodInfo>
870 DirectMethodDefinitions;
871
872 /// MethodSelectorStubs - Map from (selector,class) to stub function.
873 llvm::DenseMap<std::pair<Selector, StringRef>, llvm::Function *>
874 MethodSelectorStubs;
875
876 /// PropertyNames - uniqued method variable names.
877 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> PropertyNames;
878
879 /// ClassReferences - uniqued class references.
880 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> ClassReferences;
881
882 /// SelectorReferences - uniqued selector references.
883 llvm::DenseMap<Selector, llvm::GlobalVariable *> SelectorReferences;
884
885 /// Protocols - Protocols for which an objc_protocol structure has
886 /// been emitted. Forward declarations are handled by creating an
887 /// empty structure whose initializer is filled in when/if defined.
888 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> Protocols;
889
890 /// DefinedProtocols - Protocols which have actually been
891 /// defined. We should not need this, see FIXME in GenerateProtocol.
892 llvm::DenseSet<IdentifierInfo *> DefinedProtocols;
893
894 /// DefinedClasses - List of defined classes.
895 SmallVector<llvm::GlobalValue *, 16> DefinedClasses;
896
897 /// ImplementedClasses - List of @implemented classes.
898 SmallVector<const ObjCInterfaceDecl *, 16> ImplementedClasses;
899
900 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
901 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyClasses;
902
903 /// DefinedCategories - List of defined categories.
904 SmallVector<llvm::GlobalValue *, 16> DefinedCategories;
905
906 /// DefinedStubCategories - List of defined categories on class stubs.
907 SmallVector<llvm::GlobalValue *, 16> DefinedStubCategories;
908
909 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
910 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyCategories;
911
912 /// Cached reference to the class for constant strings. This value has type
913 /// int * but is actually an Obj-C class pointer.
914 llvm::WeakTrackingVH ConstantStringClassRef;
915 llvm::WeakTrackingVH ConstantArrayClassRef;
916 llvm::WeakTrackingVH ConstantDictionaryClassRef;
917
918 llvm::WeakTrackingVH ConstantIntegerNumberClassRef;
919 llvm::WeakTrackingVH ConstantFloatNumberClassRef;
920 llvm::WeakTrackingVH ConstantDoubleNumberClassRef;
921
922 /// The LLVM type corresponding to NSConstantString.
923 llvm::StructType *NSConstantStringType = nullptr;
924 llvm::StructType *NSConstantArrayType = nullptr;
925 llvm::StructType *NSConstantDictionaryType = nullptr;
926
927 llvm::StructType *NSConstantIntegerNumberType = nullptr;
928 llvm::StructType *NSConstantFloatNumberType = nullptr;
929 llvm::StructType *NSConstantDoubleNumberType = nullptr;
930
931 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
932
933 /// Uniqued CF boolean singletons.
934 llvm::GlobalVariable *DefinedCFBooleanTrue = nullptr;
935 llvm::GlobalVariable *DefinedCFBooleanFalse = nullptr;
936
937 /// Uniqued `NSNumber`s.
938 llvm::DenseMap<NSConstantNumberMapInfo, llvm::GlobalVariable *>
939 NSConstantNumberMap;
940
941 /// Cached empty collection singletons.
942 llvm::GlobalVariable *DefinedEmptyNSDictionary = nullptr;
943 llvm::GlobalVariable *DefinedEmptyNSArray = nullptr;
944
945 /// GetMethodVarName - Return a unique constant for the given
946 /// selector's name. The return value has type char *.
947 llvm::Constant *GetMethodVarName(Selector Sel);
948 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
949
950 /// GetMethodVarType - Return a unique constant for the given
951 /// method's type encoding string. The return value has type char *.
952
953 // FIXME: This is a horrible name.
954 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
955 bool Extended = false);
956 llvm::Constant *GetMethodVarType(const FieldDecl *D);
957
958 /// GetPropertyName - Return a unique constant for the given
959 /// name. The return value has type char *.
960 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
961
962 // FIXME: This can be dropped once string functions are unified.
963 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
964 const Decl *Container);
965
966 /// GetClassName - Return a unique constant for the given selector's
967 /// runtime name (which may change via use of objc_runtime_name attribute on
968 /// class or protocol definition. The return value has type char *.
969 llvm::Constant *GetClassName(StringRef RuntimeName);
970
971 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
972
973 /// BuildIvarLayout - Builds ivar layout bitmap for the class
974 /// implementation for the __strong or __weak case.
975 ///
976 /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there
977 /// are any weak ivars defined directly in the class. Meaningless unless
978 /// building a weak layout. Does not guarantee that the layout will
979 /// actually have any entries, because the ivar might be under-aligned.
980 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
981 CharUnits beginOffset, CharUnits endOffset,
982 bool forStrongLayout, bool hasMRCWeakIvars);
983
984 llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,
985 CharUnits beginOffset,
986 CharUnits endOffset) {
987 return BuildIvarLayout(OI, beginOffset, endOffset, forStrongLayout: true, hasMRCWeakIvars: false);
988 }
989
990 llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,
991 CharUnits beginOffset,
992 CharUnits endOffset,
993 bool hasMRCWeakIvars) {
994 return BuildIvarLayout(OI, beginOffset, endOffset, forStrongLayout: false, hasMRCWeakIvars);
995 }
996
997 Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT,
998 bool ByrefLayout);
999
1000 void UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime,
1001 CharUnits FieldOffset, CharUnits FieldSize);
1002
1003 void BuildRCBlockVarRecordLayout(const RecordType *RT, CharUnits BytePos,
1004 bool &HasUnion, bool ByrefLayout = false);
1005
1006 void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
1007 const RecordDecl *RD,
1008 ArrayRef<const FieldDecl *> RecFields,
1009 CharUnits BytePos, bool &HasUnion, bool ByrefLayout);
1010
1011 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
1012
1013 llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
1014
1015 /// GetIvarLayoutName - Returns a unique constant for the given
1016 /// ivar layout bitmap.
1017 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
1018 const ObjCCommonTypesHelper &ObjCTypes);
1019
1020 /// EmitPropertyList - Emit the given property list. The return
1021 /// value has type PropertyListPtrTy.
1022 llvm::Constant *EmitPropertyList(Twine Name, const Decl *Container,
1023 const ObjCContainerDecl *OCD,
1024 const ObjCCommonTypesHelper &ObjCTypes,
1025 bool IsClassProperty);
1026
1027 /// EmitProtocolMethodTypes - Generate the array of extended method type
1028 /// strings. The return value has type Int8PtrPtrTy.
1029 llvm::Constant *
1030 EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
1031 const ObjCCommonTypesHelper &ObjCTypes);
1032
1033 /// GetProtocolRef - Return a reference to the internal protocol
1034 /// description, creating an empty one if it has not been
1035 /// defined. The return value has type ProtocolPtrTy.
1036 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
1037
1038 /// Return a reference to the given Class using runtime calls rather than
1039 /// by a symbol reference.
1040 llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1041 const ObjCInterfaceDecl *ID,
1042 ObjCCommonTypesHelper &ObjCTypes);
1043
1044 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1045
1046 /// Returns the section name to use for NSNumber integer literals.
1047 static constexpr llvm::StringLiteral GetNSConstantIntegerNumberSectionName() {
1048 return "__DATA,__objc_intobj,regular,no_dead_strip";
1049 }
1050
1051 /// Returns the section name to use for NSNumber float literals.
1052 static constexpr llvm::StringLiteral GetNSConstantFloatNumberSectionName() {
1053 return "__DATA,__objc_floatobj,regular,no_dead_strip";
1054 }
1055
1056 /// Returns the section name to use for NSNumber double literals.
1057 static constexpr llvm::StringLiteral GetNSConstantDoubleNumberSectionName() {
1058 return "__DATA,__objc_doubleobj,regular,no_dead_strip";
1059 }
1060
1061 /// Returns the section name used for the internal ID arrays
1062 /// used by `NSConstantArray` and `NSConstantDictionary`.
1063 static constexpr llvm::StringLiteral
1064 GetNSConstantCollectionStorageSectionName() {
1065 return "__DATA,__objc_arraydata,regular,no_dead_strip";
1066 }
1067
1068 /// Returns the section name to use for NSArray literals.
1069 static constexpr llvm::StringLiteral GetNSConstantArraySectionName() {
1070 return "__DATA,__objc_arrayobj,regular,no_dead_strip";
1071 }
1072
1073 /// Returns the section name to use for NSDictionary literals.
1074 static constexpr llvm::StringLiteral GetNSConstantDictionarySectionName() {
1075 return "__DATA,__objc_dictobj,regular,no_dead_strip";
1076 }
1077
1078public:
1079 /// CreateMetadataVar - Create a global variable with internal
1080 /// linkage for use by the Objective-C runtime.
1081 ///
1082 /// This is a convenience wrapper which not only creates the
1083 /// variable, but also sets the section and alignment and adds the
1084 /// global to the "llvm.used" list.
1085 ///
1086 /// \param Name - The variable name.
1087 /// \param Init - The variable initializer; this is also used to
1088 /// define the type of the variable.
1089 /// \param Section - The section the variable should go into, or empty.
1090 /// \param Align - The alignment for the variable, or 0.
1091 /// \param AddToUsed - Whether the variable should be added to
1092 /// "llvm.used".
1093 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1094 ConstantStructBuilder &Init,
1095 StringRef Section, CharUnits Align,
1096 bool AddToUsed);
1097 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
1098 StringRef Section, CharUnits Align,
1099 bool AddToUsed);
1100
1101 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1102 ObjCLabelType LabelType,
1103 bool ForceNonFragileABI = false,
1104 bool NullTerminate = true);
1105
1106protected:
1107 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1108 ReturnValueSlot Return, QualType ResultType,
1109 Selector Sel, llvm::Value *Arg0,
1110 QualType Arg0Ty, bool IsSuper,
1111 const CallArgList &CallArgs,
1112 const ObjCMethodDecl *OMD,
1113 const ObjCInterfaceDecl *ClassReceiver,
1114 const ObjCCommonTypesHelper &ObjCTypes);
1115
1116 /// EmitImageInfo - Emit the image info marker used to encode some module
1117 /// level information.
1118 void EmitImageInfo();
1119
1120public:
1121 CGObjCCommonMac(CodeGen::CodeGenModule &cgm)
1122 : CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) {}
1123
1124 bool isNonFragileABI() const { return ObjCABI == 2; }
1125
1126 /// Emits, and caches, a reference to the `__kCFBooleanTrue` singleton.
1127 llvm::GlobalVariable *EmitConstantCFBooleanTrue() {
1128 if (DefinedCFBooleanTrue)
1129 return DefinedCFBooleanTrue;
1130
1131 assert(CGM.getLangOpts().ObjCRuntime.hasConstantCFBooleans() &&
1132 "The current ABI doesn't support the constant CFBooleanTrue "
1133 "singleton!");
1134
1135 DefinedCFBooleanTrue = cast<llvm::GlobalVariable>(
1136 Val: CGM.CreateRuntimeVariable(Ty: CGM.DefaultPtrTy, Name: "__kCFBooleanTrue"));
1137 DefinedCFBooleanTrue->addAttribute(Kind: "objc_arc_inert");
1138 return DefinedCFBooleanTrue;
1139 }
1140
1141 /// Emits, and caches, a reference to the `__kCFBooleanFalse` singleton.
1142 llvm::GlobalVariable *EmitConstantCFBooleanFalse() {
1143 if (DefinedCFBooleanFalse)
1144 return DefinedCFBooleanFalse;
1145
1146 assert(CGM.getLangOpts().ObjCRuntime.hasConstantCFBooleans() &&
1147 "The current ABI doesn't support the constant CFBooleanFalse "
1148 "singleton!");
1149
1150 DefinedCFBooleanFalse = cast<llvm::GlobalVariable>(
1151 Val: CGM.CreateRuntimeVariable(Ty: CGM.DefaultPtrTy, Name: "__kCFBooleanFalse"));
1152 DefinedCFBooleanFalse->addAttribute(Kind: "objc_arc_inert");
1153 return DefinedCFBooleanFalse;
1154 }
1155
1156 /// Emits, and caches, a reference to the empty dictionary singleton.
1157 llvm::GlobalVariable *EmitEmptyConstantNSDictionary() {
1158 if (DefinedEmptyNSDictionary)
1159 return DefinedEmptyNSDictionary;
1160
1161 assert(CGM.getLangOpts().ObjCRuntime.hasConstantEmptyCollections() &&
1162 "The current ABI doesn't support an empty constant NSDictionary "
1163 "singleton!");
1164
1165 DefinedEmptyNSDictionary = cast<llvm::GlobalVariable>(
1166 Val: CGM.CreateRuntimeVariable(Ty: CGM.DefaultPtrTy, Name: "__NSDictionary0__struct"));
1167 DefinedEmptyNSDictionary->addAttribute(Kind: "objc_arc_inert");
1168 return DefinedEmptyNSDictionary;
1169 }
1170
1171 /// Emits, and caches, a reference to the empty array singleton.
1172 llvm::GlobalVariable *EmitEmptyConstantNSArray() {
1173 if (DefinedEmptyNSArray)
1174 return DefinedEmptyNSArray;
1175
1176 assert(
1177 CGM.getLangOpts().ObjCRuntime.hasConstantEmptyCollections() &&
1178 "The current ABI doesn't support an empty constant NSArray singleton!");
1179
1180 DefinedEmptyNSArray = cast<llvm::GlobalVariable>(
1181 Val: CGM.CreateRuntimeVariable(Ty: CGM.DefaultPtrTy, Name: "__NSArray0__struct"));
1182 DefinedEmptyNSArray->addAttribute(Kind: "objc_arc_inert");
1183 return DefinedEmptyNSArray;
1184 }
1185
1186 ConstantAddress GenerateConstantString(const StringLiteral *SL) override;
1187
1188 ConstantAddress GenerateConstantNumber(const bool Value,
1189 const QualType &Ty) override;
1190 ConstantAddress GenerateConstantNumber(const llvm::APSInt &Value,
1191 const QualType &Ty) override;
1192 ConstantAddress GenerateConstantNumber(const llvm::APFloat &Value,
1193 const QualType &Ty) override;
1194 ConstantAddress
1195 GenerateConstantArray(const ArrayRef<llvm::Constant *> &Objects) override;
1196 ConstantAddress GenerateConstantDictionary(
1197 const ObjCDictionaryLiteral *E,
1198 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects)
1199 override;
1200
1201 ConstantAddress GenerateConstantNSString(const StringLiteral *SL);
1202 ConstantAddress GenerateConstantNSNumber(const bool Value,
1203 const QualType &Ty);
1204 ConstantAddress GenerateConstantNSNumber(const llvm::APSInt &Value,
1205 const QualType &Ty);
1206 ConstantAddress GenerateConstantNSNumber(const llvm::APFloat &Value,
1207 const QualType &Ty);
1208 ConstantAddress
1209 GenerateConstantNSArray(const ArrayRef<llvm::Constant *> &Objects);
1210 ConstantAddress GenerateConstantNSDictionary(
1211 const ObjCDictionaryLiteral *E,
1212 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects);
1213
1214 llvm::Function *
1215 GenerateMethod(const ObjCMethodDecl *OMD,
1216 const ObjCContainerDecl *CD = nullptr) override;
1217
1218 DirectMethodInfo &GenerateDirectMethod(const ObjCMethodDecl *OMD,
1219 const ObjCContainerDecl *CD);
1220
1221 llvm::Function *GenerateObjCDirectThunk(const ObjCMethodDecl *OMD,
1222 const ObjCContainerDecl *CD,
1223 llvm::Function *Implementation);
1224
1225 llvm::Function *GetDirectMethodCallee(const ObjCMethodDecl *OMD,
1226 const ObjCContainerDecl *CD,
1227 bool ReceiverCanBeNull,
1228 bool ClassObjectCanBeUnrealized);
1229
1230 /// Generate class realization code: [self self]
1231 /// This is used for class methods to ensure the class is initialized.
1232 /// Returns the realized class object.
1233 llvm::Value *GenerateClassRealization(CodeGenFunction &CGF,
1234 llvm::Value *classObject,
1235 const ObjCInterfaceDecl *OID);
1236
1237 void GenerateDirectMethodsPreconditionCheck(
1238 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
1239 const ObjCContainerDecl *CD) override;
1240
1241 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
1242 const ObjCMethodDecl *OMD,
1243 const ObjCContainerDecl *CD) override;
1244
1245 llvm::Function *
1246 GenerateMethodSelectorStub(Selector Sel, StringRef ClassName,
1247 const ObjCCommonTypesHelper &ObjCTypes);
1248
1249 void GenerateProtocol(const ObjCProtocolDecl *PD) override;
1250
1251 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1252 /// object for the given declaration, emitting it if needed. These
1253 /// forward references will be filled in with empty bodies if no
1254 /// definition is seen. The return value has type ProtocolPtrTy.
1255 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) = 0;
1256
1257 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1258 virtual llvm::Constant *getNSConstantArrayClassRef() = 0;
1259 virtual llvm::Constant *getNSConstantDictionaryClassRef() = 0;
1260
1261 virtual llvm::Constant *getNSConstantIntegerNumberClassRef() = 0;
1262 virtual llvm::Constant *getNSConstantFloatNumberClassRef() = 0;
1263 virtual llvm::Constant *getNSConstantDoubleNumberClassRef() = 0;
1264
1265 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1266 const CGBlockInfo &blockInfo) override;
1267 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1268 const CGBlockInfo &blockInfo) override;
1269 std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
1270 const CGBlockInfo &blockInfo) override;
1271
1272 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1273 QualType T) override;
1274
1275private:
1276 void fillRunSkipBlockVars(CodeGenModule &CGM, const CGBlockInfo &blockInfo);
1277 llvm::GlobalVariable *EmitNSConstantCollectionLiteralArrayStorage(
1278 const ArrayRef<llvm::Constant *> &Elements);
1279};
1280
1281namespace {
1282
1283enum class MethodListType {
1284 CategoryInstanceMethods,
1285 CategoryClassMethods,
1286 InstanceMethods,
1287 ClassMethods,
1288 ProtocolInstanceMethods,
1289 ProtocolClassMethods,
1290 OptionalProtocolInstanceMethods,
1291 OptionalProtocolClassMethods,
1292};
1293
1294/// A convenience class for splitting the methods of a protocol into
1295/// the four interesting groups.
1296class ProtocolMethodLists {
1297public:
1298 enum Kind {
1299 RequiredInstanceMethods,
1300 RequiredClassMethods,
1301 OptionalInstanceMethods,
1302 OptionalClassMethods
1303 };
1304 enum { NumProtocolMethodLists = 4 };
1305
1306 static MethodListType getMethodListKind(Kind kind) {
1307 switch (kind) {
1308 case RequiredInstanceMethods:
1309 return MethodListType::ProtocolInstanceMethods;
1310 case RequiredClassMethods:
1311 return MethodListType::ProtocolClassMethods;
1312 case OptionalInstanceMethods:
1313 return MethodListType::OptionalProtocolInstanceMethods;
1314 case OptionalClassMethods:
1315 return MethodListType::OptionalProtocolClassMethods;
1316 }
1317 llvm_unreachable("bad kind");
1318 }
1319
1320 SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1321
1322 static ProtocolMethodLists get(const ObjCProtocolDecl *PD) {
1323 ProtocolMethodLists result;
1324
1325 for (auto *MD : PD->methods()) {
1326 size_t index =
1327 (2 * size_t(MD->isOptional())) + (size_t(MD->isClassMethod()));
1328 result.Methods[index].push_back(Elt: MD);
1329 }
1330
1331 return result;
1332 }
1333
1334 template <class Self>
1335 SmallVector<llvm::Constant *, 8> emitExtendedTypesArray(Self *self) const {
1336 // In both ABIs, the method types list is parallel with the
1337 // concatenation of the methods arrays in the following order:
1338 // instance methods
1339 // class methods
1340 // optional instance methods
1341 // optional class methods
1342 SmallVector<llvm::Constant *, 8> result;
1343
1344 // Methods is already in the correct order for both ABIs.
1345 for (auto &list : Methods) {
1346 for (auto MD : list) {
1347 result.push_back(Elt: self->GetMethodVarType(MD, true));
1348 }
1349 }
1350
1351 return result;
1352 }
1353
1354 template <class Self>
1355 llvm::Constant *emitMethodList(Self *self, const ObjCProtocolDecl *PD,
1356 Kind kind) const {
1357 return self->emitMethodList(PD->getObjCRuntimeNameAsString(),
1358 getMethodListKind(kind), Methods[kind]);
1359 }
1360};
1361
1362} // end anonymous namespace
1363
1364class CGObjCMac : public CGObjCCommonMac {
1365private:
1366 friend ProtocolMethodLists;
1367
1368 ObjCTypesHelper ObjCTypes;
1369
1370 /// EmitModuleInfo - Another marker encoding module level
1371 /// information.
1372 void EmitModuleInfo();
1373
1374 /// EmitModuleSymols - Emit module symbols, the list of defined
1375 /// classes and categories. The result has type SymtabPtrTy.
1376 llvm::Constant *EmitModuleSymbols();
1377
1378 /// FinishModule - Write out global data structures at the end of
1379 /// processing a translation unit.
1380 void FinishModule();
1381
1382 /// EmitClassExtension - Generate the class extension structure used
1383 /// to store the weak ivar layout and properties. The return value
1384 /// has type ClassExtensionPtrTy.
1385 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,
1386 CharUnits instanceSize,
1387 bool hasMRCWeakIvars, bool isMetaclass);
1388
1389 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1390 /// for the given class.
1391 llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID);
1392
1393 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II);
1394
1395 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1396
1397 /// EmitSuperClassRef - Emits reference to class's main metadata class.
1398 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1399
1400 /// EmitIvarList - Emit the ivar list for the given
1401 /// implementation. If ForClass is true the list of class ivars
1402 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1403 /// interface ivars will be emitted. The return value has type
1404 /// IvarListPtrTy.
1405 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, bool ForClass);
1406
1407 /// EmitMetaClass - Emit a forward reference to the class structure
1408 /// for the metaclass of the given interface. The return value has
1409 /// type ClassPtrTy.
1410 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1411
1412 /// EmitMetaClass - Emit a class structure for the metaclass of the
1413 /// given implementation. The return value has type ClassPtrTy.
1414 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1415 llvm::Constant *Protocols,
1416 ArrayRef<const ObjCMethodDecl *> Methods);
1417
1418 void emitMethodConstant(ConstantArrayBuilder &builder,
1419 const ObjCMethodDecl *MD);
1420
1421 void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1422 const ObjCMethodDecl *MD);
1423
1424 /// EmitMethodList - Emit the method list for the given
1425 /// implementation. The return value has type MethodListPtrTy.
1426 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1427 ArrayRef<const ObjCMethodDecl *> Methods);
1428
1429 /// GetOrEmitProtocol - Get the protocol object for the given
1430 /// declaration, emitting it if necessary. The return value has type
1431 /// ProtocolPtrTy.
1432 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1433
1434 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1435 /// object for the given declaration, emitting it if needed. These
1436 /// forward references will be filled in with empty bodies if no
1437 /// definition is seen. The return value has type ProtocolPtrTy.
1438 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1439
1440 /// EmitProtocolExtension - Generate the protocol extension
1441 /// structure used to store optional instance and class methods, and
1442 /// protocol properties. The return value has type
1443 /// ProtocolExtensionPtrTy.
1444 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD,
1445 const ProtocolMethodLists &methodLists);
1446
1447 /// EmitProtocolList - Generate the list of referenced
1448 /// protocols. The return value has type ProtocolListPtrTy.
1449 llvm::Constant *EmitProtocolList(Twine Name,
1450 ObjCProtocolDecl::protocol_iterator begin,
1451 ObjCProtocolDecl::protocol_iterator end);
1452
1453 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1454 /// for the given selector.
1455 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1456 ConstantAddress EmitSelectorAddr(Selector Sel);
1457
1458public:
1459 CGObjCMac(CodeGen::CodeGenModule &cgm);
1460
1461 llvm::Constant *getNSConstantStringClassRef() override;
1462 llvm::Constant *getNSConstantArrayClassRef() override;
1463 llvm::Constant *getNSConstantDictionaryClassRef() override;
1464
1465 llvm::Constant *getNSConstantIntegerNumberClassRef() override;
1466 llvm::Constant *getNSConstantFloatNumberClassRef() override;
1467 llvm::Constant *getNSConstantDoubleNumberClassRef() override;
1468
1469 llvm::Function *ModuleInitFunction() override;
1470
1471 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1472 ReturnValueSlot Return,
1473 QualType ResultType, Selector Sel,
1474 llvm::Value *Receiver,
1475 const CallArgList &CallArgs,
1476 const ObjCInterfaceDecl *Class,
1477 const ObjCMethodDecl *Method) override;
1478
1479 CodeGen::RValue GenerateMessageSendSuper(
1480 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1481 QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class,
1482 bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage,
1483 const CallArgList &CallArgs, const ObjCMethodDecl *Method) override;
1484
1485 llvm::Value *GetClass(CodeGenFunction &CGF,
1486 const ObjCInterfaceDecl *ID) override;
1487
1488 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;
1489 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;
1490
1491 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1492 /// untyped one.
1493 llvm::Value *GetSelector(CodeGenFunction &CGF,
1494 const ObjCMethodDecl *Method) override;
1495
1496 llvm::Constant *GetEHType(QualType T) override;
1497
1498 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1499
1500 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1501
1502 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1503
1504 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1505 const ObjCProtocolDecl *PD) override;
1506
1507 llvm::FunctionCallee GetPropertyGetFunction() override;
1508 llvm::FunctionCallee GetPropertySetFunction() override;
1509 llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
1510 bool copy) override;
1511 llvm::FunctionCallee GetGetStructFunction() override;
1512 llvm::FunctionCallee GetSetStructFunction() override;
1513 llvm::FunctionCallee GetCppAtomicObjectGetFunction() override;
1514 llvm::FunctionCallee GetCppAtomicObjectSetFunction() override;
1515 llvm::FunctionCallee EnumerationMutationFunction() override;
1516
1517 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1518 const ObjCAtTryStmt &S) override;
1519 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1520 const ObjCAtSynchronizedStmt &S) override;
1521 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1522 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1523 bool ClearInsertionPoint = true) override;
1524 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1525 Address AddrWeakObj) override;
1526 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1527 Address dst) override;
1528 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1529 Address dest, bool threadlocal = false) override;
1530 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1531 Address dest, llvm::Value *ivarOffset) override;
1532 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1533 Address dest) override;
1534 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1535 Address src, llvm::Value *size) override;
1536
1537 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1538 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1539 unsigned CVRQualifiers) override;
1540 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1541 const ObjCInterfaceDecl *Interface,
1542 const ObjCIvarDecl *Ivar) override;
1543};
1544
1545class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1546private:
1547 friend ProtocolMethodLists;
1548 ObjCNonFragileABITypesHelper ObjCTypes;
1549 llvm::GlobalVariable *ObjCEmptyCacheVar;
1550 llvm::Constant *ObjCEmptyVtableVar;
1551
1552 /// SuperClassReferences - uniqued super class references.
1553 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> SuperClassReferences;
1554
1555 /// MetaClassReferences - uniqued meta class references.
1556 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> MetaClassReferences;
1557
1558 /// EHTypeReferences - uniqued class ehtype references.
1559 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> EHTypeReferences;
1560
1561 /// VTableDispatchMethods - List of methods for which we generate
1562 /// vtable-based message dispatch.
1563 llvm::DenseSet<Selector> VTableDispatchMethods;
1564
1565 /// DefinedMetaClasses - List of defined meta-classes.
1566 std::vector<llvm::GlobalValue *> DefinedMetaClasses;
1567
1568 /// isVTableDispatchedSelector - Returns true if SEL is a
1569 /// vtable-based selector.
1570 bool isVTableDispatchedSelector(Selector Sel);
1571
1572 /// FinishNonFragileABIModule - Write out global data structures at the end of
1573 /// processing a translation unit.
1574 void FinishNonFragileABIModule();
1575
1576 /// AddModuleClassList - Add the given list of class pointers to the
1577 /// module with the provided symbol and section names.
1578 void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1579 StringRef SymbolName, StringRef SectionName);
1580
1581 llvm::GlobalVariable *
1582 BuildClassRoTInitializer(unsigned flags, unsigned InstanceStart,
1583 unsigned InstanceSize,
1584 const ObjCImplementationDecl *ID);
1585 llvm::GlobalVariable *
1586 BuildClassObject(const ObjCInterfaceDecl *CI, bool isMetaclass,
1587 llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
1588 llvm::Constant *ClassRoGV, bool HiddenVisibility);
1589
1590 void emitMethodConstant(ConstantArrayBuilder &builder,
1591 const ObjCMethodDecl *MD, bool forProtocol);
1592
1593 /// Emit the method list for the given implementation. The return value
1594 /// has type MethodListnfABITy.
1595 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1596 ArrayRef<const ObjCMethodDecl *> Methods);
1597
1598 /// EmitIvarList - Emit the ivar list for the given
1599 /// implementation. If ForClass is true the list of class ivars
1600 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1601 /// interface ivars will be emitted. The return value has type
1602 /// IvarListnfABIPtrTy.
1603 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1604
1605 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1606 const ObjCIvarDecl *Ivar,
1607 unsigned long int offset);
1608
1609 /// GetOrEmitProtocol - Get the protocol object for the given
1610 /// declaration, emitting it if necessary. The return value has type
1611 /// ProtocolPtrTy.
1612 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1613
1614 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1615 /// object for the given declaration, emitting it if needed. These
1616 /// forward references will be filled in with empty bodies if no
1617 /// definition is seen. The return value has type ProtocolPtrTy.
1618 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1619
1620 /// EmitProtocolList - Generate the list of referenced
1621 /// protocols. The return value has type ProtocolListPtrTy.
1622 llvm::Constant *EmitProtocolList(Twine Name,
1623 ObjCProtocolDecl::protocol_iterator begin,
1624 ObjCProtocolDecl::protocol_iterator end);
1625
1626 CodeGen::RValue EmitVTableMessageSend(
1627 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1628 QualType ResultType, Selector Sel, llvm::Value *Receiver, QualType Arg0Ty,
1629 bool IsSuper, const CallArgList &CallArgs, const ObjCMethodDecl *Method);
1630
1631 /// GetClassGlobal - Return the global variable for the Objective-C
1632 /// class of the given name.
1633 llvm::Constant *GetClassGlobal(StringRef Name,
1634 ForDefinition_t IsForDefinition,
1635 bool Weak = false, bool DLLImport = false);
1636 llvm::Constant *GetClassGlobal(const ObjCInterfaceDecl *ID, bool isMetaclass,
1637 ForDefinition_t isForDefinition);
1638
1639 llvm::Constant *GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID);
1640
1641 llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,
1642 const ObjCInterfaceDecl *ID,
1643 llvm::GlobalVariable *Entry);
1644
1645 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1646 /// for the given class reference.
1647 llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID);
1648
1649 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II,
1650 const ObjCInterfaceDecl *ID);
1651
1652 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1653
1654 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1655 /// for the given super class reference.
1656 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1657 const ObjCInterfaceDecl *ID);
1658
1659 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1660 /// meta-data
1661 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1662 const ObjCInterfaceDecl *ID, bool Weak);
1663
1664 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1665 /// the given ivar.
1666 ///
1667 llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
1668 const ObjCIvarDecl *Ivar);
1669
1670 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1671 /// for the given selector.
1672 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1673 ConstantAddress EmitSelectorAddr(Selector Sel);
1674
1675 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1676 /// interface. The return value has type EHTypePtrTy.
1677 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1678 ForDefinition_t IsForDefinition);
1679
1680 StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }
1681
1682 StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; }
1683
1684 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1685 uint32_t &InstanceStart, uint32_t &InstanceSize);
1686
1687 // Shamelessly stolen from Analysis/CFRefCount.cpp
1688 Selector GetNullarySelector(const char *name) const {
1689 const IdentifierInfo *II = &CGM.getContext().Idents.get(Name: name);
1690 return CGM.getContext().Selectors.getSelector(NumArgs: 0, IIV: &II);
1691 }
1692
1693 Selector GetUnarySelector(const char *name) const {
1694 const IdentifierInfo *II = &CGM.getContext().Idents.get(Name: name);
1695 return CGM.getContext().Selectors.getSelector(NumArgs: 1, IIV: &II);
1696 }
1697
1698 /// ImplementationIsNonLazy - Check whether the given category or
1699 /// class implementation is "non-lazy".
1700 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1701
1702 bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1703 const ObjCIvarDecl *IV) {
1704 // Annotate the load as an invariant load iff inside an instance method
1705 // and ivar belongs to instance method's class and one of its super class.
1706 // This check is needed because the ivar offset is a lazily
1707 // initialised value that may depend on objc_msgSend to perform a fixup on
1708 // the first message dispatch.
1709 //
1710 // An additional opportunity to mark the load as invariant arises when the
1711 // base of the ivar access is a parameter to an Objective C method.
1712 // However, because the parameters are not available in the current
1713 // interface, we cannot perform this check.
1714 //
1715 // Note that for direct methods, because objc_msgSend is skipped,
1716 // and that the method may be inlined, this optimization actually
1717 // can't be performed.
1718 if (const ObjCMethodDecl *MD =
1719 dyn_cast_or_null<ObjCMethodDecl>(Val: CGF.CurFuncDecl))
1720 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1721 if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1722 return IV->getContainingInterface()->isSuperClassOf(I: ID);
1723 return false;
1724 }
1725
1726 bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
1727 // Test a class by checking its superclasses up to
1728 // its base class if it has one.
1729 assert(ID != nullptr && "Passed a null class to check layout");
1730 for (; ID != nullptr; ID = ID->getSuperClass()) {
1731 // The layout of base class NSObject
1732 // is guaranteed to be statically known
1733 if (ID->getIdentifier()->getName() == "NSObject")
1734 return true;
1735
1736 // If we cannot see the @implementation of a class,
1737 // we cannot statically know the class layout.
1738 if (!ID->getImplementation())
1739 return false;
1740 }
1741
1742 // We know the layout of all the intermediate classes and superclasses.
1743 return true;
1744 }
1745
1746public:
1747 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1748
1749 llvm::Constant *getNSConstantStringClassRef() override;
1750 llvm::Constant *getNSConstantArrayClassRef() override;
1751 llvm::Constant *getNSConstantDictionaryClassRef() override;
1752
1753 llvm::Constant *getNSConstantIntegerNumberClassRef() override;
1754 llvm::Constant *getNSConstantFloatNumberClassRef() override;
1755 llvm::Constant *getNSConstantDoubleNumberClassRef() override;
1756
1757 llvm::Function *ModuleInitFunction() override;
1758
1759 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1760 ReturnValueSlot Return,
1761 QualType ResultType, Selector Sel,
1762 llvm::Value *Receiver,
1763 const CallArgList &CallArgs,
1764 const ObjCInterfaceDecl *Class,
1765 const ObjCMethodDecl *Method) override;
1766
1767 CodeGen::RValue GenerateMessageSendSuper(
1768 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1769 QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class,
1770 bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage,
1771 const CallArgList &CallArgs, const ObjCMethodDecl *Method) override;
1772
1773 llvm::Value *GetClass(CodeGenFunction &CGF,
1774 const ObjCInterfaceDecl *ID) override;
1775
1776 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override {
1777 return EmitSelector(CGF, Sel);
1778 }
1779 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override {
1780 return EmitSelectorAddr(Sel);
1781 }
1782
1783 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1784 /// untyped one.
1785 llvm::Value *GetSelector(CodeGenFunction &CGF,
1786 const ObjCMethodDecl *Method) override {
1787 return EmitSelector(CGF, Sel: Method->getSelector());
1788 }
1789
1790 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1791
1792 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1793
1794 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1795
1796 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1797 const ObjCProtocolDecl *PD) override;
1798
1799 llvm::Constant *GetEHType(QualType T) override;
1800
1801 llvm::FunctionCallee GetPropertyGetFunction() override {
1802 return ObjCTypes.getGetPropertyFn();
1803 }
1804 llvm::FunctionCallee GetPropertySetFunction() override {
1805 return ObjCTypes.getSetPropertyFn();
1806 }
1807
1808 llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
1809 bool copy) override {
1810 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1811 }
1812
1813 llvm::FunctionCallee GetSetStructFunction() override {
1814 return ObjCTypes.getCopyStructFn();
1815 }
1816
1817 llvm::FunctionCallee GetGetStructFunction() override {
1818 return ObjCTypes.getCopyStructFn();
1819 }
1820
1821 llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {
1822 return ObjCTypes.getCppAtomicObjectFunction();
1823 }
1824
1825 llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {
1826 return ObjCTypes.getCppAtomicObjectFunction();
1827 }
1828
1829 llvm::FunctionCallee EnumerationMutationFunction() override {
1830 return ObjCTypes.getEnumerationMutationFn();
1831 }
1832
1833 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1834 const ObjCAtTryStmt &S) override;
1835 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1836 const ObjCAtSynchronizedStmt &S) override;
1837 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1838 bool ClearInsertionPoint = true) override;
1839 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1840 Address AddrWeakObj) override;
1841 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1842 Address edst) override;
1843 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1844 Address dest, bool threadlocal = false) override;
1845 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1846 Address dest, llvm::Value *ivarOffset) override;
1847 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1848 Address dest) override;
1849 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1850 Address src, llvm::Value *size) override;
1851 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1852 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1853 unsigned CVRQualifiers) override;
1854 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1855 const ObjCInterfaceDecl *Interface,
1856 const ObjCIvarDecl *Ivar) override;
1857};
1858
1859/// A helper class for performing the null-initialization of a return
1860/// value.
1861struct NullReturnState {
1862 llvm::BasicBlock *NullBB = nullptr;
1863 NullReturnState() = default;
1864
1865 /// Perform a null-check of the given receiver.
1866 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1867 // Make blocks for the null-receiver and call edges.
1868 NullBB = CGF.createBasicBlock(name: "msgSend.null-receiver");
1869 llvm::BasicBlock *callBB = CGF.createBasicBlock(name: "msgSend.call");
1870
1871 // Check for a null receiver and, if there is one, jump to the
1872 // null-receiver block. There's no point in trying to avoid it:
1873 // we're always going to put *something* there, because otherwise
1874 // we shouldn't have done this null-check in the first place.
1875 llvm::Value *isNull = CGF.Builder.CreateIsNull(Arg: receiver);
1876 CGF.Builder.CreateCondBr(Cond: isNull, True: NullBB, False: callBB);
1877
1878 // Otherwise, start performing the call.
1879 CGF.EmitBlock(BB: callBB);
1880 }
1881
1882 /// Complete the null-return operation. It is valid to call this
1883 /// regardless of whether 'init' has been called.
1884 RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,
1885 RValue result, QualType resultType,
1886 const CallArgList &CallArgs, const ObjCMethodDecl *Method) {
1887 // If we never had to do a null-check, just use the raw result.
1888 if (!NullBB)
1889 return result;
1890
1891 // The continuation block. This will be left null if we don't have an
1892 // IP, which can happen if the method we're calling is marked noreturn.
1893 llvm::BasicBlock *contBB = nullptr;
1894
1895 // Finish the call path.
1896 llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1897 if (callBB) {
1898 contBB = CGF.createBasicBlock(name: "msgSend.cont");
1899 CGF.Builder.CreateBr(Dest: contBB);
1900 }
1901
1902 // Okay, start emitting the null-receiver block.
1903 CGF.EmitBlock(BB: NullBB);
1904
1905 // Destroy any consumed arguments we've got.
1906 if (Method) {
1907 CGObjCRuntime::destroyCalleeDestroyedArguments(CGF, method: Method, callArgs: CallArgs);
1908 }
1909
1910 // The phi code below assumes that we haven't needed any control flow yet.
1911 assert(CGF.Builder.GetInsertBlock() == NullBB);
1912
1913 // If we've got a void return, just jump to the continuation block.
1914 if (result.isScalar() && resultType->isVoidType()) {
1915 // No jumps required if the message-send was noreturn.
1916 if (contBB)
1917 CGF.EmitBlock(BB: contBB);
1918 return result;
1919 }
1920
1921 // If we've got a scalar return, build a phi.
1922 if (result.isScalar()) {
1923 // Derive the null-initialization value.
1924 llvm::Value *null =
1925 CGF.EmitFromMemory(Value: CGF.CGM.EmitNullConstant(T: resultType), Ty: resultType);
1926
1927 // If no join is necessary, just flow out.
1928 if (!contBB)
1929 return RValue::get(V: null);
1930
1931 // Otherwise, build a phi.
1932 CGF.EmitBlock(BB: contBB);
1933 llvm::PHINode *phi = CGF.Builder.CreatePHI(Ty: null->getType(), NumReservedValues: 2);
1934 phi->addIncoming(V: result.getScalarVal(), BB: callBB);
1935 phi->addIncoming(V: null, BB: NullBB);
1936 return RValue::get(V: phi);
1937 }
1938
1939 // If we've got an aggregate return, null the buffer out.
1940 // FIXME: maybe we should be doing things differently for all the
1941 // cases where the ABI has us returning (1) non-agg values in
1942 // memory or (2) agg values in registers.
1943 if (result.isAggregate()) {
1944 assert(result.isAggregate() && "null init of non-aggregate result?");
1945 if (!returnSlot.isUnused())
1946 CGF.EmitNullInitialization(DestPtr: result.getAggregateAddress(), Ty: resultType);
1947 if (contBB)
1948 CGF.EmitBlock(BB: contBB);
1949 return result;
1950 }
1951
1952 // Complex types.
1953 CGF.EmitBlock(BB: contBB);
1954 CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1955
1956 // Find the scalar type and its zero value.
1957 llvm::Type *scalarTy = callResult.first->getType();
1958 llvm::Constant *scalarZero = llvm::Constant::getNullValue(Ty: scalarTy);
1959
1960 // Build phis for both coordinates.
1961 llvm::PHINode *real = CGF.Builder.CreatePHI(Ty: scalarTy, NumReservedValues: 2);
1962 real->addIncoming(V: callResult.first, BB: callBB);
1963 real->addIncoming(V: scalarZero, BB: NullBB);
1964 llvm::PHINode *imag = CGF.Builder.CreatePHI(Ty: scalarTy, NumReservedValues: 2);
1965 imag->addIncoming(V: callResult.second, BB: callBB);
1966 imag->addIncoming(V: scalarZero, BB: NullBB);
1967 return RValue::getComplex(V1: real, V2: imag);
1968 }
1969};
1970
1971} // end anonymous namespace
1972
1973/* *** Helper Functions *** */
1974
1975/// hasObjCExceptionAttribute - Return true if this class or any super
1976/// class has the __objc_exception__ attribute.
1977static bool hasObjCExceptionAttribute(ASTContext &Context,
1978 const ObjCInterfaceDecl *OID) {
1979 if (OID->hasAttr<ObjCExceptionAttr>())
1980 return true;
1981 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1982 return hasObjCExceptionAttribute(Context, OID: Super);
1983 return false;
1984}
1985
1986static llvm::GlobalValue::LinkageTypes
1987getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) {
1988 if (CGM.getTriple().isOSBinFormatMachO() &&
1989 (Section.empty() || Section.starts_with(Prefix: "__DATA")))
1990 return llvm::GlobalValue::InternalLinkage;
1991 return llvm::GlobalValue::PrivateLinkage;
1992}
1993
1994/// A helper function to create an internal or private global variable.
1995static llvm::GlobalVariable *
1996finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder,
1997 const llvm::Twine &Name, CodeGenModule &CGM) {
1998 std::string SectionName;
1999 if (CGM.getTriple().isOSBinFormatMachO())
2000 SectionName = "__DATA, __objc_const";
2001 auto *GV = Builder.finishAndCreateGlobal(
2002 args: Name, args: CGM.getPointerAlign(), /*constant*/ args: false,
2003 args: getLinkageTypeForObjCMetadata(CGM, Section: SectionName));
2004 GV->setSection(SectionName);
2005 return GV;
2006}
2007
2008/* *** CGObjCMac Public Interface *** */
2009
2010CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
2011 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2012 ObjCABI = 1;
2013 EmitImageInfo();
2014}
2015
2016/// GetClass - Return a reference to the class for the given interface
2017/// decl.
2018llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
2019 const ObjCInterfaceDecl *ID) {
2020 return EmitClassRef(CGF, ID);
2021}
2022
2023/// GetSelector - Return the pointer to the unique'd string for this selector.
2024llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2025 return EmitSelector(CGF, Sel);
2026}
2027Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2028 return EmitSelectorAddr(Sel);
2029}
2030llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2031 const ObjCMethodDecl *Method) {
2032 return EmitSelector(CGF, Sel: Method->getSelector());
2033}
2034
2035llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2036 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
2037 return CGM.GetAddrOfRTTIDescriptor(
2038 Ty: CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
2039 }
2040 if (T->isObjCClassType() || T->isObjCQualifiedClassType()) {
2041 return CGM.GetAddrOfRTTIDescriptor(
2042 Ty: CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
2043 }
2044 if (T->isObjCObjectPointerType())
2045 return CGM.GetAddrOfRTTIDescriptor(Ty: T, /*ForEH=*/true);
2046
2047 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
2048}
2049
2050/// Generate a constant CFString object.
2051/*
2052 struct __builtin_CFString {
2053 const int *isa; // point to __CFConstantStringClassReference
2054 int flags;
2055 const char *str;
2056 long length;
2057 };
2058*/
2059
2060/// or Generate a constant NSString object.
2061/*
2062 struct __builtin_NSString {
2063 const int *isa; // point to __NSConstantStringClassReference
2064 const char *str;
2065 unsigned int length;
2066 };
2067*/
2068
2069ConstantAddress
2070CGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {
2071 return (!CGM.getLangOpts().NoConstantCFStrings
2072 ? CGM.GetAddrOfConstantCFString(Literal: SL)
2073 : GenerateConstantNSString(SL));
2074}
2075
2076ConstantAddress CGObjCCommonMac::GenerateConstantNumber(const bool Value,
2077 const QualType &Ty) {
2078 return GenerateConstantNSNumber(Value, Ty);
2079}
2080
2081ConstantAddress
2082CGObjCCommonMac::GenerateConstantNumber(const llvm::APSInt &Value,
2083 const QualType &Ty) {
2084 return GenerateConstantNSNumber(Value, Ty);
2085}
2086
2087ConstantAddress
2088CGObjCCommonMac::GenerateConstantNumber(const llvm::APFloat &Value,
2089 const QualType &Ty) {
2090 return GenerateConstantNSNumber(Value, Ty);
2091}
2092
2093ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2094 const ArrayRef<llvm::Constant *> &Objects) {
2095 return GenerateConstantNSArray(Objects);
2096}
2097
2098ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2099 const ObjCDictionaryLiteral *E,
2100 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2101 return GenerateConstantNSDictionary(E, KeysAndObjects);
2102}
2103
2104static llvm::StringMapEntry<llvm::GlobalVariable *> &
2105GetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
2106 const StringLiteral *Literal, unsigned &StringLength) {
2107 StringRef String = Literal->getString();
2108 StringLength = String.size();
2109 return *Map.insert(KV: std::make_pair(x&: String, y: nullptr)).first;
2110}
2111
2112llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2113 if (llvm::Value *V = ConstantStringClassRef)
2114 return cast<llvm::Constant>(Val: V);
2115
2116 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2117 std::string str = StringClass.empty() ? "_NSConstantStringClassReference"
2118 : "_" + StringClass + "ClassReference";
2119
2120 llvm::Type *PTy = llvm::ArrayType::get(ElementType: CGM.IntTy, NumElements: 0);
2121 auto GV = CGM.CreateRuntimeVariable(Ty: PTy, Name: str);
2122 ConstantStringClassRef = GV;
2123 return GV;
2124}
2125
2126llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2127 llvm_unreachable("constant array literals not supported for fragile ABI");
2128}
2129
2130llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2131 llvm_unreachable("constant dictionary literals not supported for fragile "
2132 "ABI");
2133}
2134
2135llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2136 llvm_unreachable("constant number literals not supported for fragile ABI");
2137}
2138
2139llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2140 llvm_unreachable("constant number literals not supported for fragile ABI");
2141}
2142
2143llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2144 llvm_unreachable("constant number literals not supported for fragile ABI");
2145}
2146
2147llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2148 if (llvm::Value *V = ConstantStringClassRef)
2149 return cast<llvm::Constant>(Val: V);
2150
2151 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2152 std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
2153 : "OBJC_CLASS_$_" + StringClass;
2154 llvm::Constant *GV = GetClassGlobal(Name: str, IsForDefinition: NotForDefinition);
2155 ConstantStringClassRef = GV;
2156 return GV;
2157}
2158
2159llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2160 if (llvm::Value *V = ConstantArrayClassRef)
2161 return cast<llvm::Constant>(Val: V);
2162
2163 const std::string &ArrayClass = CGM.getLangOpts().ObjCConstantArrayClass;
2164 std::string Str = ArrayClass.empty() ? "OBJC_CLASS_$_NSConstantArray"
2165 : "OBJC_CLASS_$_" + ArrayClass;
2166 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2167
2168 ConstantArrayClassRef = GV;
2169 return GV;
2170}
2171
2172llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2173 if (llvm::Value *V = ConstantDictionaryClassRef)
2174 return cast<llvm::Constant>(Val: V);
2175
2176 const std::string &DictionaryClass =
2177 CGM.getLangOpts().ObjCConstantDictionaryClass;
2178 std::string Str = DictionaryClass.empty()
2179 ? "OBJC_CLASS_$_NSConstantDictionary"
2180 : "OBJC_CLASS_$_" + DictionaryClass;
2181 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2182
2183 ConstantDictionaryClassRef = GV;
2184 return GV;
2185}
2186
2187llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2188 if (llvm::Value *V = ConstantIntegerNumberClassRef)
2189 return cast<llvm::Constant>(Val: V);
2190
2191 const std::string &NumberClass =
2192 CGM.getLangOpts().ObjCConstantIntegerNumberClass;
2193 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantIntegerNumber"
2194 : "OBJC_CLASS_$_" + NumberClass;
2195 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2196
2197 ConstantIntegerNumberClassRef = GV;
2198 return GV;
2199}
2200
2201llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2202 if (llvm::Value *V = ConstantFloatNumberClassRef)
2203 return cast<llvm::Constant>(Val: V);
2204
2205 const std::string &NumberClass =
2206 CGM.getLangOpts().ObjCConstantFloatNumberClass;
2207 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantFloatNumber"
2208 : "OBJC_CLASS_$_" + NumberClass;
2209 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2210
2211 ConstantFloatNumberClassRef = GV;
2212 return GV;
2213}
2214
2215llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2216 if (llvm::Value *V = ConstantDoubleNumberClassRef)
2217 return cast<llvm::Constant>(Val: V);
2218
2219 const std::string &NumberClass =
2220 CGM.getLangOpts().ObjCConstantDoubleNumberClass;
2221 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantDoubleNumber"
2222 : "OBJC_CLASS_$_" + NumberClass;
2223 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2224
2225 ConstantDoubleNumberClassRef = GV;
2226 return GV;
2227}
2228
2229ConstantAddress
2230CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {
2231 unsigned StringLength = 0;
2232 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2233 GetConstantStringEntry(Map&: NSConstantStringMap, Literal, StringLength);
2234
2235 if (auto *C = Entry.second)
2236 return ConstantAddress(C, C->getValueType(),
2237 CharUnits::fromQuantity(Quantity: C->getAlign().valueOrOne()));
2238
2239 // If we don't already have it, get _NSConstantStringClassReference.
2240 llvm::Constant *Class = getNSConstantStringClassRef();
2241
2242 // If we don't already have it, construct the type for a constant NSString.
2243 if (!NSConstantStringType) {
2244 // NOTE: The existing implementation used a pointer to a Int32Ty not a
2245 // struct pointer as the ISA type when emitting constant strings so this is
2246 // maintained for now.
2247 NSConstantStringType =
2248 llvm::StructType::create(Elements: {CGM.DefaultPtrTy, CGM.Int8PtrTy, CGM.IntTy},
2249 Name: "struct.__builtin_NSString");
2250 }
2251
2252 ConstantInitBuilder Builder(CGM);
2253 auto Fields = Builder.beginStruct(structTy: NSConstantStringType);
2254
2255 // Class pointer.
2256 Fields.addSignedPointer(Pointer: Class,
2257 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2258 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2259
2260 // String pointer.
2261 llvm::Constant *C =
2262 llvm::ConstantDataArray::getString(Context&: VMContext, Initializer: Entry.first());
2263
2264 llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;
2265 bool isConstant = !CGM.getLangOpts().WritableStrings;
2266
2267 auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
2268 Linkage, C, ".str");
2269 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2270 // Don't enforce the target's minimum global alignment, since the only use
2271 // of the string is via this class initializer.
2272 GV->setAlignment(llvm::Align(1));
2273 Fields.add(value: GV);
2274
2275 // String length.
2276 Fields.addInt(intTy: CGM.IntTy, value: StringLength);
2277
2278 // The struct.
2279 CharUnits Alignment = CGM.getPointerAlign();
2280 GV = Fields.finishAndCreateGlobal(args: "_unnamed_nsstring_", args&: Alignment,
2281 /*constant*/ args: true,
2282 args: llvm::GlobalVariable::PrivateLinkage);
2283 const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
2284 const char *NSStringNonFragileABISection =
2285 "__DATA,__objc_stringobj,regular,no_dead_strip";
2286 // FIXME. Fix section.
2287 GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
2288 ? NSStringNonFragileABISection
2289 : NSStringSection);
2290 Entry.second = GV;
2291
2292 return ConstantAddress(GV, GV->getValueType(), Alignment);
2293}
2294
2295/// Emit the boolean singletons for BOOL literals @YES and @NO.
2296ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value,
2297 const QualType &Ty) {
2298 llvm::GlobalVariable *Val =
2299 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2300 return ConstantAddress(Val, Val->getValueType(), CGM.getPointerAlign());
2301}
2302
2303/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal,
2304/// e.g., @2.
2305/*
2306 struct __builtin_NSConstantIntegerNumber {
2307 struct._class_t *isa; // point to _NSConstantIntegerNumberClassReference
2308 char const *const _encoding;
2309 long long const _value;
2310 };
2311*/
2312ConstantAddress
2313CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value,
2314 const QualType &Ty) {
2315 CharUnits Alignment = CGM.getPointerAlign();
2316
2317 // Check if we've already emitted, if so emit a reference to it.
2318 llvm::GlobalVariable *&Entry =
2319 NSConstantNumberMap[{CGM.getContext().getCanonicalType(T: Ty), Value}];
2320 if (Entry) {
2321 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2322 }
2323
2324 // The encoding type.
2325 std::string ObjCEncodingType;
2326 CodeGenFunction(CGM).getContext().getObjCEncodingForType(T: Ty,
2327 S&: ObjCEncodingType);
2328
2329 llvm::Constant *const Class = getNSConstantIntegerNumberClassRef();
2330
2331 if (!NSConstantIntegerNumberType) {
2332 NSConstantIntegerNumberType = llvm::StructType::create(
2333 Elements: {
2334 CGM.DefaultPtrTy, // isa
2335 CGM.Int8PtrTy, // _encoding
2336 CGM.Int64Ty, // _value
2337 },
2338 Name: "struct.__builtin_NSConstantIntegerNumber");
2339 }
2340
2341 ConstantInitBuilder Builder(CGM);
2342 auto Fields = Builder.beginStruct(structTy: NSConstantIntegerNumberType);
2343
2344 // Class pointer.
2345 Fields.addSignedPointer(Pointer: Class,
2346 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2347 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2348
2349 // add the @encode.
2350 Fields.add(value: CGM.GetAddrOfConstantCString(Str: ObjCEncodingType).getPointer());
2351
2352 // add the value stored.
2353 llvm::Constant *IntegerValue =
2354 llvm::ConstantInt::get(Ty: CGM.Int64Ty, V: Value.extOrTrunc(width: 64));
2355
2356 Fields.add(value: IntegerValue);
2357
2358 // The struct.
2359 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2360 args: "_unnamed_nsconstantintegernumber_", args&: Alignment,
2361 /* constant */ args: true, args: llvm::GlobalVariable::PrivateLinkage);
2362
2363 GV->setSection(GetNSConstantIntegerNumberSectionName());
2364 GV->addAttribute(Kind: "objc_arc_inert");
2365
2366 Entry = GV;
2367
2368 return ConstantAddress(GV, GV->getValueType(), Alignment);
2369}
2370
2371/// Generate either a constant NSConstantFloatNumber or NSConstantDoubleNumber
2372/// from an ObjC literal based on it's encoding. @(2.2f) would be
2373/// NSConstantFloatNumber. @(2.222) would be NSConstantDoubleNumber.
2374/*
2375 struct __builtin_NSConstantFloatNumber {
2376 struct._class_t *isa; // point to _NSConstantFloatNumberClassReference
2377 float const _value;
2378 };
2379
2380 struct __builtin_NSConstantDoubleNumber {
2381 struct._class_t *isa; // point to _NSConstantDoubleNumberClassReference
2382 double const _value;
2383 };
2384*/
2385ConstantAddress
2386CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value,
2387 const QualType &Ty) {
2388 CharUnits Alignment = CGM.getPointerAlign();
2389
2390 // Check if we've already emitted, if so emit a reference to it.
2391 llvm::GlobalVariable *&Entry =
2392 NSConstantNumberMap[{CGM.getContext().getCanonicalType(T: Ty), Value}];
2393 if (Entry) {
2394 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2395 }
2396
2397 // @encode type used to pick which class type to use.
2398 std::string ObjCEncodingType;
2399 CodeGenFunction(CGM).getContext().getObjCEncodingForType(T: Ty,
2400 S&: ObjCEncodingType);
2401
2402 assert((ObjCEncodingType == "d" || ObjCEncodingType == "f") &&
2403 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2404
2405 llvm::GlobalValue::LinkageTypes Linkage =
2406 llvm::GlobalVariable::PrivateLinkage;
2407
2408 // Handle floats.
2409 if (ObjCEncodingType == "f") {
2410 llvm::Constant *const Class = getNSConstantFloatNumberClassRef();
2411
2412 if (!NSConstantFloatNumberType) {
2413 NSConstantFloatNumberType = llvm::StructType::create(
2414 Elements: {
2415 CGM.DefaultPtrTy, // isa
2416 CGM.FloatTy, // _value
2417 },
2418 Name: "struct.__builtin_NSConstantFloatNumber");
2419 }
2420
2421 ConstantInitBuilder Builder(CGM);
2422 auto Fields = Builder.beginStruct(structTy: NSConstantFloatNumberType);
2423
2424 // Class pointer.
2425 Fields.addSignedPointer(Pointer: Class,
2426 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2427 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2428
2429 // add the value stored.
2430 llvm::Constant *FV = llvm::ConstantFP::get(Ty: CGM.FloatTy, V: Value);
2431 Fields.add(value: FV);
2432
2433 // The struct.
2434 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2435 args: "_unnamed_nsconstantfloatnumber_", args&: Alignment,
2436 /*constant*/ args: true, args&: Linkage);
2437
2438 GV->setSection(GetNSConstantFloatNumberSectionName());
2439 GV->addAttribute(Kind: "objc_arc_inert");
2440
2441 Entry = GV;
2442
2443 return ConstantAddress(GV, GV->getValueType(), Alignment);
2444 }
2445
2446 llvm::Constant *const Class = getNSConstantDoubleNumberClassRef();
2447 if (!NSConstantDoubleNumberType) {
2448 // NOTE: this will be padded on some 32-bit targets and is expected.
2449 NSConstantDoubleNumberType = llvm::StructType::create(
2450 Elements: {
2451 CGM.DefaultPtrTy, // isa
2452 CGM.DoubleTy, // _value
2453 },
2454 Name: "struct.__builtin_NSConstantDoubleNumber");
2455 }
2456
2457 ConstantInitBuilder Builder(CGM);
2458 auto Fields = Builder.beginStruct(structTy: NSConstantDoubleNumberType);
2459
2460 // Class pointer.
2461 Fields.addSignedPointer(Pointer: Class,
2462 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2463 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2464
2465 // add the value stored.
2466 llvm::Constant *DV = llvm::ConstantFP::get(Ty: CGM.DoubleTy, V: Value);
2467 Fields.add(value: DV);
2468
2469 // The struct.
2470 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2471 args: "_unnamed_nsconstantdoublenumber_", args&: Alignment,
2472 /*constant*/ args: true, args&: Linkage);
2473
2474 GV->setSection(GetNSConstantDoubleNumberSectionName());
2475 GV->addAttribute(Kind: "objc_arc_inert");
2476
2477 Entry = GV;
2478
2479 return ConstantAddress(GV, GV->getValueType(), Alignment);
2480}
2481
2482/// Shared private method to emit the id array storage for constant NSArray and
2483/// NSDictionary literals as they share the same sections and behavior.
2484llvm::GlobalVariable *
2485CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2486 const ArrayRef<llvm::Constant *> &Elements) {
2487 llvm::Type *ElementsTy = Elements[0]->getType();
2488 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementType: ElementsTy, NumElements: Elements.size());
2489
2490 llvm::Constant *const ArrayData = llvm::ConstantArray::get(T: ArrayTy, V: Elements);
2491
2492 llvm::GlobalVariable *ObjectsGV = new llvm::GlobalVariable(
2493 CGM.getModule(), ArrayTy, true, llvm::GlobalValue::InternalLinkage,
2494 ArrayData, "_unnamed_array_storage");
2495
2496 ObjectsGV->setAlignment(CGM.getPointerAlign().getAsAlign());
2497 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2498 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2499 return ObjectsGV;
2500}
2501
2502/// Generate a constant NSConstantArray from an ObjC array literal,
2503/// e.g., @[ @2 ] or the singleton for an empty `__NSArray0__struct`.
2504/*
2505 struct __builtin_NSArray {
2506 struct._class_t *isa; // points to _NSConstantArrayClassReference
2507 NSUInteger const _count;
2508 id const *const _objects;
2509 };
2510*/
2511ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2512 const ArrayRef<llvm::Constant *> &Objects) {
2513 CharUnits Alignment = CGM.getPointerAlign();
2514
2515 if (Objects.size() == 0) {
2516 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2517 return ConstantAddress(GV, GV->getValueType(), Alignment);
2518 }
2519
2520 ASTContext &Context = CGM.getContext();
2521 CodeGenTypes &Types = CGM.getTypes();
2522 llvm::Constant *const Class = getNSConstantArrayClassRef();
2523 llvm::Type *const NSUIntegerTy =
2524 Types.ConvertType(T: Context.getNSUIntegerType());
2525
2526 if (!NSConstantArrayType) {
2527 NSConstantArrayType = llvm::StructType::create(
2528 Elements: {
2529 CGM.DefaultPtrTy, // isa
2530 NSUIntegerTy, // _count
2531 CGM.DefaultPtrTy, // _objects
2532 },
2533 Name: "struct.__builtin_NSArray");
2534 }
2535
2536 ConstantInitBuilder Builder(CGM);
2537 auto Fields = Builder.beginStruct(structTy: NSConstantArrayType);
2538
2539 // Class pointer.
2540 Fields.addSignedPointer(Pointer: Class,
2541 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2542 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2543
2544 // count.
2545 uint64_t ObjectCount = Objects.size();
2546 llvm::Constant *Count = llvm::ConstantInt::get(Ty: NSUIntegerTy, V: ObjectCount);
2547 Fields.add(value: Count);
2548
2549 // objects.
2550 llvm::GlobalVariable *ObjectsGV =
2551 EmitNSConstantCollectionLiteralArrayStorage(Elements: Objects);
2552 Fields.add(value: ObjectsGV);
2553
2554 // The struct.
2555 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2556 args: "_unnamed_nsarray_", args&: Alignment,
2557 /* constant */ args: true, args: llvm::GlobalValue::PrivateLinkage);
2558
2559 GV->setSection(GetNSConstantArraySectionName());
2560 GV->addAttribute(Kind: "objc_arc_inert");
2561
2562 return ConstantAddress(GV, GV->getValueType(), Alignment);
2563}
2564
2565/// Generate a constant NSConstantDictionary from an ObjC dictionary literal
2566/// with string keys, e.g., @{ @"someNum" : @2 } or the singleton for an empty
2567/// `__NSDictionary0__struct`.
2568/*
2569 struct __builtin_NSDictionary {
2570 struct._class_t *isa; // point to _NSConstantDictionaryClassReference
2571 NSUInteger const _hashOptions;
2572 NSUInteger const _count;
2573 id const *const _keys;
2574 id const *const _objects;
2575 };
2576 */
2577ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2578 const ObjCDictionaryLiteral *E,
2579 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2580 CharUnits Alignment = CGM.getPointerAlign();
2581
2582 if (KeysAndObjects.size() == 0) {
2583 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2584 return ConstantAddress(GV, GV->getValueType(), Alignment);
2585 }
2586
2587 ASTContext &Context = CGM.getContext();
2588 CodeGenTypes &Types = CGM.getTypes();
2589 llvm::Constant *const Class = getNSConstantDictionaryClassRef();
2590
2591 llvm::Type *const NSUIntegerTy =
2592 Types.ConvertType(T: Context.getNSUIntegerType());
2593
2594 if (!NSConstantDictionaryType) {
2595 NSConstantDictionaryType = llvm::StructType::create(
2596 Elements: {
2597 CGM.DefaultPtrTy, // isa
2598 NSUIntegerTy, // _hashOptions
2599 NSUIntegerTy, // _count
2600 CGM.DefaultPtrTy, // _keys
2601 CGM.DefaultPtrTy, // _objects
2602 },
2603 Name: "struct.__builtin_NSDictionary");
2604 }
2605
2606 ConstantInitBuilder Builder(CGM);
2607 auto Fields = Builder.beginStruct(structTy: NSConstantDictionaryType);
2608
2609 // Class pointer.
2610 Fields.addSignedPointer(Pointer: Class,
2611 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2612 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2613
2614 // Use the hashing helper to manage the keys and sorting.
2615 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2616 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2617
2618 // Ask `HashBuilder` for the fully sorted keys / values and the count.
2619 uint64_t const NumElements = DictBuilder.getNumElements();
2620
2621 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2622 Ty: NSUIntegerTy, V: static_cast<uint64_t>(DictBuilder.getOptions()));
2623 Fields.add(value: OptionsConstant);
2624
2625 // count.
2626 llvm::Constant *Count = llvm::ConstantInt::get(Ty: NSUIntegerTy, V: NumElements);
2627 Fields.add(value: Count);
2628
2629 // Split sorted pairs into separate keys and objects arrays for storage.
2630 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2631 SortedKeys.reserve(N: NumElements);
2632 SortedObjects.reserve(N: NumElements);
2633 for (auto &[Key, Obj] : DictBuilder.getElements()) {
2634 SortedKeys.push_back(Elt: Key);
2635 SortedObjects.push_back(Elt: Obj);
2636 }
2637
2638 // keys.
2639 llvm::GlobalVariable *KeysGV =
2640 EmitNSConstantCollectionLiteralArrayStorage(Elements: SortedKeys);
2641 Fields.add(value: KeysGV);
2642
2643 // objects.
2644 llvm::GlobalVariable *ObjectsGV =
2645 EmitNSConstantCollectionLiteralArrayStorage(Elements: SortedObjects);
2646 Fields.add(value: ObjectsGV);
2647
2648 // The struct.
2649 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2650 args: "_unnamed_nsdictionary_", args&: Alignment,
2651 /* constant */ args: true, args: llvm::GlobalValue::PrivateLinkage);
2652
2653 GV->setSection(GetNSConstantDictionarySectionName());
2654 GV->addAttribute(Kind: "objc_arc_inert");
2655
2656 return ConstantAddress(GV, GV->getValueType(), Alignment);
2657}
2658
2659enum { kCFTaggedObjectID_Integer = (1 << 1) + 1 };
2660
2661/// Generates a message send where the super is the receiver. This is
2662/// a message send to self with special delivery semantics indicating
2663/// which class's method should be called.
2664CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2665 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2666 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
2667 llvm::Value *Receiver, bool IsClassMessage,
2668 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
2669 // Create and init a super structure; this is a (receiver, class)
2670 // pair we will pass to objc_msgSendSuper.
2671 RawAddress ObjCSuper = CGF.CreateTempAlloca(
2672 Ty: ObjCTypes.SuperTy, align: CGF.getPointerAlign(), Name: "objc_super");
2673 llvm::Value *ReceiverAsObject =
2674 CGF.Builder.CreateBitCast(V: Receiver, DestTy: ObjCTypes.ObjectPtrTy);
2675 CGF.Builder.CreateStore(Val: ReceiverAsObject,
2676 Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 0));
2677
2678 // If this is a class message the metaclass is passed as the target.
2679 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(C&: VMContext);
2680 llvm::Value *Target;
2681 if (IsClassMessage) {
2682 if (isCategoryImpl) {
2683 // Message sent to 'super' in a class method defined in a category
2684 // implementation requires an odd treatment.
2685 // If we are in a class method, we must retrieve the
2686 // _metaclass_ for the current class, pointed at by
2687 // the class's "isa" pointer. The following assumes that
2688 // isa" is the first ivar in a class (which it must be).
2689 Target = EmitClassRef(CGF, ID: Class->getSuperClass());
2690 Target = CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: Target, Idx: 0);
2691 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: Target,
2692 Align: CGF.getPointerAlign());
2693 } else {
2694 llvm::Constant *MetaClassPtr = EmitMetaClassRef(ID: Class);
2695 llvm::Value *SuperPtr =
2696 CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: MetaClassPtr, Idx: 1);
2697 llvm::Value *Super = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: SuperPtr,
2698 Align: CGF.getPointerAlign());
2699 Target = Super;
2700 }
2701 } else if (isCategoryImpl)
2702 Target = EmitClassRef(CGF, ID: Class->getSuperClass());
2703 else {
2704 llvm::Value *ClassPtr = EmitSuperClassRef(ID: Class);
2705 ClassPtr = CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: ClassPtr, Idx: 1);
2706 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: ClassPtr,
2707 Align: CGF.getPointerAlign());
2708 }
2709 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
2710 // ObjCTypes types.
2711 llvm::Type *ClassTy =
2712 CGM.getTypes().ConvertType(T: CGF.getContext().getObjCClassType());
2713 Target = CGF.Builder.CreateBitCast(V: Target, DestTy: ClassTy);
2714 CGF.Builder.CreateStore(Val: Target, Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 1));
2715 return EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: ObjCSuper.getPointer(),
2716 Arg0Ty: ObjCTypes.SuperPtrCTy, IsSuper: true, CallArgs, OMD: Method, ClassReceiver: Class,
2717 ObjCTypes);
2718}
2719
2720/// Generate code for a message send expression.
2721CodeGen::RValue CGObjCMac::GenerateMessageSend(
2722 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2723 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
2724 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
2725 return EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: Receiver,
2726 Arg0Ty: CGF.getContext().getObjCIdType(), IsSuper: false, CallArgs,
2727 OMD: Method, ClassReceiver: Class, ObjCTypes);
2728}
2729
2730CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2731 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2732 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper,
2733 const CallArgList &CallArgs, const ObjCMethodDecl *Method,
2734 const ObjCInterfaceDecl *ClassReceiver,
2735 const ObjCCommonTypesHelper &ObjCTypes) {
2736 CodeGenTypes &Types = CGM.getTypes();
2737 auto selTy = CGF.getContext().getObjCSelType();
2738 llvm::Value *ReceiverValue =
2739 llvm::PoisonValue::get(T: Types.ConvertType(T: Arg0Ty));
2740 llvm::Value *SelValue = llvm::UndefValue::get(T: Types.ConvertType(T: selTy));
2741
2742 CallArgList ActualArgs;
2743 if (!IsSuper)
2744 Arg0 = CGF.Builder.CreateBitCast(V: Arg0, DestTy: ObjCTypes.ObjectPtrTy);
2745 ActualArgs.add(rvalue: RValue::get(V: ReceiverValue), type: Arg0Ty);
2746 if (!Method || !Method->isDirectMethod())
2747 ActualArgs.add(rvalue: RValue::get(V: SelValue), type: selTy);
2748 ActualArgs.addFrom(other: CallArgs);
2749
2750 // If we're calling a method, use the formal signature.
2751 MessageSendInfo MSI = getMessageSendInfo(method: Method, resultType: ResultType, callArgs&: ActualArgs);
2752
2753 if (Method)
2754 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
2755 CGM.getContext().getCanonicalType(ResultType) &&
2756 "Result type mismatch!");
2757
2758 bool ReceiverCanBeNull =
2759 canMessageReceiverBeNull(CGF, method: Method, isSuper: IsSuper, classReceiver: ClassReceiver, receiver: Arg0);
2760 bool ClassObjectCanBeUnrealized =
2761 Method && Method->isClassMethod() &&
2762 canClassObjectBeUnrealized(ClassDecl: ClassReceiver, CGF);
2763
2764 bool RequiresNullCheck = false;
2765 bool RequiresReceiverValue = true;
2766 bool RequiresSelValue = true;
2767
2768 llvm::FunctionCallee Fn = nullptr;
2769 if (Method && Method->isDirectMethod()) {
2770 assert(!IsSuper);
2771 Fn = GetDirectMethodCallee(OMD: Method, CD: Method->getClassInterface(),
2772 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2773 // Direct methods will synthesize the proper `_cmd` internally,
2774 // so just don't bother with setting the `_cmd` argument.
2775 RequiresSelValue = false;
2776 } else if (CGM.ReturnSlotInterferesWithArgs(FI: MSI.CallInfo)) {
2777 if (ReceiverCanBeNull)
2778 RequiresNullCheck = true;
2779 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2780 : ObjCTypes.getSendStretFn(IsSuper);
2781 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2782 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2783 : ObjCTypes.getSendFpretFn(IsSuper);
2784 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2785 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2786 : ObjCTypes.getSendFp2retFn(IsSuper);
2787 } else {
2788 // arm64 uses objc_msgSend for stret methods and yet null receiver check
2789 // must be made for it.
2790 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(FI: MSI.CallInfo))
2791 RequiresNullCheck = true;
2792 // The class name that's used to create the class msgSend stub declaration.
2793 StringRef ClassName;
2794
2795 // We cannot use class msgSend stubs in the following cases:
2796 // 1. The class is annotated with `objc_class_stub` or
2797 // `objc_runtime_visible`.
2798 // 2. The selector name contains a '$'.
2799 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2800 Method && Method->isClassMethod() &&
2801 !ClassReceiver->hasAttr<ObjCClassStubAttr>() &&
2802 !ClassReceiver->hasAttr<ObjCRuntimeVisibleAttr>() &&
2803 Sel.getAsString().find(c: '$') == std::string::npos)
2804 ClassName = ClassReceiver->getObjCRuntimeNameAsString();
2805
2806 bool UseClassStub = ClassName.data();
2807 // Try to use a selector stub declaration instead of objc_msgSend.
2808 if (!IsSuper &&
2809 (CGM.getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2810 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2811 // Selector stubs synthesize `_cmd` in the stub, so we don't have to.
2812 RequiresReceiverValue = !UseClassStub;
2813 RequiresSelValue = false;
2814 } else {
2815 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2816 : ObjCTypes.getSendFn(IsSuper);
2817 }
2818 }
2819
2820 // Cast function to proper signature
2821 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2822 Val: CGF.Builder.CreateBitCast(V: Fn.getCallee(), DestTy: MSI.MessengerType));
2823
2824 // We don't need to emit a null check to zero out an indirect result if the
2825 // result is ignored.
2826 if (Return.isUnused())
2827 RequiresNullCheck = false;
2828
2829 // Emit a null-check if there's a consumed argument other than the receiver.
2830 if (!RequiresNullCheck && Method && Method->hasParamDestroyedInCallee())
2831 RequiresNullCheck = true;
2832
2833 if (CGM.shouldHavePreconditionInline(OMD: Method)) {
2834 // For variadic class methods, we need to inline precondition checks. That
2835 // include two things:
2836 // 1. We have to inline the class realization if we are not sure if it must
2837 // have been realized.
2838 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2839 // Perform class realization using the helper function
2840 Arg0 = GenerateClassRealization(CGF, classObject: Arg0, OID: ClassReceiver);
2841 ActualArgs[0] = CallArg(RValue::get(V: Arg0), ActualArgs[0].Ty);
2842 }
2843 // 2. We have to inline the precondition thunk if we are not sure if the
2844 // receiver can be null. Luckly, `NullReturnState` already does that for
2845 // corner cases like ns_consume, so we only need to override the flag,
2846 // regardless if the return value is unused.
2847 RequiresNullCheck |= ReceiverCanBeNull;
2848 }
2849
2850 NullReturnState nullReturn;
2851 if (RequiresNullCheck) {
2852 nullReturn.init(CGF, receiver: Arg0);
2853 }
2854
2855 // Pass the receiver value if it's needed.
2856 if (RequiresReceiverValue)
2857 ActualArgs[0] = CallArg(RValue::get(V: Arg0), Arg0Ty);
2858
2859 // If a selector value needs to be passed, emit the load before the call.
2860 if (RequiresSelValue) {
2861 SelValue = GetSelector(CGF, Sel);
2862 ActualArgs[1] = CallArg(RValue::get(V: SelValue), selTy);
2863 }
2864
2865 llvm::CallBase *CallSite;
2866 CGCallee Callee = CGCallee::forDirect(functionPtr: BitcastFn);
2867 RValue rvalue =
2868 CGF.EmitCall(CallInfo: MSI.CallInfo, Callee, ReturnValue: Return, Args: ActualArgs, CallOrInvoke: &CallSite);
2869
2870 // Mark the call as noreturn if the method is marked noreturn and the
2871 // receiver cannot be null.
2872 if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2873 CallSite->setDoesNotReturn();
2874 }
2875
2876 return nullReturn.complete(CGF, returnSlot: Return, result: rvalue, resultType: ResultType, CallArgs,
2877 Method: RequiresNullCheck ? Method : nullptr);
2878}
2879
2880static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,
2881 bool pointee = false) {
2882 // Note that GC qualification applies recursively to C pointer types
2883 // that aren't otherwise decorated. This is weird, but it's probably
2884 // an intentional workaround to the unreliable placement of GC qualifiers.
2885 if (FQT.isObjCGCStrong())
2886 return Qualifiers::Strong;
2887
2888 if (FQT.isObjCGCWeak())
2889 return Qualifiers::Weak;
2890
2891 if (auto ownership = FQT.getObjCLifetime()) {
2892 // Ownership does not apply recursively to C pointer types.
2893 if (pointee)
2894 return Qualifiers::GCNone;
2895 switch (ownership) {
2896 case Qualifiers::OCL_Weak:
2897 return Qualifiers::Weak;
2898 case Qualifiers::OCL_Strong:
2899 return Qualifiers::Strong;
2900 case Qualifiers::OCL_ExplicitNone:
2901 return Qualifiers::GCNone;
2902 case Qualifiers::OCL_Autoreleasing:
2903 llvm_unreachable("autoreleasing ivar?");
2904 case Qualifiers::OCL_None:
2905 llvm_unreachable("known nonzero");
2906 }
2907 llvm_unreachable("bad objc ownership");
2908 }
2909
2910 // Treat unqualified retainable pointers as strong.
2911 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2912 return Qualifiers::Strong;
2913
2914 // Walk into C pointer types, but only in GC.
2915 if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
2916 if (const PointerType *PT = FQT->getAs<PointerType>())
2917 return GetGCAttrTypeForType(Ctx, FQT: PT->getPointeeType(), /*pointee*/ true);
2918 }
2919
2920 return Qualifiers::GCNone;
2921}
2922
2923namespace {
2924struct IvarInfo {
2925 CharUnits Offset;
2926 uint64_t SizeInWords;
2927 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2928 : Offset(offset), SizeInWords(sizeInWords) {}
2929
2930 // Allow sorting based on byte pos.
2931 bool operator<(const IvarInfo &other) const { return Offset < other.Offset; }
2932};
2933
2934/// A helper class for building GC layout strings.
2935class IvarLayoutBuilder {
2936 CodeGenModule &CGM;
2937
2938 /// The start of the layout. Offsets will be relative to this value,
2939 /// and entries less than this value will be silently discarded.
2940 CharUnits InstanceBegin;
2941
2942 /// The end of the layout. Offsets will never exceed this value.
2943 CharUnits InstanceEnd;
2944
2945 /// Whether we're generating the strong layout or the weak layout.
2946 bool ForStrongLayout;
2947
2948 /// Whether the offsets in IvarsInfo might be out-of-order.
2949 bool IsDisordered = false;
2950
2951 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2952
2953public:
2954 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2955 CharUnits instanceEnd, bool forStrongLayout)
2956 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2957 ForStrongLayout(forStrongLayout) {}
2958
2959 void visitRecord(const RecordType *RT, CharUnits offset);
2960
2961 template <class Iterator, class GetOffsetFn>
2962 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2963 const GetOffsetFn &getOffset);
2964
2965 void visitField(const FieldDecl *field, CharUnits offset);
2966
2967 /// Add the layout of a block implementation.
2968 void visitBlock(const CGBlockInfo &blockInfo);
2969
2970 /// Is there any information for an interesting bitmap?
2971 bool hasBitmapData() const { return !IvarsInfo.empty(); }
2972
2973 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2974 llvm::SmallVectorImpl<unsigned char> &buffer);
2975
2976 static void dump(ArrayRef<unsigned char> buffer) {
2977 const unsigned char *s = buffer.data();
2978 for (unsigned i = 0, e = buffer.size(); i < e; i++)
2979 if (!(s[i] & 0xf0))
2980 printf(format: "0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2981 else
2982 printf(format: "0x%x%s", s[i], s[i] != 0 ? ", " : "");
2983 printf(format: "\n");
2984 }
2985};
2986} // end anonymous namespace
2987
2988llvm::Constant *
2989CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2990 const CGBlockInfo &blockInfo) {
2991
2992 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
2993 if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
2994 return nullPtr;
2995
2996 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
2997 /*for strong layout*/ true);
2998
2999 builder.visitBlock(blockInfo);
3000
3001 if (!builder.hasBitmapData())
3002 return nullPtr;
3003
3004 llvm::SmallVector<unsigned char, 32> buffer;
3005 llvm::Constant *C = builder.buildBitmap(CGObjC&: *this, buffer);
3006 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3007 printf(format: "\n block variable layout for block: ");
3008 builder.dump(buffer);
3009 }
3010
3011 return C;
3012}
3013
3014void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
3015 // __isa is the first field in block descriptor and must assume by runtime's
3016 // convention that it is GC'able.
3017 IvarsInfo.push_back(Elt: IvarInfo(CharUnits::Zero(), 1));
3018
3019 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3020
3021 // Ignore the optional 'this' capture: C++ objects are not assumed
3022 // to be GC'ed.
3023
3024 CharUnits lastFieldOffset;
3025
3026 // Walk the captured variables.
3027 for (const auto &CI : blockDecl->captures()) {
3028 const VarDecl *variable = CI.getVariable();
3029 QualType type = variable->getType();
3030
3031 const CGBlockInfo::Capture &capture = blockInfo.getCapture(var: variable);
3032
3033 // Ignore constant captures.
3034 if (capture.isConstant())
3035 continue;
3036
3037 CharUnits fieldOffset = capture.getOffset();
3038
3039 // Block fields are not necessarily ordered; if we detect that we're
3040 // adding them out-of-order, make sure we sort later.
3041 if (fieldOffset < lastFieldOffset)
3042 IsDisordered = true;
3043 lastFieldOffset = fieldOffset;
3044
3045 // __block variables are passed by their descriptor address.
3046 if (CI.isByRef()) {
3047 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, /*size in words*/ 1));
3048 continue;
3049 }
3050
3051 assert(!type->isArrayType() && "array variable should not be caught");
3052 if (const RecordType *record = type->getAsCanonical<RecordType>()) {
3053 visitRecord(RT: record, offset: fieldOffset);
3054 continue;
3055 }
3056
3057 Qualifiers::GC GCAttr = GetGCAttrTypeForType(Ctx&: CGM.getContext(), FQT: type);
3058
3059 if (GCAttr == Qualifiers::Strong) {
3060 assert(CGM.getContext().getTypeSize(type) ==
3061 CGM.getTarget().getPointerWidth(LangAS::Default));
3062 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, /*size in words*/ 1));
3063 }
3064 }
3065}
3066
3067/// getBlockCaptureLifetime - This routine returns life time of the captured
3068/// block variable for the purpose of block layout meta-data generation. FQT is
3069/// the type of the variable captured in the block.
3070Qualifiers::ObjCLifetime
3071CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT, bool ByrefLayout) {
3072 // If it has an ownership qualifier, we're done.
3073 if (auto lifetime = FQT.getObjCLifetime())
3074 return lifetime;
3075
3076 // If it doesn't, and this is ARC, it has no ownership.
3077 if (CGM.getLangOpts().ObjCAutoRefCount)
3078 return Qualifiers::OCL_None;
3079
3080 // In MRC, retainable pointers are owned by non-__block variables.
3081 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
3082 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
3083
3084 return Qualifiers::OCL_None;
3085}
3086
3087void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
3088 Qualifiers::ObjCLifetime LifeTime,
3089 CharUnits FieldOffset,
3090 CharUnits FieldSize) {
3091 // __block variables are passed by their descriptor address.
3092 if (IsByref)
3093 RunSkipBlockVars.push_back(
3094 Elt: RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3095 else if (LifeTime == Qualifiers::OCL_Strong)
3096 RunSkipBlockVars.push_back(
3097 Elt: RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3098 else if (LifeTime == Qualifiers::OCL_Weak)
3099 RunSkipBlockVars.push_back(
3100 Elt: RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3101 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
3102 RunSkipBlockVars.push_back(
3103 Elt: RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3104 else
3105 RunSkipBlockVars.push_back(
3106 Elt: RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3107}
3108
3109void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
3110 const RecordDecl *RD,
3111 ArrayRef<const FieldDecl *> RecFields,
3112 CharUnits BytePos, bool &HasUnion,
3113 bool ByrefLayout) {
3114 bool IsUnion = (RD && RD->isUnion());
3115 CharUnits MaxUnionSize = CharUnits::Zero();
3116 const FieldDecl *MaxField = nullptr;
3117 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
3118 CharUnits MaxFieldOffset = CharUnits::Zero();
3119 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
3120
3121 if (RecFields.empty())
3122 return;
3123 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3124
3125 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3126 const FieldDecl *Field = RecFields[i];
3127 // Note that 'i' here is actually the field index inside RD of Field,
3128 // although this dependency is hidden.
3129 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(D: RD);
3130 CharUnits FieldOffset =
3131 CGM.getContext().toCharUnitsFromBits(BitSize: RL.getFieldOffset(FieldNo: i));
3132
3133 // Skip over unnamed or bitfields
3134 if (!Field->getIdentifier() || Field->isBitField()) {
3135 LastFieldBitfieldOrUnnamed = Field;
3136 LastBitfieldOrUnnamedOffset = FieldOffset;
3137 continue;
3138 }
3139
3140 LastFieldBitfieldOrUnnamed = nullptr;
3141 QualType FQT = Field->getType();
3142 if (FQT->isRecordType() || FQT->isUnionType()) {
3143 if (FQT->isUnionType())
3144 HasUnion = true;
3145
3146 BuildRCBlockVarRecordLayout(RT: FQT->castAsCanonical<RecordType>(),
3147 BytePos: BytePos + FieldOffset, HasUnion);
3148 continue;
3149 }
3150
3151 if (const ArrayType *Array = CGM.getContext().getAsArrayType(T: FQT)) {
3152 auto *CArray = cast<ConstantArrayType>(Val: Array);
3153 uint64_t ElCount = CArray->getZExtSize();
3154 assert(CArray && "only array with known element size is supported");
3155 FQT = CArray->getElementType();
3156 while (const ArrayType *Array = CGM.getContext().getAsArrayType(T: FQT)) {
3157 auto *CArray = cast<ConstantArrayType>(Val: Array);
3158 ElCount *= CArray->getZExtSize();
3159 FQT = CArray->getElementType();
3160 }
3161 if (FQT->isRecordType() && ElCount) {
3162 int OldIndex = RunSkipBlockVars.size() - 1;
3163 auto *RT = FQT->castAsCanonical<RecordType>();
3164 BuildRCBlockVarRecordLayout(RT, BytePos: BytePos + FieldOffset, HasUnion);
3165
3166 // Replicate layout information for each array element. Note that
3167 // one element is already done.
3168 uint64_t ElIx = 1;
3169 for (int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3170 ElIx++) {
3171 CharUnits Size = CGM.getContext().getTypeSizeInChars(T: RT);
3172 for (int i = OldIndex + 1; i <= FirstIndex; ++i)
3173 RunSkipBlockVars.push_back(
3174 Elt: RUN_SKIP(RunSkipBlockVars[i].opcode,
3175 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3176 RunSkipBlockVars[i].block_var_size));
3177 }
3178 continue;
3179 }
3180 }
3181 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(T: Field->getType());
3182 if (IsUnion) {
3183 CharUnits UnionIvarSize = FieldSize;
3184 if (UnionIvarSize > MaxUnionSize) {
3185 MaxUnionSize = UnionIvarSize;
3186 MaxField = Field;
3187 MaxFieldOffset = FieldOffset;
3188 }
3189 } else {
3190 UpdateRunSkipBlockVars(IsByref: false, LifeTime: getBlockCaptureLifetime(FQT, ByrefLayout),
3191 FieldOffset: BytePos + FieldOffset, FieldSize);
3192 }
3193 }
3194
3195 if (LastFieldBitfieldOrUnnamed) {
3196 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3197 // Last field was a bitfield. Must update the info.
3198 uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue();
3199 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3200 ((BitFieldSize % ByteSizeInBits) != 0);
3201 CharUnits Size = CharUnits::fromQuantity(Quantity: UnsSize);
3202 Size += LastBitfieldOrUnnamedOffset;
3203 UpdateRunSkipBlockVars(
3204 IsByref: false,
3205 LifeTime: getBlockCaptureLifetime(FQT: LastFieldBitfieldOrUnnamed->getType(),
3206 ByrefLayout),
3207 FieldOffset: BytePos + LastBitfieldOrUnnamedOffset, FieldSize: Size);
3208 } else {
3209 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&
3210 "Expected unnamed");
3211 // Last field was unnamed. Must update skip info.
3212 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(
3213 T: LastFieldBitfieldOrUnnamed->getType());
3214 UpdateRunSkipBlockVars(
3215 IsByref: false,
3216 LifeTime: getBlockCaptureLifetime(FQT: LastFieldBitfieldOrUnnamed->getType(),
3217 ByrefLayout),
3218 FieldOffset: BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3219 }
3220 }
3221
3222 if (MaxField)
3223 UpdateRunSkipBlockVars(
3224 IsByref: false, LifeTime: getBlockCaptureLifetime(FQT: MaxField->getType(), ByrefLayout),
3225 FieldOffset: BytePos + MaxFieldOffset, FieldSize: MaxUnionSize);
3226}
3227
3228void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
3229 CharUnits BytePos,
3230 bool &HasUnion,
3231 bool ByrefLayout) {
3232 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
3233 SmallVector<const FieldDecl *, 16> Fields(RD->fields());
3234 llvm::Type *Ty = CGM.getTypes().ConvertType(T: QualType(RT, 0));
3235 const llvm::StructLayout *RecLayout =
3236 CGM.getDataLayout().getStructLayout(Ty: cast<llvm::StructType>(Val: Ty));
3237
3238 BuildRCRecordLayout(RecLayout, RD, RecFields: Fields, BytePos, HasUnion, ByrefLayout);
3239}
3240
3241/// InlineLayoutInstruction - This routine produce an inline instruction for the
3242/// block variable layout if it can. If not, it returns 0. Rules are as follow:
3243/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit
3244/// world, an inline layout of value 0x0000000000000xyz is interpreted as
3245/// follows: x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by y
3246/// captured object of BLOCK_LAYOUT_BYREF. Followed by z captured object of
3247/// BLOCK_LAYOUT_WEAK. If any of the above is missing, zero replaces it. For
3248/// example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no BLOCK_LAYOUT_BYREF
3249/// and no BLOCK_LAYOUT_WEAK objects are captured.
3250uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3251 SmallVectorImpl<unsigned char> &Layout) {
3252 uint64_t Result = 0;
3253 if (Layout.size() <= 3) {
3254 unsigned size = Layout.size();
3255 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3256 unsigned char inst;
3257 enum BLOCK_LAYOUT_OPCODE opcode;
3258 switch (size) {
3259 case 3:
3260 inst = Layout[0];
3261 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3262 if (opcode == BLOCK_LAYOUT_STRONG)
3263 strong_word_count = (inst & 0xF) + 1;
3264 else
3265 return 0;
3266 inst = Layout[1];
3267 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3268 if (opcode == BLOCK_LAYOUT_BYREF)
3269 byref_word_count = (inst & 0xF) + 1;
3270 else
3271 return 0;
3272 inst = Layout[2];
3273 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3274 if (opcode == BLOCK_LAYOUT_WEAK)
3275 weak_word_count = (inst & 0xF) + 1;
3276 else
3277 return 0;
3278 break;
3279
3280 case 2:
3281 inst = Layout[0];
3282 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3283 if (opcode == BLOCK_LAYOUT_STRONG) {
3284 strong_word_count = (inst & 0xF) + 1;
3285 inst = Layout[1];
3286 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3287 if (opcode == BLOCK_LAYOUT_BYREF)
3288 byref_word_count = (inst & 0xF) + 1;
3289 else if (opcode == BLOCK_LAYOUT_WEAK)
3290 weak_word_count = (inst & 0xF) + 1;
3291 else
3292 return 0;
3293 } else if (opcode == BLOCK_LAYOUT_BYREF) {
3294 byref_word_count = (inst & 0xF) + 1;
3295 inst = Layout[1];
3296 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3297 if (opcode == BLOCK_LAYOUT_WEAK)
3298 weak_word_count = (inst & 0xF) + 1;
3299 else
3300 return 0;
3301 } else
3302 return 0;
3303 break;
3304
3305 case 1:
3306 inst = Layout[0];
3307 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3308 if (opcode == BLOCK_LAYOUT_STRONG)
3309 strong_word_count = (inst & 0xF) + 1;
3310 else if (opcode == BLOCK_LAYOUT_BYREF)
3311 byref_word_count = (inst & 0xF) + 1;
3312 else if (opcode == BLOCK_LAYOUT_WEAK)
3313 weak_word_count = (inst & 0xF) + 1;
3314 else
3315 return 0;
3316 break;
3317
3318 default:
3319 return 0;
3320 }
3321
3322 // Cannot inline when any of the word counts is 15. Because this is one less
3323 // than the actual work count (so 15 means 16 actual word counts),
3324 // and we can only display 0 thru 15 word counts.
3325 if (strong_word_count == 16 || byref_word_count == 16 ||
3326 weak_word_count == 16)
3327 return 0;
3328
3329 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3330 (weak_word_count != 0);
3331
3332 if (size == count) {
3333 if (strong_word_count)
3334 Result = strong_word_count;
3335 Result <<= 4;
3336 if (byref_word_count)
3337 Result += byref_word_count;
3338 Result <<= 4;
3339 if (weak_word_count)
3340 Result += weak_word_count;
3341 }
3342 }
3343 return Result;
3344}
3345
3346llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
3347 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
3348 if (RunSkipBlockVars.empty())
3349 return nullPtr;
3350 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(AddrSpace: LangAS::Default);
3351 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3352 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3353
3354 // Sort on byte position; captures might not be allocated in order,
3355 // and unions can do funny things.
3356 llvm::array_pod_sort(Start: RunSkipBlockVars.begin(), End: RunSkipBlockVars.end());
3357 SmallVector<unsigned char, 16> Layout;
3358
3359 unsigned size = RunSkipBlockVars.size();
3360 for (unsigned i = 0; i < size; i++) {
3361 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3362 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3363 CharUnits end_byte_pos = start_byte_pos;
3364 unsigned j = i + 1;
3365 while (j < size) {
3366 if (opcode == RunSkipBlockVars[j].opcode) {
3367 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3368 i++;
3369 } else
3370 break;
3371 }
3372 CharUnits size_in_bytes =
3373 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3374 if (j < size) {
3375 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3376 RunSkipBlockVars[j - 1].block_var_bytepos -
3377 RunSkipBlockVars[j - 1].block_var_size;
3378 size_in_bytes += gap;
3379 }
3380 CharUnits residue_in_bytes = CharUnits::Zero();
3381 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3382 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3383 size_in_bytes -= residue_in_bytes;
3384 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3385 }
3386
3387 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
3388 while (size_in_words >= 16) {
3389 // Note that value in imm. is one less that the actual
3390 // value. So, 0xf means 16 words follow!
3391 unsigned char inst = (opcode << 4) | 0xf;
3392 Layout.push_back(Elt: inst);
3393 size_in_words -= 16;
3394 }
3395 if (size_in_words > 0) {
3396 // Note that value in imm. is one less that the actual
3397 // value. So, we subtract 1 away!
3398 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3399 Layout.push_back(Elt: inst);
3400 }
3401 if (residue_in_bytes > CharUnits::Zero()) {
3402 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3403 (residue_in_bytes.getQuantity() - 1);
3404 Layout.push_back(Elt: inst);
3405 }
3406 }
3407
3408 while (!Layout.empty()) {
3409 unsigned char inst = Layout.back();
3410 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3411 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3412 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3413 Layout.pop_back();
3414 else
3415 break;
3416 }
3417
3418 uint64_t Result = InlineLayoutInstruction(Layout);
3419 if (Result != 0) {
3420 // Block variable layout instruction has been inlined.
3421 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3422 if (ComputeByrefLayout)
3423 printf(format: "\n Inline BYREF variable layout: ");
3424 else
3425 printf(format: "\n Inline block variable layout: ");
3426 printf(format: "0x0%" PRIx64 "", Result);
3427 if (auto numStrong = (Result & 0xF00) >> 8)
3428 printf(format: ", BL_STRONG:%d", (int)numStrong);
3429 if (auto numByref = (Result & 0x0F0) >> 4)
3430 printf(format: ", BL_BYREF:%d", (int)numByref);
3431 if (auto numWeak = (Result & 0x00F) >> 0)
3432 printf(format: ", BL_WEAK:%d", (int)numWeak);
3433 printf(format: ", BL_OPERATOR:0\n");
3434 }
3435 return llvm::ConstantInt::get(Ty: CGM.IntPtrTy, V: Result);
3436 }
3437
3438 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3439 Layout.push_back(Elt: inst);
3440 std::string BitMap;
3441 for (unsigned char C : Layout)
3442 BitMap += C;
3443
3444 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3445 if (ComputeByrefLayout)
3446 printf(format: "\n Byref variable layout: ");
3447 else
3448 printf(format: "\n Block variable layout: ");
3449 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
3450 unsigned char inst = BitMap[i];
3451 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3452 unsigned delta = 1;
3453 switch (opcode) {
3454 case BLOCK_LAYOUT_OPERATOR:
3455 printf(format: "BL_OPERATOR:");
3456 delta = 0;
3457 break;
3458 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3459 printf(format: "BL_NON_OBJECT_BYTES:");
3460 break;
3461 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3462 printf(format: "BL_NON_OBJECT_WORD:");
3463 break;
3464 case BLOCK_LAYOUT_STRONG:
3465 printf(format: "BL_STRONG:");
3466 break;
3467 case BLOCK_LAYOUT_BYREF:
3468 printf(format: "BL_BYREF:");
3469 break;
3470 case BLOCK_LAYOUT_WEAK:
3471 printf(format: "BL_WEAK:");
3472 break;
3473 case BLOCK_LAYOUT_UNRETAINED:
3474 printf(format: "BL_UNRETAINED:");
3475 break;
3476 }
3477 // Actual value of word count is one more that what is in the imm.
3478 // field of the instruction
3479 printf(format: "%d", (inst & 0xf) + delta);
3480 if (i < e - 1)
3481 printf(format: ", ");
3482 else
3483 printf(format: "\n");
3484 }
3485 }
3486
3487 return CreateCStringLiteral(Name: BitMap, LabelType: ObjCLabelType::LayoutBitMap,
3488 /*ForceNonFragileABI=*/true,
3489 /*NullTerminate=*/false);
3490}
3491
3492static std::string getBlockLayoutInfoString(
3493 const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,
3494 bool HasCopyDisposeHelpers) {
3495 std::string Str;
3496 for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3497 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3498 // Copy/dispose helpers don't have any information about
3499 // __unsafe_unretained captures, so unconditionally concatenate a string.
3500 Str += "u";
3501 } else if (HasCopyDisposeHelpers) {
3502 // Information about __strong, __weak, or byref captures has already been
3503 // encoded into the names of the copy/dispose helpers. We have to add a
3504 // string here only when the copy/dispose helpers aren't generated (which
3505 // happens when the block is non-escaping).
3506 continue;
3507 } else {
3508 switch (R.opcode) {
3509 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3510 Str += "s";
3511 break;
3512 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3513 Str += "r";
3514 break;
3515 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3516 Str += "w";
3517 break;
3518 default:
3519 continue;
3520 }
3521 }
3522 Str += llvm::to_string(Value: R.block_var_bytepos.getQuantity());
3523 Str += "l" + llvm::to_string(Value: R.block_var_size.getQuantity());
3524 }
3525 return Str;
3526}
3527
3528void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3529 const CGBlockInfo &blockInfo) {
3530 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3531
3532 RunSkipBlockVars.clear();
3533 bool hasUnion = false;
3534
3535 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(AddrSpace: LangAS::Default);
3536 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3537 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3538
3539 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3540
3541 // Calculate the basic layout of the block structure.
3542 const llvm::StructLayout *layout =
3543 CGM.getDataLayout().getStructLayout(Ty: blockInfo.StructureType);
3544
3545 // Ignore the optional 'this' capture: C++ objects are not assumed
3546 // to be GC'ed.
3547 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
3548 UpdateRunSkipBlockVars(IsByref: false, LifeTime: Qualifiers::OCL_None,
3549 FieldOffset: blockInfo.BlockHeaderForcedGapOffset,
3550 FieldSize: blockInfo.BlockHeaderForcedGapSize);
3551 // Walk the captured variables.
3552 for (const auto &CI : blockDecl->captures()) {
3553 const VarDecl *variable = CI.getVariable();
3554 QualType type = variable->getType();
3555
3556 const CGBlockInfo::Capture &capture = blockInfo.getCapture(var: variable);
3557
3558 // Ignore constant captures.
3559 if (capture.isConstant())
3560 continue;
3561
3562 CharUnits fieldOffset =
3563 CharUnits::fromQuantity(Quantity: layout->getElementOffset(Idx: capture.getIndex()));
3564
3565 assert(!type->isArrayType() && "array variable should not be caught");
3566 if (!CI.isByRef())
3567 if (const auto *record = type->getAsCanonical<RecordType>()) {
3568 BuildRCBlockVarRecordLayout(RT: record, BytePos: fieldOffset, HasUnion&: hasUnion);
3569 continue;
3570 }
3571 CharUnits fieldSize;
3572 if (CI.isByRef())
3573 fieldSize = CharUnits::fromQuantity(Quantity: WordSizeInBytes);
3574 else
3575 fieldSize = CGM.getContext().getTypeSizeInChars(T: type);
3576 UpdateRunSkipBlockVars(IsByref: CI.isByRef(), LifeTime: getBlockCaptureLifetime(FQT: type, ByrefLayout: false),
3577 FieldOffset: fieldOffset, FieldSize: fieldSize);
3578 }
3579}
3580
3581llvm::Constant *
3582CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3583 const CGBlockInfo &blockInfo) {
3584 fillRunSkipBlockVars(CGM, blockInfo);
3585 return getBitmapBlockLayout(ComputeByrefLayout: false);
3586}
3587
3588std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3589 const CGBlockInfo &blockInfo) {
3590 fillRunSkipBlockVars(CGM, blockInfo);
3591 return getBlockLayoutInfoString(RunSkipBlockVars, HasCopyDisposeHelpers: blockInfo.NeedsCopyDispose);
3592}
3593
3594llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3595 QualType T) {
3596 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3597 assert(!T->isArrayType() && "__block array variable should not be caught");
3598 CharUnits fieldOffset;
3599 RunSkipBlockVars.clear();
3600 bool hasUnion = false;
3601 if (const auto *record = T->getAsCanonical<RecordType>()) {
3602 BuildRCBlockVarRecordLayout(RT: record, BytePos: fieldOffset, HasUnion&: hasUnion,
3603 ByrefLayout: true /*ByrefLayout */);
3604 llvm::Constant *Result = getBitmapBlockLayout(ComputeByrefLayout: true);
3605 if (isa<llvm::ConstantInt>(Val: Result))
3606 Result = llvm::ConstantExpr::getIntToPtr(C: Result, Ty: CGM.Int8PtrTy);
3607 return Result;
3608 }
3609 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
3610 return nullPtr;
3611}
3612
3613llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3614 const ObjCProtocolDecl *PD) {
3615 // FIXME: I don't understand why gcc generates this, or where it is
3616 // resolved. Investigate. Its also wasteful to look this up over and over.
3617 LazySymbols.insert(X: &CGM.getContext().Idents.get(Name: "Protocol"));
3618
3619 return GetProtocolRef(PD);
3620}
3621
3622void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
3623 // FIXME: We shouldn't need this, the protocol decl should contain enough
3624 // information to tell us whether this was a declaration or a definition.
3625 DefinedProtocols.insert(V: PD->getIdentifier());
3626
3627 // If we have generated a forward reference to this protocol, emit
3628 // it now. Otherwise do nothing, the protocol objects are lazily
3629 // emitted.
3630 if (Protocols.count(Val: PD->getIdentifier()))
3631 GetOrEmitProtocol(PD);
3632}
3633
3634llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
3635 if (DefinedProtocols.count(V: PD->getIdentifier()))
3636 return GetOrEmitProtocol(PD);
3637
3638 return GetOrEmitProtocolRef(PD);
3639}
3640
3641llvm::Value *
3642CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3643 const ObjCInterfaceDecl *ID,
3644 ObjCCommonTypesHelper &ObjCTypes) {
3645 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3646
3647 llvm::Value *className = CGF.CGM
3648 .GetAddrOfConstantCString(Str: std::string(
3649 ID->getObjCRuntimeNameAsString()))
3650 .getPointer();
3651 ASTContext &ctx = CGF.CGM.getContext();
3652 className = CGF.Builder.CreateBitCast(
3653 V: className, DestTy: CGF.ConvertType(T: ctx.getPointerType(T: ctx.CharTy.withConst())));
3654 llvm::CallInst *call = CGF.Builder.CreateCall(Callee: lookUpClassFn, Args: className);
3655 call->setDoesNotThrow();
3656 return call;
3657}
3658
3659/*
3660// Objective-C 1.0 extensions
3661struct _objc_protocol {
3662struct _objc_protocol_extension *isa;
3663char *protocol_name;
3664struct _objc_protocol_list *protocol_list;
3665struct _objc__method_prototype_list *instance_methods;
3666struct _objc__method_prototype_list *class_methods
3667};
3668
3669See EmitProtocolExtension().
3670*/
3671llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
3672 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
3673
3674 // Early exit if a defining object has already been generated.
3675 if (Entry && Entry->hasInitializer())
3676 return Entry;
3677
3678 // Use the protocol definition, if there is one.
3679 if (const ObjCProtocolDecl *Def = PD->getDefinition())
3680 PD = Def;
3681
3682 // FIXME: I don't understand why gcc generates this, or where it is
3683 // resolved. Investigate. Its also wasteful to look this up over and over.
3684 LazySymbols.insert(X: &CGM.getContext().Idents.get(Name: "Protocol"));
3685
3686 // Construct method lists.
3687 auto methodLists = ProtocolMethodLists::get(PD);
3688
3689 ConstantInitBuilder builder(CGM);
3690 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolTy);
3691 values.add(value: EmitProtocolExtension(PD, methodLists));
3692 values.add(value: GetClassName(RuntimeName: PD->getObjCRuntimeNameAsString()));
3693 values.add(value: EmitProtocolList(Name: "OBJC_PROTOCOL_REFS_" + PD->getName(),
3694 begin: PD->protocol_begin(), end: PD->protocol_end()));
3695 values.add(value: methodLists.emitMethodList(
3696 self: this, PD, kind: ProtocolMethodLists::RequiredInstanceMethods));
3697 values.add(value: methodLists.emitMethodList(
3698 self: this, PD, kind: ProtocolMethodLists::RequiredClassMethods));
3699
3700 if (Entry) {
3701 // Already created, update the initializer.
3702 assert(Entry->hasPrivateLinkage());
3703 values.finishAndSetAsInitializer(global: Entry);
3704 } else {
3705 Entry = values.finishAndCreateGlobal(
3706 args: "OBJC_PROTOCOL_" + PD->getName(), args: CGM.getPointerAlign(),
3707 /*constant*/ args: false, args: llvm::GlobalValue::PrivateLinkage);
3708 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3709
3710 Protocols[PD->getIdentifier()] = Entry;
3711 }
3712 CGM.addCompilerUsedGlobal(GV: Entry);
3713
3714 return Entry;
3715}
3716
3717llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
3718 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
3719
3720 if (!Entry) {
3721 // We use the initializer as a marker of whether this is a forward
3722 // reference or not. At module finalization we add the empty
3723 // contents for protocols which were referenced but never defined.
3724 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
3725 false, llvm::GlobalValue::PrivateLinkage,
3726 nullptr, "OBJC_PROTOCOL_" + PD->getName());
3727 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3728 // FIXME: Is this necessary? Why only for protocol?
3729 Entry->setAlignment(llvm::Align(4));
3730 }
3731
3732 return Entry;
3733}
3734
3735/*
3736 struct _objc_protocol_extension {
3737 uint32_t size;
3738 struct objc_method_description_list *optional_instance_methods;
3739 struct objc_method_description_list *optional_class_methods;
3740 struct objc_property_list *instance_properties;
3741 const char ** extendedMethodTypes;
3742 struct objc_property_list *class_properties;
3743 };
3744*/
3745llvm::Constant *
3746CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
3747 const ProtocolMethodLists &methodLists) {
3748 auto optInstanceMethods = methodLists.emitMethodList(
3749 self: this, PD, kind: ProtocolMethodLists::OptionalInstanceMethods);
3750 auto optClassMethods = methodLists.emitMethodList(
3751 self: this, PD, kind: ProtocolMethodLists::OptionalClassMethods);
3752
3753 auto extendedMethodTypes = EmitProtocolMethodTypes(
3754 Name: "OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3755 MethodTypes: methodLists.emitExtendedTypesArray(self: this), ObjCTypes);
3756
3757 auto instanceProperties = EmitPropertyList(
3758 Name: "OBJC_$_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: false);
3759 auto classProperties =
3760 EmitPropertyList(Name: "OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr,
3761 OCD: PD, ObjCTypes, IsClassProperty: true);
3762
3763 // Return null if no extension bits are used.
3764 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3765 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3766 classProperties->isNullValue()) {
3767 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolExtensionPtrTy);
3768 }
3769
3770 uint64_t size =
3771 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ProtocolExtensionTy);
3772
3773 ConstantInitBuilder builder(CGM);
3774 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolExtensionTy);
3775 values.addInt(intTy: ObjCTypes.IntTy, value: size);
3776 values.add(value: optInstanceMethods);
3777 values.add(value: optClassMethods);
3778 values.add(value: instanceProperties);
3779 values.add(value: extendedMethodTypes);
3780 values.add(value: classProperties);
3781
3782 // No special section, but goes in llvm.used
3783 return CreateMetadataVar(Name: "_OBJC_PROTOCOLEXT_" + PD->getName(), Init&: values,
3784 Section: StringRef(), Align: CGM.getPointerAlign(), AddToUsed: true);
3785}
3786
3787/*
3788 struct objc_protocol_list {
3789 struct objc_protocol_list *next;
3790 long count;
3791 Protocol *list[];
3792 };
3793*/
3794llvm::Constant *
3795CGObjCMac::EmitProtocolList(Twine name,
3796 ObjCProtocolDecl::protocol_iterator begin,
3797 ObjCProtocolDecl::protocol_iterator end) {
3798 // Just return null for empty protocol lists
3799 auto PDs = GetRuntimeProtocolList(begin, end);
3800 if (PDs.empty())
3801 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListPtrTy);
3802
3803 ConstantInitBuilder builder(CGM);
3804 auto values = builder.beginStruct();
3805
3806 // This field is only used by the runtime.
3807 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
3808
3809 // Reserve a slot for the count.
3810 auto countSlot = values.addPlaceholder();
3811
3812 auto refsArray = values.beginArray(eltTy: ObjCTypes.ProtocolPtrTy);
3813 for (const auto *Proto : PDs)
3814 refsArray.add(value: GetProtocolRef(PD: Proto));
3815
3816 auto count = refsArray.size();
3817
3818 // This list is null terminated.
3819 refsArray.addNullPointer(ptrTy: ObjCTypes.ProtocolPtrTy);
3820
3821 refsArray.finishAndAddTo(parent&: values);
3822 values.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.LongTy, value: count);
3823
3824 StringRef section;
3825 if (CGM.getTriple().isOSBinFormatMachO())
3826 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3827
3828 llvm::GlobalVariable *GV =
3829 CreateMetadataVar(Name: name, Init&: values, Section: section, Align: CGM.getPointerAlign(), AddToUsed: false);
3830 return GV;
3831}
3832
3833static void PushProtocolProperties(
3834 llvm::SmallPtrSet<const IdentifierInfo *, 16> &PropertySet,
3835 SmallVectorImpl<const ObjCPropertyDecl *> &Properties,
3836 const ObjCProtocolDecl *Proto, bool IsClassProperty) {
3837 for (const auto *PD : Proto->properties()) {
3838 if (IsClassProperty != PD->isClassProperty())
3839 continue;
3840 if (!PropertySet.insert(Ptr: PD->getIdentifier()).second)
3841 continue;
3842 Properties.push_back(Elt: PD);
3843 }
3844
3845 for (const auto *P : Proto->protocols())
3846 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3847}
3848
3849/*
3850 struct _objc_property {
3851 const char * const name;
3852 const char * const attributes;
3853 };
3854
3855 struct _objc_property_list {
3856 uint32_t entsize; // sizeof (struct _objc_property)
3857 uint32_t prop_count;
3858 struct _objc_property[prop_count];
3859 };
3860*/
3861llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3862 Twine Name, const Decl *Container, const ObjCContainerDecl *OCD,
3863 const ObjCCommonTypesHelper &ObjCTypes, bool IsClassProperty) {
3864 if (IsClassProperty) {
3865 // Make this entry NULL for OS X with deployment target < 10.11, for iOS
3866 // with deployment target < 9.0.
3867 const llvm::Triple &Triple = CGM.getTarget().getTriple();
3868 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(Major: 10, Minor: 11)) ||
3869 (Triple.isiOS() && Triple.isOSVersionLT(Major: 9)))
3870 return llvm::Constant::getNullValue(Ty: ObjCTypes.PropertyListPtrTy);
3871 }
3872
3873 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3874 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3875
3876 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(Val: OCD))
3877 for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3878 for (auto *PD : ClassExt->properties()) {
3879 if (IsClassProperty != PD->isClassProperty())
3880 continue;
3881 if (PD->isDirectProperty())
3882 continue;
3883 PropertySet.insert(Ptr: PD->getIdentifier());
3884 Properties.push_back(Elt: PD);
3885 }
3886
3887 for (const auto *PD : OCD->properties()) {
3888 if (IsClassProperty != PD->isClassProperty())
3889 continue;
3890 // Don't emit duplicate metadata for properties that were already in a
3891 // class extension.
3892 if (!PropertySet.insert(Ptr: PD->getIdentifier()).second)
3893 continue;
3894 if (PD->isDirectProperty())
3895 continue;
3896 Properties.push_back(Elt: PD);
3897 }
3898
3899 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(Val: OCD)) {
3900 for (const auto *P : OID->all_referenced_protocols())
3901 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3902 } else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(Val: OCD)) {
3903 for (const auto *P : CD->protocols())
3904 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3905 }
3906
3907 // Return null for empty list.
3908 if (Properties.empty())
3909 return llvm::Constant::getNullValue(Ty: ObjCTypes.PropertyListPtrTy);
3910
3911 unsigned propertySize =
3912 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.PropertyTy);
3913
3914 ConstantInitBuilder builder(CGM);
3915 auto values = builder.beginStruct();
3916 values.addInt(intTy: ObjCTypes.IntTy, value: propertySize);
3917 values.addInt(intTy: ObjCTypes.IntTy, value: Properties.size());
3918 auto propertiesArray = values.beginArray(eltTy: ObjCTypes.PropertyTy);
3919 for (auto PD : Properties) {
3920 auto property = propertiesArray.beginStruct(ty: ObjCTypes.PropertyTy);
3921 property.add(value: GetPropertyName(Ident: PD->getIdentifier()));
3922 property.add(value: GetPropertyTypeString(PD, Container));
3923 property.finishAndAddTo(parent&: propertiesArray);
3924 }
3925 propertiesArray.finishAndAddTo(parent&: values);
3926
3927 StringRef Section;
3928 if (CGM.getTriple().isOSBinFormatMachO())
3929 Section = (ObjCABI == 2) ? "__DATA, __objc_const"
3930 : "__OBJC,__property,regular,no_dead_strip";
3931
3932 llvm::GlobalVariable *GV =
3933 CreateMetadataVar(Name, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
3934 return GV;
3935}
3936
3937llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3938 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3939 const ObjCCommonTypesHelper &ObjCTypes) {
3940 // Return null for empty list.
3941 if (MethodTypes.empty())
3942 return llvm::Constant::getNullValue(Ty: ObjCTypes.Int8PtrPtrTy);
3943
3944 llvm::ArrayType *AT =
3945 llvm::ArrayType::get(ElementType: ObjCTypes.Int8PtrTy, NumElements: MethodTypes.size());
3946 llvm::Constant *Init = llvm::ConstantArray::get(T: AT, V: MethodTypes);
3947
3948 StringRef Section;
3949 if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3950 Section = "__DATA, __objc_const";
3951
3952 llvm::GlobalVariable *GV =
3953 CreateMetadataVar(Name, Init, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
3954 return GV;
3955}
3956
3957/*
3958 struct _objc_category {
3959 char *category_name;
3960 char *class_name;
3961 struct _objc_method_list *instance_methods;
3962 struct _objc_method_list *class_methods;
3963 struct _objc_protocol_list *protocols;
3964 uint32_t size; // sizeof(struct _objc_category)
3965 struct _objc_property_list *instance_properties;
3966 struct _objc_property_list *class_properties;
3967 };
3968*/
3969void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3970 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.CategoryTy);
3971
3972 // FIXME: This is poor design, the OCD should have a pointer to the category
3973 // decl. Additionally, note that Category can be null for the @implementation
3974 // w/o an @interface case. Sema should just create one for us as it does for
3975 // @implementation so everyone else can live life under a clear blue sky.
3976 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3977 const ObjCCategoryDecl *Category =
3978 Interface->FindCategoryDeclaration(CategoryId: OCD->getIdentifier());
3979
3980 SmallString<256> ExtName;
3981 llvm::raw_svector_ostream(ExtName)
3982 << Interface->getName() << '_' << OCD->getName();
3983
3984 ConstantInitBuilder Builder(CGM);
3985 auto Values = Builder.beginStruct(structTy: ObjCTypes.CategoryTy);
3986
3987 enum { InstanceMethods, ClassMethods, NumMethodLists };
3988 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3989 for (const auto *MD : OCD->methods()) {
3990 if (!MD->isDirectMethod())
3991 Methods[unsigned(MD->isClassMethod())].push_back(Elt: MD);
3992 }
3993
3994 Values.add(value: GetClassName(RuntimeName: OCD->getName()));
3995 Values.add(value: GetClassName(RuntimeName: Interface->getObjCRuntimeNameAsString()));
3996 LazySymbols.insert(X: Interface->getIdentifier());
3997
3998 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryInstanceMethods,
3999 Methods: Methods[InstanceMethods]));
4000 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryClassMethods,
4001 Methods: Methods[ClassMethods]));
4002 if (Category) {
4003 Values.add(value: EmitProtocolList(name: "OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4004 begin: Category->protocol_begin(),
4005 end: Category->protocol_end()));
4006 } else {
4007 Values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
4008 }
4009 Values.addInt(intTy: ObjCTypes.IntTy, value: Size);
4010
4011 // If there is no category @interface then there can be no properties.
4012 if (Category) {
4013 Values.add(value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + ExtName.str(), Container: OCD,
4014 OCD: Category, ObjCTypes, IsClassProperty: false));
4015 Values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), Container: OCD,
4016 OCD: Category, ObjCTypes, IsClassProperty: true));
4017 } else {
4018 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
4019 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
4020 }
4021
4022 llvm::GlobalVariable *GV = CreateMetadataVar(
4023 Name: "OBJC_CATEGORY_" + ExtName.str(), Init&: Values,
4024 Section: "__OBJC,__category,regular,no_dead_strip", Align: CGM.getPointerAlign(), AddToUsed: true);
4025 DefinedCategories.push_back(Elt: GV);
4026 DefinedCategoryNames.insert(X: llvm::CachedHashString(ExtName));
4027 // method definition entries must be clear for next implementation.
4028 MethodDefinitions.clear();
4029}
4030
4031// clang-format off
4032enum FragileClassFlags {
4033 /// Apparently: is not a meta-class.
4034 FragileABI_Class_Factory = 0x00001,
4035
4036 /// Is a meta-class.
4037 FragileABI_Class_Meta = 0x00002,
4038
4039 /// Has a non-trivial constructor or destructor.
4040 FragileABI_Class_HasCXXStructors = 0x02000,
4041
4042 /// Has hidden visibility.
4043 FragileABI_Class_Hidden = 0x20000,
4044
4045 /// Class implementation was compiled under ARC.
4046 FragileABI_Class_CompiledByARC = 0x04000000,
4047
4048 /// Class implementation was compiled under MRC and has MRC weak ivars.
4049 /// Exclusive with CompiledByARC.
4050 FragileABI_Class_HasMRCWeakIvars = 0x08000000,
4051};
4052
4053enum NonFragileClassFlags {
4054 /// Is a meta-class.
4055 NonFragileABI_Class_Meta = 0x00001,
4056
4057 /// Is a root class.
4058 NonFragileABI_Class_Root = 0x00002,
4059
4060 /// Has a non-trivial constructor or destructor.
4061 NonFragileABI_Class_HasCXXStructors = 0x00004,
4062
4063 /// Has hidden visibility.
4064 NonFragileABI_Class_Hidden = 0x00010,
4065
4066 /// Has the exception attribute.
4067 NonFragileABI_Class_Exception = 0x00020,
4068
4069 /// (Obsolete) ARC-specific: this class has a .release_ivars method
4070 NonFragileABI_Class_HasIvarReleaser = 0x00040,
4071
4072 /// Class implementation was compiled under ARC.
4073 NonFragileABI_Class_CompiledByARC = 0x00080,
4074
4075 /// Class has non-trivial destructors, but zero-initialization is okay.
4076 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,
4077
4078 /// Class implementation was compiled under MRC and has MRC weak ivars.
4079 /// Exclusive with CompiledByARC.
4080 NonFragileABI_Class_HasMRCWeakIvars = 0x00200,
4081};
4082// clang-format on
4083
4084static bool hasWeakMember(QualType type) {
4085 if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
4086 return true;
4087 }
4088
4089 if (auto *RD = type->getAsRecordDecl()) {
4090 for (auto *field : RD->fields()) {
4091 if (hasWeakMember(type: field->getType()))
4092 return true;
4093 }
4094 }
4095
4096 return false;
4097}
4098
4099/// For compatibility, we only want to set the "HasMRCWeakIvars" flag
4100/// (and actually fill in a layout string) if we really do have any
4101/// __weak ivars.
4102static bool hasMRCWeakIvars(CodeGenModule &CGM,
4103 const ObjCImplementationDecl *ID) {
4104 if (!CGM.getLangOpts().ObjCWeak)
4105 return false;
4106 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
4107
4108 for (const ObjCIvarDecl *ivar =
4109 ID->getClassInterface()->all_declared_ivar_begin();
4110 ivar; ivar = ivar->getNextIvar()) {
4111 if (hasWeakMember(type: ivar->getType()))
4112 return true;
4113 }
4114
4115 return false;
4116}
4117
4118/*
4119 struct _objc_class {
4120 Class isa;
4121 Class super_class;
4122 const char *name;
4123 long version;
4124 long info;
4125 long instance_size;
4126 struct _objc_ivar_list *ivars;
4127 struct _objc_method_list *methods;
4128 struct _objc_cache *cache;
4129 struct _objc_protocol_list *protocols;
4130 // Objective-C 1.0 extensions (<rdr://4585769>)
4131 const char *ivar_layout;
4132 struct _objc_class_ext *ext;
4133 };
4134
4135 See EmitClassExtension();
4136*/
4137void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
4138 IdentifierInfo *RuntimeName =
4139 &CGM.getContext().Idents.get(Name: ID->getObjCRuntimeNameAsString());
4140 DefinedSymbols.insert(X: RuntimeName);
4141
4142 std::string ClassName = ID->getNameAsString();
4143 // FIXME: Gross
4144 ObjCInterfaceDecl *Interface =
4145 const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());
4146 llvm::Constant *Protocols =
4147 EmitProtocolList(name: "OBJC_CLASS_PROTOCOLS_" + ID->getName(),
4148 begin: Interface->all_referenced_protocol_begin(),
4149 end: Interface->all_referenced_protocol_end());
4150 unsigned Flags = FragileABI_Class_Factory;
4151 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
4152 Flags |= FragileABI_Class_HasCXXStructors;
4153
4154 bool hasMRCWeak = false;
4155
4156 if (CGM.getLangOpts().ObjCAutoRefCount)
4157 Flags |= FragileABI_Class_CompiledByARC;
4158 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
4159 Flags |= FragileABI_Class_HasMRCWeakIvars;
4160
4161 CharUnits Size = CGM.getContext()
4162 .getASTObjCInterfaceLayout(D: ID->getClassInterface())
4163 .getSize();
4164
4165 // FIXME: Set CXX-structors flag.
4166 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4167 Flags |= FragileABI_Class_Hidden;
4168
4169 enum { InstanceMethods, ClassMethods, NumMethodLists };
4170 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4171 for (const auto *MD : ID->methods()) {
4172 if (!MD->isDirectMethod())
4173 Methods[unsigned(MD->isClassMethod())].push_back(Elt: MD);
4174 }
4175
4176 for (const auto *PID : ID->property_impls()) {
4177 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
4178 if (PID->getPropertyDecl()->isDirectProperty())
4179 continue;
4180 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4181 if (GetMethodDefinition(MD))
4182 Methods[InstanceMethods].push_back(Elt: MD);
4183 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4184 if (GetMethodDefinition(MD))
4185 Methods[InstanceMethods].push_back(Elt: MD);
4186 }
4187 }
4188
4189 ConstantInitBuilder builder(CGM);
4190 auto values = builder.beginStruct(structTy: ObjCTypes.ClassTy);
4191 values.add(value: EmitMetaClass(ID, Protocols, Methods: Methods[ClassMethods]));
4192 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
4193 // Record a reference to the super class.
4194 LazySymbols.insert(X: Super->getIdentifier());
4195
4196 values.add(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
4197 } else {
4198 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
4199 }
4200 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
4201 // Version is always 0.
4202 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
4203 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
4204 values.addInt(intTy: ObjCTypes.LongTy, value: Size.getQuantity());
4205 values.add(value: EmitIvarList(ID, ForClass: false));
4206 values.add(value: emitMethodList(Name: ID->getName(), MLT: MethodListType::InstanceMethods,
4207 Methods: Methods[InstanceMethods]));
4208 // cache is always NULL.
4209 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
4210 values.add(value: Protocols);
4211 values.add(value: BuildStrongIvarLayout(OI: ID, beginOffset: CharUnits::Zero(), endOffset: Size));
4212 values.add(value: EmitClassExtension(ID, instanceSize: Size, hasMRCWeakIvars: hasMRCWeak,
4213 /*isMetaclass*/ false));
4214
4215 std::string Name("OBJC_CLASS_");
4216 Name += ClassName;
4217 const char *Section = "__OBJC,__class,regular,no_dead_strip";
4218 // Check for a forward reference.
4219 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4220 if (GV) {
4221 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4222 "Forward metaclass reference has incorrect type.");
4223 values.finishAndSetAsInitializer(global: GV);
4224 GV->setSection(Section);
4225 GV->setAlignment(CGM.getPointerAlign().getAsAlign());
4226 CGM.addCompilerUsedGlobal(GV);
4227 } else
4228 GV = CreateMetadataVar(Name, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
4229 DefinedClasses.push_back(Elt: GV);
4230 ImplementedClasses.push_back(Elt: Interface);
4231 // method definition entries must be clear for next implementation.
4232 MethodDefinitions.clear();
4233}
4234
4235llvm::Constant *
4236CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
4237 llvm::Constant *Protocols,
4238 ArrayRef<const ObjCMethodDecl *> Methods) {
4239 unsigned Flags = FragileABI_Class_Meta;
4240 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassTy);
4241
4242 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4243 Flags |= FragileABI_Class_Hidden;
4244
4245 ConstantInitBuilder builder(CGM);
4246 auto values = builder.beginStruct(structTy: ObjCTypes.ClassTy);
4247 // The isa for the metaclass is the root of the hierarchy.
4248 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4249 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4250 Root = Super;
4251 values.add(value: GetClassName(RuntimeName: Root->getObjCRuntimeNameAsString()));
4252 // The super class for the metaclass is emitted as the name of the
4253 // super class. The runtime fixes this up to point to the
4254 // *metaclass* for the super class.
4255 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
4256 values.add(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
4257 } else {
4258 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
4259 }
4260 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
4261 // Version is always 0.
4262 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
4263 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
4264 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
4265 values.add(value: EmitIvarList(ID, ForClass: true));
4266 values.add(
4267 value: emitMethodList(Name: ID->getName(), MLT: MethodListType::ClassMethods, Methods));
4268 // cache is always NULL.
4269 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
4270 values.add(value: Protocols);
4271 // ivar_layout for metaclass is always NULL.
4272 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
4273 // The class extension is used to store class properties for metaclasses.
4274 values.add(value: EmitClassExtension(ID, instanceSize: CharUnits::Zero(), hasMRCWeakIvars: false /*hasMRCWeak*/,
4275 /*isMetaclass*/ true));
4276
4277 std::string Name("OBJC_METACLASS_");
4278 Name += ID->getName();
4279
4280 // Check for a forward reference.
4281 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4282 if (GV) {
4283 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4284 "Forward metaclass reference has incorrect type.");
4285 values.finishAndSetAsInitializer(global: GV);
4286 } else {
4287 GV = values.finishAndCreateGlobal(args&: Name, args: CGM.getPointerAlign(),
4288 /*constant*/ args: false,
4289 args: llvm::GlobalValue::PrivateLinkage);
4290 }
4291 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
4292 CGM.addCompilerUsedGlobal(GV);
4293
4294 return GV;
4295}
4296
4297llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
4298 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
4299
4300 // FIXME: Should we look these up somewhere other than the module. Its a bit
4301 // silly since we only generate these while processing an implementation, so
4302 // exactly one pointer would work if know when we entered/exitted an
4303 // implementation block.
4304
4305 // Check for an existing forward reference.
4306 // Previously, metaclass with internal linkage may have been defined.
4307 // pass 'true' as 2nd argument so it is returned.
4308 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4309 if (!GV)
4310 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4311 llvm::GlobalValue::PrivateLinkage, nullptr,
4312 Name);
4313
4314 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4315 "Forward metaclass reference has incorrect type.");
4316 return GV;
4317}
4318
4319llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
4320 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
4321 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4322
4323 if (!GV)
4324 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4325 llvm::GlobalValue::PrivateLinkage, nullptr,
4326 Name);
4327
4328 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4329 "Forward class metadata reference has incorrect type.");
4330 return GV;
4331}
4332
4333/*
4334 Emit a "class extension", which in this specific context means extra
4335 data that doesn't fit in the normal fragile-ABI class structure, and
4336 has nothing to do with the language concept of a class extension.
4337
4338 struct objc_class_ext {
4339 uint32_t size;
4340 const char *weak_ivar_layout;
4341 struct _objc_property_list *properties;
4342 };
4343*/
4344llvm::Constant *CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
4345 CharUnits InstanceSize,
4346 bool hasMRCWeakIvars,
4347 bool isMetaclass) {
4348 // Weak ivar layout.
4349 llvm::Constant *layout;
4350 if (isMetaclass) {
4351 layout = llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy);
4352 } else {
4353 layout = BuildWeakIvarLayout(OI: ID, beginOffset: CharUnits::Zero(), endOffset: InstanceSize,
4354 hasMRCWeakIvars);
4355 }
4356
4357 // Properties.
4358 llvm::Constant *propertyList =
4359 EmitPropertyList(Name: (isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")
4360 : Twine("_OBJC_$_PROP_LIST_")) +
4361 ID->getName(),
4362 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: isMetaclass);
4363
4364 // Return null if no extension bits are used.
4365 if (layout->isNullValue() && propertyList->isNullValue()) {
4366 return llvm::Constant::getNullValue(Ty: ObjCTypes.ClassExtensionPtrTy);
4367 }
4368
4369 uint64_t size =
4370 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassExtensionTy);
4371
4372 ConstantInitBuilder builder(CGM);
4373 auto values = builder.beginStruct(structTy: ObjCTypes.ClassExtensionTy);
4374 values.addInt(intTy: ObjCTypes.IntTy, value: size);
4375 values.add(value: layout);
4376 values.add(value: propertyList);
4377
4378 return CreateMetadataVar(Name: "OBJC_CLASSEXT_" + ID->getName(), Init&: values,
4379 Section: "__OBJC,__class_ext,regular,no_dead_strip",
4380 Align: CGM.getPointerAlign(), AddToUsed: true);
4381}
4382
4383/*
4384 struct objc_ivar {
4385 char *ivar_name;
4386 char *ivar_type;
4387 int ivar_offset;
4388 };
4389
4390 struct objc_ivar_list {
4391 int ivar_count;
4392 struct objc_ivar list[count];
4393 };
4394*/
4395llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
4396 bool ForClass) {
4397 // When emitting the root class GCC emits ivar entries for the
4398 // actual class structure. It is not clear if we need to follow this
4399 // behavior; for now lets try and get away with not doing it. If so,
4400 // the cleanest solution would be to make up an ObjCInterfaceDecl
4401 // for the class.
4402 if (ForClass)
4403 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListPtrTy);
4404
4405 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4406
4407 ConstantInitBuilder builder(CGM);
4408 auto ivarList = builder.beginStruct();
4409 auto countSlot = ivarList.addPlaceholder();
4410 auto ivars = ivarList.beginArray(eltTy: ObjCTypes.IvarTy);
4411
4412 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
4413 IVD = IVD->getNextIvar()) {
4414 // Ignore unnamed bit-fields.
4415 if (!IVD->getDeclName())
4416 continue;
4417
4418 auto ivar = ivars.beginStruct(ty: ObjCTypes.IvarTy);
4419 ivar.add(value: GetMethodVarName(Ident: IVD->getIdentifier()));
4420 ivar.add(value: GetMethodVarType(D: IVD));
4421 ivar.addInt(intTy: ObjCTypes.IntTy, value: ComputeIvarBaseOffset(CGM, OID, Ivar: IVD));
4422 ivar.finishAndAddTo(parent&: ivars);
4423 }
4424
4425 // Return null for empty list.
4426 auto count = ivars.size();
4427 if (count == 0) {
4428 ivars.abandon();
4429 ivarList.abandon();
4430 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListPtrTy);
4431 }
4432
4433 ivars.finishAndAddTo(parent&: ivarList);
4434 ivarList.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.IntTy, value: count);
4435
4436 llvm::GlobalVariable *GV;
4437 GV = CreateMetadataVar(Name: "OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init&: ivarList,
4438 Section: "__OBJC,__instance_vars,regular,no_dead_strip",
4439 Align: CGM.getPointerAlign(), AddToUsed: true);
4440 return GV;
4441}
4442
4443/// Build a struct objc_method_description constant for the given method.
4444///
4445/// struct objc_method_description {
4446/// SEL method_name;
4447/// char *method_types;
4448/// };
4449void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4450 const ObjCMethodDecl *MD) {
4451 auto description = builder.beginStruct(ty: ObjCTypes.MethodDescriptionTy);
4452 description.add(value: GetMethodVarName(Sel: MD->getSelector()));
4453 description.add(value: GetMethodVarType(D: MD));
4454 description.finishAndAddTo(parent&: builder);
4455}
4456
4457/// Build a struct objc_method constant for the given method.
4458///
4459/// struct objc_method {
4460/// SEL method_name;
4461/// char *method_types;
4462/// void *method;
4463/// };
4464void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4465 const ObjCMethodDecl *MD) {
4466 llvm::Function *fn = GetMethodDefinition(MD);
4467 assert(fn && "no definition registered for method");
4468
4469 auto method = builder.beginStruct(ty: ObjCTypes.MethodTy);
4470 method.add(value: GetMethodVarName(Sel: MD->getSelector()));
4471 method.add(value: GetMethodVarType(D: MD));
4472 method.add(value: fn);
4473 method.finishAndAddTo(parent&: builder);
4474}
4475
4476/// Build a struct objc_method_list or struct objc_method_description_list,
4477/// as appropriate.
4478///
4479/// struct objc_method_list {
4480/// struct objc_method_list *obsolete;
4481/// int count;
4482/// struct objc_method methods_list[count];
4483/// };
4484///
4485/// struct objc_method_description_list {
4486/// int count;
4487/// struct objc_method_description list[count];
4488/// };
4489llvm::Constant *
4490CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4491 ArrayRef<const ObjCMethodDecl *> methods) {
4492 StringRef prefix;
4493 StringRef section;
4494 bool forProtocol = false;
4495 switch (MLT) {
4496 case MethodListType::CategoryInstanceMethods:
4497 prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";
4498 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4499 forProtocol = false;
4500 break;
4501 case MethodListType::CategoryClassMethods:
4502 prefix = "OBJC_CATEGORY_CLASS_METHODS_";
4503 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4504 forProtocol = false;
4505 break;
4506 case MethodListType::InstanceMethods:
4507 prefix = "OBJC_INSTANCE_METHODS_";
4508 section = "__OBJC,__inst_meth,regular,no_dead_strip";
4509 forProtocol = false;
4510 break;
4511 case MethodListType::ClassMethods:
4512 prefix = "OBJC_CLASS_METHODS_";
4513 section = "__OBJC,__cls_meth,regular,no_dead_strip";
4514 forProtocol = false;
4515 break;
4516 case MethodListType::ProtocolInstanceMethods:
4517 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";
4518 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4519 forProtocol = true;
4520 break;
4521 case MethodListType::ProtocolClassMethods:
4522 prefix = "OBJC_PROTOCOL_CLASS_METHODS_";
4523 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4524 forProtocol = true;
4525 break;
4526 case MethodListType::OptionalProtocolInstanceMethods:
4527 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4528 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4529 forProtocol = true;
4530 break;
4531 case MethodListType::OptionalProtocolClassMethods:
4532 prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4533 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4534 forProtocol = true;
4535 break;
4536 }
4537
4538 // Return null for empty list.
4539 if (methods.empty())
4540 return llvm::Constant::getNullValue(
4541 Ty: forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4542 : ObjCTypes.MethodListPtrTy);
4543
4544 // For protocols, this is an objc_method_description_list, which has
4545 // a slightly different structure.
4546 if (forProtocol) {
4547 ConstantInitBuilder builder(CGM);
4548 auto values = builder.beginStruct();
4549 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
4550 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodDescriptionTy);
4551 for (auto MD : methods) {
4552 emitMethodDescriptionConstant(builder&: methodArray, MD);
4553 }
4554 methodArray.finishAndAddTo(parent&: values);
4555
4556 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
4557 Align: CGM.getPointerAlign(), AddToUsed: true);
4558 return GV;
4559 }
4560
4561 // Otherwise, it's an objc_method_list.
4562 ConstantInitBuilder builder(CGM);
4563 auto values = builder.beginStruct();
4564 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
4565 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
4566 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodTy);
4567 for (auto MD : methods) {
4568 if (!MD->isDirectMethod())
4569 emitMethodConstant(builder&: methodArray, MD);
4570 }
4571 methodArray.finishAndAddTo(parent&: values);
4572
4573 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
4574 Align: CGM.getPointerAlign(), AddToUsed: true);
4575 return GV;
4576}
4577
4578llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
4579 const ObjCContainerDecl *CD) {
4580 llvm::Function *Method;
4581
4582 if (OMD->isDirectMethod()) {
4583 // Returns DirectMethodInfo& containing both Implementation and Thunk
4584 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4585 Method = Info.Implementation; // Extract implementation for body generation
4586 } else {
4587 auto Name = getSymbolNameForMethod(method: OMD);
4588
4589 CodeGenTypes &Types = CGM.getTypes();
4590 llvm::FunctionType *MethodTy =
4591 Types.GetFunctionType(Info: Types.arrangeObjCMethodDeclaration(MD: OMD));
4592 Method = llvm::Function::Create(
4593 Ty: MethodTy, Linkage: llvm::GlobalValue::InternalLinkage, N: Name, M: &CGM.getModule());
4594 }
4595
4596 MethodDefinitions.insert(KV: std::make_pair(x&: OMD, y&: Method));
4597
4598 return Method;
4599}
4600
4601/// Generate or retrieve a direct method info.
4602CGObjCCommonMac::DirectMethodInfo &
4603CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
4604 const ObjCContainerDecl *CD) {
4605 auto *COMD = OMD->getCanonicalDecl();
4606
4607 // Fast path: return cached entry if this is not an implementation (no body)
4608 // or if the return types match between declaration and implementation.
4609 auto Cached = DirectMethodDefinitions.find(Val: COMD);
4610 if (Cached != DirectMethodDefinitions.end()) {
4611 if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType())
4612 return Cached->second;
4613 }
4614
4615 CodeGenTypes &Types = CGM.getTypes();
4616 llvm::FunctionType *MethodTy =
4617 Types.GetFunctionType(Info: Types.arrangeObjCMethodDeclaration(MD: OMD));
4618 std::string Name =
4619 getSymbolNameForMethod(method: OMD, /*includeCategoryName*/ false,
4620 useDirectABI: CGM.isObjCDirectPreconditionThunkEnabled());
4621 std::string ThunkName = Name + "_thunk";
4622
4623 // Replace OldFn with NewFn: transfer name, replace all uses, and erase.
4624 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4625 NewFn->takeName(V: OldFn);
4626 OldFn->replaceAllUsesWith(V: NewFn);
4627 OldFn->eraseFromParent();
4628 };
4629
4630 // Check if the function already exists in the module (created by Clang or
4631 // Swift).
4632 llvm::Function *Fn = CGM.getModule().getFunction(Name);
4633
4634 // Function doesn't exist yet.
4635 if (!Fn) {
4636 Fn = llvm::Function::Create(Ty: MethodTy, Linkage: llvm::GlobalValue::ExternalLinkage,
4637 N: Name, M: &CGM.getModule());
4638 return DirectMethodDefinitions.insert(KV: {COMD, DirectMethodInfo(Fn)})
4639 .first->second;
4640 }
4641
4642 // Function exists with matching type.
4643 // Other frontends operating on the same module may have created the function.
4644 if (Fn->getFunctionType() == MethodTy) {
4645 // Reinforce linkage in case Swift created it with different linkage.
4646 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4647
4648 // Check if Swift also created a thunk for this method.
4649 DirectMethodInfo Info(Fn);
4650 if (llvm::Function *Thunk = CGM.getModule().getFunction(Name: ThunkName))
4651 Info.Thunk = Thunk;
4652
4653 return DirectMethodDefinitions.insert(KV: {COMD, Info}).first->second;
4654 }
4655
4656 // Function exists but with mismatched type - replace it.
4657 // This happens when Swift's optional handling differs from ObjC, or when
4658 // ObjC declaration and implementation have slightly different return types.
4659 llvm::Function *NewFn = llvm::Function::Create(
4660 Ty: MethodTy, Linkage: llvm::GlobalValue::ExternalLinkage, N: "", M: &CGM.getModule());
4661 ReplaceFunction(Fn, NewFn);
4662
4663 // Check if the thunk also needs replacement.
4664 DirectMethodInfo Info(NewFn);
4665 if (llvm::Function *OldThunk = CGM.getModule().getFunction(Name: ThunkName)) {
4666 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, Implementation: NewFn);
4667 ReplaceFunction(OldThunk, NewThunk);
4668 Info.Thunk = NewThunk;
4669 }
4670
4671 if (Cached != DirectMethodDefinitions.end()) {
4672 Cached->second = Info;
4673 return Cached->second;
4674 }
4675 return DirectMethodDefinitions.insert(KV: {COMD, Info}).first->second;
4676}
4677
4678/// Start an Objective-C direct method precondition thunk.
4679void CodeGenFunction::StartObjCDirectPreconditionThunk(
4680 const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI) {
4681 // Mark this as a thunk function to disable ARC parameter processing
4682 // and other thunk-inappropriate behavior. We don't need to retain
4683 // parameters because we're going to immediately forward them.
4684 //
4685 // Skipping ARC parameter processing is correct as long as (1) we don't
4686 // run any code that could invalidate the parameters between the start of
4687 // the thunk and the call and (2) we don't use the parameters after the
4688 // call. Both hold whether we tail-call or not. Class realization could in
4689 // theory invalidate parameters, but we assume that doesn't happen in
4690 // practice.
4691 CurFuncIsThunk = true;
4692
4693 // Build argument list for StartFunction.
4694 // We must include all parameters to match the thunk's LLVM function type.
4695 FunctionArgList FunctionArgs;
4696 FunctionArgs.push_back(Elt: OMD->getSelfDecl());
4697 FunctionArgs.append(in_start: OMD->param_begin(), in_end: OMD->param_end());
4698
4699 // The Start/Finish thunk pattern is borrowed from CGVTables.cpp
4700 // for C++ virtual method thunks, but adapted for ObjC direct methods.
4701 //
4702 // Like C++ thunks, we don't have an actual AST body for the thunk - we only
4703 // have the method's parameter declarations. Therefore, we pass empty
4704 // `GlobalDecl` to `StartFunction` ...
4705 StartFunction(GD: GlobalDecl(), RetTy: OMD->getReturnType(), Fn, FnInfo: FI, Args: FunctionArgs,
4706 Loc: OMD->getLocation(), StartLoc: OMD->getLocation());
4707
4708 // and manually set the decl afterwards so other utilities / helpers in CGF
4709 // can still access the AST (e.g. arrange function arguments)
4710 CurCodeDecl = OMD;
4711 CurFuncDecl = OMD;
4712}
4713
4714/// Finish an Objective-C direct method precondition thunk.
4715void CodeGenFunction::FinishObjCDirectPreconditionThunk() {
4716 // Create a dummy block to return the value of the thunk.
4717 //
4718 // The non-nil branch alredy returned because of musttail.
4719 // Only nil branch will jump to this return block.
4720 // If the nil check is not emitted (for class methods), this will be a dead
4721 // block.
4722 //
4723 // Either way, the LLVM optimizer will simplify it later. This is just to make
4724 // CFG happy.
4725 EmitBlock(BB: createBasicBlock(name: "dummy_ret_block"));
4726
4727 // Disable the final ARC autorelease.
4728 // Thunk functions are tailcall to actual implementation, so it doesn't need
4729 // to worry about ARC.
4730 AutoreleaseResult = false;
4731
4732 // Clear these to restore the invariants expected by
4733 // StartFunction/FinishFunction.
4734 CurCodeDecl = nullptr;
4735 CurFuncDecl = nullptr;
4736
4737 FinishFunction();
4738}
4739
4740llvm::Function *
4741CGObjCCommonMac::GenerateObjCDirectThunk(const ObjCMethodDecl *OMD,
4742 const ObjCContainerDecl *CD,
4743 llvm::Function *Implementation) {
4744
4745 assert(CGM.shouldHavePreconditionThunk(OMD) &&
4746 "Should only generate thunk when optimization enabled");
4747 assert(Implementation && "Implementation must exist");
4748
4749 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4750 std::string ThunkName = Implementation->getName().str() + "_thunk";
4751
4752 // Create thunk with linkonce_odr linkage (allows deduplication)
4753 llvm::Function *Thunk =
4754 llvm::Function::Create(Ty: ThunkTy, Linkage: llvm::GlobalValue::LinkOnceODRLinkage,
4755 N: ThunkName, M: &CGM.getModule());
4756
4757 // Thunks should always have hidden visibility, other link units will have
4758 // their own version of the (identical) thunk. If they make cross link-unit
4759 // call, they are either calling through their thunk or directly dispatching
4760 // to the true implementation, so making thunk visibile is meaningless.
4761 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4762 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4763
4764 // Start the ObjC direct thunk (sets up state and calls StartFunction)
4765 const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(MD: OMD);
4766
4767 // Create a CodeGenFunction to generate the thunk body
4768 CodeGenFunction CGF(CGM);
4769 CGF.StartObjCDirectPreconditionThunk(OMD, Fn: Thunk, FI);
4770
4771 // Set function attributes from CGFunctionInfo to ensure the thunk has
4772 // matching parameter attributes (especially sret) for musttail correctness.
4773 // We use SetLLVMFunctionAttributes rather than copying from Implementation
4774 // because Implementation may not have its attributes set yet at this point.
4775 CGM.SetLLVMFunctionAttributes(GD: GlobalDecl(OMD), Info: FI, F: Thunk, /*IsThunk=*/false);
4776 CGM.SetLLVMFunctionAttributesForDefinition(D: OMD, F: Thunk);
4777
4778 // - [self self] for class methods (class realization)
4779 // - if (self == nil) branch to nil block with zero return
4780 // - continuation block for non-nil case
4781 GenerateDirectMethodsPreconditionCheck(CGF, Fn: Thunk, OMD, CD);
4782
4783 // Now emit the musttail call to the true implementation
4784 // Collect all arguments for forwarding
4785 SmallVector<llvm::Value *, 8> Args;
4786 for (auto &Arg : Thunk->args())
4787 Args.push_back(Elt: &Arg);
4788
4789 // Create musttail call to the implementation
4790 llvm::CallInst *Call = CGF.Builder.CreateCall(Callee: Implementation, Args);
4791 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4792
4793 // Apply call-site attributes using ConstructAttributeList
4794 // When sret is used, the call must have matching sret attributes on the first
4795 // parameter for musttail to work correctly. This mirrors what C++ thunks do
4796 // in EmitMustTailThunk.
4797 unsigned CallingConv;
4798 llvm::AttributeList Attrs;
4799 CGM.ConstructAttributeList(Name: Implementation->getName(), Info: FI, CalleeInfo: GlobalDecl(OMD),
4800 Attrs, CallingConv, /*AttrOnCallSite=*/true,
4801 /*IsThunk=*/false);
4802 Call->setAttributes(Attrs);
4803 Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
4804
4805 // Immediately return the call result (musttail requirement).
4806 // For sret returns, the Apple ABI produces void-returning LLVM functions,
4807 // so checking the LLVM return type is suffice.
4808 if (ThunkTy->getReturnType()->isVoidTy())
4809 CGF.Builder.CreateRetVoid();
4810 else
4811 CGF.Builder.CreateRet(V: Call);
4812
4813 // Finish the ObjC direct thunk (creates dummy block and calls FinishFunction)
4814 CGF.FinishObjCDirectPreconditionThunk();
4815 return Thunk;
4816}
4817
4818llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4819 const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
4820 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
4821
4822 // Get from cache or populate the function declaration.
4823 // Copy by value to avoid holding a reference into DirectMethodDefinitions
4824 // DenseMap, which could be invalidated by future insertions.
4825 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4826
4827 // If thunk optimization not enabled (or variadic method which can't use
4828 // thunks), use implementation directly. Variadic methods and methods without
4829 // the optimization enabled include precondition checks in the implementation.
4830 if (!CGM.shouldHavePreconditionThunk(OMD)) {
4831 return Info.Implementation;
4832 }
4833
4834 // Thunk is lazily generated.
4835 auto getOrCreateThunk = [&]() {
4836 if (!Info.Thunk) {
4837 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Implementation: Info.Implementation);
4838 // Write back the lazily created thunk to the map.
4839 DirectMethodDefinitions.insert_or_assign(Key: OMD->getCanonicalDecl(), Val&: Info);
4840 }
4841 return Info.Thunk;
4842 };
4843
4844 if (OMD->isInstanceMethod()) {
4845 // If we can prove instance methods receiver is not null, return the true
4846 // implementation
4847 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4848 }
4849 assert(OMD->isClassMethod() &&
4850 "OMD should either be a class method or instance method");
4851
4852 // For class methods, it need to be non-null and realized before we dispatch
4853 // to true implementation
4854 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4855 ? getOrCreateThunk()
4856 : Info.Implementation;
4857}
4858
4859llvm::Value *
4860CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4861 llvm::Value *classObject,
4862 const ObjCInterfaceDecl *OID) {
4863 // Generate: self = [self self]
4864 // This forces class lazy initialization
4865 Selector SelfSel = GetNullarySelector(name: "self", Ctx&: CGM.getContext());
4866 auto ResultType = CGF.getContext().getObjCIdType();
4867 CallArgList Args;
4868
4869 RValue result = GeneratePossiblySpecializedMessageSend(
4870 CGF, Return: ReturnValueSlot(), ResultType, Sel: SelfSel, Receiver: classObject, Args, OID,
4871 Method: nullptr, isClassMessage: true);
4872
4873 return result.getScalarVal();
4874}
4875
4876void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4877 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4878 const ObjCContainerDecl *CD) {
4879 auto &Builder = CGF.Builder;
4880 bool ReceiverCanBeNull = true;
4881 auto selfAddr = CGF.GetAddrOfLocalVar(VD: OMD->getSelfDecl());
4882 auto selfValue = Builder.CreateLoad(Addr: selfAddr);
4883
4884 // Generate:
4885 //
4886 // /* for class methods only to force class lazy initialization */
4887 // self = [self self];
4888 //
4889 // /* unless the receiver is never NULL */
4890 // if (self == nil) {
4891 // return (ReturnType){ };
4892 // }
4893
4894 if (OMD->isClassMethod()) {
4895 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(Val: CD);
4896 assert(OID &&
4897 "GenerateDirectMethod() should be called with the Class Interface");
4898
4899 // TODO: If this method is inlined, the caller might know that `self` is
4900 // already initialized; for example, it might be an ordinary Objective-C
4901 // method which always receives an initialized `self`, or it might have just
4902 // forced initialization on its own.
4903 //
4904 // We should find a way to eliminate this unnecessary initialization in such
4905 // cases in LLVM.
4906
4907 // Perform class realization using the helper function
4908 llvm::Value *realizedClass = GenerateClassRealization(CGF, classObject: selfValue, OID);
4909 Builder.CreateStore(Val: realizedClass, Addr: selfAddr);
4910
4911 // Nullable `Class` expressions cannot be messaged with a direct method
4912 // so the only reason why the receive can be null would be because
4913 // of weak linking.
4914 ReceiverCanBeNull = isWeakLinkedClass(cls: OID);
4915 }
4916
4917 // Generate nil check
4918 if (ReceiverCanBeNull) {
4919 llvm::BasicBlock *SelfIsNilBlock =
4920 CGF.createBasicBlock(name: "objc_direct_method.self_is_nil");
4921 llvm::BasicBlock *ContBlock =
4922 CGF.createBasicBlock(name: "objc_direct_method.cont");
4923
4924 // if (self == nil) {
4925 auto selfTy = cast<llvm::PointerType>(Val: selfValue->getType());
4926 auto Zero = llvm::ConstantPointerNull::get(T: selfTy);
4927
4928 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
4929 Builder.CreateCondBr(Cond: Builder.CreateICmpEQ(LHS: selfValue, RHS: Zero), True: SelfIsNilBlock,
4930 False: ContBlock, BranchWeights: MDHelper.createUnlikelyBranchWeights());
4931
4932 CGF.EmitBlock(BB: SelfIsNilBlock);
4933
4934 // return (ReturnType){ };
4935 auto retTy = OMD->getReturnType();
4936 Builder.SetInsertPoint(SelfIsNilBlock);
4937 if (!retTy->isVoidType()) {
4938 CGF.EmitNullInitialization(DestPtr: CGF.ReturnValue, Ty: retTy);
4939 }
4940 CGF.EmitBranchThroughCleanup(Dest: CGF.ReturnBlock);
4941 // }
4942
4943 // rest of the body
4944 CGF.EmitBlock(BB: ContBlock);
4945 Builder.SetInsertPoint(ContBlock);
4946 }
4947}
4948
4949void CGObjCCommonMac::GenerateDirectMethodPrologue(
4950 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4951 const ObjCContainerDecl *CD) {
4952 // Generate precondition checks (class realization + nil check) if needed
4953 if (!CGM.isObjCDirectPreconditionThunkEnabled())
4954 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4955
4956 auto &Builder = CGF.Builder;
4957 // Only synthesize _cmd if it's referenced
4958 // This is the actual "prologue" work that always happens
4959 if (OMD->getCmdDecl()->isUsed()) {
4960 // `_cmd` is not a parameter to direct methods, so storage must be
4961 // explicitly declared for it.
4962 CGF.EmitVarDecl(D: *OMD->getCmdDecl());
4963 Builder.CreateStore(Val: GetSelector(CGF, Method: OMD),
4964 Addr: CGF.GetAddrOfLocalVar(VD: OMD->getCmdDecl()));
4965 }
4966}
4967
4968llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4969 Selector Sel, StringRef ClassName, const ObjCCommonTypesHelper &ObjCTypes) {
4970 assert((!ClassName.data() || !ClassName.empty()) &&
4971 "class name cannot be an empty string");
4972 auto Key = std::make_pair(x&: Sel, y&: ClassName);
4973 auto I = MethodSelectorStubs.find(Val: Key);
4974
4975 if (I != MethodSelectorStubs.end())
4976 return I->second;
4977
4978 auto *FnTy = llvm::FunctionType::get(
4979 Result: ObjCTypes.ObjectPtrTy, Params: {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4980 /*IsVarArg=*/isVarArg: true);
4981 std::string FnName;
4982
4983 if (ClassName.data())
4984 FnName = ("objc_msgSendClass$" + Sel.getAsString() + "$_OBJC_CLASS_$_" +
4985 llvm::Twine(ClassName))
4986 .str();
4987 else
4988 FnName = "objc_msgSend$" + Sel.getAsString();
4989
4990 auto *Fn =
4991 cast<llvm::Function>(Val: CGM.CreateRuntimeFunction(Ty: FnTy, Name: FnName).getCallee());
4992
4993 MethodSelectorStubs.insert(KV: std::make_pair(x&: Key, y&: Fn));
4994 return Fn;
4995}
4996
4997llvm::GlobalVariable *
4998CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &Init,
4999 StringRef Section, CharUnits Align,
5000 bool AddToUsed) {
5001 llvm::GlobalValue::LinkageTypes LT =
5002 getLinkageTypeForObjCMetadata(CGM, Section);
5003 llvm::GlobalVariable *GV =
5004 Init.finishAndCreateGlobal(args&: Name, args&: Align, /*constant*/ args: false, args&: LT);
5005 if (!Section.empty())
5006 GV->setSection(Section);
5007 if (AddToUsed)
5008 CGM.addCompilerUsedGlobal(GV);
5009 return GV;
5010}
5011
5012llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5013 llvm::Constant *Init,
5014 StringRef Section,
5015 CharUnits Align,
5016 bool AddToUsed) {
5017 llvm::Type *Ty = Init->getType();
5018 llvm::GlobalValue::LinkageTypes LT =
5019 getLinkageTypeForObjCMetadata(CGM, Section);
5020 llvm::GlobalVariable *GV =
5021 new llvm::GlobalVariable(CGM.getModule(), Ty, false, LT, Init, Name);
5022 if (!Section.empty())
5023 GV->setSection(Section);
5024 GV->setAlignment(Align.getAsAlign());
5025 if (AddToUsed)
5026 CGM.addCompilerUsedGlobal(GV);
5027 return GV;
5028}
5029
5030llvm::GlobalVariable *
5031CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,
5032 bool ForceNonFragileABI,
5033 bool NullTerminate) {
5034 StringRef Label;
5035 switch (Type) {
5036 case ObjCLabelType::ClassName:
5037 Label = "OBJC_CLASS_NAME_";
5038 break;
5039 case ObjCLabelType::MethodVarName:
5040 Label = "OBJC_METH_VAR_NAME_";
5041 break;
5042 case ObjCLabelType::MethodVarType:
5043 Label = "OBJC_METH_VAR_TYPE_";
5044 break;
5045 case ObjCLabelType::PropertyName:
5046 Label = "OBJC_PROP_NAME_ATTR_";
5047 break;
5048 case ObjCLabelType::LayoutBitMap:
5049 Label = "OBJC_LAYOUT_BITMAP_";
5050 break;
5051 }
5052
5053 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5054
5055 StringRef Section;
5056 switch (Type) {
5057 case ObjCLabelType::ClassName:
5058 Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"
5059 : "__TEXT,__cstring,cstring_literals";
5060 break;
5061 case ObjCLabelType::MethodVarName:
5062 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5063 : "__TEXT,__cstring,cstring_literals";
5064 break;
5065 case ObjCLabelType::MethodVarType:
5066 Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"
5067 : "__TEXT,__cstring,cstring_literals";
5068 break;
5069 case ObjCLabelType::PropertyName:
5070 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5071 : "__TEXT,__cstring,cstring_literals";
5072 break;
5073 case ObjCLabelType::LayoutBitMap:
5074 Section = "__TEXT,__cstring,cstring_literals";
5075 break;
5076 }
5077
5078 llvm::Constant *Value =
5079 llvm::ConstantDataArray::getString(Context&: VMContext, Initializer: Name, AddNull: NullTerminate);
5080 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
5081 CGM.getModule(), Value->getType(),
5082 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Value, Label);
5083 if (CGM.getTriple().isOSBinFormatMachO())
5084 GV->setSection(Section);
5085 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5086 GV->setAlignment(CharUnits::One().getAsAlign());
5087 CGM.addCompilerUsedGlobal(GV);
5088
5089 return GV;
5090}
5091
5092llvm::Function *CGObjCMac::ModuleInitFunction() {
5093 // Abuse this interface function as a place to finalize.
5094 FinishModule();
5095 return nullptr;
5096}
5097
5098llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5099 return ObjCTypes.getGetPropertyFn();
5100}
5101
5102llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5103 return ObjCTypes.getSetPropertyFn();
5104}
5105
5106llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
5107 bool copy) {
5108 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5109}
5110
5111llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5112 return ObjCTypes.getCopyStructFn();
5113}
5114
5115llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5116 return ObjCTypes.getCopyStructFn();
5117}
5118
5119llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5120 return ObjCTypes.getCppAtomicObjectFunction();
5121}
5122
5123llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5124 return ObjCTypes.getCppAtomicObjectFunction();
5125}
5126
5127llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5128 return ObjCTypes.getEnumerationMutationFn();
5129}
5130
5131void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
5132 return EmitTryOrSynchronizedStmt(CGF, S);
5133}
5134
5135void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5136 const ObjCAtSynchronizedStmt &S) {
5137 return EmitTryOrSynchronizedStmt(CGF, S);
5138}
5139
5140namespace {
5141struct PerformFragileFinally final : EHScopeStack::Cleanup {
5142 const Stmt &S;
5143 Address SyncArgSlot;
5144 Address CallTryExitVar;
5145 Address ExceptionData;
5146 ObjCTypesHelper &ObjCTypes;
5147 PerformFragileFinally(const Stmt *S, Address SyncArgSlot,
5148 Address CallTryExitVar, Address ExceptionData,
5149 ObjCTypesHelper *ObjCTypes)
5150 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5151 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5152
5153 void Emit(CodeGenFunction &CGF, Flags flags) override {
5154 // Check whether we need to call objc_exception_try_exit.
5155 // In optimized code, this branch will always be folded.
5156 llvm::BasicBlock *FinallyCallExit =
5157 CGF.createBasicBlock(name: "finally.call_exit");
5158 llvm::BasicBlock *FinallyNoCallExit =
5159 CGF.createBasicBlock(name: "finally.no_call_exit");
5160 CGF.Builder.CreateCondBr(Cond: CGF.Builder.CreateLoad(Addr: CallTryExitVar),
5161 True: FinallyCallExit, False: FinallyNoCallExit);
5162
5163 CGF.EmitBlock(BB: FinallyCallExit);
5164 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryExitFn(),
5165 args: ExceptionData.emitRawPointer(CGF));
5166
5167 CGF.EmitBlock(BB: FinallyNoCallExit);
5168
5169 if (isa<ObjCAtTryStmt>(Val: S)) {
5170 if (const ObjCAtFinallyStmt *FinallyStmt =
5171 cast<ObjCAtTryStmt>(Val: S).getFinallyStmt()) {
5172 // Don't try to do the @finally if this is an EH cleanup.
5173 if (flags.isForEHCleanup())
5174 return;
5175
5176 // Save the current cleanup destination in case there's
5177 // control flow inside the finally statement.
5178 llvm::Value *CurCleanupDest =
5179 CGF.Builder.CreateLoad(Addr: CGF.getNormalCleanupDestSlot());
5180
5181 CGF.EmitStmt(S: FinallyStmt->getFinallyBody());
5182
5183 if (CGF.HaveInsertPoint()) {
5184 CGF.Builder.CreateStore(Val: CurCleanupDest,
5185 Addr: CGF.getNormalCleanupDestSlot());
5186 } else {
5187 // Currently, the end of the cleanup must always exist.
5188 CGF.EnsureInsertPoint();
5189 }
5190 }
5191 } else {
5192 // Emit objc_sync_exit(expr); as finally's sole statement for
5193 // @synchronized.
5194 llvm::Value *SyncArg = CGF.Builder.CreateLoad(Addr: SyncArgSlot);
5195 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getSyncExitFn(), args: SyncArg);
5196 }
5197 }
5198};
5199
5200class FragileHazards {
5201 CodeGenFunction &CGF;
5202 SmallVector<llvm::Value *, 20> Locals;
5203 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5204
5205 llvm::InlineAsm *ReadHazard;
5206 llvm::InlineAsm *WriteHazard;
5207
5208 llvm::FunctionType *GetAsmFnType();
5209
5210 void collectLocals();
5211 void emitReadHazard(CGBuilderTy &Builder);
5212
5213public:
5214 FragileHazards(CodeGenFunction &CGF);
5215
5216 void emitWriteHazard();
5217 void emitHazardsInNewBlocks();
5218};
5219} // end anonymous namespace
5220
5221/// Create the fragile-ABI read and write hazards based on the current
5222/// state of the function, which is presumed to be immediately prior
5223/// to a @try block. These hazards are used to maintain correct
5224/// semantics in the face of optimization and the fragile ABI's
5225/// cavalier use of setjmp/longjmp.
5226FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5227 collectLocals();
5228
5229 if (Locals.empty())
5230 return;
5231
5232 // Collect all the blocks in the function.
5233 for (llvm::BasicBlock &BB : *CGF.CurFn)
5234 BlocksBeforeTry.insert(V: &BB);
5235
5236 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5237
5238 // Create a read hazard for the allocas. This inhibits dead-store
5239 // optimizations and forces the values to memory. This hazard is
5240 // inserted before any 'throwing' calls in the protected scope to
5241 // reflect the possibility that the variables might be read from the
5242 // catch block if the call throws.
5243 {
5244 std::string Constraint;
5245 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5246 if (I)
5247 Constraint += ',';
5248 Constraint += "*m";
5249 }
5250
5251 ReadHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
5252 }
5253
5254 // Create a write hazard for the allocas. This inhibits folding
5255 // loads across the hazard. This hazard is inserted at the
5256 // beginning of the catch path to reflect the possibility that the
5257 // variables might have been written within the protected scope.
5258 {
5259 std::string Constraint;
5260 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5261 if (I)
5262 Constraint += ',';
5263 Constraint += "=*m";
5264 }
5265
5266 WriteHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
5267 }
5268}
5269
5270/// Emit a write hazard at the current location.
5271void FragileHazards::emitWriteHazard() {
5272 if (Locals.empty())
5273 return;
5274
5275 llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(callee: WriteHazard, args: Locals);
5276 for (auto Pair : llvm::enumerate(First&: Locals))
5277 Call->addParamAttr(
5278 ArgNo: Pair.index(),
5279 Attr: llvm::Attribute::get(
5280 Context&: CGF.getLLVMContext(), Kind: llvm::Attribute::ElementType,
5281 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
5282}
5283
5284void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
5285 assert(!Locals.empty());
5286 llvm::CallInst *call = Builder.CreateCall(Callee: ReadHazard, Args: Locals);
5287 call->setDoesNotThrow();
5288 call->setCallingConv(CGF.getRuntimeCC());
5289 for (auto Pair : llvm::enumerate(First&: Locals))
5290 call->addParamAttr(
5291 ArgNo: Pair.index(),
5292 Attr: llvm::Attribute::get(
5293 Context&: Builder.getContext(), Kind: llvm::Attribute::ElementType,
5294 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
5295}
5296
5297/// Emit read hazards in all the protected blocks, i.e. all the blocks
5298/// which have been inserted since the beginning of the try.
5299void FragileHazards::emitHazardsInNewBlocks() {
5300 if (Locals.empty())
5301 return;
5302
5303 CGBuilderTy Builder(CGF.CGM, CGF.getLLVMContext());
5304
5305 // Iterate through all blocks, skipping those prior to the try.
5306 for (llvm::BasicBlock &BB : *CGF.CurFn) {
5307 if (BlocksBeforeTry.count(V: &BB))
5308 continue;
5309
5310 // Walk through all the calls in the block.
5311 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5312 ++BI) {
5313 llvm::Instruction &I = *BI;
5314
5315 // Ignore instructions that aren't non-intrinsic calls.
5316 // These are the only calls that can possibly call longjmp.
5317 if (!isa<llvm::CallInst>(Val: I) && !isa<llvm::InvokeInst>(Val: I))
5318 continue;
5319 if (isa<llvm::IntrinsicInst>(Val: I))
5320 continue;
5321
5322 // Ignore call sites marked nounwind. This may be questionable,
5323 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
5324 if (cast<llvm::CallBase>(Val&: I).doesNotThrow())
5325 continue;
5326
5327 // Insert a read hazard before the call. This will ensure that
5328 // any writes to the locals are performed before making the
5329 // call. If the call throws, then this is sufficient to
5330 // guarantee correctness as long as it doesn't also write to any
5331 // locals.
5332 Builder.SetInsertPoint(TheBB: &BB, IP: BI);
5333 emitReadHazard(Builder);
5334 }
5335 }
5336}
5337
5338static void addIfPresent(llvm::DenseSet<llvm::Value *> &S, Address V) {
5339 if (V.isValid())
5340 if (llvm::Value *Ptr = V.getBasePointer())
5341 S.insert(V: Ptr);
5342}
5343
5344void FragileHazards::collectLocals() {
5345 // Compute a set of allocas to ignore.
5346 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5347 addIfPresent(S&: AllocasToIgnore, V: CGF.ReturnValue);
5348 addIfPresent(S&: AllocasToIgnore, V: CGF.NormalCleanupDest);
5349
5350 // Collect all the allocas currently in the function. This is
5351 // probably way too aggressive.
5352 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
5353 for (llvm::Instruction &I : Entry)
5354 if (isa<llvm::AllocaInst>(Val: I) && !AllocasToIgnore.count(V: &I))
5355 Locals.push_back(Elt: &I);
5356}
5357
5358llvm::FunctionType *FragileHazards::GetAsmFnType() {
5359 SmallVector<llvm::Type *, 16> tys(Locals.size());
5360 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
5361 tys[i] = Locals[i]->getType();
5362 return llvm::FunctionType::get(Result: CGF.VoidTy, Params: tys, isVarArg: false);
5363}
5364
5365/*
5366
5367 Objective-C setjmp-longjmp (sjlj) Exception Handling
5368 --
5369
5370 A catch buffer is a setjmp buffer plus:
5371 - a pointer to the exception that was caught
5372 - a pointer to the previous exception data buffer
5373 - two pointers of reserved storage
5374 Therefore catch buffers form a stack, with a pointer to the top
5375 of the stack kept in thread-local storage.
5376
5377 objc_exception_try_enter pushes a catch buffer onto the EH stack.
5378 objc_exception_try_exit pops the given catch buffer, which is
5379 required to be the top of the EH stack.
5380 objc_exception_throw pops the top of the EH stack, writes the
5381 thrown exception into the appropriate field, and longjmps
5382 to the setjmp buffer. It crashes the process (with a printf
5383 and an abort()) if there are no catch buffers on the stack.
5384 objc_exception_extract just reads the exception pointer out of the
5385 catch buffer.
5386
5387 There's no reason an implementation couldn't use a light-weight
5388 setjmp here --- something like __builtin_setjmp, but API-compatible
5389 with the heavyweight setjmp. This will be more important if we ever
5390 want to implement correct ObjC/C++ exception interactions for the
5391 fragile ABI.
5392
5393 Note that for this use of setjmp/longjmp to be correct in the presence of
5394 optimization, we use inline assembly on the set of local variables to force
5395 flushing locals to memory immediately before any protected calls and to
5396 inhibit optimizing locals across the setjmp->catch edge.
5397
5398 The basic framework for a @try-catch-finally is as follows:
5399 {
5400 objc_exception_data d;
5401 id _rethrow = null;
5402 bool _call_try_exit = true;
5403
5404 objc_exception_try_enter(&d);
5405 if (!setjmp(d.jmp_buf)) {
5406 ... try body ...
5407 } else {
5408 // exception path
5409 id _caught = objc_exception_extract(&d);
5410
5411 // enter new try scope for handlers
5412 if (!setjmp(d.jmp_buf)) {
5413 ... match exception and execute catch blocks ...
5414
5415 // fell off end, rethrow.
5416 _rethrow = _caught;
5417 ... jump-through-finally to finally_rethrow ...
5418 } else {
5419 // exception in catch block
5420 _rethrow = objc_exception_extract(&d);
5421 _call_try_exit = false;
5422 ... jump-through-finally to finally_rethrow ...
5423 }
5424 }
5425 ... jump-through-finally to finally_end ...
5426
5427 finally:
5428 if (_call_try_exit)
5429 objc_exception_try_exit(&d);
5430
5431 ... finally block ....
5432 ... dispatch to finally destination ...
5433
5434 finally_rethrow:
5435 objc_exception_throw(_rethrow);
5436
5437 finally_end:
5438 }
5439
5440 This framework differs slightly from the one gcc uses, in that gcc
5441 uses _rethrow to determine if objc_exception_try_exit should be called
5442 and if the object should be rethrown. This breaks in the face of
5443 throwing nil and introduces unnecessary branches.
5444
5445 We specialize this framework for a few particular circumstances:
5446
5447 - If there are no catch blocks, then we avoid emitting the second
5448 exception handling context.
5449
5450 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
5451 e)) we avoid emitting the code to rethrow an uncaught exception.
5452
5453 - FIXME: If there is no @finally block we can do a few more
5454 simplifications.
5455
5456 Rethrows and Jumps-Through-Finally
5457 --
5458
5459 '@throw;' is supported by pushing the currently-caught exception
5460 onto ObjCEHStack while the @catch blocks are emitted.
5461
5462 Branches through the @finally block are handled with an ordinary
5463 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
5464 exceptions are not compatible with C++ exceptions, and this is
5465 hardly the only place where this will go wrong.
5466
5467 @synchronized(expr) { stmt; } is emitted as if it were:
5468 id synch_value = expr;
5469 objc_sync_enter(synch_value);
5470 @try { stmt; } @finally { objc_sync_exit(synch_value); }
5471*/
5472
5473void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5474 const Stmt &S) {
5475 bool isTry = isa<ObjCAtTryStmt>(Val: S);
5476
5477 // A destination for the fall-through edges of the catch handlers to
5478 // jump to.
5479 CodeGenFunction::JumpDest FinallyEnd =
5480 CGF.getJumpDestInCurrentScope(Name: "finally.end");
5481
5482 // A destination for the rethrow edge of the catch handlers to jump
5483 // to.
5484 CodeGenFunction::JumpDest FinallyRethrow =
5485 CGF.getJumpDestInCurrentScope(Name: "finally.rethrow");
5486
5487 // For @synchronized, call objc_sync_enter(sync.expr). The
5488 // evaluation of the expression must occur before we enter the
5489 // @synchronized. We can't avoid a temp here because we need the
5490 // value to be preserved. If the backend ever does liveness
5491 // correctly after setjmp, this will be unnecessary.
5492 Address SyncArgSlot = Address::invalid();
5493 if (!isTry) {
5494 llvm::Value *SyncArg =
5495 CGF.EmitScalarExpr(E: cast<ObjCAtSynchronizedStmt>(Val: S).getSynchExpr());
5496 SyncArg = CGF.Builder.CreateBitCast(V: SyncArg, DestTy: ObjCTypes.ObjectPtrTy);
5497 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getSyncEnterFn(), args: SyncArg);
5498
5499 SyncArgSlot = CGF.CreateTempAlloca(Ty: SyncArg->getType(),
5500 align: CGF.getPointerAlign(), Name: "sync.arg");
5501 CGF.Builder.CreateStore(Val: SyncArg, Addr: SyncArgSlot);
5502 }
5503
5504 // Allocate memory for the setjmp buffer. This needs to be kept
5505 // live throughout the try and catch blocks.
5506 Address ExceptionData = CGF.CreateTempAlloca(
5507 Ty: ObjCTypes.ExceptionDataTy, align: CGF.getPointerAlign(), Name: "exceptiondata.ptr");
5508
5509 // Create the fragile hazards. Note that this will not capture any
5510 // of the allocas required for exception processing, but will
5511 // capture the current basic block (which extends all the way to the
5512 // setjmp call) as "before the @try".
5513 FragileHazards Hazards(CGF);
5514
5515 // Create a flag indicating whether the cleanup needs to call
5516 // objc_exception_try_exit. This is true except when
5517 // - no catches match and we're branching through the cleanup
5518 // just to rethrow the exception, or
5519 // - a catch matched and we're falling out of the catch handler.
5520 // The setjmp-safety rule here is that we should always store to this
5521 // variable in a place that dominates the branch through the cleanup
5522 // without passing through any setjmps.
5523 Address CallTryExitVar = CGF.CreateTempAlloca(
5524 Ty: CGF.Builder.getInt1Ty(), align: CharUnits::One(), Name: "_call_try_exit");
5525
5526 // A slot containing the exception to rethrow. Only needed when we
5527 // have both a @catch and a @finally.
5528 Address PropagatingExnVar = Address::invalid();
5529
5530 // Push a normal cleanup to leave the try scope.
5531 CGF.EHStack.pushCleanup<PerformFragileFinally>(Kind: NormalAndEHCleanup, A: &S,
5532 A: SyncArgSlot, A: CallTryExitVar,
5533 A: ExceptionData, A: &ObjCTypes);
5534
5535 // Enter a try block:
5536 // - Call objc_exception_try_enter to push ExceptionData on top of
5537 // the EH stack.
5538 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
5539 args: ExceptionData.emitRawPointer(CGF));
5540
5541 // - Call setjmp on the exception data buffer.
5542 llvm::Constant *Zero = llvm::ConstantInt::get(Ty: CGF.Builder.getInt32Ty(), V: 0);
5543 llvm::Value *GEPIndexes[] = {Zero, Zero, Zero};
5544 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
5545 Ty: ObjCTypes.ExceptionDataTy, Ptr: ExceptionData.emitRawPointer(CGF), IdxList: GEPIndexes,
5546 Name: "setjmp_buffer");
5547 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5548 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp_result");
5549 SetJmpResult->setCanReturnTwice();
5550
5551 // If setjmp returned 0, enter the protected block; otherwise,
5552 // branch to the handler.
5553 llvm::BasicBlock *TryBlock = CGF.createBasicBlock(name: "try");
5554 llvm::BasicBlock *TryHandler = CGF.createBasicBlock(name: "try.handler");
5555 llvm::Value *DidCatch =
5556 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
5557 CGF.Builder.CreateCondBr(Cond: DidCatch, True: TryHandler, False: TryBlock);
5558
5559 // Emit the protected block.
5560 CGF.EmitBlock(BB: TryBlock);
5561 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
5562 CGF.EmitStmt(S: isTry ? cast<ObjCAtTryStmt>(Val: S).getTryBody()
5563 : cast<ObjCAtSynchronizedStmt>(Val: S).getSynchBody());
5564
5565 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
5566
5567 // Emit the exception handler block.
5568 CGF.EmitBlock(BB: TryHandler);
5569
5570 // Don't optimize loads of the in-scope locals across this point.
5571 Hazards.emitWriteHazard();
5572
5573 // For a @synchronized (or a @try with no catches), just branch
5574 // through the cleanup to the rethrow block.
5575 if (!isTry || !cast<ObjCAtTryStmt>(Val: S).getNumCatchStmts()) {
5576 // Tell the cleanup not to re-pop the exit.
5577 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
5578 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5579
5580 // Otherwise, we have to match against the caught exceptions.
5581 } else {
5582 // Retrieve the exception object. We may emit multiple blocks but
5583 // nothing can cross this so the value is already in SSA form.
5584 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5585 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
5586 name: "caught");
5587
5588 // Push the exception to rethrow onto the EH value stack for the
5589 // benefit of any @throws in the handlers.
5590 CGF.ObjCEHValueStack.push_back(Elt: Caught);
5591
5592 const ObjCAtTryStmt *AtTryStmt = cast<ObjCAtTryStmt>(Val: &S);
5593
5594 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
5595
5596 llvm::BasicBlock *CatchBlock = nullptr;
5597 llvm::BasicBlock *CatchHandler = nullptr;
5598 if (HasFinally) {
5599 // Save the currently-propagating exception before
5600 // objc_exception_try_enter clears the exception slot.
5601 PropagatingExnVar = CGF.CreateTempAlloca(
5602 Ty: Caught->getType(), align: CGF.getPointerAlign(), Name: "propagating_exception");
5603 CGF.Builder.CreateStore(Val: Caught, Addr: PropagatingExnVar);
5604
5605 // Enter a new exception try block (in case a @catch block
5606 // throws an exception).
5607 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
5608 args: ExceptionData.emitRawPointer(CGF));
5609
5610 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5611 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp.result");
5612 SetJmpResult->setCanReturnTwice();
5613
5614 llvm::Value *Threw =
5615 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
5616
5617 CatchBlock = CGF.createBasicBlock(name: "catch");
5618 CatchHandler = CGF.createBasicBlock(name: "catch_for_catch");
5619 CGF.Builder.CreateCondBr(Cond: Threw, True: CatchHandler, False: CatchBlock);
5620
5621 CGF.EmitBlock(BB: CatchBlock);
5622 }
5623
5624 CGF.Builder.CreateStore(Val: CGF.Builder.getInt1(V: HasFinally), Addr: CallTryExitVar);
5625
5626 // Handle catch list. As a special case we check if everything is
5627 // matched and avoid generating code for falling off the end if
5628 // so.
5629 bool AllMatched = false;
5630 for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) {
5631 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5632 const ObjCObjectPointerType *OPT = nullptr;
5633
5634 // catch(...) always matches.
5635 if (!CatchParam) {
5636 AllMatched = true;
5637 } else {
5638 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
5639
5640 // catch(id e) always matches under this ABI, since only
5641 // ObjC exceptions end up here in the first place.
5642 // FIXME: For the time being we also match id<X>; this should
5643 // be rejected by Sema instead.
5644 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
5645 AllMatched = true;
5646 }
5647
5648 // If this is a catch-all, we don't need to test anything.
5649 if (AllMatched) {
5650 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5651
5652 if (CatchParam) {
5653 CGF.EmitAutoVarDecl(D: *CatchParam);
5654 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5655
5656 // These types work out because ConvertType(id) == i8*.
5657 EmitInitOfCatchParam(CGF, exn: Caught, paramDecl: CatchParam);
5658 }
5659
5660 CGF.EmitStmt(S: CatchStmt->getCatchBody());
5661
5662 // The scope of the catch variable ends right here.
5663 CatchVarCleanups.ForceCleanup();
5664
5665 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
5666 break;
5667 }
5668
5669 assert(OPT && "Unexpected non-object pointer type in @catch");
5670 const ObjCObjectType *ObjTy = OPT->getObjectType();
5671
5672 // FIXME: @catch (Class c) ?
5673 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5674 assert(IDecl && "Catch parameter must have Objective-C type!");
5675
5676 // Check if the @catch block matches the exception object.
5677 llvm::Value *Class = EmitClassRef(CGF, ID: IDecl);
5678
5679 llvm::Value *matchArgs[] = {Class, Caught};
5680 llvm::CallInst *Match = CGF.EmitNounwindRuntimeCall(
5681 callee: ObjCTypes.getExceptionMatchFn(), args: matchArgs, name: "match");
5682
5683 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock(name: "match");
5684 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock(name: "catch.next");
5685
5686 CGF.Builder.CreateCondBr(Cond: CGF.Builder.CreateIsNotNull(Arg: Match, Name: "matched"),
5687 True: MatchedBlock, False: NextCatchBlock);
5688
5689 // Emit the @catch block.
5690 CGF.EmitBlock(BB: MatchedBlock);
5691
5692 // Collect any cleanups for the catch variable. The scope lasts until
5693 // the end of the catch body.
5694 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5695
5696 CGF.EmitAutoVarDecl(D: *CatchParam);
5697 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5698
5699 // Initialize the catch variable.
5700 llvm::Value *Tmp = CGF.Builder.CreateBitCast(
5701 V: Caught, DestTy: CGF.ConvertType(T: CatchParam->getType()));
5702 EmitInitOfCatchParam(CGF, exn: Tmp, paramDecl: CatchParam);
5703
5704 CGF.EmitStmt(S: CatchStmt->getCatchBody());
5705
5706 // We're done with the catch variable.
5707 CatchVarCleanups.ForceCleanup();
5708
5709 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
5710
5711 CGF.EmitBlock(BB: NextCatchBlock);
5712 }
5713
5714 CGF.ObjCEHValueStack.pop_back();
5715
5716 // If nothing wanted anything to do with the caught exception,
5717 // kill the extract call.
5718 if (Caught->use_empty())
5719 Caught->eraseFromParent();
5720
5721 if (!AllMatched)
5722 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5723
5724 if (HasFinally) {
5725 // Emit the exception handler for the @catch blocks.
5726 CGF.EmitBlock(BB: CatchHandler);
5727
5728 // In theory we might now need a write hazard, but actually it's
5729 // unnecessary because there's no local-accessing code between
5730 // the try's write hazard and here.
5731 // Hazards.emitWriteHazard();
5732
5733 // Extract the new exception and save it to the
5734 // propagating-exception slot.
5735 assert(PropagatingExnVar.isValid());
5736 llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall(
5737 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
5738 name: "caught");
5739 CGF.Builder.CreateStore(Val: NewCaught, Addr: PropagatingExnVar);
5740
5741 // Don't pop the catch handler; the throw already did.
5742 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
5743 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5744 }
5745 }
5746
5747 // Insert read hazards as required in the new blocks.
5748 Hazards.emitHazardsInNewBlocks();
5749
5750 // Pop the cleanup.
5751 CGF.Builder.restoreIP(IP: TryFallthroughIP);
5752 if (CGF.HaveInsertPoint())
5753 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
5754 CGF.PopCleanupBlock();
5755 CGF.EmitBlock(BB: FinallyEnd.getBlock(), IsFinished: true);
5756
5757 // Emit the rethrow block.
5758 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
5759 CGF.EmitBlock(BB: FinallyRethrow.getBlock(), IsFinished: true);
5760 if (CGF.HaveInsertPoint()) {
5761 // If we have a propagating-exception variable, check it.
5762 llvm::Value *PropagatingExn;
5763 if (PropagatingExnVar.isValid()) {
5764 PropagatingExn = CGF.Builder.CreateLoad(Addr: PropagatingExnVar);
5765
5766 // Otherwise, just look in the buffer for the exception to throw.
5767 } else {
5768 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5769 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF));
5770 PropagatingExn = Caught;
5771 }
5772
5773 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(),
5774 args: PropagatingExn);
5775 CGF.Builder.CreateUnreachable();
5776 }
5777
5778 CGF.Builder.restoreIP(IP: SavedIP);
5779}
5780
5781void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5782 const ObjCAtThrowStmt &S,
5783 bool ClearInsertionPoint) {
5784 llvm::Value *ExceptionAsObject;
5785
5786 if (const Expr *ThrowExpr = S.getThrowExpr()) {
5787 llvm::Value *Exception = CGF.EmitObjCThrowOperand(expr: ThrowExpr);
5788 ExceptionAsObject =
5789 CGF.Builder.CreateBitCast(V: Exception, DestTy: ObjCTypes.ObjectPtrTy);
5790 } else {
5791 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
5792 "Unexpected rethrow outside @catch block.");
5793 ExceptionAsObject = CGF.ObjCEHValueStack.back();
5794 }
5795
5796 CGF.EmitRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(), args: ExceptionAsObject)
5797 ->setDoesNotReturn();
5798 CGF.Builder.CreateUnreachable();
5799
5800 // Clear the insertion point to indicate we are in unreachable code.
5801 if (ClearInsertionPoint)
5802 CGF.Builder.ClearInsertionPoint();
5803}
5804
5805/// EmitObjCWeakRead - Code gen for loading value of a __weak
5806/// object: objc_read_weak (id *src)
5807///
5808llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5809 Address AddrWeakObj) {
5810 llvm::Type *DestTy = AddrWeakObj.getElementType();
5811 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
5812 V: AddrWeakObj.emitRawPointer(CGF), DestTy: ObjCTypes.PtrObjectPtrTy);
5813 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
5814 callee: ObjCTypes.getGcReadWeakFn(), args: AddrWeakObjVal, name: "weakread");
5815 read_weak = CGF.Builder.CreateBitCast(V: read_weak, DestTy);
5816 return read_weak;
5817}
5818
5819/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5820/// objc_assign_weak (id src, id *dst)
5821///
5822void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5823 llvm::Value *src, Address dst) {
5824 llvm::Type *SrcTy = src->getType();
5825 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5826 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5827 assert(Size <= 8 && "does not support size > 8");
5828 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5829 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5830 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5831 }
5832 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5833 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5834 DestTy: ObjCTypes.PtrObjectPtrTy);
5835 llvm::Value *args[] = {src, dstVal};
5836 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignWeakFn(), args,
5837 name: "weakassign");
5838}
5839
5840/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5841/// objc_assign_global (id src, id *dst)
5842///
5843void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5844 llvm::Value *src, Address dst,
5845 bool threadlocal) {
5846 llvm::Type *SrcTy = src->getType();
5847 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5848 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5849 assert(Size <= 8 && "does not support size > 8");
5850 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5851 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5852 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5853 }
5854 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5855 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5856 DestTy: ObjCTypes.PtrObjectPtrTy);
5857 llvm::Value *args[] = {src, dstVal};
5858 if (!threadlocal)
5859 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignGlobalFn(), args,
5860 name: "globalassign");
5861 else
5862 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignThreadLocalFn(), args,
5863 name: "threadlocalassign");
5864}
5865
5866/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5867/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
5868///
5869void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5870 llvm::Value *src, Address dst,
5871 llvm::Value *ivarOffset) {
5872 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
5873 llvm::Type *SrcTy = src->getType();
5874 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5875 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5876 assert(Size <= 8 && "does not support size > 8");
5877 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5878 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5879 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5880 }
5881 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5882 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5883 DestTy: ObjCTypes.PtrObjectPtrTy);
5884 llvm::Value *args[] = {src, dstVal, ivarOffset};
5885 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignIvarFn(), args);
5886}
5887
5888/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5889/// objc_assign_strongCast (id src, id *dst)
5890///
5891void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5892 llvm::Value *src, Address dst) {
5893 llvm::Type *SrcTy = src->getType();
5894 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5895 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5896 assert(Size <= 8 && "does not support size > 8");
5897 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5898 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5899 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5900 }
5901 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5902 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5903 DestTy: ObjCTypes.PtrObjectPtrTy);
5904 llvm::Value *args[] = {src, dstVal};
5905 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignStrongCastFn(), args,
5906 name: "strongassign");
5907}
5908
5909void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5910 Address DestPtr, Address SrcPtr,
5911 llvm::Value *size) {
5912 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5913 SrcPtr.emitRawPointer(CGF), size};
5914 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.GcMemmoveCollectableFn(), args);
5915}
5916
5917/// EmitObjCValueForIvar - Code Gen for ivar reference.
5918///
5919LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5920 QualType ObjectTy,
5921 llvm::Value *BaseValue,
5922 const ObjCIvarDecl *Ivar,
5923 unsigned CVRQualifiers) {
5924 const ObjCInterfaceDecl *ID =
5925 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5926 return EmitValueForIvarAtOffset(CGF, OID: ID, BaseValue, Ivar, CVRQualifiers,
5927 Offset: EmitIvarOffset(CGF, Interface: ID, Ivar));
5928}
5929
5930llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5931 const ObjCInterfaceDecl *Interface,
5932 const ObjCIvarDecl *Ivar) {
5933 uint64_t Offset = ComputeIvarBaseOffset(CGM, OID: Interface, Ivar);
5934 return llvm::ConstantInt::get(
5935 Ty: CGM.getTypes().ConvertType(T: CGM.getContext().LongTy), V: Offset);
5936}
5937
5938/* *** Private Interface *** */
5939
5940std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5941 StringRef MachOAttributes) {
5942 switch (CGM.getTriple().getObjectFormat()) {
5943 case llvm::Triple::UnknownObjectFormat:
5944 llvm_unreachable("unexpected object file format");
5945 case llvm::Triple::MachO: {
5946 if (MachOAttributes.empty())
5947 return ("__DATA," + Section).str();
5948 return ("__DATA," + Section + "," + MachOAttributes).str();
5949 }
5950 case llvm::Triple::ELF:
5951 assert(Section.starts_with("__") && "expected the name to begin with __");
5952 return Section.substr(Start: 2).str();
5953 case llvm::Triple::COFF:
5954 assert(Section.starts_with("__") && "expected the name to begin with __");
5955 return ("." + Section.substr(Start: 2) + "$B").str();
5956 case llvm::Triple::Wasm:
5957 case llvm::Triple::GOFF:
5958 case llvm::Triple::SPIRV:
5959 case llvm::Triple::XCOFF:
5960 case llvm::Triple::DXContainer:
5961 llvm::report_fatal_error(
5962 reason: "Objective-C support is unimplemented for object file format");
5963 }
5964
5965 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");
5966}
5967
5968// clang-format off
5969/// EmitImageInfo - Emit the image info marker used to encode some module
5970/// level information.
5971///
5972/// See: <rdr://4810609&4810587&4810587>
5973/// struct IMAGE_INFO {
5974/// unsigned version;
5975/// unsigned flags;
5976/// };
5977enum ImageInfoFlags {
5978 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5979 eImageInfo_GarbageCollected = (1 << 1),
5980 eImageInfo_GCOnly = (1 << 2),
5981 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5982
5983 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5984 eImageInfo_ImageIsSimulated = (1 << 5),
5985 eImageInfo_ClassProperties = (1 << 6)
5986};
5987// clang-format on
5988
5989void CGObjCCommonMac::EmitImageInfo() {
5990 unsigned version = 0; // Version is unused?
5991 std::string Section =
5992 (ObjCABI == 1)
5993 ? "__OBJC,__image_info,regular"
5994 : GetSectionName(Section: "__objc_imageinfo", MachOAttributes: "regular,no_dead_strip");
5995
5996 // Generate module-level named metadata to convey this information to the
5997 // linker and code-gen.
5998 llvm::Module &Mod = CGM.getModule();
5999
6000 // Add the ObjC ABI version to the module flags.
6001 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Version", Val: ObjCABI);
6002 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Version",
6003 Val: version);
6004 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Section",
6005 Val: llvm::MDString::get(Context&: VMContext, Str: Section));
6006
6007 auto Int8Ty = llvm::Type::getInt8Ty(C&: VMContext);
6008 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6009 // Non-GC overrides those files which specify GC.
6010 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
6011 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: 0));
6012 } else {
6013 // Add the ObjC garbage collection value.
6014 Mod.addModuleFlag(
6015 Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
6016 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: (uint8_t)eImageInfo_GarbageCollected));
6017
6018 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6019 // Add the ObjC GC Only value.
6020 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C GC Only",
6021 Val: eImageInfo_GCOnly);
6022
6023 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6024 llvm::Metadata *Ops[2] = {
6025 llvm::MDString::get(Context&: VMContext, Str: "Objective-C Garbage Collection"),
6026 llvm::ConstantAsMetadata::get(
6027 C: llvm::ConstantInt::get(Ty: Int8Ty, V: eImageInfo_GarbageCollected))};
6028 Mod.addModuleFlag(Behavior: llvm::Module::Require, Key: "Objective-C GC Only",
6029 Val: llvm::MDNode::get(Context&: VMContext, MDs: Ops));
6030 }
6031 }
6032
6033 // Indicate whether we're compiling this to run on a simulator.
6034 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6035 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Is Simulated",
6036 Val: eImageInfo_ImageIsSimulated);
6037
6038 // Indicate whether we are generating class properties.
6039 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Class Properties",
6040 Val: eImageInfo_ClassProperties);
6041
6042 // Indicate whether we want enforcement of pointer signing for class_ro_t
6043 // pointers.
6044 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6045 Mod.addModuleFlag(Behavior: llvm::Module::Error,
6046 Key: "Objective-C Enforce ClassRO Pointer Signing",
6047 Val: eImageInfo_SignedClassRO);
6048 else
6049 Mod.addModuleFlag(Behavior: llvm::Module::Error,
6050 Key: "Objective-C Enforce ClassRO Pointer Signing",
6051 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: 0));
6052}
6053
6054// struct objc_module {
6055// unsigned long version;
6056// unsigned long size;
6057// const char *name;
6058// Symtab symtab;
6059// };
6060
6061// FIXME: Get from somewhere
6062static const int ModuleVersion = 7;
6063
6064void CGObjCMac::EmitModuleInfo() {
6065 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ModuleTy);
6066
6067 ConstantInitBuilder builder(CGM);
6068 auto values = builder.beginStruct(structTy: ObjCTypes.ModuleTy);
6069 values.addInt(intTy: ObjCTypes.LongTy, value: ModuleVersion);
6070 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
6071 // This used to be the filename, now it is unused. <rdr://4327263>
6072 values.add(value: GetClassName(RuntimeName: StringRef("")));
6073 values.add(value: EmitModuleSymbols());
6074 CreateMetadataVar(Name: "OBJC_MODULES", Init&: values,
6075 Section: "__OBJC,__module_info,regular,no_dead_strip",
6076 Align: CGM.getPointerAlign(), AddToUsed: true);
6077}
6078
6079llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6080 unsigned NumClasses = DefinedClasses.size();
6081 unsigned NumCategories = DefinedCategories.size();
6082
6083 // Return null if no symbols were defined.
6084 if (!NumClasses && !NumCategories)
6085 return llvm::Constant::getNullValue(Ty: ObjCTypes.SymtabPtrTy);
6086
6087 ConstantInitBuilder builder(CGM);
6088 auto values = builder.beginStruct();
6089 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
6090 values.addNullPointer(ptrTy: ObjCTypes.SelectorPtrTy);
6091 values.addInt(intTy: ObjCTypes.ShortTy, value: NumClasses);
6092 values.addInt(intTy: ObjCTypes.ShortTy, value: NumCategories);
6093
6094 // The runtime expects exactly the list of defined classes followed
6095 // by the list of defined categories, in a single array.
6096 auto array = values.beginArray(eltTy: ObjCTypes.Int8PtrTy);
6097 for (unsigned i = 0; i < NumClasses; i++) {
6098 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6099 assert(ID);
6100 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6101 // We are implementing a weak imported interface. Give it external linkage
6102 if (ID->isWeakImported() && !IMP->isWeakImported())
6103 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6104
6105 array.add(value: DefinedClasses[i]);
6106 }
6107 for (unsigned i = 0; i < NumCategories; i++)
6108 array.add(value: DefinedCategories[i]);
6109
6110 array.finishAndAddTo(parent&: values);
6111
6112 llvm::GlobalVariable *GV = CreateMetadataVar(
6113 Name: "OBJC_SYMBOLS", Init&: values, Section: "__OBJC,__symbols,regular,no_dead_strip",
6114 Align: CGM.getPointerAlign(), AddToUsed: true);
6115 return GV;
6116}
6117
6118llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6119 IdentifierInfo *II) {
6120 LazySymbols.insert(X: II);
6121
6122 llvm::GlobalVariable *&Entry = ClassReferences[II];
6123
6124 if (!Entry) {
6125 Entry =
6126 CreateMetadataVar(Name: "OBJC_CLASS_REFERENCES_", Init: GetClassName(RuntimeName: II->getName()),
6127 Section: "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
6128 Align: CGM.getPointerAlign(), AddToUsed: true);
6129 }
6130
6131 return CGF.Builder.CreateAlignedLoad(Ty: Entry->getValueType(), Addr: Entry,
6132 Align: CGF.getPointerAlign());
6133}
6134
6135llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6136 const ObjCInterfaceDecl *ID) {
6137 // If the class has the objc_runtime_visible attribute, we need to
6138 // use the Objective-C runtime to get the class.
6139 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6140 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6141
6142 IdentifierInfo *RuntimeName =
6143 &CGM.getContext().Idents.get(Name: ID->getObjCRuntimeNameAsString());
6144 return EmitClassRefFromId(CGF, II: RuntimeName);
6145}
6146
6147llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6148 IdentifierInfo *II = &CGM.getContext().Idents.get(Name: "NSAutoreleasePool");
6149 return EmitClassRefFromId(CGF, II);
6150}
6151
6152llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6153 return CGF.Builder.CreateLoad(Addr: EmitSelectorAddr(Sel));
6154}
6155
6156ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6157 CharUnits Align = CGM.getPointerAlign();
6158
6159 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6160 if (!Entry) {
6161 Entry = CreateMetadataVar(
6162 Name: "OBJC_SELECTOR_REFERENCES_", Init: GetMethodVarName(Sel),
6163 Section: "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, AddToUsed: true);
6164 Entry->setExternallyInitialized(true);
6165 }
6166
6167 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6168}
6169
6170llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6171 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6172 if (!Entry)
6173 Entry = CreateCStringLiteral(Name: RuntimeName, Type: ObjCLabelType::ClassName);
6174 return Entry;
6175}
6176
6177llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6178 return MethodDefinitions.lookup(Val: MD);
6179}
6180
6181/// GetIvarLayoutName - Returns a unique constant for the given
6182/// ivar layout bitmap.
6183llvm::Constant *
6184CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6185 const ObjCCommonTypesHelper &ObjCTypes) {
6186 return llvm::Constant::getNullValue(Ty: ObjCTypes.Int8PtrTy);
6187}
6188
6189void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6190 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6191
6192 // If this is a union, remember that we had one, because it might mess
6193 // up the ordering of layout entries.
6194 if (RD->isUnion())
6195 IsDisordered = true;
6196
6197 const ASTRecordLayout *recLayout = nullptr;
6198 visitAggregate(begin: RD->field_begin(), end: RD->field_end(), aggregateOffset: offset,
6199 getOffset: [&](const FieldDecl *field) -> CharUnits {
6200 if (!recLayout)
6201 recLayout = &CGM.getContext().getASTRecordLayout(D: RD);
6202 auto offsetInBits =
6203 recLayout->getFieldOffset(FieldNo: field->getFieldIndex());
6204 return CGM.getContext().toCharUnitsFromBits(BitSize: offsetInBits);
6205 });
6206}
6207
6208template <class Iterator, class GetOffsetFn>
6209void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6210 CharUnits aggregateOffset,
6211 const GetOffsetFn &getOffset) {
6212 for (; begin != end; ++begin) {
6213 auto field = *begin;
6214
6215 // Skip over bitfields.
6216 if (field->isBitField()) {
6217 continue;
6218 }
6219
6220 // Compute the offset of the field within the aggregate.
6221 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6222
6223 visitField(field, offset: fieldOffset);
6224 }
6225}
6226
6227/// Collect layout information for the given fields into IvarsInfo.
6228void IvarLayoutBuilder::visitField(const FieldDecl *field,
6229 CharUnits fieldOffset) {
6230 QualType fieldType = field->getType();
6231
6232 // Drill down into arrays.
6233 uint64_t numElts = 1;
6234 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(T: fieldType)) {
6235 numElts = 0;
6236 fieldType = arrayType->getElementType();
6237 }
6238 // Unlike incomplete arrays, constant arrays can be nested.
6239 while (auto arrayType = CGM.getContext().getAsConstantArrayType(T: fieldType)) {
6240 numElts *= arrayType->getZExtSize();
6241 fieldType = arrayType->getElementType();
6242 }
6243
6244 assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
6245
6246 // If we ended up with a zero-sized array, we've done what we can do within
6247 // the limits of this layout encoding.
6248 if (numElts == 0)
6249 return;
6250
6251 // Recurse if the base element type is a record type.
6252 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6253 size_t oldEnd = IvarsInfo.size();
6254
6255 visitRecord(RT: recType, offset: fieldOffset);
6256
6257 // If we have an array, replicate the first entry's layout information.
6258 auto numEltEntries = IvarsInfo.size() - oldEnd;
6259 if (numElts != 1 && numEltEntries != 0) {
6260 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(T: recType);
6261 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6262 // Copy the last numEltEntries onto the end of the array, adjusting
6263 // each for the element size.
6264 for (size_t i = 0; i != numEltEntries; ++i) {
6265 auto firstEntry = IvarsInfo[oldEnd + i];
6266 IvarsInfo.push_back(Elt: IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6267 firstEntry.SizeInWords));
6268 }
6269 }
6270 }
6271
6272 return;
6273 }
6274
6275 // Classify the element type.
6276 Qualifiers::GC GCAttr = GetGCAttrTypeForType(Ctx&: CGM.getContext(), FQT: fieldType);
6277
6278 // If it matches what we're looking for, add an entry.
6279 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6280 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6281 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6282 CGM.getPointerSize());
6283 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, numElts));
6284 }
6285}
6286
6287/// buildBitmap - This routine does the horsework of taking the offsets of
6288/// strong/weak references and creating a bitmap. The bitmap is also
6289/// returned in the given buffer, suitable for being passed to \c dump().
6290llvm::Constant *
6291IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6292 llvm::SmallVectorImpl<unsigned char> &buffer) {
6293 // The bitmap is a series of skip/scan instructions, aligned to word
6294 // boundaries. The skip is performed first.
6295 const unsigned char MaxNibble = 0xF;
6296 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6297 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6298
6299 assert(!IvarsInfo.empty() && "generating bitmap for no data");
6300
6301 // Sort the ivar info on byte position in case we encounterred a
6302 // union nested in the ivar list.
6303 if (IsDisordered) {
6304 // This isn't a stable sort, but our algorithm should handle it fine.
6305 llvm::array_pod_sort(Start: IvarsInfo.begin(), End: IvarsInfo.end());
6306 } else {
6307 assert(llvm::is_sorted(IvarsInfo));
6308 }
6309 assert(IvarsInfo.back().Offset < InstanceEnd);
6310
6311 assert(buffer.empty());
6312
6313 // Skip the next N words.
6314 auto skip = [&](unsigned numWords) {
6315 assert(numWords > 0);
6316
6317 // Try to merge into the previous byte. Since scans happen second, we
6318 // can't do this if it includes a scan.
6319 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6320 unsigned lastSkip = buffer.back() >> SkipShift;
6321 if (lastSkip < MaxNibble) {
6322 unsigned claimed = std::min(a: MaxNibble - lastSkip, b: numWords);
6323 numWords -= claimed;
6324 lastSkip += claimed;
6325 buffer.back() = (lastSkip << SkipShift);
6326 }
6327 }
6328
6329 while (numWords >= MaxNibble) {
6330 buffer.push_back(Elt: MaxNibble << SkipShift);
6331 numWords -= MaxNibble;
6332 }
6333 if (numWords) {
6334 buffer.push_back(Elt: numWords << SkipShift);
6335 }
6336 };
6337
6338 // Scan the next N words.
6339 auto scan = [&](unsigned numWords) {
6340 assert(numWords > 0);
6341
6342 // Try to merge into the previous byte. Since scans happen second, we can
6343 // do this even if it includes a skip.
6344 if (!buffer.empty()) {
6345 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6346 if (lastScan < MaxNibble) {
6347 unsigned claimed = std::min(a: MaxNibble - lastScan, b: numWords);
6348 numWords -= claimed;
6349 lastScan += claimed;
6350 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6351 }
6352 }
6353
6354 while (numWords >= MaxNibble) {
6355 buffer.push_back(Elt: MaxNibble << ScanShift);
6356 numWords -= MaxNibble;
6357 }
6358 if (numWords) {
6359 buffer.push_back(Elt: numWords << ScanShift);
6360 }
6361 };
6362
6363 // One past the end of the last scan.
6364 unsigned endOfLastScanInWords = 0;
6365 const CharUnits WordSize = CGM.getPointerSize();
6366
6367 // Consider all the scan requests.
6368 for (auto &request : IvarsInfo) {
6369 CharUnits beginOfScan = request.Offset - InstanceBegin;
6370
6371 // Ignore scan requests that don't start at an even multiple of the
6372 // word size. We can't encode them.
6373 if (!beginOfScan.isMultipleOf(N: WordSize))
6374 continue;
6375
6376 // Ignore scan requests that start before the instance start.
6377 // This assumes that scans never span that boundary. The boundary
6378 // isn't the true start of the ivars, because in the fragile-ARC case
6379 // it's rounded up to word alignment, but the test above should leave
6380 // us ignoring that possibility.
6381 if (beginOfScan.isNegative()) {
6382 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6383 continue;
6384 }
6385
6386 unsigned beginOfScanInWords = beginOfScan / WordSize;
6387 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6388
6389 // If the scan starts some number of words after the last one ended,
6390 // skip forward.
6391 if (beginOfScanInWords > endOfLastScanInWords) {
6392 skip(beginOfScanInWords - endOfLastScanInWords);
6393
6394 // Otherwise, start scanning where the last left off.
6395 } else {
6396 beginOfScanInWords = endOfLastScanInWords;
6397
6398 // If that leaves us with nothing to scan, ignore this request.
6399 if (beginOfScanInWords >= endOfScanInWords)
6400 continue;
6401 }
6402
6403 // Scan to the end of the request.
6404 assert(beginOfScanInWords < endOfScanInWords);
6405 scan(endOfScanInWords - beginOfScanInWords);
6406 endOfLastScanInWords = endOfScanInWords;
6407 }
6408
6409 if (buffer.empty())
6410 return llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy);
6411
6412 // For GC layouts, emit a skip to the end of the allocation so that we
6413 // have precise information about the entire thing. This isn't useful
6414 // or necessary for the ARC-style layout strings.
6415 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6416 unsigned lastOffsetInWords =
6417 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6418 if (lastOffsetInWords > endOfLastScanInWords) {
6419 skip(lastOffsetInWords - endOfLastScanInWords);
6420 }
6421 }
6422
6423 // Null terminate the string.
6424 buffer.push_back(Elt: 0);
6425
6426 return CGObjC.CreateCStringLiteral(Name: reinterpret_cast<char *>(buffer.data()),
6427 Type: ObjCLabelType::LayoutBitMap);
6428}
6429
6430/// BuildIvarLayout - Builds ivar layout bitmap for the class
6431/// implementation for the __strong or __weak case.
6432/// The layout map displays which words in ivar list must be skipped
6433/// and which must be scanned by GC (see below). String is built of bytes.
6434/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
6435/// of words to skip and right nibble is count of words to scan. So, each
6436/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
6437/// represented by a 0x00 byte which also ends the string.
6438/// 1. when ForStrongLayout is true, following ivars are scanned:
6439/// - id, Class
6440/// - object *
6441/// - __strong anything
6442///
6443/// 2. When ForStrongLayout is false, following ivars are scanned:
6444/// - __weak anything
6445///
6446llvm::Constant *
6447CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6448 CharUnits beginOffset, CharUnits endOffset,
6449 bool ForStrongLayout, bool HasMRCWeakIvars) {
6450 // If this is MRC, and we're either building a strong layout or there
6451 // are no weak ivars, bail out early.
6452 llvm::Type *PtrTy = CGM.Int8PtrTy;
6453 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6454 !CGM.getLangOpts().ObjCAutoRefCount &&
6455 (ForStrongLayout || !HasMRCWeakIvars))
6456 return llvm::Constant::getNullValue(Ty: PtrTy);
6457
6458 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6459 SmallVector<const ObjCIvarDecl *, 32> ivars;
6460
6461 // GC layout strings include the complete object layout, possibly
6462 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6463 // up.
6464 //
6465 // ARC layout strings only include the class's ivars. In non-fragile
6466 // runtimes, that means starting at InstanceStart, rounded up to word
6467 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6468 // starting at the offset of the first ivar, rounded up to word alignment.
6469 //
6470 // MRC weak layout strings follow the ARC style.
6471 CharUnits baseOffset;
6472 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6473 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6474 IVD = IVD->getNextIvar())
6475 ivars.push_back(Elt: IVD);
6476
6477 if (isNonFragileABI()) {
6478 baseOffset = beginOffset; // InstanceStart
6479 } else if (!ivars.empty()) {
6480 baseOffset =
6481 CharUnits::fromQuantity(Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivars[0]));
6482 } else {
6483 baseOffset = CharUnits::Zero();
6484 }
6485
6486 baseOffset = baseOffset.alignTo(Align: CGM.getPointerAlign());
6487 } else {
6488 CGM.getContext().DeepCollectObjCIvars(OI, leafClass: true, Ivars&: ivars);
6489
6490 baseOffset = CharUnits::Zero();
6491 }
6492
6493 if (ivars.empty())
6494 return llvm::Constant::getNullValue(Ty: PtrTy);
6495
6496 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6497
6498 builder.visitAggregate(begin: ivars.begin(), end: ivars.end(), aggregateOffset: CharUnits::Zero(),
6499 getOffset: [&](const ObjCIvarDecl *ivar) -> CharUnits {
6500 return CharUnits::fromQuantity(
6501 Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivar));
6502 });
6503
6504 if (!builder.hasBitmapData())
6505 return llvm::Constant::getNullValue(Ty: PtrTy);
6506
6507 llvm::SmallVector<unsigned char, 4> buffer;
6508 llvm::Constant *C = builder.buildBitmap(CGObjC&: *this, buffer);
6509
6510 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6511 printf(format: "\n%s ivar layout for class '%s': ",
6512 ForStrongLayout ? "strong" : "weak",
6513 OMD->getClassInterface()->getName().str().c_str());
6514 builder.dump(buffer);
6515 }
6516 return C;
6517}
6518
6519llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6520 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6521 // FIXME: Avoid std::string in "Sel.getAsString()"
6522 if (!Entry)
6523 Entry =
6524 CreateCStringLiteral(Name: Sel.getAsString(), Type: ObjCLabelType::MethodVarName);
6525 return Entry;
6526}
6527
6528// FIXME: Merge into a single cstring creation function.
6529llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6530 return GetMethodVarName(Sel: CGM.getContext().Selectors.getNullarySelector(ID));
6531}
6532
6533llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6534 std::string TypeStr;
6535 CGM.getContext().getObjCEncodingForType(T: Field->getType(), S&: TypeStr, Field);
6536
6537 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6538 if (!Entry)
6539 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
6540 return Entry;
6541}
6542
6543llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6544 bool Extended) {
6545 std::string TypeStr =
6546 CGM.getContext().getObjCEncodingForMethodDecl(Decl: D, Extended);
6547
6548 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6549 if (!Entry)
6550 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
6551 return Entry;
6552}
6553
6554// FIXME: Merge into a single cstring creation function.
6555llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6556 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6557 if (!Entry)
6558 Entry = CreateCStringLiteral(Name: Ident->getName(), Type: ObjCLabelType::PropertyName);
6559 return Entry;
6560}
6561
6562// FIXME: Merge into a single cstring creation function.
6563// FIXME: This Decl should be more precise.
6564llvm::Constant *
6565CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6566 const Decl *Container) {
6567 std::string TypeStr =
6568 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6569 return GetPropertyName(Ident: &CGM.getContext().Idents.get(Name: TypeStr));
6570}
6571
6572void CGObjCMac::FinishModule() {
6573 EmitModuleInfo();
6574
6575 // Emit the dummy bodies for any protocols which were referenced but
6576 // never defined.
6577 for (auto &entry : Protocols) {
6578 llvm::GlobalVariable *global = entry.second;
6579 if (global->hasInitializer())
6580 continue;
6581
6582 ConstantInitBuilder builder(CGM);
6583 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolTy);
6584 values.addNullPointer(ptrTy: ObjCTypes.ProtocolExtensionPtrTy);
6585 values.add(value: GetClassName(RuntimeName: entry.first->getName()));
6586 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
6587 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
6588 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
6589 values.finishAndSetAsInitializer(global);
6590 CGM.addCompilerUsedGlobal(GV: global);
6591 }
6592
6593 // Add assembler directives to add lazy undefined symbol references
6594 // for classes which are referenced but not defined. This is
6595 // important for correct linker interaction.
6596 //
6597 // FIXME: It would be nice if we had an LLVM construct for this.
6598 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6599 CGM.getTriple().isOSBinFormatMachO()) {
6600 SmallString<256> Asm;
6601 llvm::raw_svector_ostream OS(Asm);
6602 for (const auto *Sym : DefinedSymbols)
6603 OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"
6604 << "\t.globl .objc_class_name_" << Sym->getName() << "\n";
6605 for (const auto *Sym : LazySymbols)
6606 OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";
6607 for (const auto &Category : DefinedCategoryNames)
6608 OS << "\t.objc_category_name_" << Category << "=0\n"
6609 << "\t.globl .objc_category_name_" << Category << "\n";
6610
6611 CGM.getModule().appendModuleInlineAsm(Fragment: OS.str());
6612 }
6613}
6614
6615CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6616 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6617 ObjCEmptyVtableVar(nullptr) {
6618 ObjCABI = 2;
6619}
6620
6621/* *** */
6622
6623ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6624 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6625 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6626 ASTContext &Ctx = CGM.getContext();
6627 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6628
6629 ShortTy = cast<llvm::IntegerType>(Val: Types.ConvertType(T: Ctx.ShortTy));
6630 IntTy = CGM.IntTy;
6631 LongTy = cast<llvm::IntegerType>(Val: Types.ConvertType(T: Ctx.LongTy));
6632 Int8PtrTy = CGM.Int8PtrTy;
6633 Int8PtrProgramASTy = llvm::PointerType::get(C&: CGM.getLLVMContext(), AddressSpace: ProgramAS);
6634 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6635
6636 // arm64 targets use "int" ivar offset variables. All others,
6637 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6638 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6639 IvarOffsetVarTy = IntTy;
6640 else
6641 IvarOffsetVarTy = LongTy;
6642
6643 ObjectPtrTy = cast<llvm::PointerType>(Val: Types.ConvertType(T: Ctx.getObjCIdType()));
6644 PtrObjectPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6645 SelectorPtrTy =
6646 cast<llvm::PointerType>(Val: Types.ConvertType(T: Ctx.getObjCSelType()));
6647
6648 // I'm not sure I like this. The implicit coordination is a bit
6649 // gross. We should solve this in a reasonable fashion because this
6650 // is a pretty common task (match some runtime data structure with
6651 // an LLVM data structure).
6652
6653 // FIXME: This is leaked.
6654 // FIXME: Merge with rewriter code?
6655
6656 // struct _objc_super {
6657 // id self;
6658 // Class cls;
6659 // }
6660 RecordDecl *RD = RecordDecl::Create(
6661 C: Ctx, TK: TagTypeKind::Struct, DC: Ctx.getTranslationUnitDecl(), StartLoc: SourceLocation(),
6662 IdLoc: SourceLocation(), Id: &Ctx.Idents.get(Name: "_objc_super"));
6663 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
6664 Id: nullptr, T: Ctx.getObjCIdType(), TInfo: nullptr, BW: nullptr,
6665 Mutable: false, InitStyle: ICIS_NoInit));
6666 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
6667 Id: nullptr, T: Ctx.getObjCClassType(), TInfo: nullptr,
6668 BW: nullptr, Mutable: false, InitStyle: ICIS_NoInit));
6669 RD->completeDefinition();
6670
6671 SuperCTy = Ctx.getCanonicalTagType(TD: RD);
6672 SuperPtrCTy = Ctx.getPointerType(T: SuperCTy);
6673
6674 SuperTy = cast<llvm::StructType>(Val: Types.ConvertType(T: SuperCTy));
6675 SuperPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6676
6677 // struct _prop_t {
6678 // char *name;
6679 // char *attributes;
6680 // }
6681 PropertyTy = llvm::StructType::create(Name: "struct._prop_t", elt1: Int8PtrTy, elts: Int8PtrTy);
6682
6683 // struct _prop_list_t {
6684 // uint32_t entsize; // sizeof(struct _prop_t)
6685 // uint32_t count_of_properties;
6686 // struct _prop_t prop_list[count_of_properties];
6687 // }
6688 PropertyListTy = llvm::StructType::create(
6689 Name: "struct._prop_list_t", elt1: IntTy, elts: IntTy, elts: llvm::ArrayType::get(ElementType: PropertyTy, NumElements: 0));
6690 // struct _prop_list_t *
6691 PropertyListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6692
6693 // struct _objc_method {
6694 // SEL _cmd;
6695 // char *method_type;
6696 // char *_imp;
6697 // }
6698 MethodTy = llvm::StructType::create(Name: "struct._objc_method", elt1: SelectorPtrTy,
6699 elts: Int8PtrTy, elts: Int8PtrProgramASTy);
6700
6701 // struct _objc_cache *
6702 CacheTy = llvm::StructType::create(Context&: VMContext, Name: "struct._objc_cache");
6703 CachePtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6704}
6705
6706ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6707 : ObjCCommonTypesHelper(cgm) {
6708 // struct _objc_method_description {
6709 // SEL name;
6710 // char *types;
6711 // }
6712 MethodDescriptionTy = llvm::StructType::create(
6713 Name: "struct._objc_method_description", elt1: SelectorPtrTy, elts: Int8PtrTy);
6714
6715 // struct _objc_method_description_list {
6716 // int count;
6717 // struct _objc_method_description[1];
6718 // }
6719 MethodDescriptionListTy =
6720 llvm::StructType::create(Name: "struct._objc_method_description_list", elt1: IntTy,
6721 elts: llvm::ArrayType::get(ElementType: MethodDescriptionTy, NumElements: 0));
6722
6723 // struct _objc_method_description_list *
6724 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6725
6726 // Protocol description structures
6727
6728 // struct _objc_protocol_extension {
6729 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6730 // struct _objc_method_description_list *optional_instance_methods;
6731 // struct _objc_method_description_list *optional_class_methods;
6732 // struct _objc_property_list *instance_properties;
6733 // const char ** extendedMethodTypes;
6734 // struct _objc_property_list *class_properties;
6735 // }
6736 ProtocolExtensionTy = llvm::StructType::create(
6737 Name: "struct._objc_protocol_extension", elt1: IntTy, elts: MethodDescriptionListPtrTy,
6738 elts: MethodDescriptionListPtrTy, elts: PropertyListPtrTy, elts: Int8PtrPtrTy,
6739 elts: PropertyListPtrTy);
6740
6741 // struct _objc_protocol_extension *
6742 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6743
6744 // Handle construction of Protocol and ProtocolList types
6745
6746 // struct _objc_protocol {
6747 // struct _objc_protocol_extension *isa;
6748 // char *protocol_name;
6749 // struct _objc_protocol **_objc_protocol_list;
6750 // struct _objc_method_description_list *instance_methods;
6751 // struct _objc_method_description_list *class_methods;
6752 // }
6753 ProtocolTy = llvm::StructType::create(
6754 Elements: {ProtocolExtensionPtrTy, Int8PtrTy,
6755 llvm::PointerType::getUnqual(C&: VMContext), MethodDescriptionListPtrTy,
6756 MethodDescriptionListPtrTy},
6757 Name: "struct._objc_protocol");
6758
6759 ProtocolListTy =
6760 llvm::StructType::create(Elements: {llvm::PointerType::getUnqual(C&: VMContext), LongTy,
6761 llvm::ArrayType::get(ElementType: ProtocolTy, NumElements: 0)},
6762 Name: "struct._objc_protocol_list");
6763
6764 // struct _objc_protocol_list *
6765 ProtocolListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6766
6767 ProtocolPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6768
6769 // Class description structures
6770
6771 // struct _objc_ivar {
6772 // char *ivar_name;
6773 // char *ivar_type;
6774 // int ivar_offset;
6775 // }
6776 IvarTy = llvm::StructType::create(Name: "struct._objc_ivar", elt1: Int8PtrTy, elts: Int8PtrTy,
6777 elts: IntTy);
6778
6779 // struct _objc_ivar_list *
6780 IvarListTy = llvm::StructType::create(Context&: VMContext, Name: "struct._objc_ivar_list");
6781 IvarListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6782
6783 // struct _objc_method_list *
6784 MethodListTy =
6785 llvm::StructType::create(Context&: VMContext, Name: "struct._objc_method_list");
6786 MethodListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6787
6788 // struct _objc_class_extension *
6789 ClassExtensionTy = llvm::StructType::create(
6790 Name: "struct._objc_class_extension", elt1: IntTy, elts: Int8PtrTy, elts: PropertyListPtrTy);
6791 ClassExtensionPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6792
6793 // struct _objc_class {
6794 // Class isa;
6795 // Class super_class;
6796 // char *name;
6797 // long version;
6798 // long info;
6799 // long instance_size;
6800 // struct _objc_ivar_list *ivars;
6801 // struct _objc_method_list *methods;
6802 // struct _objc_cache *cache;
6803 // struct _objc_protocol_list *protocols;
6804 // char *ivar_layout;
6805 // struct _objc_class_ext *ext;
6806 // };
6807 ClassTy = llvm::StructType::create(
6808 Elements: {llvm::PointerType::getUnqual(C&: VMContext),
6809 llvm::PointerType::getUnqual(C&: VMContext), Int8PtrTy, LongTy, LongTy,
6810 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6811 Int8PtrTy, ClassExtensionPtrTy},
6812 Name: "struct._objc_class");
6813
6814 ClassPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6815
6816 // struct _objc_category {
6817 // char *category_name;
6818 // char *class_name;
6819 // struct _objc_method_list *instance_method;
6820 // struct _objc_method_list *class_method;
6821 // struct _objc_protocol_list *protocols;
6822 // uint32_t size; // sizeof(struct _objc_category)
6823 // struct _objc_property_list *instance_properties;// category's @property
6824 // struct _objc_property_list *class_properties;
6825 // }
6826 CategoryTy = llvm::StructType::create(
6827 Name: "struct._objc_category", elt1: Int8PtrTy, elts: Int8PtrTy, elts: MethodListPtrTy,
6828 elts: MethodListPtrTy, elts: ProtocolListPtrTy, elts: IntTy, elts: PropertyListPtrTy,
6829 elts: PropertyListPtrTy);
6830
6831 // Global metadata structures
6832
6833 // struct _objc_symtab {
6834 // long sel_ref_cnt;
6835 // SEL *refs;
6836 // short cls_def_cnt;
6837 // short cat_def_cnt;
6838 // char *defs[cls_def_cnt + cat_def_cnt];
6839 // }
6840 SymtabTy = llvm::StructType::create(Name: "struct._objc_symtab", elt1: LongTy,
6841 elts: SelectorPtrTy, elts: ShortTy, elts: ShortTy,
6842 elts: llvm::ArrayType::get(ElementType: Int8PtrTy, NumElements: 0));
6843 SymtabPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6844
6845 // struct _objc_module {
6846 // long version;
6847 // long size; // sizeof(struct _objc_module)
6848 // char *name;
6849 // struct _objc_symtab* symtab;
6850 // }
6851 ModuleTy = llvm::StructType::create(Name: "struct._objc_module", elt1: LongTy, elts: LongTy,
6852 elts: Int8PtrTy, elts: SymtabPtrTy);
6853
6854 // FIXME: This is the size of the setjmp buffer and should be target
6855 // specific. 18 is what's used on 32-bit X86.
6856 uint64_t SetJmpBufferSize = 18;
6857
6858 // Exceptions
6859 llvm::Type *StackPtrTy = llvm::ArrayType::get(ElementType: CGM.Int8PtrTy, NumElements: 4);
6860
6861 ExceptionDataTy = llvm::StructType::create(
6862 Name: "struct._objc_exception_data",
6863 elt1: llvm::ArrayType::get(ElementType: CGM.Int32Ty, NumElements: SetJmpBufferSize), elts: StackPtrTy);
6864}
6865
6866ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6867 CodeGen::CodeGenModule &cgm)
6868 : ObjCCommonTypesHelper(cgm) {
6869 // struct _method_list_t {
6870 // uint32_t entsize; // sizeof(struct _objc_method)
6871 // uint32_t method_count;
6872 // struct _objc_method method_list[method_count];
6873 // }
6874 MethodListnfABITy =
6875 llvm::StructType::create(Name: "struct.__method_list_t", elt1: IntTy, elts: IntTy,
6876 elts: llvm::ArrayType::get(ElementType: MethodTy, NumElements: 0));
6877 // struct method_list_t *
6878 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6879
6880 // struct _protocol_t {
6881 // id isa; // NULL
6882 // const char * const protocol_name;
6883 // const struct _protocol_list_t * protocol_list; // super protocols
6884 // const struct method_list_t * const instance_methods;
6885 // const struct method_list_t * const class_methods;
6886 // const struct method_list_t *optionalInstanceMethods;
6887 // const struct method_list_t *optionalClassMethods;
6888 // const struct _prop_list_t * properties;
6889 // const uint32_t size; // sizeof(struct _protocol_t)
6890 // const uint32_t flags; // = 0
6891 // const char ** extendedMethodTypes;
6892 // const char *demangledName;
6893 // const struct _prop_list_t * class_properties;
6894 // }
6895
6896 ProtocolnfABITy = llvm::StructType::create(
6897 Name: "struct._protocol_t", elt1: ObjectPtrTy, elts: Int8PtrTy,
6898 elts: llvm::PointerType::getUnqual(C&: VMContext), elts: MethodListnfABIPtrTy,
6899 elts: MethodListnfABIPtrTy, elts: MethodListnfABIPtrTy, elts: MethodListnfABIPtrTy,
6900 elts: PropertyListPtrTy, elts: IntTy, elts: IntTy, elts: Int8PtrPtrTy, elts: Int8PtrTy,
6901 elts: PropertyListPtrTy);
6902
6903 // struct _protocol_t*
6904 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6905
6906 // struct _protocol_list_t {
6907 // long protocol_count; // Note, this is 32/64 bit
6908 // struct _protocol_t *[protocol_count];
6909 // }
6910 ProtocolListnfABITy = llvm::StructType::create(
6911 Elements: {LongTy, llvm::ArrayType::get(ElementType: ProtocolnfABIPtrTy, NumElements: 0)},
6912 Name: "struct._objc_protocol_list");
6913
6914 // struct _objc_protocol_list*
6915 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6916
6917 // struct _ivar_t {
6918 // unsigned [long] int *offset; // pointer to ivar offset location
6919 // char *name;
6920 // char *type;
6921 // uint32_t alignment;
6922 // uint32_t size;
6923 // }
6924 IvarnfABITy = llvm::StructType::create(
6925 Name: "struct._ivar_t", elt1: llvm::PointerType::getUnqual(C&: VMContext), elts: Int8PtrTy,
6926 elts: Int8PtrTy, elts: IntTy, elts: IntTy);
6927
6928 // struct _ivar_list_t {
6929 // uint32 entsize; // sizeof(struct _ivar_t)
6930 // uint32 count;
6931 // struct _iver_t list[count];
6932 // }
6933 IvarListnfABITy =
6934 llvm::StructType::create(Name: "struct._ivar_list_t", elt1: IntTy, elts: IntTy,
6935 elts: llvm::ArrayType::get(ElementType: IvarnfABITy, NumElements: 0));
6936
6937 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6938
6939 // struct _class_ro_t {
6940 // uint32_t const flags;
6941 // uint32_t const instanceStart;
6942 // uint32_t const instanceSize;
6943 // uint32_t const reserved; // only when building for 64bit targets
6944 // const uint8_t * const ivarLayout;
6945 // const char *const name;
6946 // const struct _method_list_t * const baseMethods;
6947 // const struct _objc_protocol_list *const baseProtocols;
6948 // const struct _ivar_list_t *const ivars;
6949 // const uint8_t * const weakIvarLayout;
6950 // const struct _prop_list_t * const properties;
6951 // }
6952
6953 // FIXME. Add 'reserved' field in 64bit abi mode!
6954 ClassRonfABITy = llvm::StructType::create(
6955 Name: "struct._class_ro_t", elt1: IntTy, elts: IntTy, elts: IntTy, elts: Int8PtrTy, elts: Int8PtrTy,
6956 elts: MethodListnfABIPtrTy, elts: ProtocolListnfABIPtrTy, elts: IvarListnfABIPtrTy,
6957 elts: Int8PtrTy, elts: PropertyListPtrTy);
6958
6959 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6960 ImpnfABITy = CGM.DefaultPtrTy;
6961
6962 // struct _class_t {
6963 // struct _class_t *isa;
6964 // struct _class_t * const superclass;
6965 // void *cache;
6966 // IMP *vtable;
6967 // struct class_ro_t *ro;
6968 // }
6969
6970 ClassnfABITy = llvm::StructType::create(
6971 Elements: {llvm::PointerType::getUnqual(C&: VMContext),
6972 llvm::PointerType::getUnqual(C&: VMContext), CachePtrTy,
6973 llvm::PointerType::getUnqual(C&: VMContext),
6974 llvm::PointerType::getUnqual(C&: VMContext)},
6975 Name: "struct._class_t");
6976
6977 // LLVM for struct _class_t *
6978 ClassnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6979
6980 // struct _category_t {
6981 // const char * const name;
6982 // struct _class_t *const cls;
6983 // const struct _method_list_t * const instance_methods;
6984 // const struct _method_list_t * const class_methods;
6985 // const struct _protocol_list_t * const protocols;
6986 // const struct _prop_list_t * const properties;
6987 // const struct _prop_list_t * const class_properties;
6988 // const uint32_t size;
6989 // }
6990 CategorynfABITy = llvm::StructType::create(
6991 Name: "struct._category_t", elt1: Int8PtrTy, elts: ClassnfABIPtrTy, elts: MethodListnfABIPtrTy,
6992 elts: MethodListnfABIPtrTy, elts: ProtocolListnfABIPtrTy, elts: PropertyListPtrTy,
6993 elts: PropertyListPtrTy, elts: IntTy);
6994
6995 // New types for nonfragile abi messaging.
6996 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6997 ASTContext &Ctx = CGM.getContext();
6998
6999 // MessageRefTy - LLVM for:
7000 // struct _message_ref_t {
7001 // IMP messenger;
7002 // SEL name;
7003 // };
7004
7005 // First the clang type for struct _message_ref_t
7006 RecordDecl *RD = RecordDecl::Create(
7007 C: Ctx, TK: TagTypeKind::Struct, DC: Ctx.getTranslationUnitDecl(), StartLoc: SourceLocation(),
7008 IdLoc: SourceLocation(), Id: &Ctx.Idents.get(Name: "_message_ref_t"));
7009 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
7010 Id: nullptr, T: Ctx.VoidPtrTy, TInfo: nullptr, BW: nullptr, Mutable: false,
7011 InitStyle: ICIS_NoInit));
7012 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
7013 Id: nullptr, T: Ctx.getObjCSelType(), TInfo: nullptr, BW: nullptr,
7014 Mutable: false, InitStyle: ICIS_NoInit));
7015 RD->completeDefinition();
7016
7017 MessageRefCTy = Ctx.getCanonicalTagType(TD: RD);
7018 MessageRefCPtrTy = Ctx.getPointerType(T: MessageRefCTy);
7019 MessageRefTy = cast<llvm::StructType>(Val: Types.ConvertType(T: MessageRefCTy));
7020
7021 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7022 MessageRefPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
7023
7024 // SuperMessageRefTy - LLVM for:
7025 // struct _super_message_ref_t {
7026 // SUPER_IMP messenger;
7027 // SEL name;
7028 // };
7029 SuperMessageRefTy = llvm::StructType::create(Name: "struct._super_message_ref_t",
7030 elt1: ImpnfABITy, elts: SelectorPtrTy);
7031
7032 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7033 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
7034
7035 // struct objc_typeinfo {
7036 // const void** vtable; // objc_ehtype_vtable + 2
7037 // const char* name; // c++ typeinfo string
7038 // Class cls;
7039 // };
7040 EHTypeTy = llvm::StructType::create(Name: "struct._objc_typeinfo",
7041 elt1: llvm::PointerType::getUnqual(C&: VMContext),
7042 elts: Int8PtrTy, elts: ClassnfABIPtrTy);
7043 EHTypePtrTy = llvm::PointerType::getUnqual(C&: VMContext);
7044}
7045
7046llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7047 FinishNonFragileABIModule();
7048
7049 return nullptr;
7050}
7051
7052void CGObjCNonFragileABIMac::AddModuleClassList(
7053 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7054 StringRef SectionName) {
7055 unsigned NumClasses = Container.size();
7056
7057 if (!NumClasses)
7058 return;
7059
7060 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7061 for (unsigned i = 0; i < NumClasses; i++)
7062 Symbols[i] = Container[i];
7063
7064 llvm::Constant *Init = llvm::ConstantArray::get(
7065 T: llvm::ArrayType::get(ElementType: ObjCTypes.Int8PtrTy, NumElements: Symbols.size()), V: Symbols);
7066
7067 // Section name is obtained by calling GetSectionName, which returns
7068 // sections in the __DATA segment on MachO.
7069 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7070 SectionName.starts_with("__DATA")) &&
7071 "SectionName expected to start with __DATA on MachO");
7072 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7073 CGM.getModule(), Init->getType(), false,
7074 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7075 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Ty: Init->getType()));
7076 GV->setSection(SectionName);
7077 CGM.addCompilerUsedGlobal(GV);
7078}
7079
7080void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7081 // nonfragile abi has no module definition.
7082
7083 // Build list of all implemented class addresses in array
7084 // L_OBJC_LABEL_CLASS_$.
7085
7086 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7087 i++) {
7088 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7089 assert(ID);
7090 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7091 // We are implementing a weak imported interface. Give it external linkage
7092 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7093 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7094 DefinedMetaClasses[i]->setLinkage(
7095 llvm::GlobalVariable::ExternalLinkage);
7096 }
7097 }
7098
7099 AddModuleClassList(
7100 Container: DefinedClasses, SymbolName: "OBJC_LABEL_CLASS_$",
7101 SectionName: GetSectionName(Section: "__objc_classlist", MachOAttributes: "regular,no_dead_strip"));
7102
7103 AddModuleClassList(
7104 Container: DefinedNonLazyClasses, SymbolName: "OBJC_LABEL_NONLAZY_CLASS_$",
7105 SectionName: GetSectionName(Section: "__objc_nlclslist", MachOAttributes: "regular,no_dead_strip"));
7106
7107 // Build list of all implemented category addresses in array
7108 // L_OBJC_LABEL_CATEGORY_$.
7109 AddModuleClassList(Container: DefinedCategories, SymbolName: "OBJC_LABEL_CATEGORY_$",
7110 SectionName: GetSectionName(Section: "__objc_catlist", MachOAttributes: "regular,no_dead_strip"));
7111 AddModuleClassList(
7112 Container: DefinedStubCategories, SymbolName: "OBJC_LABEL_STUB_CATEGORY_$",
7113 SectionName: GetSectionName(Section: "__objc_catlist2", MachOAttributes: "regular,no_dead_strip"));
7114 AddModuleClassList(
7115 Container: DefinedNonLazyCategories, SymbolName: "OBJC_LABEL_NONLAZY_CATEGORY_$",
7116 SectionName: GetSectionName(Section: "__objc_nlcatlist", MachOAttributes: "regular,no_dead_strip"));
7117
7118 EmitImageInfo();
7119}
7120
7121/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
7122/// VTableDispatchMethods; false otherwise. What this means is that
7123/// except for the 19 selectors in the list, we generate 32bit-style
7124/// message dispatch call for all the rest.
7125bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7126 // At various points we've experimented with using vtable-based
7127 // dispatch for all methods.
7128 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7129 case CodeGenOptions::Legacy:
7130 return false;
7131 case CodeGenOptions::NonLegacy:
7132 return true;
7133 case CodeGenOptions::Mixed:
7134 break;
7135 }
7136
7137 // If so, see whether this selector is in the white-list of things which must
7138 // use the new dispatch convention. We lazily build a dense set for this.
7139 if (VTableDispatchMethods.empty()) {
7140 VTableDispatchMethods.insert(V: GetNullarySelector(name: "alloc"));
7141 VTableDispatchMethods.insert(V: GetNullarySelector(name: "class"));
7142 VTableDispatchMethods.insert(V: GetNullarySelector(name: "self"));
7143 VTableDispatchMethods.insert(V: GetNullarySelector(name: "isFlipped"));
7144 VTableDispatchMethods.insert(V: GetNullarySelector(name: "length"));
7145 VTableDispatchMethods.insert(V: GetNullarySelector(name: "count"));
7146
7147 // These are vtable-based if GC is disabled.
7148 // Optimistically use vtable dispatch for hybrid compiles.
7149 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7150 VTableDispatchMethods.insert(V: GetNullarySelector(name: "retain"));
7151 VTableDispatchMethods.insert(V: GetNullarySelector(name: "release"));
7152 VTableDispatchMethods.insert(V: GetNullarySelector(name: "autorelease"));
7153 }
7154
7155 VTableDispatchMethods.insert(V: GetUnarySelector(name: "allocWithZone"));
7156 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isKindOfClass"));
7157 VTableDispatchMethods.insert(V: GetUnarySelector(name: "respondsToSelector"));
7158 VTableDispatchMethods.insert(V: GetUnarySelector(name: "objectForKey"));
7159 VTableDispatchMethods.insert(V: GetUnarySelector(name: "objectAtIndex"));
7160 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isEqualToString"));
7161 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isEqual"));
7162
7163 // These are vtable-based if GC is enabled.
7164 // Optimistically use vtable dispatch for hybrid compiles.
7165 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7166 VTableDispatchMethods.insert(V: GetNullarySelector(name: "hash"));
7167 VTableDispatchMethods.insert(V: GetUnarySelector(name: "addObject"));
7168
7169 // "countByEnumeratingWithState:objects:count"
7170 const IdentifierInfo *KeyIdents[] = {
7171 &CGM.getContext().Idents.get(Name: "countByEnumeratingWithState"),
7172 &CGM.getContext().Idents.get(Name: "objects"),
7173 &CGM.getContext().Idents.get(Name: "count")};
7174 VTableDispatchMethods.insert(
7175 V: CGM.getContext().Selectors.getSelector(NumArgs: 3, IIV: KeyIdents));
7176 }
7177 }
7178
7179 return VTableDispatchMethods.count(V: Sel);
7180}
7181
7182/// BuildClassRoTInitializer - generate meta-data for:
7183/// struct _class_ro_t {
7184/// uint32_t const flags;
7185/// uint32_t const instanceStart;
7186/// uint32_t const instanceSize;
7187/// uint32_t const reserved; // only when building for 64bit targets
7188/// const uint8_t * const ivarLayout;
7189/// const char *const name;
7190/// const struct _method_list_t * const baseMethods;
7191/// const struct _protocol_list_t *const baseProtocols;
7192/// const struct _ivar_list_t *const ivars;
7193/// const uint8_t * const weakIvarLayout;
7194/// const struct _prop_list_t * const properties;
7195/// }
7196///
7197llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7198 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7199 const ObjCImplementationDecl *ID) {
7200 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7201
7202 CharUnits beginInstance = CharUnits::fromQuantity(Quantity: InstanceStart);
7203 CharUnits endInstance = CharUnits::fromQuantity(Quantity: InstanceSize);
7204
7205 bool hasMRCWeak = false;
7206 if (CGM.getLangOpts().ObjCAutoRefCount)
7207 flags |= NonFragileABI_Class_CompiledByARC;
7208 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7209 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7210
7211 ConstantInitBuilder builder(CGM);
7212 auto values = builder.beginStruct(structTy: ObjCTypes.ClassRonfABITy);
7213
7214 values.addInt(intTy: ObjCTypes.IntTy, value: flags);
7215 values.addInt(intTy: ObjCTypes.IntTy, value: InstanceStart);
7216 values.addInt(intTy: ObjCTypes.IntTy, value: InstanceSize);
7217 values.add(value: (flags & NonFragileABI_Class_Meta)
7218 ? GetIvarLayoutName(Ident: nullptr, ObjCTypes)
7219 : BuildStrongIvarLayout(OI: ID, beginOffset: beginInstance, endOffset: endInstance));
7220 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
7221
7222 // const struct _method_list_t * const baseMethods;
7223 SmallVector<const ObjCMethodDecl *, 16> methods;
7224 if (flags & NonFragileABI_Class_Meta) {
7225 for (const auto *MD : ID->class_methods())
7226 if (!MD->isDirectMethod())
7227 methods.push_back(Elt: MD);
7228 } else {
7229 for (const auto *MD : ID->instance_methods())
7230 if (!MD->isDirectMethod())
7231 methods.push_back(Elt: MD);
7232 }
7233
7234 llvm::Constant *MethListPtr = emitMethodList(
7235 Name: ID->getObjCRuntimeNameAsString(),
7236 MLT: (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7237 : MethodListType::InstanceMethods,
7238 Methods: methods);
7239
7240 const PointerAuthSchema &MethListSchema =
7241 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7242 if (!MethListPtr->isNullValue())
7243 values.addSignedPointer(Pointer: MethListPtr, Schema: MethListSchema, CalleeDecl: GlobalDecl(),
7244 CalleeType: QualType());
7245 else
7246 values.add(value: MethListPtr);
7247
7248 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7249 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
7250 values.add(value: EmitProtocolList(Name: "_OBJC_CLASS_PROTOCOLS_$_" +
7251 OID->getObjCRuntimeNameAsString(),
7252 begin: OID->all_referenced_protocol_begin(),
7253 end: OID->all_referenced_protocol_end()));
7254
7255 if (flags & NonFragileABI_Class_Meta) {
7256 values.addNullPointer(ptrTy: ObjCTypes.IvarListnfABIPtrTy);
7257 values.add(value: GetIvarLayoutName(Ident: nullptr, ObjCTypes));
7258 values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" +
7259 ID->getObjCRuntimeNameAsString(),
7260 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: true));
7261 } else {
7262 values.add(value: EmitIvarList(ID));
7263 values.add(value: BuildWeakIvarLayout(OI: ID, beginOffset: beginInstance, endOffset: endInstance, hasMRCWeakIvars: hasMRCWeak));
7264 values.add(value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" +
7265 ID->getObjCRuntimeNameAsString(),
7266 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: false));
7267 }
7268
7269 llvm::SmallString<64> roLabel;
7270 llvm::raw_svector_ostream(roLabel)
7271 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_"
7272 : "_OBJC_CLASS_RO_$_")
7273 << ClassName;
7274
7275 return finishAndCreateGlobal(Builder&: values, Name: roLabel, CGM);
7276}
7277
7278/// Build the metaclass object for a class.
7279///
7280/// struct _class_t {
7281/// struct _class_t *isa;
7282/// struct _class_t * const superclass;
7283/// void *cache;
7284/// IMP *vtable;
7285/// struct class_ro_t *ro;
7286/// }
7287///
7288llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7289 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7290 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7291 bool HiddenVisibility) {
7292 ConstantInitBuilder builder(CGM);
7293 auto values = builder.beginStruct(structTy: ObjCTypes.ClassnfABITy);
7294 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7295 values.addSignedPointer(Pointer: IsAGV, Schema: PointerAuthOpts.ObjCIsaPointers, CalleeDecl: GlobalDecl(),
7296 CalleeType: QualType());
7297 if (SuperClassGV)
7298 values.addSignedPointer(Pointer: SuperClassGV, Schema: PointerAuthOpts.ObjCSuperPointers,
7299 CalleeDecl: GlobalDecl(), CalleeType: QualType());
7300 else
7301 values.addNullPointer(ptrTy: ObjCTypes.ClassnfABIPtrTy);
7302
7303 values.add(value: ObjCEmptyCacheVar);
7304 values.add(value: ObjCEmptyVtableVar);
7305
7306 values.addSignedPointer(Pointer: ClassRoGV, Schema: PointerAuthOpts.ObjCClassROPointers,
7307 CalleeDecl: GlobalDecl(), CalleeType: QualType());
7308
7309 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7310 Val: GetClassGlobal(ID: CI, isMetaclass, isForDefinition: ForDefinition));
7311 values.finishAndSetAsInitializer(global: GV);
7312
7313 if (CGM.getTriple().isOSBinFormatMachO())
7314 GV->setSection("__DATA, __objc_data");
7315 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.ClassnfABITy));
7316 if (!CGM.getTriple().isOSBinFormatCOFF())
7317 if (HiddenVisibility)
7318 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7319 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7320 CGM.addUsedGlobal(GV);
7321 return GV;
7322}
7323
7324bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7325 const ObjCImplDecl *OD) const {
7326 return OD->getClassMethod(Sel: GetNullarySelector(name: "load")) != nullptr ||
7327 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7328 OD->hasAttr<ObjCNonLazyClassAttr>();
7329}
7330
7331void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7332 uint32_t &InstanceStart,
7333 uint32_t &InstanceSize) {
7334 const ASTRecordLayout &RL =
7335 CGM.getContext().getASTObjCInterfaceLayout(D: OID->getClassInterface());
7336
7337 // InstanceSize is really instance end.
7338 InstanceSize = RL.getDataSize().getQuantity();
7339
7340 // If there are no fields, the start is the same as the end.
7341 if (!RL.getFieldCount())
7342 InstanceStart = InstanceSize;
7343 else
7344 InstanceStart = RL.getFieldOffset(FieldNo: 0) / CGM.getContext().getCharWidth();
7345}
7346
7347static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7348 StringRef Name) {
7349 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7350 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7351 DeclContext *DC = TranslationUnitDecl::castToDeclContext(D: TUDecl);
7352
7353 const VarDecl *VD = nullptr;
7354 for (const auto *Result : DC->lookup(Name: &II))
7355 if ((VD = dyn_cast<VarDecl>(Val: Result)))
7356 break;
7357
7358 if (!VD)
7359 return llvm::GlobalValue::DLLImportStorageClass;
7360 if (VD->hasAttr<DLLExportAttr>())
7361 return llvm::GlobalValue::DLLExportStorageClass;
7362 if (VD->hasAttr<DLLImportAttr>())
7363 return llvm::GlobalValue::DLLImportStorageClass;
7364 return llvm::GlobalValue::DefaultStorageClass;
7365}
7366
7367void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7368 if (!ObjCEmptyCacheVar) {
7369 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7370 CGM.getModule(), ObjCTypes.CacheTy, false,
7371 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");
7372 if (CGM.getTriple().isOSBinFormatCOFF())
7373 ObjCEmptyCacheVar->setDLLStorageClass(
7374 getStorage(CGM, Name: "_objc_empty_cache"));
7375
7376 // Only OS X with deployment version <10.9 use the empty vtable symbol
7377 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7378 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(Major: 10, Minor: 9))
7379 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7380 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7381 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");
7382 else
7383 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(T: CGM.DefaultPtrTy);
7384 }
7385
7386 // FIXME: Is this correct (that meta class size is never computed)?
7387 uint32_t InstanceStart =
7388 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassnfABITy);
7389 uint32_t InstanceSize = InstanceStart;
7390 uint32_t flags = NonFragileABI_Class_Meta;
7391
7392 llvm::Constant *SuperClassGV, *IsAGV;
7393
7394 const auto *CI = ID->getClassInterface();
7395 assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
7396
7397 // Build the flags for the metaclass.
7398 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7399 ? !CI->hasAttr<DLLExportAttr>()
7400 : CI->getVisibility() == HiddenVisibility;
7401 if (classIsHidden)
7402 flags |= NonFragileABI_Class_Hidden;
7403
7404 // FIXME: why is this flag set on the metaclass?
7405 // ObjC metaclasses have no fields and don't really get constructed.
7406 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7407 flags |= NonFragileABI_Class_HasCXXStructors;
7408 if (!ID->hasNonZeroConstructors())
7409 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7410 }
7411
7412 if (!CI->getSuperClass()) {
7413 // class is root
7414 flags |= NonFragileABI_Class_Root;
7415
7416 SuperClassGV = GetClassGlobal(ID: CI, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition);
7417 IsAGV = GetClassGlobal(ID: CI, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
7418 } else {
7419 // Has a root. Current class is not a root.
7420 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7421 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7422 Root = Super;
7423
7424 const auto *Super = CI->getSuperClass();
7425 IsAGV = GetClassGlobal(ID: Root, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
7426 SuperClassGV = GetClassGlobal(ID: Super, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
7427 }
7428
7429 llvm::GlobalVariable *CLASS_RO_GV =
7430 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7431
7432 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7433 CI, /*metaclass*/ isMetaclass: true, IsAGV, SuperClassGV, ClassRoGV: CLASS_RO_GV, HiddenVisibility: classIsHidden);
7434 CGM.setGVProperties(GV: MetaTClass, D: CI);
7435 DefinedMetaClasses.push_back(x: MetaTClass);
7436
7437 // Metadata for the class
7438 flags = 0;
7439 if (classIsHidden)
7440 flags |= NonFragileABI_Class_Hidden;
7441
7442 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7443 flags |= NonFragileABI_Class_HasCXXStructors;
7444
7445 // Set a flag to enable a runtime optimization when a class has
7446 // fields that require destruction but which don't require
7447 // anything except zero-initialization during construction. This
7448 // is most notably true of __strong and __weak types, but you can
7449 // also imagine there being C++ types with non-trivial default
7450 // constructors that merely set all fields to null.
7451 if (!ID->hasNonZeroConstructors())
7452 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7453 }
7454
7455 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: CI))
7456 flags |= NonFragileABI_Class_Exception;
7457
7458 if (!CI->getSuperClass()) {
7459 flags |= NonFragileABI_Class_Root;
7460 SuperClassGV = nullptr;
7461 } else {
7462 // Has a root. Current class is not a root.
7463 const auto *Super = CI->getSuperClass();
7464 SuperClassGV = GetClassGlobal(ID: Super, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition);
7465 }
7466
7467 GetClassSizeInfo(OID: ID, InstanceStart, InstanceSize);
7468 CLASS_RO_GV =
7469 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7470
7471 llvm::GlobalVariable *ClassMD =
7472 BuildClassObject(CI, /*metaclass*/ isMetaclass: false, IsAGV: MetaTClass, SuperClassGV,
7473 ClassRoGV: CLASS_RO_GV, HiddenVisibility: classIsHidden);
7474 CGM.setGVProperties(GV: ClassMD, D: CI);
7475 DefinedClasses.push_back(Elt: ClassMD);
7476 ImplementedClasses.push_back(Elt: CI);
7477
7478 // Determine if this class is also "non-lazy".
7479 if (ImplementationIsNonLazy(OD: ID))
7480 DefinedNonLazyClasses.push_back(Elt: ClassMD);
7481
7482 // Force the definition of the EHType if necessary.
7483 if (flags & NonFragileABI_Class_Exception)
7484 (void)GetInterfaceEHType(ID: CI, IsForDefinition: ForDefinition);
7485 // Make sure method definition entries are all clear for next implementation.
7486 MethodDefinitions.clear();
7487}
7488
7489/// GenerateProtocolRef - This routine is called to generate code for
7490/// a protocol reference expression; as in:
7491/// @code
7492/// @protocol(Proto1);
7493/// @endcode
7494/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
7495/// which will hold address of the protocol meta-data.
7496///
7497llvm::Value *
7498CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7499 const ObjCProtocolDecl *PD) {
7500
7501 // This routine is called for @protocol only. So, we must build definition
7502 // of protocol's meta-data (not a reference to it!)
7503 assert(!PD->isNonRuntimeProtocol() &&
7504 "attempting to get a protocol ref to a static protocol.");
7505 llvm::Constant *Init = GetOrEmitProtocol(PD);
7506
7507 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_");
7508 ProtocolName += PD->getObjCRuntimeNameAsString();
7509
7510 CharUnits Align = CGF.getPointerAlign();
7511
7512 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(Name: ProtocolName);
7513 if (PTGV)
7514 return CGF.Builder.CreateAlignedLoad(Ty: PTGV->getValueType(), Addr: PTGV, Align);
7515 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7516 llvm::GlobalValue::WeakAnyLinkage, Init,
7517 ProtocolName);
7518 PTGV->setSection(
7519 GetSectionName(Section: "__objc_protorefs", MachOAttributes: "coalesced,no_dead_strip"));
7520 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7521 PTGV->setAlignment(Align.getAsAlign());
7522 if (!CGM.getTriple().isOSBinFormatMachO())
7523 PTGV->setComdat(CGM.getModule().getOrInsertComdat(Name: ProtocolName));
7524 CGM.addUsedGlobal(GV: PTGV);
7525 return CGF.Builder.CreateAlignedLoad(Ty: PTGV->getValueType(), Addr: PTGV, Align);
7526}
7527
7528/// GenerateCategory - Build metadata for a category implementation.
7529/// struct _category_t {
7530/// const char * const name;
7531/// struct _class_t *const cls;
7532/// const struct _method_list_t * const instance_methods;
7533/// const struct _method_list_t * const class_methods;
7534/// const struct _protocol_list_t * const protocols;
7535/// const struct _prop_list_t * const properties;
7536/// const struct _prop_list_t * const class_properties;
7537/// const uint32_t size;
7538/// }
7539///
7540void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7541 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7542 const char *Prefix = "_OBJC_$_CATEGORY_";
7543
7544 llvm::SmallString<64> ExtCatName(Prefix);
7545 ExtCatName += Interface->getObjCRuntimeNameAsString();
7546 ExtCatName += "_$_";
7547 ExtCatName += OCD->getNameAsString();
7548
7549 ConstantInitBuilder builder(CGM);
7550 auto values = builder.beginStruct(structTy: ObjCTypes.CategorynfABITy);
7551 values.add(value: GetClassName(RuntimeName: OCD->getIdentifier()->getName()));
7552 // meta-class entry symbol
7553 values.add(value: GetClassGlobal(ID: Interface, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition));
7554 std::string listName =
7555 (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
7556
7557 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7558 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7559 for (const auto *MD : OCD->methods()) {
7560 if (MD->isDirectMethod())
7561 continue;
7562 if (MD->isInstanceMethod()) {
7563 instanceMethods.push_back(Elt: MD);
7564 } else {
7565 classMethods.push_back(Elt: MD);
7566 }
7567 }
7568
7569 llvm::Constant *InstanceMethodList = emitMethodList(
7570 Name: listName, MLT: MethodListType::CategoryInstanceMethods, Methods: instanceMethods);
7571 const PointerAuthSchema &MethListSchema =
7572 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7573 if (!InstanceMethodList->isNullValue())
7574 values.addSignedPointer(Pointer: InstanceMethodList, Schema: MethListSchema, CalleeDecl: GlobalDecl(),
7575 CalleeType: QualType());
7576 else
7577 values.add(value: InstanceMethodList);
7578
7579 llvm::Constant *ClassMethodList = emitMethodList(
7580 Name: listName, MLT: MethodListType::CategoryClassMethods, Methods: classMethods);
7581 if (!ClassMethodList->isNullValue())
7582 values.addSignedPointer(Pointer: ClassMethodList, Schema: MethListSchema, CalleeDecl: GlobalDecl(),
7583 CalleeType: QualType());
7584 else
7585 values.add(value: ClassMethodList);
7586
7587 // Keep track of whether we have actual metadata to emit.
7588 bool isEmptyCategory =
7589 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7590
7591 const ObjCCategoryDecl *Category =
7592 Interface->FindCategoryDeclaration(CategoryId: OCD->getIdentifier());
7593 if (Category) {
7594 SmallString<256> ExtName;
7595 llvm::raw_svector_ostream(ExtName)
7596 << Interface->getObjCRuntimeNameAsString() << "_$_" << OCD->getName();
7597 auto protocolList =
7598 EmitProtocolList(Name: "_OBJC_CATEGORY_PROTOCOLS_$_" +
7599 Interface->getObjCRuntimeNameAsString() + "_$_" +
7600 Category->getName(),
7601 begin: Category->protocol_begin(), end: Category->protocol_end());
7602 auto propertyList = EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + ExtName.str(),
7603 Container: OCD, OCD: Category, ObjCTypes, IsClassProperty: false);
7604 auto classPropertyList =
7605 EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), Container: OCD,
7606 OCD: Category, ObjCTypes, IsClassProperty: true);
7607 values.add(value: protocolList);
7608 values.add(value: propertyList);
7609 values.add(value: classPropertyList);
7610 isEmptyCategory &= protocolList->isNullValue() &&
7611 propertyList->isNullValue() &&
7612 classPropertyList->isNullValue();
7613 } else {
7614 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListnfABIPtrTy);
7615 values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
7616 values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
7617 }
7618
7619 if (isEmptyCategory) {
7620 // Empty category, don't emit any metadata.
7621 values.abandon();
7622 MethodDefinitions.clear();
7623 return;
7624 }
7625
7626 unsigned Size =
7627 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.CategorynfABITy);
7628 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
7629
7630 llvm::GlobalVariable *GCATV =
7631 finishAndCreateGlobal(Builder&: values, Name: ExtCatName.str(), CGM);
7632 CGM.addCompilerUsedGlobal(GV: GCATV);
7633 if (Interface->hasAttr<ObjCClassStubAttr>())
7634 DefinedStubCategories.push_back(Elt: GCATV);
7635 else
7636 DefinedCategories.push_back(Elt: GCATV);
7637
7638 // Determine if this category is also "non-lazy".
7639 if (ImplementationIsNonLazy(OD: OCD))
7640 DefinedNonLazyCategories.push_back(Elt: GCATV);
7641 // method definition entries must be clear for next implementation.
7642 MethodDefinitions.clear();
7643}
7644
7645/// emitMethodConstant - Return a struct objc_method constant. If
7646/// forProtocol is true, the implementation will be null; otherwise,
7647/// the method must have a definition registered with the runtime.
7648///
7649/// struct _objc_method {
7650/// SEL _cmd;
7651/// char *method_type;
7652/// char *_imp;
7653/// }
7654void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7655 const ObjCMethodDecl *MD,
7656 bool forProtocol) {
7657 auto method = builder.beginStruct(ty: ObjCTypes.MethodTy);
7658 method.add(value: GetMethodVarName(Sel: MD->getSelector()));
7659 method.add(value: GetMethodVarType(D: MD));
7660
7661 if (forProtocol) {
7662 // Protocol methods have no implementation. So, this entry is always NULL.
7663 method.addNullPointer(ptrTy: ObjCTypes.Int8PtrProgramASTy);
7664 } else {
7665 llvm::Function *fn = GetMethodDefinition(MD);
7666 assert(fn && "no definition for method?");
7667 if (const PointerAuthSchema &Schema =
7668 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7669 llvm::Constant *Bitcast =
7670 llvm::ConstantExpr::getBitCast(C: fn, Ty: ObjCTypes.Int8PtrProgramASTy);
7671 method.addSignedPointer(Pointer: Bitcast, Schema, CalleeDecl: GlobalDecl(), CalleeType: QualType());
7672 } else
7673 method.add(value: fn);
7674 }
7675
7676 method.finishAndAddTo(parent&: builder);
7677}
7678
7679/// Build meta-data for method declarations.
7680///
7681/// struct _method_list_t {
7682/// uint32_t entsize; // sizeof(struct _objc_method)
7683/// uint32_t method_count;
7684/// struct _objc_method method_list[method_count];
7685/// }
7686///
7687llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7688 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7689 // Return null for empty list.
7690 if (methods.empty())
7691 return llvm::Constant::getNullValue(Ty: ObjCTypes.MethodListnfABIPtrTy);
7692
7693 StringRef prefix;
7694 bool forProtocol;
7695 switch (kind) {
7696 case MethodListType::CategoryInstanceMethods:
7697 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
7698 forProtocol = false;
7699 break;
7700 case MethodListType::CategoryClassMethods:
7701 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_";
7702 forProtocol = false;
7703 break;
7704 case MethodListType::InstanceMethods:
7705 prefix = "_OBJC_$_INSTANCE_METHODS_";
7706 forProtocol = false;
7707 break;
7708 case MethodListType::ClassMethods:
7709 prefix = "_OBJC_$_CLASS_METHODS_";
7710 forProtocol = false;
7711 break;
7712
7713 case MethodListType::ProtocolInstanceMethods:
7714 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
7715 forProtocol = true;
7716 break;
7717 case MethodListType::ProtocolClassMethods:
7718 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_";
7719 forProtocol = true;
7720 break;
7721 case MethodListType::OptionalProtocolInstanceMethods:
7722 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
7723 forProtocol = true;
7724 break;
7725 case MethodListType::OptionalProtocolClassMethods:
7726 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
7727 forProtocol = true;
7728 break;
7729 }
7730
7731 ConstantInitBuilder builder(CGM);
7732 auto values = builder.beginStruct();
7733
7734 // sizeof(struct _objc_method)
7735 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.MethodTy);
7736 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
7737 // method_count
7738 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
7739 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodTy);
7740 for (auto MD : methods)
7741 emitMethodConstant(builder&: methodArray, MD, forProtocol);
7742 methodArray.finishAndAddTo(parent&: values);
7743
7744 llvm::GlobalVariable *GV = finishAndCreateGlobal(Builder&: values, Name: prefix + name, CGM);
7745 CGM.addCompilerUsedGlobal(GV);
7746 return GV;
7747}
7748
7749/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
7750/// the given ivar.
7751llvm::GlobalVariable *
7752CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7753 const ObjCIvarDecl *Ivar) {
7754 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7755 llvm::SmallString<64> Name("OBJC_IVAR_$_");
7756 Name += Container->getObjCRuntimeNameAsString();
7757 Name += ".";
7758 Name += Ivar->getName();
7759 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7760 if (!IvarOffsetGV) {
7761 IvarOffsetGV = new llvm::GlobalVariable(
7762 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7763 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7764 if (CGM.getTriple().isOSBinFormatCOFF()) {
7765 bool IsPrivateOrPackage =
7766 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7767 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7768
7769 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7770
7771 if (ContainingID->hasAttr<DLLImportAttr>())
7772 IvarOffsetGV->setDLLStorageClass(
7773 llvm::GlobalValue::DLLImportStorageClass);
7774 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7775 IvarOffsetGV->setDLLStorageClass(
7776 llvm::GlobalValue::DLLExportStorageClass);
7777 }
7778 }
7779 return IvarOffsetGV;
7780}
7781
7782llvm::Constant *
7783CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7784 const ObjCIvarDecl *Ivar,
7785 unsigned long int Offset) {
7786 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7787 IvarOffsetGV->setInitializer(
7788 llvm::ConstantInt::get(Ty: ObjCTypes.IvarOffsetVarTy, V: Offset));
7789 IvarOffsetGV->setAlignment(
7790 CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.IvarOffsetVarTy));
7791
7792 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7793 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7794 // as well (i.e., in ObjCIvarOffsetVariable).
7795 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7796 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7797 ID->getVisibility() == HiddenVisibility)
7798 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7799 else
7800 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7801 }
7802
7803 // If ID's layout is known, then make the global constant. This serves as a
7804 // useful assertion: we'll never use this variable to calculate ivar offsets,
7805 // so if the runtime tries to patch it then we should crash.
7806 if (isClassLayoutKnownStatically(ID))
7807 IvarOffsetGV->setConstant(true);
7808
7809 if (CGM.getTriple().isOSBinFormatMachO())
7810 IvarOffsetGV->setSection("__DATA, __objc_ivar");
7811 return IvarOffsetGV;
7812}
7813
7814/// EmitIvarList - Emit the ivar list for the given
7815/// implementation. The return value has type
7816/// IvarListnfABIPtrTy.
7817/// struct _ivar_t {
7818/// unsigned [long] int *offset; // pointer to ivar offset location
7819/// char *name;
7820/// char *type;
7821/// uint32_t alignment;
7822/// uint32_t size;
7823/// }
7824/// struct _ivar_list_t {
7825/// uint32 entsize; // sizeof(struct _ivar_t)
7826/// uint32 count;
7827/// struct _iver_t list[count];
7828/// }
7829///
7830
7831llvm::Constant *
7832CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7833
7834 ConstantInitBuilder builder(CGM);
7835 auto ivarList = builder.beginStruct();
7836 ivarList.addInt(intTy: ObjCTypes.IntTy,
7837 value: CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.IvarnfABITy));
7838 auto ivarCountSlot = ivarList.addPlaceholder();
7839 auto ivars = ivarList.beginArray(eltTy: ObjCTypes.IvarnfABITy);
7840
7841 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7842 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
7843
7844 // FIXME. Consolidate this with similar code in GenerateClass.
7845
7846 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7847 IVD = IVD->getNextIvar()) {
7848 // Ignore unnamed bit-fields.
7849 if (!IVD->getDeclName())
7850 continue;
7851
7852 auto ivar = ivars.beginStruct(ty: ObjCTypes.IvarnfABITy);
7853 ivar.add(value: EmitIvarOffsetVar(ID: ID->getClassInterface(), Ivar: IVD,
7854 Offset: ComputeIvarBaseOffset(CGM, OID: ID, Ivar: IVD)));
7855 ivar.add(value: GetMethodVarName(ID: IVD->getIdentifier()));
7856 ivar.add(value: GetMethodVarType(Field: IVD));
7857 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(T: IVD->getType());
7858 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: FieldTy);
7859 unsigned Align =
7860 CGM.getContext().getPreferredTypeAlign(T: IVD->getType().getTypePtr()) >>
7861 3;
7862 Align = llvm::Log2_32(Value: Align);
7863 ivar.addInt(intTy: ObjCTypes.IntTy, value: Align);
7864 // NOTE. Size of a bitfield does not match gcc's, because of the
7865 // way bitfields are treated special in each. But I am told that
7866 // 'size' for bitfield ivars is ignored by the runtime so it does
7867 // not matter. If it matters, there is enough info to get the
7868 // bitfield right!
7869 ivar.addInt(intTy: ObjCTypes.IntTy, value: Size);
7870 ivar.finishAndAddTo(parent&: ivars);
7871 }
7872 // Return null for empty list.
7873 if (ivars.empty()) {
7874 ivars.abandon();
7875 ivarList.abandon();
7876 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListnfABIPtrTy);
7877 }
7878
7879 auto ivarCount = ivars.size();
7880 ivars.finishAndAddTo(parent&: ivarList);
7881 ivarList.fillPlaceholderWithInt(position: ivarCountSlot, type: ObjCTypes.IntTy, value: ivarCount);
7882
7883 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_";
7884 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7885 Builder&: ivarList, Name: Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7886 CGM.addCompilerUsedGlobal(GV);
7887 return GV;
7888}
7889
7890llvm::Constant *
7891CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7892 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7893
7894 assert(!PD->isNonRuntimeProtocol() &&
7895 "attempting to GetOrEmit a non-runtime protocol");
7896 if (!Entry) {
7897 // We use the initializer as a marker of whether this is a forward
7898 // reference or not. At module finalization we add the empty
7899 // contents for protocols which were referenced but never defined.
7900 llvm::SmallString<64> Protocol;
7901 llvm::raw_svector_ostream(Protocol)
7902 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
7903
7904 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7905 false, llvm::GlobalValue::ExternalLinkage,
7906 nullptr, Protocol);
7907 if (!CGM.getTriple().isOSBinFormatMachO())
7908 Entry->setComdat(CGM.getModule().getOrInsertComdat(Name: Protocol));
7909 }
7910
7911 return Entry;
7912}
7913
7914/// GetOrEmitProtocol - Generate the protocol meta-data:
7915/// @code
7916/// struct _protocol_t {
7917/// id isa; // NULL
7918/// const char * const protocol_name;
7919/// const struct _protocol_list_t * protocol_list; // super protocols
7920/// const struct method_list_t * const instance_methods;
7921/// const struct method_list_t * const class_methods;
7922/// const struct method_list_t *optionalInstanceMethods;
7923/// const struct method_list_t *optionalClassMethods;
7924/// const struct _prop_list_t * properties;
7925/// const uint32_t size; // sizeof(struct _protocol_t)
7926/// const uint32_t flags; // = 0
7927/// const char ** extendedMethodTypes;
7928/// const char *demangledName;
7929/// const struct _prop_list_t * class_properties;
7930/// }
7931/// @endcode
7932///
7933
7934llvm::Constant *
7935CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7936 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7937
7938 // Early exit if a defining object has already been generated.
7939 if (Entry && Entry->hasInitializer())
7940 return Entry;
7941
7942 // Use the protocol definition, if there is one.
7943 assert(PD->hasDefinition() &&
7944 "emitting protocol metadata without definition");
7945 PD = PD->getDefinition();
7946
7947 auto methodLists = ProtocolMethodLists::get(PD);
7948
7949 ConstantInitBuilder builder(CGM);
7950 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolnfABITy);
7951
7952 // isa is NULL
7953 values.addNullPointer(ptrTy: ObjCTypes.ObjectPtrTy);
7954 values.add(value: GetClassName(RuntimeName: PD->getObjCRuntimeNameAsString()));
7955 values.add(value: EmitProtocolList(Name: "_OBJC_$_PROTOCOL_REFS_" +
7956 PD->getObjCRuntimeNameAsString(),
7957 begin: PD->protocol_begin(), end: PD->protocol_end()));
7958 values.add(value: methodLists.emitMethodList(
7959 self: this, PD, kind: ProtocolMethodLists::RequiredInstanceMethods));
7960 values.add(value: methodLists.emitMethodList(
7961 self: this, PD, kind: ProtocolMethodLists::RequiredClassMethods));
7962 values.add(value: methodLists.emitMethodList(
7963 self: this, PD, kind: ProtocolMethodLists::OptionalInstanceMethods));
7964 values.add(value: methodLists.emitMethodList(
7965 self: this, PD, kind: ProtocolMethodLists::OptionalClassMethods));
7966 values.add(
7967 value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7968 Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: false));
7969 uint32_t Size =
7970 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ProtocolnfABITy);
7971 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
7972 values.addInt(intTy: ObjCTypes.IntTy, value: 0);
7973 values.add(value: EmitProtocolMethodTypes(
7974 Name: "_OBJC_$_PROTOCOL_METHOD_TYPES_" + PD->getObjCRuntimeNameAsString(),
7975 MethodTypes: methodLists.emitExtendedTypesArray(self: this), ObjCTypes));
7976
7977 // const char *demangledName;
7978 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
7979
7980 values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" +
7981 PD->getObjCRuntimeNameAsString(),
7982 Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: true));
7983
7984 if (Entry) {
7985 // Already created, fix the linkage and update the initializer.
7986 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7987 values.finishAndSetAsInitializer(global: Entry);
7988 } else {
7989 llvm::SmallString<64> symbolName;
7990 llvm::raw_svector_ostream(symbolName)
7991 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
7992
7993 Entry = values.finishAndCreateGlobal(args&: symbolName, args: CGM.getPointerAlign(),
7994 /*constant*/ args: false,
7995 args: llvm::GlobalValue::WeakAnyLinkage);
7996 if (!CGM.getTriple().isOSBinFormatMachO())
7997 Entry->setComdat(CGM.getModule().getOrInsertComdat(Name: symbolName));
7998
7999 Protocols[PD->getIdentifier()] = Entry;
8000 }
8001 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8002 CGM.addUsedGlobal(GV: Entry);
8003
8004 // Use this protocol meta-data to build protocol list table in section
8005 // __DATA, __objc_protolist
8006 llvm::SmallString<64> ProtocolRef;
8007 llvm::raw_svector_ostream(ProtocolRef)
8008 << "_OBJC_LABEL_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
8009
8010 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8011 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8012 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8013 if (!CGM.getTriple().isOSBinFormatMachO())
8014 PTGV->setComdat(CGM.getModule().getOrInsertComdat(Name: ProtocolRef));
8015 PTGV->setAlignment(
8016 CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.ProtocolnfABIPtrTy));
8017 PTGV->setSection(
8018 GetSectionName(Section: "__objc_protolist", MachOAttributes: "coalesced,no_dead_strip"));
8019 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8020 CGM.addUsedGlobal(GV: PTGV);
8021 return Entry;
8022}
8023
8024/// EmitProtocolList - Generate protocol list meta-data:
8025/// @code
8026/// struct _protocol_list_t {
8027/// long protocol_count; // Note, this is 32/64 bit
8028/// struct _protocol_t[protocol_count];
8029/// }
8030/// @endcode
8031///
8032llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8033 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8034 ObjCProtocolDecl::protocol_iterator end) {
8035 // Just return null for empty protocol lists
8036 auto Protocols = GetRuntimeProtocolList(begin, end);
8037 if (Protocols.empty())
8038 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListnfABIPtrTy);
8039
8040 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8041 ProtocolRefs.reserve(N: Protocols.size());
8042
8043 for (const auto *PD : Protocols)
8044 ProtocolRefs.push_back(Elt: GetProtocolRef(PD));
8045
8046 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8047 // just return null
8048 if (ProtocolRefs.size() == 0)
8049 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListnfABIPtrTy);
8050
8051 // FIXME: We shouldn't need to do this lookup here, should we?
8052 SmallString<256> TmpName;
8053 Name.toVector(Out&: TmpName);
8054 llvm::GlobalVariable *GV =
8055 CGM.getModule().getGlobalVariable(Name: TmpName.str(), AllowInternal: true);
8056 if (GV)
8057 return GV;
8058
8059 ConstantInitBuilder builder(CGM);
8060 auto values = builder.beginStruct();
8061 auto countSlot = values.addPlaceholder();
8062
8063 // A null-terminated array of protocols.
8064 auto array = values.beginArray(eltTy: ObjCTypes.ProtocolnfABIPtrTy);
8065 for (auto const &proto : ProtocolRefs)
8066 array.add(value: proto);
8067 auto count = array.size();
8068 array.addNullPointer(ptrTy: ObjCTypes.ProtocolnfABIPtrTy);
8069
8070 array.finishAndAddTo(parent&: values);
8071 values.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.LongTy, value: count);
8072
8073 GV = finishAndCreateGlobal(Builder&: values, Name, CGM);
8074 CGM.addCompilerUsedGlobal(GV);
8075 return GV;
8076}
8077
8078/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
8079/// This code gen. amounts to generating code for:
8080/// @code
8081/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
8082/// @encode
8083///
8084LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8085 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8086 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8087 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8088 llvm::Value *Offset = EmitIvarOffset(CGF, Interface: ID, Ivar);
8089 return EmitValueForIvarAtOffset(CGF, OID: ID, BaseValue, Ivar, CVRQualifiers,
8090 Offset);
8091}
8092
8093llvm::Value *
8094CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8095 const ObjCInterfaceDecl *Interface,
8096 const ObjCIvarDecl *Ivar) {
8097 llvm::Value *IvarOffsetValue;
8098 if (isClassLayoutKnownStatically(ID: Interface)) {
8099 IvarOffsetValue = llvm::ConstantInt::get(
8100 Ty: ObjCTypes.IvarOffsetVarTy,
8101 V: ComputeIvarBaseOffset(CGM, OID: Interface->getImplementation(), Ivar));
8102 } else {
8103 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(ID: Interface, Ivar);
8104 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(Ty: GV->getValueType(), Addr: GV,
8105 Align: CGF.getSizeAlign(), Name: "ivar");
8106 if (IsIvarOffsetKnownIdempotent(CGF, IV: Ivar))
8107 cast<llvm::LoadInst>(Val: IvarOffsetValue)
8108 ->setMetadata(KindID: llvm::LLVMContext::MD_invariant_load,
8109 Node: llvm::MDNode::get(Context&: VMContext, MDs: {}));
8110 }
8111
8112 // This could be 32bit int or 64bit integer depending on the architecture.
8113 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8114 // as this is what caller always expects.
8115 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8116 IvarOffsetValue = CGF.Builder.CreateIntCast(
8117 V: IvarOffsetValue, DestTy: ObjCTypes.LongTy, isSigned: true, Name: "ivar.conv");
8118 return IvarOffsetValue;
8119}
8120
8121static void appendSelectorForMessageRefTable(std::string &buffer,
8122 Selector selector) {
8123 if (selector.isUnarySelector()) {
8124 buffer += selector.getNameForSlot(argIndex: 0);
8125 return;
8126 }
8127
8128 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8129 buffer += selector.getNameForSlot(argIndex: i);
8130 buffer += '_';
8131 }
8132}
8133
8134/// Emit a "vtable" message send. We emit a weak hidden-visibility
8135/// struct, initially containing the selector pointer and a pointer to
8136/// a "fixup" variant of the appropriate objc_msgSend. To call, we
8137/// load and call the function pointer, passing the address of the
8138/// struct as the second parameter. The runtime determines whether
8139/// the selector is currently emitted using vtable dispatch; if so, it
8140/// substitutes a stub function which simply tail-calls through the
8141/// appropriate vtable slot, and if not, it substitues a stub function
8142/// which tail-calls objc_msgSend. Both stubs adjust the selector
8143/// argument to correctly point to the selector.
8144RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8145 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8146 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8147 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8148 // Compute the actual arguments.
8149 CallArgList args;
8150
8151 // First argument: the receiver / super-call structure.
8152 if (!isSuper)
8153 arg0 = CGF.Builder.CreateBitCast(V: arg0, DestTy: ObjCTypes.ObjectPtrTy);
8154 args.add(rvalue: RValue::get(V: arg0), type: arg0Type);
8155
8156 // Second argument: a pointer to the message ref structure. Leave
8157 // the actual argument value blank for now.
8158 args.add(rvalue: RValue::get(V: nullptr), type: ObjCTypes.MessageRefCPtrTy);
8159
8160 llvm::append_range(C&: args, R: formalArgs);
8161
8162 MessageSendInfo MSI = getMessageSendInfo(method, resultType, callArgs&: args);
8163
8164 NullReturnState nullReturn;
8165
8166 // Find the function to call and the mangled name for the message
8167 // ref structure. Using a different mangled name wouldn't actually
8168 // be a problem; it would just be a waste.
8169 //
8170 // The runtime currently never uses vtable dispatch for anything
8171 // except normal, non-super message-sends.
8172 // FIXME: don't use this for that.
8173 llvm::FunctionCallee fn = nullptr;
8174 std::string messageRefName("_");
8175 if (CGM.ReturnSlotInterferesWithArgs(FI: MSI.CallInfo)) {
8176 if (isSuper) {
8177 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8178 messageRefName += "objc_msgSendSuper2_stret_fixup";
8179 } else {
8180 nullReturn.init(CGF, receiver: arg0);
8181 fn = ObjCTypes.getMessageSendStretFixupFn();
8182 messageRefName += "objc_msgSend_stret_fixup";
8183 }
8184 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(ResultType: resultType)) {
8185 fn = ObjCTypes.getMessageSendFpretFixupFn();
8186 messageRefName += "objc_msgSend_fpret_fixup";
8187 } else {
8188 if (isSuper) {
8189 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8190 messageRefName += "objc_msgSendSuper2_fixup";
8191 } else {
8192 fn = ObjCTypes.getMessageSendFixupFn();
8193 messageRefName += "objc_msgSend_fixup";
8194 }
8195 }
8196 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
8197 messageRefName += '_';
8198
8199 // Append the selector name, except use underscores anywhere we
8200 // would have used colons.
8201 appendSelectorForMessageRefTable(buffer&: messageRefName, selector);
8202
8203 llvm::GlobalVariable *messageRef =
8204 CGM.getModule().getGlobalVariable(Name: messageRefName);
8205 if (!messageRef) {
8206 // Build the message ref structure.
8207 ConstantInitBuilder builder(CGM);
8208 auto values = builder.beginStruct();
8209 values.add(value: cast<llvm::Constant>(Val: fn.getCallee()));
8210 values.add(value: GetMethodVarName(Sel: selector));
8211 messageRef = values.finishAndCreateGlobal(
8212 args&: messageRefName, args: CharUnits::fromQuantity(Quantity: 16),
8213 /*constant*/ args: false, args: llvm::GlobalValue::WeakAnyLinkage);
8214 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8215 messageRef->setSection(GetSectionName(Section: "__objc_msgrefs", MachOAttributes: "coalesced"));
8216 }
8217
8218 bool requiresnullCheck = false;
8219 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8220 for (const auto *ParamDecl : method->parameters()) {
8221 if (ParamDecl->isDestroyedInCallee()) {
8222 if (!nullReturn.NullBB)
8223 nullReturn.init(CGF, receiver: arg0);
8224 requiresnullCheck = true;
8225 break;
8226 }
8227 }
8228
8229 Address mref =
8230 Address(CGF.Builder.CreateBitCast(V: messageRef, DestTy: ObjCTypes.MessageRefPtrTy),
8231 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8232
8233 // Update the message ref argument.
8234 args[1].setRValue(RValue::get(Addr: mref, CGF));
8235
8236 // Load the function to call from the message ref table.
8237 Address calleeAddr = CGF.Builder.CreateStructGEP(Addr: mref, Index: 0);
8238 llvm::Value *calleePtr = CGF.Builder.CreateLoad(Addr: calleeAddr, Name: "msgSend_fn");
8239
8240 calleePtr = CGF.Builder.CreateBitCast(V: calleePtr, DestTy: MSI.MessengerType);
8241 CGCallee callee(CGCalleeInfo(), calleePtr);
8242
8243 RValue result = CGF.EmitCall(CallInfo: MSI.CallInfo, Callee: callee, ReturnValue: returnSlot, Args: args);
8244 return nullReturn.complete(CGF, returnSlot, result, resultType, CallArgs: formalArgs,
8245 Method: requiresnullCheck ? method : nullptr);
8246}
8247
8248/// Generate code for a message send expression in the nonfragile abi.
8249CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8250 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8251 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8252 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8253 return isVTableDispatchedSelector(Sel)
8254 ? EmitVTableMessageSend(CGF, returnSlot: Return, resultType: ResultType, selector: Sel, arg0: Receiver,
8255 arg0Type: CGF.getContext().getObjCIdType(), isSuper: false,
8256 formalArgs: CallArgs, method: Method)
8257 : EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: Receiver,
8258 Arg0Ty: CGF.getContext().getObjCIdType(), IsSuper: false,
8259 CallArgs, Method, ClassReceiver: Class, ObjCTypes);
8260}
8261
8262llvm::Constant *
8263CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8264 bool metaclass,
8265 ForDefinition_t isForDefinition) {
8266 auto prefix =
8267 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8268 return GetClassGlobal(Name: (prefix + ID->getObjCRuntimeNameAsString()).str(),
8269 IsForDefinition: isForDefinition, Weak: ID->isWeakImported(),
8270 DLLImport: !isForDefinition &&
8271 CGM.getTriple().isOSBinFormatCOFF() &&
8272 ID->hasAttr<DLLImportAttr>());
8273}
8274
8275llvm::Constant *
8276CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8277 ForDefinition_t IsForDefinition,
8278 bool Weak, bool DLLImport) {
8279 llvm::GlobalValue::LinkageTypes L =
8280 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8281 : llvm::GlobalValue::ExternalLinkage;
8282
8283 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8284 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8285 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8286 nullptr, Name);
8287
8288 if (DLLImport)
8289 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8290
8291 if (GV) {
8292 GV->replaceAllUsesWith(V: NewGV);
8293 GV->eraseFromParent();
8294 }
8295 GV = NewGV;
8296 CGM.getModule().insertGlobalVariable(GV);
8297 }
8298
8299 assert(GV->getLinkage() == L);
8300 return GV;
8301}
8302
8303llvm::Constant *
8304CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8305 llvm::Constant *ClassGV =
8306 GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition);
8307
8308 if (!ID->hasAttr<ObjCClassStubAttr>())
8309 return ClassGV;
8310
8311 ClassGV = llvm::ConstantExpr::getPointerCast(C: ClassGV, Ty: ObjCTypes.Int8PtrTy);
8312
8313 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8314 // must set the least significant bit set to 1.
8315 auto *Idx = llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 1);
8316 return llvm::ConstantExpr::getPtrAdd(Ptr: ClassGV, Offset: Idx);
8317}
8318
8319llvm::Value *
8320CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8321 const ObjCInterfaceDecl *ID,
8322 llvm::GlobalVariable *Entry) {
8323 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8324 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8325 // a special runtime function.
8326 return CGF.EmitRuntimeCall(callee: ObjCTypes.getLoadClassrefFn(), args: Entry,
8327 name: "load_classref_result");
8328 }
8329
8330 CharUnits Align = CGF.getPointerAlign();
8331 return CGF.Builder.CreateAlignedLoad(Ty: Entry->getValueType(), Addr: Entry, Align);
8332}
8333
8334llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8335 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8336 llvm::GlobalVariable *&Entry = ClassReferences[II];
8337
8338 if (!Entry) {
8339 llvm::Constant *ClassGV;
8340 if (ID) {
8341 ClassGV = GetClassGlobalForClassRef(ID);
8342 } else {
8343 ClassGV = GetClassGlobal(Name: (getClassSymbolPrefix() + II->getName()).str(),
8344 IsForDefinition: NotForDefinition);
8345 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8346 "classref was emitted with the wrong type?");
8347 }
8348
8349 std::string SectionName =
8350 GetSectionName(Section: "__objc_classrefs", MachOAttributes: "regular,no_dead_strip");
8351 Entry = new llvm::GlobalVariable(
8352 CGM.getModule(), ClassGV->getType(), false,
8353 getLinkageTypeForObjCMetadata(CGM, Section: SectionName), ClassGV,
8354 "OBJC_CLASSLIST_REFERENCES_$_");
8355 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8356 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8357 Entry->setSection(SectionName);
8358
8359 CGM.addCompilerUsedGlobal(GV: Entry);
8360 }
8361
8362 return EmitLoadOfClassRef(CGF, ID, Entry);
8363}
8364
8365llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8366 const ObjCInterfaceDecl *ID) {
8367 // If the class has the objc_runtime_visible attribute, we need to
8368 // use the Objective-C runtime to get the class.
8369 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8370 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8371
8372 return EmitClassRefFromId(CGF, II: ID->getIdentifier(), ID);
8373}
8374
8375llvm::Value *
8376CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8377 IdentifierInfo *II = &CGM.getContext().Idents.get(Name: "NSAutoreleasePool");
8378 return EmitClassRefFromId(CGF, II, ID: nullptr);
8379}
8380
8381llvm::Value *
8382CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8383 const ObjCInterfaceDecl *ID) {
8384 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8385
8386 if (!Entry) {
8387 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8388 std::string SectionName =
8389 GetSectionName(Section: "__objc_superrefs", MachOAttributes: "regular,no_dead_strip");
8390 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8391 llvm::GlobalValue::PrivateLinkage, ClassGV,
8392 "OBJC_CLASSLIST_SUP_REFS_$_");
8393 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8394 Entry->setSection(SectionName);
8395 CGM.addCompilerUsedGlobal(GV: Entry);
8396 }
8397
8398 return EmitLoadOfClassRef(CGF, ID, Entry);
8399}
8400
8401/// EmitMetaClassRef - Return a Value * of the address of _class_t
8402/// meta-data
8403///
8404llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8405 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8406 CharUnits Align = CGF.getPointerAlign();
8407 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8408 if (!Entry) {
8409 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, isForDefinition: NotForDefinition);
8410 std::string SectionName =
8411 GetSectionName(Section: "__objc_superrefs", MachOAttributes: "regular,no_dead_strip");
8412 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8413 false, llvm::GlobalValue::PrivateLinkage,
8414 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
8415 Entry->setAlignment(Align.getAsAlign());
8416 Entry->setSection(SectionName);
8417 CGM.addCompilerUsedGlobal(GV: Entry);
8418 }
8419
8420 return CGF.Builder.CreateAlignedLoad(Ty: ObjCTypes.ClassnfABIPtrTy, Addr: Entry, Align);
8421}
8422
8423/// GetClass - Return a reference to the class for the given interface
8424/// decl.
8425llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8426 const ObjCInterfaceDecl *ID) {
8427 if (ID->isWeakImported()) {
8428 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition);
8429 (void)ClassGV;
8430 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8431 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8432 }
8433
8434 return EmitClassRef(CGF, ID);
8435}
8436
8437/// Generates a message send where the super is the receiver. This is
8438/// a message send to self with special delivery semantics indicating
8439/// which class's method should be called.
8440CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8441 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8442 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8443 llvm::Value *Receiver, bool IsClassMessage,
8444 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8445 // ...
8446 // Create and init a super structure; this is a (receiver, class)
8447 // pair we will pass to objc_msgSendSuper.
8448 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8449 Ty: ObjCTypes.SuperTy, align: CGF.getPointerAlign(), Name: "objc_super");
8450
8451 llvm::Value *ReceiverAsObject =
8452 CGF.Builder.CreateBitCast(V: Receiver, DestTy: ObjCTypes.ObjectPtrTy);
8453 CGF.Builder.CreateStore(Val: ReceiverAsObject,
8454 Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 0));
8455
8456 // If this is a class message the metaclass is passed as the target.
8457 llvm::Value *Target;
8458 if (IsClassMessage)
8459 Target = EmitMetaClassRef(CGF, ID: Class, Weak: Class->isWeakImported());
8460 else
8461 Target = EmitSuperClassRef(CGF, ID: Class);
8462
8463 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8464 // ObjCTypes types.
8465 llvm::Type *ClassTy =
8466 CGM.getTypes().ConvertType(T: CGF.getContext().getObjCClassType());
8467 Target = CGF.Builder.CreateBitCast(V: Target, DestTy: ClassTy);
8468 CGF.Builder.CreateStore(Val: Target, Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 1));
8469
8470 return (isVTableDispatchedSelector(Sel))
8471 ? EmitVTableMessageSend(
8472 CGF, returnSlot: Return, resultType: ResultType, selector: Sel, arg0: ObjCSuper.getPointer(),
8473 arg0Type: ObjCTypes.SuperPtrCTy, isSuper: true, formalArgs: CallArgs, method: Method)
8474 : EmitMessageSend(CGF, Return, ResultType, Sel,
8475 Arg0: ObjCSuper.getPointer(), Arg0Ty: ObjCTypes.SuperPtrCTy,
8476 IsSuper: true, CallArgs, Method, ClassReceiver: Class, ObjCTypes);
8477}
8478
8479llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8480 Selector Sel) {
8481 Address Addr = EmitSelectorAddr(Sel);
8482
8483 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8484 LI->setMetadata(KindID: llvm::LLVMContext::MD_invariant_load,
8485 Node: llvm::MDNode::get(Context&: VMContext, MDs: {}));
8486 return LI;
8487}
8488
8489ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8490 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8491 CharUnits Align = CGM.getPointerAlign();
8492 if (!Entry) {
8493 std::string SectionName =
8494 GetSectionName(Section: "__objc_selrefs", MachOAttributes: "literal_pointers,no_dead_strip");
8495 Entry = new llvm::GlobalVariable(
8496 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8497 getLinkageTypeForObjCMetadata(CGM, Section: SectionName), GetMethodVarName(Sel),
8498 "OBJC_SELECTOR_REFERENCES_");
8499 Entry->setExternallyInitialized(true);
8500 Entry->setSection(SectionName);
8501 Entry->setAlignment(Align.getAsAlign());
8502 CGM.addCompilerUsedGlobal(GV: Entry);
8503 }
8504
8505 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8506}
8507
8508/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
8509/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
8510///
8511void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8512 llvm::Value *src, Address dst,
8513 llvm::Value *ivarOffset) {
8514 llvm::Type *SrcTy = src->getType();
8515 if (!isa<llvm::PointerType>(Val: SrcTy)) {
8516 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
8517 assert(Size <= 8 && "does not support size > 8");
8518 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
8519 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
8520 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
8521 }
8522 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
8523 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
8524 DestTy: ObjCTypes.PtrObjectPtrTy);
8525 llvm::Value *args[] = {src, dstVal, ivarOffset};
8526 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignIvarFn(), args);
8527}
8528
8529/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
8530/// objc_assign_strongCast (id src, id *dst)
8531///
8532void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8533 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8534 llvm::Type *SrcTy = src->getType();
8535 if (!isa<llvm::PointerType>(Val: SrcTy)) {
8536 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
8537 assert(Size <= 8 && "does not support size > 8");
8538 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
8539 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
8540 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
8541 }
8542 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
8543 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
8544 DestTy: ObjCTypes.PtrObjectPtrTy);
8545 llvm::Value *args[] = {src, dstVal};
8546 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignStrongCastFn(), args,
8547 name: "weakassign");
8548}
8549
8550void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8551 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8552 llvm::Value *Size) {
8553 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8554 SrcPtr.emitRawPointer(CGF), Size};
8555 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.GcMemmoveCollectableFn(), args);
8556}
8557
8558/// EmitObjCWeakRead - Code gen for loading value of a __weak
8559/// object: objc_read_weak (id *src)
8560///
8561llvm::Value *
8562CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8563 Address AddrWeakObj) {
8564 llvm::Type *DestTy = AddrWeakObj.getElementType();
8565 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8566 V: AddrWeakObj.emitRawPointer(CGF), DestTy: ObjCTypes.PtrObjectPtrTy);
8567 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8568 callee: ObjCTypes.getGcReadWeakFn(), args: AddrWeakObjVal, name: "weakread");
8569 read_weak = CGF.Builder.CreateBitCast(V: read_weak, DestTy);
8570 return read_weak;
8571}
8572
8573/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
8574/// objc_assign_weak (id src, id *dst)
8575///
8576void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8577 llvm::Value *src, Address dst) {
8578 llvm::Type *SrcTy = src->getType();
8579 if (!isa<llvm::PointerType>(Val: SrcTy)) {
8580 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
8581 assert(Size <= 8 && "does not support size > 8");
8582 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
8583 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
8584 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
8585 }
8586 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
8587 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
8588 DestTy: ObjCTypes.PtrObjectPtrTy);
8589 llvm::Value *args[] = {src, dstVal};
8590 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignWeakFn(), args,
8591 name: "weakassign");
8592}
8593
8594/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
8595/// objc_assign_global (id src, id *dst)
8596///
8597void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8598 llvm::Value *src, Address dst,
8599 bool threadlocal) {
8600 llvm::Type *SrcTy = src->getType();
8601 if (!isa<llvm::PointerType>(Val: SrcTy)) {
8602 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
8603 assert(Size <= 8 && "does not support size > 8");
8604 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
8605 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
8606 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
8607 }
8608 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
8609 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
8610 DestTy: ObjCTypes.PtrObjectPtrTy);
8611 llvm::Value *args[] = {src, dstVal};
8612 if (!threadlocal)
8613 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignGlobalFn(), args,
8614 name: "globalassign");
8615 else
8616 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignThreadLocalFn(), args,
8617 name: "threadlocalassign");
8618}
8619
8620void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8621 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8622 EmitAtSynchronizedStmt(CGF, S, syncEnterFn: ObjCTypes.getSyncEnterFn(),
8623 syncExitFn: ObjCTypes.getSyncExitFn());
8624}
8625
8626llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8627 // There's a particular fixed type info for 'id'.
8628 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8629 auto *IDEHType = CGM.getModule().getGlobalVariable(Name: "OBJC_EHTYPE_id");
8630 if (!IDEHType) {
8631 IDEHType = new llvm::GlobalVariable(
8632 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8633 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id");
8634 if (CGM.getTriple().isOSBinFormatCOFF())
8635 IDEHType->setDLLStorageClass(getStorage(CGM, Name: "OBJC_EHTYPE_id"));
8636 }
8637 return IDEHType;
8638 }
8639
8640 // All other types should be Objective-C interface pointer types.
8641 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8642 assert(PT && "Invalid @catch type.");
8643
8644 const ObjCInterfaceType *IT = PT->getInterfaceType();
8645 assert(IT && "Invalid @catch type.");
8646
8647 return GetInterfaceEHType(ID: IT->getDecl(), IsForDefinition: NotForDefinition);
8648}
8649
8650void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8651 const ObjCAtTryStmt &S) {
8652 EmitTryCatchStmt(CGF, S, beginCatchFn: ObjCTypes.getObjCBeginCatchFn(),
8653 endCatchFn: ObjCTypes.getObjCEndCatchFn(),
8654 exceptionRethrowFn: ObjCTypes.getExceptionRethrowFn());
8655}
8656
8657/// EmitThrowStmt - Generate code for a throw statement.
8658void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8659 const ObjCAtThrowStmt &S,
8660 bool ClearInsertionPoint) {
8661 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8662 llvm::Value *Exception = CGF.EmitObjCThrowOperand(expr: ThrowExpr);
8663 Exception = CGF.Builder.CreateBitCast(V: Exception, DestTy: ObjCTypes.ObjectPtrTy);
8664 llvm::CallBase *Call =
8665 CGF.EmitRuntimeCallOrInvoke(callee: ObjCTypes.getExceptionThrowFn(), args: Exception);
8666 Call->setDoesNotReturn();
8667 } else {
8668 llvm::CallBase *Call =
8669 CGF.EmitRuntimeCallOrInvoke(callee: ObjCTypes.getExceptionRethrowFn());
8670 Call->setDoesNotReturn();
8671 }
8672
8673 CGF.Builder.CreateUnreachable();
8674 if (ClearInsertionPoint)
8675 CGF.Builder.ClearInsertionPoint();
8676}
8677
8678llvm::Constant *
8679CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8680 ForDefinition_t IsForDefinition) {
8681 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8682 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8683
8684 // If we don't need a definition, return the entry if found or check
8685 // if we use an external reference.
8686 if (!IsForDefinition) {
8687 if (Entry)
8688 return Entry;
8689
8690 // If this type (or a super class) has the __objc_exception__
8691 // attribute, emit an external reference.
8692 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: ID)) {
8693 std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();
8694 Entry = new llvm::GlobalVariable(
8695 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8696 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8697 CGM.setGVProperties(GV: Entry, D: ID);
8698 return Entry;
8699 }
8700 }
8701
8702 // Otherwise we need to either make a new entry or fill in the initializer.
8703 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
8704
8705 std::string VTableName = "objc_ehtype_vtable";
8706 auto *VTableGV = CGM.getModule().getGlobalVariable(Name: VTableName);
8707 if (!VTableGV) {
8708 VTableGV = new llvm::GlobalVariable(
8709 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8710 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8711 if (CGM.getTriple().isOSBinFormatCOFF())
8712 VTableGV->setDLLStorageClass(getStorage(CGM, Name: VTableName));
8713 }
8714
8715 llvm::Value *VTableIdx = llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 2);
8716 llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(
8717 Ty: VTableGV->getValueType(), C: VTableGV, IdxList: VTableIdx);
8718
8719 ConstantInitBuilder builder(CGM);
8720 auto values = builder.beginStruct(structTy: ObjCTypes.EHTypeTy);
8721 const PointerAuthSchema &TypeInfoSchema =
8722 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8723 values.addSignedPointer(Pointer: VTablePtr, Schema: TypeInfoSchema, CalleeDecl: GlobalDecl(), CalleeType: QualType());
8724
8725 values.add(value: GetClassName(RuntimeName: ClassName));
8726 values.add(value: GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition));
8727
8728 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8729 ? llvm::GlobalValue::ExternalLinkage
8730 : llvm::GlobalValue::WeakAnyLinkage;
8731 if (Entry) {
8732 values.finishAndSetAsInitializer(global: Entry);
8733 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8734 } else {
8735 Entry = values.finishAndCreateGlobal(args: "OBJC_EHTYPE_$_" + ClassName,
8736 args: CGM.getPointerAlign(),
8737 /*constant*/ args: false, args&: L);
8738 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: ID))
8739 CGM.setGVProperties(GV: Entry, D: ID);
8740 }
8741 assert(Entry->getLinkage() == L);
8742
8743 if (!CGM.getTriple().isOSBinFormatCOFF())
8744 if (ID->getVisibility() == HiddenVisibility)
8745 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8746
8747 if (IsForDefinition)
8748 if (CGM.getTriple().isOSBinFormatMachO())
8749 Entry->setSection("__DATA,__objc_const");
8750
8751 return Entry;
8752}
8753
8754/* *** */
8755
8756CodeGen::CGObjCRuntime *
8757CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8758 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8759 case ObjCRuntime::FragileMacOSX:
8760 return new CGObjCMac(CGM);
8761
8762 case ObjCRuntime::MacOSX:
8763 case ObjCRuntime::iOS:
8764 case ObjCRuntime::WatchOS:
8765 return new CGObjCNonFragileABIMac(CGM);
8766
8767 case ObjCRuntime::GNUstep:
8768 case ObjCRuntime::GCC:
8769 case ObjCRuntime::ObjFW:
8770 llvm_unreachable("these runtimes are not Mac runtimes");
8771 }
8772 llvm_unreachable("bad runtime");
8773}
8774
8775// Public wrapper function for external compilers (e.g., Swift) to access
8776// the Mac runtime's GetDirectMethodCallee functionality.
8777llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8778 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8779 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8780 // This function should only be called when targeting Darwin platforms,
8781 // which always use the Mac runtime.
8782 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8783 "getObjCDirectMethodCallee requires Mac ObjC runtime");
8784 CGObjCCommonMac *MacRuntime =
8785 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8786 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8787 ClassObjectCanBeUnrealized);
8788}
8789