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