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/// getConstantGEP() - Help routine to construct simple GEPs.
1976static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1977 llvm::GlobalVariable *C, unsigned idx0,
1978 unsigned idx1) {
1979 llvm::Value *Idxs[] = {
1980 llvm::ConstantInt::get(Ty: llvm::Type::getInt32Ty(C&: VMContext), V: idx0),
1981 llvm::ConstantInt::get(Ty: llvm::Type::getInt32Ty(C&: VMContext), V: idx1)};
1982 return llvm::ConstantExpr::getGetElementPtr(Ty: C->getValueType(), C, IdxList: Idxs);
1983}
1984
1985/// hasObjCExceptionAttribute - Return true if this class or any super
1986/// class has the __objc_exception__ attribute.
1987static bool hasObjCExceptionAttribute(ASTContext &Context,
1988 const ObjCInterfaceDecl *OID) {
1989 if (OID->hasAttr<ObjCExceptionAttr>())
1990 return true;
1991 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1992 return hasObjCExceptionAttribute(Context, OID: Super);
1993 return false;
1994}
1995
1996static llvm::GlobalValue::LinkageTypes
1997getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) {
1998 if (CGM.getTriple().isOSBinFormatMachO() &&
1999 (Section.empty() || Section.starts_with(Prefix: "__DATA")))
2000 return llvm::GlobalValue::InternalLinkage;
2001 return llvm::GlobalValue::PrivateLinkage;
2002}
2003
2004/// A helper function to create an internal or private global variable.
2005static llvm::GlobalVariable *
2006finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder,
2007 const llvm::Twine &Name, CodeGenModule &CGM) {
2008 std::string SectionName;
2009 if (CGM.getTriple().isOSBinFormatMachO())
2010 SectionName = "__DATA, __objc_const";
2011 auto *GV = Builder.finishAndCreateGlobal(
2012 args: Name, args: CGM.getPointerAlign(), /*constant*/ args: false,
2013 args: getLinkageTypeForObjCMetadata(CGM, Section: SectionName));
2014 GV->setSection(SectionName);
2015 return GV;
2016}
2017
2018/* *** CGObjCMac Public Interface *** */
2019
2020CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
2021 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2022 ObjCABI = 1;
2023 EmitImageInfo();
2024}
2025
2026/// GetClass - Return a reference to the class for the given interface
2027/// decl.
2028llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
2029 const ObjCInterfaceDecl *ID) {
2030 return EmitClassRef(CGF, ID);
2031}
2032
2033/// GetSelector - Return the pointer to the unique'd string for this selector.
2034llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2035 return EmitSelector(CGF, Sel);
2036}
2037Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2038 return EmitSelectorAddr(Sel);
2039}
2040llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2041 const ObjCMethodDecl *Method) {
2042 return EmitSelector(CGF, Sel: Method->getSelector());
2043}
2044
2045llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2046 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
2047 return CGM.GetAddrOfRTTIDescriptor(
2048 Ty: CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
2049 }
2050 if (T->isObjCClassType() || T->isObjCQualifiedClassType()) {
2051 return CGM.GetAddrOfRTTIDescriptor(
2052 Ty: CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
2053 }
2054 if (T->isObjCObjectPointerType())
2055 return CGM.GetAddrOfRTTIDescriptor(Ty: T, /*ForEH=*/true);
2056
2057 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
2058}
2059
2060/// Generate a constant CFString object.
2061/*
2062 struct __builtin_CFString {
2063 const int *isa; // point to __CFConstantStringClassReference
2064 int flags;
2065 const char *str;
2066 long length;
2067 };
2068*/
2069
2070/// or Generate a constant NSString object.
2071/*
2072 struct __builtin_NSString {
2073 const int *isa; // point to __NSConstantStringClassReference
2074 const char *str;
2075 unsigned int length;
2076 };
2077*/
2078
2079ConstantAddress
2080CGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {
2081 return (!CGM.getLangOpts().NoConstantCFStrings
2082 ? CGM.GetAddrOfConstantCFString(Literal: SL)
2083 : GenerateConstantNSString(SL));
2084}
2085
2086ConstantAddress CGObjCCommonMac::GenerateConstantNumber(const bool Value,
2087 const QualType &Ty) {
2088 return GenerateConstantNSNumber(Value, Ty);
2089}
2090
2091ConstantAddress
2092CGObjCCommonMac::GenerateConstantNumber(const llvm::APSInt &Value,
2093 const QualType &Ty) {
2094 return GenerateConstantNSNumber(Value, Ty);
2095}
2096
2097ConstantAddress
2098CGObjCCommonMac::GenerateConstantNumber(const llvm::APFloat &Value,
2099 const QualType &Ty) {
2100 return GenerateConstantNSNumber(Value, Ty);
2101}
2102
2103ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2104 const ArrayRef<llvm::Constant *> &Objects) {
2105 return GenerateConstantNSArray(Objects);
2106}
2107
2108ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2109 const ObjCDictionaryLiteral *E,
2110 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2111 return GenerateConstantNSDictionary(E, KeysAndObjects);
2112}
2113
2114static llvm::StringMapEntry<llvm::GlobalVariable *> &
2115GetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
2116 const StringLiteral *Literal, unsigned &StringLength) {
2117 StringRef String = Literal->getString();
2118 StringLength = String.size();
2119 return *Map.insert(KV: std::make_pair(x&: String, y: nullptr)).first;
2120}
2121
2122llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2123 if (llvm::Value *V = ConstantStringClassRef)
2124 return cast<llvm::Constant>(Val: V);
2125
2126 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2127 std::string str = StringClass.empty() ? "_NSConstantStringClassReference"
2128 : "_" + StringClass + "ClassReference";
2129
2130 llvm::Type *PTy = llvm::ArrayType::get(ElementType: CGM.IntTy, NumElements: 0);
2131 auto GV = CGM.CreateRuntimeVariable(Ty: PTy, Name: str);
2132 ConstantStringClassRef = GV;
2133 return GV;
2134}
2135
2136llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2137 llvm_unreachable("constant array literals not supported for fragile ABI");
2138}
2139
2140llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2141 llvm_unreachable("constant dictionary literals not supported for fragile "
2142 "ABI");
2143}
2144
2145llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2146 llvm_unreachable("constant number literals not supported for fragile ABI");
2147}
2148
2149llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2150 llvm_unreachable("constant number literals not supported for fragile ABI");
2151}
2152
2153llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2154 llvm_unreachable("constant number literals not supported for fragile ABI");
2155}
2156
2157llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2158 if (llvm::Value *V = ConstantStringClassRef)
2159 return cast<llvm::Constant>(Val: V);
2160
2161 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2162 std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
2163 : "OBJC_CLASS_$_" + StringClass;
2164 llvm::Constant *GV = GetClassGlobal(Name: str, IsForDefinition: NotForDefinition);
2165 ConstantStringClassRef = GV;
2166 return GV;
2167}
2168
2169llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2170 if (llvm::Value *V = ConstantArrayClassRef)
2171 return cast<llvm::Constant>(Val: V);
2172
2173 const std::string &ArrayClass = CGM.getLangOpts().ObjCConstantArrayClass;
2174 std::string Str = ArrayClass.empty() ? "OBJC_CLASS_$_NSConstantArray"
2175 : "OBJC_CLASS_$_" + ArrayClass;
2176 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2177
2178 ConstantArrayClassRef = GV;
2179 return GV;
2180}
2181
2182llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2183 if (llvm::Value *V = ConstantDictionaryClassRef)
2184 return cast<llvm::Constant>(Val: V);
2185
2186 const std::string &DictionaryClass =
2187 CGM.getLangOpts().ObjCConstantDictionaryClass;
2188 std::string Str = DictionaryClass.empty()
2189 ? "OBJC_CLASS_$_NSConstantDictionary"
2190 : "OBJC_CLASS_$_" + DictionaryClass;
2191 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2192
2193 ConstantDictionaryClassRef = GV;
2194 return GV;
2195}
2196
2197llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2198 if (llvm::Value *V = ConstantIntegerNumberClassRef)
2199 return cast<llvm::Constant>(Val: V);
2200
2201 const std::string &NumberClass =
2202 CGM.getLangOpts().ObjCConstantIntegerNumberClass;
2203 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantIntegerNumber"
2204 : "OBJC_CLASS_$_" + NumberClass;
2205 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2206
2207 ConstantIntegerNumberClassRef = GV;
2208 return GV;
2209}
2210
2211llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2212 if (llvm::Value *V = ConstantFloatNumberClassRef)
2213 return cast<llvm::Constant>(Val: V);
2214
2215 const std::string &NumberClass =
2216 CGM.getLangOpts().ObjCConstantFloatNumberClass;
2217 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantFloatNumber"
2218 : "OBJC_CLASS_$_" + NumberClass;
2219 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2220
2221 ConstantFloatNumberClassRef = GV;
2222 return GV;
2223}
2224
2225llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2226 if (llvm::Value *V = ConstantDoubleNumberClassRef)
2227 return cast<llvm::Constant>(Val: V);
2228
2229 const std::string &NumberClass =
2230 CGM.getLangOpts().ObjCConstantDoubleNumberClass;
2231 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantDoubleNumber"
2232 : "OBJC_CLASS_$_" + NumberClass;
2233 llvm::Constant *GV = GetClassGlobal(Name: Str, IsForDefinition: NotForDefinition);
2234
2235 ConstantDoubleNumberClassRef = GV;
2236 return GV;
2237}
2238
2239ConstantAddress
2240CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {
2241 unsigned StringLength = 0;
2242 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2243 GetConstantStringEntry(Map&: NSConstantStringMap, Literal, StringLength);
2244
2245 if (auto *C = Entry.second)
2246 return ConstantAddress(C, C->getValueType(),
2247 CharUnits::fromQuantity(Quantity: C->getAlignment()));
2248
2249 // If we don't already have it, get _NSConstantStringClassReference.
2250 llvm::Constant *Class = getNSConstantStringClassRef();
2251
2252 // If we don't already have it, construct the type for a constant NSString.
2253 if (!NSConstantStringType) {
2254 // NOTE: The existing implementation used a pointer to a Int32Ty not a
2255 // struct pointer as the ISA type when emitting constant strings so this is
2256 // maintained for now
2257 NSConstantStringType =
2258 llvm::StructType::create(Elements: {CGM.DefaultPtrTy, CGM.Int8PtrTy, CGM.IntTy},
2259 Name: "struct.__builtin_NSString");
2260 }
2261
2262 ConstantInitBuilder Builder(CGM);
2263 auto Fields = Builder.beginStruct(structTy: NSConstantStringType);
2264
2265 // Class pointer.
2266 Fields.addSignedPointer(Pointer: Class,
2267 Schema: CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,
2268 CalleeDecl: GlobalDecl(), CalleeType: QualType());
2269
2270 // String pointer.
2271 llvm::Constant *C =
2272 llvm::ConstantDataArray::getString(Context&: VMContext, Initializer: Entry.first());
2273
2274 llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;
2275 bool isConstant = !CGM.getLangOpts().WritableStrings;
2276
2277 auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
2278 Linkage, C, ".str");
2279 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2280 // Don't enforce the target's minimum global alignment, since the only use
2281 // of the string is via this class initializer.
2282 GV->setAlignment(llvm::Align(1));
2283 Fields.add(value: GV);
2284
2285 // String length.
2286 Fields.addInt(intTy: CGM.IntTy, value: StringLength);
2287
2288 // The struct.
2289 CharUnits Alignment = CGM.getPointerAlign();
2290 GV = Fields.finishAndCreateGlobal(args: "_unnamed_nsstring_", args&: Alignment,
2291 /*constant*/ args: true,
2292 args: llvm::GlobalVariable::PrivateLinkage);
2293 const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
2294 const char *NSStringNonFragileABISection =
2295 "__DATA,__objc_stringobj,regular,no_dead_strip";
2296 // FIXME. Fix section.
2297 GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
2298 ? NSStringNonFragileABISection
2299 : NSStringSection);
2300 Entry.second = GV;
2301
2302 return ConstantAddress(GV, GV->getValueType(), Alignment);
2303}
2304
2305/// Emit the boolean singletons for BOOL literals @YES @NO
2306ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value,
2307 const QualType &Ty) {
2308 llvm::GlobalVariable *Val =
2309 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2310 return ConstantAddress(Val, Val->getValueType(), CGM.getPointerAlign());
2311}
2312
2313/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal
2314/*
2315 struct __builtin_NSConstantIntegerNumber {
2316 struct._class_t *isa; // point to _NSConstantIntegerNumberClassReference
2317 char const *const _encoding;
2318 long long const _value;
2319 };
2320*/
2321ConstantAddress
2322CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value,
2323 const QualType &Ty) {
2324 CharUnits Alignment = CGM.getPointerAlign();
2325
2326 // check if we've already emitted, if so emit a reference to it
2327 llvm::GlobalVariable *&Entry =
2328 NSConstantNumberMap[{CGM.getContext().getCanonicalType(T: Ty), Value}];
2329 if (Entry) {
2330 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2331 }
2332
2333 // The encoding type
2334 std::string ObjCEncodingType;
2335 CodeGenFunction(CGM).getContext().getObjCEncodingForType(T: Ty,
2336 S&: ObjCEncodingType);
2337
2338 llvm::Constant *const Class = getNSConstantIntegerNumberClassRef();
2339
2340 if (!NSConstantIntegerNumberType) {
2341 NSConstantIntegerNumberType = llvm::StructType::create(
2342 Elements: {
2343 CGM.DefaultPtrTy, // isa
2344 CGM.Int8PtrTy, // _encoding
2345 CGM.Int64Ty, // _value
2346 },
2347 Name: "struct.__builtin_NSConstantIntegerNumber");
2348 }
2349
2350 ConstantInitBuilder Builder(CGM);
2351 auto Fields = Builder.beginStruct(structTy: NSConstantIntegerNumberType);
2352
2353 // Class pointer.
2354 Fields.add(value: Class);
2355
2356 // add the @encode
2357 Fields.add(value: CGM.GetAddrOfConstantCString(Str: ObjCEncodingType).getPointer());
2358
2359 // add the value stored.
2360 llvm::Constant *IntegerValue =
2361 llvm::ConstantInt::get(Ty: CGM.Int64Ty, V: Value.extOrTrunc(width: 64));
2362
2363 Fields.add(value: IntegerValue);
2364
2365 // The struct
2366 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2367 args: "_unnamed_nsconstantintegernumber_", args&: Alignment,
2368 /* constant */ args: true, args: llvm::GlobalVariable::PrivateLinkage);
2369
2370 GV->setSection(GetNSConstantIntegerNumberSectionName());
2371 GV->addAttribute(Kind: "objc_arc_inert");
2372
2373 Entry = GV;
2374
2375 return ConstantAddress(GV, GV->getValueType(), Alignment);
2376}
2377
2378/// Generate either a constant NSConstantFloatNumber or NSConstantDoubleNumber
2379/*
2380 struct __builtin_NSConstantFloatNumber {
2381 struct._class_t *isa;
2382 float const _value;
2383 };
2384
2385 struct __builtin_NSConstantDoubleNumber {
2386 struct._class_t *isa;
2387 double const _value;
2388 };
2389*/
2390ConstantAddress
2391CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value,
2392 const QualType &Ty) {
2393 CharUnits Alignment = CGM.getPointerAlign();
2394
2395 // check if we've already emitted, if so emit a reference to it
2396 llvm::GlobalVariable *&Entry =
2397 NSConstantNumberMap[{CGM.getContext().getCanonicalType(T: Ty), Value}];
2398 if (Entry) {
2399 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2400 }
2401
2402 // @encode type used to pick which class type to use
2403 std::string ObjCEncodingType;
2404 CodeGenFunction(CGM).getContext().getObjCEncodingForType(T: Ty,
2405 S&: ObjCEncodingType);
2406
2407 assert((ObjCEncodingType == "d" || ObjCEncodingType == "f") &&
2408 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2409
2410 llvm::GlobalValue::LinkageTypes Linkage =
2411 llvm::GlobalVariable::PrivateLinkage;
2412
2413 // Handle floats
2414 if (ObjCEncodingType == "f") {
2415 llvm::Constant *const Class = getNSConstantFloatNumberClassRef();
2416
2417 if (!NSConstantFloatNumberType) {
2418 NSConstantFloatNumberType = llvm::StructType::create(
2419 Elements: {
2420 CGM.DefaultPtrTy, // isa
2421 CGM.FloatTy, // _value
2422 },
2423 Name: "struct.__builtin_NSConstantFloatNumber");
2424 }
2425
2426 ConstantInitBuilder Builder(CGM);
2427 auto Fields = Builder.beginStruct(structTy: NSConstantFloatNumberType);
2428
2429 // Class pointer.
2430 Fields.add(value: Class);
2431
2432 // add the value stored.
2433 llvm::Constant *FV = llvm::ConstantFP::get(Ty: CGM.FloatTy, V: Value);
2434 Fields.add(value: FV);
2435
2436 // The struct
2437 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2438 args: "_unnamed_nsconstantfloatnumber_", args&: Alignment,
2439 /*constant*/ args: true, args&: Linkage);
2440
2441 GV->setSection(GetNSConstantFloatNumberSectionName());
2442 GV->addAttribute(Kind: "objc_arc_inert");
2443
2444 Entry = GV;
2445
2446 return ConstantAddress(GV, GV->getValueType(), Alignment);
2447 }
2448
2449 llvm::Constant *const Class = getNSConstantDoubleNumberClassRef();
2450 if (!NSConstantDoubleNumberType) {
2451 // NOTE: this will be padded on some 32-bit targets and is expected
2452 NSConstantDoubleNumberType = llvm::StructType::create(
2453 Elements: {
2454 CGM.DefaultPtrTy, // isa
2455 CGM.DoubleTy, // _value
2456 },
2457 Name: "struct.__builtin_NSConstantDoubleNumber");
2458 }
2459
2460 ConstantInitBuilder Builder(CGM);
2461 auto Fields = Builder.beginStruct(structTy: NSConstantDoubleNumberType);
2462
2463 // Class pointer.
2464 Fields.add(value: Class);
2465
2466 // add the value stored.
2467 llvm::Constant *DV = llvm::ConstantFP::get(Ty: CGM.DoubleTy, V: Value);
2468 Fields.add(value: DV);
2469
2470 // The struct
2471 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2472 args: "_unnamed_nsconstantdoublenumber_", args&: Alignment,
2473 /*constant*/ args: true, args&: Linkage);
2474
2475 GV->setSection(GetNSConstantDoubleNumberSectionName());
2476 GV->addAttribute(Kind: "objc_arc_inert");
2477
2478 Entry = GV;
2479
2480 return ConstantAddress(GV, GV->getValueType(), Alignment);
2481}
2482
2483/// Shared private method to emit the id array storage for constant NSArray and
2484/// NSDictionary literals
2485llvm::GlobalVariable *
2486CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2487 const ArrayRef<llvm::Constant *> &Elements) {
2488 llvm::Type *ElementsTy = Elements[0]->getType();
2489 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementType: ElementsTy, NumElements: Elements.size());
2490
2491 llvm::Constant *const ArrayData = llvm::ConstantArray::get(T: ArrayTy, V: Elements);
2492
2493 llvm::GlobalVariable *ObjectsGV = new llvm::GlobalVariable(
2494 CGM.getModule(), ArrayTy, true, llvm::GlobalValue::InternalLinkage,
2495 ArrayData, "_unnamed_array_storage");
2496
2497 ObjectsGV->setAlignment(CGM.getPointerAlign().getAsAlign());
2498 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2499 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2500 return ObjectsGV;
2501}
2502
2503/// Generate a constant NSConstantArray from an ObjC array literal
2504/*
2505 struct __builtin_NSArray {
2506 struct._class_t *isa;
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.add(value: Class);
2541
2542 // count
2543 uint64_t ObjectCount = Objects.size();
2544 llvm::Constant *Count = llvm::ConstantInt::get(Ty: NSUIntegerTy, V: ObjectCount);
2545 Fields.add(value: Count);
2546
2547 // objects
2548 llvm::GlobalVariable *ObjectsGV =
2549 EmitNSConstantCollectionLiteralArrayStorage(Elements: Objects);
2550 Fields.add(value: ObjectsGV);
2551
2552 // The struct
2553 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2554 args: "_unnamed_nsarray_", args&: Alignment,
2555 /* constant */ args: true, args: llvm::GlobalValue::PrivateLinkage);
2556
2557 GV->setSection(GetNSConstantArraySectionName());
2558 GV->addAttribute(Kind: "objc_arc_inert");
2559
2560 return ConstantAddress(GV, GV->getValueType(), Alignment);
2561}
2562
2563/// Generate a constant NSConstantDictionary from an ObjC dictionary literal
2564/*
2565 struct __builtin_NSDictionary {
2566 struct._class_t *isa;
2567 NSUInteger const _hashOptions;
2568 NSUInteger const _count;
2569 id const *const _keys;
2570 id const *const _objects;
2571 };
2572 */
2573ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2574 const ObjCDictionaryLiteral *E,
2575 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2576 CharUnits Alignment = CGM.getPointerAlign();
2577
2578 if (KeysAndObjects.size() == 0) {
2579 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2580 return ConstantAddress(GV, GV->getValueType(), Alignment);
2581 }
2582
2583 ASTContext &Context = CGM.getContext();
2584 CodeGenTypes &Types = CGM.getTypes();
2585 llvm::Constant *const Class = getNSConstantDictionaryClassRef();
2586
2587 llvm::Type *const NSUIntegerTy =
2588 Types.ConvertType(T: Context.getNSUIntegerType());
2589
2590 if (!NSConstantDictionaryType) {
2591 NSConstantDictionaryType = llvm::StructType::create(
2592 Elements: {
2593 CGM.DefaultPtrTy, // isa
2594 NSUIntegerTy, // _hashOptions
2595 NSUIntegerTy, // _count
2596 CGM.DefaultPtrTy, // _keys
2597 CGM.DefaultPtrTy, // _objects
2598 },
2599 Name: "struct.__builtin_NSDictionary");
2600 }
2601
2602 ConstantInitBuilder Builder(CGM);
2603 auto Fields = Builder.beginStruct(structTy: NSConstantDictionaryType);
2604
2605 // Class pointer.
2606 Fields.add(value: Class);
2607
2608 // Use the hashing helper to manage the keys and sorting
2609 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2610 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2611
2612 // Ask `HashBuilder` for the fully sorted keys / values and the count
2613 uint64_t const NumElements = DictBuilder.getNumElements();
2614
2615 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2616 Ty: NSUIntegerTy, V: static_cast<uint64_t>(DictBuilder.getOptions()));
2617 Fields.add(value: OptionsConstant);
2618
2619 // count
2620 llvm::Constant *Count = llvm::ConstantInt::get(Ty: NSUIntegerTy, V: NumElements);
2621 Fields.add(value: Count);
2622
2623 // Split sorted pairs into separate keys and objects arrays for storage.
2624 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2625 SortedKeys.reserve(N: NumElements);
2626 SortedObjects.reserve(N: NumElements);
2627 for (auto &[Key, Obj] : DictBuilder.getElements()) {
2628 SortedKeys.push_back(Elt: Key);
2629 SortedObjects.push_back(Elt: Obj);
2630 }
2631
2632 // keys
2633 llvm::GlobalVariable *KeysGV =
2634 EmitNSConstantCollectionLiteralArrayStorage(Elements: SortedKeys);
2635 Fields.add(value: KeysGV);
2636
2637 // objects
2638 llvm::GlobalVariable *ObjectsGV =
2639 EmitNSConstantCollectionLiteralArrayStorage(Elements: SortedObjects);
2640 Fields.add(value: ObjectsGV);
2641
2642 // The struct
2643 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2644 args: "_unnamed_nsdictionary_", args&: Alignment,
2645 /* constant */ args: true, args: llvm::GlobalValue::PrivateLinkage);
2646
2647 GV->setSection(GetNSConstantDictionarySectionName());
2648 GV->addAttribute(Kind: "objc_arc_inert");
2649
2650 return ConstantAddress(GV, GV->getValueType(), Alignment);
2651}
2652
2653enum { kCFTaggedObjectID_Integer = (1 << 1) + 1 };
2654
2655/// Generates a message send where the super is the receiver. This is
2656/// a message send to self with special delivery semantics indicating
2657/// which class's method should be called.
2658CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2659 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2660 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
2661 llvm::Value *Receiver, bool IsClassMessage,
2662 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
2663 // Create and init a super structure; this is a (receiver, class)
2664 // pair we will pass to objc_msgSendSuper.
2665 RawAddress ObjCSuper = CGF.CreateTempAlloca(
2666 Ty: ObjCTypes.SuperTy, align: CGF.getPointerAlign(), Name: "objc_super");
2667 llvm::Value *ReceiverAsObject =
2668 CGF.Builder.CreateBitCast(V: Receiver, DestTy: ObjCTypes.ObjectPtrTy);
2669 CGF.Builder.CreateStore(Val: ReceiverAsObject,
2670 Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 0));
2671
2672 // If this is a class message the metaclass is passed as the target.
2673 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(C&: VMContext);
2674 llvm::Value *Target;
2675 if (IsClassMessage) {
2676 if (isCategoryImpl) {
2677 // Message sent to 'super' in a class method defined in a category
2678 // implementation requires an odd treatment.
2679 // If we are in a class method, we must retrieve the
2680 // _metaclass_ for the current class, pointed at by
2681 // the class's "isa" pointer. The following assumes that
2682 // isa" is the first ivar in a class (which it must be).
2683 Target = EmitClassRef(CGF, ID: Class->getSuperClass());
2684 Target = CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: Target, Idx: 0);
2685 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: Target,
2686 Align: CGF.getPointerAlign());
2687 } else {
2688 llvm::Constant *MetaClassPtr = EmitMetaClassRef(ID: Class);
2689 llvm::Value *SuperPtr =
2690 CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: MetaClassPtr, Idx: 1);
2691 llvm::Value *Super = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: SuperPtr,
2692 Align: CGF.getPointerAlign());
2693 Target = Super;
2694 }
2695 } else if (isCategoryImpl)
2696 Target = EmitClassRef(CGF, ID: Class->getSuperClass());
2697 else {
2698 llvm::Value *ClassPtr = EmitSuperClassRef(ID: Class);
2699 ClassPtr = CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: ClassPtr, Idx: 1);
2700 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: ClassPtr,
2701 Align: CGF.getPointerAlign());
2702 }
2703 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
2704 // ObjCTypes types.
2705 llvm::Type *ClassTy =
2706 CGM.getTypes().ConvertType(T: CGF.getContext().getObjCClassType());
2707 Target = CGF.Builder.CreateBitCast(V: Target, DestTy: ClassTy);
2708 CGF.Builder.CreateStore(Val: Target, Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 1));
2709 return EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: ObjCSuper.getPointer(),
2710 Arg0Ty: ObjCTypes.SuperPtrCTy, IsSuper: true, CallArgs, OMD: Method, ClassReceiver: Class,
2711 ObjCTypes);
2712}
2713
2714/// Generate code for a message send expression.
2715CodeGen::RValue CGObjCMac::GenerateMessageSend(
2716 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2717 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
2718 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
2719 return EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: Receiver,
2720 Arg0Ty: CGF.getContext().getObjCIdType(), IsSuper: false, CallArgs,
2721 OMD: Method, ClassReceiver: Class, ObjCTypes);
2722}
2723
2724CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2725 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2726 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper,
2727 const CallArgList &CallArgs, const ObjCMethodDecl *Method,
2728 const ObjCInterfaceDecl *ClassReceiver,
2729 const ObjCCommonTypesHelper &ObjCTypes) {
2730 CodeGenTypes &Types = CGM.getTypes();
2731 auto selTy = CGF.getContext().getObjCSelType();
2732 llvm::Value *ReceiverValue =
2733 llvm::PoisonValue::get(T: Types.ConvertType(T: Arg0Ty));
2734 llvm::Value *SelValue = llvm::UndefValue::get(T: Types.ConvertType(T: selTy));
2735
2736 CallArgList ActualArgs;
2737 if (!IsSuper)
2738 Arg0 = CGF.Builder.CreateBitCast(V: Arg0, DestTy: ObjCTypes.ObjectPtrTy);
2739 ActualArgs.add(rvalue: RValue::get(V: ReceiverValue), type: Arg0Ty);
2740 if (!Method || !Method->isDirectMethod())
2741 ActualArgs.add(rvalue: RValue::get(V: SelValue), type: selTy);
2742 ActualArgs.addFrom(other: CallArgs);
2743
2744 // If we're calling a method, use the formal signature.
2745 MessageSendInfo MSI = getMessageSendInfo(method: Method, resultType: ResultType, callArgs&: ActualArgs);
2746
2747 if (Method)
2748 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
2749 CGM.getContext().getCanonicalType(ResultType) &&
2750 "Result type mismatch!");
2751
2752 bool ReceiverCanBeNull =
2753 canMessageReceiverBeNull(CGF, method: Method, isSuper: IsSuper, classReceiver: ClassReceiver, receiver: Arg0);
2754 bool ClassObjectCanBeUnrealized =
2755 Method && Method->isClassMethod() &&
2756 canClassObjectBeUnrealized(ClassDecl: ClassReceiver, CGF);
2757
2758 bool RequiresNullCheck = false;
2759 bool RequiresReceiverValue = true;
2760 bool RequiresSelValue = true;
2761
2762 llvm::FunctionCallee Fn = nullptr;
2763 if (Method && Method->isDirectMethod()) {
2764 assert(!IsSuper);
2765 Fn = GetDirectMethodCallee(OMD: Method, CD: Method->getClassInterface(),
2766 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2767 // Direct methods will synthesize the proper `_cmd` internally,
2768 // so just don't bother with setting the `_cmd` argument.
2769 RequiresSelValue = false;
2770 } else if (CGM.ReturnSlotInterferesWithArgs(FI: MSI.CallInfo)) {
2771 if (ReceiverCanBeNull)
2772 RequiresNullCheck = true;
2773 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2774 : ObjCTypes.getSendStretFn(IsSuper);
2775 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2776 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2777 : ObjCTypes.getSendFpretFn(IsSuper);
2778 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2779 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2780 : ObjCTypes.getSendFp2retFn(IsSuper);
2781 } else {
2782 // arm64 uses objc_msgSend for stret methods and yet null receiver check
2783 // must be made for it.
2784 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(FI: MSI.CallInfo))
2785 RequiresNullCheck = true;
2786 // The class name that's used to create the class msgSend stub declaration.
2787 StringRef ClassName;
2788
2789 // We cannot use class msgSend stubs in the following cases:
2790 // 1. The class is annotated with `objc_class_stub` or
2791 // `objc_runtime_visible`.
2792 // 2. The selector name contains a '$'.
2793 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2794 Method && Method->isClassMethod() &&
2795 !ClassReceiver->hasAttr<ObjCClassStubAttr>() &&
2796 !ClassReceiver->hasAttr<ObjCRuntimeVisibleAttr>() &&
2797 Sel.getAsString().find(c: '$') == std::string::npos)
2798 ClassName = ClassReceiver->getObjCRuntimeNameAsString();
2799
2800 bool UseClassStub = ClassName.data();
2801 // Try to use a selector stub declaration instead of objc_msgSend.
2802 if (!IsSuper &&
2803 (CGM.getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2804 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2805 // Selector stubs synthesize `_cmd` in the stub, so we don't have to.
2806 RequiresReceiverValue = !UseClassStub;
2807 RequiresSelValue = false;
2808 } else {
2809 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2810 : ObjCTypes.getSendFn(IsSuper);
2811 }
2812 }
2813
2814 // Cast function to proper signature
2815 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2816 Val: CGF.Builder.CreateBitCast(V: Fn.getCallee(), DestTy: MSI.MessengerType));
2817
2818 // We don't need to emit a null check to zero out an indirect result if the
2819 // result is ignored.
2820 if (Return.isUnused())
2821 RequiresNullCheck = false;
2822
2823 // Emit a null-check if there's a consumed argument other than the receiver.
2824 if (!RequiresNullCheck && Method && Method->hasParamDestroyedInCallee())
2825 RequiresNullCheck = true;
2826
2827 if (CGM.shouldHavePreconditionInline(OMD: Method)) {
2828 // For variadic class methods, we need to inline precondition checks. That
2829 // include two things:
2830 // 1. We have to inline the class realization if we are not sure if it must
2831 // have been realized.
2832 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2833 // Perform class realization using the helper function
2834 Arg0 = GenerateClassRealization(CGF, classObject: Arg0, OID: ClassReceiver);
2835 ActualArgs[0] = CallArg(RValue::get(V: Arg0), ActualArgs[0].Ty);
2836 }
2837 // 2. We have to inline the precondition thunk if we are not sure if the
2838 // receiver can be null. Luckly, `NullReturnState` already does that for
2839 // corner cases like ns_consume, so we only need to override the flag,
2840 // regardless if the return value is unused.
2841 RequiresNullCheck |= ReceiverCanBeNull;
2842 }
2843
2844 NullReturnState nullReturn;
2845 if (RequiresNullCheck) {
2846 nullReturn.init(CGF, receiver: Arg0);
2847 }
2848
2849 // Pass the receiver value if it's needed.
2850 if (RequiresReceiverValue)
2851 ActualArgs[0] = CallArg(RValue::get(V: Arg0), Arg0Ty);
2852
2853 // If a selector value needs to be passed, emit the load before the call.
2854 if (RequiresSelValue) {
2855 SelValue = GetSelector(CGF, Sel);
2856 ActualArgs[1] = CallArg(RValue::get(V: SelValue), selTy);
2857 }
2858
2859 llvm::CallBase *CallSite;
2860 CGCallee Callee = CGCallee::forDirect(functionPtr: BitcastFn);
2861 RValue rvalue =
2862 CGF.EmitCall(CallInfo: MSI.CallInfo, Callee, ReturnValue: Return, Args: ActualArgs, CallOrInvoke: &CallSite);
2863
2864 // Mark the call as noreturn if the method is marked noreturn and the
2865 // receiver cannot be null.
2866 if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2867 CallSite->setDoesNotReturn();
2868 }
2869
2870 return nullReturn.complete(CGF, returnSlot: Return, result: rvalue, resultType: ResultType, CallArgs,
2871 Method: RequiresNullCheck ? Method : nullptr);
2872}
2873
2874static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,
2875 bool pointee = false) {
2876 // Note that GC qualification applies recursively to C pointer types
2877 // that aren't otherwise decorated. This is weird, but it's probably
2878 // an intentional workaround to the unreliable placement of GC qualifiers.
2879 if (FQT.isObjCGCStrong())
2880 return Qualifiers::Strong;
2881
2882 if (FQT.isObjCGCWeak())
2883 return Qualifiers::Weak;
2884
2885 if (auto ownership = FQT.getObjCLifetime()) {
2886 // Ownership does not apply recursively to C pointer types.
2887 if (pointee)
2888 return Qualifiers::GCNone;
2889 switch (ownership) {
2890 case Qualifiers::OCL_Weak:
2891 return Qualifiers::Weak;
2892 case Qualifiers::OCL_Strong:
2893 return Qualifiers::Strong;
2894 case Qualifiers::OCL_ExplicitNone:
2895 return Qualifiers::GCNone;
2896 case Qualifiers::OCL_Autoreleasing:
2897 llvm_unreachable("autoreleasing ivar?");
2898 case Qualifiers::OCL_None:
2899 llvm_unreachable("known nonzero");
2900 }
2901 llvm_unreachable("bad objc ownership");
2902 }
2903
2904 // Treat unqualified retainable pointers as strong.
2905 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2906 return Qualifiers::Strong;
2907
2908 // Walk into C pointer types, but only in GC.
2909 if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
2910 if (const PointerType *PT = FQT->getAs<PointerType>())
2911 return GetGCAttrTypeForType(Ctx, FQT: PT->getPointeeType(), /*pointee*/ true);
2912 }
2913
2914 return Qualifiers::GCNone;
2915}
2916
2917namespace {
2918struct IvarInfo {
2919 CharUnits Offset;
2920 uint64_t SizeInWords;
2921 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2922 : Offset(offset), SizeInWords(sizeInWords) {}
2923
2924 // Allow sorting based on byte pos.
2925 bool operator<(const IvarInfo &other) const { return Offset < other.Offset; }
2926};
2927
2928/// A helper class for building GC layout strings.
2929class IvarLayoutBuilder {
2930 CodeGenModule &CGM;
2931
2932 /// The start of the layout. Offsets will be relative to this value,
2933 /// and entries less than this value will be silently discarded.
2934 CharUnits InstanceBegin;
2935
2936 /// The end of the layout. Offsets will never exceed this value.
2937 CharUnits InstanceEnd;
2938
2939 /// Whether we're generating the strong layout or the weak layout.
2940 bool ForStrongLayout;
2941
2942 /// Whether the offsets in IvarsInfo might be out-of-order.
2943 bool IsDisordered = false;
2944
2945 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2946
2947public:
2948 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2949 CharUnits instanceEnd, bool forStrongLayout)
2950 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2951 ForStrongLayout(forStrongLayout) {}
2952
2953 void visitRecord(const RecordType *RT, CharUnits offset);
2954
2955 template <class Iterator, class GetOffsetFn>
2956 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2957 const GetOffsetFn &getOffset);
2958
2959 void visitField(const FieldDecl *field, CharUnits offset);
2960
2961 /// Add the layout of a block implementation.
2962 void visitBlock(const CGBlockInfo &blockInfo);
2963
2964 /// Is there any information for an interesting bitmap?
2965 bool hasBitmapData() const { return !IvarsInfo.empty(); }
2966
2967 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2968 llvm::SmallVectorImpl<unsigned char> &buffer);
2969
2970 static void dump(ArrayRef<unsigned char> buffer) {
2971 const unsigned char *s = buffer.data();
2972 for (unsigned i = 0, e = buffer.size(); i < e; i++)
2973 if (!(s[i] & 0xf0))
2974 printf(format: "0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2975 else
2976 printf(format: "0x%x%s", s[i], s[i] != 0 ? ", " : "");
2977 printf(format: "\n");
2978 }
2979};
2980} // end anonymous namespace
2981
2982llvm::Constant *
2983CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2984 const CGBlockInfo &blockInfo) {
2985
2986 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
2987 if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
2988 return nullPtr;
2989
2990 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
2991 /*for strong layout*/ true);
2992
2993 builder.visitBlock(blockInfo);
2994
2995 if (!builder.hasBitmapData())
2996 return nullPtr;
2997
2998 llvm::SmallVector<unsigned char, 32> buffer;
2999 llvm::Constant *C = builder.buildBitmap(CGObjC&: *this, buffer);
3000 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3001 printf(format: "\n block variable layout for block: ");
3002 builder.dump(buffer);
3003 }
3004
3005 return C;
3006}
3007
3008void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
3009 // __isa is the first field in block descriptor and must assume by runtime's
3010 // convention that it is GC'able.
3011 IvarsInfo.push_back(Elt: IvarInfo(CharUnits::Zero(), 1));
3012
3013 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3014
3015 // Ignore the optional 'this' capture: C++ objects are not assumed
3016 // to be GC'ed.
3017
3018 CharUnits lastFieldOffset;
3019
3020 // Walk the captured variables.
3021 for (const auto &CI : blockDecl->captures()) {
3022 const VarDecl *variable = CI.getVariable();
3023 QualType type = variable->getType();
3024
3025 const CGBlockInfo::Capture &capture = blockInfo.getCapture(var: variable);
3026
3027 // Ignore constant captures.
3028 if (capture.isConstant())
3029 continue;
3030
3031 CharUnits fieldOffset = capture.getOffset();
3032
3033 // Block fields are not necessarily ordered; if we detect that we're
3034 // adding them out-of-order, make sure we sort later.
3035 if (fieldOffset < lastFieldOffset)
3036 IsDisordered = true;
3037 lastFieldOffset = fieldOffset;
3038
3039 // __block variables are passed by their descriptor address.
3040 if (CI.isByRef()) {
3041 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, /*size in words*/ 1));
3042 continue;
3043 }
3044
3045 assert(!type->isArrayType() && "array variable should not be caught");
3046 if (const RecordType *record = type->getAsCanonical<RecordType>()) {
3047 visitRecord(RT: record, offset: fieldOffset);
3048 continue;
3049 }
3050
3051 Qualifiers::GC GCAttr = GetGCAttrTypeForType(Ctx&: CGM.getContext(), FQT: type);
3052
3053 if (GCAttr == Qualifiers::Strong) {
3054 assert(CGM.getContext().getTypeSize(type) ==
3055 CGM.getTarget().getPointerWidth(LangAS::Default));
3056 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, /*size in words*/ 1));
3057 }
3058 }
3059}
3060
3061/// getBlockCaptureLifetime - This routine returns life time of the captured
3062/// block variable for the purpose of block layout meta-data generation. FQT is
3063/// the type of the variable captured in the block.
3064Qualifiers::ObjCLifetime
3065CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT, bool ByrefLayout) {
3066 // If it has an ownership qualifier, we're done.
3067 if (auto lifetime = FQT.getObjCLifetime())
3068 return lifetime;
3069
3070 // If it doesn't, and this is ARC, it has no ownership.
3071 if (CGM.getLangOpts().ObjCAutoRefCount)
3072 return Qualifiers::OCL_None;
3073
3074 // In MRC, retainable pointers are owned by non-__block variables.
3075 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
3076 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
3077
3078 return Qualifiers::OCL_None;
3079}
3080
3081void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
3082 Qualifiers::ObjCLifetime LifeTime,
3083 CharUnits FieldOffset,
3084 CharUnits FieldSize) {
3085 // __block variables are passed by their descriptor address.
3086 if (IsByref)
3087 RunSkipBlockVars.push_back(
3088 Elt: RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3089 else if (LifeTime == Qualifiers::OCL_Strong)
3090 RunSkipBlockVars.push_back(
3091 Elt: RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3092 else if (LifeTime == Qualifiers::OCL_Weak)
3093 RunSkipBlockVars.push_back(
3094 Elt: RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3095 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
3096 RunSkipBlockVars.push_back(
3097 Elt: RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3098 else
3099 RunSkipBlockVars.push_back(
3100 Elt: RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3101}
3102
3103void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
3104 const RecordDecl *RD,
3105 ArrayRef<const FieldDecl *> RecFields,
3106 CharUnits BytePos, bool &HasUnion,
3107 bool ByrefLayout) {
3108 bool IsUnion = (RD && RD->isUnion());
3109 CharUnits MaxUnionSize = CharUnits::Zero();
3110 const FieldDecl *MaxField = nullptr;
3111 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
3112 CharUnits MaxFieldOffset = CharUnits::Zero();
3113 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
3114
3115 if (RecFields.empty())
3116 return;
3117 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3118
3119 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3120 const FieldDecl *Field = RecFields[i];
3121 // Note that 'i' here is actually the field index inside RD of Field,
3122 // although this dependency is hidden.
3123 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(D: RD);
3124 CharUnits FieldOffset =
3125 CGM.getContext().toCharUnitsFromBits(BitSize: RL.getFieldOffset(FieldNo: i));
3126
3127 // Skip over unnamed or bitfields
3128 if (!Field->getIdentifier() || Field->isBitField()) {
3129 LastFieldBitfieldOrUnnamed = Field;
3130 LastBitfieldOrUnnamedOffset = FieldOffset;
3131 continue;
3132 }
3133
3134 LastFieldBitfieldOrUnnamed = nullptr;
3135 QualType FQT = Field->getType();
3136 if (FQT->isRecordType() || FQT->isUnionType()) {
3137 if (FQT->isUnionType())
3138 HasUnion = true;
3139
3140 BuildRCBlockVarRecordLayout(RT: FQT->castAsCanonical<RecordType>(),
3141 BytePos: BytePos + FieldOffset, HasUnion);
3142 continue;
3143 }
3144
3145 if (const ArrayType *Array = CGM.getContext().getAsArrayType(T: FQT)) {
3146 auto *CArray = cast<ConstantArrayType>(Val: Array);
3147 uint64_t ElCount = CArray->getZExtSize();
3148 assert(CArray && "only array with known element size is supported");
3149 FQT = CArray->getElementType();
3150 while (const ArrayType *Array = CGM.getContext().getAsArrayType(T: FQT)) {
3151 auto *CArray = cast<ConstantArrayType>(Val: Array);
3152 ElCount *= CArray->getZExtSize();
3153 FQT = CArray->getElementType();
3154 }
3155 if (FQT->isRecordType() && ElCount) {
3156 int OldIndex = RunSkipBlockVars.size() - 1;
3157 auto *RT = FQT->castAsCanonical<RecordType>();
3158 BuildRCBlockVarRecordLayout(RT, BytePos: BytePos + FieldOffset, HasUnion);
3159
3160 // Replicate layout information for each array element. Note that
3161 // one element is already done.
3162 uint64_t ElIx = 1;
3163 for (int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3164 ElIx++) {
3165 CharUnits Size = CGM.getContext().getTypeSizeInChars(T: RT);
3166 for (int i = OldIndex + 1; i <= FirstIndex; ++i)
3167 RunSkipBlockVars.push_back(
3168 Elt: RUN_SKIP(RunSkipBlockVars[i].opcode,
3169 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3170 RunSkipBlockVars[i].block_var_size));
3171 }
3172 continue;
3173 }
3174 }
3175 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(T: Field->getType());
3176 if (IsUnion) {
3177 CharUnits UnionIvarSize = FieldSize;
3178 if (UnionIvarSize > MaxUnionSize) {
3179 MaxUnionSize = UnionIvarSize;
3180 MaxField = Field;
3181 MaxFieldOffset = FieldOffset;
3182 }
3183 } else {
3184 UpdateRunSkipBlockVars(IsByref: false, LifeTime: getBlockCaptureLifetime(FQT, ByrefLayout),
3185 FieldOffset: BytePos + FieldOffset, FieldSize);
3186 }
3187 }
3188
3189 if (LastFieldBitfieldOrUnnamed) {
3190 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3191 // Last field was a bitfield. Must update the info.
3192 uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue();
3193 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3194 ((BitFieldSize % ByteSizeInBits) != 0);
3195 CharUnits Size = CharUnits::fromQuantity(Quantity: UnsSize);
3196 Size += LastBitfieldOrUnnamedOffset;
3197 UpdateRunSkipBlockVars(
3198 IsByref: false,
3199 LifeTime: getBlockCaptureLifetime(FQT: LastFieldBitfieldOrUnnamed->getType(),
3200 ByrefLayout),
3201 FieldOffset: BytePos + LastBitfieldOrUnnamedOffset, FieldSize: Size);
3202 } else {
3203 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&
3204 "Expected unnamed");
3205 // Last field was unnamed. Must update skip info.
3206 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(
3207 T: LastFieldBitfieldOrUnnamed->getType());
3208 UpdateRunSkipBlockVars(
3209 IsByref: false,
3210 LifeTime: getBlockCaptureLifetime(FQT: LastFieldBitfieldOrUnnamed->getType(),
3211 ByrefLayout),
3212 FieldOffset: BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3213 }
3214 }
3215
3216 if (MaxField)
3217 UpdateRunSkipBlockVars(
3218 IsByref: false, LifeTime: getBlockCaptureLifetime(FQT: MaxField->getType(), ByrefLayout),
3219 FieldOffset: BytePos + MaxFieldOffset, FieldSize: MaxUnionSize);
3220}
3221
3222void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
3223 CharUnits BytePos,
3224 bool &HasUnion,
3225 bool ByrefLayout) {
3226 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
3227 SmallVector<const FieldDecl *, 16> Fields(RD->fields());
3228 llvm::Type *Ty = CGM.getTypes().ConvertType(T: QualType(RT, 0));
3229 const llvm::StructLayout *RecLayout =
3230 CGM.getDataLayout().getStructLayout(Ty: cast<llvm::StructType>(Val: Ty));
3231
3232 BuildRCRecordLayout(RecLayout, RD, RecFields: Fields, BytePos, HasUnion, ByrefLayout);
3233}
3234
3235/// InlineLayoutInstruction - This routine produce an inline instruction for the
3236/// block variable layout if it can. If not, it returns 0. Rules are as follow:
3237/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit
3238/// world, an inline layout of value 0x0000000000000xyz is interpreted as
3239/// follows: x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by y
3240/// captured object of BLOCK_LAYOUT_BYREF. Followed by z captured object of
3241/// BLOCK_LAYOUT_WEAK. If any of the above is missing, zero replaces it. For
3242/// example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no BLOCK_LAYOUT_BYREF
3243/// and no BLOCK_LAYOUT_WEAK objects are captured.
3244uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3245 SmallVectorImpl<unsigned char> &Layout) {
3246 uint64_t Result = 0;
3247 if (Layout.size() <= 3) {
3248 unsigned size = Layout.size();
3249 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3250 unsigned char inst;
3251 enum BLOCK_LAYOUT_OPCODE opcode;
3252 switch (size) {
3253 case 3:
3254 inst = Layout[0];
3255 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3256 if (opcode == BLOCK_LAYOUT_STRONG)
3257 strong_word_count = (inst & 0xF) + 1;
3258 else
3259 return 0;
3260 inst = Layout[1];
3261 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3262 if (opcode == BLOCK_LAYOUT_BYREF)
3263 byref_word_count = (inst & 0xF) + 1;
3264 else
3265 return 0;
3266 inst = Layout[2];
3267 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3268 if (opcode == BLOCK_LAYOUT_WEAK)
3269 weak_word_count = (inst & 0xF) + 1;
3270 else
3271 return 0;
3272 break;
3273
3274 case 2:
3275 inst = Layout[0];
3276 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3277 if (opcode == BLOCK_LAYOUT_STRONG) {
3278 strong_word_count = (inst & 0xF) + 1;
3279 inst = Layout[1];
3280 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3281 if (opcode == BLOCK_LAYOUT_BYREF)
3282 byref_word_count = (inst & 0xF) + 1;
3283 else if (opcode == BLOCK_LAYOUT_WEAK)
3284 weak_word_count = (inst & 0xF) + 1;
3285 else
3286 return 0;
3287 } else if (opcode == BLOCK_LAYOUT_BYREF) {
3288 byref_word_count = (inst & 0xF) + 1;
3289 inst = Layout[1];
3290 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3291 if (opcode == BLOCK_LAYOUT_WEAK)
3292 weak_word_count = (inst & 0xF) + 1;
3293 else
3294 return 0;
3295 } else
3296 return 0;
3297 break;
3298
3299 case 1:
3300 inst = Layout[0];
3301 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3302 if (opcode == BLOCK_LAYOUT_STRONG)
3303 strong_word_count = (inst & 0xF) + 1;
3304 else if (opcode == BLOCK_LAYOUT_BYREF)
3305 byref_word_count = (inst & 0xF) + 1;
3306 else if (opcode == BLOCK_LAYOUT_WEAK)
3307 weak_word_count = (inst & 0xF) + 1;
3308 else
3309 return 0;
3310 break;
3311
3312 default:
3313 return 0;
3314 }
3315
3316 // Cannot inline when any of the word counts is 15. Because this is one less
3317 // than the actual work count (so 15 means 16 actual word counts),
3318 // and we can only display 0 thru 15 word counts.
3319 if (strong_word_count == 16 || byref_word_count == 16 ||
3320 weak_word_count == 16)
3321 return 0;
3322
3323 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3324 (weak_word_count != 0);
3325
3326 if (size == count) {
3327 if (strong_word_count)
3328 Result = strong_word_count;
3329 Result <<= 4;
3330 if (byref_word_count)
3331 Result += byref_word_count;
3332 Result <<= 4;
3333 if (weak_word_count)
3334 Result += weak_word_count;
3335 }
3336 }
3337 return Result;
3338}
3339
3340llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
3341 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
3342 if (RunSkipBlockVars.empty())
3343 return nullPtr;
3344 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(AddrSpace: LangAS::Default);
3345 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3346 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3347
3348 // Sort on byte position; captures might not be allocated in order,
3349 // and unions can do funny things.
3350 llvm::array_pod_sort(Start: RunSkipBlockVars.begin(), End: RunSkipBlockVars.end());
3351 SmallVector<unsigned char, 16> Layout;
3352
3353 unsigned size = RunSkipBlockVars.size();
3354 for (unsigned i = 0; i < size; i++) {
3355 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3356 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3357 CharUnits end_byte_pos = start_byte_pos;
3358 unsigned j = i + 1;
3359 while (j < size) {
3360 if (opcode == RunSkipBlockVars[j].opcode) {
3361 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3362 i++;
3363 } else
3364 break;
3365 }
3366 CharUnits size_in_bytes =
3367 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3368 if (j < size) {
3369 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3370 RunSkipBlockVars[j - 1].block_var_bytepos -
3371 RunSkipBlockVars[j - 1].block_var_size;
3372 size_in_bytes += gap;
3373 }
3374 CharUnits residue_in_bytes = CharUnits::Zero();
3375 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3376 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3377 size_in_bytes -= residue_in_bytes;
3378 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3379 }
3380
3381 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
3382 while (size_in_words >= 16) {
3383 // Note that value in imm. is one less that the actual
3384 // value. So, 0xf means 16 words follow!
3385 unsigned char inst = (opcode << 4) | 0xf;
3386 Layout.push_back(Elt: inst);
3387 size_in_words -= 16;
3388 }
3389 if (size_in_words > 0) {
3390 // Note that value in imm. is one less that the actual
3391 // value. So, we subtract 1 away!
3392 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3393 Layout.push_back(Elt: inst);
3394 }
3395 if (residue_in_bytes > CharUnits::Zero()) {
3396 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3397 (residue_in_bytes.getQuantity() - 1);
3398 Layout.push_back(Elt: inst);
3399 }
3400 }
3401
3402 while (!Layout.empty()) {
3403 unsigned char inst = Layout.back();
3404 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3405 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3406 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3407 Layout.pop_back();
3408 else
3409 break;
3410 }
3411
3412 uint64_t Result = InlineLayoutInstruction(Layout);
3413 if (Result != 0) {
3414 // Block variable layout instruction has been inlined.
3415 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3416 if (ComputeByrefLayout)
3417 printf(format: "\n Inline BYREF variable layout: ");
3418 else
3419 printf(format: "\n Inline block variable layout: ");
3420 printf(format: "0x0%" PRIx64 "", Result);
3421 if (auto numStrong = (Result & 0xF00) >> 8)
3422 printf(format: ", BL_STRONG:%d", (int)numStrong);
3423 if (auto numByref = (Result & 0x0F0) >> 4)
3424 printf(format: ", BL_BYREF:%d", (int)numByref);
3425 if (auto numWeak = (Result & 0x00F) >> 0)
3426 printf(format: ", BL_WEAK:%d", (int)numWeak);
3427 printf(format: ", BL_OPERATOR:0\n");
3428 }
3429 return llvm::ConstantInt::get(Ty: CGM.IntPtrTy, V: Result);
3430 }
3431
3432 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3433 Layout.push_back(Elt: inst);
3434 std::string BitMap;
3435 for (unsigned char C : Layout)
3436 BitMap += C;
3437
3438 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3439 if (ComputeByrefLayout)
3440 printf(format: "\n Byref variable layout: ");
3441 else
3442 printf(format: "\n Block variable layout: ");
3443 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
3444 unsigned char inst = BitMap[i];
3445 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3446 unsigned delta = 1;
3447 switch (opcode) {
3448 case BLOCK_LAYOUT_OPERATOR:
3449 printf(format: "BL_OPERATOR:");
3450 delta = 0;
3451 break;
3452 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3453 printf(format: "BL_NON_OBJECT_BYTES:");
3454 break;
3455 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3456 printf(format: "BL_NON_OBJECT_WORD:");
3457 break;
3458 case BLOCK_LAYOUT_STRONG:
3459 printf(format: "BL_STRONG:");
3460 break;
3461 case BLOCK_LAYOUT_BYREF:
3462 printf(format: "BL_BYREF:");
3463 break;
3464 case BLOCK_LAYOUT_WEAK:
3465 printf(format: "BL_WEAK:");
3466 break;
3467 case BLOCK_LAYOUT_UNRETAINED:
3468 printf(format: "BL_UNRETAINED:");
3469 break;
3470 }
3471 // Actual value of word count is one more that what is in the imm.
3472 // field of the instruction
3473 printf(format: "%d", (inst & 0xf) + delta);
3474 if (i < e - 1)
3475 printf(format: ", ");
3476 else
3477 printf(format: "\n");
3478 }
3479 }
3480
3481 auto *Entry = CreateCStringLiteral(Name: BitMap, LabelType: ObjCLabelType::LayoutBitMap,
3482 /*ForceNonFragileABI=*/true,
3483 /*NullTerminate=*/false);
3484 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
3485}
3486
3487static std::string getBlockLayoutInfoString(
3488 const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,
3489 bool HasCopyDisposeHelpers) {
3490 std::string Str;
3491 for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3492 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3493 // Copy/dispose helpers don't have any information about
3494 // __unsafe_unretained captures, so unconditionally concatenate a string.
3495 Str += "u";
3496 } else if (HasCopyDisposeHelpers) {
3497 // Information about __strong, __weak, or byref captures has already been
3498 // encoded into the names of the copy/dispose helpers. We have to add a
3499 // string here only when the copy/dispose helpers aren't generated (which
3500 // happens when the block is non-escaping).
3501 continue;
3502 } else {
3503 switch (R.opcode) {
3504 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3505 Str += "s";
3506 break;
3507 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3508 Str += "r";
3509 break;
3510 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3511 Str += "w";
3512 break;
3513 default:
3514 continue;
3515 }
3516 }
3517 Str += llvm::to_string(Value: R.block_var_bytepos.getQuantity());
3518 Str += "l" + llvm::to_string(Value: R.block_var_size.getQuantity());
3519 }
3520 return Str;
3521}
3522
3523void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3524 const CGBlockInfo &blockInfo) {
3525 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3526
3527 RunSkipBlockVars.clear();
3528 bool hasUnion = false;
3529
3530 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(AddrSpace: LangAS::Default);
3531 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3532 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3533
3534 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3535
3536 // Calculate the basic layout of the block structure.
3537 const llvm::StructLayout *layout =
3538 CGM.getDataLayout().getStructLayout(Ty: blockInfo.StructureType);
3539
3540 // Ignore the optional 'this' capture: C++ objects are not assumed
3541 // to be GC'ed.
3542 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
3543 UpdateRunSkipBlockVars(IsByref: false, LifeTime: Qualifiers::OCL_None,
3544 FieldOffset: blockInfo.BlockHeaderForcedGapOffset,
3545 FieldSize: blockInfo.BlockHeaderForcedGapSize);
3546 // Walk the captured variables.
3547 for (const auto &CI : blockDecl->captures()) {
3548 const VarDecl *variable = CI.getVariable();
3549 QualType type = variable->getType();
3550
3551 const CGBlockInfo::Capture &capture = blockInfo.getCapture(var: variable);
3552
3553 // Ignore constant captures.
3554 if (capture.isConstant())
3555 continue;
3556
3557 CharUnits fieldOffset =
3558 CharUnits::fromQuantity(Quantity: layout->getElementOffset(Idx: capture.getIndex()));
3559
3560 assert(!type->isArrayType() && "array variable should not be caught");
3561 if (!CI.isByRef())
3562 if (const auto *record = type->getAsCanonical<RecordType>()) {
3563 BuildRCBlockVarRecordLayout(RT: record, BytePos: fieldOffset, HasUnion&: hasUnion);
3564 continue;
3565 }
3566 CharUnits fieldSize;
3567 if (CI.isByRef())
3568 fieldSize = CharUnits::fromQuantity(Quantity: WordSizeInBytes);
3569 else
3570 fieldSize = CGM.getContext().getTypeSizeInChars(T: type);
3571 UpdateRunSkipBlockVars(IsByref: CI.isByRef(), LifeTime: getBlockCaptureLifetime(FQT: type, ByrefLayout: false),
3572 FieldOffset: fieldOffset, FieldSize: fieldSize);
3573 }
3574}
3575
3576llvm::Constant *
3577CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3578 const CGBlockInfo &blockInfo) {
3579 fillRunSkipBlockVars(CGM, blockInfo);
3580 return getBitmapBlockLayout(ComputeByrefLayout: false);
3581}
3582
3583std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3584 const CGBlockInfo &blockInfo) {
3585 fillRunSkipBlockVars(CGM, blockInfo);
3586 return getBlockLayoutInfoString(RunSkipBlockVars, HasCopyDisposeHelpers: blockInfo.NeedsCopyDispose);
3587}
3588
3589llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3590 QualType T) {
3591 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3592 assert(!T->isArrayType() && "__block array variable should not be caught");
3593 CharUnits fieldOffset;
3594 RunSkipBlockVars.clear();
3595 bool hasUnion = false;
3596 if (const auto *record = T->getAsCanonical<RecordType>()) {
3597 BuildRCBlockVarRecordLayout(RT: record, BytePos: fieldOffset, HasUnion&: hasUnion,
3598 ByrefLayout: true /*ByrefLayout */);
3599 llvm::Constant *Result = getBitmapBlockLayout(ComputeByrefLayout: true);
3600 if (isa<llvm::ConstantInt>(Val: Result))
3601 Result = llvm::ConstantExpr::getIntToPtr(C: Result, Ty: CGM.Int8PtrTy);
3602 return Result;
3603 }
3604 llvm::Constant *nullPtr = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
3605 return nullPtr;
3606}
3607
3608llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3609 const ObjCProtocolDecl *PD) {
3610 // FIXME: I don't understand why gcc generates this, or where it is
3611 // resolved. Investigate. Its also wasteful to look this up over and over.
3612 LazySymbols.insert(X: &CGM.getContext().Idents.get(Name: "Protocol"));
3613
3614 return GetProtocolRef(PD);
3615}
3616
3617void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
3618 // FIXME: We shouldn't need this, the protocol decl should contain enough
3619 // information to tell us whether this was a declaration or a definition.
3620 DefinedProtocols.insert(V: PD->getIdentifier());
3621
3622 // If we have generated a forward reference to this protocol, emit
3623 // it now. Otherwise do nothing, the protocol objects are lazily
3624 // emitted.
3625 if (Protocols.count(Val: PD->getIdentifier()))
3626 GetOrEmitProtocol(PD);
3627}
3628
3629llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
3630 if (DefinedProtocols.count(V: PD->getIdentifier()))
3631 return GetOrEmitProtocol(PD);
3632
3633 return GetOrEmitProtocolRef(PD);
3634}
3635
3636llvm::Value *
3637CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3638 const ObjCInterfaceDecl *ID,
3639 ObjCCommonTypesHelper &ObjCTypes) {
3640 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3641
3642 llvm::Value *className = CGF.CGM
3643 .GetAddrOfConstantCString(Str: std::string(
3644 ID->getObjCRuntimeNameAsString()))
3645 .getPointer();
3646 ASTContext &ctx = CGF.CGM.getContext();
3647 className = CGF.Builder.CreateBitCast(
3648 V: className, DestTy: CGF.ConvertType(T: ctx.getPointerType(T: ctx.CharTy.withConst())));
3649 llvm::CallInst *call = CGF.Builder.CreateCall(Callee: lookUpClassFn, Args: className);
3650 call->setDoesNotThrow();
3651 return call;
3652}
3653
3654/*
3655// Objective-C 1.0 extensions
3656struct _objc_protocol {
3657struct _objc_protocol_extension *isa;
3658char *protocol_name;
3659struct _objc_protocol_list *protocol_list;
3660struct _objc__method_prototype_list *instance_methods;
3661struct _objc__method_prototype_list *class_methods
3662};
3663
3664See EmitProtocolExtension().
3665*/
3666llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
3667 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
3668
3669 // Early exit if a defining object has already been generated.
3670 if (Entry && Entry->hasInitializer())
3671 return Entry;
3672
3673 // Use the protocol definition, if there is one.
3674 if (const ObjCProtocolDecl *Def = PD->getDefinition())
3675 PD = Def;
3676
3677 // FIXME: I don't understand why gcc generates this, or where it is
3678 // resolved. Investigate. Its also wasteful to look this up over and over.
3679 LazySymbols.insert(X: &CGM.getContext().Idents.get(Name: "Protocol"));
3680
3681 // Construct method lists.
3682 auto methodLists = ProtocolMethodLists::get(PD);
3683
3684 ConstantInitBuilder builder(CGM);
3685 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolTy);
3686 values.add(value: EmitProtocolExtension(PD, methodLists));
3687 values.add(value: GetClassName(RuntimeName: PD->getObjCRuntimeNameAsString()));
3688 values.add(value: EmitProtocolList(Name: "OBJC_PROTOCOL_REFS_" + PD->getName(),
3689 begin: PD->protocol_begin(), end: PD->protocol_end()));
3690 values.add(value: methodLists.emitMethodList(
3691 self: this, PD, kind: ProtocolMethodLists::RequiredInstanceMethods));
3692 values.add(value: methodLists.emitMethodList(
3693 self: this, PD, kind: ProtocolMethodLists::RequiredClassMethods));
3694
3695 if (Entry) {
3696 // Already created, update the initializer.
3697 assert(Entry->hasPrivateLinkage());
3698 values.finishAndSetAsInitializer(global: Entry);
3699 } else {
3700 Entry = values.finishAndCreateGlobal(
3701 args: "OBJC_PROTOCOL_" + PD->getName(), args: CGM.getPointerAlign(),
3702 /*constant*/ args: false, args: llvm::GlobalValue::PrivateLinkage);
3703 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3704
3705 Protocols[PD->getIdentifier()] = Entry;
3706 }
3707 CGM.addCompilerUsedGlobal(GV: Entry);
3708
3709 return Entry;
3710}
3711
3712llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
3713 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
3714
3715 if (!Entry) {
3716 // We use the initializer as a marker of whether this is a forward
3717 // reference or not. At module finalization we add the empty
3718 // contents for protocols which were referenced but never defined.
3719 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
3720 false, llvm::GlobalValue::PrivateLinkage,
3721 nullptr, "OBJC_PROTOCOL_" + PD->getName());
3722 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3723 // FIXME: Is this necessary? Why only for protocol?
3724 Entry->setAlignment(llvm::Align(4));
3725 }
3726
3727 return Entry;
3728}
3729
3730/*
3731 struct _objc_protocol_extension {
3732 uint32_t size;
3733 struct objc_method_description_list *optional_instance_methods;
3734 struct objc_method_description_list *optional_class_methods;
3735 struct objc_property_list *instance_properties;
3736 const char ** extendedMethodTypes;
3737 struct objc_property_list *class_properties;
3738 };
3739*/
3740llvm::Constant *
3741CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
3742 const ProtocolMethodLists &methodLists) {
3743 auto optInstanceMethods = methodLists.emitMethodList(
3744 self: this, PD, kind: ProtocolMethodLists::OptionalInstanceMethods);
3745 auto optClassMethods = methodLists.emitMethodList(
3746 self: this, PD, kind: ProtocolMethodLists::OptionalClassMethods);
3747
3748 auto extendedMethodTypes = EmitProtocolMethodTypes(
3749 Name: "OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3750 MethodTypes: methodLists.emitExtendedTypesArray(self: this), ObjCTypes);
3751
3752 auto instanceProperties = EmitPropertyList(
3753 Name: "OBJC_$_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: false);
3754 auto classProperties =
3755 EmitPropertyList(Name: "OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr,
3756 OCD: PD, ObjCTypes, IsClassProperty: true);
3757
3758 // Return null if no extension bits are used.
3759 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3760 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3761 classProperties->isNullValue()) {
3762 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolExtensionPtrTy);
3763 }
3764
3765 uint64_t size =
3766 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ProtocolExtensionTy);
3767
3768 ConstantInitBuilder builder(CGM);
3769 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolExtensionTy);
3770 values.addInt(intTy: ObjCTypes.IntTy, value: size);
3771 values.add(value: optInstanceMethods);
3772 values.add(value: optClassMethods);
3773 values.add(value: instanceProperties);
3774 values.add(value: extendedMethodTypes);
3775 values.add(value: classProperties);
3776
3777 // No special section, but goes in llvm.used
3778 return CreateMetadataVar(Name: "_OBJC_PROTOCOLEXT_" + PD->getName(), Init&: values,
3779 Section: StringRef(), Align: CGM.getPointerAlign(), AddToUsed: true);
3780}
3781
3782/*
3783 struct objc_protocol_list {
3784 struct objc_protocol_list *next;
3785 long count;
3786 Protocol *list[];
3787 };
3788*/
3789llvm::Constant *
3790CGObjCMac::EmitProtocolList(Twine name,
3791 ObjCProtocolDecl::protocol_iterator begin,
3792 ObjCProtocolDecl::protocol_iterator end) {
3793 // Just return null for empty protocol lists
3794 auto PDs = GetRuntimeProtocolList(begin, end);
3795 if (PDs.empty())
3796 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListPtrTy);
3797
3798 ConstantInitBuilder builder(CGM);
3799 auto values = builder.beginStruct();
3800
3801 // This field is only used by the runtime.
3802 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
3803
3804 // Reserve a slot for the count.
3805 auto countSlot = values.addPlaceholder();
3806
3807 auto refsArray = values.beginArray(eltTy: ObjCTypes.ProtocolPtrTy);
3808 for (const auto *Proto : PDs)
3809 refsArray.add(value: GetProtocolRef(PD: Proto));
3810
3811 auto count = refsArray.size();
3812
3813 // This list is null terminated.
3814 refsArray.addNullPointer(ptrTy: ObjCTypes.ProtocolPtrTy);
3815
3816 refsArray.finishAndAddTo(parent&: values);
3817 values.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.LongTy, value: count);
3818
3819 StringRef section;
3820 if (CGM.getTriple().isOSBinFormatMachO())
3821 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3822
3823 llvm::GlobalVariable *GV =
3824 CreateMetadataVar(Name: name, Init&: values, Section: section, Align: CGM.getPointerAlign(), AddToUsed: false);
3825 return GV;
3826}
3827
3828static void PushProtocolProperties(
3829 llvm::SmallPtrSet<const IdentifierInfo *, 16> &PropertySet,
3830 SmallVectorImpl<const ObjCPropertyDecl *> &Properties,
3831 const ObjCProtocolDecl *Proto, bool IsClassProperty) {
3832 for (const auto *PD : Proto->properties()) {
3833 if (IsClassProperty != PD->isClassProperty())
3834 continue;
3835 if (!PropertySet.insert(Ptr: PD->getIdentifier()).second)
3836 continue;
3837 Properties.push_back(Elt: PD);
3838 }
3839
3840 for (const auto *P : Proto->protocols())
3841 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3842}
3843
3844/*
3845 struct _objc_property {
3846 const char * const name;
3847 const char * const attributes;
3848 };
3849
3850 struct _objc_property_list {
3851 uint32_t entsize; // sizeof (struct _objc_property)
3852 uint32_t prop_count;
3853 struct _objc_property[prop_count];
3854 };
3855*/
3856llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3857 Twine Name, const Decl *Container, const ObjCContainerDecl *OCD,
3858 const ObjCCommonTypesHelper &ObjCTypes, bool IsClassProperty) {
3859 if (IsClassProperty) {
3860 // Make this entry NULL for OS X with deployment target < 10.11, for iOS
3861 // with deployment target < 9.0.
3862 const llvm::Triple &Triple = CGM.getTarget().getTriple();
3863 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(Major: 10, Minor: 11)) ||
3864 (Triple.isiOS() && Triple.isOSVersionLT(Major: 9)))
3865 return llvm::Constant::getNullValue(Ty: ObjCTypes.PropertyListPtrTy);
3866 }
3867
3868 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3869 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3870
3871 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(Val: OCD))
3872 for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3873 for (auto *PD : ClassExt->properties()) {
3874 if (IsClassProperty != PD->isClassProperty())
3875 continue;
3876 if (PD->isDirectProperty())
3877 continue;
3878 PropertySet.insert(Ptr: PD->getIdentifier());
3879 Properties.push_back(Elt: PD);
3880 }
3881
3882 for (const auto *PD : OCD->properties()) {
3883 if (IsClassProperty != PD->isClassProperty())
3884 continue;
3885 // Don't emit duplicate metadata for properties that were already in a
3886 // class extension.
3887 if (!PropertySet.insert(Ptr: PD->getIdentifier()).second)
3888 continue;
3889 if (PD->isDirectProperty())
3890 continue;
3891 Properties.push_back(Elt: PD);
3892 }
3893
3894 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(Val: OCD)) {
3895 for (const auto *P : OID->all_referenced_protocols())
3896 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3897 } else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(Val: OCD)) {
3898 for (const auto *P : CD->protocols())
3899 PushProtocolProperties(PropertySet, Properties, Proto: P, IsClassProperty);
3900 }
3901
3902 // Return null for empty list.
3903 if (Properties.empty())
3904 return llvm::Constant::getNullValue(Ty: ObjCTypes.PropertyListPtrTy);
3905
3906 unsigned propertySize =
3907 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.PropertyTy);
3908
3909 ConstantInitBuilder builder(CGM);
3910 auto values = builder.beginStruct();
3911 values.addInt(intTy: ObjCTypes.IntTy, value: propertySize);
3912 values.addInt(intTy: ObjCTypes.IntTy, value: Properties.size());
3913 auto propertiesArray = values.beginArray(eltTy: ObjCTypes.PropertyTy);
3914 for (auto PD : Properties) {
3915 auto property = propertiesArray.beginStruct(ty: ObjCTypes.PropertyTy);
3916 property.add(value: GetPropertyName(Ident: PD->getIdentifier()));
3917 property.add(value: GetPropertyTypeString(PD, Container));
3918 property.finishAndAddTo(parent&: propertiesArray);
3919 }
3920 propertiesArray.finishAndAddTo(parent&: values);
3921
3922 StringRef Section;
3923 if (CGM.getTriple().isOSBinFormatMachO())
3924 Section = (ObjCABI == 2) ? "__DATA, __objc_const"
3925 : "__OBJC,__property,regular,no_dead_strip";
3926
3927 llvm::GlobalVariable *GV =
3928 CreateMetadataVar(Name, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
3929 return GV;
3930}
3931
3932llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3933 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3934 const ObjCCommonTypesHelper &ObjCTypes) {
3935 // Return null for empty list.
3936 if (MethodTypes.empty())
3937 return llvm::Constant::getNullValue(Ty: ObjCTypes.Int8PtrPtrTy);
3938
3939 llvm::ArrayType *AT =
3940 llvm::ArrayType::get(ElementType: ObjCTypes.Int8PtrTy, NumElements: MethodTypes.size());
3941 llvm::Constant *Init = llvm::ConstantArray::get(T: AT, V: MethodTypes);
3942
3943 StringRef Section;
3944 if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3945 Section = "__DATA, __objc_const";
3946
3947 llvm::GlobalVariable *GV =
3948 CreateMetadataVar(Name, Init, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
3949 return GV;
3950}
3951
3952/*
3953 struct _objc_category {
3954 char *category_name;
3955 char *class_name;
3956 struct _objc_method_list *instance_methods;
3957 struct _objc_method_list *class_methods;
3958 struct _objc_protocol_list *protocols;
3959 uint32_t size; // sizeof(struct _objc_category)
3960 struct _objc_property_list *instance_properties;
3961 struct _objc_property_list *class_properties;
3962 };
3963*/
3964void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3965 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.CategoryTy);
3966
3967 // FIXME: This is poor design, the OCD should have a pointer to the category
3968 // decl. Additionally, note that Category can be null for the @implementation
3969 // w/o an @interface case. Sema should just create one for us as it does for
3970 // @implementation so everyone else can live life under a clear blue sky.
3971 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3972 const ObjCCategoryDecl *Category =
3973 Interface->FindCategoryDeclaration(CategoryId: OCD->getIdentifier());
3974
3975 SmallString<256> ExtName;
3976 llvm::raw_svector_ostream(ExtName)
3977 << Interface->getName() << '_' << OCD->getName();
3978
3979 ConstantInitBuilder Builder(CGM);
3980 auto Values = Builder.beginStruct(structTy: ObjCTypes.CategoryTy);
3981
3982 enum { InstanceMethods, ClassMethods, NumMethodLists };
3983 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3984 for (const auto *MD : OCD->methods()) {
3985 if (!MD->isDirectMethod())
3986 Methods[unsigned(MD->isClassMethod())].push_back(Elt: MD);
3987 }
3988
3989 Values.add(value: GetClassName(RuntimeName: OCD->getName()));
3990 Values.add(value: GetClassName(RuntimeName: Interface->getObjCRuntimeNameAsString()));
3991 LazySymbols.insert(X: Interface->getIdentifier());
3992
3993 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryInstanceMethods,
3994 Methods: Methods[InstanceMethods]));
3995 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryClassMethods,
3996 Methods: Methods[ClassMethods]));
3997 if (Category) {
3998 Values.add(value: EmitProtocolList(name: "OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3999 begin: Category->protocol_begin(),
4000 end: Category->protocol_end()));
4001 } else {
4002 Values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
4003 }
4004 Values.addInt(intTy: ObjCTypes.IntTy, value: Size);
4005
4006 // If there is no category @interface then there can be no properties.
4007 if (Category) {
4008 Values.add(value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + ExtName.str(), Container: OCD,
4009 OCD: Category, ObjCTypes, IsClassProperty: false));
4010 Values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), Container: OCD,
4011 OCD: Category, ObjCTypes, IsClassProperty: true));
4012 } else {
4013 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
4014 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
4015 }
4016
4017 llvm::GlobalVariable *GV = CreateMetadataVar(
4018 Name: "OBJC_CATEGORY_" + ExtName.str(), Init&: Values,
4019 Section: "__OBJC,__category,regular,no_dead_strip", Align: CGM.getPointerAlign(), AddToUsed: true);
4020 DefinedCategories.push_back(Elt: GV);
4021 DefinedCategoryNames.insert(X: llvm::CachedHashString(ExtName));
4022 // method definition entries must be clear for next implementation.
4023 MethodDefinitions.clear();
4024}
4025
4026// clang-format off
4027enum FragileClassFlags {
4028 /// Apparently: is not a meta-class.
4029 FragileABI_Class_Factory = 0x00001,
4030
4031 /// Is a meta-class.
4032 FragileABI_Class_Meta = 0x00002,
4033
4034 /// Has a non-trivial constructor or destructor.
4035 FragileABI_Class_HasCXXStructors = 0x02000,
4036
4037 /// Has hidden visibility.
4038 FragileABI_Class_Hidden = 0x20000,
4039
4040 /// Class implementation was compiled under ARC.
4041 FragileABI_Class_CompiledByARC = 0x04000000,
4042
4043 /// Class implementation was compiled under MRC and has MRC weak ivars.
4044 /// Exclusive with CompiledByARC.
4045 FragileABI_Class_HasMRCWeakIvars = 0x08000000,
4046};
4047
4048enum NonFragileClassFlags {
4049 /// Is a meta-class.
4050 NonFragileABI_Class_Meta = 0x00001,
4051
4052 /// Is a root class.
4053 NonFragileABI_Class_Root = 0x00002,
4054
4055 /// Has a non-trivial constructor or destructor.
4056 NonFragileABI_Class_HasCXXStructors = 0x00004,
4057
4058 /// Has hidden visibility.
4059 NonFragileABI_Class_Hidden = 0x00010,
4060
4061 /// Has the exception attribute.
4062 NonFragileABI_Class_Exception = 0x00020,
4063
4064 /// (Obsolete) ARC-specific: this class has a .release_ivars method
4065 NonFragileABI_Class_HasIvarReleaser = 0x00040,
4066
4067 /// Class implementation was compiled under ARC.
4068 NonFragileABI_Class_CompiledByARC = 0x00080,
4069
4070 /// Class has non-trivial destructors, but zero-initialization is okay.
4071 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,
4072
4073 /// Class implementation was compiled under MRC and has MRC weak ivars.
4074 /// Exclusive with CompiledByARC.
4075 NonFragileABI_Class_HasMRCWeakIvars = 0x00200,
4076};
4077// clang-format on
4078
4079static bool hasWeakMember(QualType type) {
4080 if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
4081 return true;
4082 }
4083
4084 if (auto *RD = type->getAsRecordDecl()) {
4085 for (auto *field : RD->fields()) {
4086 if (hasWeakMember(type: field->getType()))
4087 return true;
4088 }
4089 }
4090
4091 return false;
4092}
4093
4094/// For compatibility, we only want to set the "HasMRCWeakIvars" flag
4095/// (and actually fill in a layout string) if we really do have any
4096/// __weak ivars.
4097static bool hasMRCWeakIvars(CodeGenModule &CGM,
4098 const ObjCImplementationDecl *ID) {
4099 if (!CGM.getLangOpts().ObjCWeak)
4100 return false;
4101 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
4102
4103 for (const ObjCIvarDecl *ivar =
4104 ID->getClassInterface()->all_declared_ivar_begin();
4105 ivar; ivar = ivar->getNextIvar()) {
4106 if (hasWeakMember(type: ivar->getType()))
4107 return true;
4108 }
4109
4110 return false;
4111}
4112
4113/*
4114 struct _objc_class {
4115 Class isa;
4116 Class super_class;
4117 const char *name;
4118 long version;
4119 long info;
4120 long instance_size;
4121 struct _objc_ivar_list *ivars;
4122 struct _objc_method_list *methods;
4123 struct _objc_cache *cache;
4124 struct _objc_protocol_list *protocols;
4125 // Objective-C 1.0 extensions (<rdr://4585769>)
4126 const char *ivar_layout;
4127 struct _objc_class_ext *ext;
4128 };
4129
4130 See EmitClassExtension();
4131*/
4132void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
4133 IdentifierInfo *RuntimeName =
4134 &CGM.getContext().Idents.get(Name: ID->getObjCRuntimeNameAsString());
4135 DefinedSymbols.insert(X: RuntimeName);
4136
4137 std::string ClassName = ID->getNameAsString();
4138 // FIXME: Gross
4139 ObjCInterfaceDecl *Interface =
4140 const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());
4141 llvm::Constant *Protocols =
4142 EmitProtocolList(name: "OBJC_CLASS_PROTOCOLS_" + ID->getName(),
4143 begin: Interface->all_referenced_protocol_begin(),
4144 end: Interface->all_referenced_protocol_end());
4145 unsigned Flags = FragileABI_Class_Factory;
4146 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
4147 Flags |= FragileABI_Class_HasCXXStructors;
4148
4149 bool hasMRCWeak = false;
4150
4151 if (CGM.getLangOpts().ObjCAutoRefCount)
4152 Flags |= FragileABI_Class_CompiledByARC;
4153 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
4154 Flags |= FragileABI_Class_HasMRCWeakIvars;
4155
4156 CharUnits Size = CGM.getContext()
4157 .getASTObjCInterfaceLayout(D: ID->getClassInterface())
4158 .getSize();
4159
4160 // FIXME: Set CXX-structors flag.
4161 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4162 Flags |= FragileABI_Class_Hidden;
4163
4164 enum { InstanceMethods, ClassMethods, NumMethodLists };
4165 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4166 for (const auto *MD : ID->methods()) {
4167 if (!MD->isDirectMethod())
4168 Methods[unsigned(MD->isClassMethod())].push_back(Elt: MD);
4169 }
4170
4171 for (const auto *PID : ID->property_impls()) {
4172 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
4173 if (PID->getPropertyDecl()->isDirectProperty())
4174 continue;
4175 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4176 if (GetMethodDefinition(MD))
4177 Methods[InstanceMethods].push_back(Elt: MD);
4178 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4179 if (GetMethodDefinition(MD))
4180 Methods[InstanceMethods].push_back(Elt: MD);
4181 }
4182 }
4183
4184 ConstantInitBuilder builder(CGM);
4185 auto values = builder.beginStruct(structTy: ObjCTypes.ClassTy);
4186 values.add(value: EmitMetaClass(ID, Protocols, Methods: Methods[ClassMethods]));
4187 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
4188 // Record a reference to the super class.
4189 LazySymbols.insert(X: Super->getIdentifier());
4190
4191 values.add(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
4192 } else {
4193 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
4194 }
4195 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
4196 // Version is always 0.
4197 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
4198 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
4199 values.addInt(intTy: ObjCTypes.LongTy, value: Size.getQuantity());
4200 values.add(value: EmitIvarList(ID, ForClass: false));
4201 values.add(value: emitMethodList(Name: ID->getName(), MLT: MethodListType::InstanceMethods,
4202 Methods: Methods[InstanceMethods]));
4203 // cache is always NULL.
4204 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
4205 values.add(value: Protocols);
4206 values.add(value: BuildStrongIvarLayout(OI: ID, beginOffset: CharUnits::Zero(), endOffset: Size));
4207 values.add(value: EmitClassExtension(ID, instanceSize: Size, hasMRCWeakIvars: hasMRCWeak,
4208 /*isMetaclass*/ false));
4209
4210 std::string Name("OBJC_CLASS_");
4211 Name += ClassName;
4212 const char *Section = "__OBJC,__class,regular,no_dead_strip";
4213 // Check for a forward reference.
4214 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4215 if (GV) {
4216 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4217 "Forward metaclass reference has incorrect type.");
4218 values.finishAndSetAsInitializer(global: GV);
4219 GV->setSection(Section);
4220 GV->setAlignment(CGM.getPointerAlign().getAsAlign());
4221 CGM.addCompilerUsedGlobal(GV);
4222 } else
4223 GV = CreateMetadataVar(Name, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: true);
4224 DefinedClasses.push_back(Elt: GV);
4225 ImplementedClasses.push_back(Elt: Interface);
4226 // method definition entries must be clear for next implementation.
4227 MethodDefinitions.clear();
4228}
4229
4230llvm::Constant *
4231CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
4232 llvm::Constant *Protocols,
4233 ArrayRef<const ObjCMethodDecl *> Methods) {
4234 unsigned Flags = FragileABI_Class_Meta;
4235 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassTy);
4236
4237 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4238 Flags |= FragileABI_Class_Hidden;
4239
4240 ConstantInitBuilder builder(CGM);
4241 auto values = builder.beginStruct(structTy: ObjCTypes.ClassTy);
4242 // The isa for the metaclass is the root of the hierarchy.
4243 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4244 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4245 Root = Super;
4246 values.add(value: GetClassName(RuntimeName: Root->getObjCRuntimeNameAsString()));
4247 // The super class for the metaclass is emitted as the name of the
4248 // super class. The runtime fixes this up to point to the
4249 // *metaclass* for the super class.
4250 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
4251 values.add(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
4252 } else {
4253 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
4254 }
4255 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
4256 // Version is always 0.
4257 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
4258 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
4259 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
4260 values.add(value: EmitIvarList(ID, ForClass: true));
4261 values.add(
4262 value: emitMethodList(Name: ID->getName(), MLT: MethodListType::ClassMethods, Methods));
4263 // cache is always NULL.
4264 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
4265 values.add(value: Protocols);
4266 // ivar_layout for metaclass is always NULL.
4267 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
4268 // The class extension is used to store class properties for metaclasses.
4269 values.add(value: EmitClassExtension(ID, instanceSize: CharUnits::Zero(), hasMRCWeakIvars: false /*hasMRCWeak*/,
4270 /*isMetaclass*/ true));
4271
4272 std::string Name("OBJC_METACLASS_");
4273 Name += ID->getName();
4274
4275 // Check for a forward reference.
4276 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4277 if (GV) {
4278 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4279 "Forward metaclass reference has incorrect type.");
4280 values.finishAndSetAsInitializer(global: GV);
4281 } else {
4282 GV = values.finishAndCreateGlobal(args&: Name, args: CGM.getPointerAlign(),
4283 /*constant*/ args: false,
4284 args: llvm::GlobalValue::PrivateLinkage);
4285 }
4286 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
4287 CGM.addCompilerUsedGlobal(GV);
4288
4289 return GV;
4290}
4291
4292llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
4293 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
4294
4295 // FIXME: Should we look these up somewhere other than the module. Its a bit
4296 // silly since we only generate these while processing an implementation, so
4297 // exactly one pointer would work if know when we entered/exitted an
4298 // implementation block.
4299
4300 // Check for an existing forward reference.
4301 // Previously, metaclass with internal linkage may have been defined.
4302 // pass 'true' as 2nd argument so it is returned.
4303 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4304 if (!GV)
4305 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4306 llvm::GlobalValue::PrivateLinkage, nullptr,
4307 Name);
4308
4309 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4310 "Forward metaclass reference has incorrect type.");
4311 return GV;
4312}
4313
4314llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
4315 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
4316 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, AllowInternal: true);
4317
4318 if (!GV)
4319 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4320 llvm::GlobalValue::PrivateLinkage, nullptr,
4321 Name);
4322
4323 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4324 "Forward class metadata reference has incorrect type.");
4325 return GV;
4326}
4327
4328/*
4329 Emit a "class extension", which in this specific context means extra
4330 data that doesn't fit in the normal fragile-ABI class structure, and
4331 has nothing to do with the language concept of a class extension.
4332
4333 struct objc_class_ext {
4334 uint32_t size;
4335 const char *weak_ivar_layout;
4336 struct _objc_property_list *properties;
4337 };
4338*/
4339llvm::Constant *CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
4340 CharUnits InstanceSize,
4341 bool hasMRCWeakIvars,
4342 bool isMetaclass) {
4343 // Weak ivar layout.
4344 llvm::Constant *layout;
4345 if (isMetaclass) {
4346 layout = llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy);
4347 } else {
4348 layout = BuildWeakIvarLayout(OI: ID, beginOffset: CharUnits::Zero(), endOffset: InstanceSize,
4349 hasMRCWeakIvars);
4350 }
4351
4352 // Properties.
4353 llvm::Constant *propertyList =
4354 EmitPropertyList(Name: (isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")
4355 : Twine("_OBJC_$_PROP_LIST_")) +
4356 ID->getName(),
4357 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: isMetaclass);
4358
4359 // Return null if no extension bits are used.
4360 if (layout->isNullValue() && propertyList->isNullValue()) {
4361 return llvm::Constant::getNullValue(Ty: ObjCTypes.ClassExtensionPtrTy);
4362 }
4363
4364 uint64_t size =
4365 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassExtensionTy);
4366
4367 ConstantInitBuilder builder(CGM);
4368 auto values = builder.beginStruct(structTy: ObjCTypes.ClassExtensionTy);
4369 values.addInt(intTy: ObjCTypes.IntTy, value: size);
4370 values.add(value: layout);
4371 values.add(value: propertyList);
4372
4373 return CreateMetadataVar(Name: "OBJC_CLASSEXT_" + ID->getName(), Init&: values,
4374 Section: "__OBJC,__class_ext,regular,no_dead_strip",
4375 Align: CGM.getPointerAlign(), AddToUsed: true);
4376}
4377
4378/*
4379 struct objc_ivar {
4380 char *ivar_name;
4381 char *ivar_type;
4382 int ivar_offset;
4383 };
4384
4385 struct objc_ivar_list {
4386 int ivar_count;
4387 struct objc_ivar list[count];
4388 };
4389*/
4390llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
4391 bool ForClass) {
4392 // When emitting the root class GCC emits ivar entries for the
4393 // actual class structure. It is not clear if we need to follow this
4394 // behavior; for now lets try and get away with not doing it. If so,
4395 // the cleanest solution would be to make up an ObjCInterfaceDecl
4396 // for the class.
4397 if (ForClass)
4398 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListPtrTy);
4399
4400 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4401
4402 ConstantInitBuilder builder(CGM);
4403 auto ivarList = builder.beginStruct();
4404 auto countSlot = ivarList.addPlaceholder();
4405 auto ivars = ivarList.beginArray(eltTy: ObjCTypes.IvarTy);
4406
4407 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
4408 IVD = IVD->getNextIvar()) {
4409 // Ignore unnamed bit-fields.
4410 if (!IVD->getDeclName())
4411 continue;
4412
4413 auto ivar = ivars.beginStruct(ty: ObjCTypes.IvarTy);
4414 ivar.add(value: GetMethodVarName(Ident: IVD->getIdentifier()));
4415 ivar.add(value: GetMethodVarType(D: IVD));
4416 ivar.addInt(intTy: ObjCTypes.IntTy, value: ComputeIvarBaseOffset(CGM, OID, Ivar: IVD));
4417 ivar.finishAndAddTo(parent&: ivars);
4418 }
4419
4420 // Return null for empty list.
4421 auto count = ivars.size();
4422 if (count == 0) {
4423 ivars.abandon();
4424 ivarList.abandon();
4425 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListPtrTy);
4426 }
4427
4428 ivars.finishAndAddTo(parent&: ivarList);
4429 ivarList.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.IntTy, value: count);
4430
4431 llvm::GlobalVariable *GV;
4432 GV = CreateMetadataVar(Name: "OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init&: ivarList,
4433 Section: "__OBJC,__instance_vars,regular,no_dead_strip",
4434 Align: CGM.getPointerAlign(), AddToUsed: true);
4435 return GV;
4436}
4437
4438/// Build a struct objc_method_description constant for the given method.
4439///
4440/// struct objc_method_description {
4441/// SEL method_name;
4442/// char *method_types;
4443/// };
4444void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4445 const ObjCMethodDecl *MD) {
4446 auto description = builder.beginStruct(ty: ObjCTypes.MethodDescriptionTy);
4447 description.add(value: GetMethodVarName(Sel: MD->getSelector()));
4448 description.add(value: GetMethodVarType(D: MD));
4449 description.finishAndAddTo(parent&: builder);
4450}
4451
4452/// Build a struct objc_method constant for the given method.
4453///
4454/// struct objc_method {
4455/// SEL method_name;
4456/// char *method_types;
4457/// void *method;
4458/// };
4459void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4460 const ObjCMethodDecl *MD) {
4461 llvm::Function *fn = GetMethodDefinition(MD);
4462 assert(fn && "no definition registered for method");
4463
4464 auto method = builder.beginStruct(ty: ObjCTypes.MethodTy);
4465 method.add(value: GetMethodVarName(Sel: MD->getSelector()));
4466 method.add(value: GetMethodVarType(D: MD));
4467 method.add(value: fn);
4468 method.finishAndAddTo(parent&: builder);
4469}
4470
4471/// Build a struct objc_method_list or struct objc_method_description_list,
4472/// as appropriate.
4473///
4474/// struct objc_method_list {
4475/// struct objc_method_list *obsolete;
4476/// int count;
4477/// struct objc_method methods_list[count];
4478/// };
4479///
4480/// struct objc_method_description_list {
4481/// int count;
4482/// struct objc_method_description list[count];
4483/// };
4484llvm::Constant *
4485CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4486 ArrayRef<const ObjCMethodDecl *> methods) {
4487 StringRef prefix;
4488 StringRef section;
4489 bool forProtocol = false;
4490 switch (MLT) {
4491 case MethodListType::CategoryInstanceMethods:
4492 prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";
4493 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4494 forProtocol = false;
4495 break;
4496 case MethodListType::CategoryClassMethods:
4497 prefix = "OBJC_CATEGORY_CLASS_METHODS_";
4498 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4499 forProtocol = false;
4500 break;
4501 case MethodListType::InstanceMethods:
4502 prefix = "OBJC_INSTANCE_METHODS_";
4503 section = "__OBJC,__inst_meth,regular,no_dead_strip";
4504 forProtocol = false;
4505 break;
4506 case MethodListType::ClassMethods:
4507 prefix = "OBJC_CLASS_METHODS_";
4508 section = "__OBJC,__cls_meth,regular,no_dead_strip";
4509 forProtocol = false;
4510 break;
4511 case MethodListType::ProtocolInstanceMethods:
4512 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";
4513 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4514 forProtocol = true;
4515 break;
4516 case MethodListType::ProtocolClassMethods:
4517 prefix = "OBJC_PROTOCOL_CLASS_METHODS_";
4518 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4519 forProtocol = true;
4520 break;
4521 case MethodListType::OptionalProtocolInstanceMethods:
4522 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4523 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4524 forProtocol = true;
4525 break;
4526 case MethodListType::OptionalProtocolClassMethods:
4527 prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4528 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4529 forProtocol = true;
4530 break;
4531 }
4532
4533 // Return null for empty list.
4534 if (methods.empty())
4535 return llvm::Constant::getNullValue(
4536 Ty: forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4537 : ObjCTypes.MethodListPtrTy);
4538
4539 // For protocols, this is an objc_method_description_list, which has
4540 // a slightly different structure.
4541 if (forProtocol) {
4542 ConstantInitBuilder builder(CGM);
4543 auto values = builder.beginStruct();
4544 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
4545 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodDescriptionTy);
4546 for (auto MD : methods) {
4547 emitMethodDescriptionConstant(builder&: methodArray, MD);
4548 }
4549 methodArray.finishAndAddTo(parent&: values);
4550
4551 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
4552 Align: CGM.getPointerAlign(), AddToUsed: true);
4553 return GV;
4554 }
4555
4556 // Otherwise, it's an objc_method_list.
4557 ConstantInitBuilder builder(CGM);
4558 auto values = builder.beginStruct();
4559 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
4560 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
4561 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodTy);
4562 for (auto MD : methods) {
4563 if (!MD->isDirectMethod())
4564 emitMethodConstant(builder&: methodArray, MD);
4565 }
4566 methodArray.finishAndAddTo(parent&: values);
4567
4568 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
4569 Align: CGM.getPointerAlign(), AddToUsed: true);
4570 return GV;
4571}
4572
4573llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
4574 const ObjCContainerDecl *CD) {
4575 llvm::Function *Method;
4576
4577 if (OMD->isDirectMethod()) {
4578 // Returns DirectMethodInfo& containing both Implementation and Thunk
4579 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4580 Method = Info.Implementation; // Extract implementation for body generation
4581 } else {
4582 auto Name = getSymbolNameForMethod(method: OMD);
4583
4584 CodeGenTypes &Types = CGM.getTypes();
4585 llvm::FunctionType *MethodTy =
4586 Types.GetFunctionType(Info: Types.arrangeObjCMethodDeclaration(MD: OMD));
4587 Method = llvm::Function::Create(
4588 Ty: MethodTy, Linkage: llvm::GlobalValue::InternalLinkage, N: Name, M: &CGM.getModule());
4589 }
4590
4591 MethodDefinitions.insert(KV: std::make_pair(x&: OMD, y&: Method));
4592
4593 return Method;
4594}
4595
4596/// Generate or retrieve a direct method info.
4597CGObjCCommonMac::DirectMethodInfo &
4598CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
4599 const ObjCContainerDecl *CD) {
4600 auto *COMD = OMD->getCanonicalDecl();
4601
4602 // Fast path: return cached entry if this is not an implementation (no body)
4603 // or if the return types match between declaration and implementation.
4604 auto Cached = DirectMethodDefinitions.find(Val: COMD);
4605 if (Cached != DirectMethodDefinitions.end()) {
4606 if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType())
4607 return Cached->second;
4608 }
4609
4610 CodeGenTypes &Types = CGM.getTypes();
4611 llvm::FunctionType *MethodTy =
4612 Types.GetFunctionType(Info: Types.arrangeObjCMethodDeclaration(MD: OMD));
4613 std::string Name =
4614 getSymbolNameForMethod(method: OMD, /*includeCategoryName*/ false,
4615 useDirectABI: CGM.isObjCDirectPreconditionThunkEnabled());
4616 std::string ThunkName = Name + "_thunk";
4617
4618 // Replace OldFn with NewFn: transfer name, replace all uses, and erase.
4619 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4620 NewFn->takeName(V: OldFn);
4621 OldFn->replaceAllUsesWith(V: NewFn);
4622 OldFn->eraseFromParent();
4623 };
4624
4625 // Check if the function already exists in the module (created by Clang or
4626 // Swift).
4627 llvm::Function *Fn = CGM.getModule().getFunction(Name);
4628
4629 // Function doesn't exist yet.
4630 if (!Fn) {
4631 Fn = llvm::Function::Create(Ty: MethodTy, Linkage: llvm::GlobalValue::ExternalLinkage,
4632 N: Name, M: &CGM.getModule());
4633 return DirectMethodDefinitions.insert(KV: {COMD, DirectMethodInfo(Fn)})
4634 .first->second;
4635 }
4636
4637 // Function exists with matching type.
4638 // Other frontends operating on the same module may have created the function.
4639 if (Fn->getFunctionType() == MethodTy) {
4640 // Reinforce linkage in case Swift created it with different linkage.
4641 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4642
4643 // Check if Swift also created a thunk for this method.
4644 DirectMethodInfo Info(Fn);
4645 if (llvm::Function *Thunk = CGM.getModule().getFunction(Name: ThunkName))
4646 Info.Thunk = Thunk;
4647
4648 return DirectMethodDefinitions.insert(KV: {COMD, Info}).first->second;
4649 }
4650
4651 // Function exists but with mismatched type - replace it.
4652 // This happens when Swift's optional handling differs from ObjC, or when
4653 // ObjC declaration and implementation have slightly different return types.
4654 llvm::Function *NewFn = llvm::Function::Create(
4655 Ty: MethodTy, Linkage: llvm::GlobalValue::ExternalLinkage, N: "", M: &CGM.getModule());
4656 ReplaceFunction(Fn, NewFn);
4657
4658 // Check if the thunk also needs replacement.
4659 DirectMethodInfo Info(NewFn);
4660 if (llvm::Function *OldThunk = CGM.getModule().getFunction(Name: ThunkName)) {
4661 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, Implementation: NewFn);
4662 ReplaceFunction(OldThunk, NewThunk);
4663 Info.Thunk = NewThunk;
4664 }
4665
4666 if (Cached != DirectMethodDefinitions.end()) {
4667 Cached->second = Info;
4668 return Cached->second;
4669 }
4670 return DirectMethodDefinitions.insert(KV: {COMD, Info}).first->second;
4671}
4672
4673/// Start an Objective-C direct method precondition thunk.
4674void CodeGenFunction::StartObjCDirectPreconditionThunk(
4675 const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI) {
4676 // Mark this as a thunk function to disable ARC parameter processing
4677 // and other thunk-inappropriate behavior. We don't need to retain
4678 // parameters because we're going to immediately forward them.
4679 //
4680 // Skipping ARC parameter processing is correct as long as (1) we don't
4681 // run any code that could invalidate the parameters between the start of
4682 // the thunk and the call and (2) we don't use the parameters after the
4683 // call. Both hold whether we tail-call or not. Class realization could in
4684 // theory invalidate parameters, but we assume that doesn't happen in
4685 // practice.
4686 CurFuncIsThunk = true;
4687
4688 // Build argument list for StartFunction.
4689 // We must include all parameters to match the thunk's LLVM function type.
4690 FunctionArgList FunctionArgs;
4691 FunctionArgs.push_back(Elt: OMD->getSelfDecl());
4692 FunctionArgs.append(in_start: OMD->param_begin(), in_end: OMD->param_end());
4693
4694 // The Start/Finish thunk pattern is borrowed from CGVTables.cpp
4695 // for C++ virtual method thunks, but adapted for ObjC direct methods.
4696 //
4697 // Like C++ thunks, we don't have an actual AST body for the thunk - we only
4698 // have the method's parameter declarations. Therefore, we pass empty
4699 // `GlobalDecl` to `StartFunction` ...
4700 StartFunction(GD: GlobalDecl(), RetTy: OMD->getReturnType(), Fn, FnInfo: FI, Args: FunctionArgs,
4701 Loc: OMD->getLocation(), StartLoc: OMD->getLocation());
4702
4703 // and manually set the decl afterwards so other utilities / helpers in CGF
4704 // can still access the AST (e.g. arrange function arguments)
4705 CurCodeDecl = OMD;
4706 CurFuncDecl = OMD;
4707}
4708
4709/// Finish an Objective-C direct method precondition thunk.
4710void CodeGenFunction::FinishObjCDirectPreconditionThunk() {
4711 // Create a dummy block to return the value of the thunk.
4712 //
4713 // The non-nil branch alredy returned because of musttail.
4714 // Only nil branch will jump to this return block.
4715 // If the nil check is not emitted (for class methods), this will be a dead
4716 // block.
4717 //
4718 // Either way, the LLVM optimizer will simplify it later. This is just to make
4719 // CFG happy.
4720 EmitBlock(BB: createBasicBlock(name: "dummy_ret_block"));
4721
4722 // Disable the final ARC autorelease.
4723 // Thunk functions are tailcall to actual implementation, so it doesn't need
4724 // to worry about ARC.
4725 AutoreleaseResult = false;
4726
4727 // Clear these to restore the invariants expected by
4728 // StartFunction/FinishFunction.
4729 CurCodeDecl = nullptr;
4730 CurFuncDecl = nullptr;
4731
4732 FinishFunction();
4733}
4734
4735llvm::Function *
4736CGObjCCommonMac::GenerateObjCDirectThunk(const ObjCMethodDecl *OMD,
4737 const ObjCContainerDecl *CD,
4738 llvm::Function *Implementation) {
4739
4740 assert(CGM.shouldHavePreconditionThunk(OMD) &&
4741 "Should only generate thunk when optimization enabled");
4742 assert(Implementation && "Implementation must exist");
4743
4744 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4745 std::string ThunkName = Implementation->getName().str() + "_thunk";
4746
4747 // Create thunk with linkonce_odr linkage (allows deduplication)
4748 llvm::Function *Thunk =
4749 llvm::Function::Create(Ty: ThunkTy, Linkage: llvm::GlobalValue::LinkOnceODRLinkage,
4750 N: ThunkName, M: &CGM.getModule());
4751
4752 // Thunks should always have hidden visibility, other link units will have
4753 // their own version of the (identical) thunk. If they make cross link-unit
4754 // call, they are either calling through their thunk or directly dispatching
4755 // to the true implementation, so making thunk visibile is meaningless.
4756 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4757 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4758
4759 // Start the ObjC direct thunk (sets up state and calls StartFunction)
4760 const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(MD: OMD);
4761
4762 // Create a CodeGenFunction to generate the thunk body
4763 CodeGenFunction CGF(CGM);
4764 CGF.StartObjCDirectPreconditionThunk(OMD, Fn: Thunk, FI);
4765
4766 // Set function attributes from CGFunctionInfo to ensure the thunk has
4767 // matching parameter attributes (especially sret) for musttail correctness.
4768 // We use SetLLVMFunctionAttributes rather than copying from Implementation
4769 // because Implementation may not have its attributes set yet at this point.
4770 CGM.SetLLVMFunctionAttributes(GD: GlobalDecl(OMD), Info: FI, F: Thunk, /*IsThunk=*/false);
4771 CGM.SetLLVMFunctionAttributesForDefinition(D: OMD, F: Thunk);
4772
4773 // - [self self] for class methods (class realization)
4774 // - if (self == nil) branch to nil block with zero return
4775 // - continuation block for non-nil case
4776 GenerateDirectMethodsPreconditionCheck(CGF, Fn: Thunk, OMD, CD);
4777
4778 // Now emit the musttail call to the true implementation
4779 // Collect all arguments for forwarding
4780 SmallVector<llvm::Value *, 8> Args;
4781 for (auto &Arg : Thunk->args())
4782 Args.push_back(Elt: &Arg);
4783
4784 // Create musttail call to the implementation
4785 llvm::CallInst *Call = CGF.Builder.CreateCall(Callee: Implementation, Args);
4786 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4787
4788 // Apply call-site attributes using ConstructAttributeList
4789 // When sret is used, the call must have matching sret attributes on the first
4790 // parameter for musttail to work correctly. This mirrors what C++ thunks do
4791 // in EmitMustTailThunk.
4792 unsigned CallingConv;
4793 llvm::AttributeList Attrs;
4794 CGM.ConstructAttributeList(Name: Implementation->getName(), Info: FI, CalleeInfo: GlobalDecl(OMD),
4795 Attrs, CallingConv, /*AttrOnCallSite=*/true,
4796 /*IsThunk=*/false);
4797 Call->setAttributes(Attrs);
4798 Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
4799
4800 // Immediately return the call result (musttail requirement).
4801 // For sret returns, the Apple ABI produces void-returning LLVM functions,
4802 // so checking the LLVM return type is suffice.
4803 if (ThunkTy->getReturnType()->isVoidTy())
4804 CGF.Builder.CreateRetVoid();
4805 else
4806 CGF.Builder.CreateRet(V: Call);
4807
4808 // Finish the ObjC direct thunk (creates dummy block and calls FinishFunction)
4809 CGF.FinishObjCDirectPreconditionThunk();
4810 return Thunk;
4811}
4812
4813llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4814 const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
4815 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
4816
4817 // Get from cache or populate the function declaration.
4818 // Copy by value to avoid holding a reference into DirectMethodDefinitions
4819 // DenseMap, which could be invalidated by future insertions.
4820 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4821
4822 // If thunk optimization not enabled (or variadic method which can't use
4823 // thunks), use implementation directly. Variadic methods and methods without
4824 // the optimization enabled include precondition checks in the implementation.
4825 if (!CGM.shouldHavePreconditionThunk(OMD)) {
4826 return Info.Implementation;
4827 }
4828
4829 // Thunk is lazily generated.
4830 auto getOrCreateThunk = [&]() {
4831 if (!Info.Thunk) {
4832 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Implementation: Info.Implementation);
4833 // Write back the lazily created thunk to the map.
4834 DirectMethodDefinitions.insert_or_assign(Key: OMD->getCanonicalDecl(), Val&: Info);
4835 }
4836 return Info.Thunk;
4837 };
4838
4839 if (OMD->isInstanceMethod()) {
4840 // If we can prove instance methods receiver is not null, return the true
4841 // implementation
4842 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4843 }
4844 assert(OMD->isClassMethod() &&
4845 "OMD should either be a class method or instance method");
4846
4847 // For class methods, it need to be non-null and realized before we dispatch
4848 // to true implementation
4849 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4850 ? getOrCreateThunk()
4851 : Info.Implementation;
4852}
4853
4854llvm::Value *
4855CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4856 llvm::Value *classObject,
4857 const ObjCInterfaceDecl *OID) {
4858 // Generate: self = [self self]
4859 // This forces class lazy initialization
4860 Selector SelfSel = GetNullarySelector(name: "self", Ctx&: CGM.getContext());
4861 auto ResultType = CGF.getContext().getObjCIdType();
4862 CallArgList Args;
4863
4864 RValue result = GeneratePossiblySpecializedMessageSend(
4865 CGF, Return: ReturnValueSlot(), ResultType, Sel: SelfSel, Receiver: classObject, Args, OID,
4866 Method: nullptr, isClassMessage: true);
4867
4868 return result.getScalarVal();
4869}
4870
4871void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4872 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4873 const ObjCContainerDecl *CD) {
4874 auto &Builder = CGF.Builder;
4875 bool ReceiverCanBeNull = true;
4876 auto selfAddr = CGF.GetAddrOfLocalVar(VD: OMD->getSelfDecl());
4877 auto selfValue = Builder.CreateLoad(Addr: selfAddr);
4878
4879 // Generate:
4880 //
4881 // /* for class methods only to force class lazy initialization */
4882 // self = [self self];
4883 //
4884 // /* unless the receiver is never NULL */
4885 // if (self == nil) {
4886 // return (ReturnType){ };
4887 // }
4888
4889 if (OMD->isClassMethod()) {
4890 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(Val: CD);
4891 assert(OID &&
4892 "GenerateDirectMethod() should be called with the Class Interface");
4893
4894 // TODO: If this method is inlined, the caller might know that `self` is
4895 // already initialized; for example, it might be an ordinary Objective-C
4896 // method which always receives an initialized `self`, or it might have just
4897 // forced initialization on its own.
4898 //
4899 // We should find a way to eliminate this unnecessary initialization in such
4900 // cases in LLVM.
4901
4902 // Perform class realization using the helper function
4903 llvm::Value *realizedClass = GenerateClassRealization(CGF, classObject: selfValue, OID);
4904 Builder.CreateStore(Val: realizedClass, Addr: selfAddr);
4905
4906 // Nullable `Class` expressions cannot be messaged with a direct method
4907 // so the only reason why the receive can be null would be because
4908 // of weak linking.
4909 ReceiverCanBeNull = isWeakLinkedClass(cls: OID);
4910 }
4911
4912 // Generate nil check
4913 if (ReceiverCanBeNull) {
4914 llvm::BasicBlock *SelfIsNilBlock =
4915 CGF.createBasicBlock(name: "objc_direct_method.self_is_nil");
4916 llvm::BasicBlock *ContBlock =
4917 CGF.createBasicBlock(name: "objc_direct_method.cont");
4918
4919 // if (self == nil) {
4920 auto selfTy = cast<llvm::PointerType>(Val: selfValue->getType());
4921 auto Zero = llvm::ConstantPointerNull::get(T: selfTy);
4922
4923 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
4924 Builder.CreateCondBr(Cond: Builder.CreateICmpEQ(LHS: selfValue, RHS: Zero), True: SelfIsNilBlock,
4925 False: ContBlock, BranchWeights: MDHelper.createUnlikelyBranchWeights());
4926
4927 CGF.EmitBlock(BB: SelfIsNilBlock);
4928
4929 // return (ReturnType){ };
4930 auto retTy = OMD->getReturnType();
4931 Builder.SetInsertPoint(SelfIsNilBlock);
4932 if (!retTy->isVoidType()) {
4933 CGF.EmitNullInitialization(DestPtr: CGF.ReturnValue, Ty: retTy);
4934 }
4935 CGF.EmitBranchThroughCleanup(Dest: CGF.ReturnBlock);
4936 // }
4937
4938 // rest of the body
4939 CGF.EmitBlock(BB: ContBlock);
4940 Builder.SetInsertPoint(ContBlock);
4941 }
4942}
4943
4944void CGObjCCommonMac::GenerateDirectMethodPrologue(
4945 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4946 const ObjCContainerDecl *CD) {
4947 // Generate precondition checks (class realization + nil check) if needed
4948 if (!CGM.isObjCDirectPreconditionThunkEnabled())
4949 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4950
4951 auto &Builder = CGF.Builder;
4952 // Only synthesize _cmd if it's referenced
4953 // This is the actual "prologue" work that always happens
4954 if (OMD->getCmdDecl()->isUsed()) {
4955 // `_cmd` is not a parameter to direct methods, so storage must be
4956 // explicitly declared for it.
4957 CGF.EmitVarDecl(D: *OMD->getCmdDecl());
4958 Builder.CreateStore(Val: GetSelector(CGF, Method: OMD),
4959 Addr: CGF.GetAddrOfLocalVar(VD: OMD->getCmdDecl()));
4960 }
4961}
4962
4963llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4964 Selector Sel, StringRef ClassName, const ObjCCommonTypesHelper &ObjCTypes) {
4965 assert((!ClassName.data() || !ClassName.empty()) &&
4966 "class name cannot be an empty string");
4967 auto Key = std::make_pair(x&: Sel, y&: ClassName);
4968 auto I = MethodSelectorStubs.find(Val: Key);
4969
4970 if (I != MethodSelectorStubs.end())
4971 return I->second;
4972
4973 auto *FnTy = llvm::FunctionType::get(
4974 Result: ObjCTypes.ObjectPtrTy, Params: {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4975 /*IsVarArg=*/isVarArg: true);
4976 std::string FnName;
4977
4978 if (ClassName.data())
4979 FnName = ("objc_msgSendClass$" + Sel.getAsString() + "$_OBJC_CLASS_$_" +
4980 llvm::Twine(ClassName))
4981 .str();
4982 else
4983 FnName = "objc_msgSend$" + Sel.getAsString();
4984
4985 auto *Fn =
4986 cast<llvm::Function>(Val: CGM.CreateRuntimeFunction(Ty: FnTy, Name: FnName).getCallee());
4987
4988 MethodSelectorStubs.insert(KV: std::make_pair(x&: Key, y&: Fn));
4989 return Fn;
4990}
4991
4992llvm::GlobalVariable *
4993CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &Init,
4994 StringRef Section, CharUnits Align,
4995 bool AddToUsed) {
4996 llvm::GlobalValue::LinkageTypes LT =
4997 getLinkageTypeForObjCMetadata(CGM, Section);
4998 llvm::GlobalVariable *GV =
4999 Init.finishAndCreateGlobal(args&: Name, args&: Align, /*constant*/ args: false, args&: LT);
5000 if (!Section.empty())
5001 GV->setSection(Section);
5002 if (AddToUsed)
5003 CGM.addCompilerUsedGlobal(GV);
5004 return GV;
5005}
5006
5007llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5008 llvm::Constant *Init,
5009 StringRef Section,
5010 CharUnits Align,
5011 bool AddToUsed) {
5012 llvm::Type *Ty = Init->getType();
5013 llvm::GlobalValue::LinkageTypes LT =
5014 getLinkageTypeForObjCMetadata(CGM, Section);
5015 llvm::GlobalVariable *GV =
5016 new llvm::GlobalVariable(CGM.getModule(), Ty, false, LT, Init, Name);
5017 if (!Section.empty())
5018 GV->setSection(Section);
5019 GV->setAlignment(Align.getAsAlign());
5020 if (AddToUsed)
5021 CGM.addCompilerUsedGlobal(GV);
5022 return GV;
5023}
5024
5025llvm::GlobalVariable *
5026CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,
5027 bool ForceNonFragileABI,
5028 bool NullTerminate) {
5029 StringRef Label;
5030 switch (Type) {
5031 case ObjCLabelType::ClassName:
5032 Label = "OBJC_CLASS_NAME_";
5033 break;
5034 case ObjCLabelType::MethodVarName:
5035 Label = "OBJC_METH_VAR_NAME_";
5036 break;
5037 case ObjCLabelType::MethodVarType:
5038 Label = "OBJC_METH_VAR_TYPE_";
5039 break;
5040 case ObjCLabelType::PropertyName:
5041 Label = "OBJC_PROP_NAME_ATTR_";
5042 break;
5043 case ObjCLabelType::LayoutBitMap:
5044 Label = "OBJC_LAYOUT_BITMAP_";
5045 break;
5046 }
5047
5048 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5049
5050 StringRef Section;
5051 switch (Type) {
5052 case ObjCLabelType::ClassName:
5053 Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"
5054 : "__TEXT,__cstring,cstring_literals";
5055 break;
5056 case ObjCLabelType::MethodVarName:
5057 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5058 : "__TEXT,__cstring,cstring_literals";
5059 break;
5060 case ObjCLabelType::MethodVarType:
5061 Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"
5062 : "__TEXT,__cstring,cstring_literals";
5063 break;
5064 case ObjCLabelType::PropertyName:
5065 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5066 : "__TEXT,__cstring,cstring_literals";
5067 break;
5068 case ObjCLabelType::LayoutBitMap:
5069 Section = "__TEXT,__cstring,cstring_literals";
5070 break;
5071 }
5072
5073 llvm::Constant *Value =
5074 llvm::ConstantDataArray::getString(Context&: VMContext, Initializer: Name, AddNull: NullTerminate);
5075 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
5076 CGM.getModule(), Value->getType(),
5077 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Value, Label);
5078 if (CGM.getTriple().isOSBinFormatMachO())
5079 GV->setSection(Section);
5080 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5081 GV->setAlignment(CharUnits::One().getAsAlign());
5082 CGM.addCompilerUsedGlobal(GV);
5083
5084 return GV;
5085}
5086
5087llvm::Function *CGObjCMac::ModuleInitFunction() {
5088 // Abuse this interface function as a place to finalize.
5089 FinishModule();
5090 return nullptr;
5091}
5092
5093llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5094 return ObjCTypes.getGetPropertyFn();
5095}
5096
5097llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5098 return ObjCTypes.getSetPropertyFn();
5099}
5100
5101llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
5102 bool copy) {
5103 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5104}
5105
5106llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5107 return ObjCTypes.getCopyStructFn();
5108}
5109
5110llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5111 return ObjCTypes.getCopyStructFn();
5112}
5113
5114llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5115 return ObjCTypes.getCppAtomicObjectFunction();
5116}
5117
5118llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5119 return ObjCTypes.getCppAtomicObjectFunction();
5120}
5121
5122llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5123 return ObjCTypes.getEnumerationMutationFn();
5124}
5125
5126void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
5127 return EmitTryOrSynchronizedStmt(CGF, S);
5128}
5129
5130void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5131 const ObjCAtSynchronizedStmt &S) {
5132 return EmitTryOrSynchronizedStmt(CGF, S);
5133}
5134
5135namespace {
5136struct PerformFragileFinally final : EHScopeStack::Cleanup {
5137 const Stmt &S;
5138 Address SyncArgSlot;
5139 Address CallTryExitVar;
5140 Address ExceptionData;
5141 ObjCTypesHelper &ObjCTypes;
5142 PerformFragileFinally(const Stmt *S, Address SyncArgSlot,
5143 Address CallTryExitVar, Address ExceptionData,
5144 ObjCTypesHelper *ObjCTypes)
5145 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5146 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5147
5148 void Emit(CodeGenFunction &CGF, Flags flags) override {
5149 // Check whether we need to call objc_exception_try_exit.
5150 // In optimized code, this branch will always be folded.
5151 llvm::BasicBlock *FinallyCallExit =
5152 CGF.createBasicBlock(name: "finally.call_exit");
5153 llvm::BasicBlock *FinallyNoCallExit =
5154 CGF.createBasicBlock(name: "finally.no_call_exit");
5155 CGF.Builder.CreateCondBr(Cond: CGF.Builder.CreateLoad(Addr: CallTryExitVar),
5156 True: FinallyCallExit, False: FinallyNoCallExit);
5157
5158 CGF.EmitBlock(BB: FinallyCallExit);
5159 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryExitFn(),
5160 args: ExceptionData.emitRawPointer(CGF));
5161
5162 CGF.EmitBlock(BB: FinallyNoCallExit);
5163
5164 if (isa<ObjCAtTryStmt>(Val: S)) {
5165 if (const ObjCAtFinallyStmt *FinallyStmt =
5166 cast<ObjCAtTryStmt>(Val: S).getFinallyStmt()) {
5167 // Don't try to do the @finally if this is an EH cleanup.
5168 if (flags.isForEHCleanup())
5169 return;
5170
5171 // Save the current cleanup destination in case there's
5172 // control flow inside the finally statement.
5173 llvm::Value *CurCleanupDest =
5174 CGF.Builder.CreateLoad(Addr: CGF.getNormalCleanupDestSlot());
5175
5176 CGF.EmitStmt(S: FinallyStmt->getFinallyBody());
5177
5178 if (CGF.HaveInsertPoint()) {
5179 CGF.Builder.CreateStore(Val: CurCleanupDest,
5180 Addr: CGF.getNormalCleanupDestSlot());
5181 } else {
5182 // Currently, the end of the cleanup must always exist.
5183 CGF.EnsureInsertPoint();
5184 }
5185 }
5186 } else {
5187 // Emit objc_sync_exit(expr); as finally's sole statement for
5188 // @synchronized.
5189 llvm::Value *SyncArg = CGF.Builder.CreateLoad(Addr: SyncArgSlot);
5190 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getSyncExitFn(), args: SyncArg);
5191 }
5192 }
5193};
5194
5195class FragileHazards {
5196 CodeGenFunction &CGF;
5197 SmallVector<llvm::Value *, 20> Locals;
5198 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5199
5200 llvm::InlineAsm *ReadHazard;
5201 llvm::InlineAsm *WriteHazard;
5202
5203 llvm::FunctionType *GetAsmFnType();
5204
5205 void collectLocals();
5206 void emitReadHazard(CGBuilderTy &Builder);
5207
5208public:
5209 FragileHazards(CodeGenFunction &CGF);
5210
5211 void emitWriteHazard();
5212 void emitHazardsInNewBlocks();
5213};
5214} // end anonymous namespace
5215
5216/// Create the fragile-ABI read and write hazards based on the current
5217/// state of the function, which is presumed to be immediately prior
5218/// to a @try block. These hazards are used to maintain correct
5219/// semantics in the face of optimization and the fragile ABI's
5220/// cavalier use of setjmp/longjmp.
5221FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5222 collectLocals();
5223
5224 if (Locals.empty())
5225 return;
5226
5227 // Collect all the blocks in the function.
5228 for (llvm::BasicBlock &BB : *CGF.CurFn)
5229 BlocksBeforeTry.insert(V: &BB);
5230
5231 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5232
5233 // Create a read hazard for the allocas. This inhibits dead-store
5234 // optimizations and forces the values to memory. This hazard is
5235 // inserted before any 'throwing' calls in the protected scope to
5236 // reflect the possibility that the variables might be read from the
5237 // catch block if the call throws.
5238 {
5239 std::string Constraint;
5240 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5241 if (I)
5242 Constraint += ',';
5243 Constraint += "*m";
5244 }
5245
5246 ReadHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
5247 }
5248
5249 // Create a write hazard for the allocas. This inhibits folding
5250 // loads across the hazard. This hazard is inserted at the
5251 // beginning of the catch path to reflect the possibility that the
5252 // variables might have been written within the protected scope.
5253 {
5254 std::string Constraint;
5255 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5256 if (I)
5257 Constraint += ',';
5258 Constraint += "=*m";
5259 }
5260
5261 WriteHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
5262 }
5263}
5264
5265/// Emit a write hazard at the current location.
5266void FragileHazards::emitWriteHazard() {
5267 if (Locals.empty())
5268 return;
5269
5270 llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(callee: WriteHazard, args: Locals);
5271 for (auto Pair : llvm::enumerate(First&: Locals))
5272 Call->addParamAttr(
5273 ArgNo: Pair.index(),
5274 Attr: llvm::Attribute::get(
5275 Context&: CGF.getLLVMContext(), Kind: llvm::Attribute::ElementType,
5276 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
5277}
5278
5279void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
5280 assert(!Locals.empty());
5281 llvm::CallInst *call = Builder.CreateCall(Callee: ReadHazard, Args: Locals);
5282 call->setDoesNotThrow();
5283 call->setCallingConv(CGF.getRuntimeCC());
5284 for (auto Pair : llvm::enumerate(First&: Locals))
5285 call->addParamAttr(
5286 ArgNo: Pair.index(),
5287 Attr: llvm::Attribute::get(
5288 Context&: Builder.getContext(), Kind: llvm::Attribute::ElementType,
5289 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
5290}
5291
5292/// Emit read hazards in all the protected blocks, i.e. all the blocks
5293/// which have been inserted since the beginning of the try.
5294void FragileHazards::emitHazardsInNewBlocks() {
5295 if (Locals.empty())
5296 return;
5297
5298 CGBuilderTy Builder(CGF.CGM, CGF.getLLVMContext());
5299
5300 // Iterate through all blocks, skipping those prior to the try.
5301 for (llvm::BasicBlock &BB : *CGF.CurFn) {
5302 if (BlocksBeforeTry.count(V: &BB))
5303 continue;
5304
5305 // Walk through all the calls in the block.
5306 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5307 ++BI) {
5308 llvm::Instruction &I = *BI;
5309
5310 // Ignore instructions that aren't non-intrinsic calls.
5311 // These are the only calls that can possibly call longjmp.
5312 if (!isa<llvm::CallInst>(Val: I) && !isa<llvm::InvokeInst>(Val: I))
5313 continue;
5314 if (isa<llvm::IntrinsicInst>(Val: I))
5315 continue;
5316
5317 // Ignore call sites marked nounwind. This may be questionable,
5318 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
5319 if (cast<llvm::CallBase>(Val&: I).doesNotThrow())
5320 continue;
5321
5322 // Insert a read hazard before the call. This will ensure that
5323 // any writes to the locals are performed before making the
5324 // call. If the call throws, then this is sufficient to
5325 // guarantee correctness as long as it doesn't also write to any
5326 // locals.
5327 Builder.SetInsertPoint(TheBB: &BB, IP: BI);
5328 emitReadHazard(Builder);
5329 }
5330 }
5331}
5332
5333static void addIfPresent(llvm::DenseSet<llvm::Value *> &S, Address V) {
5334 if (V.isValid())
5335 if (llvm::Value *Ptr = V.getBasePointer())
5336 S.insert(V: Ptr);
5337}
5338
5339void FragileHazards::collectLocals() {
5340 // Compute a set of allocas to ignore.
5341 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5342 addIfPresent(S&: AllocasToIgnore, V: CGF.ReturnValue);
5343 addIfPresent(S&: AllocasToIgnore, V: CGF.NormalCleanupDest);
5344
5345 // Collect all the allocas currently in the function. This is
5346 // probably way too aggressive.
5347 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
5348 for (llvm::Instruction &I : Entry)
5349 if (isa<llvm::AllocaInst>(Val: I) && !AllocasToIgnore.count(V: &I))
5350 Locals.push_back(Elt: &I);
5351}
5352
5353llvm::FunctionType *FragileHazards::GetAsmFnType() {
5354 SmallVector<llvm::Type *, 16> tys(Locals.size());
5355 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
5356 tys[i] = Locals[i]->getType();
5357 return llvm::FunctionType::get(Result: CGF.VoidTy, Params: tys, isVarArg: false);
5358}
5359
5360/*
5361
5362 Objective-C setjmp-longjmp (sjlj) Exception Handling
5363 --
5364
5365 A catch buffer is a setjmp buffer plus:
5366 - a pointer to the exception that was caught
5367 - a pointer to the previous exception data buffer
5368 - two pointers of reserved storage
5369 Therefore catch buffers form a stack, with a pointer to the top
5370 of the stack kept in thread-local storage.
5371
5372 objc_exception_try_enter pushes a catch buffer onto the EH stack.
5373 objc_exception_try_exit pops the given catch buffer, which is
5374 required to be the top of the EH stack.
5375 objc_exception_throw pops the top of the EH stack, writes the
5376 thrown exception into the appropriate field, and longjmps
5377 to the setjmp buffer. It crashes the process (with a printf
5378 and an abort()) if there are no catch buffers on the stack.
5379 objc_exception_extract just reads the exception pointer out of the
5380 catch buffer.
5381
5382 There's no reason an implementation couldn't use a light-weight
5383 setjmp here --- something like __builtin_setjmp, but API-compatible
5384 with the heavyweight setjmp. This will be more important if we ever
5385 want to implement correct ObjC/C++ exception interactions for the
5386 fragile ABI.
5387
5388 Note that for this use of setjmp/longjmp to be correct in the presence of
5389 optimization, we use inline assembly on the set of local variables to force
5390 flushing locals to memory immediately before any protected calls and to
5391 inhibit optimizing locals across the setjmp->catch edge.
5392
5393 The basic framework for a @try-catch-finally is as follows:
5394 {
5395 objc_exception_data d;
5396 id _rethrow = null;
5397 bool _call_try_exit = true;
5398
5399 objc_exception_try_enter(&d);
5400 if (!setjmp(d.jmp_buf)) {
5401 ... try body ...
5402 } else {
5403 // exception path
5404 id _caught = objc_exception_extract(&d);
5405
5406 // enter new try scope for handlers
5407 if (!setjmp(d.jmp_buf)) {
5408 ... match exception and execute catch blocks ...
5409
5410 // fell off end, rethrow.
5411 _rethrow = _caught;
5412 ... jump-through-finally to finally_rethrow ...
5413 } else {
5414 // exception in catch block
5415 _rethrow = objc_exception_extract(&d);
5416 _call_try_exit = false;
5417 ... jump-through-finally to finally_rethrow ...
5418 }
5419 }
5420 ... jump-through-finally to finally_end ...
5421
5422 finally:
5423 if (_call_try_exit)
5424 objc_exception_try_exit(&d);
5425
5426 ... finally block ....
5427 ... dispatch to finally destination ...
5428
5429 finally_rethrow:
5430 objc_exception_throw(_rethrow);
5431
5432 finally_end:
5433 }
5434
5435 This framework differs slightly from the one gcc uses, in that gcc
5436 uses _rethrow to determine if objc_exception_try_exit should be called
5437 and if the object should be rethrown. This breaks in the face of
5438 throwing nil and introduces unnecessary branches.
5439
5440 We specialize this framework for a few particular circumstances:
5441
5442 - If there are no catch blocks, then we avoid emitting the second
5443 exception handling context.
5444
5445 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
5446 e)) we avoid emitting the code to rethrow an uncaught exception.
5447
5448 - FIXME: If there is no @finally block we can do a few more
5449 simplifications.
5450
5451 Rethrows and Jumps-Through-Finally
5452 --
5453
5454 '@throw;' is supported by pushing the currently-caught exception
5455 onto ObjCEHStack while the @catch blocks are emitted.
5456
5457 Branches through the @finally block are handled with an ordinary
5458 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
5459 exceptions are not compatible with C++ exceptions, and this is
5460 hardly the only place where this will go wrong.
5461
5462 @synchronized(expr) { stmt; } is emitted as if it were:
5463 id synch_value = expr;
5464 objc_sync_enter(synch_value);
5465 @try { stmt; } @finally { objc_sync_exit(synch_value); }
5466*/
5467
5468void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5469 const Stmt &S) {
5470 bool isTry = isa<ObjCAtTryStmt>(Val: S);
5471
5472 // A destination for the fall-through edges of the catch handlers to
5473 // jump to.
5474 CodeGenFunction::JumpDest FinallyEnd =
5475 CGF.getJumpDestInCurrentScope(Name: "finally.end");
5476
5477 // A destination for the rethrow edge of the catch handlers to jump
5478 // to.
5479 CodeGenFunction::JumpDest FinallyRethrow =
5480 CGF.getJumpDestInCurrentScope(Name: "finally.rethrow");
5481
5482 // For @synchronized, call objc_sync_enter(sync.expr). The
5483 // evaluation of the expression must occur before we enter the
5484 // @synchronized. We can't avoid a temp here because we need the
5485 // value to be preserved. If the backend ever does liveness
5486 // correctly after setjmp, this will be unnecessary.
5487 Address SyncArgSlot = Address::invalid();
5488 if (!isTry) {
5489 llvm::Value *SyncArg =
5490 CGF.EmitScalarExpr(E: cast<ObjCAtSynchronizedStmt>(Val: S).getSynchExpr());
5491 SyncArg = CGF.Builder.CreateBitCast(V: SyncArg, DestTy: ObjCTypes.ObjectPtrTy);
5492 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getSyncEnterFn(), args: SyncArg);
5493
5494 SyncArgSlot = CGF.CreateTempAlloca(Ty: SyncArg->getType(),
5495 align: CGF.getPointerAlign(), Name: "sync.arg");
5496 CGF.Builder.CreateStore(Val: SyncArg, Addr: SyncArgSlot);
5497 }
5498
5499 // Allocate memory for the setjmp buffer. This needs to be kept
5500 // live throughout the try and catch blocks.
5501 Address ExceptionData = CGF.CreateTempAlloca(
5502 Ty: ObjCTypes.ExceptionDataTy, align: CGF.getPointerAlign(), Name: "exceptiondata.ptr");
5503
5504 // Create the fragile hazards. Note that this will not capture any
5505 // of the allocas required for exception processing, but will
5506 // capture the current basic block (which extends all the way to the
5507 // setjmp call) as "before the @try".
5508 FragileHazards Hazards(CGF);
5509
5510 // Create a flag indicating whether the cleanup needs to call
5511 // objc_exception_try_exit. This is true except when
5512 // - no catches match and we're branching through the cleanup
5513 // just to rethrow the exception, or
5514 // - a catch matched and we're falling out of the catch handler.
5515 // The setjmp-safety rule here is that we should always store to this
5516 // variable in a place that dominates the branch through the cleanup
5517 // without passing through any setjmps.
5518 Address CallTryExitVar = CGF.CreateTempAlloca(
5519 Ty: CGF.Builder.getInt1Ty(), align: CharUnits::One(), Name: "_call_try_exit");
5520
5521 // A slot containing the exception to rethrow. Only needed when we
5522 // have both a @catch and a @finally.
5523 Address PropagatingExnVar = Address::invalid();
5524
5525 // Push a normal cleanup to leave the try scope.
5526 CGF.EHStack.pushCleanup<PerformFragileFinally>(Kind: NormalAndEHCleanup, A: &S,
5527 A: SyncArgSlot, A: CallTryExitVar,
5528 A: ExceptionData, A: &ObjCTypes);
5529
5530 // Enter a try block:
5531 // - Call objc_exception_try_enter to push ExceptionData on top of
5532 // the EH stack.
5533 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
5534 args: ExceptionData.emitRawPointer(CGF));
5535
5536 // - Call setjmp on the exception data buffer.
5537 llvm::Constant *Zero = llvm::ConstantInt::get(Ty: CGF.Builder.getInt32Ty(), V: 0);
5538 llvm::Value *GEPIndexes[] = {Zero, Zero, Zero};
5539 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
5540 Ty: ObjCTypes.ExceptionDataTy, Ptr: ExceptionData.emitRawPointer(CGF), IdxList: GEPIndexes,
5541 Name: "setjmp_buffer");
5542 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5543 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp_result");
5544 SetJmpResult->setCanReturnTwice();
5545
5546 // If setjmp returned 0, enter the protected block; otherwise,
5547 // branch to the handler.
5548 llvm::BasicBlock *TryBlock = CGF.createBasicBlock(name: "try");
5549 llvm::BasicBlock *TryHandler = CGF.createBasicBlock(name: "try.handler");
5550 llvm::Value *DidCatch =
5551 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
5552 CGF.Builder.CreateCondBr(Cond: DidCatch, True: TryHandler, False: TryBlock);
5553
5554 // Emit the protected block.
5555 CGF.EmitBlock(BB: TryBlock);
5556 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
5557 CGF.EmitStmt(S: isTry ? cast<ObjCAtTryStmt>(Val: S).getTryBody()
5558 : cast<ObjCAtSynchronizedStmt>(Val: S).getSynchBody());
5559
5560 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
5561
5562 // Emit the exception handler block.
5563 CGF.EmitBlock(BB: TryHandler);
5564
5565 // Don't optimize loads of the in-scope locals across this point.
5566 Hazards.emitWriteHazard();
5567
5568 // For a @synchronized (or a @try with no catches), just branch
5569 // through the cleanup to the rethrow block.
5570 if (!isTry || !cast<ObjCAtTryStmt>(Val: S).getNumCatchStmts()) {
5571 // Tell the cleanup not to re-pop the exit.
5572 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
5573 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5574
5575 // Otherwise, we have to match against the caught exceptions.
5576 } else {
5577 // Retrieve the exception object. We may emit multiple blocks but
5578 // nothing can cross this so the value is already in SSA form.
5579 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5580 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
5581 name: "caught");
5582
5583 // Push the exception to rethrow onto the EH value stack for the
5584 // benefit of any @throws in the handlers.
5585 CGF.ObjCEHValueStack.push_back(Elt: Caught);
5586
5587 const ObjCAtTryStmt *AtTryStmt = cast<ObjCAtTryStmt>(Val: &S);
5588
5589 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
5590
5591 llvm::BasicBlock *CatchBlock = nullptr;
5592 llvm::BasicBlock *CatchHandler = nullptr;
5593 if (HasFinally) {
5594 // Save the currently-propagating exception before
5595 // objc_exception_try_enter clears the exception slot.
5596 PropagatingExnVar = CGF.CreateTempAlloca(
5597 Ty: Caught->getType(), align: CGF.getPointerAlign(), Name: "propagating_exception");
5598 CGF.Builder.CreateStore(Val: Caught, Addr: PropagatingExnVar);
5599
5600 // Enter a new exception try block (in case a @catch block
5601 // throws an exception).
5602 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
5603 args: ExceptionData.emitRawPointer(CGF));
5604
5605 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5606 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp.result");
5607 SetJmpResult->setCanReturnTwice();
5608
5609 llvm::Value *Threw =
5610 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
5611
5612 CatchBlock = CGF.createBasicBlock(name: "catch");
5613 CatchHandler = CGF.createBasicBlock(name: "catch_for_catch");
5614 CGF.Builder.CreateCondBr(Cond: Threw, True: CatchHandler, False: CatchBlock);
5615
5616 CGF.EmitBlock(BB: CatchBlock);
5617 }
5618
5619 CGF.Builder.CreateStore(Val: CGF.Builder.getInt1(V: HasFinally), Addr: CallTryExitVar);
5620
5621 // Handle catch list. As a special case we check if everything is
5622 // matched and avoid generating code for falling off the end if
5623 // so.
5624 bool AllMatched = false;
5625 for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) {
5626 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5627 const ObjCObjectPointerType *OPT = nullptr;
5628
5629 // catch(...) always matches.
5630 if (!CatchParam) {
5631 AllMatched = true;
5632 } else {
5633 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
5634
5635 // catch(id e) always matches under this ABI, since only
5636 // ObjC exceptions end up here in the first place.
5637 // FIXME: For the time being we also match id<X>; this should
5638 // be rejected by Sema instead.
5639 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
5640 AllMatched = true;
5641 }
5642
5643 // If this is a catch-all, we don't need to test anything.
5644 if (AllMatched) {
5645 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5646
5647 if (CatchParam) {
5648 CGF.EmitAutoVarDecl(D: *CatchParam);
5649 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5650
5651 // These types work out because ConvertType(id) == i8*.
5652 EmitInitOfCatchParam(CGF, exn: Caught, paramDecl: CatchParam);
5653 }
5654
5655 CGF.EmitStmt(S: CatchStmt->getCatchBody());
5656
5657 // The scope of the catch variable ends right here.
5658 CatchVarCleanups.ForceCleanup();
5659
5660 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
5661 break;
5662 }
5663
5664 assert(OPT && "Unexpected non-object pointer type in @catch");
5665 const ObjCObjectType *ObjTy = OPT->getObjectType();
5666
5667 // FIXME: @catch (Class c) ?
5668 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5669 assert(IDecl && "Catch parameter must have Objective-C type!");
5670
5671 // Check if the @catch block matches the exception object.
5672 llvm::Value *Class = EmitClassRef(CGF, ID: IDecl);
5673
5674 llvm::Value *matchArgs[] = {Class, Caught};
5675 llvm::CallInst *Match = CGF.EmitNounwindRuntimeCall(
5676 callee: ObjCTypes.getExceptionMatchFn(), args: matchArgs, name: "match");
5677
5678 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock(name: "match");
5679 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock(name: "catch.next");
5680
5681 CGF.Builder.CreateCondBr(Cond: CGF.Builder.CreateIsNotNull(Arg: Match, Name: "matched"),
5682 True: MatchedBlock, False: NextCatchBlock);
5683
5684 // Emit the @catch block.
5685 CGF.EmitBlock(BB: MatchedBlock);
5686
5687 // Collect any cleanups for the catch variable. The scope lasts until
5688 // the end of the catch body.
5689 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5690
5691 CGF.EmitAutoVarDecl(D: *CatchParam);
5692 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5693
5694 // Initialize the catch variable.
5695 llvm::Value *Tmp = CGF.Builder.CreateBitCast(
5696 V: Caught, DestTy: CGF.ConvertType(T: CatchParam->getType()));
5697 EmitInitOfCatchParam(CGF, exn: Tmp, paramDecl: CatchParam);
5698
5699 CGF.EmitStmt(S: CatchStmt->getCatchBody());
5700
5701 // We're done with the catch variable.
5702 CatchVarCleanups.ForceCleanup();
5703
5704 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
5705
5706 CGF.EmitBlock(BB: NextCatchBlock);
5707 }
5708
5709 CGF.ObjCEHValueStack.pop_back();
5710
5711 // If nothing wanted anything to do with the caught exception,
5712 // kill the extract call.
5713 if (Caught->use_empty())
5714 Caught->eraseFromParent();
5715
5716 if (!AllMatched)
5717 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5718
5719 if (HasFinally) {
5720 // Emit the exception handler for the @catch blocks.
5721 CGF.EmitBlock(BB: CatchHandler);
5722
5723 // In theory we might now need a write hazard, but actually it's
5724 // unnecessary because there's no local-accessing code between
5725 // the try's write hazard and here.
5726 // Hazards.emitWriteHazard();
5727
5728 // Extract the new exception and save it to the
5729 // propagating-exception slot.
5730 assert(PropagatingExnVar.isValid());
5731 llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall(
5732 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
5733 name: "caught");
5734 CGF.Builder.CreateStore(Val: NewCaught, Addr: PropagatingExnVar);
5735
5736 // Don't pop the catch handler; the throw already did.
5737 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
5738 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
5739 }
5740 }
5741
5742 // Insert read hazards as required in the new blocks.
5743 Hazards.emitHazardsInNewBlocks();
5744
5745 // Pop the cleanup.
5746 CGF.Builder.restoreIP(IP: TryFallthroughIP);
5747 if (CGF.HaveInsertPoint())
5748 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
5749 CGF.PopCleanupBlock();
5750 CGF.EmitBlock(BB: FinallyEnd.getBlock(), IsFinished: true);
5751
5752 // Emit the rethrow block.
5753 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
5754 CGF.EmitBlock(BB: FinallyRethrow.getBlock(), IsFinished: true);
5755 if (CGF.HaveInsertPoint()) {
5756 // If we have a propagating-exception variable, check it.
5757 llvm::Value *PropagatingExn;
5758 if (PropagatingExnVar.isValid()) {
5759 PropagatingExn = CGF.Builder.CreateLoad(Addr: PropagatingExnVar);
5760
5761 // Otherwise, just look in the buffer for the exception to throw.
5762 } else {
5763 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5764 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF));
5765 PropagatingExn = Caught;
5766 }
5767
5768 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(),
5769 args: PropagatingExn);
5770 CGF.Builder.CreateUnreachable();
5771 }
5772
5773 CGF.Builder.restoreIP(IP: SavedIP);
5774}
5775
5776void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5777 const ObjCAtThrowStmt &S,
5778 bool ClearInsertionPoint) {
5779 llvm::Value *ExceptionAsObject;
5780
5781 if (const Expr *ThrowExpr = S.getThrowExpr()) {
5782 llvm::Value *Exception = CGF.EmitObjCThrowOperand(expr: ThrowExpr);
5783 ExceptionAsObject =
5784 CGF.Builder.CreateBitCast(V: Exception, DestTy: ObjCTypes.ObjectPtrTy);
5785 } else {
5786 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
5787 "Unexpected rethrow outside @catch block.");
5788 ExceptionAsObject = CGF.ObjCEHValueStack.back();
5789 }
5790
5791 CGF.EmitRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(), args: ExceptionAsObject)
5792 ->setDoesNotReturn();
5793 CGF.Builder.CreateUnreachable();
5794
5795 // Clear the insertion point to indicate we are in unreachable code.
5796 if (ClearInsertionPoint)
5797 CGF.Builder.ClearInsertionPoint();
5798}
5799
5800/// EmitObjCWeakRead - Code gen for loading value of a __weak
5801/// object: objc_read_weak (id *src)
5802///
5803llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5804 Address AddrWeakObj) {
5805 llvm::Type *DestTy = AddrWeakObj.getElementType();
5806 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
5807 V: AddrWeakObj.emitRawPointer(CGF), DestTy: ObjCTypes.PtrObjectPtrTy);
5808 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
5809 callee: ObjCTypes.getGcReadWeakFn(), args: AddrWeakObjVal, name: "weakread");
5810 read_weak = CGF.Builder.CreateBitCast(V: read_weak, DestTy);
5811 return read_weak;
5812}
5813
5814/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5815/// objc_assign_weak (id src, id *dst)
5816///
5817void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5818 llvm::Value *src, Address dst) {
5819 llvm::Type *SrcTy = src->getType();
5820 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5821 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5822 assert(Size <= 8 && "does not support size > 8");
5823 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5824 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5825 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5826 }
5827 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5828 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5829 DestTy: ObjCTypes.PtrObjectPtrTy);
5830 llvm::Value *args[] = {src, dstVal};
5831 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignWeakFn(), args,
5832 name: "weakassign");
5833}
5834
5835/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5836/// objc_assign_global (id src, id *dst)
5837///
5838void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5839 llvm::Value *src, Address dst,
5840 bool threadlocal) {
5841 llvm::Type *SrcTy = src->getType();
5842 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5843 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5844 assert(Size <= 8 && "does not support size > 8");
5845 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5846 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5847 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5848 }
5849 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5850 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5851 DestTy: ObjCTypes.PtrObjectPtrTy);
5852 llvm::Value *args[] = {src, dstVal};
5853 if (!threadlocal)
5854 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignGlobalFn(), args,
5855 name: "globalassign");
5856 else
5857 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignThreadLocalFn(), args,
5858 name: "threadlocalassign");
5859}
5860
5861/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5862/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
5863///
5864void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5865 llvm::Value *src, Address dst,
5866 llvm::Value *ivarOffset) {
5867 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
5868 llvm::Type *SrcTy = src->getType();
5869 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5870 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5871 assert(Size <= 8 && "does not support size > 8");
5872 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5873 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5874 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5875 }
5876 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5877 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5878 DestTy: ObjCTypes.PtrObjectPtrTy);
5879 llvm::Value *args[] = {src, dstVal, ivarOffset};
5880 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignIvarFn(), args);
5881}
5882
5883/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5884/// objc_assign_strongCast (id src, id *dst)
5885///
5886void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5887 llvm::Value *src, Address dst) {
5888 llvm::Type *SrcTy = src->getType();
5889 if (!isa<llvm::PointerType>(Val: SrcTy)) {
5890 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
5891 assert(Size <= 8 && "does not support size > 8");
5892 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
5893 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
5894 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
5895 }
5896 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
5897 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
5898 DestTy: ObjCTypes.PtrObjectPtrTy);
5899 llvm::Value *args[] = {src, dstVal};
5900 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignStrongCastFn(), args,
5901 name: "strongassign");
5902}
5903
5904void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5905 Address DestPtr, Address SrcPtr,
5906 llvm::Value *size) {
5907 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5908 SrcPtr.emitRawPointer(CGF), size};
5909 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.GcMemmoveCollectableFn(), args);
5910}
5911
5912/// EmitObjCValueForIvar - Code Gen for ivar reference.
5913///
5914LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5915 QualType ObjectTy,
5916 llvm::Value *BaseValue,
5917 const ObjCIvarDecl *Ivar,
5918 unsigned CVRQualifiers) {
5919 const ObjCInterfaceDecl *ID =
5920 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5921 return EmitValueForIvarAtOffset(CGF, OID: ID, BaseValue, Ivar, CVRQualifiers,
5922 Offset: EmitIvarOffset(CGF, Interface: ID, Ivar));
5923}
5924
5925llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5926 const ObjCInterfaceDecl *Interface,
5927 const ObjCIvarDecl *Ivar) {
5928 uint64_t Offset = ComputeIvarBaseOffset(CGM, OID: Interface, Ivar);
5929 return llvm::ConstantInt::get(
5930 Ty: CGM.getTypes().ConvertType(T: CGM.getContext().LongTy), V: Offset);
5931}
5932
5933/* *** Private Interface *** */
5934
5935std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5936 StringRef MachOAttributes) {
5937 switch (CGM.getTriple().getObjectFormat()) {
5938 case llvm::Triple::UnknownObjectFormat:
5939 llvm_unreachable("unexpected object file format");
5940 case llvm::Triple::MachO: {
5941 if (MachOAttributes.empty())
5942 return ("__DATA," + Section).str();
5943 return ("__DATA," + Section + "," + MachOAttributes).str();
5944 }
5945 case llvm::Triple::ELF:
5946 assert(Section.starts_with("__") && "expected the name to begin with __");
5947 return Section.substr(Start: 2).str();
5948 case llvm::Triple::COFF:
5949 assert(Section.starts_with("__") && "expected the name to begin with __");
5950 return ("." + Section.substr(Start: 2) + "$B").str();
5951 case llvm::Triple::Wasm:
5952 case llvm::Triple::GOFF:
5953 case llvm::Triple::SPIRV:
5954 case llvm::Triple::XCOFF:
5955 case llvm::Triple::DXContainer:
5956 llvm::report_fatal_error(
5957 reason: "Objective-C support is unimplemented for object file format");
5958 }
5959
5960 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");
5961}
5962
5963// clang-format off
5964/// EmitImageInfo - Emit the image info marker used to encode some module
5965/// level information.
5966///
5967/// See: <rdr://4810609&4810587&4810587>
5968/// struct IMAGE_INFO {
5969/// unsigned version;
5970/// unsigned flags;
5971/// };
5972enum ImageInfoFlags {
5973 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5974 eImageInfo_GarbageCollected = (1 << 1),
5975 eImageInfo_GCOnly = (1 << 2),
5976 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5977
5978 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5979 eImageInfo_ImageIsSimulated = (1 << 5),
5980 eImageInfo_ClassProperties = (1 << 6)
5981};
5982// clang-format on
5983
5984void CGObjCCommonMac::EmitImageInfo() {
5985 unsigned version = 0; // Version is unused?
5986 std::string Section =
5987 (ObjCABI == 1)
5988 ? "__OBJC,__image_info,regular"
5989 : GetSectionName(Section: "__objc_imageinfo", MachOAttributes: "regular,no_dead_strip");
5990
5991 // Generate module-level named metadata to convey this information to the
5992 // linker and code-gen.
5993 llvm::Module &Mod = CGM.getModule();
5994
5995 // Add the ObjC ABI version to the module flags.
5996 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Version", Val: ObjCABI);
5997 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Version",
5998 Val: version);
5999 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Section",
6000 Val: llvm::MDString::get(Context&: VMContext, Str: Section));
6001
6002 auto Int8Ty = llvm::Type::getInt8Ty(C&: VMContext);
6003 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6004 // Non-GC overrides those files which specify GC.
6005 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
6006 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: 0));
6007 } else {
6008 // Add the ObjC garbage collection value.
6009 Mod.addModuleFlag(
6010 Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
6011 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: (uint8_t)eImageInfo_GarbageCollected));
6012
6013 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6014 // Add the ObjC GC Only value.
6015 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C GC Only",
6016 Val: eImageInfo_GCOnly);
6017
6018 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6019 llvm::Metadata *Ops[2] = {
6020 llvm::MDString::get(Context&: VMContext, Str: "Objective-C Garbage Collection"),
6021 llvm::ConstantAsMetadata::get(
6022 C: llvm::ConstantInt::get(Ty: Int8Ty, V: eImageInfo_GarbageCollected))};
6023 Mod.addModuleFlag(Behavior: llvm::Module::Require, Key: "Objective-C GC Only",
6024 Val: llvm::MDNode::get(Context&: VMContext, MDs: Ops));
6025 }
6026 }
6027
6028 // Indicate whether we're compiling this to run on a simulator.
6029 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6030 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Is Simulated",
6031 Val: eImageInfo_ImageIsSimulated);
6032
6033 // Indicate whether we are generating class properties.
6034 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Class Properties",
6035 Val: eImageInfo_ClassProperties);
6036
6037 // Indicate whether we want enforcement of pointer signing for class_ro_t
6038 // pointers.
6039 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6040 Mod.addModuleFlag(Behavior: llvm::Module::Error,
6041 Key: "Objective-C Enforce ClassRO Pointer Signing",
6042 Val: eImageInfo_SignedClassRO);
6043 else
6044 Mod.addModuleFlag(Behavior: llvm::Module::Error,
6045 Key: "Objective-C Enforce ClassRO Pointer Signing",
6046 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: 0));
6047}
6048
6049// struct objc_module {
6050// unsigned long version;
6051// unsigned long size;
6052// const char *name;
6053// Symtab symtab;
6054// };
6055
6056// FIXME: Get from somewhere
6057static const int ModuleVersion = 7;
6058
6059void CGObjCMac::EmitModuleInfo() {
6060 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ModuleTy);
6061
6062 ConstantInitBuilder builder(CGM);
6063 auto values = builder.beginStruct(structTy: ObjCTypes.ModuleTy);
6064 values.addInt(intTy: ObjCTypes.LongTy, value: ModuleVersion);
6065 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
6066 // This used to be the filename, now it is unused. <rdr://4327263>
6067 values.add(value: GetClassName(RuntimeName: StringRef("")));
6068 values.add(value: EmitModuleSymbols());
6069 CreateMetadataVar(Name: "OBJC_MODULES", Init&: values,
6070 Section: "__OBJC,__module_info,regular,no_dead_strip",
6071 Align: CGM.getPointerAlign(), AddToUsed: true);
6072}
6073
6074llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6075 unsigned NumClasses = DefinedClasses.size();
6076 unsigned NumCategories = DefinedCategories.size();
6077
6078 // Return null if no symbols were defined.
6079 if (!NumClasses && !NumCategories)
6080 return llvm::Constant::getNullValue(Ty: ObjCTypes.SymtabPtrTy);
6081
6082 ConstantInitBuilder builder(CGM);
6083 auto values = builder.beginStruct();
6084 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
6085 values.addNullPointer(ptrTy: ObjCTypes.SelectorPtrTy);
6086 values.addInt(intTy: ObjCTypes.ShortTy, value: NumClasses);
6087 values.addInt(intTy: ObjCTypes.ShortTy, value: NumCategories);
6088
6089 // The runtime expects exactly the list of defined classes followed
6090 // by the list of defined categories, in a single array.
6091 auto array = values.beginArray(eltTy: ObjCTypes.Int8PtrTy);
6092 for (unsigned i = 0; i < NumClasses; i++) {
6093 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6094 assert(ID);
6095 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6096 // We are implementing a weak imported interface. Give it external linkage
6097 if (ID->isWeakImported() && !IMP->isWeakImported())
6098 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6099
6100 array.add(value: DefinedClasses[i]);
6101 }
6102 for (unsigned i = 0; i < NumCategories; i++)
6103 array.add(value: DefinedCategories[i]);
6104
6105 array.finishAndAddTo(parent&: values);
6106
6107 llvm::GlobalVariable *GV = CreateMetadataVar(
6108 Name: "OBJC_SYMBOLS", Init&: values, Section: "__OBJC,__symbols,regular,no_dead_strip",
6109 Align: CGM.getPointerAlign(), AddToUsed: true);
6110 return GV;
6111}
6112
6113llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6114 IdentifierInfo *II) {
6115 LazySymbols.insert(X: II);
6116
6117 llvm::GlobalVariable *&Entry = ClassReferences[II];
6118
6119 if (!Entry) {
6120 Entry =
6121 CreateMetadataVar(Name: "OBJC_CLASS_REFERENCES_", Init: GetClassName(RuntimeName: II->getName()),
6122 Section: "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
6123 Align: CGM.getPointerAlign(), AddToUsed: true);
6124 }
6125
6126 return CGF.Builder.CreateAlignedLoad(Ty: Entry->getValueType(), Addr: Entry,
6127 Align: CGF.getPointerAlign());
6128}
6129
6130llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6131 const ObjCInterfaceDecl *ID) {
6132 // If the class has the objc_runtime_visible attribute, we need to
6133 // use the Objective-C runtime to get the class.
6134 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6135 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6136
6137 IdentifierInfo *RuntimeName =
6138 &CGM.getContext().Idents.get(Name: ID->getObjCRuntimeNameAsString());
6139 return EmitClassRefFromId(CGF, II: RuntimeName);
6140}
6141
6142llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6143 IdentifierInfo *II = &CGM.getContext().Idents.get(Name: "NSAutoreleasePool");
6144 return EmitClassRefFromId(CGF, II);
6145}
6146
6147llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6148 return CGF.Builder.CreateLoad(Addr: EmitSelectorAddr(Sel));
6149}
6150
6151ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6152 CharUnits Align = CGM.getPointerAlign();
6153
6154 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6155 if (!Entry) {
6156 Entry = CreateMetadataVar(
6157 Name: "OBJC_SELECTOR_REFERENCES_", Init: GetMethodVarName(Sel),
6158 Section: "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, AddToUsed: true);
6159 Entry->setExternallyInitialized(true);
6160 }
6161
6162 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6163}
6164
6165llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6166 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6167 if (!Entry)
6168 Entry = CreateCStringLiteral(Name: RuntimeName, Type: ObjCLabelType::ClassName);
6169 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
6170}
6171
6172llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6173 return MethodDefinitions.lookup(Val: MD);
6174}
6175
6176/// GetIvarLayoutName - Returns a unique constant for the given
6177/// ivar layout bitmap.
6178llvm::Constant *
6179CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6180 const ObjCCommonTypesHelper &ObjCTypes) {
6181 return llvm::Constant::getNullValue(Ty: ObjCTypes.Int8PtrTy);
6182}
6183
6184void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6185 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6186
6187 // If this is a union, remember that we had one, because it might mess
6188 // up the ordering of layout entries.
6189 if (RD->isUnion())
6190 IsDisordered = true;
6191
6192 const ASTRecordLayout *recLayout = nullptr;
6193 visitAggregate(begin: RD->field_begin(), end: RD->field_end(), aggregateOffset: offset,
6194 getOffset: [&](const FieldDecl *field) -> CharUnits {
6195 if (!recLayout)
6196 recLayout = &CGM.getContext().getASTRecordLayout(D: RD);
6197 auto offsetInBits =
6198 recLayout->getFieldOffset(FieldNo: field->getFieldIndex());
6199 return CGM.getContext().toCharUnitsFromBits(BitSize: offsetInBits);
6200 });
6201}
6202
6203template <class Iterator, class GetOffsetFn>
6204void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6205 CharUnits aggregateOffset,
6206 const GetOffsetFn &getOffset) {
6207 for (; begin != end; ++begin) {
6208 auto field = *begin;
6209
6210 // Skip over bitfields.
6211 if (field->isBitField()) {
6212 continue;
6213 }
6214
6215 // Compute the offset of the field within the aggregate.
6216 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6217
6218 visitField(field, offset: fieldOffset);
6219 }
6220}
6221
6222/// Collect layout information for the given fields into IvarsInfo.
6223void IvarLayoutBuilder::visitField(const FieldDecl *field,
6224 CharUnits fieldOffset) {
6225 QualType fieldType = field->getType();
6226
6227 // Drill down into arrays.
6228 uint64_t numElts = 1;
6229 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(T: fieldType)) {
6230 numElts = 0;
6231 fieldType = arrayType->getElementType();
6232 }
6233 // Unlike incomplete arrays, constant arrays can be nested.
6234 while (auto arrayType = CGM.getContext().getAsConstantArrayType(T: fieldType)) {
6235 numElts *= arrayType->getZExtSize();
6236 fieldType = arrayType->getElementType();
6237 }
6238
6239 assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
6240
6241 // If we ended up with a zero-sized array, we've done what we can do within
6242 // the limits of this layout encoding.
6243 if (numElts == 0)
6244 return;
6245
6246 // Recurse if the base element type is a record type.
6247 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6248 size_t oldEnd = IvarsInfo.size();
6249
6250 visitRecord(RT: recType, offset: fieldOffset);
6251
6252 // If we have an array, replicate the first entry's layout information.
6253 auto numEltEntries = IvarsInfo.size() - oldEnd;
6254 if (numElts != 1 && numEltEntries != 0) {
6255 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(T: recType);
6256 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6257 // Copy the last numEltEntries onto the end of the array, adjusting
6258 // each for the element size.
6259 for (size_t i = 0; i != numEltEntries; ++i) {
6260 auto firstEntry = IvarsInfo[oldEnd + i];
6261 IvarsInfo.push_back(Elt: IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6262 firstEntry.SizeInWords));
6263 }
6264 }
6265 }
6266
6267 return;
6268 }
6269
6270 // Classify the element type.
6271 Qualifiers::GC GCAttr = GetGCAttrTypeForType(Ctx&: CGM.getContext(), FQT: fieldType);
6272
6273 // If it matches what we're looking for, add an entry.
6274 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6275 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6276 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6277 CGM.getPointerSize());
6278 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, numElts));
6279 }
6280}
6281
6282/// buildBitmap - This routine does the horsework of taking the offsets of
6283/// strong/weak references and creating a bitmap. The bitmap is also
6284/// returned in the given buffer, suitable for being passed to \c dump().
6285llvm::Constant *
6286IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6287 llvm::SmallVectorImpl<unsigned char> &buffer) {
6288 // The bitmap is a series of skip/scan instructions, aligned to word
6289 // boundaries. The skip is performed first.
6290 const unsigned char MaxNibble = 0xF;
6291 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6292 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6293
6294 assert(!IvarsInfo.empty() && "generating bitmap for no data");
6295
6296 // Sort the ivar info on byte position in case we encounterred a
6297 // union nested in the ivar list.
6298 if (IsDisordered) {
6299 // This isn't a stable sort, but our algorithm should handle it fine.
6300 llvm::array_pod_sort(Start: IvarsInfo.begin(), End: IvarsInfo.end());
6301 } else {
6302 assert(llvm::is_sorted(IvarsInfo));
6303 }
6304 assert(IvarsInfo.back().Offset < InstanceEnd);
6305
6306 assert(buffer.empty());
6307
6308 // Skip the next N words.
6309 auto skip = [&](unsigned numWords) {
6310 assert(numWords > 0);
6311
6312 // Try to merge into the previous byte. Since scans happen second, we
6313 // can't do this if it includes a scan.
6314 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6315 unsigned lastSkip = buffer.back() >> SkipShift;
6316 if (lastSkip < MaxNibble) {
6317 unsigned claimed = std::min(a: MaxNibble - lastSkip, b: numWords);
6318 numWords -= claimed;
6319 lastSkip += claimed;
6320 buffer.back() = (lastSkip << SkipShift);
6321 }
6322 }
6323
6324 while (numWords >= MaxNibble) {
6325 buffer.push_back(Elt: MaxNibble << SkipShift);
6326 numWords -= MaxNibble;
6327 }
6328 if (numWords) {
6329 buffer.push_back(Elt: numWords << SkipShift);
6330 }
6331 };
6332
6333 // Scan the next N words.
6334 auto scan = [&](unsigned numWords) {
6335 assert(numWords > 0);
6336
6337 // Try to merge into the previous byte. Since scans happen second, we can
6338 // do this even if it includes a skip.
6339 if (!buffer.empty()) {
6340 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6341 if (lastScan < MaxNibble) {
6342 unsigned claimed = std::min(a: MaxNibble - lastScan, b: numWords);
6343 numWords -= claimed;
6344 lastScan += claimed;
6345 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6346 }
6347 }
6348
6349 while (numWords >= MaxNibble) {
6350 buffer.push_back(Elt: MaxNibble << ScanShift);
6351 numWords -= MaxNibble;
6352 }
6353 if (numWords) {
6354 buffer.push_back(Elt: numWords << ScanShift);
6355 }
6356 };
6357
6358 // One past the end of the last scan.
6359 unsigned endOfLastScanInWords = 0;
6360 const CharUnits WordSize = CGM.getPointerSize();
6361
6362 // Consider all the scan requests.
6363 for (auto &request : IvarsInfo) {
6364 CharUnits beginOfScan = request.Offset - InstanceBegin;
6365
6366 // Ignore scan requests that don't start at an even multiple of the
6367 // word size. We can't encode them.
6368 if (!beginOfScan.isMultipleOf(N: WordSize))
6369 continue;
6370
6371 // Ignore scan requests that start before the instance start.
6372 // This assumes that scans never span that boundary. The boundary
6373 // isn't the true start of the ivars, because in the fragile-ARC case
6374 // it's rounded up to word alignment, but the test above should leave
6375 // us ignoring that possibility.
6376 if (beginOfScan.isNegative()) {
6377 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6378 continue;
6379 }
6380
6381 unsigned beginOfScanInWords = beginOfScan / WordSize;
6382 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6383
6384 // If the scan starts some number of words after the last one ended,
6385 // skip forward.
6386 if (beginOfScanInWords > endOfLastScanInWords) {
6387 skip(beginOfScanInWords - endOfLastScanInWords);
6388
6389 // Otherwise, start scanning where the last left off.
6390 } else {
6391 beginOfScanInWords = endOfLastScanInWords;
6392
6393 // If that leaves us with nothing to scan, ignore this request.
6394 if (beginOfScanInWords >= endOfScanInWords)
6395 continue;
6396 }
6397
6398 // Scan to the end of the request.
6399 assert(beginOfScanInWords < endOfScanInWords);
6400 scan(endOfScanInWords - beginOfScanInWords);
6401 endOfLastScanInWords = endOfScanInWords;
6402 }
6403
6404 if (buffer.empty())
6405 return llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy);
6406
6407 // For GC layouts, emit a skip to the end of the allocation so that we
6408 // have precise information about the entire thing. This isn't useful
6409 // or necessary for the ARC-style layout strings.
6410 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6411 unsigned lastOffsetInWords =
6412 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6413 if (lastOffsetInWords > endOfLastScanInWords) {
6414 skip(lastOffsetInWords - endOfLastScanInWords);
6415 }
6416 }
6417
6418 // Null terminate the string.
6419 buffer.push_back(Elt: 0);
6420
6421 auto *Entry = CGObjC.CreateCStringLiteral(
6422 Name: reinterpret_cast<char *>(buffer.data()), Type: ObjCLabelType::LayoutBitMap);
6423 return getConstantGEP(VMContext&: CGM.getLLVMContext(), C: Entry, idx0: 0, idx1: 0);
6424}
6425
6426/// BuildIvarLayout - Builds ivar layout bitmap for the class
6427/// implementation for the __strong or __weak case.
6428/// The layout map displays which words in ivar list must be skipped
6429/// and which must be scanned by GC (see below). String is built of bytes.
6430/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
6431/// of words to skip and right nibble is count of words to scan. So, each
6432/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
6433/// represented by a 0x00 byte which also ends the string.
6434/// 1. when ForStrongLayout is true, following ivars are scanned:
6435/// - id, Class
6436/// - object *
6437/// - __strong anything
6438///
6439/// 2. When ForStrongLayout is false, following ivars are scanned:
6440/// - __weak anything
6441///
6442llvm::Constant *
6443CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6444 CharUnits beginOffset, CharUnits endOffset,
6445 bool ForStrongLayout, bool HasMRCWeakIvars) {
6446 // If this is MRC, and we're either building a strong layout or there
6447 // are no weak ivars, bail out early.
6448 llvm::Type *PtrTy = CGM.Int8PtrTy;
6449 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6450 !CGM.getLangOpts().ObjCAutoRefCount &&
6451 (ForStrongLayout || !HasMRCWeakIvars))
6452 return llvm::Constant::getNullValue(Ty: PtrTy);
6453
6454 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6455 SmallVector<const ObjCIvarDecl *, 32> ivars;
6456
6457 // GC layout strings include the complete object layout, possibly
6458 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6459 // up.
6460 //
6461 // ARC layout strings only include the class's ivars. In non-fragile
6462 // runtimes, that means starting at InstanceStart, rounded up to word
6463 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6464 // starting at the offset of the first ivar, rounded up to word alignment.
6465 //
6466 // MRC weak layout strings follow the ARC style.
6467 CharUnits baseOffset;
6468 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6469 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6470 IVD = IVD->getNextIvar())
6471 ivars.push_back(Elt: IVD);
6472
6473 if (isNonFragileABI()) {
6474 baseOffset = beginOffset; // InstanceStart
6475 } else if (!ivars.empty()) {
6476 baseOffset =
6477 CharUnits::fromQuantity(Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivars[0]));
6478 } else {
6479 baseOffset = CharUnits::Zero();
6480 }
6481
6482 baseOffset = baseOffset.alignTo(Align: CGM.getPointerAlign());
6483 } else {
6484 CGM.getContext().DeepCollectObjCIvars(OI, leafClass: true, Ivars&: ivars);
6485
6486 baseOffset = CharUnits::Zero();
6487 }
6488
6489 if (ivars.empty())
6490 return llvm::Constant::getNullValue(Ty: PtrTy);
6491
6492 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6493
6494 builder.visitAggregate(begin: ivars.begin(), end: ivars.end(), aggregateOffset: CharUnits::Zero(),
6495 getOffset: [&](const ObjCIvarDecl *ivar) -> CharUnits {
6496 return CharUnits::fromQuantity(
6497 Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivar));
6498 });
6499
6500 if (!builder.hasBitmapData())
6501 return llvm::Constant::getNullValue(Ty: PtrTy);
6502
6503 llvm::SmallVector<unsigned char, 4> buffer;
6504 llvm::Constant *C = builder.buildBitmap(CGObjC&: *this, buffer);
6505
6506 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6507 printf(format: "\n%s ivar layout for class '%s': ",
6508 ForStrongLayout ? "strong" : "weak",
6509 OMD->getClassInterface()->getName().str().c_str());
6510 builder.dump(buffer);
6511 }
6512 return C;
6513}
6514
6515llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6516 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6517 // FIXME: Avoid std::string in "Sel.getAsString()"
6518 if (!Entry)
6519 Entry =
6520 CreateCStringLiteral(Name: Sel.getAsString(), Type: ObjCLabelType::MethodVarName);
6521 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
6522}
6523
6524// FIXME: Merge into a single cstring creation function.
6525llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6526 return GetMethodVarName(Sel: CGM.getContext().Selectors.getNullarySelector(ID));
6527}
6528
6529llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6530 std::string TypeStr;
6531 CGM.getContext().getObjCEncodingForType(T: Field->getType(), S&: TypeStr, Field);
6532
6533 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6534 if (!Entry)
6535 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
6536 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
6537}
6538
6539llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6540 bool Extended) {
6541 std::string TypeStr =
6542 CGM.getContext().getObjCEncodingForMethodDecl(Decl: D, Extended);
6543
6544 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6545 if (!Entry)
6546 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
6547 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
6548}
6549
6550// FIXME: Merge into a single cstring creation function.
6551llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6552 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6553 if (!Entry)
6554 Entry = CreateCStringLiteral(Name: Ident->getName(), Type: ObjCLabelType::PropertyName);
6555 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
6556}
6557
6558// FIXME: Merge into a single cstring creation function.
6559// FIXME: This Decl should be more precise.
6560llvm::Constant *
6561CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6562 const Decl *Container) {
6563 std::string TypeStr =
6564 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6565 return GetPropertyName(Ident: &CGM.getContext().Idents.get(Name: TypeStr));
6566}
6567
6568void CGObjCMac::FinishModule() {
6569 EmitModuleInfo();
6570
6571 // Emit the dummy bodies for any protocols which were referenced but
6572 // never defined.
6573 for (auto &entry : Protocols) {
6574 llvm::GlobalVariable *global = entry.second;
6575 if (global->hasInitializer())
6576 continue;
6577
6578 ConstantInitBuilder builder(CGM);
6579 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolTy);
6580 values.addNullPointer(ptrTy: ObjCTypes.ProtocolExtensionPtrTy);
6581 values.add(value: GetClassName(RuntimeName: entry.first->getName()));
6582 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
6583 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
6584 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
6585 values.finishAndSetAsInitializer(global);
6586 CGM.addCompilerUsedGlobal(GV: global);
6587 }
6588
6589 // Add assembler directives to add lazy undefined symbol references
6590 // for classes which are referenced but not defined. This is
6591 // important for correct linker interaction.
6592 //
6593 // FIXME: It would be nice if we had an LLVM construct for this.
6594 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6595 CGM.getTriple().isOSBinFormatMachO()) {
6596 SmallString<256> Asm;
6597 Asm += CGM.getModule().getModuleInlineAsm();
6598 if (!Asm.empty() && Asm.back() != '\n')
6599 Asm += '\n';
6600
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().setModuleInlineAsm(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