1//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides Objective-C code generation targeting the Apple runtime.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGBlocks.h"
14#include "CGCleanup.h"
15#include "CGObjCRuntime.h"
16#include "CGRecordLayout.h"
17#include "CodeGenFunction.h"
18#include "CodeGenModule.h"
19#include "clang/AST/ASTContext.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/Mangle.h"
24#include "clang/AST/RecordLayout.h"
25#include "clang/AST/StmtObjC.h"
26#include "clang/Basic/CodeGenOptions.h"
27#include "clang/Basic/LangOptions.h"
28#include "clang/CodeGen/ConstantInitBuilder.h"
29#include "llvm/ADT/CachedHashString.h"
30#include "llvm/ADT/DenseSet.h"
31#include "llvm/ADT/SetVector.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/InlineAsm.h"
36#include "llvm/IR/IntrinsicInst.h"
37#include "llvm/IR/LLVMContext.h"
38#include "llvm/IR/Module.h"
39#include "llvm/Support/ScopedPrinter.h"
40#include "llvm/Support/raw_ostream.h"
41#include <cstdio>
42
43using namespace clang;
44using namespace CodeGen;
45
46namespace {
47
48// FIXME: We should find a nicer way to make the labels for metadata, string
49// concatenation is lame.
50
51class ObjCCommonTypesHelper {
52protected:
53 llvm::LLVMContext &VMContext;
54
55private:
56 // The types of these functions don't really matter because we
57 // should always bitcast before calling them.
58
59 /// id objc_msgSend (id, SEL, ...)
60 ///
61 /// The default messenger, used for sends whose ABI is unchanged from
62 /// the all-integer/pointer case.
63 llvm::FunctionCallee getMessageSendFn() const {
64 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
65 // be called a lot.
66 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
67 return CGM.CreateRuntimeFunction(
68 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true), Name: "objc_msgSend",
69 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
70 Index: llvm::AttributeList::FunctionIndex,
71 Kinds: llvm::Attribute::NonLazyBind));
72 }
73
74 /// void objc_msgSend_stret (id, SEL, ...)
75 ///
76 /// The messenger used when the return value is an aggregate returned
77 /// by indirect reference in the first argument, and therefore the
78 /// self and selector parameters are shifted over by one.
79 llvm::FunctionCallee getMessageSendStretFn() const {
80 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
81 return CGM.CreateRuntimeFunction(
82 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
83 Name: "objc_msgSend_stret");
84 }
85
86 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
87 ///
88 /// The messenger used when the return value is returned on the x87
89 /// floating-point stack; without a special entrypoint, the nil case
90 /// would be unbalanced.
91 llvm::FunctionCallee getMessageSendFpretFn() const {
92 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
93 return CGM.CreateRuntimeFunction(
94 Ty: llvm::FunctionType::get(Result: CGM.DoubleTy, Params: params, isVarArg: true),
95 Name: "objc_msgSend_fpret");
96 }
97
98 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
99 ///
100 /// The messenger used when the return value is returned in two values on the
101 /// x87 floating point stack; without a special entrypoint, the nil case
102 /// would be unbalanced. Only used on 64-bit X86.
103 llvm::FunctionCallee getMessageSendFp2retFn() const {
104 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
105 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(C&: VMContext);
106 llvm::Type *resultType =
107 llvm::StructType::get(elt1: longDoubleType, elts: longDoubleType);
108
109 return CGM.CreateRuntimeFunction(
110 Ty: llvm::FunctionType::get(Result: resultType, Params: params, isVarArg: true),
111 Name: "objc_msgSend_fp2ret");
112 }
113
114 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
115 ///
116 /// The messenger used for super calls, which have different dispatch
117 /// semantics. The class passed is the superclass of the current
118 /// class.
119 llvm::FunctionCallee getMessageSendSuperFn() const {
120 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
121 return CGM.CreateRuntimeFunction(
122 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
123 Name: "objc_msgSendSuper");
124 }
125
126 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
127 ///
128 /// A slightly different messenger used for super calls. The class
129 /// passed is the current class.
130 llvm::FunctionCallee getMessageSendSuperFn2() const {
131 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
132 return CGM.CreateRuntimeFunction(
133 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
134 Name: "objc_msgSendSuper2");
135 }
136
137 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
138 /// SEL op, ...)
139 ///
140 /// The messenger used for super calls which return an aggregate indirectly.
141 llvm::FunctionCallee getMessageSendSuperStretFn() const {
142 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
143 return CGM.CreateRuntimeFunction(
144 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
145 Name: "objc_msgSendSuper_stret");
146 }
147
148 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
149 /// SEL op, ...)
150 ///
151 /// objc_msgSendSuper_stret with the super2 semantics.
152 llvm::FunctionCallee getMessageSendSuperStretFn2() const {
153 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
154 return CGM.CreateRuntimeFunction(
155 Ty: llvm::FunctionType::get(Result: CGM.VoidTy, Params: params, isVarArg: true),
156 Name: "objc_msgSendSuper2_stret");
157 }
158
159 llvm::FunctionCallee getMessageSendSuperFpretFn() const {
160 // There is no objc_msgSendSuper_fpret? How can that work?
161 return getMessageSendSuperFn();
162 }
163
164 llvm::FunctionCallee getMessageSendSuperFpretFn2() const {
165 // There is no objc_msgSendSuper_fpret? How can that work?
166 return getMessageSendSuperFn2();
167 }
168
169protected:
170 CodeGen::CodeGenModule &CGM;
171
172public:
173 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
174 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
175 llvm::PointerType *Int8PtrProgramASTy;
176 llvm::Type *IvarOffsetVarTy;
177
178 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
179 llvm::PointerType *ObjectPtrTy;
180
181 /// PtrObjectPtrTy - LLVM type for id *
182 llvm::PointerType *PtrObjectPtrTy;
183
184 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
185 llvm::PointerType *SelectorPtrTy;
186
187 // SuperCTy - clang type for struct objc_super.
188 QualType SuperCTy;
189 // SuperPtrCTy - clang type for struct objc_super *.
190 QualType SuperPtrCTy;
191
192 /// SuperTy - LLVM type for struct objc_super.
193 llvm::StructType *SuperTy;
194 /// SuperPtrTy - LLVM type for struct objc_super *.
195 llvm::PointerType *SuperPtrTy;
196
197 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
198 /// in GCC parlance).
199 llvm::StructType *PropertyTy;
200
201 /// PropertyListTy - LLVM type for struct objc_property_list
202 /// (_prop_list_t in GCC parlance).
203 llvm::StructType *PropertyListTy;
204 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
205 llvm::PointerType *PropertyListPtrTy;
206
207 // MethodTy - LLVM type for struct objc_method.
208 llvm::StructType *MethodTy;
209
210 /// CacheTy - LLVM type for struct objc_cache.
211 llvm::Type *CacheTy;
212 /// CachePtrTy - LLVM type for struct objc_cache *.
213 llvm::PointerType *CachePtrTy;
214
215 llvm::FunctionCallee getGetPropertyFn() {
216 CodeGen::CodeGenTypes &Types = CGM.getTypes();
217 ASTContext &Ctx = CGM.getContext();
218 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
219 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
220 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
221 CanQualType Params[] = {
222 IdType, SelType,
223 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};
224 llvm::FunctionType *FTy = Types.GetFunctionType(
225 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: IdType, argTypes: Params));
226 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_getProperty");
227 }
228
229 llvm::FunctionCallee getSetPropertyFn() {
230 CodeGen::CodeGenTypes &Types = CGM.getTypes();
231 ASTContext &Ctx = CGM.getContext();
232 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
233 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
234 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
235 CanQualType Params[] = {
236 IdType,
237 SelType,
238 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),
239 IdType,
240 Ctx.BoolTy,
241 Ctx.BoolTy};
242 llvm::FunctionType *FTy = Types.GetFunctionType(
243 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
244 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_setProperty");
245 }
246
247 llvm::FunctionCallee getOptimizedSetPropertyFn(bool atomic, bool copy) {
248 CodeGen::CodeGenTypes &Types = CGM.getTypes();
249 ASTContext &Ctx = CGM.getContext();
250 // void objc_setProperty_atomic(id self, SEL _cmd,
251 // id newValue, ptrdiff_t offset);
252 // void objc_setProperty_nonatomic(id self, SEL _cmd,
253 // id newValue, ptrdiff_t offset);
254 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
255 // id newValue, ptrdiff_t offset);
256 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
257 // id newValue, ptrdiff_t offset);
258
259 SmallVector<CanQualType, 4> Params;
260 CanQualType IdType = Ctx.getCanonicalParamType(T: Ctx.getObjCIdType());
261 CanQualType SelType = Ctx.getCanonicalParamType(T: Ctx.getObjCSelType());
262 Params.push_back(Elt: IdType);
263 Params.push_back(Elt: SelType);
264 Params.push_back(Elt: IdType);
265 Params.push_back(Elt: Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
266 llvm::FunctionType *FTy = Types.GetFunctionType(
267 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
268 const char *name;
269 if (atomic && copy)
270 name = "objc_setProperty_atomic_copy";
271 else if (atomic && !copy)
272 name = "objc_setProperty_atomic";
273 else if (!atomic && copy)
274 name = "objc_setProperty_nonatomic_copy";
275 else
276 name = "objc_setProperty_nonatomic";
277
278 return CGM.CreateRuntimeFunction(Ty: FTy, Name: name);
279 }
280
281 llvm::FunctionCallee getCopyStructFn() {
282 CodeGen::CodeGenTypes &Types = CGM.getTypes();
283 ASTContext &Ctx = CGM.getContext();
284 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
285 SmallVector<CanQualType, 5> Params;
286 Params.push_back(Elt: Ctx.VoidPtrTy);
287 Params.push_back(Elt: Ctx.VoidPtrTy);
288 Params.push_back(Elt: Ctx.getSizeType());
289 Params.push_back(Elt: Ctx.BoolTy);
290 Params.push_back(Elt: Ctx.BoolTy);
291 llvm::FunctionType *FTy = Types.GetFunctionType(
292 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
293 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_copyStruct");
294 }
295
296 /// This routine declares and returns address of:
297 /// void objc_copyCppObjectAtomic(
298 /// void *dest, const void *src,
299 /// void (*copyHelper) (void *dest, const void *source));
300 llvm::FunctionCallee getCppAtomicObjectFunction() {
301 CodeGen::CodeGenTypes &Types = CGM.getTypes();
302 ASTContext &Ctx = CGM.getContext();
303 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void
304 /// *helper);
305 SmallVector<CanQualType, 3> Params;
306 Params.push_back(Elt: Ctx.VoidPtrTy);
307 Params.push_back(Elt: Ctx.VoidPtrTy);
308 Params.push_back(Elt: Ctx.VoidPtrTy);
309 llvm::FunctionType *FTy = Types.GetFunctionType(
310 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
311 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_copyCppObjectAtomic");
312 }
313
314 llvm::FunctionCallee getEnumerationMutationFn() {
315 CodeGen::CodeGenTypes &Types = CGM.getTypes();
316 ASTContext &Ctx = CGM.getContext();
317 // void objc_enumerationMutation (id)
318 SmallVector<CanQualType, 1> Params;
319 Params.push_back(Elt: Ctx.getCanonicalParamType(T: Ctx.getObjCIdType()));
320 llvm::FunctionType *FTy = Types.GetFunctionType(
321 Info: Types.arrangeBuiltinFunctionDeclaration(resultType: Ctx.VoidTy, argTypes: Params));
322 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_enumerationMutation");
323 }
324
325 llvm::FunctionCallee getLookUpClassFn() {
326 CodeGen::CodeGenTypes &Types = CGM.getTypes();
327 ASTContext &Ctx = CGM.getContext();
328 // Class objc_lookUpClass (const char *)
329 SmallVector<CanQualType, 1> Params;
330 Params.push_back(
331 Elt: Ctx.getCanonicalType(T: Ctx.getPointerType(T: Ctx.CharTy.withConst())));
332 llvm::FunctionType *FTy =
333 Types.GetFunctionType(Info: Types.arrangeBuiltinFunctionDeclaration(
334 resultType: Ctx.getCanonicalType(T: Ctx.getObjCClassType()), argTypes: Params));
335 return CGM.CreateRuntimeFunction(Ty: FTy, Name: "objc_lookUpClass");
336 }
337
338 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
339 llvm::FunctionCallee getGcReadWeakFn() {
340 // id objc_read_weak (id *)
341 llvm::Type *args[] = {CGM.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 Ty: llvm::FunctionType::get(Result: CGM.Int32Ty, Params: params, isVarArg: false), Name: "_setjmp",
556 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
557 Index: llvm::AttributeList::FunctionIndex,
558 Kinds: llvm::Attribute::NonLazyBind));
559 }
560
561public:
562 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
563};
564
565/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
566/// modern abi
567class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
568public:
569 // MethodListnfABITy - LLVM for struct _method_list_t
570 llvm::StructType *MethodListnfABITy;
571
572 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
573 llvm::PointerType *MethodListnfABIPtrTy;
574
575 // ProtocolnfABITy = LLVM for struct _protocol_t
576 llvm::StructType *ProtocolnfABITy;
577
578 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
579 llvm::PointerType *ProtocolnfABIPtrTy;
580
581 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
582 llvm::StructType *ProtocolListnfABITy;
583
584 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
585 llvm::PointerType *ProtocolListnfABIPtrTy;
586
587 // ClassnfABITy - LLVM for struct _class_t
588 llvm::StructType *ClassnfABITy;
589
590 // ClassnfABIPtrTy - LLVM for struct _class_t*
591 llvm::PointerType *ClassnfABIPtrTy;
592
593 // IvarnfABITy - LLVM for struct _ivar_t
594 llvm::StructType *IvarnfABITy;
595
596 // IvarListnfABITy - LLVM for struct _ivar_list_t
597 llvm::StructType *IvarListnfABITy;
598
599 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
600 llvm::PointerType *IvarListnfABIPtrTy;
601
602 // ClassRonfABITy - LLVM for struct _class_ro_t
603 llvm::StructType *ClassRonfABITy;
604
605 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
606 llvm::PointerType *ImpnfABITy;
607
608 // CategorynfABITy - LLVM for struct _category_t
609 llvm::StructType *CategorynfABITy;
610
611 // New types for nonfragile abi messaging.
612
613 // MessageRefTy - LLVM for:
614 // struct _message_ref_t {
615 // IMP messenger;
616 // SEL name;
617 // };
618 llvm::StructType *MessageRefTy;
619 // MessageRefCTy - clang type for struct _message_ref_t
620 QualType MessageRefCTy;
621
622 // MessageRefPtrTy - LLVM for struct _message_ref_t*
623 llvm::Type *MessageRefPtrTy;
624 // MessageRefCPtrTy - clang type for struct _message_ref_t*
625 QualType MessageRefCPtrTy;
626
627 // SuperMessageRefTy - LLVM for:
628 // struct _super_message_ref_t {
629 // SUPER_IMP messenger;
630 // SEL name;
631 // };
632 llvm::StructType *SuperMessageRefTy;
633
634 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
635 llvm::PointerType *SuperMessageRefPtrTy;
636
637 llvm::FunctionCallee getMessageSendFixupFn() {
638 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
639 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
640 return CGM.CreateRuntimeFunction(
641 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
642 Name: "objc_msgSend_fixup");
643 }
644
645 llvm::FunctionCallee getMessageSendFpretFixupFn() {
646 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
647 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
648 return CGM.CreateRuntimeFunction(
649 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
650 Name: "objc_msgSend_fpret_fixup");
651 }
652
653 llvm::FunctionCallee getMessageSendStretFixupFn() {
654 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
655 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
656 return CGM.CreateRuntimeFunction(
657 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
658 Name: "objc_msgSend_stret_fixup");
659 }
660
661 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
662 // id objc_msgSendSuper2_fixup (struct objc_super *,
663 // struct _super_message_ref_t*, ...)
664 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
665 return CGM.CreateRuntimeFunction(
666 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
667 Name: "objc_msgSendSuper2_fixup");
668 }
669
670 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
671 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
672 // struct _super_message_ref_t*, ...)
673 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
674 return CGM.CreateRuntimeFunction(
675 Ty: llvm::FunctionType::get(Result: ObjectPtrTy, Params: params, isVarArg: true),
676 Name: "objc_msgSendSuper2_stret_fixup");
677 }
678
679 llvm::FunctionCallee getObjCEndCatchFn() {
680 return CGM.CreateRuntimeFunction(Ty: llvm::FunctionType::get(Result: CGM.VoidTy, isVarArg: false),
681 Name: "objc_end_catch");
682 }
683
684 llvm::FunctionCallee getObjCBeginCatchFn() {
685 llvm::Type *params[] = {Int8PtrTy};
686 return CGM.CreateRuntimeFunction(
687 Ty: llvm::FunctionType::get(Result: Int8PtrTy, Params: params, isVarArg: false), Name: "objc_begin_catch");
688 }
689
690 /// Class objc_loadClassref (void *)
691 ///
692 /// Loads from a classref. For Objective-C stub classes, this invokes the
693 /// initialization callback stored inside the stub. For all other classes
694 /// this simply dereferences the pointer.
695 llvm::FunctionCallee getLoadClassrefFn() const {
696 // Add the non-lazy-bind attribute, since objc_loadClassref is likely to
697 // be called a lot.
698 //
699 // Also it is safe to make it readnone, since we never load or store the
700 // classref except by calling this function.
701 llvm::Type *params[] = {Int8PtrPtrTy};
702 llvm::LLVMContext &C = CGM.getLLVMContext();
703 llvm::AttributeSet AS = llvm::AttributeSet::get(
704 C, Attrs: {
705 llvm::Attribute::get(Context&: C, Kind: llvm::Attribute::NonLazyBind),
706 llvm::Attribute::getWithMemoryEffects(
707 Context&: C, ME: llvm::MemoryEffects::none()),
708 llvm::Attribute::get(Context&: C, Kind: llvm::Attribute::NoUnwind),
709 });
710 llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
711 Ty: llvm::FunctionType::get(Result: ClassnfABIPtrTy, Params: params, isVarArg: false),
712 Name: "objc_loadClassref",
713 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
714 Index: llvm::AttributeList::FunctionIndex, Attrs: AS));
715 if (!CGM.getTriple().isOSBinFormatCOFF())
716 cast<llvm::Function>(Val: F.getCallee())
717 ->setLinkage(llvm::Function::ExternalWeakLinkage);
718
719 return F;
720 }
721
722 llvm::StructType *EHTypeTy;
723 llvm::Type *EHTypePtrTy;
724
725 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
726};
727
728enum class ObjCLabelType {
729 ClassName,
730 MethodVarName,
731 MethodVarType,
732 PropertyName,
733};
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(Elt: 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 args: Name, args: CGM.getPointerAlign(), /*constant*/ args: false,
1807 args: 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 Ty: ObjCTypes.SuperTy, align: CGF.getPointerAlign(), Name: "objc_super");
1989 llvm::Value *ReceiverAsObject =
1990 CGF.Builder.CreateBitCast(V: Receiver, DestTy: 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(Ty: ObjCTypes.ClassTy, Ptr: Target, Idx: 0);
2007 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: Target,
2008 Align: CGF.getPointerAlign());
2009 } else {
2010 llvm::Constant *MetaClassPtr = EmitMetaClassRef(ID: Class);
2011 llvm::Value *SuperPtr =
2012 CGF.Builder.CreateStructGEP(Ty: ObjCTypes.ClassTy, Ptr: MetaClassPtr, Idx: 1);
2013 llvm::Value *Super = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: SuperPtr,
2014 Align: 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(Ty: ObjCTypes.ClassTy, Ptr: ClassPtr, Idx: 1);
2022 Target = CGF.Builder.CreateAlignedLoad(Ty: ClassTyPtr, Addr: ClassPtr,
2023 Align: 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, Arg0: ObjCSuper.getPointer(),
2032 Arg0Ty: ObjCTypes.SuperPtrCTy, IsSuper: true, CallArgs, OMD: Method, ClassReceiver: 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, Arg0: Receiver,
2042 Arg0Ty: CGF.getContext().getObjCIdType(), IsSuper: false, CallArgs,
2043 OMD: Method, ClassReceiver: 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(OMD: Method, CD: 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, 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(T: 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(T: 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 T: 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 char C : Layout)
2706 BitMap += C;
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(V: 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(T: ctx.getPointerType(T: 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(structTy: ObjCTypes.ProtocolTy);
2956 values.add(value: EmitProtocolExtension(PD, methodLists));
2957 values.add(value: GetClassName(RuntimeName: PD->getObjCRuntimeNameAsString()));
2958 values.add(value: EmitProtocolList(Name: "OBJC_PROTOCOL_REFS_" + PD->getName(),
2959 begin: PD->protocol_begin(), end: PD->protocol_end()));
2960 values.add(value: methodLists.emitMethodList(
2961 self: this, PD, kind: ProtocolMethodLists::RequiredInstanceMethods));
2962 values.add(value: 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(global: Entry);
2969 } else {
2970 Entry = values.finishAndCreateGlobal(
2971 args: "OBJC_PROTOCOL_" + PD->getName(), args: CGM.getPointerAlign(),
2972 /*constant*/ args: false, args: 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 Name: "OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3020 MethodTypes: methodLists.emitExtendedTypesArray(self: this), ObjCTypes);
3021
3022 auto instanceProperties = EmitPropertyList(
3023 Name: "OBJC_$_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: false);
3024 auto classProperties =
3025 EmitPropertyList(Name: "OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), Container: nullptr,
3026 OCD: PD, ObjCTypes, IsClassProperty: 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(Ty: ObjCTypes.ProtocolExtensionPtrTy);
3033 }
3034
3035 uint64_t size =
3036 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ProtocolExtensionTy);
3037
3038 ConstantInitBuilder builder(CGM);
3039 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolExtensionTy);
3040 values.addInt(intTy: ObjCTypes.IntTy, value: size);
3041 values.add(value: optInstanceMethods);
3042 values.add(value: optClassMethods);
3043 values.add(value: instanceProperties);
3044 values.add(value: extendedMethodTypes);
3045 values.add(value: classProperties);
3046
3047 // No special section, but goes in llvm.used
3048 return CreateMetadataVar(Name: "_OBJC_PROTOCOLEXT_" + PD->getName(), Init&: values,
3049 Section: StringRef(), Align: CGM.getPointerAlign(), AddToUsed: 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(Ty: 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(ptrTy: ObjCTypes.ProtocolListPtrTy);
3073
3074 // Reserve a slot for the count.
3075 auto countSlot = values.addPlaceholder();
3076
3077 auto refsArray = values.beginArray(eltTy: ObjCTypes.ProtocolPtrTy);
3078 for (const auto *Proto : PDs)
3079 refsArray.add(value: GetProtocolRef(PD: Proto));
3080
3081 auto count = refsArray.size();
3082
3083 // This list is null terminated.
3084 refsArray.addNullPointer(ptrTy: ObjCTypes.ProtocolPtrTy);
3085
3086 refsArray.finishAndAddTo(parent&: values);
3087 values.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.LongTy, value: 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: name, Init&: values, Section: section, Align: CGM.getPointerAlign(), AddToUsed: 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(Ptr: PD->getIdentifier()).second)
3106 continue;
3107 Properties.push_back(Elt: 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>(Val: 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(Ptr: PD->getIdentifier());
3149 Properties.push_back(Elt: 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(Ptr: 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, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: 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, Align: CGM.getPointerAlign(), AddToUsed: 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(Ty: 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(structTy: 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(Elt: MD);
3257 }
3258
3259 Values.add(value: GetClassName(RuntimeName: OCD->getName()));
3260 Values.add(value: GetClassName(RuntimeName: Interface->getObjCRuntimeNameAsString()));
3261 LazySymbols.insert(X: Interface->getIdentifier());
3262
3263 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryInstanceMethods,
3264 Methods: Methods[InstanceMethods]));
3265 Values.add(value: emitMethodList(Name: ExtName, MLT: MethodListType::CategoryClassMethods,
3266 Methods: Methods[ClassMethods]));
3267 if (Category) {
3268 Values.add(value: EmitProtocolList(name: "OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3269 begin: Category->protocol_begin(),
3270 end: Category->protocol_end()));
3271 } else {
3272 Values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
3273 }
3274 Values.addInt(intTy: ObjCTypes.IntTy, value: Size);
3275
3276 // If there is no category @interface then there can be no properties.
3277 if (Category) {
3278 Values.add(value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + ExtName.str(), Container: OCD,
3279 OCD: Category, ObjCTypes, IsClassProperty: false));
3280 Values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), Container: OCD,
3281 OCD: Category, ObjCTypes, IsClassProperty: true));
3282 } else {
3283 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
3284 Values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
3285 }
3286
3287 llvm::GlobalVariable *GV = CreateMetadataVar(
3288 Name: "OBJC_CATEGORY_" + ExtName.str(), Init&: Values,
3289 Section: "__OBJC,__category,regular,no_dead_strip", Align: CGM.getPointerAlign(), AddToUsed: 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(type: 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(type: 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(Elt: 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(Elt: MD);
3448 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
3449 if (GetMethodDefinition(MD))
3450 Methods[InstanceMethods].push_back(Elt: MD);
3451 }
3452 }
3453
3454 ConstantInitBuilder builder(CGM);
3455 auto values = builder.beginStruct(structTy: ObjCTypes.ClassTy);
3456 values.add(value: EmitMetaClass(ID, Protocols, Methods: Methods[ClassMethods]));
3457 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3458 // Record a reference to the super class.
3459 LazySymbols.insert(X: Super->getIdentifier());
3460
3461 values.add(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
3462 } else {
3463 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
3464 }
3465 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
3466 // Version is always 0.
3467 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
3468 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
3469 values.addInt(intTy: ObjCTypes.LongTy, value: Size.getQuantity());
3470 values.add(value: EmitIvarList(ID, ForClass: false));
3471 values.add(value: emitMethodList(Name: ID->getName(), MLT: MethodListType::InstanceMethods,
3472 Methods: Methods[InstanceMethods]));
3473 // cache is always NULL.
3474 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
3475 values.add(value: Protocols);
3476 values.add(value: BuildStrongIvarLayout(OI: ID, beginOffset: CharUnits::Zero(), endOffset: Size));
3477 values.add(value: 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(global: GV);
3489 GV->setSection(Section);
3490 GV->setAlignment(CGM.getPointerAlign().getAsAlign());
3491 CGM.addCompilerUsedGlobal(GV);
3492 } else
3493 GV = CreateMetadataVar(Name, Init&: values, Section, Align: CGM.getPointerAlign(), AddToUsed: 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(Ty: ObjCTypes.ClassTy);
3506
3507 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3508 Flags |= FragileABI_Class_Hidden;
3509
3510 ConstantInitBuilder builder(CGM);
3511 auto values = builder.beginStruct(structTy: 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(value: GetClassName(RuntimeName: 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(value: GetClassName(RuntimeName: Super->getObjCRuntimeNameAsString()));
3522 } else {
3523 values.addNullPointer(ptrTy: ObjCTypes.ClassPtrTy);
3524 }
3525 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
3526 // Version is always 0.
3527 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
3528 values.addInt(intTy: ObjCTypes.LongTy, value: Flags);
3529 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
3530 values.add(value: EmitIvarList(ID, ForClass: true));
3531 values.add(
3532 value: emitMethodList(Name: ID->getName(), MLT: MethodListType::ClassMethods, Methods));
3533 // cache is always NULL.
3534 values.addNullPointer(ptrTy: ObjCTypes.CachePtrTy);
3535 values.add(value: Protocols);
3536 // ivar_layout for metaclass is always NULL.
3537 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
3538 // The class extension is used to store class properties for metaclasses.
3539 values.add(value: 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(global: GV);
3551 } else {
3552 GV = values.finishAndCreateGlobal(args&: Name, args: CGM.getPointerAlign(),
3553 /*constant*/ args: false,
3554 args: 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(OI: ID, beginOffset: CharUnits::Zero(), endOffset: InstanceSize,
3619 hasMRCWeakIvars);
3620 }
3621
3622 // Properties.
3623 llvm::Constant *propertyList =
3624 EmitPropertyList(Name: (isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")
3625 : Twine("_OBJC_$_PROP_LIST_")) +
3626 ID->getName(),
3627 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: isMetaclass);
3628
3629 // Return null if no extension bits are used.
3630 if (layout->isNullValue() && propertyList->isNullValue()) {
3631 return llvm::Constant::getNullValue(Ty: ObjCTypes.ClassExtensionPtrTy);
3632 }
3633
3634 uint64_t size =
3635 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassExtensionTy);
3636
3637 ConstantInitBuilder builder(CGM);
3638 auto values = builder.beginStruct(structTy: ObjCTypes.ClassExtensionTy);
3639 values.addInt(intTy: ObjCTypes.IntTy, value: size);
3640 values.add(value: layout);
3641 values.add(value: propertyList);
3642
3643 return CreateMetadataVar(Name: "OBJC_CLASSEXT_" + ID->getName(), Init&: values,
3644 Section: "__OBJC,__class_ext,regular,no_dead_strip",
3645 Align: CGM.getPointerAlign(), AddToUsed: 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(Ty: 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(eltTy: 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(ty: ObjCTypes.IvarTy);
3684 ivar.add(value: GetMethodVarName(Ident: IVD->getIdentifier()));
3685 ivar.add(value: GetMethodVarType(D: IVD));
3686 ivar.addInt(intTy: ObjCTypes.IntTy, value: ComputeIvarBaseOffset(CGM, OID, Ivar: IVD));
3687 ivar.finishAndAddTo(parent&: 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(Ty: ObjCTypes.IvarListPtrTy);
3696 }
3697
3698 ivars.finishAndAddTo(parent&: ivarList);
3699 ivarList.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.IntTy, value: count);
3700
3701 llvm::GlobalVariable *GV;
3702 GV = CreateMetadataVar(Name: "OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init&: ivarList,
3703 Section: "__OBJC,__instance_vars,regular,no_dead_strip",
3704 Align: CGM.getPointerAlign(), AddToUsed: 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(ty: ObjCTypes.MethodDescriptionTy);
3717 description.add(value: GetMethodVarName(Sel: MD->getSelector()));
3718 description.add(value: GetMethodVarType(D: MD));
3719 description.finishAndAddTo(parent&: 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(ty: ObjCTypes.MethodTy);
3735 method.add(value: GetMethodVarName(Sel: MD->getSelector()));
3736 method.add(value: GetMethodVarType(D: MD));
3737 method.add(value: fn);
3738 method.finishAndAddTo(parent&: 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 Ty: 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(intTy: ObjCTypes.IntTy, value: methods.size());
3815 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodDescriptionTy);
3816 for (auto MD : methods) {
3817 emitMethodDescriptionConstant(builder&: methodArray, MD);
3818 }
3819 methodArray.finishAndAddTo(parent&: values);
3820
3821 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
3822 Align: CGM.getPointerAlign(), AddToUsed: 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(ptrTy: ObjCTypes.Int8PtrTy);
3830 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
3831 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodTy);
3832 for (auto MD : methods) {
3833 if (!MD->isDirectMethod())
3834 emitMethodConstant(builder&: methodArray, MD);
3835 }
3836 methodArray.finishAndAddTo(parent&: values);
3837
3838 llvm::GlobalVariable *GV = CreateMetadataVar(Name: prefix + name, Init&: values, Section: section,
3839 Align: CGM.getPointerAlign(), AddToUsed: 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(VD: OMD->getSelfDecl());
3916 auto selfValue = Builder.CreateLoad(Addr: 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>(Val: selfValue->getType());
3966 auto Zero = llvm::ConstantPointerNull::get(T: selfTy);
3967
3968 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
3969 Builder.CreateCondBr(Cond: Builder.CreateICmpEQ(LHS: selfValue, RHS: Zero), True: SelfIsNilBlock,
3970 False: ContBlock, BranchWeights: 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(D: *OMD->getCmdDecl());
3993 Builder.CreateStore(Val: GetSelector(CGF, Method: OMD),
3994 Addr: CGF.GetAddrOfLocalVar(VD: 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(callee: ObjCTypes.getSyncExitFn(), args: 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::BasicBlock &BB : *CGF.CurFn)
4229 BlocksBeforeTry.insert(V: &BB);
4230
4231 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4232
4233 // Create a read hazard for the allocas. This inhibits dead-store
4234 // optimizations and forces the values to memory. This hazard is
4235 // inserted before any 'throwing' calls in the protected scope to
4236 // reflect the possibility that the variables might be read from the
4237 // catch block if the call throws.
4238 {
4239 std::string Constraint;
4240 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4241 if (I)
4242 Constraint += ',';
4243 Constraint += "*m";
4244 }
4245
4246 ReadHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
4247 }
4248
4249 // Create a write hazard for the allocas. This inhibits folding
4250 // loads across the hazard. This hazard is inserted at the
4251 // beginning of the catch path to reflect the possibility that the
4252 // variables might have been written within the protected scope.
4253 {
4254 std::string Constraint;
4255 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4256 if (I)
4257 Constraint += ',';
4258 Constraint += "=*m";
4259 }
4260
4261 WriteHazard = llvm::InlineAsm::get(Ty: AsmFnTy, AsmString: "", Constraints: Constraint, hasSideEffects: true, isAlignStack: false);
4262 }
4263}
4264
4265/// Emit a write hazard at the current location.
4266void FragileHazards::emitWriteHazard() {
4267 if (Locals.empty())
4268 return;
4269
4270 llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(callee: WriteHazard, args: Locals);
4271 for (auto Pair : llvm::enumerate(First&: Locals))
4272 Call->addParamAttr(
4273 ArgNo: Pair.index(),
4274 Attr: llvm::Attribute::get(
4275 Context&: CGF.getLLVMContext(), Kind: llvm::Attribute::ElementType,
4276 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
4277}
4278
4279void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
4280 assert(!Locals.empty());
4281 llvm::CallInst *call = Builder.CreateCall(Callee: ReadHazard, Args: Locals);
4282 call->setDoesNotThrow();
4283 call->setCallingConv(CGF.getRuntimeCC());
4284 for (auto Pair : llvm::enumerate(First&: Locals))
4285 call->addParamAttr(
4286 ArgNo: Pair.index(),
4287 Attr: llvm::Attribute::get(
4288 Context&: Builder.getContext(), Kind: llvm::Attribute::ElementType,
4289 Ty: cast<llvm::AllocaInst>(Val: Pair.value())->getAllocatedType()));
4290}
4291
4292/// Emit read hazards in all the protected blocks, i.e. all the blocks
4293/// which have been inserted since the beginning of the try.
4294void FragileHazards::emitHazardsInNewBlocks() {
4295 if (Locals.empty())
4296 return;
4297
4298 CGBuilderTy Builder(CGF, CGF.getLLVMContext());
4299
4300 // Iterate through all blocks, skipping those prior to the try.
4301 for (llvm::BasicBlock &BB : *CGF.CurFn) {
4302 if (BlocksBeforeTry.count(V: &BB))
4303 continue;
4304
4305 // Walk through all the calls in the block.
4306 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
4307 ++BI) {
4308 llvm::Instruction &I = *BI;
4309
4310 // Ignore instructions that aren't non-intrinsic calls.
4311 // These are the only calls that can possibly call longjmp.
4312 if (!isa<llvm::CallInst>(Val: I) && !isa<llvm::InvokeInst>(Val: I))
4313 continue;
4314 if (isa<llvm::IntrinsicInst>(Val: I))
4315 continue;
4316
4317 // Ignore call sites marked nounwind. This may be questionable,
4318 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
4319 if (cast<llvm::CallBase>(Val&: I).doesNotThrow())
4320 continue;
4321
4322 // Insert a read hazard before the call. This will ensure that
4323 // any writes to the locals are performed before making the
4324 // call. If the call throws, then this is sufficient to
4325 // guarantee correctness as long as it doesn't also write to any
4326 // locals.
4327 Builder.SetInsertPoint(TheBB: &BB, IP: BI);
4328 emitReadHazard(Builder);
4329 }
4330 }
4331}
4332
4333static void addIfPresent(llvm::DenseSet<llvm::Value *> &S, Address V) {
4334 if (V.isValid())
4335 if (llvm::Value *Ptr = V.getBasePointer())
4336 S.insert(V: Ptr);
4337}
4338
4339void FragileHazards::collectLocals() {
4340 // Compute a set of allocas to ignore.
4341 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
4342 addIfPresent(S&: AllocasToIgnore, V: CGF.ReturnValue);
4343 addIfPresent(S&: AllocasToIgnore, V: CGF.NormalCleanupDest);
4344
4345 // Collect all the allocas currently in the function. This is
4346 // probably way too aggressive.
4347 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
4348 for (llvm::Instruction &I : Entry)
4349 if (isa<llvm::AllocaInst>(Val: I) && !AllocasToIgnore.count(V: &I))
4350 Locals.push_back(Elt: &I);
4351}
4352
4353llvm::FunctionType *FragileHazards::GetAsmFnType() {
4354 SmallVector<llvm::Type *, 16> tys(Locals.size());
4355 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
4356 tys[i] = Locals[i]->getType();
4357 return llvm::FunctionType::get(Result: CGF.VoidTy, Params: tys, isVarArg: false);
4358}
4359
4360/*
4361
4362 Objective-C setjmp-longjmp (sjlj) Exception Handling
4363 --
4364
4365 A catch buffer is a setjmp buffer plus:
4366 - a pointer to the exception that was caught
4367 - a pointer to the previous exception data buffer
4368 - two pointers of reserved storage
4369 Therefore catch buffers form a stack, with a pointer to the top
4370 of the stack kept in thread-local storage.
4371
4372 objc_exception_try_enter pushes a catch buffer onto the EH stack.
4373 objc_exception_try_exit pops the given catch buffer, which is
4374 required to be the top of the EH stack.
4375 objc_exception_throw pops the top of the EH stack, writes the
4376 thrown exception into the appropriate field, and longjmps
4377 to the setjmp buffer. It crashes the process (with a printf
4378 and an abort()) if there are no catch buffers on the stack.
4379 objc_exception_extract just reads the exception pointer out of the
4380 catch buffer.
4381
4382 There's no reason an implementation couldn't use a light-weight
4383 setjmp here --- something like __builtin_setjmp, but API-compatible
4384 with the heavyweight setjmp. This will be more important if we ever
4385 want to implement correct ObjC/C++ exception interactions for the
4386 fragile ABI.
4387
4388 Note that for this use of setjmp/longjmp to be correct in the presence of
4389 optimization, we use inline assembly on the set of local variables to force
4390 flushing locals to memory immediately before any protected calls and to
4391 inhibit optimizing locals across the setjmp->catch edge.
4392
4393 The basic framework for a @try-catch-finally is as follows:
4394 {
4395 objc_exception_data d;
4396 id _rethrow = null;
4397 bool _call_try_exit = true;
4398
4399 objc_exception_try_enter(&d);
4400 if (!setjmp(d.jmp_buf)) {
4401 ... try body ...
4402 } else {
4403 // exception path
4404 id _caught = objc_exception_extract(&d);
4405
4406 // enter new try scope for handlers
4407 if (!setjmp(d.jmp_buf)) {
4408 ... match exception and execute catch blocks ...
4409
4410 // fell off end, rethrow.
4411 _rethrow = _caught;
4412 ... jump-through-finally to finally_rethrow ...
4413 } else {
4414 // exception in catch block
4415 _rethrow = objc_exception_extract(&d);
4416 _call_try_exit = false;
4417 ... jump-through-finally to finally_rethrow ...
4418 }
4419 }
4420 ... jump-through-finally to finally_end ...
4421
4422 finally:
4423 if (_call_try_exit)
4424 objc_exception_try_exit(&d);
4425
4426 ... finally block ....
4427 ... dispatch to finally destination ...
4428
4429 finally_rethrow:
4430 objc_exception_throw(_rethrow);
4431
4432 finally_end:
4433 }
4434
4435 This framework differs slightly from the one gcc uses, in that gcc
4436 uses _rethrow to determine if objc_exception_try_exit should be called
4437 and if the object should be rethrown. This breaks in the face of
4438 throwing nil and introduces unnecessary branches.
4439
4440 We specialize this framework for a few particular circumstances:
4441
4442 - If there are no catch blocks, then we avoid emitting the second
4443 exception handling context.
4444
4445 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
4446 e)) we avoid emitting the code to rethrow an uncaught exception.
4447
4448 - FIXME: If there is no @finally block we can do a few more
4449 simplifications.
4450
4451 Rethrows and Jumps-Through-Finally
4452 --
4453
4454 '@throw;' is supported by pushing the currently-caught exception
4455 onto ObjCEHStack while the @catch blocks are emitted.
4456
4457 Branches through the @finally block are handled with an ordinary
4458 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
4459 exceptions are not compatible with C++ exceptions, and this is
4460 hardly the only place where this will go wrong.
4461
4462 @synchronized(expr) { stmt; } is emitted as if it were:
4463 id synch_value = expr;
4464 objc_sync_enter(synch_value);
4465 @try { stmt; } @finally { objc_sync_exit(synch_value); }
4466*/
4467
4468void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
4469 const Stmt &S) {
4470 bool isTry = isa<ObjCAtTryStmt>(Val: S);
4471
4472 // A destination for the fall-through edges of the catch handlers to
4473 // jump to.
4474 CodeGenFunction::JumpDest FinallyEnd =
4475 CGF.getJumpDestInCurrentScope(Name: "finally.end");
4476
4477 // A destination for the rethrow edge of the catch handlers to jump
4478 // to.
4479 CodeGenFunction::JumpDest FinallyRethrow =
4480 CGF.getJumpDestInCurrentScope(Name: "finally.rethrow");
4481
4482 // For @synchronized, call objc_sync_enter(sync.expr). The
4483 // evaluation of the expression must occur before we enter the
4484 // @synchronized. We can't avoid a temp here because we need the
4485 // value to be preserved. If the backend ever does liveness
4486 // correctly after setjmp, this will be unnecessary.
4487 Address SyncArgSlot = Address::invalid();
4488 if (!isTry) {
4489 llvm::Value *SyncArg =
4490 CGF.EmitScalarExpr(E: cast<ObjCAtSynchronizedStmt>(Val: S).getSynchExpr());
4491 SyncArg = CGF.Builder.CreateBitCast(V: SyncArg, DestTy: ObjCTypes.ObjectPtrTy);
4492 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getSyncEnterFn(), args: SyncArg);
4493
4494 SyncArgSlot = CGF.CreateTempAlloca(Ty: SyncArg->getType(),
4495 align: CGF.getPointerAlign(), Name: "sync.arg");
4496 CGF.Builder.CreateStore(Val: SyncArg, Addr: SyncArgSlot);
4497 }
4498
4499 // Allocate memory for the setjmp buffer. This needs to be kept
4500 // live throughout the try and catch blocks.
4501 Address ExceptionData = CGF.CreateTempAlloca(
4502 Ty: ObjCTypes.ExceptionDataTy, align: CGF.getPointerAlign(), Name: "exceptiondata.ptr");
4503
4504 // Create the fragile hazards. Note that this will not capture any
4505 // of the allocas required for exception processing, but will
4506 // capture the current basic block (which extends all the way to the
4507 // setjmp call) as "before the @try".
4508 FragileHazards Hazards(CGF);
4509
4510 // Create a flag indicating whether the cleanup needs to call
4511 // objc_exception_try_exit. This is true except when
4512 // - no catches match and we're branching through the cleanup
4513 // just to rethrow the exception, or
4514 // - a catch matched and we're falling out of the catch handler.
4515 // The setjmp-safety rule here is that we should always store to this
4516 // variable in a place that dominates the branch through the cleanup
4517 // without passing through any setjmps.
4518 Address CallTryExitVar = CGF.CreateTempAlloca(
4519 Ty: CGF.Builder.getInt1Ty(), align: CharUnits::One(), Name: "_call_try_exit");
4520
4521 // A slot containing the exception to rethrow. Only needed when we
4522 // have both a @catch and a @finally.
4523 Address PropagatingExnVar = Address::invalid();
4524
4525 // Push a normal cleanup to leave the try scope.
4526 CGF.EHStack.pushCleanup<PerformFragileFinally>(Kind: NormalAndEHCleanup, A: &S,
4527 A: SyncArgSlot, A: CallTryExitVar,
4528 A: ExceptionData, A: &ObjCTypes);
4529
4530 // Enter a try block:
4531 // - Call objc_exception_try_enter to push ExceptionData on top of
4532 // the EH stack.
4533 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
4534 args: ExceptionData.emitRawPointer(CGF));
4535
4536 // - Call setjmp on the exception data buffer.
4537 llvm::Constant *Zero = llvm::ConstantInt::get(Ty: CGF.Builder.getInt32Ty(), V: 0);
4538 llvm::Value *GEPIndexes[] = {Zero, Zero, Zero};
4539 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
4540 Ty: ObjCTypes.ExceptionDataTy, Ptr: ExceptionData.emitRawPointer(CGF), IdxList: GEPIndexes,
4541 Name: "setjmp_buffer");
4542 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
4543 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp_result");
4544 SetJmpResult->setCanReturnTwice();
4545
4546 // If setjmp returned 0, enter the protected block; otherwise,
4547 // branch to the handler.
4548 llvm::BasicBlock *TryBlock = CGF.createBasicBlock(name: "try");
4549 llvm::BasicBlock *TryHandler = CGF.createBasicBlock(name: "try.handler");
4550 llvm::Value *DidCatch =
4551 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
4552 CGF.Builder.CreateCondBr(Cond: DidCatch, True: TryHandler, False: TryBlock);
4553
4554 // Emit the protected block.
4555 CGF.EmitBlock(BB: TryBlock);
4556 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
4557 CGF.EmitStmt(S: isTry ? cast<ObjCAtTryStmt>(Val: S).getTryBody()
4558 : cast<ObjCAtSynchronizedStmt>(Val: S).getSynchBody());
4559
4560 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
4561
4562 // Emit the exception handler block.
4563 CGF.EmitBlock(BB: TryHandler);
4564
4565 // Don't optimize loads of the in-scope locals across this point.
4566 Hazards.emitWriteHazard();
4567
4568 // For a @synchronized (or a @try with no catches), just branch
4569 // through the cleanup to the rethrow block.
4570 if (!isTry || !cast<ObjCAtTryStmt>(Val: S).getNumCatchStmts()) {
4571 // Tell the cleanup not to re-pop the exit.
4572 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
4573 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
4574
4575 // Otherwise, we have to match against the caught exceptions.
4576 } else {
4577 // Retrieve the exception object. We may emit multiple blocks but
4578 // nothing can cross this so the value is already in SSA form.
4579 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
4580 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
4581 name: "caught");
4582
4583 // Push the exception to rethrow onto the EH value stack for the
4584 // benefit of any @throws in the handlers.
4585 CGF.ObjCEHValueStack.push_back(Elt: Caught);
4586
4587 const ObjCAtTryStmt *AtTryStmt = cast<ObjCAtTryStmt>(Val: &S);
4588
4589 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
4590
4591 llvm::BasicBlock *CatchBlock = nullptr;
4592 llvm::BasicBlock *CatchHandler = nullptr;
4593 if (HasFinally) {
4594 // Save the currently-propagating exception before
4595 // objc_exception_try_enter clears the exception slot.
4596 PropagatingExnVar = CGF.CreateTempAlloca(
4597 Ty: Caught->getType(), align: CGF.getPointerAlign(), Name: "propagating_exception");
4598 CGF.Builder.CreateStore(Val: Caught, Addr: PropagatingExnVar);
4599
4600 // Enter a new exception try block (in case a @catch block
4601 // throws an exception).
4602 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionTryEnterFn(),
4603 args: ExceptionData.emitRawPointer(CGF));
4604
4605 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
4606 callee: ObjCTypes.getSetJmpFn(), args: SetJmpBuffer, name: "setjmp.result");
4607 SetJmpResult->setCanReturnTwice();
4608
4609 llvm::Value *Threw =
4610 CGF.Builder.CreateIsNotNull(Arg: SetJmpResult, Name: "did_catch_exception");
4611
4612 CatchBlock = CGF.createBasicBlock(name: "catch");
4613 CatchHandler = CGF.createBasicBlock(name: "catch_for_catch");
4614 CGF.Builder.CreateCondBr(Cond: Threw, True: CatchHandler, False: CatchBlock);
4615
4616 CGF.EmitBlock(BB: CatchBlock);
4617 }
4618
4619 CGF.Builder.CreateStore(Val: CGF.Builder.getInt1(V: HasFinally), Addr: CallTryExitVar);
4620
4621 // Handle catch list. As a special case we check if everything is
4622 // matched and avoid generating code for falling off the end if
4623 // so.
4624 bool AllMatched = false;
4625 for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) {
4626 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4627 const ObjCObjectPointerType *OPT = nullptr;
4628
4629 // catch(...) always matches.
4630 if (!CatchParam) {
4631 AllMatched = true;
4632 } else {
4633 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
4634
4635 // catch(id e) always matches under this ABI, since only
4636 // ObjC exceptions end up here in the first place.
4637 // FIXME: For the time being we also match id<X>; this should
4638 // be rejected by Sema instead.
4639 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
4640 AllMatched = true;
4641 }
4642
4643 // If this is a catch-all, we don't need to test anything.
4644 if (AllMatched) {
4645 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4646
4647 if (CatchParam) {
4648 CGF.EmitAutoVarDecl(D: *CatchParam);
4649 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4650
4651 // These types work out because ConvertType(id) == i8*.
4652 EmitInitOfCatchParam(CGF, exn: Caught, paramDecl: CatchParam);
4653 }
4654
4655 CGF.EmitStmt(S: CatchStmt->getCatchBody());
4656
4657 // The scope of the catch variable ends right here.
4658 CatchVarCleanups.ForceCleanup();
4659
4660 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
4661 break;
4662 }
4663
4664 assert(OPT && "Unexpected non-object pointer type in @catch");
4665 const ObjCObjectType *ObjTy = OPT->getObjectType();
4666
4667 // FIXME: @catch (Class c) ?
4668 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
4669 assert(IDecl && "Catch parameter must have Objective-C type!");
4670
4671 // Check if the @catch block matches the exception object.
4672 llvm::Value *Class = EmitClassRef(CGF, ID: IDecl);
4673
4674 llvm::Value *matchArgs[] = {Class, Caught};
4675 llvm::CallInst *Match = CGF.EmitNounwindRuntimeCall(
4676 callee: ObjCTypes.getExceptionMatchFn(), args: matchArgs, name: "match");
4677
4678 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock(name: "match");
4679 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock(name: "catch.next");
4680
4681 CGF.Builder.CreateCondBr(Cond: CGF.Builder.CreateIsNotNull(Arg: Match, Name: "matched"),
4682 True: MatchedBlock, False: NextCatchBlock);
4683
4684 // Emit the @catch block.
4685 CGF.EmitBlock(BB: MatchedBlock);
4686
4687 // Collect any cleanups for the catch variable. The scope lasts until
4688 // the end of the catch body.
4689 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4690
4691 CGF.EmitAutoVarDecl(D: *CatchParam);
4692 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4693
4694 // Initialize the catch variable.
4695 llvm::Value *Tmp = CGF.Builder.CreateBitCast(
4696 V: Caught, DestTy: CGF.ConvertType(T: CatchParam->getType()));
4697 EmitInitOfCatchParam(CGF, exn: Tmp, paramDecl: CatchParam);
4698
4699 CGF.EmitStmt(S: CatchStmt->getCatchBody());
4700
4701 // We're done with the catch variable.
4702 CatchVarCleanups.ForceCleanup();
4703
4704 CGF.EmitBranchThroughCleanup(Dest: FinallyEnd);
4705
4706 CGF.EmitBlock(BB: NextCatchBlock);
4707 }
4708
4709 CGF.ObjCEHValueStack.pop_back();
4710
4711 // If nothing wanted anything to do with the caught exception,
4712 // kill the extract call.
4713 if (Caught->use_empty())
4714 Caught->eraseFromParent();
4715
4716 if (!AllMatched)
4717 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
4718
4719 if (HasFinally) {
4720 // Emit the exception handler for the @catch blocks.
4721 CGF.EmitBlock(BB: CatchHandler);
4722
4723 // In theory we might now need a write hazard, but actually it's
4724 // unnecessary because there's no local-accessing code between
4725 // the try's write hazard and here.
4726 // Hazards.emitWriteHazard();
4727
4728 // Extract the new exception and save it to the
4729 // propagating-exception slot.
4730 assert(PropagatingExnVar.isValid());
4731 llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall(
4732 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF),
4733 name: "caught");
4734 CGF.Builder.CreateStore(Val: NewCaught, Addr: PropagatingExnVar);
4735
4736 // Don't pop the catch handler; the throw already did.
4737 CGF.Builder.CreateStore(Val: CGF.Builder.getFalse(), Addr: CallTryExitVar);
4738 CGF.EmitBranchThroughCleanup(Dest: FinallyRethrow);
4739 }
4740 }
4741
4742 // Insert read hazards as required in the new blocks.
4743 Hazards.emitHazardsInNewBlocks();
4744
4745 // Pop the cleanup.
4746 CGF.Builder.restoreIP(IP: TryFallthroughIP);
4747 if (CGF.HaveInsertPoint())
4748 CGF.Builder.CreateStore(Val: CGF.Builder.getTrue(), Addr: CallTryExitVar);
4749 CGF.PopCleanupBlock();
4750 CGF.EmitBlock(BB: FinallyEnd.getBlock(), IsFinished: true);
4751
4752 // Emit the rethrow block.
4753 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4754 CGF.EmitBlock(BB: FinallyRethrow.getBlock(), IsFinished: true);
4755 if (CGF.HaveInsertPoint()) {
4756 // If we have a propagating-exception variable, check it.
4757 llvm::Value *PropagatingExn;
4758 if (PropagatingExnVar.isValid()) {
4759 PropagatingExn = CGF.Builder.CreateLoad(Addr: PropagatingExnVar);
4760
4761 // Otherwise, just look in the buffer for the exception to throw.
4762 } else {
4763 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
4764 callee: ObjCTypes.getExceptionExtractFn(), args: ExceptionData.emitRawPointer(CGF));
4765 PropagatingExn = Caught;
4766 }
4767
4768 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(),
4769 args: PropagatingExn);
4770 CGF.Builder.CreateUnreachable();
4771 }
4772
4773 CGF.Builder.restoreIP(IP: SavedIP);
4774}
4775
4776void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4777 const ObjCAtThrowStmt &S,
4778 bool ClearInsertionPoint) {
4779 llvm::Value *ExceptionAsObject;
4780
4781 if (const Expr *ThrowExpr = S.getThrowExpr()) {
4782 llvm::Value *Exception = CGF.EmitObjCThrowOperand(expr: ThrowExpr);
4783 ExceptionAsObject =
4784 CGF.Builder.CreateBitCast(V: Exception, DestTy: ObjCTypes.ObjectPtrTy);
4785 } else {
4786 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4787 "Unexpected rethrow outside @catch block.");
4788 ExceptionAsObject = CGF.ObjCEHValueStack.back();
4789 }
4790
4791 CGF.EmitRuntimeCall(callee: ObjCTypes.getExceptionThrowFn(), args: ExceptionAsObject)
4792 ->setDoesNotReturn();
4793 CGF.Builder.CreateUnreachable();
4794
4795 // Clear the insertion point to indicate we are in unreachable code.
4796 if (ClearInsertionPoint)
4797 CGF.Builder.ClearInsertionPoint();
4798}
4799
4800/// EmitObjCWeakRead - Code gen for loading value of a __weak
4801/// object: objc_read_weak (id *src)
4802///
4803llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4804 Address AddrWeakObj) {
4805 llvm::Type *DestTy = AddrWeakObj.getElementType();
4806 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
4807 V: AddrWeakObj.emitRawPointer(CGF), DestTy: ObjCTypes.PtrObjectPtrTy);
4808 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
4809 callee: ObjCTypes.getGcReadWeakFn(), args: AddrWeakObjVal, name: "weakread");
4810 read_weak = CGF.Builder.CreateBitCast(V: read_weak, DestTy);
4811 return read_weak;
4812}
4813
4814/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4815/// objc_assign_weak (id src, id *dst)
4816///
4817void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4818 llvm::Value *src, Address dst) {
4819 llvm::Type *SrcTy = src->getType();
4820 if (!isa<llvm::PointerType>(Val: SrcTy)) {
4821 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
4822 assert(Size <= 8 && "does not support size > 8");
4823 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
4824 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
4825 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
4826 }
4827 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
4828 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
4829 DestTy: ObjCTypes.PtrObjectPtrTy);
4830 llvm::Value *args[] = {src, dstVal};
4831 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignWeakFn(), args,
4832 name: "weakassign");
4833}
4834
4835/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4836/// objc_assign_global (id src, id *dst)
4837///
4838void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4839 llvm::Value *src, Address dst,
4840 bool threadlocal) {
4841 llvm::Type *SrcTy = src->getType();
4842 if (!isa<llvm::PointerType>(Val: SrcTy)) {
4843 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
4844 assert(Size <= 8 && "does not support size > 8");
4845 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
4846 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
4847 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
4848 }
4849 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
4850 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
4851 DestTy: ObjCTypes.PtrObjectPtrTy);
4852 llvm::Value *args[] = {src, dstVal};
4853 if (!threadlocal)
4854 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignGlobalFn(), args,
4855 name: "globalassign");
4856 else
4857 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignThreadLocalFn(), args,
4858 name: "threadlocalassign");
4859}
4860
4861/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4862/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4863///
4864void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4865 llvm::Value *src, Address dst,
4866 llvm::Value *ivarOffset) {
4867 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4868 llvm::Type *SrcTy = src->getType();
4869 if (!isa<llvm::PointerType>(Val: SrcTy)) {
4870 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
4871 assert(Size <= 8 && "does not support size > 8");
4872 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
4873 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
4874 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
4875 }
4876 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
4877 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
4878 DestTy: ObjCTypes.PtrObjectPtrTy);
4879 llvm::Value *args[] = {src, dstVal, ivarOffset};
4880 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignIvarFn(), args);
4881}
4882
4883/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4884/// objc_assign_strongCast (id src, id *dst)
4885///
4886void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4887 llvm::Value *src, Address dst) {
4888 llvm::Type *SrcTy = src->getType();
4889 if (!isa<llvm::PointerType>(Val: SrcTy)) {
4890 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
4891 assert(Size <= 8 && "does not support size > 8");
4892 src = (Size == 4) ? CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int32Ty)
4893 : CGF.Builder.CreateBitCast(V: src, DestTy: CGM.Int64Ty);
4894 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
4895 }
4896 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
4897 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
4898 DestTy: ObjCTypes.PtrObjectPtrTy);
4899 llvm::Value *args[] = {src, dstVal};
4900 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignStrongCastFn(), args,
4901 name: "strongassign");
4902}
4903
4904void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4905 Address DestPtr, Address SrcPtr,
4906 llvm::Value *size) {
4907 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
4908 SrcPtr.emitRawPointer(CGF), size};
4909 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.GcMemmoveCollectableFn(), args);
4910}
4911
4912/// EmitObjCValueForIvar - Code Gen for ivar reference.
4913///
4914LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4915 QualType ObjectTy,
4916 llvm::Value *BaseValue,
4917 const ObjCIvarDecl *Ivar,
4918 unsigned CVRQualifiers) {
4919 const ObjCInterfaceDecl *ID =
4920 ObjectTy->castAs<ObjCObjectType>()->getInterface();
4921 return EmitValueForIvarAtOffset(CGF, OID: ID, BaseValue, Ivar, CVRQualifiers,
4922 Offset: EmitIvarOffset(CGF, Interface: ID, Ivar));
4923}
4924
4925llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4926 const ObjCInterfaceDecl *Interface,
4927 const ObjCIvarDecl *Ivar) {
4928 uint64_t Offset = ComputeIvarBaseOffset(CGM, OID: Interface, Ivar);
4929 return llvm::ConstantInt::get(
4930 Ty: CGM.getTypes().ConvertType(T: CGM.getContext().LongTy), V: Offset);
4931}
4932
4933/* *** Private Interface *** */
4934
4935std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4936 StringRef MachOAttributes) {
4937 switch (CGM.getTriple().getObjectFormat()) {
4938 case llvm::Triple::UnknownObjectFormat:
4939 llvm_unreachable("unexpected object file format");
4940 case llvm::Triple::MachO: {
4941 if (MachOAttributes.empty())
4942 return ("__DATA," + Section).str();
4943 return ("__DATA," + Section + "," + MachOAttributes).str();
4944 }
4945 case llvm::Triple::ELF:
4946 assert(Section.starts_with("__") && "expected the name to begin with __");
4947 return Section.substr(Start: 2).str();
4948 case llvm::Triple::COFF:
4949 assert(Section.starts_with("__") && "expected the name to begin with __");
4950 return ("." + Section.substr(Start: 2) + "$B").str();
4951 case llvm::Triple::Wasm:
4952 case llvm::Triple::GOFF:
4953 case llvm::Triple::SPIRV:
4954 case llvm::Triple::XCOFF:
4955 case llvm::Triple::DXContainer:
4956 llvm::report_fatal_error(
4957 reason: "Objective-C support is unimplemented for object file format");
4958 }
4959
4960 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");
4961}
4962
4963// clang-format off
4964/// EmitImageInfo - Emit the image info marker used to encode some module
4965/// level information.
4966///
4967/// See: <rdr://4810609&4810587&4810587>
4968/// struct IMAGE_INFO {
4969/// unsigned version;
4970/// unsigned flags;
4971/// };
4972enum ImageInfoFlags {
4973 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4974 eImageInfo_GarbageCollected = (1 << 1),
4975 eImageInfo_GCOnly = (1 << 2),
4976 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4977
4978 // A flag indicating that the module has no instances of a @synthesize of a
4979 // superclass variable. This flag used to be consumed by the runtime to work
4980 // around miscompile by gcc.
4981 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4982 eImageInfo_ImageIsSimulated = (1 << 5),
4983 eImageInfo_ClassProperties = (1 << 6)
4984};
4985// clang-format on
4986
4987void CGObjCCommonMac::EmitImageInfo() {
4988 unsigned version = 0; // Version is unused?
4989 std::string Section =
4990 (ObjCABI == 1)
4991 ? "__OBJC,__image_info,regular"
4992 : GetSectionName(Section: "__objc_imageinfo", MachOAttributes: "regular,no_dead_strip");
4993
4994 // Generate module-level named metadata to convey this information to the
4995 // linker and code-gen.
4996 llvm::Module &Mod = CGM.getModule();
4997
4998 // Add the ObjC ABI version to the module flags.
4999 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Version", Val: ObjCABI);
5000 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Version",
5001 Val: version);
5002 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Image Info Section",
5003 Val: llvm::MDString::get(Context&: VMContext, Str: Section));
5004
5005 auto Int8Ty = llvm::Type::getInt8Ty(C&: VMContext);
5006 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5007 // Non-GC overrides those files which specify GC.
5008 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
5009 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: 0));
5010 } else {
5011 // Add the ObjC garbage collection value.
5012 Mod.addModuleFlag(
5013 Behavior: llvm::Module::Error, Key: "Objective-C Garbage Collection",
5014 Val: llvm::ConstantInt::get(Ty: Int8Ty, V: (uint8_t)eImageInfo_GarbageCollected));
5015
5016 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
5017 // Add the ObjC GC Only value.
5018 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C GC Only",
5019 Val: eImageInfo_GCOnly);
5020
5021 // Require that GC be specified and set to eImageInfo_GarbageCollected.
5022 llvm::Metadata *Ops[2] = {
5023 llvm::MDString::get(Context&: VMContext, Str: "Objective-C Garbage Collection"),
5024 llvm::ConstantAsMetadata::get(
5025 C: llvm::ConstantInt::get(Ty: Int8Ty, V: eImageInfo_GarbageCollected))};
5026 Mod.addModuleFlag(Behavior: llvm::Module::Require, Key: "Objective-C GC Only",
5027 Val: llvm::MDNode::get(Context&: VMContext, MDs: Ops));
5028 }
5029 }
5030
5031 // Indicate whether we're compiling this to run on a simulator.
5032 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
5033 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Is Simulated",
5034 Val: eImageInfo_ImageIsSimulated);
5035
5036 // Indicate whether we are generating class properties.
5037 Mod.addModuleFlag(Behavior: llvm::Module::Error, Key: "Objective-C Class Properties",
5038 Val: eImageInfo_ClassProperties);
5039}
5040
5041// struct objc_module {
5042// unsigned long version;
5043// unsigned long size;
5044// const char *name;
5045// Symtab symtab;
5046// };
5047
5048// FIXME: Get from somewhere
5049static const int ModuleVersion = 7;
5050
5051void CGObjCMac::EmitModuleInfo() {
5052 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ModuleTy);
5053
5054 ConstantInitBuilder builder(CGM);
5055 auto values = builder.beginStruct(structTy: ObjCTypes.ModuleTy);
5056 values.addInt(intTy: ObjCTypes.LongTy, value: ModuleVersion);
5057 values.addInt(intTy: ObjCTypes.LongTy, value: Size);
5058 // This used to be the filename, now it is unused. <rdr://4327263>
5059 values.add(value: GetClassName(RuntimeName: StringRef("")));
5060 values.add(value: EmitModuleSymbols());
5061 CreateMetadataVar(Name: "OBJC_MODULES", Init&: values,
5062 Section: "__OBJC,__module_info,regular,no_dead_strip",
5063 Align: CGM.getPointerAlign(), AddToUsed: true);
5064}
5065
5066llvm::Constant *CGObjCMac::EmitModuleSymbols() {
5067 unsigned NumClasses = DefinedClasses.size();
5068 unsigned NumCategories = DefinedCategories.size();
5069
5070 // Return null if no symbols were defined.
5071 if (!NumClasses && !NumCategories)
5072 return llvm::Constant::getNullValue(Ty: ObjCTypes.SymtabPtrTy);
5073
5074 ConstantInitBuilder builder(CGM);
5075 auto values = builder.beginStruct();
5076 values.addInt(intTy: ObjCTypes.LongTy, value: 0);
5077 values.addNullPointer(ptrTy: ObjCTypes.SelectorPtrTy);
5078 values.addInt(intTy: ObjCTypes.ShortTy, value: NumClasses);
5079 values.addInt(intTy: ObjCTypes.ShortTy, value: NumCategories);
5080
5081 // The runtime expects exactly the list of defined classes followed
5082 // by the list of defined categories, in a single array.
5083 auto array = values.beginArray(eltTy: ObjCTypes.Int8PtrTy);
5084 for (unsigned i = 0; i < NumClasses; i++) {
5085 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5086 assert(ID);
5087 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5088 // We are implementing a weak imported interface. Give it external linkage
5089 if (ID->isWeakImported() && !IMP->isWeakImported())
5090 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5091
5092 array.add(value: DefinedClasses[i]);
5093 }
5094 for (unsigned i = 0; i < NumCategories; i++)
5095 array.add(value: DefinedCategories[i]);
5096
5097 array.finishAndAddTo(parent&: values);
5098
5099 llvm::GlobalVariable *GV = CreateMetadataVar(
5100 Name: "OBJC_SYMBOLS", Init&: values, Section: "__OBJC,__symbols,regular,no_dead_strip",
5101 Align: CGM.getPointerAlign(), AddToUsed: true);
5102 return GV;
5103}
5104
5105llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
5106 IdentifierInfo *II) {
5107 LazySymbols.insert(X: II);
5108
5109 llvm::GlobalVariable *&Entry = ClassReferences[II];
5110
5111 if (!Entry) {
5112 Entry =
5113 CreateMetadataVar(Name: "OBJC_CLASS_REFERENCES_", Init: GetClassName(RuntimeName: II->getName()),
5114 Section: "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
5115 Align: CGM.getPointerAlign(), AddToUsed: true);
5116 }
5117
5118 return CGF.Builder.CreateAlignedLoad(Ty: Entry->getValueType(), Addr: Entry,
5119 Align: CGF.getPointerAlign());
5120}
5121
5122llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
5123 const ObjCInterfaceDecl *ID) {
5124 // If the class has the objc_runtime_visible attribute, we need to
5125 // use the Objective-C runtime to get the class.
5126 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
5127 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
5128
5129 IdentifierInfo *RuntimeName =
5130 &CGM.getContext().Idents.get(Name: ID->getObjCRuntimeNameAsString());
5131 return EmitClassRefFromId(CGF, II: RuntimeName);
5132}
5133
5134llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
5135 IdentifierInfo *II = &CGM.getContext().Idents.get(Name: "NSAutoreleasePool");
5136 return EmitClassRefFromId(CGF, II);
5137}
5138
5139llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
5140 return CGF.Builder.CreateLoad(Addr: EmitSelectorAddr(Sel));
5141}
5142
5143ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
5144 CharUnits Align = CGM.getPointerAlign();
5145
5146 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5147 if (!Entry) {
5148 Entry = CreateMetadataVar(
5149 Name: "OBJC_SELECTOR_REFERENCES_", Init: GetMethodVarName(Sel),
5150 Section: "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, AddToUsed: true);
5151 Entry->setExternallyInitialized(true);
5152 }
5153
5154 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
5155}
5156
5157llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5158 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5159 if (!Entry)
5160 Entry = CreateCStringLiteral(Name: RuntimeName, Type: ObjCLabelType::ClassName);
5161 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
5162}
5163
5164llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5165 return MethodDefinitions.lookup(Val: MD);
5166}
5167
5168/// GetIvarLayoutName - Returns a unique constant for the given
5169/// ivar layout bitmap.
5170llvm::Constant *
5171CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5172 const ObjCCommonTypesHelper &ObjCTypes) {
5173 return llvm::Constant::getNullValue(Ty: ObjCTypes.Int8PtrTy);
5174}
5175
5176void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
5177 const RecordDecl *RD = RT->getDecl();
5178
5179 // If this is a union, remember that we had one, because it might mess
5180 // up the ordering of layout entries.
5181 if (RD->isUnion())
5182 IsDisordered = true;
5183
5184 const ASTRecordLayout *recLayout = nullptr;
5185 visitAggregate(begin: RD->field_begin(), end: RD->field_end(), aggregateOffset: offset,
5186 getOffset: [&](const FieldDecl *field) -> CharUnits {
5187 if (!recLayout)
5188 recLayout = &CGM.getContext().getASTRecordLayout(D: RD);
5189 auto offsetInBits =
5190 recLayout->getFieldOffset(FieldNo: field->getFieldIndex());
5191 return CGM.getContext().toCharUnitsFromBits(BitSize: offsetInBits);
5192 });
5193}
5194
5195template <class Iterator, class GetOffsetFn>
5196void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5197 CharUnits aggregateOffset,
5198 const GetOffsetFn &getOffset) {
5199 for (; begin != end; ++begin) {
5200 auto field = *begin;
5201
5202 // Skip over bitfields.
5203 if (field->isBitField()) {
5204 continue;
5205 }
5206
5207 // Compute the offset of the field within the aggregate.
5208 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5209
5210 visitField(field, offset: fieldOffset);
5211 }
5212}
5213
5214/// Collect layout information for the given fields into IvarsInfo.
5215void IvarLayoutBuilder::visitField(const FieldDecl *field,
5216 CharUnits fieldOffset) {
5217 QualType fieldType = field->getType();
5218
5219 // Drill down into arrays.
5220 uint64_t numElts = 1;
5221 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(T: fieldType)) {
5222 numElts = 0;
5223 fieldType = arrayType->getElementType();
5224 }
5225 // Unlike incomplete arrays, constant arrays can be nested.
5226 while (auto arrayType = CGM.getContext().getAsConstantArrayType(T: fieldType)) {
5227 numElts *= arrayType->getZExtSize();
5228 fieldType = arrayType->getElementType();
5229 }
5230
5231 assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
5232
5233 // If we ended up with a zero-sized array, we've done what we can do within
5234 // the limits of this layout encoding.
5235 if (numElts == 0)
5236 return;
5237
5238 // Recurse if the base element type is a record type.
5239 if (auto recType = fieldType->getAs<RecordType>()) {
5240 size_t oldEnd = IvarsInfo.size();
5241
5242 visitRecord(RT: recType, offset: fieldOffset);
5243
5244 // If we have an array, replicate the first entry's layout information.
5245 auto numEltEntries = IvarsInfo.size() - oldEnd;
5246 if (numElts != 1 && numEltEntries != 0) {
5247 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(T: recType);
5248 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5249 // Copy the last numEltEntries onto the end of the array, adjusting
5250 // each for the element size.
5251 for (size_t i = 0; i != numEltEntries; ++i) {
5252 auto firstEntry = IvarsInfo[oldEnd + i];
5253 IvarsInfo.push_back(Elt: IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5254 firstEntry.SizeInWords));
5255 }
5256 }
5257 }
5258
5259 return;
5260 }
5261
5262 // Classify the element type.
5263 Qualifiers::GC GCAttr = GetGCAttrTypeForType(Ctx&: CGM.getContext(), FQT: fieldType);
5264
5265 // If it matches what we're looking for, add an entry.
5266 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
5267 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5268 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
5269 CGM.getPointerSize());
5270 IvarsInfo.push_back(Elt: IvarInfo(fieldOffset, numElts));
5271 }
5272}
5273
5274/// buildBitmap - This routine does the horsework of taking the offsets of
5275/// strong/weak references and creating a bitmap. The bitmap is also
5276/// returned in the given buffer, suitable for being passed to \c dump().
5277llvm::Constant *
5278IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5279 llvm::SmallVectorImpl<unsigned char> &buffer) {
5280 // The bitmap is a series of skip/scan instructions, aligned to word
5281 // boundaries. The skip is performed first.
5282 const unsigned char MaxNibble = 0xF;
5283 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5284 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5285
5286 assert(!IvarsInfo.empty() && "generating bitmap for no data");
5287
5288 // Sort the ivar info on byte position in case we encounterred a
5289 // union nested in the ivar list.
5290 if (IsDisordered) {
5291 // This isn't a stable sort, but our algorithm should handle it fine.
5292 llvm::array_pod_sort(Start: IvarsInfo.begin(), End: IvarsInfo.end());
5293 } else {
5294 assert(llvm::is_sorted(IvarsInfo));
5295 }
5296 assert(IvarsInfo.back().Offset < InstanceEnd);
5297
5298 assert(buffer.empty());
5299
5300 // Skip the next N words.
5301 auto skip = [&](unsigned numWords) {
5302 assert(numWords > 0);
5303
5304 // Try to merge into the previous byte. Since scans happen second, we
5305 // can't do this if it includes a scan.
5306 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5307 unsigned lastSkip = buffer.back() >> SkipShift;
5308 if (lastSkip < MaxNibble) {
5309 unsigned claimed = std::min(a: MaxNibble - lastSkip, b: numWords);
5310 numWords -= claimed;
5311 lastSkip += claimed;
5312 buffer.back() = (lastSkip << SkipShift);
5313 }
5314 }
5315
5316 while (numWords >= MaxNibble) {
5317 buffer.push_back(Elt: MaxNibble << SkipShift);
5318 numWords -= MaxNibble;
5319 }
5320 if (numWords) {
5321 buffer.push_back(Elt: numWords << SkipShift);
5322 }
5323 };
5324
5325 // Scan the next N words.
5326 auto scan = [&](unsigned numWords) {
5327 assert(numWords > 0);
5328
5329 // Try to merge into the previous byte. Since scans happen second, we can
5330 // do this even if it includes a skip.
5331 if (!buffer.empty()) {
5332 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5333 if (lastScan < MaxNibble) {
5334 unsigned claimed = std::min(a: MaxNibble - lastScan, b: numWords);
5335 numWords -= claimed;
5336 lastScan += claimed;
5337 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5338 }
5339 }
5340
5341 while (numWords >= MaxNibble) {
5342 buffer.push_back(Elt: MaxNibble << ScanShift);
5343 numWords -= MaxNibble;
5344 }
5345 if (numWords) {
5346 buffer.push_back(Elt: numWords << ScanShift);
5347 }
5348 };
5349
5350 // One past the end of the last scan.
5351 unsigned endOfLastScanInWords = 0;
5352 const CharUnits WordSize = CGM.getPointerSize();
5353
5354 // Consider all the scan requests.
5355 for (auto &request : IvarsInfo) {
5356 CharUnits beginOfScan = request.Offset - InstanceBegin;
5357
5358 // Ignore scan requests that don't start at an even multiple of the
5359 // word size. We can't encode them.
5360 if ((beginOfScan % WordSize) != 0)
5361 continue;
5362
5363 // Ignore scan requests that start before the instance start.
5364 // This assumes that scans never span that boundary. The boundary
5365 // isn't the true start of the ivars, because in the fragile-ARC case
5366 // it's rounded up to word alignment, but the test above should leave
5367 // us ignoring that possibility.
5368 if (beginOfScan.isNegative()) {
5369 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5370 continue;
5371 }
5372
5373 unsigned beginOfScanInWords = beginOfScan / WordSize;
5374 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5375
5376 // If the scan starts some number of words after the last one ended,
5377 // skip forward.
5378 if (beginOfScanInWords > endOfLastScanInWords) {
5379 skip(beginOfScanInWords - endOfLastScanInWords);
5380
5381 // Otherwise, start scanning where the last left off.
5382 } else {
5383 beginOfScanInWords = endOfLastScanInWords;
5384
5385 // If that leaves us with nothing to scan, ignore this request.
5386 if (beginOfScanInWords >= endOfScanInWords)
5387 continue;
5388 }
5389
5390 // Scan to the end of the request.
5391 assert(beginOfScanInWords < endOfScanInWords);
5392 scan(endOfScanInWords - beginOfScanInWords);
5393 endOfLastScanInWords = endOfScanInWords;
5394 }
5395
5396 if (buffer.empty())
5397 return llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy);
5398
5399 // For GC layouts, emit a skip to the end of the allocation so that we
5400 // have precise information about the entire thing. This isn't useful
5401 // or necessary for the ARC-style layout strings.
5402 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5403 unsigned lastOffsetInWords =
5404 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5405 if (lastOffsetInWords > endOfLastScanInWords) {
5406 skip(lastOffsetInWords - endOfLastScanInWords);
5407 }
5408 }
5409
5410 // Null terminate the string.
5411 buffer.push_back(Elt: 0);
5412
5413 auto *Entry = CGObjC.CreateCStringLiteral(
5414 Name: reinterpret_cast<char *>(buffer.data()), Type: ObjCLabelType::ClassName);
5415 return getConstantGEP(VMContext&: CGM.getLLVMContext(), C: Entry, idx0: 0, idx1: 0);
5416}
5417
5418/// BuildIvarLayout - Builds ivar layout bitmap for the class
5419/// implementation for the __strong or __weak case.
5420/// The layout map displays which words in ivar list must be skipped
5421/// and which must be scanned by GC (see below). String is built of bytes.
5422/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
5423/// of words to skip and right nibble is count of words to scan. So, each
5424/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
5425/// represented by a 0x00 byte which also ends the string.
5426/// 1. when ForStrongLayout is true, following ivars are scanned:
5427/// - id, Class
5428/// - object *
5429/// - __strong anything
5430///
5431/// 2. When ForStrongLayout is false, following ivars are scanned:
5432/// - __weak anything
5433///
5434llvm::Constant *
5435CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5436 CharUnits beginOffset, CharUnits endOffset,
5437 bool ForStrongLayout, bool HasMRCWeakIvars) {
5438 // If this is MRC, and we're either building a strong layout or there
5439 // are no weak ivars, bail out early.
5440 llvm::Type *PtrTy = CGM.Int8PtrTy;
5441 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5442 !CGM.getLangOpts().ObjCAutoRefCount &&
5443 (ForStrongLayout || !HasMRCWeakIvars))
5444 return llvm::Constant::getNullValue(Ty: PtrTy);
5445
5446 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5447 SmallVector<const ObjCIvarDecl *, 32> ivars;
5448
5449 // GC layout strings include the complete object layout, possibly
5450 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5451 // up.
5452 //
5453 // ARC layout strings only include the class's ivars. In non-fragile
5454 // runtimes, that means starting at InstanceStart, rounded up to word
5455 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5456 // starting at the offset of the first ivar, rounded up to word alignment.
5457 //
5458 // MRC weak layout strings follow the ARC style.
5459 CharUnits baseOffset;
5460 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5461 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
5462 IVD = IVD->getNextIvar())
5463 ivars.push_back(Elt: IVD);
5464
5465 if (isNonFragileABI()) {
5466 baseOffset = beginOffset; // InstanceStart
5467 } else if (!ivars.empty()) {
5468 baseOffset =
5469 CharUnits::fromQuantity(Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivars[0]));
5470 } else {
5471 baseOffset = CharUnits::Zero();
5472 }
5473
5474 baseOffset = baseOffset.alignTo(Align: CGM.getPointerAlign());
5475 } else {
5476 CGM.getContext().DeepCollectObjCIvars(OI, leafClass: true, Ivars&: ivars);
5477
5478 baseOffset = CharUnits::Zero();
5479 }
5480
5481 if (ivars.empty())
5482 return llvm::Constant::getNullValue(Ty: PtrTy);
5483
5484 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5485
5486 builder.visitAggregate(begin: ivars.begin(), end: ivars.end(), aggregateOffset: CharUnits::Zero(),
5487 getOffset: [&](const ObjCIvarDecl *ivar) -> CharUnits {
5488 return CharUnits::fromQuantity(
5489 Quantity: ComputeIvarBaseOffset(CGM, OID: OMD, Ivar: ivar));
5490 });
5491
5492 if (!builder.hasBitmapData())
5493 return llvm::Constant::getNullValue(Ty: PtrTy);
5494
5495 llvm::SmallVector<unsigned char, 4> buffer;
5496 llvm::Constant *C = builder.buildBitmap(CGObjC&: *this, buffer);
5497
5498 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5499 printf(format: "\n%s ivar layout for class '%s': ",
5500 ForStrongLayout ? "strong" : "weak",
5501 OMD->getClassInterface()->getName().str().c_str());
5502 builder.dump(buffer);
5503 }
5504 return C;
5505}
5506
5507llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5508 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5509 // FIXME: Avoid std::string in "Sel.getAsString()"
5510 if (!Entry)
5511 Entry =
5512 CreateCStringLiteral(Name: Sel.getAsString(), Type: ObjCLabelType::MethodVarName);
5513 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
5514}
5515
5516// FIXME: Merge into a single cstring creation function.
5517llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5518 return GetMethodVarName(Sel: CGM.getContext().Selectors.getNullarySelector(ID));
5519}
5520
5521llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5522 std::string TypeStr;
5523 CGM.getContext().getObjCEncodingForType(T: Field->getType(), S&: TypeStr, Field);
5524
5525 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5526 if (!Entry)
5527 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
5528 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
5529}
5530
5531llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5532 bool Extended) {
5533 std::string TypeStr =
5534 CGM.getContext().getObjCEncodingForMethodDecl(Decl: D, Extended);
5535
5536 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5537 if (!Entry)
5538 Entry = CreateCStringLiteral(Name: TypeStr, Type: ObjCLabelType::MethodVarType);
5539 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
5540}
5541
5542// FIXME: Merge into a single cstring creation function.
5543llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5544 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5545 if (!Entry)
5546 Entry = CreateCStringLiteral(Name: Ident->getName(), Type: ObjCLabelType::PropertyName);
5547 return getConstantGEP(VMContext, C: Entry, idx0: 0, idx1: 0);
5548}
5549
5550// FIXME: Merge into a single cstring creation function.
5551// FIXME: This Decl should be more precise.
5552llvm::Constant *
5553CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5554 const Decl *Container) {
5555 std::string TypeStr =
5556 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5557 return GetPropertyName(Ident: &CGM.getContext().Idents.get(Name: TypeStr));
5558}
5559
5560void CGObjCMac::FinishModule() {
5561 EmitModuleInfo();
5562
5563 // Emit the dummy bodies for any protocols which were referenced but
5564 // never defined.
5565 for (auto &entry : Protocols) {
5566 llvm::GlobalVariable *global = entry.second;
5567 if (global->hasInitializer())
5568 continue;
5569
5570 ConstantInitBuilder builder(CGM);
5571 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolTy);
5572 values.addNullPointer(ptrTy: ObjCTypes.ProtocolExtensionPtrTy);
5573 values.add(value: GetClassName(RuntimeName: entry.first->getName()));
5574 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListPtrTy);
5575 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
5576 values.addNullPointer(ptrTy: ObjCTypes.MethodDescriptionListPtrTy);
5577 values.finishAndSetAsInitializer(global);
5578 CGM.addCompilerUsedGlobal(GV: global);
5579 }
5580
5581 // Add assembler directives to add lazy undefined symbol references
5582 // for classes which are referenced but not defined. This is
5583 // important for correct linker interaction.
5584 //
5585 // FIXME: It would be nice if we had an LLVM construct for this.
5586 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5587 CGM.getTriple().isOSBinFormatMachO()) {
5588 SmallString<256> Asm;
5589 Asm += CGM.getModule().getModuleInlineAsm();
5590 if (!Asm.empty() && Asm.back() != '\n')
5591 Asm += '\n';
5592
5593 llvm::raw_svector_ostream OS(Asm);
5594 for (const auto *Sym : DefinedSymbols)
5595 OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"
5596 << "\t.globl .objc_class_name_" << Sym->getName() << "\n";
5597 for (const auto *Sym : LazySymbols)
5598 OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";
5599 for (const auto &Category : DefinedCategoryNames)
5600 OS << "\t.objc_category_name_" << Category << "=0\n"
5601 << "\t.globl .objc_category_name_" << Category << "\n";
5602
5603 CGM.getModule().setModuleInlineAsm(OS.str());
5604 }
5605}
5606
5607CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5608 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5609 ObjCEmptyVtableVar(nullptr) {
5610 ObjCABI = 2;
5611}
5612
5613/* *** */
5614
5615ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5616 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
5617 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5618 ASTContext &Ctx = CGM.getContext();
5619 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
5620
5621 ShortTy = cast<llvm::IntegerType>(Val: Types.ConvertType(T: Ctx.ShortTy));
5622 IntTy = CGM.IntTy;
5623 LongTy = cast<llvm::IntegerType>(Val: Types.ConvertType(T: Ctx.LongTy));
5624 Int8PtrTy = CGM.Int8PtrTy;
5625 Int8PtrProgramASTy = llvm::PointerType::get(C&: CGM.getLLVMContext(), AddressSpace: ProgramAS);
5626 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5627
5628 // arm64 targets use "int" ivar offset variables. All others,
5629 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5630 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5631 IvarOffsetVarTy = IntTy;
5632 else
5633 IvarOffsetVarTy = LongTy;
5634
5635 ObjectPtrTy = cast<llvm::PointerType>(Val: Types.ConvertType(T: Ctx.getObjCIdType()));
5636 PtrObjectPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5637 SelectorPtrTy =
5638 cast<llvm::PointerType>(Val: Types.ConvertType(T: Ctx.getObjCSelType()));
5639
5640 // I'm not sure I like this. The implicit coordination is a bit
5641 // gross. We should solve this in a reasonable fashion because this
5642 // is a pretty common task (match some runtime data structure with
5643 // an LLVM data structure).
5644
5645 // FIXME: This is leaked.
5646 // FIXME: Merge with rewriter code?
5647
5648 // struct _objc_super {
5649 // id self;
5650 // Class cls;
5651 // }
5652 RecordDecl *RD = RecordDecl::Create(
5653 C: Ctx, TK: TagTypeKind::Struct, DC: Ctx.getTranslationUnitDecl(), StartLoc: SourceLocation(),
5654 IdLoc: SourceLocation(), Id: &Ctx.Idents.get(Name: "_objc_super"));
5655 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
5656 Id: nullptr, T: Ctx.getObjCIdType(), TInfo: nullptr, BW: nullptr,
5657 Mutable: false, InitStyle: ICIS_NoInit));
5658 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
5659 Id: nullptr, T: Ctx.getObjCClassType(), TInfo: nullptr,
5660 BW: nullptr, Mutable: false, InitStyle: ICIS_NoInit));
5661 RD->completeDefinition();
5662
5663 SuperCTy = Ctx.getTagDeclType(Decl: RD);
5664 SuperPtrCTy = Ctx.getPointerType(T: SuperCTy);
5665
5666 SuperTy = cast<llvm::StructType>(Val: Types.ConvertType(T: SuperCTy));
5667 SuperPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5668
5669 // struct _prop_t {
5670 // char *name;
5671 // char *attributes;
5672 // }
5673 PropertyTy = llvm::StructType::create(Name: "struct._prop_t", elt1: Int8PtrTy, elts: Int8PtrTy);
5674
5675 // struct _prop_list_t {
5676 // uint32_t entsize; // sizeof(struct _prop_t)
5677 // uint32_t count_of_properties;
5678 // struct _prop_t prop_list[count_of_properties];
5679 // }
5680 PropertyListTy = llvm::StructType::create(
5681 Name: "struct._prop_list_t", elt1: IntTy, elts: IntTy, elts: llvm::ArrayType::get(ElementType: PropertyTy, NumElements: 0));
5682 // struct _prop_list_t *
5683 PropertyListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5684
5685 // struct _objc_method {
5686 // SEL _cmd;
5687 // char *method_type;
5688 // char *_imp;
5689 // }
5690 MethodTy = llvm::StructType::create(Name: "struct._objc_method", elt1: SelectorPtrTy,
5691 elts: Int8PtrTy, elts: Int8PtrProgramASTy);
5692
5693 // struct _objc_cache *
5694 CacheTy = llvm::StructType::create(Context&: VMContext, Name: "struct._objc_cache");
5695 CachePtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5696}
5697
5698ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5699 : ObjCCommonTypesHelper(cgm) {
5700 // struct _objc_method_description {
5701 // SEL name;
5702 // char *types;
5703 // }
5704 MethodDescriptionTy = llvm::StructType::create(
5705 Name: "struct._objc_method_description", elt1: SelectorPtrTy, elts: Int8PtrTy);
5706
5707 // struct _objc_method_description_list {
5708 // int count;
5709 // struct _objc_method_description[1];
5710 // }
5711 MethodDescriptionListTy =
5712 llvm::StructType::create(Name: "struct._objc_method_description_list", elt1: IntTy,
5713 elts: llvm::ArrayType::get(ElementType: MethodDescriptionTy, NumElements: 0));
5714
5715 // struct _objc_method_description_list *
5716 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5717
5718 // Protocol description structures
5719
5720 // struct _objc_protocol_extension {
5721 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5722 // struct _objc_method_description_list *optional_instance_methods;
5723 // struct _objc_method_description_list *optional_class_methods;
5724 // struct _objc_property_list *instance_properties;
5725 // const char ** extendedMethodTypes;
5726 // struct _objc_property_list *class_properties;
5727 // }
5728 ProtocolExtensionTy = llvm::StructType::create(
5729 Name: "struct._objc_protocol_extension", elt1: IntTy, elts: MethodDescriptionListPtrTy,
5730 elts: MethodDescriptionListPtrTy, elts: PropertyListPtrTy, elts: Int8PtrPtrTy,
5731 elts: PropertyListPtrTy);
5732
5733 // struct _objc_protocol_extension *
5734 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5735
5736 // Handle construction of Protocol and ProtocolList types
5737
5738 // struct _objc_protocol {
5739 // struct _objc_protocol_extension *isa;
5740 // char *protocol_name;
5741 // struct _objc_protocol **_objc_protocol_list;
5742 // struct _objc_method_description_list *instance_methods;
5743 // struct _objc_method_description_list *class_methods;
5744 // }
5745 ProtocolTy = llvm::StructType::create(
5746 Elements: {ProtocolExtensionPtrTy, Int8PtrTy,
5747 llvm::PointerType::getUnqual(C&: VMContext), MethodDescriptionListPtrTy,
5748 MethodDescriptionListPtrTy},
5749 Name: "struct._objc_protocol");
5750
5751 ProtocolListTy =
5752 llvm::StructType::create(Elements: {llvm::PointerType::getUnqual(C&: VMContext), LongTy,
5753 llvm::ArrayType::get(ElementType: ProtocolTy, NumElements: 0)},
5754 Name: "struct._objc_protocol_list");
5755
5756 // struct _objc_protocol_list *
5757 ProtocolListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5758
5759 ProtocolPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5760
5761 // Class description structures
5762
5763 // struct _objc_ivar {
5764 // char *ivar_name;
5765 // char *ivar_type;
5766 // int ivar_offset;
5767 // }
5768 IvarTy = llvm::StructType::create(Name: "struct._objc_ivar", elt1: Int8PtrTy, elts: Int8PtrTy,
5769 elts: IntTy);
5770
5771 // struct _objc_ivar_list *
5772 IvarListTy = llvm::StructType::create(Context&: VMContext, Name: "struct._objc_ivar_list");
5773 IvarListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5774
5775 // struct _objc_method_list *
5776 MethodListTy =
5777 llvm::StructType::create(Context&: VMContext, Name: "struct._objc_method_list");
5778 MethodListPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5779
5780 // struct _objc_class_extension *
5781 ClassExtensionTy = llvm::StructType::create(
5782 Name: "struct._objc_class_extension", elt1: IntTy, elts: Int8PtrTy, elts: PropertyListPtrTy);
5783 ClassExtensionPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5784
5785 // struct _objc_class {
5786 // Class isa;
5787 // Class super_class;
5788 // char *name;
5789 // long version;
5790 // long info;
5791 // long instance_size;
5792 // struct _objc_ivar_list *ivars;
5793 // struct _objc_method_list *methods;
5794 // struct _objc_cache *cache;
5795 // struct _objc_protocol_list *protocols;
5796 // char *ivar_layout;
5797 // struct _objc_class_ext *ext;
5798 // };
5799 ClassTy = llvm::StructType::create(
5800 Elements: {llvm::PointerType::getUnqual(C&: VMContext),
5801 llvm::PointerType::getUnqual(C&: VMContext), Int8PtrTy, LongTy, LongTy,
5802 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
5803 Int8PtrTy, ClassExtensionPtrTy},
5804 Name: "struct._objc_class");
5805
5806 ClassPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5807
5808 // struct _objc_category {
5809 // char *category_name;
5810 // char *class_name;
5811 // struct _objc_method_list *instance_method;
5812 // struct _objc_method_list *class_method;
5813 // struct _objc_protocol_list *protocols;
5814 // uint32_t size; // sizeof(struct _objc_category)
5815 // struct _objc_property_list *instance_properties;// category's @property
5816 // struct _objc_property_list *class_properties;
5817 // }
5818 CategoryTy = llvm::StructType::create(
5819 Name: "struct._objc_category", elt1: Int8PtrTy, elts: Int8PtrTy, elts: MethodListPtrTy,
5820 elts: MethodListPtrTy, elts: ProtocolListPtrTy, elts: IntTy, elts: PropertyListPtrTy,
5821 elts: PropertyListPtrTy);
5822
5823 // Global metadata structures
5824
5825 // struct _objc_symtab {
5826 // long sel_ref_cnt;
5827 // SEL *refs;
5828 // short cls_def_cnt;
5829 // short cat_def_cnt;
5830 // char *defs[cls_def_cnt + cat_def_cnt];
5831 // }
5832 SymtabTy = llvm::StructType::create(Name: "struct._objc_symtab", elt1: LongTy,
5833 elts: SelectorPtrTy, elts: ShortTy, elts: ShortTy,
5834 elts: llvm::ArrayType::get(ElementType: Int8PtrTy, NumElements: 0));
5835 SymtabPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5836
5837 // struct _objc_module {
5838 // long version;
5839 // long size; // sizeof(struct _objc_module)
5840 // char *name;
5841 // struct _objc_symtab* symtab;
5842 // }
5843 ModuleTy = llvm::StructType::create(Name: "struct._objc_module", elt1: LongTy, elts: LongTy,
5844 elts: Int8PtrTy, elts: SymtabPtrTy);
5845
5846 // FIXME: This is the size of the setjmp buffer and should be target
5847 // specific. 18 is what's used on 32-bit X86.
5848 uint64_t SetJmpBufferSize = 18;
5849
5850 // Exceptions
5851 llvm::Type *StackPtrTy = llvm::ArrayType::get(ElementType: CGM.Int8PtrTy, NumElements: 4);
5852
5853 ExceptionDataTy = llvm::StructType::create(
5854 Name: "struct._objc_exception_data",
5855 elt1: llvm::ArrayType::get(ElementType: CGM.Int32Ty, NumElements: SetJmpBufferSize), elts: StackPtrTy);
5856}
5857
5858ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
5859 CodeGen::CodeGenModule &cgm)
5860 : ObjCCommonTypesHelper(cgm) {
5861 // struct _method_list_t {
5862 // uint32_t entsize; // sizeof(struct _objc_method)
5863 // uint32_t method_count;
5864 // struct _objc_method method_list[method_count];
5865 // }
5866 MethodListnfABITy =
5867 llvm::StructType::create(Name: "struct.__method_list_t", elt1: IntTy, elts: IntTy,
5868 elts: llvm::ArrayType::get(ElementType: MethodTy, NumElements: 0));
5869 // struct method_list_t *
5870 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5871
5872 // struct _protocol_t {
5873 // id isa; // NULL
5874 // const char * const protocol_name;
5875 // const struct _protocol_list_t * protocol_list; // super protocols
5876 // const struct method_list_t * const instance_methods;
5877 // const struct method_list_t * const class_methods;
5878 // const struct method_list_t *optionalInstanceMethods;
5879 // const struct method_list_t *optionalClassMethods;
5880 // const struct _prop_list_t * properties;
5881 // const uint32_t size; // sizeof(struct _protocol_t)
5882 // const uint32_t flags; // = 0
5883 // const char ** extendedMethodTypes;
5884 // const char *demangledName;
5885 // const struct _prop_list_t * class_properties;
5886 // }
5887
5888 ProtocolnfABITy = llvm::StructType::create(
5889 Name: "struct._protocol_t", elt1: ObjectPtrTy, elts: Int8PtrTy,
5890 elts: llvm::PointerType::getUnqual(C&: VMContext), elts: MethodListnfABIPtrTy,
5891 elts: MethodListnfABIPtrTy, elts: MethodListnfABIPtrTy, elts: MethodListnfABIPtrTy,
5892 elts: PropertyListPtrTy, elts: IntTy, elts: IntTy, elts: Int8PtrPtrTy, elts: Int8PtrTy,
5893 elts: PropertyListPtrTy);
5894
5895 // struct _protocol_t*
5896 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5897
5898 // struct _protocol_list_t {
5899 // long protocol_count; // Note, this is 32/64 bit
5900 // struct _protocol_t *[protocol_count];
5901 // }
5902 ProtocolListnfABITy = llvm::StructType::create(
5903 Elements: {LongTy, llvm::ArrayType::get(ElementType: ProtocolnfABIPtrTy, NumElements: 0)},
5904 Name: "struct._objc_protocol_list");
5905
5906 // struct _objc_protocol_list*
5907 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5908
5909 // struct _ivar_t {
5910 // unsigned [long] int *offset; // pointer to ivar offset location
5911 // char *name;
5912 // char *type;
5913 // uint32_t alignment;
5914 // uint32_t size;
5915 // }
5916 IvarnfABITy = llvm::StructType::create(
5917 Name: "struct._ivar_t", elt1: llvm::PointerType::getUnqual(C&: VMContext), elts: Int8PtrTy,
5918 elts: Int8PtrTy, elts: IntTy, elts: IntTy);
5919
5920 // struct _ivar_list_t {
5921 // uint32 entsize; // sizeof(struct _ivar_t)
5922 // uint32 count;
5923 // struct _iver_t list[count];
5924 // }
5925 IvarListnfABITy =
5926 llvm::StructType::create(Name: "struct._ivar_list_t", elt1: IntTy, elts: IntTy,
5927 elts: llvm::ArrayType::get(ElementType: IvarnfABITy, NumElements: 0));
5928
5929 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5930
5931 // struct _class_ro_t {
5932 // uint32_t const flags;
5933 // uint32_t const instanceStart;
5934 // uint32_t const instanceSize;
5935 // uint32_t const reserved; // only when building for 64bit targets
5936 // const uint8_t * const ivarLayout;
5937 // const char *const name;
5938 // const struct _method_list_t * const baseMethods;
5939 // const struct _objc_protocol_list *const baseProtocols;
5940 // const struct _ivar_list_t *const ivars;
5941 // const uint8_t * const weakIvarLayout;
5942 // const struct _prop_list_t * const properties;
5943 // }
5944
5945 // FIXME. Add 'reserved' field in 64bit abi mode!
5946 ClassRonfABITy = llvm::StructType::create(
5947 Name: "struct._class_ro_t", elt1: IntTy, elts: IntTy, elts: IntTy, elts: Int8PtrTy, elts: Int8PtrTy,
5948 elts: MethodListnfABIPtrTy, elts: ProtocolListnfABIPtrTy, elts: IvarListnfABIPtrTy,
5949 elts: Int8PtrTy, elts: PropertyListPtrTy);
5950
5951 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5952 ImpnfABITy = CGM.UnqualPtrTy;
5953
5954 // struct _class_t {
5955 // struct _class_t *isa;
5956 // struct _class_t * const superclass;
5957 // void *cache;
5958 // IMP *vtable;
5959 // struct class_ro_t *ro;
5960 // }
5961
5962 ClassnfABITy = llvm::StructType::create(
5963 Elements: {llvm::PointerType::getUnqual(C&: VMContext),
5964 llvm::PointerType::getUnqual(C&: VMContext), CachePtrTy,
5965 llvm::PointerType::getUnqual(C&: VMContext),
5966 llvm::PointerType::getUnqual(C&: VMContext)},
5967 Name: "struct._class_t");
5968
5969 // LLVM for struct _class_t *
5970 ClassnfABIPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
5971
5972 // struct _category_t {
5973 // const char * const name;
5974 // struct _class_t *const cls;
5975 // const struct _method_list_t * const instance_methods;
5976 // const struct _method_list_t * const class_methods;
5977 // const struct _protocol_list_t * const protocols;
5978 // const struct _prop_list_t * const properties;
5979 // const struct _prop_list_t * const class_properties;
5980 // const uint32_t size;
5981 // }
5982 CategorynfABITy = llvm::StructType::create(
5983 Name: "struct._category_t", elt1: Int8PtrTy, elts: ClassnfABIPtrTy, elts: MethodListnfABIPtrTy,
5984 elts: MethodListnfABIPtrTy, elts: ProtocolListnfABIPtrTy, elts: PropertyListPtrTy,
5985 elts: PropertyListPtrTy, elts: IntTy);
5986
5987 // New types for nonfragile abi messaging.
5988 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5989 ASTContext &Ctx = CGM.getContext();
5990
5991 // MessageRefTy - LLVM for:
5992 // struct _message_ref_t {
5993 // IMP messenger;
5994 // SEL name;
5995 // };
5996
5997 // First the clang type for struct _message_ref_t
5998 RecordDecl *RD = RecordDecl::Create(
5999 C: Ctx, TK: TagTypeKind::Struct, DC: Ctx.getTranslationUnitDecl(), StartLoc: SourceLocation(),
6000 IdLoc: SourceLocation(), Id: &Ctx.Idents.get(Name: "_message_ref_t"));
6001 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
6002 Id: nullptr, T: Ctx.VoidPtrTy, TInfo: nullptr, BW: nullptr, Mutable: false,
6003 InitStyle: ICIS_NoInit));
6004 RD->addDecl(D: FieldDecl::Create(C: Ctx, DC: RD, StartLoc: SourceLocation(), IdLoc: SourceLocation(),
6005 Id: nullptr, T: Ctx.getObjCSelType(), TInfo: nullptr, BW: nullptr,
6006 Mutable: false, InitStyle: ICIS_NoInit));
6007 RD->completeDefinition();
6008
6009 MessageRefCTy = Ctx.getTagDeclType(Decl: RD);
6010 MessageRefCPtrTy = Ctx.getPointerType(T: MessageRefCTy);
6011 MessageRefTy = cast<llvm::StructType>(Val: Types.ConvertType(T: MessageRefCTy));
6012
6013 // MessageRefPtrTy - LLVM for struct _message_ref_t*
6014 MessageRefPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6015
6016 // SuperMessageRefTy - LLVM for:
6017 // struct _super_message_ref_t {
6018 // SUPER_IMP messenger;
6019 // SEL name;
6020 // };
6021 SuperMessageRefTy = llvm::StructType::create(Name: "struct._super_message_ref_t",
6022 elt1: ImpnfABITy, elts: SelectorPtrTy);
6023
6024 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
6025 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6026
6027 // struct objc_typeinfo {
6028 // const void** vtable; // objc_ehtype_vtable + 2
6029 // const char* name; // c++ typeinfo string
6030 // Class cls;
6031 // };
6032 EHTypeTy = llvm::StructType::create(Name: "struct._objc_typeinfo",
6033 elt1: llvm::PointerType::getUnqual(C&: VMContext),
6034 elts: Int8PtrTy, elts: ClassnfABIPtrTy);
6035 EHTypePtrTy = llvm::PointerType::getUnqual(C&: VMContext);
6036}
6037
6038llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
6039 FinishNonFragileABIModule();
6040
6041 return nullptr;
6042}
6043
6044void CGObjCNonFragileABIMac::AddModuleClassList(
6045 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
6046 StringRef SectionName) {
6047 unsigned NumClasses = Container.size();
6048
6049 if (!NumClasses)
6050 return;
6051
6052 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
6053 for (unsigned i = 0; i < NumClasses; i++)
6054 Symbols[i] = Container[i];
6055
6056 llvm::Constant *Init = llvm::ConstantArray::get(
6057 T: llvm::ArrayType::get(ElementType: ObjCTypes.Int8PtrTy, NumElements: Symbols.size()), V: Symbols);
6058
6059 // Section name is obtained by calling GetSectionName, which returns
6060 // sections in the __DATA segment on MachO.
6061 assert((!CGM.getTriple().isOSBinFormatMachO() ||
6062 SectionName.starts_with("__DATA")) &&
6063 "SectionName expected to start with __DATA on MachO");
6064 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
6065 CGM.getModule(), Init->getType(), false,
6066 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
6067 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Ty: Init->getType()));
6068 GV->setSection(SectionName);
6069 CGM.addCompilerUsedGlobal(GV);
6070}
6071
6072void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
6073 // nonfragile abi has no module definition.
6074
6075 // Build list of all implemented class addresses in array
6076 // L_OBJC_LABEL_CLASS_$.
6077
6078 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
6079 i++) {
6080 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6081 assert(ID);
6082 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6083 // We are implementing a weak imported interface. Give it external linkage
6084 if (ID->isWeakImported() && !IMP->isWeakImported()) {
6085 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6086 DefinedMetaClasses[i]->setLinkage(
6087 llvm::GlobalVariable::ExternalLinkage);
6088 }
6089 }
6090
6091 AddModuleClassList(
6092 Container: DefinedClasses, SymbolName: "OBJC_LABEL_CLASS_$",
6093 SectionName: GetSectionName(Section: "__objc_classlist", MachOAttributes: "regular,no_dead_strip"));
6094
6095 AddModuleClassList(
6096 Container: DefinedNonLazyClasses, SymbolName: "OBJC_LABEL_NONLAZY_CLASS_$",
6097 SectionName: GetSectionName(Section: "__objc_nlclslist", MachOAttributes: "regular,no_dead_strip"));
6098
6099 // Build list of all implemented category addresses in array
6100 // L_OBJC_LABEL_CATEGORY_$.
6101 AddModuleClassList(Container: DefinedCategories, SymbolName: "OBJC_LABEL_CATEGORY_$",
6102 SectionName: GetSectionName(Section: "__objc_catlist", MachOAttributes: "regular,no_dead_strip"));
6103 AddModuleClassList(
6104 Container: DefinedStubCategories, SymbolName: "OBJC_LABEL_STUB_CATEGORY_$",
6105 SectionName: GetSectionName(Section: "__objc_catlist2", MachOAttributes: "regular,no_dead_strip"));
6106 AddModuleClassList(
6107 Container: DefinedNonLazyCategories, SymbolName: "OBJC_LABEL_NONLAZY_CATEGORY_$",
6108 SectionName: GetSectionName(Section: "__objc_nlcatlist", MachOAttributes: "regular,no_dead_strip"));
6109
6110 EmitImageInfo();
6111}
6112
6113/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
6114/// VTableDispatchMethods; false otherwise. What this means is that
6115/// except for the 19 selectors in the list, we generate 32bit-style
6116/// message dispatch call for all the rest.
6117bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6118 // At various points we've experimented with using vtable-based
6119 // dispatch for all methods.
6120 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6121 case CodeGenOptions::Legacy:
6122 return false;
6123 case CodeGenOptions::NonLegacy:
6124 return true;
6125 case CodeGenOptions::Mixed:
6126 break;
6127 }
6128
6129 // If so, see whether this selector is in the white-list of things which must
6130 // use the new dispatch convention. We lazily build a dense set for this.
6131 if (VTableDispatchMethods.empty()) {
6132 VTableDispatchMethods.insert(V: GetNullarySelector(name: "alloc"));
6133 VTableDispatchMethods.insert(V: GetNullarySelector(name: "class"));
6134 VTableDispatchMethods.insert(V: GetNullarySelector(name: "self"));
6135 VTableDispatchMethods.insert(V: GetNullarySelector(name: "isFlipped"));
6136 VTableDispatchMethods.insert(V: GetNullarySelector(name: "length"));
6137 VTableDispatchMethods.insert(V: GetNullarySelector(name: "count"));
6138
6139 // These are vtable-based if GC is disabled.
6140 // Optimistically use vtable dispatch for hybrid compiles.
6141 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6142 VTableDispatchMethods.insert(V: GetNullarySelector(name: "retain"));
6143 VTableDispatchMethods.insert(V: GetNullarySelector(name: "release"));
6144 VTableDispatchMethods.insert(V: GetNullarySelector(name: "autorelease"));
6145 }
6146
6147 VTableDispatchMethods.insert(V: GetUnarySelector(name: "allocWithZone"));
6148 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isKindOfClass"));
6149 VTableDispatchMethods.insert(V: GetUnarySelector(name: "respondsToSelector"));
6150 VTableDispatchMethods.insert(V: GetUnarySelector(name: "objectForKey"));
6151 VTableDispatchMethods.insert(V: GetUnarySelector(name: "objectAtIndex"));
6152 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isEqualToString"));
6153 VTableDispatchMethods.insert(V: GetUnarySelector(name: "isEqual"));
6154
6155 // These are vtable-based if GC is enabled.
6156 // Optimistically use vtable dispatch for hybrid compiles.
6157 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6158 VTableDispatchMethods.insert(V: GetNullarySelector(name: "hash"));
6159 VTableDispatchMethods.insert(V: GetUnarySelector(name: "addObject"));
6160
6161 // "countByEnumeratingWithState:objects:count"
6162 const IdentifierInfo *KeyIdents[] = {
6163 &CGM.getContext().Idents.get(Name: "countByEnumeratingWithState"),
6164 &CGM.getContext().Idents.get(Name: "objects"),
6165 &CGM.getContext().Idents.get(Name: "count")};
6166 VTableDispatchMethods.insert(
6167 V: CGM.getContext().Selectors.getSelector(NumArgs: 3, IIV: KeyIdents));
6168 }
6169 }
6170
6171 return VTableDispatchMethods.count(V: Sel);
6172}
6173
6174/// BuildClassRoTInitializer - generate meta-data for:
6175/// struct _class_ro_t {
6176/// uint32_t const flags;
6177/// uint32_t const instanceStart;
6178/// uint32_t const instanceSize;
6179/// uint32_t const reserved; // only when building for 64bit targets
6180/// const uint8_t * const ivarLayout;
6181/// const char *const name;
6182/// const struct _method_list_t * const baseMethods;
6183/// const struct _protocol_list_t *const baseProtocols;
6184/// const struct _ivar_list_t *const ivars;
6185/// const uint8_t * const weakIvarLayout;
6186/// const struct _prop_list_t * const properties;
6187/// }
6188///
6189llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6190 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
6191 const ObjCImplementationDecl *ID) {
6192 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
6193
6194 CharUnits beginInstance = CharUnits::fromQuantity(Quantity: InstanceStart);
6195 CharUnits endInstance = CharUnits::fromQuantity(Quantity: InstanceSize);
6196
6197 bool hasMRCWeak = false;
6198 if (CGM.getLangOpts().ObjCAutoRefCount)
6199 flags |= NonFragileABI_Class_CompiledByARC;
6200 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6201 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6202
6203 ConstantInitBuilder builder(CGM);
6204 auto values = builder.beginStruct(structTy: ObjCTypes.ClassRonfABITy);
6205
6206 values.addInt(intTy: ObjCTypes.IntTy, value: flags);
6207 values.addInt(intTy: ObjCTypes.IntTy, value: InstanceStart);
6208 values.addInt(intTy: ObjCTypes.IntTy, value: InstanceSize);
6209 values.add(value: (flags & NonFragileABI_Class_Meta)
6210 ? GetIvarLayoutName(Ident: nullptr, ObjCTypes)
6211 : BuildStrongIvarLayout(OI: ID, beginOffset: beginInstance, endOffset: endInstance));
6212 values.add(value: GetClassName(RuntimeName: ID->getObjCRuntimeNameAsString()));
6213
6214 // const struct _method_list_t * const baseMethods;
6215 SmallVector<const ObjCMethodDecl *, 16> methods;
6216 if (flags & NonFragileABI_Class_Meta) {
6217 for (const auto *MD : ID->class_methods())
6218 if (!MD->isDirectMethod())
6219 methods.push_back(Elt: MD);
6220 } else {
6221 for (const auto *MD : ID->instance_methods())
6222 if (!MD->isDirectMethod())
6223 methods.push_back(Elt: MD);
6224 }
6225
6226 values.add(value: emitMethodList(Name: ID->getObjCRuntimeNameAsString(),
6227 MLT: (flags & NonFragileABI_Class_Meta)
6228 ? MethodListType::ClassMethods
6229 : MethodListType::InstanceMethods,
6230 Methods: methods));
6231
6232 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6233 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
6234 values.add(value: EmitProtocolList(Name: "_OBJC_CLASS_PROTOCOLS_$_" +
6235 OID->getObjCRuntimeNameAsString(),
6236 begin: OID->all_referenced_protocol_begin(),
6237 end: OID->all_referenced_protocol_end()));
6238
6239 if (flags & NonFragileABI_Class_Meta) {
6240 values.addNullPointer(ptrTy: ObjCTypes.IvarListnfABIPtrTy);
6241 values.add(value: GetIvarLayoutName(Ident: nullptr, ObjCTypes));
6242 values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" +
6243 ID->getObjCRuntimeNameAsString(),
6244 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: true));
6245 } else {
6246 values.add(value: EmitIvarList(ID));
6247 values.add(value: BuildWeakIvarLayout(OI: ID, beginOffset: beginInstance, endOffset: endInstance, hasMRCWeakIvars: hasMRCWeak));
6248 values.add(value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" +
6249 ID->getObjCRuntimeNameAsString(),
6250 Container: ID, OCD: ID->getClassInterface(), ObjCTypes, IsClassProperty: false));
6251 }
6252
6253 llvm::SmallString<64> roLabel;
6254 llvm::raw_svector_ostream(roLabel)
6255 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_"
6256 : "_OBJC_CLASS_RO_$_")
6257 << ClassName;
6258
6259 return finishAndCreateGlobal(Builder&: values, Name: roLabel, CGM);
6260}
6261
6262/// Build the metaclass object for a class.
6263///
6264/// struct _class_t {
6265/// struct _class_t *isa;
6266/// struct _class_t * const superclass;
6267/// void *cache;
6268/// IMP *vtable;
6269/// struct class_ro_t *ro;
6270/// }
6271///
6272llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
6273 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
6274 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
6275 bool HiddenVisibility) {
6276 ConstantInitBuilder builder(CGM);
6277 auto values = builder.beginStruct(structTy: ObjCTypes.ClassnfABITy);
6278 values.add(value: IsAGV);
6279 if (SuperClassGV) {
6280 values.add(value: SuperClassGV);
6281 } else {
6282 values.addNullPointer(ptrTy: ObjCTypes.ClassnfABIPtrTy);
6283 }
6284 values.add(value: ObjCEmptyCacheVar);
6285 values.add(value: ObjCEmptyVtableVar);
6286 values.add(value: ClassRoGV);
6287
6288 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
6289 Val: GetClassGlobal(ID: CI, isMetaclass, isForDefinition: ForDefinition));
6290 values.finishAndSetAsInitializer(global: GV);
6291
6292 if (CGM.getTriple().isOSBinFormatMachO())
6293 GV->setSection("__DATA, __objc_data");
6294 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.ClassnfABITy));
6295 if (!CGM.getTriple().isOSBinFormatCOFF())
6296 if (HiddenVisibility)
6297 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6298 return GV;
6299}
6300
6301bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
6302 const ObjCImplDecl *OD) const {
6303 return OD->getClassMethod(Sel: GetNullarySelector(name: "load")) != nullptr ||
6304 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
6305 OD->hasAttr<ObjCNonLazyClassAttr>();
6306}
6307
6308void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6309 uint32_t &InstanceStart,
6310 uint32_t &InstanceSize) {
6311 const ASTRecordLayout &RL =
6312 CGM.getContext().getASTObjCInterfaceLayout(D: OID->getClassInterface());
6313
6314 // InstanceSize is really instance end.
6315 InstanceSize = RL.getDataSize().getQuantity();
6316
6317 // If there are no fields, the start is the same as the end.
6318 if (!RL.getFieldCount())
6319 InstanceStart = InstanceSize;
6320 else
6321 InstanceStart = RL.getFieldOffset(FieldNo: 0) / CGM.getContext().getCharWidth();
6322}
6323
6324static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6325 StringRef Name) {
6326 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6327 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6328 DeclContext *DC = TranslationUnitDecl::castToDeclContext(D: TUDecl);
6329
6330 const VarDecl *VD = nullptr;
6331 for (const auto *Result : DC->lookup(Name: &II))
6332 if ((VD = dyn_cast<VarDecl>(Val: Result)))
6333 break;
6334
6335 if (!VD)
6336 return llvm::GlobalValue::DLLImportStorageClass;
6337 if (VD->hasAttr<DLLExportAttr>())
6338 return llvm::GlobalValue::DLLExportStorageClass;
6339 if (VD->hasAttr<DLLImportAttr>())
6340 return llvm::GlobalValue::DLLImportStorageClass;
6341 return llvm::GlobalValue::DefaultStorageClass;
6342}
6343
6344void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6345 if (!ObjCEmptyCacheVar) {
6346 ObjCEmptyCacheVar = new llvm::GlobalVariable(
6347 CGM.getModule(), ObjCTypes.CacheTy, false,
6348 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");
6349 if (CGM.getTriple().isOSBinFormatCOFF())
6350 ObjCEmptyCacheVar->setDLLStorageClass(
6351 getStorage(CGM, Name: "_objc_empty_cache"));
6352
6353 // Only OS X with deployment version <10.9 use the empty vtable symbol
6354 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6355 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(Major: 10, Minor: 9))
6356 ObjCEmptyVtableVar = new llvm::GlobalVariable(
6357 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6358 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");
6359 else
6360 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(T: CGM.UnqualPtrTy);
6361 }
6362
6363 // FIXME: Is this correct (that meta class size is never computed)?
6364 uint32_t InstanceStart =
6365 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ClassnfABITy);
6366 uint32_t InstanceSize = InstanceStart;
6367 uint32_t flags = NonFragileABI_Class_Meta;
6368
6369 llvm::Constant *SuperClassGV, *IsAGV;
6370
6371 const auto *CI = ID->getClassInterface();
6372 assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
6373
6374 // Build the flags for the metaclass.
6375 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
6376 ? !CI->hasAttr<DLLExportAttr>()
6377 : CI->getVisibility() == HiddenVisibility;
6378 if (classIsHidden)
6379 flags |= NonFragileABI_Class_Hidden;
6380
6381 // FIXME: why is this flag set on the metaclass?
6382 // ObjC metaclasses have no fields and don't really get constructed.
6383 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6384 flags |= NonFragileABI_Class_HasCXXStructors;
6385 if (!ID->hasNonZeroConstructors())
6386 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6387 }
6388
6389 if (!CI->getSuperClass()) {
6390 // class is root
6391 flags |= NonFragileABI_Class_Root;
6392
6393 SuperClassGV = GetClassGlobal(ID: CI, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition);
6394 IsAGV = GetClassGlobal(ID: CI, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
6395 } else {
6396 // Has a root. Current class is not a root.
6397 const ObjCInterfaceDecl *Root = ID->getClassInterface();
6398 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6399 Root = Super;
6400
6401 const auto *Super = CI->getSuperClass();
6402 IsAGV = GetClassGlobal(ID: Root, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
6403 SuperClassGV = GetClassGlobal(ID: Super, /*metaclass*/ isMetaclass: true, isForDefinition: NotForDefinition);
6404 }
6405
6406 llvm::GlobalVariable *CLASS_RO_GV =
6407 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6408
6409 llvm::GlobalVariable *MetaTClass = BuildClassObject(
6410 CI, /*metaclass*/ isMetaclass: true, IsAGV, SuperClassGV, ClassRoGV: CLASS_RO_GV, HiddenVisibility: classIsHidden);
6411 CGM.setGVProperties(GV: MetaTClass, D: CI);
6412 DefinedMetaClasses.push_back(x: MetaTClass);
6413
6414 // Metadata for the class
6415 flags = 0;
6416 if (classIsHidden)
6417 flags |= NonFragileABI_Class_Hidden;
6418
6419 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6420 flags |= NonFragileABI_Class_HasCXXStructors;
6421
6422 // Set a flag to enable a runtime optimization when a class has
6423 // fields that require destruction but which don't require
6424 // anything except zero-initialization during construction. This
6425 // is most notably true of __strong and __weak types, but you can
6426 // also imagine there being C++ types with non-trivial default
6427 // constructors that merely set all fields to null.
6428 if (!ID->hasNonZeroConstructors())
6429 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6430 }
6431
6432 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: CI))
6433 flags |= NonFragileABI_Class_Exception;
6434
6435 if (!CI->getSuperClass()) {
6436 flags |= NonFragileABI_Class_Root;
6437 SuperClassGV = nullptr;
6438 } else {
6439 // Has a root. Current class is not a root.
6440 const auto *Super = CI->getSuperClass();
6441 SuperClassGV = GetClassGlobal(ID: Super, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition);
6442 }
6443
6444 GetClassSizeInfo(OID: ID, InstanceStart, InstanceSize);
6445 CLASS_RO_GV =
6446 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6447
6448 llvm::GlobalVariable *ClassMD =
6449 BuildClassObject(CI, /*metaclass*/ isMetaclass: false, IsAGV: MetaTClass, SuperClassGV,
6450 ClassRoGV: CLASS_RO_GV, HiddenVisibility: classIsHidden);
6451 CGM.setGVProperties(GV: ClassMD, D: CI);
6452 DefinedClasses.push_back(Elt: ClassMD);
6453 ImplementedClasses.push_back(Elt: CI);
6454
6455 // Determine if this class is also "non-lazy".
6456 if (ImplementationIsNonLazy(OD: ID))
6457 DefinedNonLazyClasses.push_back(Elt: ClassMD);
6458
6459 // Force the definition of the EHType if necessary.
6460 if (flags & NonFragileABI_Class_Exception)
6461 (void)GetInterfaceEHType(ID: CI, IsForDefinition: ForDefinition);
6462 // Make sure method definition entries are all clear for next implementation.
6463 MethodDefinitions.clear();
6464}
6465
6466/// GenerateProtocolRef - This routine is called to generate code for
6467/// a protocol reference expression; as in:
6468/// @code
6469/// @protocol(Proto1);
6470/// @endcode
6471/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
6472/// which will hold address of the protocol meta-data.
6473///
6474llvm::Value *
6475CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6476 const ObjCProtocolDecl *PD) {
6477
6478 // This routine is called for @protocol only. So, we must build definition
6479 // of protocol's meta-data (not a reference to it!)
6480 assert(!PD->isNonRuntimeProtocol() &&
6481 "attempting to get a protocol ref to a static protocol.");
6482 llvm::Constant *Init = GetOrEmitProtocol(PD);
6483
6484 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_");
6485 ProtocolName += PD->getObjCRuntimeNameAsString();
6486
6487 CharUnits Align = CGF.getPointerAlign();
6488
6489 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(Name: ProtocolName);
6490 if (PTGV)
6491 return CGF.Builder.CreateAlignedLoad(Ty: PTGV->getValueType(), Addr: PTGV, Align);
6492 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6493 llvm::GlobalValue::WeakAnyLinkage, Init,
6494 ProtocolName);
6495 PTGV->setSection(
6496 GetSectionName(Section: "__objc_protorefs", MachOAttributes: "coalesced,no_dead_strip"));
6497 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6498 PTGV->setAlignment(Align.getAsAlign());
6499 if (!CGM.getTriple().isOSBinFormatMachO())
6500 PTGV->setComdat(CGM.getModule().getOrInsertComdat(Name: ProtocolName));
6501 CGM.addUsedGlobal(GV: PTGV);
6502 return CGF.Builder.CreateAlignedLoad(Ty: PTGV->getValueType(), Addr: PTGV, Align);
6503}
6504
6505/// GenerateCategory - Build metadata for a category implementation.
6506/// struct _category_t {
6507/// const char * const name;
6508/// struct _class_t *const cls;
6509/// const struct _method_list_t * const instance_methods;
6510/// const struct _method_list_t * const class_methods;
6511/// const struct _protocol_list_t * const protocols;
6512/// const struct _prop_list_t * const properties;
6513/// const struct _prop_list_t * const class_properties;
6514/// const uint32_t size;
6515/// }
6516///
6517void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6518 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6519 const char *Prefix = "_OBJC_$_CATEGORY_";
6520
6521 llvm::SmallString<64> ExtCatName(Prefix);
6522 ExtCatName += Interface->getObjCRuntimeNameAsString();
6523 ExtCatName += "_$_";
6524 ExtCatName += OCD->getNameAsString();
6525
6526 ConstantInitBuilder builder(CGM);
6527 auto values = builder.beginStruct(structTy: ObjCTypes.CategorynfABITy);
6528 values.add(value: GetClassName(RuntimeName: OCD->getIdentifier()->getName()));
6529 // meta-class entry symbol
6530 values.add(value: GetClassGlobal(ID: Interface, /*metaclass*/ isMetaclass: false, isForDefinition: NotForDefinition));
6531 std::string listName =
6532 (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
6533
6534 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
6535 SmallVector<const ObjCMethodDecl *, 8> classMethods;
6536 for (const auto *MD : OCD->methods()) {
6537 if (MD->isDirectMethod())
6538 continue;
6539 if (MD->isInstanceMethod()) {
6540 instanceMethods.push_back(Elt: MD);
6541 } else {
6542 classMethods.push_back(Elt: MD);
6543 }
6544 }
6545
6546 auto instanceMethodList = emitMethodList(
6547 Name: listName, MLT: MethodListType::CategoryInstanceMethods, Methods: instanceMethods);
6548 auto classMethodList = emitMethodList(
6549 Name: listName, MLT: MethodListType::CategoryClassMethods, Methods: classMethods);
6550 values.add(value: instanceMethodList);
6551 values.add(value: classMethodList);
6552 // Keep track of whether we have actual metadata to emit.
6553 bool isEmptyCategory =
6554 instanceMethodList->isNullValue() && classMethodList->isNullValue();
6555
6556 const ObjCCategoryDecl *Category =
6557 Interface->FindCategoryDeclaration(CategoryId: OCD->getIdentifier());
6558 if (Category) {
6559 SmallString<256> ExtName;
6560 llvm::raw_svector_ostream(ExtName)
6561 << Interface->getObjCRuntimeNameAsString() << "_$_" << OCD->getName();
6562 auto protocolList =
6563 EmitProtocolList(Name: "_OBJC_CATEGORY_PROTOCOLS_$_" +
6564 Interface->getObjCRuntimeNameAsString() + "_$_" +
6565 Category->getName(),
6566 begin: Category->protocol_begin(), end: Category->protocol_end());
6567 auto propertyList = EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + ExtName.str(),
6568 Container: OCD, OCD: Category, ObjCTypes, IsClassProperty: false);
6569 auto classPropertyList =
6570 EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), Container: OCD,
6571 OCD: Category, ObjCTypes, IsClassProperty: true);
6572 values.add(value: protocolList);
6573 values.add(value: propertyList);
6574 values.add(value: classPropertyList);
6575 isEmptyCategory &= protocolList->isNullValue() &&
6576 propertyList->isNullValue() &&
6577 classPropertyList->isNullValue();
6578 } else {
6579 values.addNullPointer(ptrTy: ObjCTypes.ProtocolListnfABIPtrTy);
6580 values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
6581 values.addNullPointer(ptrTy: ObjCTypes.PropertyListPtrTy);
6582 }
6583
6584 if (isEmptyCategory) {
6585 // Empty category, don't emit any metadata.
6586 values.abandon();
6587 MethodDefinitions.clear();
6588 return;
6589 }
6590
6591 unsigned Size =
6592 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.CategorynfABITy);
6593 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
6594
6595 llvm::GlobalVariable *GCATV =
6596 finishAndCreateGlobal(Builder&: values, Name: ExtCatName.str(), CGM);
6597 CGM.addCompilerUsedGlobal(GV: GCATV);
6598 if (Interface->hasAttr<ObjCClassStubAttr>())
6599 DefinedStubCategories.push_back(Elt: GCATV);
6600 else
6601 DefinedCategories.push_back(Elt: GCATV);
6602
6603 // Determine if this category is also "non-lazy".
6604 if (ImplementationIsNonLazy(OD: OCD))
6605 DefinedNonLazyCategories.push_back(Elt: GCATV);
6606 // method definition entries must be clear for next implementation.
6607 MethodDefinitions.clear();
6608}
6609
6610/// emitMethodConstant - Return a struct objc_method constant. If
6611/// forProtocol is true, the implementation will be null; otherwise,
6612/// the method must have a definition registered with the runtime.
6613///
6614/// struct _objc_method {
6615/// SEL _cmd;
6616/// char *method_type;
6617/// char *_imp;
6618/// }
6619void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
6620 const ObjCMethodDecl *MD,
6621 bool forProtocol) {
6622 auto method = builder.beginStruct(ty: ObjCTypes.MethodTy);
6623 method.add(value: GetMethodVarName(Sel: MD->getSelector()));
6624 method.add(value: GetMethodVarType(D: MD));
6625
6626 if (forProtocol) {
6627 // Protocol methods have no implementation. So, this entry is always NULL.
6628 method.addNullPointer(ptrTy: ObjCTypes.Int8PtrProgramASTy);
6629 } else {
6630 llvm::Function *fn = GetMethodDefinition(MD);
6631 assert(fn && "no definition for method?");
6632 method.add(value: fn);
6633 }
6634
6635 method.finishAndAddTo(parent&: builder);
6636}
6637
6638/// Build meta-data for method declarations.
6639///
6640/// struct _method_list_t {
6641/// uint32_t entsize; // sizeof(struct _objc_method)
6642/// uint32_t method_count;
6643/// struct _objc_method method_list[method_count];
6644/// }
6645///
6646llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
6647 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
6648 // Return null for empty list.
6649 if (methods.empty())
6650 return llvm::Constant::getNullValue(Ty: ObjCTypes.MethodListnfABIPtrTy);
6651
6652 StringRef prefix;
6653 bool forProtocol;
6654 switch (kind) {
6655 case MethodListType::CategoryInstanceMethods:
6656 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6657 forProtocol = false;
6658 break;
6659 case MethodListType::CategoryClassMethods:
6660 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_";
6661 forProtocol = false;
6662 break;
6663 case MethodListType::InstanceMethods:
6664 prefix = "_OBJC_$_INSTANCE_METHODS_";
6665 forProtocol = false;
6666 break;
6667 case MethodListType::ClassMethods:
6668 prefix = "_OBJC_$_CLASS_METHODS_";
6669 forProtocol = false;
6670 break;
6671
6672 case MethodListType::ProtocolInstanceMethods:
6673 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6674 forProtocol = true;
6675 break;
6676 case MethodListType::ProtocolClassMethods:
6677 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_";
6678 forProtocol = true;
6679 break;
6680 case MethodListType::OptionalProtocolInstanceMethods:
6681 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6682 forProtocol = true;
6683 break;
6684 case MethodListType::OptionalProtocolClassMethods:
6685 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6686 forProtocol = true;
6687 break;
6688 }
6689
6690 ConstantInitBuilder builder(CGM);
6691 auto values = builder.beginStruct();
6692
6693 // sizeof(struct _objc_method)
6694 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.MethodTy);
6695 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
6696 // method_count
6697 values.addInt(intTy: ObjCTypes.IntTy, value: methods.size());
6698 auto methodArray = values.beginArray(eltTy: ObjCTypes.MethodTy);
6699 for (auto MD : methods)
6700 emitMethodConstant(builder&: methodArray, MD, forProtocol);
6701 methodArray.finishAndAddTo(parent&: values);
6702
6703 llvm::GlobalVariable *GV = finishAndCreateGlobal(Builder&: values, Name: prefix + name, CGM);
6704 CGM.addCompilerUsedGlobal(GV);
6705 return GV;
6706}
6707
6708/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6709/// the given ivar.
6710llvm::GlobalVariable *
6711CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6712 const ObjCIvarDecl *Ivar) {
6713 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6714 llvm::SmallString<64> Name("OBJC_IVAR_$_");
6715 Name += Container->getObjCRuntimeNameAsString();
6716 Name += ".";
6717 Name += Ivar->getName();
6718 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
6719 if (!IvarOffsetGV) {
6720 IvarOffsetGV = new llvm::GlobalVariable(
6721 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
6722 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
6723 if (CGM.getTriple().isOSBinFormatCOFF()) {
6724 bool IsPrivateOrPackage =
6725 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6726 Ivar->getAccessControl() == ObjCIvarDecl::Package;
6727
6728 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
6729
6730 if (ContainingID->hasAttr<DLLImportAttr>())
6731 IvarOffsetGV->setDLLStorageClass(
6732 llvm::GlobalValue::DLLImportStorageClass);
6733 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6734 IvarOffsetGV->setDLLStorageClass(
6735 llvm::GlobalValue::DLLExportStorageClass);
6736 }
6737 }
6738 return IvarOffsetGV;
6739}
6740
6741llvm::Constant *
6742CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6743 const ObjCIvarDecl *Ivar,
6744 unsigned long int Offset) {
6745 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6746 IvarOffsetGV->setInitializer(
6747 llvm::ConstantInt::get(Ty: ObjCTypes.IvarOffsetVarTy, V: Offset));
6748 IvarOffsetGV->setAlignment(
6749 CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.IvarOffsetVarTy));
6750
6751 if (!CGM.getTriple().isOSBinFormatCOFF()) {
6752 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
6753 // as well (i.e., in ObjCIvarOffsetVariable).
6754 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6755 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6756 ID->getVisibility() == HiddenVisibility)
6757 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6758 else
6759 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6760 }
6761
6762 // If ID's layout is known, then make the global constant. This serves as a
6763 // useful assertion: we'll never use this variable to calculate ivar offsets,
6764 // so if the runtime tries to patch it then we should crash.
6765 if (isClassLayoutKnownStatically(ID))
6766 IvarOffsetGV->setConstant(true);
6767
6768 if (CGM.getTriple().isOSBinFormatMachO())
6769 IvarOffsetGV->setSection("__DATA, __objc_ivar");
6770 return IvarOffsetGV;
6771}
6772
6773/// EmitIvarList - Emit the ivar list for the given
6774/// implementation. The return value has type
6775/// IvarListnfABIPtrTy.
6776/// struct _ivar_t {
6777/// unsigned [long] int *offset; // pointer to ivar offset location
6778/// char *name;
6779/// char *type;
6780/// uint32_t alignment;
6781/// uint32_t size;
6782/// }
6783/// struct _ivar_list_t {
6784/// uint32 entsize; // sizeof(struct _ivar_t)
6785/// uint32 count;
6786/// struct _iver_t list[count];
6787/// }
6788///
6789
6790llvm::Constant *
6791CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
6792
6793 ConstantInitBuilder builder(CGM);
6794 auto ivarList = builder.beginStruct();
6795 ivarList.addInt(intTy: ObjCTypes.IntTy,
6796 value: CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.IvarnfABITy));
6797 auto ivarCountSlot = ivarList.addPlaceholder();
6798 auto ivars = ivarList.beginArray(eltTy: ObjCTypes.IvarnfABITy);
6799
6800 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6801 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6802
6803 // FIXME. Consolidate this with similar code in GenerateClass.
6804
6805 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
6806 IVD = IVD->getNextIvar()) {
6807 // Ignore unnamed bit-fields.
6808 if (!IVD->getDeclName())
6809 continue;
6810
6811 auto ivar = ivars.beginStruct(ty: ObjCTypes.IvarnfABITy);
6812 ivar.add(value: EmitIvarOffsetVar(ID: ID->getClassInterface(), Ivar: IVD,
6813 Offset: ComputeIvarBaseOffset(CGM, OID: ID, Ivar: IVD)));
6814 ivar.add(value: GetMethodVarName(ID: IVD->getIdentifier()));
6815 ivar.add(value: GetMethodVarType(Field: IVD));
6816 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(T: IVD->getType());
6817 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: FieldTy);
6818 unsigned Align =
6819 CGM.getContext().getPreferredTypeAlign(T: IVD->getType().getTypePtr()) >>
6820 3;
6821 Align = llvm::Log2_32(Value: Align);
6822 ivar.addInt(intTy: ObjCTypes.IntTy, value: Align);
6823 // NOTE. Size of a bitfield does not match gcc's, because of the
6824 // way bitfields are treated special in each. But I am told that
6825 // 'size' for bitfield ivars is ignored by the runtime so it does
6826 // not matter. If it matters, there is enough info to get the
6827 // bitfield right!
6828 ivar.addInt(intTy: ObjCTypes.IntTy, value: Size);
6829 ivar.finishAndAddTo(parent&: ivars);
6830 }
6831 // Return null for empty list.
6832 if (ivars.empty()) {
6833 ivars.abandon();
6834 ivarList.abandon();
6835 return llvm::Constant::getNullValue(Ty: ObjCTypes.IvarListnfABIPtrTy);
6836 }
6837
6838 auto ivarCount = ivars.size();
6839 ivars.finishAndAddTo(parent&: ivarList);
6840 ivarList.fillPlaceholderWithInt(position: ivarCountSlot, type: ObjCTypes.IntTy, value: ivarCount);
6841
6842 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_";
6843 llvm::GlobalVariable *GV = finishAndCreateGlobal(
6844 Builder&: ivarList, Name: Prefix + OID->getObjCRuntimeNameAsString(), CGM);
6845 CGM.addCompilerUsedGlobal(GV);
6846 return GV;
6847}
6848
6849llvm::Constant *
6850CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
6851 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6852
6853 assert(!PD->isNonRuntimeProtocol() &&
6854 "attempting to GetOrEmit a non-runtime protocol");
6855 if (!Entry) {
6856 // We use the initializer as a marker of whether this is a forward
6857 // reference or not. At module finalization we add the empty
6858 // contents for protocols which were referenced but never defined.
6859 llvm::SmallString<64> Protocol;
6860 llvm::raw_svector_ostream(Protocol)
6861 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6862
6863 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6864 false, llvm::GlobalValue::ExternalLinkage,
6865 nullptr, Protocol);
6866 if (!CGM.getTriple().isOSBinFormatMachO())
6867 Entry->setComdat(CGM.getModule().getOrInsertComdat(Name: Protocol));
6868 }
6869
6870 return Entry;
6871}
6872
6873/// GetOrEmitProtocol - Generate the protocol meta-data:
6874/// @code
6875/// struct _protocol_t {
6876/// id isa; // NULL
6877/// const char * const protocol_name;
6878/// const struct _protocol_list_t * protocol_list; // super protocols
6879/// const struct method_list_t * const instance_methods;
6880/// const struct method_list_t * const class_methods;
6881/// const struct method_list_t *optionalInstanceMethods;
6882/// const struct method_list_t *optionalClassMethods;
6883/// const struct _prop_list_t * properties;
6884/// const uint32_t size; // sizeof(struct _protocol_t)
6885/// const uint32_t flags; // = 0
6886/// const char ** extendedMethodTypes;
6887/// const char *demangledName;
6888/// const struct _prop_list_t * class_properties;
6889/// }
6890/// @endcode
6891///
6892
6893llvm::Constant *
6894CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
6895 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6896
6897 // Early exit if a defining object has already been generated.
6898 if (Entry && Entry->hasInitializer())
6899 return Entry;
6900
6901 // Use the protocol definition, if there is one.
6902 assert(PD->hasDefinition() &&
6903 "emitting protocol metadata without definition");
6904 PD = PD->getDefinition();
6905
6906 auto methodLists = ProtocolMethodLists::get(PD);
6907
6908 ConstantInitBuilder builder(CGM);
6909 auto values = builder.beginStruct(structTy: ObjCTypes.ProtocolnfABITy);
6910
6911 // isa is NULL
6912 values.addNullPointer(ptrTy: ObjCTypes.ObjectPtrTy);
6913 values.add(value: GetClassName(RuntimeName: PD->getObjCRuntimeNameAsString()));
6914 values.add(value: EmitProtocolList(Name: "_OBJC_$_PROTOCOL_REFS_" +
6915 PD->getObjCRuntimeNameAsString(),
6916 begin: PD->protocol_begin(), end: PD->protocol_end()));
6917 values.add(value: methodLists.emitMethodList(
6918 self: this, PD, kind: ProtocolMethodLists::RequiredInstanceMethods));
6919 values.add(value: methodLists.emitMethodList(
6920 self: this, PD, kind: ProtocolMethodLists::RequiredClassMethods));
6921 values.add(value: methodLists.emitMethodList(
6922 self: this, PD, kind: ProtocolMethodLists::OptionalInstanceMethods));
6923 values.add(value: methodLists.emitMethodList(
6924 self: this, PD, kind: ProtocolMethodLists::OptionalClassMethods));
6925 values.add(
6926 value: EmitPropertyList(Name: "_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6927 Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: false));
6928 uint32_t Size =
6929 CGM.getDataLayout().getTypeAllocSize(Ty: ObjCTypes.ProtocolnfABITy);
6930 values.addInt(intTy: ObjCTypes.IntTy, value: Size);
6931 values.addInt(intTy: ObjCTypes.IntTy, value: 0);
6932 values.add(value: EmitProtocolMethodTypes(
6933 Name: "_OBJC_$_PROTOCOL_METHOD_TYPES_" + PD->getObjCRuntimeNameAsString(),
6934 MethodTypes: methodLists.emitExtendedTypesArray(self: this), ObjCTypes));
6935
6936 // const char *demangledName;
6937 values.addNullPointer(ptrTy: ObjCTypes.Int8PtrTy);
6938
6939 values.add(value: EmitPropertyList(Name: "_OBJC_$_CLASS_PROP_LIST_" +
6940 PD->getObjCRuntimeNameAsString(),
6941 Container: nullptr, OCD: PD, ObjCTypes, IsClassProperty: true));
6942
6943 if (Entry) {
6944 // Already created, fix the linkage and update the initializer.
6945 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6946 values.finishAndSetAsInitializer(global: Entry);
6947 } else {
6948 llvm::SmallString<64> symbolName;
6949 llvm::raw_svector_ostream(symbolName)
6950 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6951
6952 Entry = values.finishAndCreateGlobal(args&: symbolName, args: CGM.getPointerAlign(),
6953 /*constant*/ args: false,
6954 args: llvm::GlobalValue::WeakAnyLinkage);
6955 if (!CGM.getTriple().isOSBinFormatMachO())
6956 Entry->setComdat(CGM.getModule().getOrInsertComdat(Name: symbolName));
6957
6958 Protocols[PD->getIdentifier()] = Entry;
6959 }
6960 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6961 CGM.addUsedGlobal(GV: Entry);
6962
6963 // Use this protocol meta-data to build protocol list table in section
6964 // __DATA, __objc_protolist
6965 llvm::SmallString<64> ProtocolRef;
6966 llvm::raw_svector_ostream(ProtocolRef)
6967 << "_OBJC_LABEL_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6968
6969 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
6970 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
6971 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
6972 if (!CGM.getTriple().isOSBinFormatMachO())
6973 PTGV->setComdat(CGM.getModule().getOrInsertComdat(Name: ProtocolRef));
6974 PTGV->setAlignment(
6975 CGM.getDataLayout().getABITypeAlign(Ty: ObjCTypes.ProtocolnfABIPtrTy));
6976 PTGV->setSection(
6977 GetSectionName(Section: "__objc_protolist", MachOAttributes: "coalesced,no_dead_strip"));
6978 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6979 CGM.addUsedGlobal(GV: PTGV);
6980 return Entry;
6981}
6982
6983/// EmitProtocolList - Generate protocol list meta-data:
6984/// @code
6985/// struct _protocol_list_t {
6986/// long protocol_count; // Note, this is 32/64 bit
6987/// struct _protocol_t[protocol_count];
6988/// }
6989/// @endcode
6990///
6991llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
6992 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
6993 ObjCProtocolDecl::protocol_iterator end) {
6994 // Just return null for empty protocol lists
6995 auto Protocols = GetRuntimeProtocolList(begin, end);
6996 if (Protocols.empty())
6997 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListnfABIPtrTy);
6998
6999 SmallVector<llvm::Constant *, 16> ProtocolRefs;
7000 ProtocolRefs.reserve(N: Protocols.size());
7001
7002 for (const auto *PD : Protocols)
7003 ProtocolRefs.push_back(Elt: GetProtocolRef(PD));
7004
7005 // If all of the protocols in the protocol list are objc_non_runtime_protocol
7006 // just return null
7007 if (ProtocolRefs.size() == 0)
7008 return llvm::Constant::getNullValue(Ty: ObjCTypes.ProtocolListnfABIPtrTy);
7009
7010 // FIXME: We shouldn't need to do this lookup here, should we?
7011 SmallString<256> TmpName;
7012 Name.toVector(Out&: TmpName);
7013 llvm::GlobalVariable *GV =
7014 CGM.getModule().getGlobalVariable(Name: TmpName.str(), AllowInternal: true);
7015 if (GV)
7016 return GV;
7017
7018 ConstantInitBuilder builder(CGM);
7019 auto values = builder.beginStruct();
7020 auto countSlot = values.addPlaceholder();
7021
7022 // A null-terminated array of protocols.
7023 auto array = values.beginArray(eltTy: ObjCTypes.ProtocolnfABIPtrTy);
7024 for (auto const &proto : ProtocolRefs)
7025 array.add(value: proto);
7026 auto count = array.size();
7027 array.addNullPointer(ptrTy: ObjCTypes.ProtocolnfABIPtrTy);
7028
7029 array.finishAndAddTo(parent&: values);
7030 values.fillPlaceholderWithInt(position: countSlot, type: ObjCTypes.LongTy, value: count);
7031
7032 GV = finishAndCreateGlobal(Builder&: values, Name, CGM);
7033 CGM.addCompilerUsedGlobal(GV);
7034 return GV;
7035}
7036
7037/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
7038/// This code gen. amounts to generating code for:
7039/// @code
7040/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
7041/// @encode
7042///
7043LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7044 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
7045 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
7046 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
7047 llvm::Value *Offset = EmitIvarOffset(CGF, Interface: ID, Ivar);
7048 return EmitValueForIvarAtOffset(CGF, OID: ID, BaseValue, Ivar, CVRQualifiers,
7049 Offset);
7050}
7051
7052llvm::Value *
7053CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
7054 const ObjCInterfaceDecl *Interface,
7055 const ObjCIvarDecl *Ivar) {
7056 llvm::Value *IvarOffsetValue;
7057 if (isClassLayoutKnownStatically(ID: Interface)) {
7058 IvarOffsetValue = llvm::ConstantInt::get(
7059 Ty: ObjCTypes.IvarOffsetVarTy,
7060 V: ComputeIvarBaseOffset(CGM, OID: Interface->getImplementation(), Ivar));
7061 } else {
7062 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(ID: Interface, Ivar);
7063 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(Ty: GV->getValueType(), Addr: GV,
7064 Align: CGF.getSizeAlign(), Name: "ivar");
7065 if (IsIvarOffsetKnownIdempotent(CGF, IV: Ivar))
7066 cast<llvm::LoadInst>(Val: IvarOffsetValue)
7067 ->setMetadata(KindID: llvm::LLVMContext::MD_invariant_load,
7068 Node: llvm::MDNode::get(Context&: VMContext, MDs: {}));
7069 }
7070
7071 // This could be 32bit int or 64bit integer depending on the architecture.
7072 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
7073 // as this is what caller always expects.
7074 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7075 IvarOffsetValue = CGF.Builder.CreateIntCast(
7076 V: IvarOffsetValue, DestTy: ObjCTypes.LongTy, isSigned: true, Name: "ivar.conv");
7077 return IvarOffsetValue;
7078}
7079
7080static void appendSelectorForMessageRefTable(std::string &buffer,
7081 Selector selector) {
7082 if (selector.isUnarySelector()) {
7083 buffer += selector.getNameForSlot(argIndex: 0);
7084 return;
7085 }
7086
7087 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
7088 buffer += selector.getNameForSlot(argIndex: i);
7089 buffer += '_';
7090 }
7091}
7092
7093/// Emit a "vtable" message send. We emit a weak hidden-visibility
7094/// struct, initially containing the selector pointer and a pointer to
7095/// a "fixup" variant of the appropriate objc_msgSend. To call, we
7096/// load and call the function pointer, passing the address of the
7097/// struct as the second parameter. The runtime determines whether
7098/// the selector is currently emitted using vtable dispatch; if so, it
7099/// substitutes a stub function which simply tail-calls through the
7100/// appropriate vtable slot, and if not, it substitues a stub function
7101/// which tail-calls objc_msgSend. Both stubs adjust the selector
7102/// argument to correctly point to the selector.
7103RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
7104 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
7105 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
7106 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
7107 // Compute the actual arguments.
7108 CallArgList args;
7109
7110 // First argument: the receiver / super-call structure.
7111 if (!isSuper)
7112 arg0 = CGF.Builder.CreateBitCast(V: arg0, DestTy: ObjCTypes.ObjectPtrTy);
7113 args.add(rvalue: RValue::get(V: arg0), type: arg0Type);
7114
7115 // Second argument: a pointer to the message ref structure. Leave
7116 // the actual argument value blank for now.
7117 args.add(rvalue: RValue::get(V: nullptr), type: ObjCTypes.MessageRefCPtrTy);
7118
7119 llvm::append_range(C&: args, R: formalArgs);
7120
7121 MessageSendInfo MSI = getMessageSendInfo(method, resultType, callArgs&: args);
7122
7123 NullReturnState nullReturn;
7124
7125 // Find the function to call and the mangled name for the message
7126 // ref structure. Using a different mangled name wouldn't actually
7127 // be a problem; it would just be a waste.
7128 //
7129 // The runtime currently never uses vtable dispatch for anything
7130 // except normal, non-super message-sends.
7131 // FIXME: don't use this for that.
7132 llvm::FunctionCallee fn = nullptr;
7133 std::string messageRefName("_");
7134 if (CGM.ReturnSlotInterferesWithArgs(FI: MSI.CallInfo)) {
7135 if (isSuper) {
7136 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7137 messageRefName += "objc_msgSendSuper2_stret_fixup";
7138 } else {
7139 nullReturn.init(CGF, receiver: arg0);
7140 fn = ObjCTypes.getMessageSendStretFixupFn();
7141 messageRefName += "objc_msgSend_stret_fixup";
7142 }
7143 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(ResultType: resultType)) {
7144 fn = ObjCTypes.getMessageSendFpretFixupFn();
7145 messageRefName += "objc_msgSend_fpret_fixup";
7146 } else {
7147 if (isSuper) {
7148 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7149 messageRefName += "objc_msgSendSuper2_fixup";
7150 } else {
7151 fn = ObjCTypes.getMessageSendFixupFn();
7152 messageRefName += "objc_msgSend_fixup";
7153 }
7154 }
7155 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
7156 messageRefName += '_';
7157
7158 // Append the selector name, except use underscores anywhere we
7159 // would have used colons.
7160 appendSelectorForMessageRefTable(buffer&: messageRefName, selector);
7161
7162 llvm::GlobalVariable *messageRef =
7163 CGM.getModule().getGlobalVariable(Name: messageRefName);
7164 if (!messageRef) {
7165 // Build the message ref structure.
7166 ConstantInitBuilder builder(CGM);
7167 auto values = builder.beginStruct();
7168 values.add(value: cast<llvm::Constant>(Val: fn.getCallee()));
7169 values.add(value: GetMethodVarName(Sel: selector));
7170 messageRef = values.finishAndCreateGlobal(
7171 args&: messageRefName, args: CharUnits::fromQuantity(Quantity: 16),
7172 /*constant*/ args: false, args: llvm::GlobalValue::WeakAnyLinkage);
7173 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
7174 messageRef->setSection(GetSectionName(Section: "__objc_msgrefs", MachOAttributes: "coalesced"));
7175 }
7176
7177 bool requiresnullCheck = false;
7178 if (CGM.getLangOpts().ObjCAutoRefCount && method)
7179 for (const auto *ParamDecl : method->parameters()) {
7180 if (ParamDecl->isDestroyedInCallee()) {
7181 if (!nullReturn.NullBB)
7182 nullReturn.init(CGF, receiver: arg0);
7183 requiresnullCheck = true;
7184 break;
7185 }
7186 }
7187
7188 Address mref =
7189 Address(CGF.Builder.CreateBitCast(V: messageRef, DestTy: ObjCTypes.MessageRefPtrTy),
7190 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
7191
7192 // Update the message ref argument.
7193 args[1].setRValue(RValue::get(Addr: mref, CGF));
7194
7195 // Load the function to call from the message ref table.
7196 Address calleeAddr = CGF.Builder.CreateStructGEP(Addr: mref, Index: 0);
7197 llvm::Value *calleePtr = CGF.Builder.CreateLoad(Addr: calleeAddr, Name: "msgSend_fn");
7198
7199 calleePtr = CGF.Builder.CreateBitCast(V: calleePtr, DestTy: MSI.MessengerType);
7200 CGCallee callee(CGCalleeInfo(), calleePtr);
7201
7202 RValue result = CGF.EmitCall(CallInfo: MSI.CallInfo, Callee: callee, ReturnValue: returnSlot, Args: args);
7203 return nullReturn.complete(CGF, returnSlot, result, resultType, CallArgs: formalArgs,
7204 Method: requiresnullCheck ? method : nullptr);
7205}
7206
7207/// Generate code for a message send expression in the nonfragile abi.
7208CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
7209 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
7210 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
7211 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
7212 return isVTableDispatchedSelector(Sel)
7213 ? EmitVTableMessageSend(CGF, returnSlot: Return, resultType: ResultType, selector: Sel, arg0: Receiver,
7214 arg0Type: CGF.getContext().getObjCIdType(), isSuper: false,
7215 formalArgs: CallArgs, method: Method)
7216 : EmitMessageSend(CGF, Return, ResultType, Sel, Arg0: Receiver,
7217 Arg0Ty: CGF.getContext().getObjCIdType(), IsSuper: false,
7218 CallArgs, Method, ClassReceiver: Class, ObjCTypes);
7219}
7220
7221llvm::Constant *
7222CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
7223 bool metaclass,
7224 ForDefinition_t isForDefinition) {
7225 auto prefix =
7226 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7227 return GetClassGlobal(Name: (prefix + ID->getObjCRuntimeNameAsString()).str(),
7228 IsForDefinition: isForDefinition, Weak: ID->isWeakImported(),
7229 DLLImport: !isForDefinition &&
7230 CGM.getTriple().isOSBinFormatCOFF() &&
7231 ID->hasAttr<DLLImportAttr>());
7232}
7233
7234llvm::Constant *
7235CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7236 ForDefinition_t IsForDefinition,
7237 bool Weak, bool DLLImport) {
7238 llvm::GlobalValue::LinkageTypes L =
7239 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7240 : llvm::GlobalValue::ExternalLinkage;
7241
7242 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
7243 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
7244 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
7245 nullptr, Name);
7246
7247 if (DLLImport)
7248 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7249
7250 if (GV) {
7251 GV->replaceAllUsesWith(V: NewGV);
7252 GV->eraseFromParent();
7253 }
7254 GV = NewGV;
7255 CGM.getModule().insertGlobalVariable(GV);
7256 }
7257
7258 assert(GV->getLinkage() == L);
7259 return GV;
7260}
7261
7262llvm::Constant *
7263CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
7264 llvm::Constant *ClassGV =
7265 GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition);
7266
7267 if (!ID->hasAttr<ObjCClassStubAttr>())
7268 return ClassGV;
7269
7270 ClassGV = llvm::ConstantExpr::getPointerCast(C: ClassGV, Ty: ObjCTypes.Int8PtrTy);
7271
7272 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
7273 // must set the least significant bit set to 1.
7274 auto *Idx = llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 1);
7275 return llvm::ConstantExpr::getGetElementPtr(Ty: CGM.Int8Ty, C: ClassGV, Idx);
7276}
7277
7278llvm::Value *
7279CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
7280 const ObjCInterfaceDecl *ID,
7281 llvm::GlobalVariable *Entry) {
7282 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
7283 // Classrefs pointing at Objective-C stub classes must be loaded by calling
7284 // a special runtime function.
7285 return CGF.EmitRuntimeCall(callee: ObjCTypes.getLoadClassrefFn(), args: Entry,
7286 name: "load_classref_result");
7287 }
7288
7289 CharUnits Align = CGF.getPointerAlign();
7290 return CGF.Builder.CreateAlignedLoad(Ty: Entry->getValueType(), Addr: Entry, Align);
7291}
7292
7293llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
7294 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
7295 llvm::GlobalVariable *&Entry = ClassReferences[II];
7296
7297 if (!Entry) {
7298 llvm::Constant *ClassGV;
7299 if (ID) {
7300 ClassGV = GetClassGlobalForClassRef(ID);
7301 } else {
7302 ClassGV = GetClassGlobal(Name: (getClassSymbolPrefix() + II->getName()).str(),
7303 IsForDefinition: NotForDefinition);
7304 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7305 "classref was emitted with the wrong type?");
7306 }
7307
7308 std::string SectionName =
7309 GetSectionName(Section: "__objc_classrefs", MachOAttributes: "regular,no_dead_strip");
7310 Entry = new llvm::GlobalVariable(
7311 CGM.getModule(), ClassGV->getType(), false,
7312 getLinkageTypeForObjCMetadata(CGM, Section: SectionName), ClassGV,
7313 "OBJC_CLASSLIST_REFERENCES_$_");
7314 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7315 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
7316 Entry->setSection(SectionName);
7317
7318 CGM.addCompilerUsedGlobal(GV: Entry);
7319 }
7320
7321 return EmitLoadOfClassRef(CGF, ID, Entry);
7322}
7323
7324llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
7325 const ObjCInterfaceDecl *ID) {
7326 // If the class has the objc_runtime_visible attribute, we need to
7327 // use the Objective-C runtime to get the class.
7328 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
7329 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7330
7331 return EmitClassRefFromId(CGF, II: ID->getIdentifier(), ID);
7332}
7333
7334llvm::Value *
7335CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
7336 IdentifierInfo *II = &CGM.getContext().Idents.get(Name: "NSAutoreleasePool");
7337 return EmitClassRefFromId(CGF, II, ID: nullptr);
7338}
7339
7340llvm::Value *
7341CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
7342 const ObjCInterfaceDecl *ID) {
7343 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
7344
7345 if (!Entry) {
7346 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7347 std::string SectionName =
7348 GetSectionName(Section: "__objc_superrefs", MachOAttributes: "regular,no_dead_strip");
7349 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
7350 llvm::GlobalValue::PrivateLinkage, ClassGV,
7351 "OBJC_CLASSLIST_SUP_REFS_$_");
7352 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7353 Entry->setSection(SectionName);
7354 CGM.addCompilerUsedGlobal(GV: Entry);
7355 }
7356
7357 return EmitLoadOfClassRef(CGF, ID, Entry);
7358}
7359
7360/// EmitMetaClassRef - Return a Value * of the address of _class_t
7361/// meta-data
7362///
7363llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
7364 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
7365 CharUnits Align = CGF.getPointerAlign();
7366 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
7367 if (!Entry) {
7368 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, isForDefinition: NotForDefinition);
7369 std::string SectionName =
7370 GetSectionName(Section: "__objc_superrefs", MachOAttributes: "regular,no_dead_strip");
7371 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7372 false, llvm::GlobalValue::PrivateLinkage,
7373 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
7374 Entry->setAlignment(Align.getAsAlign());
7375 Entry->setSection(SectionName);
7376 CGM.addCompilerUsedGlobal(GV: Entry);
7377 }
7378
7379 return CGF.Builder.CreateAlignedLoad(Ty: ObjCTypes.ClassnfABIPtrTy, Addr: Entry, Align);
7380}
7381
7382/// GetClass - Return a reference to the class for the given interface
7383/// decl.
7384llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
7385 const ObjCInterfaceDecl *ID) {
7386 if (ID->isWeakImported()) {
7387 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition);
7388 (void)ClassGV;
7389 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7390 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7391 }
7392
7393 return EmitClassRef(CGF, ID);
7394}
7395
7396/// Generates a message send where the super is the receiver. This is
7397/// a message send to self with special delivery semantics indicating
7398/// which class's method should be called.
7399CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
7400 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
7401 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
7402 llvm::Value *Receiver, bool IsClassMessage,
7403 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
7404 // ...
7405 // Create and init a super structure; this is a (receiver, class)
7406 // pair we will pass to objc_msgSendSuper.
7407 RawAddress ObjCSuper = CGF.CreateTempAlloca(
7408 Ty: ObjCTypes.SuperTy, align: CGF.getPointerAlign(), Name: "objc_super");
7409
7410 llvm::Value *ReceiverAsObject =
7411 CGF.Builder.CreateBitCast(V: Receiver, DestTy: ObjCTypes.ObjectPtrTy);
7412 CGF.Builder.CreateStore(Val: ReceiverAsObject,
7413 Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 0));
7414
7415 // If this is a class message the metaclass is passed as the target.
7416 llvm::Value *Target;
7417 if (IsClassMessage)
7418 Target = EmitMetaClassRef(CGF, ID: Class, Weak: Class->isWeakImported());
7419 else
7420 Target = EmitSuperClassRef(CGF, ID: Class);
7421
7422 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7423 // ObjCTypes types.
7424 llvm::Type *ClassTy =
7425 CGM.getTypes().ConvertType(T: CGF.getContext().getObjCClassType());
7426 Target = CGF.Builder.CreateBitCast(V: Target, DestTy: ClassTy);
7427 CGF.Builder.CreateStore(Val: Target, Addr: CGF.Builder.CreateStructGEP(Addr: ObjCSuper, Index: 1));
7428
7429 return (isVTableDispatchedSelector(Sel))
7430 ? EmitVTableMessageSend(
7431 CGF, returnSlot: Return, resultType: ResultType, selector: Sel, arg0: ObjCSuper.getPointer(),
7432 arg0Type: ObjCTypes.SuperPtrCTy, isSuper: true, formalArgs: CallArgs, method: Method)
7433 : EmitMessageSend(CGF, Return, ResultType, Sel,
7434 Arg0: ObjCSuper.getPointer(), Arg0Ty: ObjCTypes.SuperPtrCTy,
7435 IsSuper: true, CallArgs, Method, ClassReceiver: Class, ObjCTypes);
7436}
7437
7438llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7439 Selector Sel) {
7440 Address Addr = EmitSelectorAddr(Sel);
7441
7442 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
7443 LI->setMetadata(KindID: llvm::LLVMContext::MD_invariant_load,
7444 Node: llvm::MDNode::get(Context&: VMContext, MDs: {}));
7445 return LI;
7446}
7447
7448ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
7449 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7450 CharUnits Align = CGM.getPointerAlign();
7451 if (!Entry) {
7452 std::string SectionName =
7453 GetSectionName(Section: "__objc_selrefs", MachOAttributes: "literal_pointers,no_dead_strip");
7454 Entry = new llvm::GlobalVariable(
7455 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
7456 getLinkageTypeForObjCMetadata(CGM, Section: SectionName), GetMethodVarName(Sel),
7457 "OBJC_SELECTOR_REFERENCES_");
7458 Entry->setExternallyInitialized(true);
7459 Entry->setSection(SectionName);
7460 Entry->setAlignment(Align.getAsAlign());
7461 CGM.addCompilerUsedGlobal(GV: Entry);
7462 }
7463
7464 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
7465}
7466
7467/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
7468/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
7469///
7470void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7471 llvm::Value *src, Address dst,
7472 llvm::Value *ivarOffset) {
7473 llvm::Type *SrcTy = src->getType();
7474 if (!isa<llvm::PointerType>(Val: SrcTy)) {
7475 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
7476 assert(Size <= 8 && "does not support size > 8");
7477 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
7478 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
7479 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
7480 }
7481 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
7482 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
7483 DestTy: ObjCTypes.PtrObjectPtrTy);
7484 llvm::Value *args[] = {src, dstVal, ivarOffset};
7485 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignIvarFn(), args);
7486}
7487
7488/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
7489/// objc_assign_strongCast (id src, id *dst)
7490///
7491void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7492 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
7493 llvm::Type *SrcTy = src->getType();
7494 if (!isa<llvm::PointerType>(Val: SrcTy)) {
7495 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
7496 assert(Size <= 8 && "does not support size > 8");
7497 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
7498 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
7499 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
7500 }
7501 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
7502 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
7503 DestTy: ObjCTypes.PtrObjectPtrTy);
7504 llvm::Value *args[] = {src, dstVal};
7505 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignStrongCastFn(), args,
7506 name: "weakassign");
7507}
7508
7509void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7510 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
7511 llvm::Value *Size) {
7512 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
7513 SrcPtr.emitRawPointer(CGF), Size};
7514 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.GcMemmoveCollectableFn(), args);
7515}
7516
7517/// EmitObjCWeakRead - Code gen for loading value of a __weak
7518/// object: objc_read_weak (id *src)
7519///
7520llvm::Value *
7521CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
7522 Address AddrWeakObj) {
7523 llvm::Type *DestTy = AddrWeakObj.getElementType();
7524 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
7525 V: AddrWeakObj.emitRawPointer(CGF), DestTy: ObjCTypes.PtrObjectPtrTy);
7526 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
7527 callee: ObjCTypes.getGcReadWeakFn(), args: AddrWeakObjVal, name: "weakread");
7528 read_weak = CGF.Builder.CreateBitCast(V: read_weak, DestTy);
7529 return read_weak;
7530}
7531
7532/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
7533/// objc_assign_weak (id src, id *dst)
7534///
7535void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7536 llvm::Value *src, Address dst) {
7537 llvm::Type *SrcTy = src->getType();
7538 if (!isa<llvm::PointerType>(Val: SrcTy)) {
7539 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
7540 assert(Size <= 8 && "does not support size > 8");
7541 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
7542 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
7543 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
7544 }
7545 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
7546 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
7547 DestTy: ObjCTypes.PtrObjectPtrTy);
7548 llvm::Value *args[] = {src, dstVal};
7549 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignWeakFn(), args,
7550 name: "weakassign");
7551}
7552
7553/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
7554/// objc_assign_global (id src, id *dst)
7555///
7556void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7557 llvm::Value *src, Address dst,
7558 bool threadlocal) {
7559 llvm::Type *SrcTy = src->getType();
7560 if (!isa<llvm::PointerType>(Val: SrcTy)) {
7561 unsigned Size = CGM.getDataLayout().getTypeAllocSize(Ty: SrcTy);
7562 assert(Size <= 8 && "does not support size > 8");
7563 src = (Size == 4 ? CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.IntTy)
7564 : CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.LongTy));
7565 src = CGF.Builder.CreateIntToPtr(V: src, DestTy: ObjCTypes.Int8PtrTy);
7566 }
7567 src = CGF.Builder.CreateBitCast(V: src, DestTy: ObjCTypes.ObjectPtrTy);
7568 llvm::Value *dstVal = CGF.Builder.CreateBitCast(V: dst.emitRawPointer(CGF),
7569 DestTy: ObjCTypes.PtrObjectPtrTy);
7570 llvm::Value *args[] = {src, dstVal};
7571 if (!threadlocal)
7572 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignGlobalFn(), args,
7573 name: "globalassign");
7574 else
7575 CGF.EmitNounwindRuntimeCall(callee: ObjCTypes.getGcAssignThreadLocalFn(), args,
7576 name: "threadlocalassign");
7577}
7578
7579void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
7580 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
7581 EmitAtSynchronizedStmt(CGF, S, syncEnterFn: ObjCTypes.getSyncEnterFn(),
7582 syncExitFn: ObjCTypes.getSyncExitFn());
7583}
7584
7585llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
7586 // There's a particular fixed type info for 'id'.
7587 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7588 auto *IDEHType = CGM.getModule().getGlobalVariable(Name: "OBJC_EHTYPE_id");
7589 if (!IDEHType) {
7590 IDEHType = new llvm::GlobalVariable(
7591 CGM.getModule(), ObjCTypes.EHTypeTy, false,
7592 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id");
7593 if (CGM.getTriple().isOSBinFormatCOFF())
7594 IDEHType->setDLLStorageClass(getStorage(CGM, Name: "OBJC_EHTYPE_id"));
7595 }
7596 return IDEHType;
7597 }
7598
7599 // All other types should be Objective-C interface pointer types.
7600 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7601 assert(PT && "Invalid @catch type.");
7602
7603 const ObjCInterfaceType *IT = PT->getInterfaceType();
7604 assert(IT && "Invalid @catch type.");
7605
7606 return GetInterfaceEHType(ID: IT->getDecl(), IsForDefinition: NotForDefinition);
7607}
7608
7609void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7610 const ObjCAtTryStmt &S) {
7611 EmitTryCatchStmt(CGF, S, beginCatchFn: ObjCTypes.getObjCBeginCatchFn(),
7612 endCatchFn: ObjCTypes.getObjCEndCatchFn(),
7613 exceptionRethrowFn: ObjCTypes.getExceptionRethrowFn());
7614}
7615
7616/// EmitThrowStmt - Generate code for a throw statement.
7617void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7618 const ObjCAtThrowStmt &S,
7619 bool ClearInsertionPoint) {
7620 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7621 llvm::Value *Exception = CGF.EmitObjCThrowOperand(expr: ThrowExpr);
7622 Exception = CGF.Builder.CreateBitCast(V: Exception, DestTy: ObjCTypes.ObjectPtrTy);
7623 llvm::CallBase *Call =
7624 CGF.EmitRuntimeCallOrInvoke(callee: ObjCTypes.getExceptionThrowFn(), args: Exception);
7625 Call->setDoesNotReturn();
7626 } else {
7627 llvm::CallBase *Call =
7628 CGF.EmitRuntimeCallOrInvoke(callee: ObjCTypes.getExceptionRethrowFn());
7629 Call->setDoesNotReturn();
7630 }
7631
7632 CGF.Builder.CreateUnreachable();
7633 if (ClearInsertionPoint)
7634 CGF.Builder.ClearInsertionPoint();
7635}
7636
7637llvm::Constant *
7638CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7639 ForDefinition_t IsForDefinition) {
7640 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
7641 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7642
7643 // If we don't need a definition, return the entry if found or check
7644 // if we use an external reference.
7645 if (!IsForDefinition) {
7646 if (Entry)
7647 return Entry;
7648
7649 // If this type (or a super class) has the __objc_exception__
7650 // attribute, emit an external reference.
7651 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: ID)) {
7652 std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();
7653 Entry = new llvm::GlobalVariable(
7654 CGM.getModule(), ObjCTypes.EHTypeTy, false,
7655 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
7656 CGM.setGVProperties(GV: Entry, D: ID);
7657 return Entry;
7658 }
7659 }
7660
7661 // Otherwise we need to either make a new entry or fill in the initializer.
7662 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
7663
7664 std::string VTableName = "objc_ehtype_vtable";
7665 auto *VTableGV = CGM.getModule().getGlobalVariable(Name: VTableName);
7666 if (!VTableGV) {
7667 VTableGV = new llvm::GlobalVariable(
7668 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7669 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
7670 if (CGM.getTriple().isOSBinFormatCOFF())
7671 VTableGV->setDLLStorageClass(getStorage(CGM, Name: VTableName));
7672 }
7673
7674 llvm::Value *VTableIdx = llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 2);
7675 ConstantInitBuilder builder(CGM);
7676 auto values = builder.beginStruct(structTy: ObjCTypes.EHTypeTy);
7677 values.add(value: llvm::ConstantExpr::getInBoundsGetElementPtr(
7678 Ty: VTableGV->getValueType(), C: VTableGV, IdxList: VTableIdx));
7679 values.add(value: GetClassName(RuntimeName: ClassName));
7680 values.add(value: GetClassGlobal(ID, /*metaclass*/ false, isForDefinition: NotForDefinition));
7681
7682 llvm::GlobalValue::LinkageTypes L = IsForDefinition
7683 ? llvm::GlobalValue::ExternalLinkage
7684 : llvm::GlobalValue::WeakAnyLinkage;
7685 if (Entry) {
7686 values.finishAndSetAsInitializer(global: Entry);
7687 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
7688 } else {
7689 Entry = values.finishAndCreateGlobal(args: "OBJC_EHTYPE_$_" + ClassName,
7690 args: CGM.getPointerAlign(),
7691 /*constant*/ args: false, args&: L);
7692 if (hasObjCExceptionAttribute(Context&: CGM.getContext(), OID: ID))
7693 CGM.setGVProperties(GV: Entry, D: ID);
7694 }
7695 assert(Entry->getLinkage() == L);
7696
7697 if (!CGM.getTriple().isOSBinFormatCOFF())
7698 if (ID->getVisibility() == HiddenVisibility)
7699 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7700
7701 if (IsForDefinition)
7702 if (CGM.getTriple().isOSBinFormatMachO())
7703 Entry->setSection("__DATA,__objc_const");
7704
7705 return Entry;
7706}
7707
7708/* *** */
7709
7710CodeGen::CGObjCRuntime *
7711CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7712 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7713 case ObjCRuntime::FragileMacOSX:
7714 return new CGObjCMac(CGM);
7715
7716 case ObjCRuntime::MacOSX:
7717 case ObjCRuntime::iOS:
7718 case ObjCRuntime::WatchOS:
7719 return new CGObjCNonFragileABIMac(CGM);
7720
7721 case ObjCRuntime::GNUstep:
7722 case ObjCRuntime::GCC:
7723 case ObjCRuntime::ObjFW:
7724 llvm_unreachable("these runtimes are not Mac runtimes");
7725 }
7726 llvm_unreachable("bad runtime");
7727}
7728