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