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