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

source code of clang/lib/CodeGen/CGObjCMac.cpp