clang 23.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/// getConstantGEP() - Help routine to construct simple GEPs.
1976static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1977 llvm::GlobalVariable *C, unsigned idx0,
1978 unsigned idx1) {
1979 llvm::Value *Idxs[] = {
1980 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1981 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)};
1982 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1983}
1984
1985/// hasObjCExceptionAttribute - Return true if this class or any super
1986/// class has the __objc_exception__ attribute.
1988 const ObjCInterfaceDecl *OID) {
1989 if (OID->hasAttr<ObjCExceptionAttr>())
1990 return true;
1991 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1992 return hasObjCExceptionAttribute(Context, Super);
1993 return false;
1994}
1995
1996static llvm::GlobalValue::LinkageTypes
1998 if (CGM.getTriple().isOSBinFormatMachO() &&
1999 (Section.empty() || Section.starts_with("__DATA")))
2000 return llvm::GlobalValue::InternalLinkage;
2001 return llvm::GlobalValue::PrivateLinkage;
2002}
2003
2004/// A helper function to create an internal or private global variable.
2005static llvm::GlobalVariable *
2006finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder,
2007 const llvm::Twine &Name, CodeGenModule &CGM) {
2008 std::string SectionName;
2009 if (CGM.getTriple().isOSBinFormatMachO())
2010 SectionName = "__DATA, __objc_const";
2011 auto *GV = Builder.finishAndCreateGlobal(
2012 Name, CGM.getPointerAlign(), /*constant*/ false,
2013 getLinkageTypeForObjCMetadata(CGM, SectionName));
2014 GV->setSection(SectionName);
2015 return GV;
2016}
2017
2018/* *** CGObjCMac Public Interface *** */
2019
2020CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
2021 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2022 ObjCABI = 1;
2023 EmitImageInfo();
2024}
2025
2026/// GetClass - Return a reference to the class for the given interface
2027/// decl.
2028llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
2029 const ObjCInterfaceDecl *ID) {
2030 return EmitClassRef(CGF, ID);
2031}
2032
2033/// GetSelector - Return the pointer to the unique'd string for this selector.
2034llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2035 return EmitSelector(CGF, Sel);
2036}
2037Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2038 return EmitSelectorAddr(Sel);
2039}
2040llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2041 const ObjCMethodDecl *Method) {
2042 return EmitSelector(CGF, Method->getSelector());
2043}
2044
2045llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2046 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
2047 return CGM.GetAddrOfRTTIDescriptor(
2048 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
2049 }
2050 if (T->isObjCClassType() || T->isObjCQualifiedClassType()) {
2051 return CGM.GetAddrOfRTTIDescriptor(
2052 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
2053 }
2054 if (T->isObjCObjectPointerType())
2055 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
2056
2057 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
2058}
2059
2060/// Generate a constant CFString object.
2061/*
2062 struct __builtin_CFString {
2063 const int *isa; // point to __CFConstantStringClassReference
2064 int flags;
2065 const char *str;
2066 long length;
2067 };
2068*/
2069
2070/// or Generate a constant NSString object.
2071/*
2072 struct __builtin_NSString {
2073 const int *isa; // point to __NSConstantStringClassReference
2074 const char *str;
2075 unsigned int length;
2076 };
2077*/
2078
2079ConstantAddress
2080CGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {
2081 return (!CGM.getLangOpts().NoConstantCFStrings
2083 : GenerateConstantNSString(SL));
2084}
2085
2086ConstantAddress CGObjCCommonMac::GenerateConstantNumber(const bool Value,
2087 const QualType &Ty) {
2088 return GenerateConstantNSNumber(Value, Ty);
2089}
2090
2091ConstantAddress
2092CGObjCCommonMac::GenerateConstantNumber(const llvm::APSInt &Value,
2093 const QualType &Ty) {
2094 return GenerateConstantNSNumber(Value, Ty);
2095}
2096
2097ConstantAddress
2098CGObjCCommonMac::GenerateConstantNumber(const llvm::APFloat &Value,
2099 const QualType &Ty) {
2100 return GenerateConstantNSNumber(Value, Ty);
2101}
2102
2103ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2104 const ArrayRef<llvm::Constant *> &Objects) {
2105 return GenerateConstantNSArray(Objects);
2106}
2107
2108ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2109 const ObjCDictionaryLiteral *E,
2110 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2111 return GenerateConstantNSDictionary(E, KeysAndObjects);
2112}
2113
2114static llvm::StringMapEntry<llvm::GlobalVariable *> &
2115GetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
2116 const StringLiteral *Literal, unsigned &StringLength) {
2117 StringRef String = Literal->getString();
2118 StringLength = String.size();
2119 return *Map.insert(std::make_pair(String, nullptr)).first;
2120}
2121
2122llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2123 if (llvm::Value *V = ConstantStringClassRef)
2124 return cast<llvm::Constant>(V);
2125
2126 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2127 std::string str = StringClass.empty() ? "_NSConstantStringClassReference"
2128 : "_" + StringClass + "ClassReference";
2129
2130 llvm::Type *PTy = llvm::ArrayType::get(CGM.IntTy, 0);
2131 auto GV = CGM.CreateRuntimeVariable(PTy, str);
2132 ConstantStringClassRef = GV;
2133 return GV;
2134}
2135
2136llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2137 llvm_unreachable("constant array literals not supported for fragile ABI");
2138}
2139
2140llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2141 llvm_unreachable("constant dictionary literals not supported for fragile "
2142 "ABI");
2143}
2144
2145llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2146 llvm_unreachable("constant number literals not supported for fragile ABI");
2147}
2148
2149llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2150 llvm_unreachable("constant number literals not supported for fragile ABI");
2151}
2152
2153llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2154 llvm_unreachable("constant number literals not supported for fragile ABI");
2155}
2156
2157llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2158 if (llvm::Value *V = ConstantStringClassRef)
2159 return cast<llvm::Constant>(V);
2160
2161 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2162 std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
2163 : "OBJC_CLASS_$_" + StringClass;
2164 llvm::Constant *GV = GetClassGlobal(str, NotForDefinition);
2165 ConstantStringClassRef = GV;
2166 return GV;
2167}
2168
2169llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2170 if (llvm::Value *V = ConstantArrayClassRef)
2171 return cast<llvm::Constant>(V);
2172
2173 const std::string &ArrayClass = CGM.getLangOpts().ObjCConstantArrayClass;
2174 std::string Str = ArrayClass.empty() ? "OBJC_CLASS_$_NSConstantArray"
2175 : "OBJC_CLASS_$_" + ArrayClass;
2176 llvm::Constant *GV = GetClassGlobal(Str, NotForDefinition);
2177
2178 ConstantArrayClassRef = GV;
2179 return GV;
2180}
2181
2182llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2183 if (llvm::Value *V = ConstantDictionaryClassRef)
2184 return cast<llvm::Constant>(V);
2185
2186 const std::string &DictionaryClass =
2188 std::string Str = DictionaryClass.empty()
2189 ? "OBJC_CLASS_$_NSConstantDictionary"
2190 : "OBJC_CLASS_$_" + DictionaryClass;
2191 llvm::Constant *GV = GetClassGlobal(Str, NotForDefinition);
2192
2193 ConstantDictionaryClassRef = GV;
2194 return GV;
2195}
2196
2197llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2198 if (llvm::Value *V = ConstantIntegerNumberClassRef)
2199 return cast<llvm::Constant>(V);
2200
2201 const std::string &NumberClass =
2203 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantIntegerNumber"
2204 : "OBJC_CLASS_$_" + NumberClass;
2205 llvm::Constant *GV = GetClassGlobal(Str, NotForDefinition);
2206
2207 ConstantIntegerNumberClassRef = GV;
2208 return GV;
2209}
2210
2211llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2212 if (llvm::Value *V = ConstantFloatNumberClassRef)
2213 return cast<llvm::Constant>(V);
2214
2215 const std::string &NumberClass =
2217 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantFloatNumber"
2218 : "OBJC_CLASS_$_" + NumberClass;
2219 llvm::Constant *GV = GetClassGlobal(Str, NotForDefinition);
2220
2221 ConstantFloatNumberClassRef = GV;
2222 return GV;
2223}
2224
2225llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2226 if (llvm::Value *V = ConstantDoubleNumberClassRef)
2227 return cast<llvm::Constant>(V);
2228
2229 const std::string &NumberClass =
2231 std::string Str = NumberClass.empty() ? "OBJC_CLASS_$_NSConstantDoubleNumber"
2232 : "OBJC_CLASS_$_" + NumberClass;
2233 llvm::Constant *GV = GetClassGlobal(Str, NotForDefinition);
2234
2235 ConstantDoubleNumberClassRef = GV;
2236 return GV;
2237}
2238
2239ConstantAddress
2240CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {
2241 unsigned StringLength = 0;
2242 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2243 GetConstantStringEntry(NSConstantStringMap, Literal, StringLength);
2244
2245 if (auto *C = Entry.second)
2246 return ConstantAddress(C, C->getValueType(),
2247 CharUnits::fromQuantity(C->getAlignment()));
2248
2249 // If we don't already have it, get _NSConstantStringClassReference.
2250 llvm::Constant *Class = getNSConstantStringClassRef();
2251
2252 // If we don't already have it, construct the type for a constant NSString.
2253 if (!NSConstantStringType) {
2254 // NOTE: The existing implementation used a pointer to a Int32Ty not a
2255 // struct pointer as the ISA type when emitting constant strings so this is
2256 // maintained for now.
2257 NSConstantStringType =
2258 llvm::StructType::create({CGM.DefaultPtrTy, CGM.Int8PtrTy, CGM.IntTy},
2259 "struct.__builtin_NSString");
2260 }
2261
2262 ConstantInitBuilder Builder(CGM);
2263 auto Fields = Builder.beginStruct(NSConstantStringType);
2264
2265 // Class pointer.
2266 Fields.addSignedPointer(Class,
2268 GlobalDecl(), QualType());
2269
2270 // String pointer.
2271 llvm::Constant *C =
2272 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2273
2274 llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;
2275 bool isConstant = !CGM.getLangOpts().WritableStrings;
2276
2277 auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
2278 Linkage, C, ".str");
2279 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2280 // Don't enforce the target's minimum global alignment, since the only use
2281 // of the string is via this class initializer.
2282 GV->setAlignment(llvm::Align(1));
2283 Fields.add(GV);
2284
2285 // String length.
2286 Fields.addInt(CGM.IntTy, StringLength);
2287
2288 // The struct.
2289 CharUnits Alignment = CGM.getPointerAlign();
2290 GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment,
2291 /*constant*/ true,
2292 llvm::GlobalVariable::PrivateLinkage);
2293 const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
2294 const char *NSStringNonFragileABISection =
2295 "__DATA,__objc_stringobj,regular,no_dead_strip";
2296 // FIXME. Fix section.
2297 GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
2298 ? NSStringNonFragileABISection
2299 : NSStringSection);
2300 Entry.second = GV;
2301
2302 return ConstantAddress(GV, GV->getValueType(), Alignment);
2303}
2304
2305/// Emit the boolean singletons for BOOL literals @YES and @NO.
2306ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(const bool Value,
2307 const QualType &Ty) {
2308 llvm::GlobalVariable *Val =
2309 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2310 return ConstantAddress(Val, Val->getValueType(), CGM.getPointerAlign());
2311}
2312
2313/// Generate a constant NSConstantIntegerNumber from an ObjC integer literal,
2314/// e.g., @2.
2315/*
2316 struct __builtin_NSConstantIntegerNumber {
2317 struct._class_t *isa; // point to _NSConstantIntegerNumberClassReference
2318 char const *const _encoding;
2319 long long const _value;
2320 };
2321*/
2322ConstantAddress
2323CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APSInt &Value,
2324 const QualType &Ty) {
2325 CharUnits Alignment = CGM.getPointerAlign();
2326
2327 // Check if we've already emitted, if so emit a reference to it.
2328 llvm::GlobalVariable *&Entry =
2329 NSConstantNumberMap[{CGM.getContext().getCanonicalType(Ty), Value}];
2330 if (Entry) {
2331 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2332 }
2333
2334 // The encoding type.
2335 std::string ObjCEncodingType;
2336 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2337 ObjCEncodingType);
2338
2339 llvm::Constant *const Class = getNSConstantIntegerNumberClassRef();
2340
2341 if (!NSConstantIntegerNumberType) {
2342 NSConstantIntegerNumberType = llvm::StructType::create(
2343 {
2344 CGM.DefaultPtrTy, // isa
2345 CGM.Int8PtrTy, // _encoding
2346 CGM.Int64Ty, // _value
2347 },
2348 "struct.__builtin_NSConstantIntegerNumber");
2349 }
2350
2351 ConstantInitBuilder Builder(CGM);
2352 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2353
2354 // Class pointer.
2355 Fields.addSignedPointer(Class,
2357 GlobalDecl(), QualType());
2358
2359 // add the @encode.
2360 Fields.add(CGM.GetAddrOfConstantCString(ObjCEncodingType).getPointer());
2361
2362 // add the value stored.
2363 llvm::Constant *IntegerValue =
2364 llvm::ConstantInt::get(CGM.Int64Ty, Value.extOrTrunc(64));
2365
2366 Fields.add(IntegerValue);
2367
2368 // The struct.
2369 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2370 "_unnamed_nsconstantintegernumber_", Alignment,
2371 /* constant */ true, llvm::GlobalVariable::PrivateLinkage);
2372
2373 GV->setSection(GetNSConstantIntegerNumberSectionName());
2374 GV->addAttribute("objc_arc_inert");
2375
2376 Entry = GV;
2377
2378 return ConstantAddress(GV, GV->getValueType(), Alignment);
2379}
2380
2381/// Generate either a constant NSConstantFloatNumber or NSConstantDoubleNumber
2382/// from an ObjC literal based on it's encoding. @(2.2f) would be
2383/// NSConstantFloatNumber. @(2.222) would be NSConstantDoubleNumber.
2384/*
2385 struct __builtin_NSConstantFloatNumber {
2386 struct._class_t *isa; // point to _NSConstantFloatNumberClassReference
2387 float const _value;
2388 };
2389
2390 struct __builtin_NSConstantDoubleNumber {
2391 struct._class_t *isa; // point to _NSConstantDoubleNumberClassReference
2392 double const _value;
2393 };
2394*/
2395ConstantAddress
2396CGObjCCommonMac::GenerateConstantNSNumber(const llvm::APFloat &Value,
2397 const QualType &Ty) {
2398 CharUnits Alignment = CGM.getPointerAlign();
2399
2400 // Check if we've already emitted, if so emit a reference to it.
2401 llvm::GlobalVariable *&Entry =
2402 NSConstantNumberMap[{CGM.getContext().getCanonicalType(Ty), Value}];
2403 if (Entry) {
2404 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2405 }
2406
2407 // @encode type used to pick which class type to use.
2408 std::string ObjCEncodingType;
2409 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2410 ObjCEncodingType);
2411
2412 assert((ObjCEncodingType == "d" || ObjCEncodingType == "f") &&
2413 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2414
2415 llvm::GlobalValue::LinkageTypes Linkage =
2416 llvm::GlobalVariable::PrivateLinkage;
2417
2418 // Handle floats.
2419 if (ObjCEncodingType == "f") {
2420 llvm::Constant *const Class = getNSConstantFloatNumberClassRef();
2421
2422 if (!NSConstantFloatNumberType) {
2423 NSConstantFloatNumberType = llvm::StructType::create(
2424 {
2425 CGM.DefaultPtrTy, // isa
2426 CGM.FloatTy, // _value
2427 },
2428 "struct.__builtin_NSConstantFloatNumber");
2429 }
2430
2431 ConstantInitBuilder Builder(CGM);
2432 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2433
2434 // Class pointer.
2435 Fields.addSignedPointer(Class,
2437 GlobalDecl(), QualType());
2438
2439 // add the value stored.
2440 llvm::Constant *FV = llvm::ConstantFP::get(CGM.FloatTy, Value);
2441 Fields.add(FV);
2442
2443 // The struct.
2444 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2445 "_unnamed_nsconstantfloatnumber_", Alignment,
2446 /*constant*/ true, Linkage);
2447
2448 GV->setSection(GetNSConstantFloatNumberSectionName());
2449 GV->addAttribute("objc_arc_inert");
2450
2451 Entry = GV;
2452
2453 return ConstantAddress(GV, GV->getValueType(), Alignment);
2454 }
2455
2456 llvm::Constant *const Class = getNSConstantDoubleNumberClassRef();
2457 if (!NSConstantDoubleNumberType) {
2458 // NOTE: this will be padded on some 32-bit targets and is expected.
2459 NSConstantDoubleNumberType = llvm::StructType::create(
2460 {
2461 CGM.DefaultPtrTy, // isa
2462 CGM.DoubleTy, // _value
2463 },
2464 "struct.__builtin_NSConstantDoubleNumber");
2465 }
2466
2467 ConstantInitBuilder Builder(CGM);
2468 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2469
2470 // Class pointer.
2471 Fields.addSignedPointer(Class,
2473 GlobalDecl(), QualType());
2474
2475 // add the value stored.
2476 llvm::Constant *DV = llvm::ConstantFP::get(CGM.DoubleTy, Value);
2477 Fields.add(DV);
2478
2479 // The struct.
2480 llvm::GlobalVariable *const GV = Fields.finishAndCreateGlobal(
2481 "_unnamed_nsconstantdoublenumber_", Alignment,
2482 /*constant*/ true, Linkage);
2483
2484 GV->setSection(GetNSConstantDoubleNumberSectionName());
2485 GV->addAttribute("objc_arc_inert");
2486
2487 Entry = GV;
2488
2489 return ConstantAddress(GV, GV->getValueType(), Alignment);
2490}
2491
2492/// Shared private method to emit the id array storage for constant NSArray and
2493/// NSDictionary literals as they share the same sections and behavior.
2494llvm::GlobalVariable *
2495CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2496 const ArrayRef<llvm::Constant *> &Elements) {
2497 llvm::Type *ElementsTy = Elements[0]->getType();
2498 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2499
2500 llvm::Constant *const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2501
2502 llvm::GlobalVariable *ObjectsGV = new llvm::GlobalVariable(
2503 CGM.getModule(), ArrayTy, true, llvm::GlobalValue::InternalLinkage,
2504 ArrayData, "_unnamed_array_storage");
2505
2506 ObjectsGV->setAlignment(CGM.getPointerAlign().getAsAlign());
2507 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2508 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2509 return ObjectsGV;
2510}
2511
2512/// Generate a constant NSConstantArray from an ObjC array literal,
2513/// e.g., @[ @2 ] or the singleton for an empty `__NSArray0__struct`.
2514/*
2515 struct __builtin_NSArray {
2516 struct._class_t *isa; // points to _NSConstantArrayClassReference
2517 NSUInteger const _count;
2518 id const *const _objects;
2519 };
2520*/
2521ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2522 const ArrayRef<llvm::Constant *> &Objects) {
2523 CharUnits Alignment = CGM.getPointerAlign();
2524
2525 if (Objects.size() == 0) {
2526 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2527 return ConstantAddress(GV, GV->getValueType(), Alignment);
2528 }
2529
2530 ASTContext &Context = CGM.getContext();
2531 CodeGenTypes &Types = CGM.getTypes();
2532 llvm::Constant *const Class = getNSConstantArrayClassRef();
2533 llvm::Type *const NSUIntegerTy =
2534 Types.ConvertType(Context.getNSUIntegerType());
2535
2536 if (!NSConstantArrayType) {
2537 NSConstantArrayType = llvm::StructType::create(
2538 {
2539 CGM.DefaultPtrTy, // isa
2540 NSUIntegerTy, // _count
2541 CGM.DefaultPtrTy, // _objects
2542 },
2543 "struct.__builtin_NSArray");
2544 }
2545
2546 ConstantInitBuilder Builder(CGM);
2547 auto Fields = Builder.beginStruct(NSConstantArrayType);
2548
2549 // Class pointer.
2550 Fields.addSignedPointer(Class,
2552 GlobalDecl(), QualType());
2553
2554 // count.
2555 uint64_t ObjectCount = Objects.size();
2556 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2557 Fields.add(Count);
2558
2559 // objects.
2560 llvm::GlobalVariable *ObjectsGV =
2561 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2562 Fields.add(ObjectsGV);
2563
2564 // The struct.
2565 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2566 "_unnamed_nsarray_", Alignment,
2567 /* constant */ true, llvm::GlobalValue::PrivateLinkage);
2568
2569 GV->setSection(GetNSConstantArraySectionName());
2570 GV->addAttribute("objc_arc_inert");
2571
2572 return ConstantAddress(GV, GV->getValueType(), Alignment);
2573}
2574
2575/// Generate a constant NSConstantDictionary from an ObjC dictionary literal
2576/// with string keys, e.g., @{ @"someNum" : @2 } or the singleton for an empty
2577/// `__NSDictionary0__struct`.
2578/*
2579 struct __builtin_NSDictionary {
2580 struct._class_t *isa; // point to _NSConstantDictionaryClassReference
2581 NSUInteger const _hashOptions;
2582 NSUInteger const _count;
2583 id const *const _keys;
2584 id const *const _objects;
2585 };
2586 */
2587ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2588 const ObjCDictionaryLiteral *E,
2589 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2590 CharUnits Alignment = CGM.getPointerAlign();
2591
2592 if (KeysAndObjects.size() == 0) {
2593 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2594 return ConstantAddress(GV, GV->getValueType(), Alignment);
2595 }
2596
2597 ASTContext &Context = CGM.getContext();
2598 CodeGenTypes &Types = CGM.getTypes();
2599 llvm::Constant *const Class = getNSConstantDictionaryClassRef();
2600
2601 llvm::Type *const NSUIntegerTy =
2602 Types.ConvertType(Context.getNSUIntegerType());
2603
2604 if (!NSConstantDictionaryType) {
2605 NSConstantDictionaryType = llvm::StructType::create(
2606 {
2607 CGM.DefaultPtrTy, // isa
2608 NSUIntegerTy, // _hashOptions
2609 NSUIntegerTy, // _count
2610 CGM.DefaultPtrTy, // _keys
2611 CGM.DefaultPtrTy, // _objects
2612 },
2613 "struct.__builtin_NSDictionary");
2614 }
2615
2616 ConstantInitBuilder Builder(CGM);
2617 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2618
2619 // Class pointer.
2620 Fields.addSignedPointer(Class,
2622 GlobalDecl(), QualType());
2623
2624 // Use the hashing helper to manage the keys and sorting.
2625 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2626 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2627
2628 // Ask `HashBuilder` for the fully sorted keys / values and the count.
2629 uint64_t const NumElements = DictBuilder.getNumElements();
2630
2631 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2632 NSUIntegerTy, static_cast<uint64_t>(DictBuilder.getOptions()));
2633 Fields.add(OptionsConstant);
2634
2635 // count.
2636 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2637 Fields.add(Count);
2638
2639 // Split sorted pairs into separate keys and objects arrays for storage.
2640 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2641 SortedKeys.reserve(NumElements);
2642 SortedObjects.reserve(NumElements);
2643 for (auto &[Key, Obj] : DictBuilder.getElements()) {
2644 SortedKeys.push_back(Key);
2645 SortedObjects.push_back(Obj);
2646 }
2647
2648 // keys.
2649 llvm::GlobalVariable *KeysGV =
2650 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2651 Fields.add(KeysGV);
2652
2653 // objects.
2654 llvm::GlobalVariable *ObjectsGV =
2655 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2656 Fields.add(ObjectsGV);
2657
2658 // The struct.
2659 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2660 "_unnamed_nsdictionary_", Alignment,
2661 /* constant */ true, llvm::GlobalValue::PrivateLinkage);
2662
2663 GV->setSection(GetNSConstantDictionarySectionName());
2664 GV->addAttribute("objc_arc_inert");
2665
2666 return ConstantAddress(GV, GV->getValueType(), Alignment);
2667}
2668
2669enum { kCFTaggedObjectID_Integer = (1 << 1) + 1 };
2670
2671/// Generates a message send where the super is the receiver. This is
2672/// a message send to self with special delivery semantics indicating
2673/// which class's method should be called.
2674CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2675 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2676 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
2677 llvm::Value *Receiver, bool IsClassMessage,
2678 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
2679 // Create and init a super structure; this is a (receiver, class)
2680 // pair we will pass to objc_msgSendSuper.
2681 RawAddress ObjCSuper = CGF.CreateTempAlloca(
2682 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super");
2683 llvm::Value *ReceiverAsObject =
2684 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2685 CGF.Builder.CreateStore(ReceiverAsObject,
2686 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
2687
2688 // If this is a class message the metaclass is passed as the target.
2689 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2690 llvm::Value *Target;
2691 if (IsClassMessage) {
2692 if (isCategoryImpl) {
2693 // Message sent to 'super' in a class method defined in a category
2694 // implementation requires an odd treatment.
2695 // If we are in a class method, we must retrieve the
2696 // _metaclass_ for the current class, pointed at by
2697 // the class's "isa" pointer. The following assumes that
2698 // isa" is the first ivar in a class (which it must be).
2699 Target = EmitClassRef(CGF, Class->getSuperClass());
2700 Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
2701 Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, Target,
2702 CGF.getPointerAlign());
2703 } else {
2704 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2705 llvm::Value *SuperPtr =
2706 CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
2707 llvm::Value *Super = CGF.Builder.CreateAlignedLoad(ClassTyPtr, SuperPtr,
2708 CGF.getPointerAlign());
2709 Target = Super;
2710 }
2711 } else if (isCategoryImpl)
2712 Target = EmitClassRef(CGF, Class->getSuperClass());
2713 else {
2714 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
2715 ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
2716 Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, ClassPtr,
2717 CGF.getPointerAlign());
2718 }
2719 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
2720 // ObjCTypes types.
2721 llvm::Type *ClassTy =
2723 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
2724 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
2725 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
2726 ObjCTypes.SuperPtrCTy, true, CallArgs, Method, Class,
2727 ObjCTypes);
2728}
2729
2730/// Generate code for a message send expression.
2731CodeGen::RValue CGObjCMac::GenerateMessageSend(
2732 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2733 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
2734 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
2735 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2736 CGF.getContext().getObjCIdType(), false, CallArgs,
2737 Method, Class, ObjCTypes);
2738}
2739
2740CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2741 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2742 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper,
2743 const CallArgList &CallArgs, const ObjCMethodDecl *Method,
2744 const ObjCInterfaceDecl *ClassReceiver,
2745 const ObjCCommonTypesHelper &ObjCTypes) {
2746 CodeGenTypes &Types = CGM.getTypes();
2747 auto selTy = CGF.getContext().getObjCSelType();
2748 llvm::Value *ReceiverValue =
2749 llvm::PoisonValue::get(Types.ConvertType(Arg0Ty));
2750 llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));
2751
2752 CallArgList ActualArgs;
2753 if (!IsSuper)
2754 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2755 ActualArgs.add(RValue::get(ReceiverValue), Arg0Ty);
2756 if (!Method || !Method->isDirectMethod())
2757 ActualArgs.add(RValue::get(SelValue), selTy);
2758 ActualArgs.addFrom(CallArgs);
2759
2760 // If we're calling a method, use the formal signature.
2761 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2762
2763 if (Method)
2764 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
2765 CGM.getContext().getCanonicalType(ResultType) &&
2766 "Result type mismatch!");
2767
2768 bool ReceiverCanBeNull =
2769 canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0);
2770 bool ClassObjectCanBeUnrealized =
2771 Method && Method->isClassMethod() &&
2772 canClassObjectBeUnrealized(ClassReceiver, CGF);
2773
2774 bool RequiresNullCheck = false;
2775 bool RequiresReceiverValue = true;
2776 bool RequiresSelValue = true;
2777
2778 llvm::FunctionCallee Fn = nullptr;
2779 if (Method && Method->isDirectMethod()) {
2780 assert(!IsSuper);
2781 Fn = GetDirectMethodCallee(Method, Method->getClassInterface(),
2782 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2783 // Direct methods will synthesize the proper `_cmd` internally,
2784 // so just don't bother with setting the `_cmd` argument.
2785 RequiresSelValue = false;
2786 } else if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
2787 if (ReceiverCanBeNull)
2788 RequiresNullCheck = true;
2789 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2790 : ObjCTypes.getSendStretFn(IsSuper);
2791 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2792 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2793 : ObjCTypes.getSendFpretFn(IsSuper);
2794 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2795 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2796 : ObjCTypes.getSendFp2retFn(IsSuper);
2797 } else {
2798 // arm64 uses objc_msgSend for stret methods and yet null receiver check
2799 // must be made for it.
2800 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
2801 RequiresNullCheck = true;
2802 // The class name that's used to create the class msgSend stub declaration.
2803 StringRef ClassName;
2804
2805 // We cannot use class msgSend stubs in the following cases:
2806 // 1. The class is annotated with `objc_class_stub` or
2807 // `objc_runtime_visible`.
2808 // 2. The selector name contains a '$'.
2809 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2810 Method && Method->isClassMethod() &&
2811 !ClassReceiver->hasAttr<ObjCClassStubAttr>() &&
2812 !ClassReceiver->hasAttr<ObjCRuntimeVisibleAttr>() &&
2813 Sel.getAsString().find('$') == std::string::npos)
2814 ClassName = ClassReceiver->getObjCRuntimeNameAsString();
2815
2816 bool UseClassStub = ClassName.data();
2817 // Try to use a selector stub declaration instead of objc_msgSend.
2818 if (!IsSuper &&
2819 (CGM.getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2820 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2821 // Selector stubs synthesize `_cmd` in the stub, so we don't have to.
2822 RequiresReceiverValue = !UseClassStub;
2823 RequiresSelValue = false;
2824 } else {
2825 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2826 : ObjCTypes.getSendFn(IsSuper);
2827 }
2828 }
2829
2830 // Cast function to proper signature
2831 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2832 CGF.Builder.CreateBitCast(Fn.getCallee(), MSI.MessengerType));
2833
2834 // We don't need to emit a null check to zero out an indirect result if the
2835 // result is ignored.
2836 if (Return.isUnused())
2837 RequiresNullCheck = false;
2838
2839 // Emit a null-check if there's a consumed argument other than the receiver.
2840 if (!RequiresNullCheck && Method && Method->hasParamDestroyedInCallee())
2841 RequiresNullCheck = true;
2842
2844 // For variadic class methods, we need to inline precondition checks. That
2845 // include two things:
2846 // 1. We have to inline the class realization if we are not sure if it must
2847 // have been realized.
2848 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2849 // Perform class realization using the helper function
2850 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2851 ActualArgs[0] = CallArg(RValue::get(Arg0), ActualArgs[0].Ty);
2852 }
2853 // 2. We have to inline the precondition thunk if we are not sure if the
2854 // receiver can be null. Luckly, `NullReturnState` already does that for
2855 // corner cases like ns_consume, so we only need to override the flag,
2856 // regardless if the return value is unused.
2857 RequiresNullCheck |= ReceiverCanBeNull;
2858 }
2859
2860 NullReturnState nullReturn;
2861 if (RequiresNullCheck) {
2862 nullReturn.init(CGF, Arg0);
2863 }
2864
2865 // Pass the receiver value if it's needed.
2866 if (RequiresReceiverValue)
2867 ActualArgs[0] = CallArg(RValue::get(Arg0), Arg0Ty);
2868
2869 // If a selector value needs to be passed, emit the load before the call.
2870 if (RequiresSelValue) {
2871 SelValue = GetSelector(CGF, Sel);
2872 ActualArgs[1] = CallArg(RValue::get(SelValue), selTy);
2873 }
2874
2875 llvm::CallBase *CallSite;
2876 CGCallee Callee = CGCallee::forDirect(BitcastFn);
2877 RValue rvalue =
2878 CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2879
2880 // Mark the call as noreturn if the method is marked noreturn and the
2881 // receiver cannot be null.
2882 if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2883 CallSite->setDoesNotReturn();
2884 }
2885
2886 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2887 RequiresNullCheck ? Method : nullptr);
2888}
2889
2891 bool pointee = false) {
2892 // Note that GC qualification applies recursively to C pointer types
2893 // that aren't otherwise decorated. This is weird, but it's probably
2894 // an intentional workaround to the unreliable placement of GC qualifiers.
2895 if (FQT.isObjCGCStrong())
2896 return Qualifiers::Strong;
2897
2898 if (FQT.isObjCGCWeak())
2899 return Qualifiers::Weak;
2900
2901 if (auto ownership = FQT.getObjCLifetime()) {
2902 // Ownership does not apply recursively to C pointer types.
2903 if (pointee)
2904 return Qualifiers::GCNone;
2905 switch (ownership) {
2907 return Qualifiers::Weak;
2909 return Qualifiers::Strong;
2911 return Qualifiers::GCNone;
2913 llvm_unreachable("autoreleasing ivar?");
2915 llvm_unreachable("known nonzero");
2916 }
2917 llvm_unreachable("bad objc ownership");
2918 }
2919
2920 // Treat unqualified retainable pointers as strong.
2921 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2922 return Qualifiers::Strong;
2923
2924 // Walk into C pointer types, but only in GC.
2925 if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
2926 if (const PointerType *PT = FQT->getAs<PointerType>())
2927 return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true);
2928 }
2929
2930 return Qualifiers::GCNone;
2931}
2932
2933namespace {
2934struct IvarInfo {
2935 CharUnits Offset;
2936 uint64_t SizeInWords;
2937 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2938 : Offset(offset), SizeInWords(sizeInWords) {}
2939
2940 // Allow sorting based on byte pos.
2941 bool operator<(const IvarInfo &other) const { return Offset < other.Offset; }
2942};
2943
2944/// A helper class for building GC layout strings.
2945class IvarLayoutBuilder {
2946 CodeGenModule &CGM;
2947
2948 /// The start of the layout. Offsets will be relative to this value,
2949 /// and entries less than this value will be silently discarded.
2950 CharUnits InstanceBegin;
2951
2952 /// The end of the layout. Offsets will never exceed this value.
2953 CharUnits InstanceEnd;
2954
2955 /// Whether we're generating the strong layout or the weak layout.
2956 bool ForStrongLayout;
2957
2958 /// Whether the offsets in IvarsInfo might be out-of-order.
2959 bool IsDisordered = false;
2960
2961 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2962
2963public:
2964 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2965 CharUnits instanceEnd, bool forStrongLayout)
2966 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2967 ForStrongLayout(forStrongLayout) {}
2968
2969 void visitRecord(const RecordType *RT, CharUnits offset);
2970
2971 template <class Iterator, class GetOffsetFn>
2972 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2973 const GetOffsetFn &getOffset);
2974
2975 void visitField(const FieldDecl *field, CharUnits offset);
2976
2977 /// Add the layout of a block implementation.
2978 void visitBlock(const CGBlockInfo &blockInfo);
2979
2980 /// Is there any information for an interesting bitmap?
2981 bool hasBitmapData() const { return !IvarsInfo.empty(); }
2982
2983 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2984 llvm::SmallVectorImpl<unsigned char> &buffer);
2985
2986 static void dump(ArrayRef<unsigned char> buffer) {
2987 const unsigned char *s = buffer.data();
2988 for (unsigned i = 0, e = buffer.size(); i < e; i++)
2989 if (!(s[i] & 0xf0))
2990 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2991 else
2992 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
2993 printf("\n");
2994 }
2995};
2996} // end anonymous namespace
2997
2998llvm::Constant *
2999CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
3000 const CGBlockInfo &blockInfo) {
3001
3002 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
3003 if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
3004 return nullPtr;
3005
3006 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
3007 /*for strong layout*/ true);
3008
3009 builder.visitBlock(blockInfo);
3010
3011 if (!builder.hasBitmapData())
3012 return nullPtr;
3013
3014 llvm::SmallVector<unsigned char, 32> buffer;
3015 llvm::Constant *C = builder.buildBitmap(*this, buffer);
3016 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3017 printf("\n block variable layout for block: ");
3018 builder.dump(buffer);
3019 }
3020
3021 return C;
3022}
3023
3024void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
3025 // __isa is the first field in block descriptor and must assume by runtime's
3026 // convention that it is GC'able.
3027 IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
3028
3029 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3030
3031 // Ignore the optional 'this' capture: C++ objects are not assumed
3032 // to be GC'ed.
3033
3034 CharUnits lastFieldOffset;
3035
3036 // Walk the captured variables.
3037 for (const auto &CI : blockDecl->captures()) {
3038 const VarDecl *variable = CI.getVariable();
3039 QualType type = variable->getType();
3040
3041 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
3042
3043 // Ignore constant captures.
3044 if (capture.isConstant())
3045 continue;
3046
3047 CharUnits fieldOffset = capture.getOffset();
3048
3049 // Block fields are not necessarily ordered; if we detect that we're
3050 // adding them out-of-order, make sure we sort later.
3051 if (fieldOffset < lastFieldOffset)
3052 IsDisordered = true;
3053 lastFieldOffset = fieldOffset;
3054
3055 // __block variables are passed by their descriptor address.
3056 if (CI.isByRef()) {
3057 IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
3058 continue;
3059 }
3060
3061 assert(!type->isArrayType() && "array variable should not be caught");
3062 if (const RecordType *record = type->getAsCanonical<RecordType>()) {
3063 visitRecord(record, fieldOffset);
3064 continue;
3065 }
3066
3068
3069 if (GCAttr == Qualifiers::Strong) {
3070 assert(CGM.getContext().getTypeSize(type) ==
3071 CGM.getTarget().getPointerWidth(LangAS::Default));
3072 IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
3073 }
3074 }
3075}
3076
3077/// getBlockCaptureLifetime - This routine returns life time of the captured
3078/// block variable for the purpose of block layout meta-data generation. FQT is
3079/// the type of the variable captured in the block.
3081CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT, bool ByrefLayout) {
3082 // If it has an ownership qualifier, we're done.
3083 if (auto lifetime = FQT.getObjCLifetime())
3084 return lifetime;
3085
3086 // If it doesn't, and this is ARC, it has no ownership.
3087 if (CGM.getLangOpts().ObjCAutoRefCount)
3088 return Qualifiers::OCL_None;
3089
3090 // In MRC, retainable pointers are owned by non-__block variables.
3091 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
3093
3094 return Qualifiers::OCL_None;
3095}
3096
3097void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
3098 Qualifiers::ObjCLifetime LifeTime,
3099 CharUnits FieldOffset,
3100 CharUnits FieldSize) {
3101 // __block variables are passed by their descriptor address.
3102 if (IsByref)
3103 RunSkipBlockVars.push_back(
3104 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3105 else if (LifeTime == Qualifiers::OCL_Strong)
3106 RunSkipBlockVars.push_back(
3107 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3108 else if (LifeTime == Qualifiers::OCL_Weak)
3109 RunSkipBlockVars.push_back(
3110 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3111 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
3112 RunSkipBlockVars.push_back(
3113 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3114 else
3115 RunSkipBlockVars.push_back(
3116 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3117}
3118
3119void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
3120 const RecordDecl *RD,
3121 ArrayRef<const FieldDecl *> RecFields,
3122 CharUnits BytePos, bool &HasUnion,
3123 bool ByrefLayout) {
3124 bool IsUnion = (RD && RD->isUnion());
3125 CharUnits MaxUnionSize = CharUnits::Zero();
3126 const FieldDecl *MaxField = nullptr;
3127 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
3128 CharUnits MaxFieldOffset = CharUnits::Zero();
3129 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
3130
3131 if (RecFields.empty())
3132 return;
3133 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3134
3135 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3136 const FieldDecl *Field = RecFields[i];
3137 // Note that 'i' here is actually the field index inside RD of Field,
3138 // although this dependency is hidden.
3139 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3140 CharUnits FieldOffset =
3142
3143 // Skip over unnamed or bitfields
3144 if (!Field->getIdentifier() || Field->isBitField()) {
3145 LastFieldBitfieldOrUnnamed = Field;
3146 LastBitfieldOrUnnamedOffset = FieldOffset;
3147 continue;
3148 }
3149
3150 LastFieldBitfieldOrUnnamed = nullptr;
3151 QualType FQT = Field->getType();
3152 if (FQT->isRecordType() || FQT->isUnionType()) {
3153 if (FQT->isUnionType())
3154 HasUnion = true;
3155
3156 BuildRCBlockVarRecordLayout(FQT->castAsCanonical<RecordType>(),
3157 BytePos + FieldOffset, HasUnion);
3158 continue;
3159 }
3160
3161 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3162 auto *CArray = cast<ConstantArrayType>(Array);
3163 uint64_t ElCount = CArray->getZExtSize();
3164 assert(CArray && "only array with known element size is supported");
3165 FQT = CArray->getElementType();
3166 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3167 auto *CArray = cast<ConstantArrayType>(Array);
3168 ElCount *= CArray->getZExtSize();
3169 FQT = CArray->getElementType();
3170 }
3171 if (FQT->isRecordType() && ElCount) {
3172 int OldIndex = RunSkipBlockVars.size() - 1;
3173 auto *RT = FQT->castAsCanonical<RecordType>();
3174 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3175
3176 // Replicate layout information for each array element. Note that
3177 // one element is already done.
3178 uint64_t ElIx = 1;
3179 for (int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3180 ElIx++) {
3181 CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
3182 for (int i = OldIndex + 1; i <= FirstIndex; ++i)
3183 RunSkipBlockVars.push_back(
3184 RUN_SKIP(RunSkipBlockVars[i].opcode,
3185 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3186 RunSkipBlockVars[i].block_var_size));
3187 }
3188 continue;
3189 }
3190 }
3191 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
3192 if (IsUnion) {
3193 CharUnits UnionIvarSize = FieldSize;
3194 if (UnionIvarSize > MaxUnionSize) {
3195 MaxUnionSize = UnionIvarSize;
3196 MaxField = Field;
3197 MaxFieldOffset = FieldOffset;
3198 }
3199 } else {
3200 UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(FQT, ByrefLayout),
3201 BytePos + FieldOffset, FieldSize);
3202 }
3203 }
3204
3205 if (LastFieldBitfieldOrUnnamed) {
3206 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3207 // Last field was a bitfield. Must update the info.
3208 uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue();
3209 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3210 ((BitFieldSize % ByteSizeInBits) != 0);
3211 CharUnits Size = CharUnits::fromQuantity(UnsSize);
3212 Size += LastBitfieldOrUnnamedOffset;
3213 UpdateRunSkipBlockVars(
3214 false,
3215 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
3216 ByrefLayout),
3217 BytePos + LastBitfieldOrUnnamedOffset, Size);
3218 } else {
3219 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&
3220 "Expected unnamed");
3221 // Last field was unnamed. Must update skip info.
3222 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(
3223 LastFieldBitfieldOrUnnamed->getType());
3224 UpdateRunSkipBlockVars(
3225 false,
3226 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
3227 ByrefLayout),
3228 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3229 }
3230 }
3231
3232 if (MaxField)
3233 UpdateRunSkipBlockVars(
3234 false, getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
3235 BytePos + MaxFieldOffset, MaxUnionSize);
3236}
3237
3238void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
3239 CharUnits BytePos,
3240 bool &HasUnion,
3241 bool ByrefLayout) {
3242 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
3243 SmallVector<const FieldDecl *, 16> Fields(RD->fields());
3244 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
3245 const llvm::StructLayout *RecLayout =
3246 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
3247
3248 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3249}
3250
3251/// InlineLayoutInstruction - This routine produce an inline instruction for the
3252/// block variable layout if it can. If not, it returns 0. Rules are as follow:
3253/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit
3254/// world, an inline layout of value 0x0000000000000xyz is interpreted as
3255/// follows: x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by y
3256/// captured object of BLOCK_LAYOUT_BYREF. Followed by z captured object of
3257/// BLOCK_LAYOUT_WEAK. If any of the above is missing, zero replaces it. For
3258/// example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no BLOCK_LAYOUT_BYREF
3259/// and no BLOCK_LAYOUT_WEAK objects are captured.
3260uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3261 SmallVectorImpl<unsigned char> &Layout) {
3262 uint64_t Result = 0;
3263 if (Layout.size() <= 3) {
3264 unsigned size = Layout.size();
3265 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3266 unsigned char inst;
3267 enum BLOCK_LAYOUT_OPCODE opcode;
3268 switch (size) {
3269 case 3:
3270 inst = Layout[0];
3271 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3272 if (opcode == BLOCK_LAYOUT_STRONG)
3273 strong_word_count = (inst & 0xF) + 1;
3274 else
3275 return 0;
3276 inst = Layout[1];
3277 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3278 if (opcode == BLOCK_LAYOUT_BYREF)
3279 byref_word_count = (inst & 0xF) + 1;
3280 else
3281 return 0;
3282 inst = Layout[2];
3283 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3284 if (opcode == BLOCK_LAYOUT_WEAK)
3285 weak_word_count = (inst & 0xF) + 1;
3286 else
3287 return 0;
3288 break;
3289
3290 case 2:
3291 inst = Layout[0];
3292 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3293 if (opcode == BLOCK_LAYOUT_STRONG) {
3294 strong_word_count = (inst & 0xF) + 1;
3295 inst = Layout[1];
3296 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3297 if (opcode == BLOCK_LAYOUT_BYREF)
3298 byref_word_count = (inst & 0xF) + 1;
3299 else if (opcode == BLOCK_LAYOUT_WEAK)
3300 weak_word_count = (inst & 0xF) + 1;
3301 else
3302 return 0;
3303 } else if (opcode == BLOCK_LAYOUT_BYREF) {
3304 byref_word_count = (inst & 0xF) + 1;
3305 inst = Layout[1];
3306 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3307 if (opcode == BLOCK_LAYOUT_WEAK)
3308 weak_word_count = (inst & 0xF) + 1;
3309 else
3310 return 0;
3311 } else
3312 return 0;
3313 break;
3314
3315 case 1:
3316 inst = Layout[0];
3317 opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3318 if (opcode == BLOCK_LAYOUT_STRONG)
3319 strong_word_count = (inst & 0xF) + 1;
3320 else if (opcode == BLOCK_LAYOUT_BYREF)
3321 byref_word_count = (inst & 0xF) + 1;
3322 else if (opcode == BLOCK_LAYOUT_WEAK)
3323 weak_word_count = (inst & 0xF) + 1;
3324 else
3325 return 0;
3326 break;
3327
3328 default:
3329 return 0;
3330 }
3331
3332 // Cannot inline when any of the word counts is 15. Because this is one less
3333 // than the actual work count (so 15 means 16 actual word counts),
3334 // and we can only display 0 thru 15 word counts.
3335 if (strong_word_count == 16 || byref_word_count == 16 ||
3336 weak_word_count == 16)
3337 return 0;
3338
3339 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3340 (weak_word_count != 0);
3341
3342 if (size == count) {
3343 if (strong_word_count)
3344 Result = strong_word_count;
3345 Result <<= 4;
3346 if (byref_word_count)
3347 Result += byref_word_count;
3348 Result <<= 4;
3349 if (weak_word_count)
3350 Result += weak_word_count;
3351 }
3352 }
3353 return Result;
3354}
3355
3356llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
3357 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
3358 if (RunSkipBlockVars.empty())
3359 return nullPtr;
3360 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(LangAS::Default);
3361 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3362 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3363
3364 // Sort on byte position; captures might not be allocated in order,
3365 // and unions can do funny things.
3366 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3367 SmallVector<unsigned char, 16> Layout;
3368
3369 unsigned size = RunSkipBlockVars.size();
3370 for (unsigned i = 0; i < size; i++) {
3371 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3372 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3373 CharUnits end_byte_pos = start_byte_pos;
3374 unsigned j = i + 1;
3375 while (j < size) {
3376 if (opcode == RunSkipBlockVars[j].opcode) {
3377 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3378 i++;
3379 } else
3380 break;
3381 }
3382 CharUnits size_in_bytes =
3383 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3384 if (j < size) {
3385 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3386 RunSkipBlockVars[j - 1].block_var_bytepos -
3387 RunSkipBlockVars[j - 1].block_var_size;
3388 size_in_bytes += gap;
3389 }
3390 CharUnits residue_in_bytes = CharUnits::Zero();
3391 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3392 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3393 size_in_bytes -= residue_in_bytes;
3394 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3395 }
3396
3397 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
3398 while (size_in_words >= 16) {
3399 // Note that value in imm. is one less that the actual
3400 // value. So, 0xf means 16 words follow!
3401 unsigned char inst = (opcode << 4) | 0xf;
3402 Layout.push_back(inst);
3403 size_in_words -= 16;
3404 }
3405 if (size_in_words > 0) {
3406 // Note that value in imm. is one less that the actual
3407 // value. So, we subtract 1 away!
3408 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3409 Layout.push_back(inst);
3410 }
3411 if (residue_in_bytes > CharUnits::Zero()) {
3412 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3413 (residue_in_bytes.getQuantity() - 1);
3414 Layout.push_back(inst);
3415 }
3416 }
3417
3418 while (!Layout.empty()) {
3419 unsigned char inst = Layout.back();
3420 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3421 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3422 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3423 Layout.pop_back();
3424 else
3425 break;
3426 }
3427
3428 uint64_t Result = InlineLayoutInstruction(Layout);
3429 if (Result != 0) {
3430 // Block variable layout instruction has been inlined.
3431 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3432 if (ComputeByrefLayout)
3433 printf("\n Inline BYREF variable layout: ");
3434 else
3435 printf("\n Inline block variable layout: ");
3436 printf("0x0%" PRIx64 "", Result);
3437 if (auto numStrong = (Result & 0xF00) >> 8)
3438 printf(", BL_STRONG:%d", (int)numStrong);
3439 if (auto numByref = (Result & 0x0F0) >> 4)
3440 printf(", BL_BYREF:%d", (int)numByref);
3441 if (auto numWeak = (Result & 0x00F) >> 0)
3442 printf(", BL_WEAK:%d", (int)numWeak);
3443 printf(", BL_OPERATOR:0\n");
3444 }
3445 return llvm::ConstantInt::get(CGM.IntPtrTy, Result);
3446 }
3447
3448 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3449 Layout.push_back(inst);
3450 std::string BitMap;
3451 for (unsigned char C : Layout)
3452 BitMap += C;
3453
3454 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
3455 if (ComputeByrefLayout)
3456 printf("\n Byref variable layout: ");
3457 else
3458 printf("\n Block variable layout: ");
3459 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
3460 unsigned char inst = BitMap[i];
3461 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3462 unsigned delta = 1;
3463 switch (opcode) {
3464 case BLOCK_LAYOUT_OPERATOR:
3465 printf("BL_OPERATOR:");
3466 delta = 0;
3467 break;
3468 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3469 printf("BL_NON_OBJECT_BYTES:");
3470 break;
3471 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3472 printf("BL_NON_OBJECT_WORD:");
3473 break;
3474 case BLOCK_LAYOUT_STRONG:
3475 printf("BL_STRONG:");
3476 break;
3477 case BLOCK_LAYOUT_BYREF:
3478 printf("BL_BYREF:");
3479 break;
3480 case BLOCK_LAYOUT_WEAK:
3481 printf("BL_WEAK:");
3482 break;
3483 case BLOCK_LAYOUT_UNRETAINED:
3484 printf("BL_UNRETAINED:");
3485 break;
3486 }
3487 // Actual value of word count is one more that what is in the imm.
3488 // field of the instruction
3489 printf("%d", (inst & 0xf) + delta);
3490 if (i < e - 1)
3491 printf(", ");
3492 else
3493 printf("\n");
3494 }
3495 }
3496
3497 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3498 /*ForceNonFragileABI=*/true,
3499 /*NullTerminate=*/false);
3500 return getConstantGEP(VMContext, Entry, 0, 0);
3501}
3502
3503static std::string getBlockLayoutInfoString(
3504 const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,
3505 bool HasCopyDisposeHelpers) {
3506 std::string Str;
3507 for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3508 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3509 // Copy/dispose helpers don't have any information about
3510 // __unsafe_unretained captures, so unconditionally concatenate a string.
3511 Str += "u";
3512 } else if (HasCopyDisposeHelpers) {
3513 // Information about __strong, __weak, or byref captures has already been
3514 // encoded into the names of the copy/dispose helpers. We have to add a
3515 // string here only when the copy/dispose helpers aren't generated (which
3516 // happens when the block is non-escaping).
3517 continue;
3518 } else {
3519 switch (R.opcode) {
3520 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3521 Str += "s";
3522 break;
3523 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3524 Str += "r";
3525 break;
3526 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3527 Str += "w";
3528 break;
3529 default:
3530 continue;
3531 }
3532 }
3533 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3534 Str += "l" + llvm::to_string(R.block_var_size.getQuantity());
3535 }
3536 return Str;
3537}
3538
3539void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3540 const CGBlockInfo &blockInfo) {
3541 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3542
3543 RunSkipBlockVars.clear();
3544 bool hasUnion = false;
3545
3546 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(LangAS::Default);
3547 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
3548 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3549
3550 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
3551
3552 // Calculate the basic layout of the block structure.
3553 const llvm::StructLayout *layout =
3554 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
3555
3556 // Ignore the optional 'this' capture: C++ objects are not assumed
3557 // to be GC'ed.
3558 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
3559 UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
3561 blockInfo.BlockHeaderForcedGapSize);
3562 // Walk the captured variables.
3563 for (const auto &CI : blockDecl->captures()) {
3564 const VarDecl *variable = CI.getVariable();
3565 QualType type = variable->getType();
3566
3567 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
3568
3569 // Ignore constant captures.
3570 if (capture.isConstant())
3571 continue;
3572
3573 CharUnits fieldOffset =
3574 CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
3575
3576 assert(!type->isArrayType() && "array variable should not be caught");
3577 if (!CI.isByRef())
3578 if (const auto *record = type->getAsCanonical<RecordType>()) {
3579 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3580 continue;
3581 }
3582 CharUnits fieldSize;
3583 if (CI.isByRef())
3584 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
3585 else
3586 fieldSize = CGM.getContext().getTypeSizeInChars(type);
3587 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
3588 fieldOffset, fieldSize);
3589 }
3590}
3591
3592llvm::Constant *
3593CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3594 const CGBlockInfo &blockInfo) {
3595 fillRunSkipBlockVars(CGM, blockInfo);
3596 return getBitmapBlockLayout(false);
3597}
3598
3599std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3600 const CGBlockInfo &blockInfo) {
3601 fillRunSkipBlockVars(CGM, blockInfo);
3602 return getBlockLayoutInfoString(RunSkipBlockVars, blockInfo.NeedsCopyDispose);
3603}
3604
3605llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3606 QualType T) {
3607 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3608 assert(!T->isArrayType() && "__block array variable should not be caught");
3609 CharUnits fieldOffset;
3610 RunSkipBlockVars.clear();
3611 bool hasUnion = false;
3612 if (const auto *record = T->getAsCanonical<RecordType>()) {
3613 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3614 true /*ByrefLayout */);
3615 llvm::Constant *Result = getBitmapBlockLayout(true);
3617 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);
3618 return Result;
3619 }
3620 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
3621 return nullPtr;
3622}
3623
3624llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3625 const ObjCProtocolDecl *PD) {
3626 // FIXME: I don't understand why gcc generates this, or where it is
3627 // resolved. Investigate. Its also wasteful to look this up over and over.
3628 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
3629
3630 return GetProtocolRef(PD);
3631}
3632
3633void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
3634 // FIXME: We shouldn't need this, the protocol decl should contain enough
3635 // information to tell us whether this was a declaration or a definition.
3636 DefinedProtocols.insert(PD->getIdentifier());
3637
3638 // If we have generated a forward reference to this protocol, emit
3639 // it now. Otherwise do nothing, the protocol objects are lazily
3640 // emitted.
3641 if (Protocols.count(PD->getIdentifier()))
3642 GetOrEmitProtocol(PD);
3643}
3644
3645llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
3646 if (DefinedProtocols.count(PD->getIdentifier()))
3647 return GetOrEmitProtocol(PD);
3648
3649 return GetOrEmitProtocolRef(PD);
3650}
3651
3652llvm::Value *
3653CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3654 const ObjCInterfaceDecl *ID,
3655 ObjCCommonTypesHelper &ObjCTypes) {
3656 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3657
3658 llvm::Value *className = CGF.CGM
3659 .GetAddrOfConstantCString(std::string(
3660 ID->getObjCRuntimeNameAsString()))
3661 .getPointer();
3662 ASTContext &ctx = CGF.CGM.getContext();
3663 className = CGF.Builder.CreateBitCast(
3664 className, CGF.ConvertType(ctx.getPointerType(ctx.CharTy.withConst())));
3665 llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className);
3666 call->setDoesNotThrow();
3667 return call;
3668}
3669
3670/*
3671// Objective-C 1.0 extensions
3672struct _objc_protocol {
3673struct _objc_protocol_extension *isa;
3674char *protocol_name;
3675struct _objc_protocol_list *protocol_list;
3676struct _objc__method_prototype_list *instance_methods;
3677struct _objc__method_prototype_list *class_methods
3678};
3679
3680See EmitProtocolExtension().
3681*/
3682llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
3683 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
3684
3685 // Early exit if a defining object has already been generated.
3686 if (Entry && Entry->hasInitializer())
3687 return Entry;
3688
3689 // Use the protocol definition, if there is one.
3690 if (const ObjCProtocolDecl *Def = PD->getDefinition())
3691 PD = Def;
3692
3693 // FIXME: I don't understand why gcc generates this, or where it is
3694 // resolved. Investigate. Its also wasteful to look this up over and over.
3695 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
3696
3697 // Construct method lists.
3698 auto methodLists = ProtocolMethodLists::get(PD);
3699
3700 ConstantInitBuilder builder(CGM);
3701 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3702 values.add(EmitProtocolExtension(PD, methodLists));
3703 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
3704 values.add(EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
3705 PD->protocol_begin(), PD->protocol_end()));
3706 values.add(methodLists.emitMethodList(
3707 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3708 values.add(methodLists.emitMethodList(
3709 this, PD, ProtocolMethodLists::RequiredClassMethods));
3710
3711 if (Entry) {
3712 // Already created, update the initializer.
3713 assert(Entry->hasPrivateLinkage());
3714 values.finishAndSetAsInitializer(Entry);
3715 } else {
3716 Entry = values.finishAndCreateGlobal(
3717 "OBJC_PROTOCOL_" + PD->getName(), CGM.getPointerAlign(),
3718 /*constant*/ false, llvm::GlobalValue::PrivateLinkage);
3719 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3720
3721 Protocols[PD->getIdentifier()] = Entry;
3722 }
3723 CGM.addCompilerUsedGlobal(Entry);
3724
3725 return Entry;
3726}
3727
3728llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
3729 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
3730
3731 if (!Entry) {
3732 // We use the initializer as a marker of whether this is a forward
3733 // reference or not. At module finalization we add the empty
3734 // contents for protocols which were referenced but never defined.
3735 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
3736 false, llvm::GlobalValue::PrivateLinkage,
3737 nullptr, "OBJC_PROTOCOL_" + PD->getName());
3738 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3739 // FIXME: Is this necessary? Why only for protocol?
3740 Entry->setAlignment(llvm::Align(4));
3741 }
3742
3743 return Entry;
3744}
3745
3746/*
3747 struct _objc_protocol_extension {
3748 uint32_t size;
3749 struct objc_method_description_list *optional_instance_methods;
3750 struct objc_method_description_list *optional_class_methods;
3751 struct objc_property_list *instance_properties;
3752 const char ** extendedMethodTypes;
3753 struct objc_property_list *class_properties;
3754 };
3755*/
3756llvm::Constant *
3757CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
3758 const ProtocolMethodLists &methodLists) {
3759 auto optInstanceMethods = methodLists.emitMethodList(
3760 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3761 auto optClassMethods = methodLists.emitMethodList(
3762 this, PD, ProtocolMethodLists::OptionalClassMethods);
3763
3764 auto extendedMethodTypes = EmitProtocolMethodTypes(
3765 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3766 methodLists.emitExtendedTypesArray(this), ObjCTypes);
3767
3768 auto instanceProperties = EmitPropertyList(
3769 "OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD, ObjCTypes, false);
3770 auto classProperties =
3771 EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr,
3772 PD, ObjCTypes, true);
3773
3774 // Return null if no extension bits are used.
3775 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3776 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3777 classProperties->isNullValue()) {
3778 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3779 }
3780
3781 uint64_t size =
3782 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3783
3784 ConstantInitBuilder builder(CGM);
3785 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3786 values.addInt(ObjCTypes.IntTy, size);
3787 values.add(optInstanceMethods);
3788 values.add(optClassMethods);
3789 values.add(instanceProperties);
3790 values.add(extendedMethodTypes);
3791 values.add(classProperties);
3792
3793 // No special section, but goes in llvm.used
3794 return CreateMetadataVar("_OBJC_PROTOCOLEXT_" + PD->getName(), values,
3795 StringRef(), CGM.getPointerAlign(), true);
3796}
3797
3798/*
3799 struct objc_protocol_list {
3800 struct objc_protocol_list *next;
3801 long count;
3802 Protocol *list[];
3803 };
3804*/
3805llvm::Constant *
3806CGObjCMac::EmitProtocolList(Twine name,
3809 // Just return null for empty protocol lists
3810 auto PDs = GetRuntimeProtocolList(begin, end);
3811 if (PDs.empty())
3812 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3813
3814 ConstantInitBuilder builder(CGM);
3815 auto values = builder.beginStruct();
3816
3817 // This field is only used by the runtime.
3818 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3819
3820 // Reserve a slot for the count.
3821 auto countSlot = values.addPlaceholder();
3822
3823 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3824 for (const auto *Proto : PDs)
3825 refsArray.add(GetProtocolRef(Proto));
3826
3827 auto count = refsArray.size();
3828
3829 // This list is null terminated.
3830 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3831
3832 refsArray.finishAndAddTo(values);
3833 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3834
3835 StringRef section;
3836 if (CGM.getTriple().isOSBinFormatMachO())
3837 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3838
3839 llvm::GlobalVariable *GV =
3840 CreateMetadataVar(name, values, section, CGM.getPointerAlign(), false);
3841 return GV;
3842}
3843
3847 const ObjCProtocolDecl *Proto, bool IsClassProperty) {
3848 for (const auto *PD : Proto->properties()) {
3849 if (IsClassProperty != PD->isClassProperty())
3850 continue;
3851 if (!PropertySet.insert(PD->getIdentifier()).second)
3852 continue;
3853 Properties.push_back(PD);
3854 }
3855
3856 for (const auto *P : Proto->protocols())
3857 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3858}
3859
3860/*
3861 struct _objc_property {
3862 const char * const name;
3863 const char * const attributes;
3864 };
3865
3866 struct _objc_property_list {
3867 uint32_t entsize; // sizeof (struct _objc_property)
3868 uint32_t prop_count;
3869 struct _objc_property[prop_count];
3870 };
3871*/
3872llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3873 Twine Name, const Decl *Container, const ObjCContainerDecl *OCD,
3874 const ObjCCommonTypesHelper &ObjCTypes, bool IsClassProperty) {
3875 if (IsClassProperty) {
3876 // Make this entry NULL for OS X with deployment target < 10.11, for iOS
3877 // with deployment target < 9.0.
3878 const llvm::Triple &Triple = CGM.getTarget().getTriple();
3879 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3880 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3881 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3882 }
3883
3884 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3885 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3886
3887 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3888 for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3889 for (auto *PD : ClassExt->properties()) {
3890 if (IsClassProperty != PD->isClassProperty())
3891 continue;
3892 if (PD->isDirectProperty())
3893 continue;
3894 PropertySet.insert(PD->getIdentifier());
3895 Properties.push_back(PD);
3896 }
3897
3898 for (const auto *PD : OCD->properties()) {
3899 if (IsClassProperty != PD->isClassProperty())
3900 continue;
3901 // Don't emit duplicate metadata for properties that were already in a
3902 // class extension.
3903 if (!PropertySet.insert(PD->getIdentifier()).second)
3904 continue;
3905 if (PD->isDirectProperty())
3906 continue;
3907 Properties.push_back(PD);
3908 }
3909
3910 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3911 for (const auto *P : OID->all_referenced_protocols())
3912 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3913 } else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3914 for (const auto *P : CD->protocols())
3915 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3916 }
3917
3918 // Return null for empty list.
3919 if (Properties.empty())
3920 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3921
3922 unsigned propertySize =
3923 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
3924
3925 ConstantInitBuilder builder(CGM);
3926 auto values = builder.beginStruct();
3927 values.addInt(ObjCTypes.IntTy, propertySize);
3928 values.addInt(ObjCTypes.IntTy, Properties.size());
3929 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3930 for (auto PD : Properties) {
3931 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3932 property.add(GetPropertyName(PD->getIdentifier()));
3933 property.add(GetPropertyTypeString(PD, Container));
3934 property.finishAndAddTo(propertiesArray);
3935 }
3936 propertiesArray.finishAndAddTo(values);
3937
3938 StringRef Section;
3939 if (CGM.getTriple().isOSBinFormatMachO())
3940 Section = (ObjCABI == 2) ? "__DATA, __objc_const"
3941 : "__OBJC,__property,regular,no_dead_strip";
3942
3943 llvm::GlobalVariable *GV =
3944 CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
3945 return GV;
3946}
3947
3948llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3949 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3950 const ObjCCommonTypesHelper &ObjCTypes) {
3951 // Return null for empty list.
3952 if (MethodTypes.empty())
3953 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3954
3955 llvm::ArrayType *AT =
3956 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3957 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3958
3959 StringRef Section;
3960 if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3961 Section = "__DATA, __objc_const";
3962
3963 llvm::GlobalVariable *GV =
3964 CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3965 return GV;
3966}
3967
3968/*
3969 struct _objc_category {
3970 char *category_name;
3971 char *class_name;
3972 struct _objc_method_list *instance_methods;
3973 struct _objc_method_list *class_methods;
3974 struct _objc_protocol_list *protocols;
3975 uint32_t size; // sizeof(struct _objc_category)
3976 struct _objc_property_list *instance_properties;
3977 struct _objc_property_list *class_properties;
3978 };
3979*/
3980void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3981 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3982
3983 // FIXME: This is poor design, the OCD should have a pointer to the category
3984 // decl. Additionally, note that Category can be null for the @implementation
3985 // w/o an @interface case. Sema should just create one for us as it does for
3986 // @implementation so everyone else can live life under a clear blue sky.
3987 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3988 const ObjCCategoryDecl *Category =
3989 Interface->FindCategoryDeclaration(OCD->getIdentifier());
3990
3991 SmallString<256> ExtName;
3992 llvm::raw_svector_ostream(ExtName)
3993 << Interface->getName() << '_' << OCD->getName();
3994
3995 ConstantInitBuilder Builder(CGM);
3996 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3997
3998 enum { InstanceMethods, ClassMethods, NumMethodLists };
3999 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4000 for (const auto *MD : OCD->methods()) {
4001 if (!MD->isDirectMethod())
4002 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4003 }
4004
4005 Values.add(GetClassName(OCD->getName()));
4006 Values.add(GetClassName(Interface->getObjCRuntimeNameAsString()));
4007 LazySymbols.insert(Interface->getIdentifier());
4008
4009 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
4010 Methods[InstanceMethods]));
4011 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
4012 Methods[ClassMethods]));
4013 if (Category) {
4014 Values.add(EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4015 Category->protocol_begin(),
4016 Category->protocol_end()));
4017 } else {
4018 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4019 }
4020 Values.addInt(ObjCTypes.IntTy, Size);
4021
4022 // If there is no category @interface then there can be no properties.
4023 if (Category) {
4024 Values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4025 Category, ObjCTypes, false));
4026 Values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4027 Category, ObjCTypes, true));
4028 } else {
4029 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4030 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4031 }
4032
4033 llvm::GlobalVariable *GV = CreateMetadataVar(
4034 "OBJC_CATEGORY_" + ExtName.str(), Values,
4035 "__OBJC,__category,regular,no_dead_strip", CGM.getPointerAlign(), true);
4036 DefinedCategories.push_back(GV);
4037 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4038 // method definition entries must be clear for next implementation.
4039 MethodDefinitions.clear();
4040}
4041
4042// clang-format off
4044 /// Apparently: is not a meta-class.
4046
4047 /// Is a meta-class.
4049
4050 /// Has a non-trivial constructor or destructor.
4052
4053 /// Has hidden visibility.
4055
4056 /// Class implementation was compiled under ARC.
4058
4059 /// Class implementation was compiled under MRC and has MRC weak ivars.
4060 /// Exclusive with CompiledByARC.
4062};
4063
4065 /// Is a meta-class.
4067
4068 /// Is a root class.
4070
4071 /// Has a non-trivial constructor or destructor.
4073
4074 /// Has hidden visibility.
4076
4077 /// Has the exception attribute.
4079
4080 /// (Obsolete) ARC-specific: this class has a .release_ivars method
4082
4083 /// Class implementation was compiled under ARC.
4085
4086 /// Class has non-trivial destructors, but zero-initialization is okay.
4088
4089 /// Class implementation was compiled under MRC and has MRC weak ivars.
4090 /// Exclusive with CompiledByARC.
4092};
4093// clang-format on
4094
4096 if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
4097 return true;
4098 }
4099
4100 if (auto *RD = type->getAsRecordDecl()) {
4101 for (auto *field : RD->fields()) {
4102 if (hasWeakMember(field->getType()))
4103 return true;
4104 }
4105 }
4106
4107 return false;
4108}
4109
4110/// For compatibility, we only want to set the "HasMRCWeakIvars" flag
4111/// (and actually fill in a layout string) if we really do have any
4112/// __weak ivars.
4114 const ObjCImplementationDecl *ID) {
4115 if (!CGM.getLangOpts().ObjCWeak)
4116 return false;
4117 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
4118
4119 for (const ObjCIvarDecl *ivar =
4120 ID->getClassInterface()->all_declared_ivar_begin();
4121 ivar; ivar = ivar->getNextIvar()) {
4122 if (hasWeakMember(ivar->getType()))
4123 return true;
4124 }
4125
4126 return false;
4127}
4128
4129/*
4130 struct _objc_class {
4131 Class isa;
4132 Class super_class;
4133 const char *name;
4134 long version;
4135 long info;
4136 long instance_size;
4137 struct _objc_ivar_list *ivars;
4138 struct _objc_method_list *methods;
4139 struct _objc_cache *cache;
4140 struct _objc_protocol_list *protocols;
4141 // Objective-C 1.0 extensions (<rdr://4585769>)
4142 const char *ivar_layout;
4143 struct _objc_class_ext *ext;
4144 };
4145
4146 See EmitClassExtension();
4147*/
4148void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
4149 IdentifierInfo *RuntimeName =
4150 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
4151 DefinedSymbols.insert(RuntimeName);
4152
4153 std::string ClassName = ID->getNameAsString();
4154 // FIXME: Gross
4155 ObjCInterfaceDecl *Interface =
4156 const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());
4157 llvm::Constant *Protocols =
4158 EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
4159 Interface->all_referenced_protocol_begin(),
4160 Interface->all_referenced_protocol_end());
4161 unsigned Flags = FragileABI_Class_Factory;
4162 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
4164
4165 bool hasMRCWeak = false;
4166
4167 if (CGM.getLangOpts().ObjCAutoRefCount)
4169 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
4171
4172 CharUnits Size = CGM.getContext()
4173 .getASTObjCInterfaceLayout(ID->getClassInterface())
4174 .getSize();
4175
4176 // FIXME: Set CXX-structors flag.
4177 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4178 Flags |= FragileABI_Class_Hidden;
4179
4180 enum { InstanceMethods, ClassMethods, NumMethodLists };
4181 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4182 for (const auto *MD : ID->methods()) {
4183 if (!MD->isDirectMethod())
4184 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4185 }
4186
4187 for (const auto *PID : ID->property_impls()) {
4188 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
4189 if (PID->getPropertyDecl()->isDirectProperty())
4190 continue;
4191 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4192 if (GetMethodDefinition(MD))
4193 Methods[InstanceMethods].push_back(MD);
4194 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4195 if (GetMethodDefinition(MD))
4196 Methods[InstanceMethods].push_back(MD);
4197 }
4198 }
4199
4200 ConstantInitBuilder builder(CGM);
4201 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4202 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4203 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
4204 // Record a reference to the super class.
4205 LazySymbols.insert(Super->getIdentifier());
4206
4207 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4208 } else {
4209 values.addNullPointer(ObjCTypes.ClassPtrTy);
4210 }
4211 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
4212 // Version is always 0.
4213 values.addInt(ObjCTypes.LongTy, 0);
4214 values.addInt(ObjCTypes.LongTy, Flags);
4215 values.addInt(ObjCTypes.LongTy, Size.getQuantity());
4216 values.add(EmitIvarList(ID, false));
4217 values.add(emitMethodList(ID->getName(), MethodListType::InstanceMethods,
4218 Methods[InstanceMethods]));
4219 // cache is always NULL.
4220 values.addNullPointer(ObjCTypes.CachePtrTy);
4221 values.add(Protocols);
4222 values.add(BuildStrongIvarLayout(ID, CharUnits::Zero(), Size));
4223 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4224 /*isMetaclass*/ false));
4225
4226 std::string Name("OBJC_CLASS_");
4227 Name += ClassName;
4228 const char *Section = "__OBJC,__class,regular,no_dead_strip";
4229 // Check for a forward reference.
4230 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
4231 if (GV) {
4232 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4233 "Forward metaclass reference has incorrect type.");
4234 values.finishAndSetAsInitializer(GV);
4235 GV->setSection(Section);
4236 GV->setAlignment(CGM.getPointerAlign().getAsAlign());
4237 CGM.addCompilerUsedGlobal(GV);
4238 } else
4239 GV = CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
4240 DefinedClasses.push_back(GV);
4241 ImplementedClasses.push_back(Interface);
4242 // method definition entries must be clear for next implementation.
4243 MethodDefinitions.clear();
4244}
4245
4246llvm::Constant *
4247CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
4248 llvm::Constant *Protocols,
4249 ArrayRef<const ObjCMethodDecl *> Methods) {
4250 unsigned Flags = FragileABI_Class_Meta;
4251 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
4252
4253 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
4254 Flags |= FragileABI_Class_Hidden;
4255
4256 ConstantInitBuilder builder(CGM);
4257 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4258 // The isa for the metaclass is the root of the hierarchy.
4259 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4260 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4261 Root = Super;
4262 values.add(GetClassName(Root->getObjCRuntimeNameAsString()));
4263 // The super class for the metaclass is emitted as the name of the
4264 // super class. The runtime fixes this up to point to the
4265 // *metaclass* for the super class.
4266 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
4267 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4268 } else {
4269 values.addNullPointer(ObjCTypes.ClassPtrTy);
4270 }
4271 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
4272 // Version is always 0.
4273 values.addInt(ObjCTypes.LongTy, 0);
4274 values.addInt(ObjCTypes.LongTy, Flags);
4275 values.addInt(ObjCTypes.LongTy, Size);
4276 values.add(EmitIvarList(ID, true));
4277 values.add(
4278 emitMethodList(ID->getName(), MethodListType::ClassMethods, Methods));
4279 // cache is always NULL.
4280 values.addNullPointer(ObjCTypes.CachePtrTy);
4281 values.add(Protocols);
4282 // ivar_layout for metaclass is always NULL.
4283 values.addNullPointer(ObjCTypes.Int8PtrTy);
4284 // The class extension is used to store class properties for metaclasses.
4285 values.add(EmitClassExtension(ID, CharUnits::Zero(), false /*hasMRCWeak*/,
4286 /*isMetaclass*/ true));
4287
4288 std::string Name("OBJC_METACLASS_");
4289 Name += ID->getName();
4290
4291 // Check for a forward reference.
4292 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
4293 if (GV) {
4294 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4295 "Forward metaclass reference has incorrect type.");
4296 values.finishAndSetAsInitializer(GV);
4297 } else {
4298 GV = values.finishAndCreateGlobal(Name, CGM.getPointerAlign(),
4299 /*constant*/ false,
4300 llvm::GlobalValue::PrivateLinkage);
4301 }
4302 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
4303 CGM.addCompilerUsedGlobal(GV);
4304
4305 return GV;
4306}
4307
4308llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
4309 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
4310
4311 // FIXME: Should we look these up somewhere other than the module. Its a bit
4312 // silly since we only generate these while processing an implementation, so
4313 // exactly one pointer would work if know when we entered/exitted an
4314 // implementation block.
4315
4316 // Check for an existing forward reference.
4317 // Previously, metaclass with internal linkage may have been defined.
4318 // pass 'true' as 2nd argument so it is returned.
4319 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
4320 if (!GV)
4321 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4322 llvm::GlobalValue::PrivateLinkage, nullptr,
4323 Name);
4324
4325 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4326 "Forward metaclass reference has incorrect type.");
4327 return GV;
4328}
4329
4330llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
4331 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
4332 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
4333
4334 if (!GV)
4335 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
4336 llvm::GlobalValue::PrivateLinkage, nullptr,
4337 Name);
4338
4339 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4340 "Forward class metadata reference has incorrect type.");
4341 return GV;
4342}
4343
4344/*
4345 Emit a "class extension", which in this specific context means extra
4346 data that doesn't fit in the normal fragile-ABI class structure, and
4347 has nothing to do with the language concept of a class extension.
4348
4349 struct objc_class_ext {
4350 uint32_t size;
4351 const char *weak_ivar_layout;
4352 struct _objc_property_list *properties;
4353 };
4354*/
4355llvm::Constant *CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
4356 CharUnits InstanceSize,
4357 bool hasMRCWeakIvars,
4358 bool isMetaclass) {
4359 // Weak ivar layout.
4360 llvm::Constant *layout;
4361 if (isMetaclass) {
4362 layout = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
4363 } else {
4364 layout = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
4366 }
4367
4368 // Properties.
4369 llvm::Constant *propertyList =
4370 EmitPropertyList((isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")
4371 : Twine("_OBJC_$_PROP_LIST_")) +
4372 ID->getName(),
4373 ID, ID->getClassInterface(), ObjCTypes, isMetaclass);
4374
4375 // Return null if no extension bits are used.
4376 if (layout->isNullValue() && propertyList->isNullValue()) {
4377 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4378 }
4379
4380 uint64_t size =
4381 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4382
4383 ConstantInitBuilder builder(CGM);
4384 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4385 values.addInt(ObjCTypes.IntTy, size);
4386 values.add(layout);
4387 values.add(propertyList);
4388
4389 return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), values,
4390 "__OBJC,__class_ext,regular,no_dead_strip",
4391 CGM.getPointerAlign(), true);
4392}
4393
4394/*
4395 struct objc_ivar {
4396 char *ivar_name;
4397 char *ivar_type;
4398 int ivar_offset;
4399 };
4400
4401 struct objc_ivar_list {
4402 int ivar_count;
4403 struct objc_ivar list[count];
4404 };
4405*/
4406llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
4407 bool ForClass) {
4408 // When emitting the root class GCC emits ivar entries for the
4409 // actual class structure. It is not clear if we need to follow this
4410 // behavior; for now lets try and get away with not doing it. If so,
4411 // the cleanest solution would be to make up an ObjCInterfaceDecl
4412 // for the class.
4413 if (ForClass)
4414 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4415
4416 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4417
4418 ConstantInitBuilder builder(CGM);
4419 auto ivarList = builder.beginStruct();
4420 auto countSlot = ivarList.addPlaceholder();
4421 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4422
4423 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
4424 IVD = IVD->getNextIvar()) {
4425 // Ignore unnamed bit-fields.
4426 if (!IVD->getDeclName())
4427 continue;
4428
4429 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4430 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4431 ivar.add(GetMethodVarType(IVD));
4432 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4433 ivar.finishAndAddTo(ivars);
4434 }
4435
4436 // Return null for empty list.
4437 auto count = ivars.size();
4438 if (count == 0) {
4439 ivars.abandon();
4440 ivarList.abandon();
4441 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4442 }
4443
4444 ivars.finishAndAddTo(ivarList);
4445 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4446
4447 llvm::GlobalVariable *GV;
4448 GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), ivarList,
4449 "__OBJC,__instance_vars,regular,no_dead_strip",
4450 CGM.getPointerAlign(), true);
4451 return GV;
4452}
4453
4454/// Build a struct objc_method_description constant for the given method.
4455///
4456/// struct objc_method_description {
4457/// SEL method_name;
4458/// char *method_types;
4459/// };
4460void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4461 const ObjCMethodDecl *MD) {
4462 auto description = builder.beginStruct(ObjCTypes.MethodDescriptionTy);
4463 description.add(GetMethodVarName(MD->getSelector()));
4464 description.add(GetMethodVarType(MD));
4465 description.finishAndAddTo(builder);
4466}
4467
4468/// Build a struct objc_method constant for the given method.
4469///
4470/// struct objc_method {
4471/// SEL method_name;
4472/// char *method_types;
4473/// void *method;
4474/// };
4475void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4476 const ObjCMethodDecl *MD) {
4477 llvm::Function *fn = GetMethodDefinition(MD);
4478 assert(fn && "no definition registered for method");
4479
4480 auto method = builder.beginStruct(ObjCTypes.MethodTy);
4481 method.add(GetMethodVarName(MD->getSelector()));
4482 method.add(GetMethodVarType(MD));
4483 method.add(fn);
4484 method.finishAndAddTo(builder);
4485}
4486
4487/// Build a struct objc_method_list or struct objc_method_description_list,
4488/// as appropriate.
4489///
4490/// struct objc_method_list {
4491/// struct objc_method_list *obsolete;
4492/// int count;
4493/// struct objc_method methods_list[count];
4494/// };
4495///
4496/// struct objc_method_description_list {
4497/// int count;
4498/// struct objc_method_description list[count];
4499/// };
4500llvm::Constant *
4501CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4502 ArrayRef<const ObjCMethodDecl *> methods) {
4503 StringRef prefix;
4504 StringRef section;
4505 bool forProtocol = false;
4506 switch (MLT) {
4507 case MethodListType::CategoryInstanceMethods:
4508 prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";
4509 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4510 forProtocol = false;
4511 break;
4512 case MethodListType::CategoryClassMethods:
4513 prefix = "OBJC_CATEGORY_CLASS_METHODS_";
4514 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4515 forProtocol = false;
4516 break;
4517 case MethodListType::InstanceMethods:
4518 prefix = "OBJC_INSTANCE_METHODS_";
4519 section = "__OBJC,__inst_meth,regular,no_dead_strip";
4520 forProtocol = false;
4521 break;
4522 case MethodListType::ClassMethods:
4523 prefix = "OBJC_CLASS_METHODS_";
4524 section = "__OBJC,__cls_meth,regular,no_dead_strip";
4525 forProtocol = false;
4526 break;
4527 case MethodListType::ProtocolInstanceMethods:
4528 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";
4529 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4530 forProtocol = true;
4531 break;
4532 case MethodListType::ProtocolClassMethods:
4533 prefix = "OBJC_PROTOCOL_CLASS_METHODS_";
4534 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4535 forProtocol = true;
4536 break;
4537 case MethodListType::OptionalProtocolInstanceMethods:
4538 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4539 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
4540 forProtocol = true;
4541 break;
4542 case MethodListType::OptionalProtocolClassMethods:
4543 prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4544 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
4545 forProtocol = true;
4546 break;
4547 }
4548
4549 // Return null for empty list.
4550 if (methods.empty())
4551 return llvm::Constant::getNullValue(
4552 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4553 : ObjCTypes.MethodListPtrTy);
4554
4555 // For protocols, this is an objc_method_description_list, which has
4556 // a slightly different structure.
4557 if (forProtocol) {
4558 ConstantInitBuilder builder(CGM);
4559 auto values = builder.beginStruct();
4560 values.addInt(ObjCTypes.IntTy, methods.size());
4561 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4562 for (auto MD : methods) {
4563 emitMethodDescriptionConstant(methodArray, MD);
4564 }
4565 methodArray.finishAndAddTo(values);
4566
4567 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4568 CGM.getPointerAlign(), true);
4569 return GV;
4570 }
4571
4572 // Otherwise, it's an objc_method_list.
4573 ConstantInitBuilder builder(CGM);
4574 auto values = builder.beginStruct();
4575 values.addNullPointer(ObjCTypes.Int8PtrTy);
4576 values.addInt(ObjCTypes.IntTy, methods.size());
4577 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4578 for (auto MD : methods) {
4579 if (!MD->isDirectMethod())
4580 emitMethodConstant(methodArray, MD);
4581 }
4582 methodArray.finishAndAddTo(values);
4583
4584 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4585 CGM.getPointerAlign(), true);
4586 return GV;
4587}
4588
4589llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
4590 const ObjCContainerDecl *CD) {
4591 llvm::Function *Method;
4592
4593 if (OMD->isDirectMethod()) {
4594 // Returns DirectMethodInfo& containing both Implementation and Thunk
4595 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4596 Method = Info.Implementation; // Extract implementation for body generation
4597 } else {
4598 auto Name = getSymbolNameForMethod(OMD);
4599
4600 CodeGenTypes &Types = CGM.getTypes();
4601 llvm::FunctionType *MethodTy =
4603 Method = llvm::Function::Create(
4604 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
4605 }
4606
4607 MethodDefinitions.insert(std::make_pair(OMD, Method));
4608
4609 return Method;
4610}
4611
4612/// Generate or retrieve a direct method info.
4613CGObjCCommonMac::DirectMethodInfo &
4614CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
4615 const ObjCContainerDecl *CD) {
4616 auto *COMD = OMD->getCanonicalDecl();
4617
4618 // Fast path: return cached entry if this is not an implementation (no body)
4619 // or if the return types match between declaration and implementation.
4620 auto Cached = DirectMethodDefinitions.find(COMD);
4621 if (Cached != DirectMethodDefinitions.end()) {
4622 if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType())
4623 return Cached->second;
4624 }
4625
4626 CodeGenTypes &Types = CGM.getTypes();
4627 llvm::FunctionType *MethodTy =
4629 std::string Name =
4630 getSymbolNameForMethod(OMD, /*includeCategoryName*/ false,
4632 std::string ThunkName = Name + "_thunk";
4633
4634 // Replace OldFn with NewFn: transfer name, replace all uses, and erase.
4635 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4636 NewFn->takeName(OldFn);
4637 OldFn->replaceAllUsesWith(NewFn);
4638 OldFn->eraseFromParent();
4639 };
4640
4641 // Check if the function already exists in the module (created by Clang or
4642 // Swift).
4643 llvm::Function *Fn = CGM.getModule().getFunction(Name);
4644
4645 // Function doesn't exist yet.
4646 if (!Fn) {
4647 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4648 Name, &CGM.getModule());
4649 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4650 .first->second;
4651 }
4652
4653 // Function exists with matching type.
4654 // Other frontends operating on the same module may have created the function.
4655 if (Fn->getFunctionType() == MethodTy) {
4656 // Reinforce linkage in case Swift created it with different linkage.
4657 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4658
4659 // Check if Swift also created a thunk for this method.
4660 DirectMethodInfo Info(Fn);
4661 if (llvm::Function *Thunk = CGM.getModule().getFunction(ThunkName))
4662 Info.Thunk = Thunk;
4663
4664 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4665 }
4666
4667 // Function exists but with mismatched type - replace it.
4668 // This happens when Swift's optional handling differs from ObjC, or when
4669 // ObjC declaration and implementation have slightly different return types.
4670 llvm::Function *NewFn = llvm::Function::Create(
4671 MethodTy, llvm::GlobalValue::ExternalLinkage, "", &CGM.getModule());
4672 ReplaceFunction(Fn, NewFn);
4673
4674 // Check if the thunk also needs replacement.
4675 DirectMethodInfo Info(NewFn);
4676 if (llvm::Function *OldThunk = CGM.getModule().getFunction(ThunkName)) {
4677 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4678 ReplaceFunction(OldThunk, NewThunk);
4679 Info.Thunk = NewThunk;
4680 }
4681
4682 if (Cached != DirectMethodDefinitions.end()) {
4683 Cached->second = Info;
4684 return Cached->second;
4685 }
4686 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4687}
4688
4689/// Start an Objective-C direct method precondition thunk.
4691 const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI) {
4692 // Mark this as a thunk function to disable ARC parameter processing
4693 // and other thunk-inappropriate behavior. We don't need to retain
4694 // parameters because we're going to immediately forward them.
4695 //
4696 // Skipping ARC parameter processing is correct as long as (1) we don't
4697 // run any code that could invalidate the parameters between the start of
4698 // the thunk and the call and (2) we don't use the parameters after the
4699 // call. Both hold whether we tail-call or not. Class realization could in
4700 // theory invalidate parameters, but we assume that doesn't happen in
4701 // practice.
4702 CurFuncIsThunk = true;
4703
4704 // Build argument list for StartFunction.
4705 // We must include all parameters to match the thunk's LLVM function type.
4706 FunctionArgList FunctionArgs;
4707 FunctionArgs.push_back(OMD->getSelfDecl());
4708 FunctionArgs.append(OMD->param_begin(), OMD->param_end());
4709
4710 // The Start/Finish thunk pattern is borrowed from CGVTables.cpp
4711 // for C++ virtual method thunks, but adapted for ObjC direct methods.
4712 //
4713 // Like C++ thunks, we don't have an actual AST body for the thunk - we only
4714 // have the method's parameter declarations. Therefore, we pass empty
4715 // `GlobalDecl` to `StartFunction` ...
4716 StartFunction(GlobalDecl(), OMD->getReturnType(), Fn, FI, FunctionArgs,
4717 OMD->getLocation(), OMD->getLocation());
4718
4719 // and manually set the decl afterwards so other utilities / helpers in CGF
4720 // can still access the AST (e.g. arrange function arguments)
4721 CurCodeDecl = OMD;
4722 CurFuncDecl = OMD;
4723}
4724
4725/// Finish an Objective-C direct method precondition thunk.
4727 // Create a dummy block to return the value of the thunk.
4728 //
4729 // The non-nil branch alredy returned because of musttail.
4730 // Only nil branch will jump to this return block.
4731 // If the nil check is not emitted (for class methods), this will be a dead
4732 // block.
4733 //
4734 // Either way, the LLVM optimizer will simplify it later. This is just to make
4735 // CFG happy.
4736 EmitBlock(createBasicBlock("dummy_ret_block"));
4737
4738 // Disable the final ARC autorelease.
4739 // Thunk functions are tailcall to actual implementation, so it doesn't need
4740 // to worry about ARC.
4741 AutoreleaseResult = false;
4742
4743 // Clear these to restore the invariants expected by
4744 // StartFunction/FinishFunction.
4745 CurCodeDecl = nullptr;
4746 CurFuncDecl = nullptr;
4747
4749}
4750
4751llvm::Function *
4752CGObjCCommonMac::GenerateObjCDirectThunk(const ObjCMethodDecl *OMD,
4753 const ObjCContainerDecl *CD,
4754 llvm::Function *Implementation) {
4755
4756 assert(CGM.shouldHavePreconditionThunk(OMD) &&
4757 "Should only generate thunk when optimization enabled");
4758 assert(Implementation && "Implementation must exist");
4759
4760 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4761 std::string ThunkName = Implementation->getName().str() + "_thunk";
4762
4763 // Create thunk with linkonce_odr linkage (allows deduplication)
4764 llvm::Function *Thunk =
4765 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4766 ThunkName, &CGM.getModule());
4767
4768 // Thunks should always have hidden visibility, other link units will have
4769 // their own version of the (identical) thunk. If they make cross link-unit
4770 // call, they are either calling through their thunk or directly dispatching
4771 // to the true implementation, so making thunk visibile is meaningless.
4772 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4773 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4774
4775 // Start the ObjC direct thunk (sets up state and calls StartFunction)
4777
4778 // Create a CodeGenFunction to generate the thunk body
4779 CodeGenFunction CGF(CGM);
4780 CGF.StartObjCDirectPreconditionThunk(OMD, Thunk, FI);
4781
4782 // Set function attributes from CGFunctionInfo to ensure the thunk has
4783 // matching parameter attributes (especially sret) for musttail correctness.
4784 // We use SetLLVMFunctionAttributes rather than copying from Implementation
4785 // because Implementation may not have its attributes set yet at this point.
4786 CGM.SetLLVMFunctionAttributes(GlobalDecl(OMD), FI, Thunk, /*IsThunk=*/false);
4788
4789 // - [self self] for class methods (class realization)
4790 // - if (self == nil) branch to nil block with zero return
4791 // - continuation block for non-nil case
4792 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4793
4794 // Now emit the musttail call to the true implementation
4795 // Collect all arguments for forwarding
4797 for (auto &Arg : Thunk->args())
4798 Args.push_back(&Arg);
4799
4800 // Create musttail call to the implementation
4801 llvm::CallInst *Call = CGF.Builder.CreateCall(Implementation, Args);
4802 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4803
4804 // Apply call-site attributes using ConstructAttributeList
4805 // When sret is used, the call must have matching sret attributes on the first
4806 // parameter for musttail to work correctly. This mirrors what C++ thunks do
4807 // in EmitMustTailThunk.
4808 unsigned CallingConv;
4809 llvm::AttributeList Attrs;
4810 CGM.ConstructAttributeList(Implementation->getName(), FI, GlobalDecl(OMD),
4811 Attrs, CallingConv, /*AttrOnCallSite=*/true,
4812 /*IsThunk=*/false);
4813 Call->setAttributes(Attrs);
4814 Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
4815
4816 // Immediately return the call result (musttail requirement).
4817 // For sret returns, the Apple ABI produces void-returning LLVM functions,
4818 // so checking the LLVM return type is suffice.
4819 if (ThunkTy->getReturnType()->isVoidTy())
4820 CGF.Builder.CreateRetVoid();
4821 else
4822 CGF.Builder.CreateRet(Call);
4823
4824 // Finish the ObjC direct thunk (creates dummy block and calls FinishFunction)
4826 return Thunk;
4827}
4828
4829llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4830 const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
4831 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
4832
4833 // Get from cache or populate the function declaration.
4834 // Copy by value to avoid holding a reference into DirectMethodDefinitions
4835 // DenseMap, which could be invalidated by future insertions.
4836 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4837
4838 // If thunk optimization not enabled (or variadic method which can't use
4839 // thunks), use implementation directly. Variadic methods and methods without
4840 // the optimization enabled include precondition checks in the implementation.
4841 if (!CGM.shouldHavePreconditionThunk(OMD)) {
4842 return Info.Implementation;
4843 }
4844
4845 // Thunk is lazily generated.
4846 auto getOrCreateThunk = [&]() {
4847 if (!Info.Thunk) {
4848 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4849 // Write back the lazily created thunk to the map.
4850 DirectMethodDefinitions.insert_or_assign(OMD->getCanonicalDecl(), Info);
4851 }
4852 return Info.Thunk;
4853 };
4854
4855 if (OMD->isInstanceMethod()) {
4856 // If we can prove instance methods receiver is not null, return the true
4857 // implementation
4858 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4859 }
4860 assert(OMD->isClassMethod() &&
4861 "OMD should either be a class method or instance method");
4862
4863 // For class methods, it need to be non-null and realized before we dispatch
4864 // to true implementation
4865 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4866 ? getOrCreateThunk()
4867 : Info.Implementation;
4868}
4869
4870llvm::Value *
4871CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4872 llvm::Value *classObject,
4873 const ObjCInterfaceDecl *OID) {
4874 // Generate: self = [self self]
4875 // This forces class lazy initialization
4876 Selector SelfSel = GetNullarySelector("self", CGM.getContext());
4877 auto ResultType = CGF.getContext().getObjCIdType();
4878 CallArgList Args;
4879
4880 RValue result = GeneratePossiblySpecializedMessageSend(
4881 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4882 nullptr, true);
4883
4884 return result.getScalarVal();
4885}
4886
4887void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4888 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4889 const ObjCContainerDecl *CD) {
4890 auto &Builder = CGF.Builder;
4891 bool ReceiverCanBeNull = true;
4892 auto selfAddr = CGF.GetAddrOfLocalVar(OMD->getSelfDecl());
4893 auto selfValue = Builder.CreateLoad(selfAddr);
4894
4895 // Generate:
4896 //
4897 // /* for class methods only to force class lazy initialization */
4898 // self = [self self];
4899 //
4900 // /* unless the receiver is never NULL */
4901 // if (self == nil) {
4902 // return (ReturnType){ };
4903 // }
4904
4905 if (OMD->isClassMethod()) {
4906 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(CD);
4907 assert(OID &&
4908 "GenerateDirectMethod() should be called with the Class Interface");
4909
4910 // TODO: If this method is inlined, the caller might know that `self` is
4911 // already initialized; for example, it might be an ordinary Objective-C
4912 // method which always receives an initialized `self`, or it might have just
4913 // forced initialization on its own.
4914 //
4915 // We should find a way to eliminate this unnecessary initialization in such
4916 // cases in LLVM.
4917
4918 // Perform class realization using the helper function
4919 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4920 Builder.CreateStore(realizedClass, selfAddr);
4921
4922 // Nullable `Class` expressions cannot be messaged with a direct method
4923 // so the only reason why the receive can be null would be because
4924 // of weak linking.
4925 ReceiverCanBeNull = isWeakLinkedClass(OID);
4926 }
4927
4928 // Generate nil check
4929 if (ReceiverCanBeNull) {
4930 llvm::BasicBlock *SelfIsNilBlock =
4931 CGF.createBasicBlock("objc_direct_method.self_is_nil");
4932 llvm::BasicBlock *ContBlock =
4933 CGF.createBasicBlock("objc_direct_method.cont");
4934
4935 // if (self == nil) {
4936 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
4937 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4938
4939 llvm::MDBuilder MDHelper(CGM.getLLVMContext());
4940 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,
4941 ContBlock, MDHelper.createUnlikelyBranchWeights());
4942
4943 CGF.EmitBlock(SelfIsNilBlock);
4944
4945 // return (ReturnType){ };
4946 auto retTy = OMD->getReturnType();
4947 Builder.SetInsertPoint(SelfIsNilBlock);
4948 if (!retTy->isVoidType()) {
4949 CGF.EmitNullInitialization(CGF.ReturnValue, retTy);
4950 }
4952 // }
4953
4954 // rest of the body
4955 CGF.EmitBlock(ContBlock);
4956 Builder.SetInsertPoint(ContBlock);
4957 }
4958}
4959
4960void CGObjCCommonMac::GenerateDirectMethodPrologue(
4961 CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4962 const ObjCContainerDecl *CD) {
4963 // Generate precondition checks (class realization + nil check) if needed
4965 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4966
4967 auto &Builder = CGF.Builder;
4968 // Only synthesize _cmd if it's referenced
4969 // This is the actual "prologue" work that always happens
4970 if (OMD->getCmdDecl()->isUsed()) {
4971 // `_cmd` is not a parameter to direct methods, so storage must be
4972 // explicitly declared for it.
4973 CGF.EmitVarDecl(*OMD->getCmdDecl());
4974 Builder.CreateStore(GetSelector(CGF, OMD),
4975 CGF.GetAddrOfLocalVar(OMD->getCmdDecl()));
4976 }
4977}
4978
4979llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4980 Selector Sel, StringRef ClassName, const ObjCCommonTypesHelper &ObjCTypes) {
4981 assert((!ClassName.data() || !ClassName.empty()) &&
4982 "class name cannot be an empty string");
4983 auto Key = std::make_pair(Sel, ClassName);
4984 auto I = MethodSelectorStubs.find(Key);
4985
4986 if (I != MethodSelectorStubs.end())
4987 return I->second;
4988
4989 auto *FnTy = llvm::FunctionType::get(
4990 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4991 /*IsVarArg=*/true);
4992 std::string FnName;
4993
4994 if (ClassName.data())
4995 FnName = ("objc_msgSendClass$" + Sel.getAsString() + "$_OBJC_CLASS_$_" +
4996 llvm::Twine(ClassName))
4997 .str();
4998 else
4999 FnName = "objc_msgSend$" + Sel.getAsString();
5000
5001 auto *Fn =
5002 cast<llvm::Function>(CGM.CreateRuntimeFunction(FnTy, FnName).getCallee());
5003
5004 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
5005 return Fn;
5006}
5007
5008llvm::GlobalVariable *
5009CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &Init,
5010 StringRef Section, CharUnits Align,
5011 bool AddToUsed) {
5012 llvm::GlobalValue::LinkageTypes LT =
5013 getLinkageTypeForObjCMetadata(CGM, Section);
5014 llvm::GlobalVariable *GV =
5015 Init.finishAndCreateGlobal(Name, Align, /*constant*/ false, LT);
5016 if (!Section.empty())
5017 GV->setSection(Section);
5018 if (AddToUsed)
5019 CGM.addCompilerUsedGlobal(GV);
5020 return GV;
5021}
5022
5023llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5024 llvm::Constant *Init,
5025 StringRef Section,
5026 CharUnits Align,
5027 bool AddToUsed) {
5028 llvm::Type *Ty = Init->getType();
5029 llvm::GlobalValue::LinkageTypes LT =
5030 getLinkageTypeForObjCMetadata(CGM, Section);
5031 llvm::GlobalVariable *GV =
5032 new llvm::GlobalVariable(CGM.getModule(), Ty, false, LT, Init, Name);
5033 if (!Section.empty())
5034 GV->setSection(Section);
5035 GV->setAlignment(Align.getAsAlign());
5036 if (AddToUsed)
5037 CGM.addCompilerUsedGlobal(GV);
5038 return GV;
5039}
5040
5041llvm::GlobalVariable *
5042CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,
5043 bool ForceNonFragileABI,
5044 bool NullTerminate) {
5045 StringRef Label;
5046 switch (Type) {
5047 case ObjCLabelType::ClassName:
5048 Label = "OBJC_CLASS_NAME_";
5049 break;
5050 case ObjCLabelType::MethodVarName:
5051 Label = "OBJC_METH_VAR_NAME_";
5052 break;
5053 case ObjCLabelType::MethodVarType:
5054 Label = "OBJC_METH_VAR_TYPE_";
5055 break;
5056 case ObjCLabelType::PropertyName:
5057 Label = "OBJC_PROP_NAME_ATTR_";
5058 break;
5059 case ObjCLabelType::LayoutBitMap:
5060 Label = "OBJC_LAYOUT_BITMAP_";
5061 break;
5062 }
5063
5064 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5065
5066 StringRef Section;
5067 switch (Type) {
5068 case ObjCLabelType::ClassName:
5069 Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"
5070 : "__TEXT,__cstring,cstring_literals";
5071 break;
5072 case ObjCLabelType::MethodVarName:
5073 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5074 : "__TEXT,__cstring,cstring_literals";
5075 break;
5076 case ObjCLabelType::MethodVarType:
5077 Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"
5078 : "__TEXT,__cstring,cstring_literals";
5079 break;
5080 case ObjCLabelType::PropertyName:
5081 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
5082 : "__TEXT,__cstring,cstring_literals";
5083 break;
5084 case ObjCLabelType::LayoutBitMap:
5085 Section = "__TEXT,__cstring,cstring_literals";
5086 break;
5087 }
5088
5089 llvm::Constant *Value =
5090 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5091 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
5092 CGM.getModule(), Value->getType(),
5093 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Value, Label);
5094 if (CGM.getTriple().isOSBinFormatMachO())
5095 GV->setSection(Section);
5096 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5097 GV->setAlignment(CharUnits::One().getAsAlign());
5098 CGM.addCompilerUsedGlobal(GV);
5099
5100 return GV;
5101}
5102
5103llvm::Function *CGObjCMac::ModuleInitFunction() {
5104 // Abuse this interface function as a place to finalize.
5105 FinishModule();
5106 return nullptr;
5107}
5108
5109llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5110 return ObjCTypes.getGetPropertyFn();
5111}
5112
5113llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5114 return ObjCTypes.getSetPropertyFn();
5115}
5116
5117llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
5118 bool copy) {
5119 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5120}
5121
5122llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5123 return ObjCTypes.getCopyStructFn();
5124}
5125
5126llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5127 return ObjCTypes.getCopyStructFn();
5128}
5129
5130llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5131 return ObjCTypes.getCppAtomicObjectFunction();
5132}
5133
5134llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5135 return ObjCTypes.getCppAtomicObjectFunction();
5136}
5137
5138llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5139 return ObjCTypes.getEnumerationMutationFn();
5140}
5141
5142void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
5143 return EmitTryOrSynchronizedStmt(CGF, S);
5144}
5145
5146void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5147 const ObjCAtSynchronizedStmt &S) {
5148 return EmitTryOrSynchronizedStmt(CGF, S);
5149}
5150
5151namespace {
5152struct PerformFragileFinally final : EHScopeStack::Cleanup {
5153 const Stmt &S;
5154 Address SyncArgSlot;
5155 Address CallTryExitVar;
5156 Address ExceptionData;
5157 ObjCTypesHelper &ObjCTypes;
5158 PerformFragileFinally(const Stmt *S, Address SyncArgSlot,
5159 Address CallTryExitVar, Address ExceptionData,
5160 ObjCTypesHelper *ObjCTypes)
5161 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5162 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5163
5164 void Emit(CodeGenFunction &CGF, Flags flags) override {
5165 // Check whether we need to call objc_exception_try_exit.
5166 // In optimized code, this branch will always be folded.
5167 llvm::BasicBlock *FinallyCallExit =
5168 CGF.createBasicBlock("finally.call_exit");
5169 llvm::BasicBlock *FinallyNoCallExit =
5170 CGF.createBasicBlock("finally.no_call_exit");
5171 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
5172 FinallyCallExit, FinallyNoCallExit);
5173
5174 CGF.EmitBlock(FinallyCallExit);
5175 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
5176 ExceptionData.emitRawPointer(CGF));
5177
5178 CGF.EmitBlock(FinallyNoCallExit);
5179
5180 if (isa<ObjCAtTryStmt>(S)) {
5181 if (const ObjCAtFinallyStmt *FinallyStmt =
5182 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
5183 // Don't try to do the @finally if this is an EH cleanup.
5184 if (flags.isForEHCleanup())
5185 return;
5186
5187 // Save the current cleanup destination in case there's
5188 // control flow inside the finally statement.
5189 llvm::Value *CurCleanupDest =
5191
5192 CGF.EmitStmt(FinallyStmt->getFinallyBody());
5193
5194 if (CGF.HaveInsertPoint()) {
5195 CGF.Builder.CreateStore(CurCleanupDest,
5197 } else {
5198 // Currently, the end of the cleanup must always exist.
5199 CGF.EnsureInsertPoint();
5200 }
5201 }
5202 } else {
5203 // Emit objc_sync_exit(expr); as finally's sole statement for
5204 // @synchronized.
5205 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
5206 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
5207 }
5208 }
5209};
5210
5211class FragileHazards {
5212 CodeGenFunction &CGF;
5213 SmallVector<llvm::Value *, 20> Locals;
5214 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5215
5216 llvm::InlineAsm *ReadHazard;
5217 llvm::InlineAsm *WriteHazard;
5218
5219 llvm::FunctionType *GetAsmFnType();
5220
5221 void collectLocals();
5222 void emitReadHazard(CGBuilderTy &Builder);
5223
5224public:
5225 FragileHazards(CodeGenFunction &CGF);
5226
5227 void emitWriteHazard();
5228 void emitHazardsInNewBlocks();
5229};
5230} // end anonymous namespace
5231
5232/// Create the fragile-ABI read and write hazards based on the current
5233/// state of the function, which is presumed to be immediately prior
5234/// to a @try block. These hazards are used to maintain correct
5235/// semantics in the face of optimization and the fragile ABI's
5236/// cavalier use of setjmp/longjmp.
5237FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5238 collectLocals();
5239
5240 if (Locals.empty())
5241 return;
5242
5243 // Collect all the blocks in the function.
5244 for (llvm::BasicBlock &BB : *CGF.CurFn)
5245 BlocksBeforeTry.insert(&BB);
5246
5247 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5248
5249 // Create a read hazard for the allocas. This inhibits dead-store
5250 // optimizations and forces the values to memory. This hazard is
5251 // inserted before any 'throwing' calls in the protected scope to
5252 // reflect the possibility that the variables might be read from the
5253 // catch block if the call throws.
5254 {
5255 std::string Constraint;
5256 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5257 if (I)
5258 Constraint += ',';
5259 Constraint += "*m";
5260 }
5261
5262 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
5263 }
5264
5265 // Create a write hazard for the allocas. This inhibits folding
5266 // loads across the hazard. This hazard is inserted at the
5267 // beginning of the catch path to reflect the possibility that the
5268 // variables might have been written within the protected scope.
5269 {
5270 std::string Constraint;
5271 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
5272 if (I)
5273 Constraint += ',';
5274 Constraint += "=*m";
5275 }
5276
5277 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
5278 }
5279}
5280
5281/// Emit a write hazard at the current location.
5282void FragileHazards::emitWriteHazard() {
5283 if (Locals.empty())
5284 return;
5285
5286 llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
5287 for (auto Pair : llvm::enumerate(Locals))
5288 Call->addParamAttr(
5289 Pair.index(),
5290 llvm::Attribute::get(
5291 CGF.getLLVMContext(), llvm::Attribute::ElementType,
5292 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
5293}
5294
5295void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
5296 assert(!Locals.empty());
5297 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5298 call->setDoesNotThrow();
5299 call->setCallingConv(CGF.getRuntimeCC());
5300 for (auto Pair : llvm::enumerate(Locals))
5301 call->addParamAttr(
5302 Pair.index(),
5303 llvm::Attribute::get(
5304 Builder.getContext(), llvm::Attribute::ElementType,
5305 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
5306}
5307
5308/// Emit read hazards in all the protected blocks, i.e. all the blocks
5309/// which have been inserted since the beginning of the try.
5310void FragileHazards::emitHazardsInNewBlocks() {
5311 if (Locals.empty())
5312 return;
5313
5314 CGBuilderTy Builder(CGF.CGM, CGF.getLLVMContext());
5315
5316 // Iterate through all blocks, skipping those prior to the try.
5317 for (llvm::BasicBlock &BB : *CGF.CurFn) {
5318 if (BlocksBeforeTry.count(&BB))
5319 continue;
5320
5321 // Walk through all the calls in the block.
5322 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5323 ++BI) {
5324 llvm::Instruction &I = *BI;
5325
5326 // Ignore instructions that aren't non-intrinsic calls.
5327 // These are the only calls that can possibly call longjmp.
5329 continue;
5331 continue;
5332
5333 // Ignore call sites marked nounwind. This may be questionable,
5334 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
5335 if (cast<llvm::CallBase>(I).doesNotThrow())
5336 continue;
5337
5338 // Insert a read hazard before the call. This will ensure that
5339 // any writes to the locals are performed before making the
5340 // call. If the call throws, then this is sufficient to
5341 // guarantee correctness as long as it doesn't also write to any
5342 // locals.
5343 Builder.SetInsertPoint(&BB, BI);
5344 emitReadHazard(Builder);
5345 }
5346 }
5347}
5348
5349static void addIfPresent(llvm::DenseSet<llvm::Value *> &S, Address V) {
5350 if (V.isValid())
5351 if (llvm::Value *Ptr = V.getBasePointer())
5352 S.insert(Ptr);
5353}
5354
5355void FragileHazards::collectLocals() {
5356 // Compute a set of allocas to ignore.
5357 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5358 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
5359 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
5360
5361 // Collect all the allocas currently in the function. This is
5362 // probably way too aggressive.
5363 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
5364 for (llvm::Instruction &I : Entry)
5365 if (isa<llvm::AllocaInst>(I) && !AllocasToIgnore.count(&I))
5366 Locals.push_back(&I);
5367}
5368
5369llvm::FunctionType *FragileHazards::GetAsmFnType() {
5370 SmallVector<llvm::Type *, 16> tys(Locals.size());
5371 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
5372 tys[i] = Locals[i]->getType();
5373 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
5374}
5375
5376/*
5377
5378 Objective-C setjmp-longjmp (sjlj) Exception Handling
5379 --
5380
5381 A catch buffer is a setjmp buffer plus:
5382 - a pointer to the exception that was caught
5383 - a pointer to the previous exception data buffer
5384 - two pointers of reserved storage
5385 Therefore catch buffers form a stack, with a pointer to the top
5386 of the stack kept in thread-local storage.
5387
5388 objc_exception_try_enter pushes a catch buffer onto the EH stack.
5389 objc_exception_try_exit pops the given catch buffer, which is
5390 required to be the top of the EH stack.
5391 objc_exception_throw pops the top of the EH stack, writes the
5392 thrown exception into the appropriate field, and longjmps
5393 to the setjmp buffer. It crashes the process (with a printf
5394 and an abort()) if there are no catch buffers on the stack.
5395 objc_exception_extract just reads the exception pointer out of the
5396 catch buffer.
5397
5398 There's no reason an implementation couldn't use a light-weight
5399 setjmp here --- something like __builtin_setjmp, but API-compatible
5400 with the heavyweight setjmp. This will be more important if we ever
5401 want to implement correct ObjC/C++ exception interactions for the
5402 fragile ABI.
5403
5404 Note that for this use of setjmp/longjmp to be correct in the presence of
5405 optimization, we use inline assembly on the set of local variables to force
5406 flushing locals to memory immediately before any protected calls and to
5407 inhibit optimizing locals across the setjmp->catch edge.
5408
5409 The basic framework for a @try-catch-finally is as follows:
5410 {
5411 objc_exception_data d;
5412 id _rethrow = null;
5413 bool _call_try_exit = true;
5414
5415 objc_exception_try_enter(&d);
5416 if (!setjmp(d.jmp_buf)) {
5417 ... try body ...
5418 } else {
5419 // exception path
5420 id _caught = objc_exception_extract(&d);
5421
5422 // enter new try scope for handlers
5423 if (!setjmp(d.jmp_buf)) {
5424 ... match exception and execute catch blocks ...
5425
5426 // fell off end, rethrow.
5427 _rethrow = _caught;
5428 ... jump-through-finally to finally_rethrow ...
5429 } else {
5430 // exception in catch block
5431 _rethrow = objc_exception_extract(&d);
5432 _call_try_exit = false;
5433 ... jump-through-finally to finally_rethrow ...
5434 }
5435 }
5436 ... jump-through-finally to finally_end ...
5437
5438 finally:
5439 if (_call_try_exit)
5440 objc_exception_try_exit(&d);
5441
5442 ... finally block ....
5443 ... dispatch to finally destination ...
5444
5445 finally_rethrow:
5446 objc_exception_throw(_rethrow);
5447
5448 finally_end:
5449 }
5450
5451 This framework differs slightly from the one gcc uses, in that gcc
5452 uses _rethrow to determine if objc_exception_try_exit should be called
5453 and if the object should be rethrown. This breaks in the face of
5454 throwing nil and introduces unnecessary branches.
5455
5456 We specialize this framework for a few particular circumstances:
5457
5458 - If there are no catch blocks, then we avoid emitting the second
5459 exception handling context.
5460
5461 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
5462 e)) we avoid emitting the code to rethrow an uncaught exception.
5463
5464 - FIXME: If there is no @finally block we can do a few more
5465 simplifications.
5466
5467 Rethrows and Jumps-Through-Finally
5468 --
5469
5470 '@throw;' is supported by pushing the currently-caught exception
5471 onto ObjCEHStack while the @catch blocks are emitted.
5472
5473 Branches through the @finally block are handled with an ordinary
5474 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
5475 exceptions are not compatible with C++ exceptions, and this is
5476 hardly the only place where this will go wrong.
5477
5478 @synchronized(expr) { stmt; } is emitted as if it were:
5479 id synch_value = expr;
5480 objc_sync_enter(synch_value);
5481 @try { stmt; } @finally { objc_sync_exit(synch_value); }
5482*/
5483
5484void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5485 const Stmt &S) {
5486 bool isTry = isa<ObjCAtTryStmt>(S);
5487
5488 // A destination for the fall-through edges of the catch handlers to
5489 // jump to.
5490 CodeGenFunction::JumpDest FinallyEnd =
5491 CGF.getJumpDestInCurrentScope("finally.end");
5492
5493 // A destination for the rethrow edge of the catch handlers to jump
5494 // to.
5495 CodeGenFunction::JumpDest FinallyRethrow =
5496 CGF.getJumpDestInCurrentScope("finally.rethrow");
5497
5498 // For @synchronized, call objc_sync_enter(sync.expr). The
5499 // evaluation of the expression must occur before we enter the
5500 // @synchronized. We can't avoid a temp here because we need the
5501 // value to be preserved. If the backend ever does liveness
5502 // correctly after setjmp, this will be unnecessary.
5503 Address SyncArgSlot = Address::invalid();
5504 if (!isTry) {
5505 llvm::Value *SyncArg =
5506 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
5507 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5508 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
5509
5510 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(),
5511 CGF.getPointerAlign(), "sync.arg");
5512 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
5513 }
5514
5515 // Allocate memory for the setjmp buffer. This needs to be kept
5516 // live throughout the try and catch blocks.
5517 Address ExceptionData = CGF.CreateTempAlloca(
5518 ObjCTypes.ExceptionDataTy, CGF.getPointerAlign(), "exceptiondata.ptr");
5519
5520 // Create the fragile hazards. Note that this will not capture any
5521 // of the allocas required for exception processing, but will
5522 // capture the current basic block (which extends all the way to the
5523 // setjmp call) as "before the @try".
5524 FragileHazards Hazards(CGF);
5525
5526 // Create a flag indicating whether the cleanup needs to call
5527 // objc_exception_try_exit. This is true except when
5528 // - no catches match and we're branching through the cleanup
5529 // just to rethrow the exception, or
5530 // - a catch matched and we're falling out of the catch handler.
5531 // The setjmp-safety rule here is that we should always store to this
5532 // variable in a place that dominates the branch through the cleanup
5533 // without passing through any setjmps.
5534 Address CallTryExitVar = CGF.CreateTempAlloca(
5535 CGF.Builder.getInt1Ty(), CharUnits::One(), "_call_try_exit");
5536
5537 // A slot containing the exception to rethrow. Only needed when we
5538 // have both a @catch and a @finally.
5539 Address PropagatingExnVar = Address::invalid();
5540
5541 // Push a normal cleanup to leave the try scope.
5542 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
5543 SyncArgSlot, CallTryExitVar,
5544 ExceptionData, &ObjCTypes);
5545
5546 // Enter a try block:
5547 // - Call objc_exception_try_enter to push ExceptionData on top of
5548 // the EH stack.
5549 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
5550 ExceptionData.emitRawPointer(CGF));
5551
5552 // - Call setjmp on the exception data buffer.
5553 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
5554 llvm::Value *GEPIndexes[] = {Zero, Zero, Zero};
5555 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
5556 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5557 "setjmp_buffer");
5558 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5559 ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
5560 SetJmpResult->setCanReturnTwice();
5561
5562 // If setjmp returned 0, enter the protected block; otherwise,
5563 // branch to the handler.
5564 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
5565 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
5566 llvm::Value *DidCatch =
5567 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
5568 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5569
5570 // Emit the protected block.
5571 CGF.EmitBlock(TryBlock);
5572 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
5573 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
5574 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
5575
5576 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
5577
5578 // Emit the exception handler block.
5579 CGF.EmitBlock(TryHandler);
5580
5581 // Don't optimize loads of the in-scope locals across this point.
5582 Hazards.emitWriteHazard();
5583
5584 // For a @synchronized (or a @try with no catches), just branch
5585 // through the cleanup to the rethrow block.
5586 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
5587 // Tell the cleanup not to re-pop the exit.
5588 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
5589 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5590
5591 // Otherwise, we have to match against the caught exceptions.
5592 } else {
5593 // Retrieve the exception object. We may emit multiple blocks but
5594 // nothing can cross this so the value is already in SSA form.
5595 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5596 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5597 "caught");
5598
5599 // Push the exception to rethrow onto the EH value stack for the
5600 // benefit of any @throws in the handlers.
5601 CGF.ObjCEHValueStack.push_back(Caught);
5602
5603 const ObjCAtTryStmt *AtTryStmt = cast<ObjCAtTryStmt>(&S);
5604
5605 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
5606
5607 llvm::BasicBlock *CatchBlock = nullptr;
5608 llvm::BasicBlock *CatchHandler = nullptr;
5609 if (HasFinally) {
5610 // Save the currently-propagating exception before
5611 // objc_exception_try_enter clears the exception slot.
5612 PropagatingExnVar = CGF.CreateTempAlloca(
5613 Caught->getType(), CGF.getPointerAlign(), "propagating_exception");
5614 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
5615
5616 // Enter a new exception try block (in case a @catch block
5617 // throws an exception).
5618 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
5619 ExceptionData.emitRawPointer(CGF));
5620
5621 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
5622 ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp.result");
5623 SetJmpResult->setCanReturnTwice();
5624
5625 llvm::Value *Threw =
5626 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
5627
5628 CatchBlock = CGF.createBasicBlock("catch");
5629 CatchHandler = CGF.createBasicBlock("catch_for_catch");
5630 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5631
5632 CGF.EmitBlock(CatchBlock);
5633 }
5634
5635 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
5636
5637 // Handle catch list. As a special case we check if everything is
5638 // matched and avoid generating code for falling off the end if
5639 // so.
5640 bool AllMatched = false;
5641 for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) {
5642 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5643 const ObjCObjectPointerType *OPT = nullptr;
5644
5645 // catch(...) always matches.
5646 if (!CatchParam) {
5647 AllMatched = true;
5648 } else {
5649 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
5650
5651 // catch(id e) always matches under this ABI, since only
5652 // ObjC exceptions end up here in the first place.
5653 // FIXME: For the time being we also match id<X>; this should
5654 // be rejected by Sema instead.
5655 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
5656 AllMatched = true;
5657 }
5658
5659 // If this is a catch-all, we don't need to test anything.
5660 if (AllMatched) {
5661 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5662
5663 if (CatchParam) {
5664 CGF.EmitAutoVarDecl(*CatchParam);
5665 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5666
5667 // These types work out because ConvertType(id) == i8*.
5668 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5669 }
5670
5671 CGF.EmitStmt(CatchStmt->getCatchBody());
5672
5673 // The scope of the catch variable ends right here.
5674 CatchVarCleanups.ForceCleanup();
5675
5676 CGF.EmitBranchThroughCleanup(FinallyEnd);
5677 break;
5678 }
5679
5680 assert(OPT && "Unexpected non-object pointer type in @catch");
5681 const ObjCObjectType *ObjTy = OPT->getObjectType();
5682
5683 // FIXME: @catch (Class c) ?
5684 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5685 assert(IDecl && "Catch parameter must have Objective-C type!");
5686
5687 // Check if the @catch block matches the exception object.
5688 llvm::Value *Class = EmitClassRef(CGF, IDecl);
5689
5690 llvm::Value *matchArgs[] = {Class, Caught};
5691 llvm::CallInst *Match = CGF.EmitNounwindRuntimeCall(
5692 ObjCTypes.getExceptionMatchFn(), matchArgs, "match");
5693
5694 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
5695 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
5696
5697 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
5698 MatchedBlock, NextCatchBlock);
5699
5700 // Emit the @catch block.
5701 CGF.EmitBlock(MatchedBlock);
5702
5703 // Collect any cleanups for the catch variable. The scope lasts until
5704 // the end of the catch body.
5705 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
5706
5707 CGF.EmitAutoVarDecl(*CatchParam);
5708 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
5709
5710 // Initialize the catch variable.
5711 llvm::Value *Tmp = CGF.Builder.CreateBitCast(
5712 Caught, CGF.ConvertType(CatchParam->getType()));
5713 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5714
5715 CGF.EmitStmt(CatchStmt->getCatchBody());
5716
5717 // We're done with the catch variable.
5718 CatchVarCleanups.ForceCleanup();
5719
5720 CGF.EmitBranchThroughCleanup(FinallyEnd);
5721
5722 CGF.EmitBlock(NextCatchBlock);
5723 }
5724
5725 CGF.ObjCEHValueStack.pop_back();
5726
5727 // If nothing wanted anything to do with the caught exception,
5728 // kill the extract call.
5729 if (Caught->use_empty())
5730 Caught->eraseFromParent();
5731
5732 if (!AllMatched)
5733 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5734
5735 if (HasFinally) {
5736 // Emit the exception handler for the @catch blocks.
5737 CGF.EmitBlock(CatchHandler);
5738
5739 // In theory we might now need a write hazard, but actually it's
5740 // unnecessary because there's no local-accessing code between
5741 // the try's write hazard and here.
5742 // Hazards.emitWriteHazard();
5743
5744 // Extract the new exception and save it to the
5745 // propagating-exception slot.
5746 assert(PropagatingExnVar.isValid());
5747 llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall(
5748 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5749 "caught");
5750 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
5751
5752 // Don't pop the catch handler; the throw already did.
5753 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
5754 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5755 }
5756 }
5757
5758 // Insert read hazards as required in the new blocks.
5759 Hazards.emitHazardsInNewBlocks();
5760
5761 // Pop the cleanup.
5762 CGF.Builder.restoreIP(TryFallthroughIP);
5763 if (CGF.HaveInsertPoint())
5764 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
5765 CGF.PopCleanupBlock();
5766 CGF.EmitBlock(FinallyEnd.getBlock(), true);
5767
5768 // Emit the rethrow block.
5769 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
5770 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
5771 if (CGF.HaveInsertPoint()) {
5772 // If we have a propagating-exception variable, check it.
5773 llvm::Value *PropagatingExn;
5774 if (PropagatingExnVar.isValid()) {
5775 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
5776
5777 // Otherwise, just look in the buffer for the exception to throw.
5778 } else {
5779 llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(
5780 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5781 PropagatingExn = Caught;
5782 }
5783
5784 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
5785 PropagatingExn);
5786 CGF.Builder.CreateUnreachable();
5787 }
5788
5789 CGF.Builder.restoreIP(SavedIP);
5790}
5791
5792void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5793 const ObjCAtThrowStmt &S,
5794 bool ClearInsertionPoint) {
5795 llvm::Value *ExceptionAsObject;
5796
5797 if (const Expr *ThrowExpr = S.getThrowExpr()) {
5798 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
5799 ExceptionAsObject =
5800 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5801 } else {
5802 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
5803 "Unexpected rethrow outside @catch block.");
5804 ExceptionAsObject = CGF.ObjCEHValueStack.back();
5805 }
5806
5807 CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5808 ->setDoesNotReturn();
5809 CGF.Builder.CreateUnreachable();
5810
5811 // Clear the insertion point to indicate we are in unreachable code.
5812 if (ClearInsertionPoint)
5813 CGF.Builder.ClearInsertionPoint();
5814}
5815
5816/// EmitObjCWeakRead - Code gen for loading value of a __weak
5817/// object: objc_read_weak (id *src)
5818///
5819llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5820 Address AddrWeakObj) {
5821 llvm::Type *DestTy = AddrWeakObj.getElementType();
5822 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
5823 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
5824 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
5825 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread");
5826 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
5827 return read_weak;
5828}
5829
5830/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5831/// objc_assign_weak (id src, id *dst)
5832///
5833void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5834 llvm::Value *src, Address dst) {
5835 llvm::Type *SrcTy = src->getType();
5836 if (!isa<llvm::PointerType>(SrcTy)) {
5837 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5838 assert(Size <= 8 && "does not support size > 8");
5839 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5840 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5841 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5842 }
5843 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5844 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5845 ObjCTypes.PtrObjectPtrTy);
5846 llvm::Value *args[] = {src, dstVal};
5847 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5848 "weakassign");
5849}
5850
5851/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5852/// objc_assign_global (id src, id *dst)
5853///
5854void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5855 llvm::Value *src, Address dst,
5856 bool threadlocal) {
5857 llvm::Type *SrcTy = src->getType();
5858 if (!isa<llvm::PointerType>(SrcTy)) {
5859 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5860 assert(Size <= 8 && "does not support size > 8");
5861 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5862 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5863 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5864 }
5865 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5866 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5867 ObjCTypes.PtrObjectPtrTy);
5868 llvm::Value *args[] = {src, dstVal};
5869 if (!threadlocal)
5870 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5871 "globalassign");
5872 else
5873 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5874 "threadlocalassign");
5875}
5876
5877/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5878/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
5879///
5880void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5881 llvm::Value *src, Address dst,
5882 llvm::Value *ivarOffset) {
5883 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
5884 llvm::Type *SrcTy = src->getType();
5885 if (!isa<llvm::PointerType>(SrcTy)) {
5886 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5887 assert(Size <= 8 && "does not support size > 8");
5888 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5889 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5890 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5891 }
5892 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5893 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5894 ObjCTypes.PtrObjectPtrTy);
5895 llvm::Value *args[] = {src, dstVal, ivarOffset};
5896 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5897}
5898
5899/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5900/// objc_assign_strongCast (id src, id *dst)
5901///
5902void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5903 llvm::Value *src, Address dst) {
5904 llvm::Type *SrcTy = src->getType();
5905 if (!isa<llvm::PointerType>(SrcTy)) {
5906 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5907 assert(Size <= 8 && "does not support size > 8");
5908 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5909 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5910 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5911 }
5912 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5913 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5914 ObjCTypes.PtrObjectPtrTy);
5915 llvm::Value *args[] = {src, dstVal};
5916 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5917 "strongassign");
5918}
5919
5920void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5921 Address DestPtr, Address SrcPtr,
5922 llvm::Value *size) {
5923 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5924 SrcPtr.emitRawPointer(CGF), size};
5925 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5926}
5927
5928/// EmitObjCValueForIvar - Code Gen for ivar reference.
5929///
5930LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5931 QualType ObjectTy,
5932 llvm::Value *BaseValue,
5933 const ObjCIvarDecl *Ivar,
5934 unsigned CVRQualifiers) {
5935 const ObjCInterfaceDecl *ID =
5936 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5937 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5938 EmitIvarOffset(CGF, ID, Ivar));
5939}
5940
5941llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5942 const ObjCInterfaceDecl *Interface,
5943 const ObjCIvarDecl *Ivar) {
5944 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5945 return llvm::ConstantInt::get(
5946 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5947}
5948
5949/* *** Private Interface *** */
5950
5951std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5952 StringRef MachOAttributes) {
5953 switch (CGM.getTriple().getObjectFormat()) {
5954 case llvm::Triple::UnknownObjectFormat:
5955 llvm_unreachable("unexpected object file format");
5956 case llvm::Triple::MachO: {
5957 if (MachOAttributes.empty())
5958 return ("__DATA," + Section).str();
5959 return ("__DATA," + Section + "," + MachOAttributes).str();
5960 }
5961 case llvm::Triple::ELF:
5962 assert(Section.starts_with("__") && "expected the name to begin with __");
5963 return Section.substr(2).str();
5964 case llvm::Triple::COFF:
5965 assert(Section.starts_with("__") && "expected the name to begin with __");
5966 return ("." + Section.substr(2) + "$B").str();
5967 case llvm::Triple::Wasm:
5968 case llvm::Triple::GOFF:
5969 case llvm::Triple::SPIRV:
5970 case llvm::Triple::XCOFF:
5971 case llvm::Triple::DXContainer:
5972 llvm::report_fatal_error(
5973 "Objective-C support is unimplemented for object file format");
5974 }
5975
5976 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");
5977}
5978
5979// clang-format off
5980/// EmitImageInfo - Emit the image info marker used to encode some module
5981/// level information.
5982///
5983/// See: <rdr://4810609&4810587&4810587>
5984/// struct IMAGE_INFO {
5985/// unsigned version;
5986/// unsigned flags;
5987/// };
5988enum ImageInfoFlags {
5989 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5990 eImageInfo_GarbageCollected = (1 << 1),
5991 eImageInfo_GCOnly = (1 << 2),
5992 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5993
5994 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5995 eImageInfo_ImageIsSimulated = (1 << 5),
5996 eImageInfo_ClassProperties = (1 << 6)
5997};
5998// clang-format on
5999
6000void CGObjCCommonMac::EmitImageInfo() {
6001 unsigned version = 0; // Version is unused?
6002 std::string Section =
6003 (ObjCABI == 1)
6004 ? "__OBJC,__image_info,regular"
6005 : GetSectionName("__objc_imageinfo", "regular,no_dead_strip");
6006
6007 // Generate module-level named metadata to convey this information to the
6008 // linker and code-gen.
6009 llvm::Module &Mod = CGM.getModule();
6010
6011 // Add the ObjC ABI version to the module flags.
6012 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
6013 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
6014 version);
6015 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
6016 llvm::MDString::get(VMContext, Section));
6017
6018 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6019 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6020 // Non-GC overrides those files which specify GC.
6021 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Garbage Collection",
6022 llvm::ConstantInt::get(Int8Ty, 0));
6023 } else {
6024 // Add the ObjC garbage collection value.
6025 Mod.addModuleFlag(
6026 llvm::Module::Error, "Objective-C Garbage Collection",
6027 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6028
6029 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6030 // Add the ObjC GC Only value.
6031 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
6032 eImageInfo_GCOnly);
6033
6034 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6035 llvm::Metadata *Ops[2] = {
6036 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
6037 llvm::ConstantAsMetadata::get(
6038 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6039 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
6040 llvm::MDNode::get(VMContext, Ops));
6041 }
6042 }
6043
6044 // Indicate whether we're compiling this to run on a simulator.
6045 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6046 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
6047 eImageInfo_ImageIsSimulated);
6048
6049 // Indicate whether we are generating class properties.
6050 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",
6051 eImageInfo_ClassProperties);
6052
6053 // Indicate whether we want enforcement of pointer signing for class_ro_t
6054 // pointers.
6055 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6056 Mod.addModuleFlag(llvm::Module::Error,
6057 "Objective-C Enforce ClassRO Pointer Signing",
6058 eImageInfo_SignedClassRO);
6059 else
6060 Mod.addModuleFlag(llvm::Module::Error,
6061 "Objective-C Enforce ClassRO Pointer Signing",
6062 llvm::ConstantInt::get(Int8Ty, 0));
6063}
6064
6065// struct objc_module {
6066// unsigned long version;
6067// unsigned long size;
6068// const char *name;
6069// Symtab symtab;
6070// };
6071
6072// FIXME: Get from somewhere
6073static const int ModuleVersion = 7;
6074
6075void CGObjCMac::EmitModuleInfo() {
6076 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6077
6078 ConstantInitBuilder builder(CGM);
6079 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6080 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6081 values.addInt(ObjCTypes.LongTy, Size);
6082 // This used to be the filename, now it is unused. <rdr://4327263>
6083 values.add(GetClassName(StringRef("")));
6084 values.add(EmitModuleSymbols());
6085 CreateMetadataVar("OBJC_MODULES", values,
6086 "__OBJC,__module_info,regular,no_dead_strip",
6087 CGM.getPointerAlign(), true);
6088}
6089
6090llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6091 unsigned NumClasses = DefinedClasses.size();
6092 unsigned NumCategories = DefinedCategories.size();
6093
6094 // Return null if no symbols were defined.
6095 if (!NumClasses && !NumCategories)
6096 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6097
6098 ConstantInitBuilder builder(CGM);
6099 auto values = builder.beginStruct();
6100 values.addInt(ObjCTypes.LongTy, 0);
6101 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6102 values.addInt(ObjCTypes.ShortTy, NumClasses);
6103 values.addInt(ObjCTypes.ShortTy, NumCategories);
6104
6105 // The runtime expects exactly the list of defined classes followed
6106 // by the list of defined categories, in a single array.
6107 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6108 for (unsigned i = 0; i < NumClasses; i++) {
6109 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6110 assert(ID);
6111 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6112 // We are implementing a weak imported interface. Give it external linkage
6113 if (ID->isWeakImported() && !IMP->isWeakImported())
6114 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6115
6116 array.add(DefinedClasses[i]);
6117 }
6118 for (unsigned i = 0; i < NumCategories; i++)
6119 array.add(DefinedCategories[i]);
6120
6121 array.finishAndAddTo(values);
6122
6123 llvm::GlobalVariable *GV = CreateMetadataVar(
6124 "OBJC_SYMBOLS", values, "__OBJC,__symbols,regular,no_dead_strip",
6125 CGM.getPointerAlign(), true);
6126 return GV;
6127}
6128
6129llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6130 IdentifierInfo *II) {
6131 LazySymbols.insert(II);
6132
6133 llvm::GlobalVariable *&Entry = ClassReferences[II];
6134
6135 if (!Entry) {
6136 Entry =
6137 CreateMetadataVar("OBJC_CLASS_REFERENCES_", GetClassName(II->getName()),
6138 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
6139 CGM.getPointerAlign(), true);
6140 }
6141
6142 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6143 CGF.getPointerAlign());
6144}
6145
6146llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6147 const ObjCInterfaceDecl *ID) {
6148 // If the class has the objc_runtime_visible attribute, we need to
6149 // use the Objective-C runtime to get the class.
6150 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6151 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6152
6153 IdentifierInfo *RuntimeName =
6154 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6155 return EmitClassRefFromId(CGF, RuntimeName);
6156}
6157
6158llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6159 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
6160 return EmitClassRefFromId(CGF, II);
6161}
6162
6163llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6164 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6165}
6166
6167ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6168 CharUnits Align = CGM.getPointerAlign();
6169
6170 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6171 if (!Entry) {
6172 Entry = CreateMetadataVar(
6173 "OBJC_SELECTOR_REFERENCES_", GetMethodVarName(Sel),
6174 "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);
6175 Entry->setExternallyInitialized(true);
6176 }
6177
6178 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6179}
6180
6181llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6182 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6183 if (!Entry)
6184 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6185 return getConstantGEP(VMContext, Entry, 0, 0);
6186}
6187
6188llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6189 return MethodDefinitions.lookup(MD);
6190}
6191
6192/// GetIvarLayoutName - Returns a unique constant for the given
6193/// ivar layout bitmap.
6194llvm::Constant *
6195CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6196 const ObjCCommonTypesHelper &ObjCTypes) {
6197 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6198}
6199
6200void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6201 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6202
6203 // If this is a union, remember that we had one, because it might mess
6204 // up the ordering of layout entries.
6205 if (RD->isUnion())
6206 IsDisordered = true;
6207
6208 const ASTRecordLayout *recLayout = nullptr;
6209 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6210 [&](const FieldDecl *field) -> CharUnits {
6211 if (!recLayout)
6212 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6213 auto offsetInBits =
6214 recLayout->getFieldOffset(field->getFieldIndex());
6215 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6216 });
6217}
6218
6219template <class Iterator, class GetOffsetFn>
6220void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6221 CharUnits aggregateOffset,
6222 const GetOffsetFn &getOffset) {
6223 for (; begin != end; ++begin) {
6224 auto field = *begin;
6225
6226 // Skip over bitfields.
6227 if (field->isBitField()) {
6228 continue;
6229 }
6230
6231 // Compute the offset of the field within the aggregate.
6232 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6233
6234 visitField(field, fieldOffset);
6235 }
6236}
6237
6238/// Collect layout information for the given fields into IvarsInfo.
6239void IvarLayoutBuilder::visitField(const FieldDecl *field,
6240 CharUnits fieldOffset) {
6241 QualType fieldType = field->getType();
6242
6243 // Drill down into arrays.
6244 uint64_t numElts = 1;
6245 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6246 numElts = 0;
6247 fieldType = arrayType->getElementType();
6248 }
6249 // Unlike incomplete arrays, constant arrays can be nested.
6250 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6251 numElts *= arrayType->getZExtSize();
6252 fieldType = arrayType->getElementType();
6253 }
6254
6255 assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
6256
6257 // If we ended up with a zero-sized array, we've done what we can do within
6258 // the limits of this layout encoding.
6259 if (numElts == 0)
6260 return;
6261
6262 // Recurse if the base element type is a record type.
6263 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6264 size_t oldEnd = IvarsInfo.size();
6265
6266 visitRecord(recType, fieldOffset);
6267
6268 // If we have an array, replicate the first entry's layout information.
6269 auto numEltEntries = IvarsInfo.size() - oldEnd;
6270 if (numElts != 1 && numEltEntries != 0) {
6271 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6272 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6273 // Copy the last numEltEntries onto the end of the array, adjusting
6274 // each for the element size.
6275 for (size_t i = 0; i != numEltEntries; ++i) {
6276 auto firstEntry = IvarsInfo[oldEnd + i];
6277 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6278 firstEntry.SizeInWords));
6279 }
6280 }
6281 }
6282
6283 return;
6284 }
6285
6286 // Classify the element type.
6287 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6288
6289 // If it matches what we're looking for, add an entry.
6290 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6291 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6292 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6293 CGM.getPointerSize());
6294 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6295 }
6296}
6297
6298/// buildBitmap - This routine does the horsework of taking the offsets of
6299/// strong/weak references and creating a bitmap. The bitmap is also
6300/// returned in the given buffer, suitable for being passed to \c dump().
6301llvm::Constant *
6302IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6303 llvm::SmallVectorImpl<unsigned char> &buffer) {
6304 // The bitmap is a series of skip/scan instructions, aligned to word
6305 // boundaries. The skip is performed first.
6306 const unsigned char MaxNibble = 0xF;
6307 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6308 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6309
6310 assert(!IvarsInfo.empty() && "generating bitmap for no data");
6311
6312 // Sort the ivar info on byte position in case we encounterred a
6313 // union nested in the ivar list.
6314 if (IsDisordered) {
6315 // This isn't a stable sort, but our algorithm should handle it fine.
6316 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6317 } else {
6318 assert(llvm::is_sorted(IvarsInfo));
6319 }
6320 assert(IvarsInfo.back().Offset < InstanceEnd);
6321
6322 assert(buffer.empty());
6323
6324 // Skip the next N words.
6325 auto skip = [&](unsigned numWords) {
6326 assert(numWords > 0);
6327
6328 // Try to merge into the previous byte. Since scans happen second, we
6329 // can't do this if it includes a scan.
6330 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6331 unsigned lastSkip = buffer.back() >> SkipShift;
6332 if (lastSkip < MaxNibble) {
6333 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6334 numWords -= claimed;
6335 lastSkip += claimed;
6336 buffer.back() = (lastSkip << SkipShift);
6337 }
6338 }
6339
6340 while (numWords >= MaxNibble) {
6341 buffer.push_back(MaxNibble << SkipShift);
6342 numWords -= MaxNibble;
6343 }
6344 if (numWords) {
6345 buffer.push_back(numWords << SkipShift);
6346 }
6347 };
6348
6349 // Scan the next N words.
6350 auto scan = [&](unsigned numWords) {
6351 assert(numWords > 0);
6352
6353 // Try to merge into the previous byte. Since scans happen second, we can
6354 // do this even if it includes a skip.
6355 if (!buffer.empty()) {
6356 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6357 if (lastScan < MaxNibble) {
6358 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6359 numWords -= claimed;
6360 lastScan += claimed;
6361 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6362 }
6363 }
6364
6365 while (numWords >= MaxNibble) {
6366 buffer.push_back(MaxNibble << ScanShift);
6367 numWords -= MaxNibble;
6368 }
6369 if (numWords) {
6370 buffer.push_back(numWords << ScanShift);
6371 }
6372 };
6373
6374 // One past the end of the last scan.
6375 unsigned endOfLastScanInWords = 0;
6376 const CharUnits WordSize = CGM.getPointerSize();
6377
6378 // Consider all the scan requests.
6379 for (auto &request : IvarsInfo) {
6380 CharUnits beginOfScan = request.Offset - InstanceBegin;
6381
6382 // Ignore scan requests that don't start at an even multiple of the
6383 // word size. We can't encode them.
6384 if (!beginOfScan.isMultipleOf(WordSize))
6385 continue;
6386
6387 // Ignore scan requests that start before the instance start.
6388 // This assumes that scans never span that boundary. The boundary
6389 // isn't the true start of the ivars, because in the fragile-ARC case
6390 // it's rounded up to word alignment, but the test above should leave
6391 // us ignoring that possibility.
6392 if (beginOfScan.isNegative()) {
6393 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6394 continue;
6395 }
6396
6397 unsigned beginOfScanInWords = beginOfScan / WordSize;
6398 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6399
6400 // If the scan starts some number of words after the last one ended,
6401 // skip forward.
6402 if (beginOfScanInWords > endOfLastScanInWords) {
6403 skip(beginOfScanInWords - endOfLastScanInWords);
6404
6405 // Otherwise, start scanning where the last left off.
6406 } else {
6407 beginOfScanInWords = endOfLastScanInWords;
6408
6409 // If that leaves us with nothing to scan, ignore this request.
6410 if (beginOfScanInWords >= endOfScanInWords)
6411 continue;
6412 }
6413
6414 // Scan to the end of the request.
6415 assert(beginOfScanInWords < endOfScanInWords);
6416 scan(endOfScanInWords - beginOfScanInWords);
6417 endOfLastScanInWords = endOfScanInWords;
6418 }
6419
6420 if (buffer.empty())
6421 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6422
6423 // For GC layouts, emit a skip to the end of the allocation so that we
6424 // have precise information about the entire thing. This isn't useful
6425 // or necessary for the ARC-style layout strings.
6426 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6427 unsigned lastOffsetInWords =
6428 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6429 if (lastOffsetInWords > endOfLastScanInWords) {
6430 skip(lastOffsetInWords - endOfLastScanInWords);
6431 }
6432 }
6433
6434 // Null terminate the string.
6435 buffer.push_back(0);
6436
6437 auto *Entry = CGObjC.CreateCStringLiteral(
6438 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::LayoutBitMap);
6439 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
6440}
6441
6442/// BuildIvarLayout - Builds ivar layout bitmap for the class
6443/// implementation for the __strong or __weak case.
6444/// The layout map displays which words in ivar list must be skipped
6445/// and which must be scanned by GC (see below). String is built of bytes.
6446/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
6447/// of words to skip and right nibble is count of words to scan. So, each
6448/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
6449/// represented by a 0x00 byte which also ends the string.
6450/// 1. when ForStrongLayout is true, following ivars are scanned:
6451/// - id, Class
6452/// - object *
6453/// - __strong anything
6454///
6455/// 2. When ForStrongLayout is false, following ivars are scanned:
6456/// - __weak anything
6457///
6458llvm::Constant *
6459CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6460 CharUnits beginOffset, CharUnits endOffset,
6461 bool ForStrongLayout, bool HasMRCWeakIvars) {
6462 // If this is MRC, and we're either building a strong layout or there
6463 // are no weak ivars, bail out early.
6464 llvm::Type *PtrTy = CGM.Int8PtrTy;
6465 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6466 !CGM.getLangOpts().ObjCAutoRefCount &&
6467 (ForStrongLayout || !HasMRCWeakIvars))
6468 return llvm::Constant::getNullValue(PtrTy);
6469
6470 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6471 SmallVector<const ObjCIvarDecl *, 32> ivars;
6472
6473 // GC layout strings include the complete object layout, possibly
6474 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6475 // up.
6476 //
6477 // ARC layout strings only include the class's ivars. In non-fragile
6478 // runtimes, that means starting at InstanceStart, rounded up to word
6479 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6480 // starting at the offset of the first ivar, rounded up to word alignment.
6481 //
6482 // MRC weak layout strings follow the ARC style.
6483 CharUnits baseOffset;
6484 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6485 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6486 IVD = IVD->getNextIvar())
6487 ivars.push_back(IVD);
6488
6489 if (isNonFragileABI()) {
6490 baseOffset = beginOffset; // InstanceStart
6491 } else if (!ivars.empty()) {
6492 baseOffset =
6493 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6494 } else {
6495 baseOffset = CharUnits::Zero();
6496 }
6497
6498 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6499 } else {
6500 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6501
6502 baseOffset = CharUnits::Zero();
6503 }
6504
6505 if (ivars.empty())
6506 return llvm::Constant::getNullValue(PtrTy);
6507
6508 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6509
6510 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6511 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6512 return CharUnits::fromQuantity(
6513 ComputeIvarBaseOffset(CGM, OMD, ivar));
6514 });
6515
6516 if (!builder.hasBitmapData())
6517 return llvm::Constant::getNullValue(PtrTy);
6518
6519 llvm::SmallVector<unsigned char, 4> buffer;
6520 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6521
6522 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6523 printf("\n%s ivar layout for class '%s': ",
6524 ForStrongLayout ? "strong" : "weak",
6525 OMD->getClassInterface()->getName().str().c_str());
6526 builder.dump(buffer);
6527 }
6528 return C;
6529}
6530
6531llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6532 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6533 // FIXME: Avoid std::string in "Sel.getAsString()"
6534 if (!Entry)
6535 Entry =
6536 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6537 return getConstantGEP(VMContext, Entry, 0, 0);
6538}
6539
6540// FIXME: Merge into a single cstring creation function.
6541llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6542 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6543}
6544
6545llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6546 std::string TypeStr;
6547 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6548
6549 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6550 if (!Entry)
6551 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6552 return getConstantGEP(VMContext, Entry, 0, 0);
6553}
6554
6555llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6556 bool Extended) {
6557 std::string TypeStr =
6558 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6559
6560 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6561 if (!Entry)
6562 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6563 return getConstantGEP(VMContext, Entry, 0, 0);
6564}
6565
6566// FIXME: Merge into a single cstring creation function.
6567llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6568 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6569 if (!Entry)
6570 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6571 return getConstantGEP(VMContext, Entry, 0, 0);
6572}
6573
6574// FIXME: Merge into a single cstring creation function.
6575// FIXME: This Decl should be more precise.
6576llvm::Constant *
6577CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6578 const Decl *Container) {
6579 std::string TypeStr =
6580 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6581 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6582}
6583
6584void CGObjCMac::FinishModule() {
6585 EmitModuleInfo();
6586
6587 // Emit the dummy bodies for any protocols which were referenced but
6588 // never defined.
6589 for (auto &entry : Protocols) {
6590 llvm::GlobalVariable *global = entry.second;
6591 if (global->hasInitializer())
6592 continue;
6593
6594 ConstantInitBuilder builder(CGM);
6595 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6596 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6597 values.add(GetClassName(entry.first->getName()));
6598 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6599 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6600 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6601 values.finishAndSetAsInitializer(global);
6602 CGM.addCompilerUsedGlobal(global);
6603 }
6604
6605 // Add assembler directives to add lazy undefined symbol references
6606 // for classes which are referenced but not defined. This is
6607 // important for correct linker interaction.
6608 //
6609 // FIXME: It would be nice if we had an LLVM construct for this.
6610 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6611 CGM.getTriple().isOSBinFormatMachO()) {
6612 SmallString<256> Asm;
6613 Asm += CGM.getModule().getModuleInlineAsm();
6614 if (!Asm.empty() && Asm.back() != '\n')
6615 Asm += '\n';
6616
6617 llvm::raw_svector_ostream OS(Asm);
6618 for (const auto *Sym : DefinedSymbols)
6619 OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"
6620 << "\t.globl .objc_class_name_" << Sym->getName() << "\n";
6621 for (const auto *Sym : LazySymbols)
6622 OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";
6623 for (const auto &Category : DefinedCategoryNames)
6624 OS << "\t.objc_category_name_" << Category << "=0\n"
6625 << "\t.globl .objc_category_name_" << Category << "\n";
6626
6627 CGM.getModule().setModuleInlineAsm(OS.str());
6628 }
6629}
6630
6631CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6632 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6633 ObjCEmptyVtableVar(nullptr) {
6634 ObjCABI = 2;
6635}
6636
6637/* *** */
6638
6639ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6640 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6641 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6642 ASTContext &Ctx = CGM.getContext();
6643 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6644
6645 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6646 IntTy = CGM.IntTy;
6647 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6648 Int8PtrTy = CGM.Int8PtrTy;
6649 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6650 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6651
6652 // arm64 targets use "int" ivar offset variables. All others,
6653 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6654 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6655 IvarOffsetVarTy = IntTy;
6656 else
6657 IvarOffsetVarTy = LongTy;
6658
6659 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6660 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6661 SelectorPtrTy =
6662 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6663
6664 // I'm not sure I like this. The implicit coordination is a bit
6665 // gross. We should solve this in a reasonable fashion because this
6666 // is a pretty common task (match some runtime data structure with
6667 // an LLVM data structure).
6668
6669 // FIXME: This is leaked.
6670 // FIXME: Merge with rewriter code?
6671
6672 // struct _objc_super {
6673 // id self;
6674 // Class cls;
6675 // }
6676 RecordDecl *RD = RecordDecl::Create(
6677 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6678 SourceLocation(), &Ctx.Idents.get("_objc_super"));
6679 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6680 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6681 false, ICIS_NoInit));
6682 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6683 nullptr, Ctx.getObjCClassType(), nullptr,
6684 nullptr, false, ICIS_NoInit));
6685 RD->completeDefinition();
6686
6687 SuperCTy = Ctx.getCanonicalTagType(RD);
6688 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6689
6690 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6691 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6692
6693 // struct _prop_t {
6694 // char *name;
6695 // char *attributes;
6696 // }
6697 PropertyTy = llvm::StructType::create("struct._prop_t", Int8PtrTy, Int8PtrTy);
6698
6699 // struct _prop_list_t {
6700 // uint32_t entsize; // sizeof(struct _prop_t)
6701 // uint32_t count_of_properties;
6702 // struct _prop_t prop_list[count_of_properties];
6703 // }
6704 PropertyListTy = llvm::StructType::create(
6705 "struct._prop_list_t", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6706 // struct _prop_list_t *
6707 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6708
6709 // struct _objc_method {
6710 // SEL _cmd;
6711 // char *method_type;
6712 // char *_imp;
6713 // }
6714 MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy,
6715 Int8PtrTy, Int8PtrProgramASTy);
6716
6717 // struct _objc_cache *
6718 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
6719 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6720}
6721
6722ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6723 : ObjCCommonTypesHelper(cgm) {
6724 // struct _objc_method_description {
6725 // SEL name;
6726 // char *types;
6727 // }
6728 MethodDescriptionTy = llvm::StructType::create(
6729 "struct._objc_method_description", SelectorPtrTy, Int8PtrTy);
6730
6731 // struct _objc_method_description_list {
6732 // int count;
6733 // struct _objc_method_description[1];
6734 // }
6735 MethodDescriptionListTy =
6736 llvm::StructType::create("struct._objc_method_description_list", IntTy,
6737 llvm::ArrayType::get(MethodDescriptionTy, 0));
6738
6739 // struct _objc_method_description_list *
6740 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6741
6742 // Protocol description structures
6743
6744 // struct _objc_protocol_extension {
6745 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6746 // struct _objc_method_description_list *optional_instance_methods;
6747 // struct _objc_method_description_list *optional_class_methods;
6748 // struct _objc_property_list *instance_properties;
6749 // const char ** extendedMethodTypes;
6750 // struct _objc_property_list *class_properties;
6751 // }
6752 ProtocolExtensionTy = llvm::StructType::create(
6753 "struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy,
6754 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6755 PropertyListPtrTy);
6756
6757 // struct _objc_protocol_extension *
6758 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6759
6760 // Handle construction of Protocol and ProtocolList types
6761
6762 // struct _objc_protocol {
6763 // struct _objc_protocol_extension *isa;
6764 // char *protocol_name;
6765 // struct _objc_protocol **_objc_protocol_list;
6766 // struct _objc_method_description_list *instance_methods;
6767 // struct _objc_method_description_list *class_methods;
6768 // }
6769 ProtocolTy = llvm::StructType::create(
6770 {ProtocolExtensionPtrTy, Int8PtrTy,
6771 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6772 MethodDescriptionListPtrTy},
6773 "struct._objc_protocol");
6774
6775 ProtocolListTy =
6776 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6777 llvm::ArrayType::get(ProtocolTy, 0)},
6778 "struct._objc_protocol_list");
6779
6780 // struct _objc_protocol_list *
6781 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6782
6783 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6784
6785 // Class description structures
6786
6787 // struct _objc_ivar {
6788 // char *ivar_name;
6789 // char *ivar_type;
6790 // int ivar_offset;
6791 // }
6792 IvarTy = llvm::StructType::create("struct._objc_ivar", Int8PtrTy, Int8PtrTy,
6793 IntTy);
6794
6795 // struct _objc_ivar_list *
6796 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list");
6797 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6798
6799 // struct _objc_method_list *
6800 MethodListTy =
6801 llvm::StructType::create(VMContext, "struct._objc_method_list");
6802 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6803
6804 // struct _objc_class_extension *
6805 ClassExtensionTy = llvm::StructType::create(
6806 "struct._objc_class_extension", IntTy, Int8PtrTy, PropertyListPtrTy);
6807 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6808
6809 // struct _objc_class {
6810 // Class isa;
6811 // Class super_class;
6812 // char *name;
6813 // long version;
6814 // long info;
6815 // long instance_size;
6816 // struct _objc_ivar_list *ivars;
6817 // struct _objc_method_list *methods;
6818 // struct _objc_cache *cache;
6819 // struct _objc_protocol_list *protocols;
6820 // char *ivar_layout;
6821 // struct _objc_class_ext *ext;
6822 // };
6823 ClassTy = llvm::StructType::create(
6824 {llvm::PointerType::getUnqual(VMContext),
6825 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6826 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6827 Int8PtrTy, ClassExtensionPtrTy},
6828 "struct._objc_class");
6829
6830 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6831
6832 // struct _objc_category {
6833 // char *category_name;
6834 // char *class_name;
6835 // struct _objc_method_list *instance_method;
6836 // struct _objc_method_list *class_method;
6837 // struct _objc_protocol_list *protocols;
6838 // uint32_t size; // sizeof(struct _objc_category)
6839 // struct _objc_property_list *instance_properties;// category's @property
6840 // struct _objc_property_list *class_properties;
6841 // }
6842 CategoryTy = llvm::StructType::create(
6843 "struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6844 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6845 PropertyListPtrTy);
6846
6847 // Global metadata structures
6848
6849 // struct _objc_symtab {
6850 // long sel_ref_cnt;
6851 // SEL *refs;
6852 // short cls_def_cnt;
6853 // short cat_def_cnt;
6854 // char *defs[cls_def_cnt + cat_def_cnt];
6855 // }
6856 SymtabTy = llvm::StructType::create("struct._objc_symtab", LongTy,
6857 SelectorPtrTy, ShortTy, ShortTy,
6858 llvm::ArrayType::get(Int8PtrTy, 0));
6859 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6860
6861 // struct _objc_module {
6862 // long version;
6863 // long size; // sizeof(struct _objc_module)
6864 // char *name;
6865 // struct _objc_symtab* symtab;
6866 // }
6867 ModuleTy = llvm::StructType::create("struct._objc_module", LongTy, LongTy,
6868 Int8PtrTy, SymtabPtrTy);
6869
6870 // FIXME: This is the size of the setjmp buffer and should be target
6871 // specific. 18 is what's used on 32-bit X86.
6872 uint64_t SetJmpBufferSize = 18;
6873
6874 // Exceptions
6875 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6876
6877 ExceptionDataTy = llvm::StructType::create(
6878 "struct._objc_exception_data",
6879 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6880}
6881
6882ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6883 CodeGen::CodeGenModule &cgm)
6884 : ObjCCommonTypesHelper(cgm) {
6885 // struct _method_list_t {
6886 // uint32_t entsize; // sizeof(struct _objc_method)
6887 // uint32_t method_count;
6888 // struct _objc_method method_list[method_count];
6889 // }
6890 MethodListnfABITy =
6891 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
6892 llvm::ArrayType::get(MethodTy, 0));
6893 // struct method_list_t *
6894 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6895
6896 // struct _protocol_t {
6897 // id isa; // NULL
6898 // const char * const protocol_name;
6899 // const struct _protocol_list_t * protocol_list; // super protocols
6900 // const struct method_list_t * const instance_methods;
6901 // const struct method_list_t * const class_methods;
6902 // const struct method_list_t *optionalInstanceMethods;
6903 // const struct method_list_t *optionalClassMethods;
6904 // const struct _prop_list_t * properties;
6905 // const uint32_t size; // sizeof(struct _protocol_t)
6906 // const uint32_t flags; // = 0
6907 // const char ** extendedMethodTypes;
6908 // const char *demangledName;
6909 // const struct _prop_list_t * class_properties;
6910 // }
6911
6912 ProtocolnfABITy = llvm::StructType::create(
6913 "struct._protocol_t", ObjectPtrTy, Int8PtrTy,
6914 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6915 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6916 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6917 PropertyListPtrTy);
6918
6919 // struct _protocol_t*
6920 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6921
6922 // struct _protocol_list_t {
6923 // long protocol_count; // Note, this is 32/64 bit
6924 // struct _protocol_t *[protocol_count];
6925 // }
6926 ProtocolListnfABITy = llvm::StructType::create(
6927 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6928 "struct._objc_protocol_list");
6929
6930 // struct _objc_protocol_list*
6931 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6932
6933 // struct _ivar_t {
6934 // unsigned [long] int *offset; // pointer to ivar offset location
6935 // char *name;
6936 // char *type;
6937 // uint32_t alignment;
6938 // uint32_t size;
6939 // }
6940 IvarnfABITy = llvm::StructType::create(
6941 "struct._ivar_t", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6942 Int8PtrTy, IntTy, IntTy);
6943
6944 // struct _ivar_list_t {
6945 // uint32 entsize; // sizeof(struct _ivar_t)
6946 // uint32 count;
6947 // struct _iver_t list[count];
6948 // }
6949 IvarListnfABITy =
6950 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
6951 llvm::ArrayType::get(IvarnfABITy, 0));
6952
6953 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6954
6955 // struct _class_ro_t {
6956 // uint32_t const flags;
6957 // uint32_t const instanceStart;
6958 // uint32_t const instanceSize;
6959 // uint32_t const reserved; // only when building for 64bit targets
6960 // const uint8_t * const ivarLayout;
6961 // const char *const name;
6962 // const struct _method_list_t * const baseMethods;
6963 // const struct _objc_protocol_list *const baseProtocols;
6964 // const struct _ivar_list_t *const ivars;
6965 // const uint8_t * const weakIvarLayout;
6966 // const struct _prop_list_t * const properties;
6967 // }
6968
6969 // FIXME. Add 'reserved' field in 64bit abi mode!
6970 ClassRonfABITy = llvm::StructType::create(
6971 "struct._class_ro_t", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6972 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6973 Int8PtrTy, PropertyListPtrTy);
6974
6975 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6976 ImpnfABITy = CGM.DefaultPtrTy;
6977
6978 // struct _class_t {
6979 // struct _class_t *isa;
6980 // struct _class_t * const superclass;
6981 // void *cache;
6982 // IMP *vtable;
6983 // struct class_ro_t *ro;
6984 // }
6985
6986 ClassnfABITy = llvm::StructType::create(
6987 {llvm::PointerType::getUnqual(VMContext),
6988 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6989 llvm::PointerType::getUnqual(VMContext),
6990 llvm::PointerType::getUnqual(VMContext)},
6991 "struct._class_t");
6992
6993 // LLVM for struct _class_t *
6994 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6995
6996 // struct _category_t {
6997 // const char * const name;
6998 // struct _class_t *const cls;
6999 // const struct _method_list_t * const instance_methods;
7000 // const struct _method_list_t * const class_methods;
7001 // const struct _protocol_list_t * const protocols;
7002 // const struct _prop_list_t * const properties;
7003 // const struct _prop_list_t * const class_properties;
7004 // const uint32_t size;
7005 // }
7006 CategorynfABITy = llvm::StructType::create(
7007 "struct._category_t", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
7008 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
7009 PropertyListPtrTy, IntTy);
7010
7011 // New types for nonfragile abi messaging.
7012 CodeGen::CodeGenTypes &Types = CGM.getTypes();
7013 ASTContext &Ctx = CGM.getContext();
7014
7015 // MessageRefTy - LLVM for:
7016 // struct _message_ref_t {
7017 // IMP messenger;
7018 // SEL name;
7019 // };
7020
7021 // First the clang type for struct _message_ref_t
7022 RecordDecl *RD = RecordDecl::Create(
7023 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7024 SourceLocation(), &Ctx.Idents.get("_message_ref_t"));
7025 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7026 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7027 ICIS_NoInit));
7028 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7029 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7030 false, ICIS_NoInit));
7031 RD->completeDefinition();
7032
7033 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7034 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7035 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7036
7037 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7038 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7039
7040 // SuperMessageRefTy - LLVM for:
7041 // struct _super_message_ref_t {
7042 // SUPER_IMP messenger;
7043 // SEL name;
7044 // };
7045 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t",
7046 ImpnfABITy, SelectorPtrTy);
7047
7048 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7049 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7050
7051 // struct objc_typeinfo {
7052 // const void** vtable; // objc_ehtype_vtable + 2
7053 // const char* name; // c++ typeinfo string
7054 // Class cls;
7055 // };
7056 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo",
7057 llvm::PointerType::getUnqual(VMContext),
7058 Int8PtrTy, ClassnfABIPtrTy);
7059 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7060}
7061
7062llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7063 FinishNonFragileABIModule();
7064
7065 return nullptr;
7066}
7067
7068void CGObjCNonFragileABIMac::AddModuleClassList(
7069 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7070 StringRef SectionName) {
7071 unsigned NumClasses = Container.size();
7072
7073 if (!NumClasses)
7074 return;
7075
7076 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7077 for (unsigned i = 0; i < NumClasses; i++)
7078 Symbols[i] = Container[i];
7079
7080 llvm::Constant *Init = llvm::ConstantArray::get(
7081 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7082
7083 // Section name is obtained by calling GetSectionName, which returns
7084 // sections in the __DATA segment on MachO.
7085 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7086 SectionName.starts_with("__DATA")) &&
7087 "SectionName expected to start with __DATA on MachO");
7088 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7089 CGM.getModule(), Init->getType(), false,
7090 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7091 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7092 GV->setSection(SectionName);
7093 CGM.addCompilerUsedGlobal(GV);
7094}
7095
7096void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7097 // nonfragile abi has no module definition.
7098
7099 // Build list of all implemented class addresses in array
7100 // L_OBJC_LABEL_CLASS_$.
7101
7102 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7103 i++) {
7104 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7105 assert(ID);
7106 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7107 // We are implementing a weak imported interface. Give it external linkage
7108 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7109 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7110 DefinedMetaClasses[i]->setLinkage(
7111 llvm::GlobalVariable::ExternalLinkage);
7112 }
7113 }
7114
7115 AddModuleClassList(
7116 DefinedClasses, "OBJC_LABEL_CLASS_$",
7117 GetSectionName("__objc_classlist", "regular,no_dead_strip"));
7118
7119 AddModuleClassList(
7120 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
7121 GetSectionName("__objc_nlclslist", "regular,no_dead_strip"));
7122
7123 // Build list of all implemented category addresses in array
7124 // L_OBJC_LABEL_CATEGORY_$.
7125 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
7126 GetSectionName("__objc_catlist", "regular,no_dead_strip"));
7127 AddModuleClassList(
7128 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$",
7129 GetSectionName("__objc_catlist2", "regular,no_dead_strip"));
7130 AddModuleClassList(
7131 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
7132 GetSectionName("__objc_nlcatlist", "regular,no_dead_strip"));
7133
7134 EmitImageInfo();
7135}
7136
7137/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
7138/// VTableDispatchMethods; false otherwise. What this means is that
7139/// except for the 19 selectors in the list, we generate 32bit-style
7140/// message dispatch call for all the rest.
7141bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7142 // At various points we've experimented with using vtable-based
7143 // dispatch for all methods.
7144 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7145 case CodeGenOptions::Legacy:
7146 return false;
7147 case CodeGenOptions::NonLegacy:
7148 return true;
7149 case CodeGenOptions::Mixed:
7150 break;
7151 }
7152
7153 // If so, see whether this selector is in the white-list of things which must
7154 // use the new dispatch convention. We lazily build a dense set for this.
7155 if (VTableDispatchMethods.empty()) {
7156 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
7157 VTableDispatchMethods.insert(GetNullarySelector("class"));
7158 VTableDispatchMethods.insert(GetNullarySelector("self"));
7159 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
7160 VTableDispatchMethods.insert(GetNullarySelector("length"));
7161 VTableDispatchMethods.insert(GetNullarySelector("count"));
7162
7163 // These are vtable-based if GC is disabled.
7164 // Optimistically use vtable dispatch for hybrid compiles.
7165 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7166 VTableDispatchMethods.insert(GetNullarySelector("retain"));
7167 VTableDispatchMethods.insert(GetNullarySelector("release"));
7168 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
7169 }
7170
7171 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
7172 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
7173 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
7174 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
7175 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
7176 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
7177 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
7178
7179 // These are vtable-based if GC is enabled.
7180 // Optimistically use vtable dispatch for hybrid compiles.
7181 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7182 VTableDispatchMethods.insert(GetNullarySelector("hash"));
7183 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
7184
7185 // "countByEnumeratingWithState:objects:count"
7186 const IdentifierInfo *KeyIdents[] = {
7187 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
7188 &CGM.getContext().Idents.get("objects"),
7189 &CGM.getContext().Idents.get("count")};
7190 VTableDispatchMethods.insert(
7191 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7192 }
7193 }
7194
7195 return VTableDispatchMethods.count(Sel);
7196}
7197
7198/// BuildClassRoTInitializer - generate meta-data for:
7199/// struct _class_ro_t {
7200/// uint32_t const flags;
7201/// uint32_t const instanceStart;
7202/// uint32_t const instanceSize;
7203/// uint32_t const reserved; // only when building for 64bit targets
7204/// const uint8_t * const ivarLayout;
7205/// const char *const name;
7206/// const struct _method_list_t * const baseMethods;
7207/// const struct _protocol_list_t *const baseProtocols;
7208/// const struct _ivar_list_t *const ivars;
7209/// const uint8_t * const weakIvarLayout;
7210/// const struct _prop_list_t * const properties;
7211/// }
7212///
7213llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7214 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7215 const ObjCImplementationDecl *ID) {
7216 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7217
7218 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7219 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7220
7221 bool hasMRCWeak = false;
7222 if (CGM.getLangOpts().ObjCAutoRefCount)
7223 flags |= NonFragileABI_Class_CompiledByARC;
7224 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7225 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7226
7227 ConstantInitBuilder builder(CGM);
7228 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7229
7230 values.addInt(ObjCTypes.IntTy, flags);
7231 values.addInt(ObjCTypes.IntTy, InstanceStart);
7232 values.addInt(ObjCTypes.IntTy, InstanceSize);
7233 values.add((flags & NonFragileABI_Class_Meta)
7234 ? GetIvarLayoutName(nullptr, ObjCTypes)
7235 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7236 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7237
7238 // const struct _method_list_t * const baseMethods;
7239 SmallVector<const ObjCMethodDecl *, 16> methods;
7240 if (flags & NonFragileABI_Class_Meta) {
7241 for (const auto *MD : ID->class_methods())
7242 if (!MD->isDirectMethod())
7243 methods.push_back(MD);
7244 } else {
7245 for (const auto *MD : ID->instance_methods())
7246 if (!MD->isDirectMethod())
7247 methods.push_back(MD);
7248 }
7249
7250 llvm::Constant *MethListPtr = emitMethodList(
7251 ID->getObjCRuntimeNameAsString(),
7252 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7253 : MethodListType::InstanceMethods,
7254 methods);
7255
7256 const PointerAuthSchema &MethListSchema =
7257 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7258 if (!MethListPtr->isNullValue())
7259 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7260 QualType());
7261 else
7262 values.add(MethListPtr);
7263
7264 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7265 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
7266 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_" +
7267 OID->getObjCRuntimeNameAsString(),
7268 OID->all_referenced_protocol_begin(),
7269 OID->all_referenced_protocol_end()));
7270
7271 if (flags & NonFragileABI_Class_Meta) {
7272 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7273 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7274 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" +
7275 ID->getObjCRuntimeNameAsString(),
7276 ID, ID->getClassInterface(), ObjCTypes, true));
7277 } else {
7278 values.add(EmitIvarList(ID));
7279 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7280 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" +
7281 ID->getObjCRuntimeNameAsString(),
7282 ID, ID->getClassInterface(), ObjCTypes, false));
7283 }
7284
7285 llvm::SmallString<64> roLabel;
7286 llvm::raw_svector_ostream(roLabel)
7287 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_"
7288 : "_OBJC_CLASS_RO_$_")
7289 << ClassName;
7290
7291 return finishAndCreateGlobal(values, roLabel, CGM);
7292}
7293
7294/// Build the metaclass object for a class.
7295///
7296/// struct _class_t {
7297/// struct _class_t *isa;
7298/// struct _class_t * const superclass;
7299/// void *cache;
7300/// IMP *vtable;
7301/// struct class_ro_t *ro;
7302/// }
7303///
7304llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7305 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7306 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7307 bool HiddenVisibility) {
7308 ConstantInitBuilder builder(CGM);
7309 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7310 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7311 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7312 QualType());
7313 if (SuperClassGV)
7314 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7315 GlobalDecl(), QualType());
7316 else
7317 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7318
7319 values.add(ObjCEmptyCacheVar);
7320 values.add(ObjCEmptyVtableVar);
7321
7322 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7323 GlobalDecl(), QualType());
7324
7325 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7326 GetClassGlobal(CI, isMetaclass, ForDefinition));
7327 values.finishAndSetAsInitializer(GV);
7328
7329 if (CGM.getTriple().isOSBinFormatMachO())
7330 GV->setSection("__DATA, __objc_data");
7331 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7332 if (!CGM.getTriple().isOSBinFormatCOFF())
7333 if (HiddenVisibility)
7334 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7335 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7336 CGM.addUsedGlobal(GV);
7337 return GV;
7338}
7339
7340bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7341 const ObjCImplDecl *OD) const {
7342 return OD->getClassMethod(GetNullarySelector("load")) != nullptr ||
7343 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7344 OD->hasAttr<ObjCNonLazyClassAttr>();
7345}
7346
7347void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7348 uint32_t &InstanceStart,
7349 uint32_t &InstanceSize) {
7350 const ASTRecordLayout &RL =
7351 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7352
7353 // InstanceSize is really instance end.
7354 InstanceSize = RL.getDataSize().getQuantity();
7355
7356 // If there are no fields, the start is the same as the end.
7357 if (!RL.getFieldCount())
7358 InstanceStart = InstanceSize;
7359 else
7360 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7361}
7362
7363static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7364 StringRef Name) {
7365 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7366 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7367 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7368
7369 const VarDecl *VD = nullptr;
7370 for (const auto *Result : DC->lookup(&II))
7371 if ((VD = dyn_cast<VarDecl>(Result)))
7372 break;
7373
7374 if (!VD)
7375 return llvm::GlobalValue::DLLImportStorageClass;
7376 if (VD->hasAttr<DLLExportAttr>())
7377 return llvm::GlobalValue::DLLExportStorageClass;
7378 if (VD->hasAttr<DLLImportAttr>())
7379 return llvm::GlobalValue::DLLImportStorageClass;
7380 return llvm::GlobalValue::DefaultStorageClass;
7381}
7382
7383void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7384 if (!ObjCEmptyCacheVar) {
7385 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7386 CGM.getModule(), ObjCTypes.CacheTy, false,
7387 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");
7388 if (CGM.getTriple().isOSBinFormatCOFF())
7389 ObjCEmptyCacheVar->setDLLStorageClass(
7390 getStorage(CGM, "_objc_empty_cache"));
7391
7392 // Only OS X with deployment version <10.9 use the empty vtable symbol
7393 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7394 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7395 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7396 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7397 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");
7398 else
7399 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7400 }
7401
7402 // FIXME: Is this correct (that meta class size is never computed)?
7403 uint32_t InstanceStart =
7404 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7405 uint32_t InstanceSize = InstanceStart;
7406 uint32_t flags = NonFragileABI_Class_Meta;
7407
7408 llvm::Constant *SuperClassGV, *IsAGV;
7409
7410 const auto *CI = ID->getClassInterface();
7411 assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
7412
7413 // Build the flags for the metaclass.
7414 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7415 ? !CI->hasAttr<DLLExportAttr>()
7416 : CI->getVisibility() == HiddenVisibility;
7417 if (classIsHidden)
7418 flags |= NonFragileABI_Class_Hidden;
7419
7420 // FIXME: why is this flag set on the metaclass?
7421 // ObjC metaclasses have no fields and don't really get constructed.
7422 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7423 flags |= NonFragileABI_Class_HasCXXStructors;
7424 if (!ID->hasNonZeroConstructors())
7425 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7426 }
7427
7428 if (!CI->getSuperClass()) {
7429 // class is root
7430 flags |= NonFragileABI_Class_Root;
7431
7432 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7433 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7434 } else {
7435 // Has a root. Current class is not a root.
7436 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7437 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7438 Root = Super;
7439
7440 const auto *Super = CI->getSuperClass();
7441 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7442 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7443 }
7444
7445 llvm::GlobalVariable *CLASS_RO_GV =
7446 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7447
7448 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7449 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7450 CGM.setGVProperties(MetaTClass, CI);
7451 DefinedMetaClasses.push_back(MetaTClass);
7452
7453 // Metadata for the class
7454 flags = 0;
7455 if (classIsHidden)
7456 flags |= NonFragileABI_Class_Hidden;
7457
7458 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7459 flags |= NonFragileABI_Class_HasCXXStructors;
7460
7461 // Set a flag to enable a runtime optimization when a class has
7462 // fields that require destruction but which don't require
7463 // anything except zero-initialization during construction. This
7464 // is most notably true of __strong and __weak types, but you can
7465 // also imagine there being C++ types with non-trivial default
7466 // constructors that merely set all fields to null.
7467 if (!ID->hasNonZeroConstructors())
7468 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7469 }
7470
7471 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7472 flags |= NonFragileABI_Class_Exception;
7473
7474 if (!CI->getSuperClass()) {
7475 flags |= NonFragileABI_Class_Root;
7476 SuperClassGV = nullptr;
7477 } else {
7478 // Has a root. Current class is not a root.
7479 const auto *Super = CI->getSuperClass();
7480 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7481 }
7482
7483 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7484 CLASS_RO_GV =
7485 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7486
7487 llvm::GlobalVariable *ClassMD =
7488 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7489 CLASS_RO_GV, classIsHidden);
7490 CGM.setGVProperties(ClassMD, CI);
7491 DefinedClasses.push_back(ClassMD);
7492 ImplementedClasses.push_back(CI);
7493
7494 // Determine if this class is also "non-lazy".
7495 if (ImplementationIsNonLazy(ID))
7496 DefinedNonLazyClasses.push_back(ClassMD);
7497
7498 // Force the definition of the EHType if necessary.
7499 if (flags & NonFragileABI_Class_Exception)
7500 (void)GetInterfaceEHType(CI, ForDefinition);
7501 // Make sure method definition entries are all clear for next implementation.
7502 MethodDefinitions.clear();
7503}
7504
7505/// GenerateProtocolRef - This routine is called to generate code for
7506/// a protocol reference expression; as in:
7507/// @code
7508/// @protocol(Proto1);
7509/// @endcode
7510/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
7511/// which will hold address of the protocol meta-data.
7512///
7513llvm::Value *
7514CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7515 const ObjCProtocolDecl *PD) {
7516
7517 // This routine is called for @protocol only. So, we must build definition
7518 // of protocol's meta-data (not a reference to it!)
7519 assert(!PD->isNonRuntimeProtocol() &&
7520 "attempting to get a protocol ref to a static protocol.");
7521 llvm::Constant *Init = GetOrEmitProtocol(PD);
7522
7523 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_");
7524 ProtocolName += PD->getObjCRuntimeNameAsString();
7525
7526 CharUnits Align = CGF.getPointerAlign();
7527
7528 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7529 if (PTGV)
7530 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7531 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7532 llvm::GlobalValue::WeakAnyLinkage, Init,
7533 ProtocolName);
7534 PTGV->setSection(
7535 GetSectionName("__objc_protorefs", "coalesced,no_dead_strip"));
7536 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7537 PTGV->setAlignment(Align.getAsAlign());
7538 if (!CGM.getTriple().isOSBinFormatMachO())
7539 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7540 CGM.addUsedGlobal(PTGV);
7541 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7542}
7543
7544/// GenerateCategory - Build metadata for a category implementation.
7545/// struct _category_t {
7546/// const char * const name;
7547/// struct _class_t *const cls;
7548/// const struct _method_list_t * const instance_methods;
7549/// const struct _method_list_t * const class_methods;
7550/// const struct _protocol_list_t * const protocols;
7551/// const struct _prop_list_t * const properties;
7552/// const struct _prop_list_t * const class_properties;
7553/// const uint32_t size;
7554/// }
7555///
7556void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7557 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7558 const char *Prefix = "_OBJC_$_CATEGORY_";
7559
7560 llvm::SmallString<64> ExtCatName(Prefix);
7561 ExtCatName += Interface->getObjCRuntimeNameAsString();
7562 ExtCatName += "_$_";
7563 ExtCatName += OCD->getNameAsString();
7564
7565 ConstantInitBuilder builder(CGM);
7566 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7567 values.add(GetClassName(OCD->getIdentifier()->getName()));
7568 // meta-class entry symbol
7569 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7570 std::string listName =
7571 (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
7572
7573 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7574 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7575 for (const auto *MD : OCD->methods()) {
7576 if (MD->isDirectMethod())
7577 continue;
7578 if (MD->isInstanceMethod()) {
7579 instanceMethods.push_back(MD);
7580 } else {
7581 classMethods.push_back(MD);
7582 }
7583 }
7584
7585 llvm::Constant *InstanceMethodList = emitMethodList(
7586 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7587 const PointerAuthSchema &MethListSchema =
7588 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7589 if (!InstanceMethodList->isNullValue())
7590 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7591 QualType());
7592 else
7593 values.add(InstanceMethodList);
7594
7595 llvm::Constant *ClassMethodList = emitMethodList(
7596 listName, MethodListType::CategoryClassMethods, classMethods);
7597 if (!ClassMethodList->isNullValue())
7598 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7599 QualType());
7600 else
7601 values.add(ClassMethodList);
7602
7603 // Keep track of whether we have actual metadata to emit.
7604 bool isEmptyCategory =
7605 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7606
7607 const ObjCCategoryDecl *Category =
7608 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7609 if (Category) {
7610 SmallString<256> ExtName;
7611 llvm::raw_svector_ostream(ExtName)
7612 << Interface->getObjCRuntimeNameAsString() << "_$_" << OCD->getName();
7613 auto protocolList =
7614 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_" +
7615 Interface->getObjCRuntimeNameAsString() + "_$_" +
7616 Category->getName(),
7617 Category->protocol_begin(), Category->protocol_end());
7618 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
7619 OCD, Category, ObjCTypes, false);
7620 auto classPropertyList =
7621 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
7622 Category, ObjCTypes, true);
7623 values.add(protocolList);
7624 values.add(propertyList);
7625 values.add(classPropertyList);
7626 isEmptyCategory &= protocolList->isNullValue() &&
7627 propertyList->isNullValue() &&
7628 classPropertyList->isNullValue();
7629 } else {
7630 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7631 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7632 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7633 }
7634
7635 if (isEmptyCategory) {
7636 // Empty category, don't emit any metadata.
7637 values.abandon();
7638 MethodDefinitions.clear();
7639 return;
7640 }
7641
7642 unsigned Size =
7643 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7644 values.addInt(ObjCTypes.IntTy, Size);
7645
7646 llvm::GlobalVariable *GCATV =
7647 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7648 CGM.addCompilerUsedGlobal(GCATV);
7649 if (Interface->hasAttr<ObjCClassStubAttr>())
7650 DefinedStubCategories.push_back(GCATV);
7651 else
7652 DefinedCategories.push_back(GCATV);
7653
7654 // Determine if this category is also "non-lazy".
7655 if (ImplementationIsNonLazy(OCD))
7656 DefinedNonLazyCategories.push_back(GCATV);
7657 // method definition entries must be clear for next implementation.
7658 MethodDefinitions.clear();
7659}
7660
7661/// emitMethodConstant - Return a struct objc_method constant. If
7662/// forProtocol is true, the implementation will be null; otherwise,
7663/// the method must have a definition registered with the runtime.
7664///
7665/// struct _objc_method {
7666/// SEL _cmd;
7667/// char *method_type;
7668/// char *_imp;
7669/// }
7670void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7671 const ObjCMethodDecl *MD,
7672 bool forProtocol) {
7673 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7674 method.add(GetMethodVarName(MD->getSelector()));
7675 method.add(GetMethodVarType(MD));
7676
7677 if (forProtocol) {
7678 // Protocol methods have no implementation. So, this entry is always NULL.
7679 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7680 } else {
7681 llvm::Function *fn = GetMethodDefinition(MD);
7682 assert(fn && "no definition for method?");
7683 if (const PointerAuthSchema &Schema =
7684 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7685 llvm::Constant *Bitcast =
7686 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7687 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7688 } else
7689 method.add(fn);
7690 }
7691
7692 method.finishAndAddTo(builder);
7693}
7694
7695/// Build meta-data for method declarations.
7696///
7697/// struct _method_list_t {
7698/// uint32_t entsize; // sizeof(struct _objc_method)
7699/// uint32_t method_count;
7700/// struct _objc_method method_list[method_count];
7701/// }
7702///
7703llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7704 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7705 // Return null for empty list.
7706 if (methods.empty())
7707 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7708
7709 StringRef prefix;
7710 bool forProtocol;
7711 switch (kind) {
7712 case MethodListType::CategoryInstanceMethods:
7713 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
7714 forProtocol = false;
7715 break;
7716 case MethodListType::CategoryClassMethods:
7717 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_";
7718 forProtocol = false;
7719 break;
7720 case MethodListType::InstanceMethods:
7721 prefix = "_OBJC_$_INSTANCE_METHODS_";
7722 forProtocol = false;
7723 break;
7724 case MethodListType::ClassMethods:
7725 prefix = "_OBJC_$_CLASS_METHODS_";
7726 forProtocol = false;
7727 break;
7728
7729 case MethodListType::ProtocolInstanceMethods:
7730 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
7731 forProtocol = true;
7732 break;
7733 case MethodListType::ProtocolClassMethods:
7734 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_";
7735 forProtocol = true;
7736 break;
7737 case MethodListType::OptionalProtocolInstanceMethods:
7738 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
7739 forProtocol = true;
7740 break;
7741 case MethodListType::OptionalProtocolClassMethods:
7742 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
7743 forProtocol = true;
7744 break;
7745 }
7746
7747 ConstantInitBuilder builder(CGM);
7748 auto values = builder.beginStruct();
7749
7750 // sizeof(struct _objc_method)
7751 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7752 values.addInt(ObjCTypes.IntTy, Size);
7753 // method_count
7754 values.addInt(ObjCTypes.IntTy, methods.size());
7755 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7756 for (auto MD : methods)
7757 emitMethodConstant(methodArray, MD, forProtocol);
7758 methodArray.finishAndAddTo(values);
7759
7760 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7761 CGM.addCompilerUsedGlobal(GV);
7762 return GV;
7763}
7764
7765/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
7766/// the given ivar.
7767llvm::GlobalVariable *
7768CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7769 const ObjCIvarDecl *Ivar) {
7770 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7771 llvm::SmallString<64> Name("OBJC_IVAR_$_");
7772 Name += Container->getObjCRuntimeNameAsString();
7773 Name += ".";
7774 Name += Ivar->getName();
7775 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7776 if (!IvarOffsetGV) {
7777 IvarOffsetGV = new llvm::GlobalVariable(
7778 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7779 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7780 if (CGM.getTriple().isOSBinFormatCOFF()) {
7781 bool IsPrivateOrPackage =
7782 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7783 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7784
7785 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7786
7787 if (ContainingID->hasAttr<DLLImportAttr>())
7788 IvarOffsetGV->setDLLStorageClass(
7789 llvm::GlobalValue::DLLImportStorageClass);
7790 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7791 IvarOffsetGV->setDLLStorageClass(
7792 llvm::GlobalValue::DLLExportStorageClass);
7793 }
7794 }
7795 return IvarOffsetGV;
7796}
7797
7798llvm::Constant *
7799CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7800 const ObjCIvarDecl *Ivar,
7801 unsigned long int Offset) {
7802 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7803 IvarOffsetGV->setInitializer(
7804 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7805 IvarOffsetGV->setAlignment(
7806 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7807
7808 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7809 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7810 // as well (i.e., in ObjCIvarOffsetVariable).
7811 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7812 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7813 ID->getVisibility() == HiddenVisibility)
7814 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7815 else
7816 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7817 }
7818
7819 // If ID's layout is known, then make the global constant. This serves as a
7820 // useful assertion: we'll never use this variable to calculate ivar offsets,
7821 // so if the runtime tries to patch it then we should crash.
7822 if (isClassLayoutKnownStatically(ID))
7823 IvarOffsetGV->setConstant(true);
7824
7825 if (CGM.getTriple().isOSBinFormatMachO())
7826 IvarOffsetGV->setSection("__DATA, __objc_ivar");
7827 return IvarOffsetGV;
7828}
7829
7830/// EmitIvarList - Emit the ivar list for the given
7831/// implementation. The return value has type
7832/// IvarListnfABIPtrTy.
7833/// struct _ivar_t {
7834/// unsigned [long] int *offset; // pointer to ivar offset location
7835/// char *name;
7836/// char *type;
7837/// uint32_t alignment;
7838/// uint32_t size;
7839/// }
7840/// struct _ivar_list_t {
7841/// uint32 entsize; // sizeof(struct _ivar_t)
7842/// uint32 count;
7843/// struct _iver_t list[count];
7844/// }
7845///
7846
7847llvm::Constant *
7848CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7849
7850 ConstantInitBuilder builder(CGM);
7851 auto ivarList = builder.beginStruct();
7852 ivarList.addInt(ObjCTypes.IntTy,
7853 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7854 auto ivarCountSlot = ivarList.addPlaceholder();
7855 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7856
7857 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7858 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
7859
7860 // FIXME. Consolidate this with similar code in GenerateClass.
7861
7862 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7863 IVD = IVD->getNextIvar()) {
7864 // Ignore unnamed bit-fields.
7865 if (!IVD->getDeclName())
7866 continue;
7867
7868 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7869 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7870 ComputeIvarBaseOffset(CGM, ID, IVD)));
7871 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7872 ivar.add(GetMethodVarType(IVD));
7873 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7874 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7875 unsigned Align =
7876 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7877 3;
7878 Align = llvm::Log2_32(Align);
7879 ivar.addInt(ObjCTypes.IntTy, Align);
7880 // NOTE. Size of a bitfield does not match gcc's, because of the
7881 // way bitfields are treated special in each. But I am told that
7882 // 'size' for bitfield ivars is ignored by the runtime so it does
7883 // not matter. If it matters, there is enough info to get the
7884 // bitfield right!
7885 ivar.addInt(ObjCTypes.IntTy, Size);
7886 ivar.finishAndAddTo(ivars);
7887 }
7888 // Return null for empty list.
7889 if (ivars.empty()) {
7890 ivars.abandon();
7891 ivarList.abandon();
7892 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7893 }
7894
7895 auto ivarCount = ivars.size();
7896 ivars.finishAndAddTo(ivarList);
7897 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7898
7899 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_";
7900 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7901 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7902 CGM.addCompilerUsedGlobal(GV);
7903 return GV;
7904}
7905
7906llvm::Constant *
7907CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7908 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7909
7910 assert(!PD->isNonRuntimeProtocol() &&
7911 "attempting to GetOrEmit a non-runtime protocol");
7912 if (!Entry) {
7913 // We use the initializer as a marker of whether this is a forward
7914 // reference or not. At module finalization we add the empty
7915 // contents for protocols which were referenced but never defined.
7916 llvm::SmallString<64> Protocol;
7917 llvm::raw_svector_ostream(Protocol)
7918 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
7919
7920 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7921 false, llvm::GlobalValue::ExternalLinkage,
7922 nullptr, Protocol);
7923 if (!CGM.getTriple().isOSBinFormatMachO())
7924 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7925 }
7926
7927 return Entry;
7928}
7929
7930/// GetOrEmitProtocol - Generate the protocol meta-data:
7931/// @code
7932/// struct _protocol_t {
7933/// id isa; // NULL
7934/// const char * const protocol_name;
7935/// const struct _protocol_list_t * protocol_list; // super protocols
7936/// const struct method_list_t * const instance_methods;
7937/// const struct method_list_t * const class_methods;
7938/// const struct method_list_t *optionalInstanceMethods;
7939/// const struct method_list_t *optionalClassMethods;
7940/// const struct _prop_list_t * properties;
7941/// const uint32_t size; // sizeof(struct _protocol_t)
7942/// const uint32_t flags; // = 0
7943/// const char ** extendedMethodTypes;
7944/// const char *demangledName;
7945/// const struct _prop_list_t * class_properties;
7946/// }
7947/// @endcode
7948///
7949
7950llvm::Constant *
7951CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7952 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7953
7954 // Early exit if a defining object has already been generated.
7955 if (Entry && Entry->hasInitializer())
7956 return Entry;
7957
7958 // Use the protocol definition, if there is one.
7959 assert(PD->hasDefinition() &&
7960 "emitting protocol metadata without definition");
7961 PD = PD->getDefinition();
7962
7963 auto methodLists = ProtocolMethodLists::get(PD);
7964
7965 ConstantInitBuilder builder(CGM);
7966 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7967
7968 // isa is NULL
7969 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7970 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7971 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_" +
7972 PD->getObjCRuntimeNameAsString(),
7973 PD->protocol_begin(), PD->protocol_end()));
7974 values.add(methodLists.emitMethodList(
7975 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7976 values.add(methodLists.emitMethodList(
7977 this, PD, ProtocolMethodLists::RequiredClassMethods));
7978 values.add(methodLists.emitMethodList(
7979 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7980 values.add(methodLists.emitMethodList(
7981 this, PD, ProtocolMethodLists::OptionalClassMethods));
7982 values.add(
7983 EmitPropertyList("_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7984 nullptr, PD, ObjCTypes, false));
7985 uint32_t Size =
7986 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7987 values.addInt(ObjCTypes.IntTy, Size);
7988 values.addInt(ObjCTypes.IntTy, 0);
7989 values.add(EmitProtocolMethodTypes(
7990 "_OBJC_$_PROTOCOL_METHOD_TYPES_" + PD->getObjCRuntimeNameAsString(),
7991 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7992
7993 // const char *demangledName;
7994 values.addNullPointer(ObjCTypes.Int8PtrTy);
7995
7996 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" +
7997 PD->getObjCRuntimeNameAsString(),
7998 nullptr, PD, ObjCTypes, true));
7999
8000 if (Entry) {
8001 // Already created, fix the linkage and update the initializer.
8002 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
8003 values.finishAndSetAsInitializer(Entry);
8004 } else {
8005 llvm::SmallString<64> symbolName;
8006 llvm::raw_svector_ostream(symbolName)
8007 << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
8008
8009 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
8010 /*constant*/ false,
8011 llvm::GlobalValue::WeakAnyLinkage);
8012 if (!CGM.getTriple().isOSBinFormatMachO())
8013 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
8014
8015 Protocols[PD->getIdentifier()] = Entry;
8016 }
8017 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8018 CGM.addUsedGlobal(Entry);
8019
8020 // Use this protocol meta-data to build protocol list table in section
8021 // __DATA, __objc_protolist
8022 llvm::SmallString<64> ProtocolRef;
8023 llvm::raw_svector_ostream(ProtocolRef)
8024 << "_OBJC_LABEL_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
8025
8026 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8027 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8028 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8029 if (!CGM.getTriple().isOSBinFormatMachO())
8030 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8031 PTGV->setAlignment(
8032 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8033 PTGV->setSection(
8034 GetSectionName("__objc_protolist", "coalesced,no_dead_strip"));
8035 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8036 CGM.addUsedGlobal(PTGV);
8037 return Entry;
8038}
8039
8040/// EmitProtocolList - Generate protocol list meta-data:
8041/// @code
8042/// struct _protocol_list_t {
8043/// long protocol_count; // Note, this is 32/64 bit
8044/// struct _protocol_t[protocol_count];
8045/// }
8046/// @endcode
8047///
8048llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8049 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8050 ObjCProtocolDecl::protocol_iterator end) {
8051 // Just return null for empty protocol lists
8052 auto Protocols = GetRuntimeProtocolList(begin, end);
8053 if (Protocols.empty())
8054 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8055
8056 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8057 ProtocolRefs.reserve(Protocols.size());
8058
8059 for (const auto *PD : Protocols)
8060 ProtocolRefs.push_back(GetProtocolRef(PD));
8061
8062 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8063 // just return null
8064 if (ProtocolRefs.size() == 0)
8065 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8066
8067 // FIXME: We shouldn't need to do this lookup here, should we?
8068 SmallString<256> TmpName;
8069 Name.toVector(TmpName);
8070 llvm::GlobalVariable *GV =
8071 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8072 if (GV)
8073 return GV;
8074
8075 ConstantInitBuilder builder(CGM);
8076 auto values = builder.beginStruct();
8077 auto countSlot = values.addPlaceholder();
8078
8079 // A null-terminated array of protocols.
8080 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8081 for (auto const &proto : ProtocolRefs)
8082 array.add(proto);
8083 auto count = array.size();
8084 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8085
8086 array.finishAndAddTo(values);
8087 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8088
8089 GV = finishAndCreateGlobal(values, Name, CGM);
8090 CGM.addCompilerUsedGlobal(GV);
8091 return GV;
8092}
8093
8094/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
8095/// This code gen. amounts to generating code for:
8096/// @code
8097/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
8098/// @encode
8099///
8100LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8101 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8102 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8103 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8104 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8105 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8106 Offset);
8107}
8108
8109llvm::Value *
8110CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8111 const ObjCInterfaceDecl *Interface,
8112 const ObjCIvarDecl *Ivar) {
8113 llvm::Value *IvarOffsetValue;
8114 if (isClassLayoutKnownStatically(Interface)) {
8115 IvarOffsetValue = llvm::ConstantInt::get(
8116 ObjCTypes.IvarOffsetVarTy,
8117 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8118 } else {
8119 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8120 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8121 CGF.getSizeAlign(), "ivar");
8122 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8123 cast<llvm::LoadInst>(IvarOffsetValue)
8124 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8125 llvm::MDNode::get(VMContext, {}));
8126 }
8127
8128 // This could be 32bit int or 64bit integer depending on the architecture.
8129 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8130 // as this is what caller always expects.
8131 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8132 IvarOffsetValue = CGF.Builder.CreateIntCast(
8133 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
8134 return IvarOffsetValue;
8135}
8136
8137static void appendSelectorForMessageRefTable(std::string &buffer,
8138 Selector selector) {
8139 if (selector.isUnarySelector()) {
8140 buffer += selector.getNameForSlot(0);
8141 return;
8142 }
8143
8144 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8145 buffer += selector.getNameForSlot(i);
8146 buffer += '_';
8147 }
8148}
8149
8150/// Emit a "vtable" message send. We emit a weak hidden-visibility
8151/// struct, initially containing the selector pointer and a pointer to
8152/// a "fixup" variant of the appropriate objc_msgSend. To call, we
8153/// load and call the function pointer, passing the address of the
8154/// struct as the second parameter. The runtime determines whether
8155/// the selector is currently emitted using vtable dispatch; if so, it
8156/// substitutes a stub function which simply tail-calls through the
8157/// appropriate vtable slot, and if not, it substitues a stub function
8158/// which tail-calls objc_msgSend. Both stubs adjust the selector
8159/// argument to correctly point to the selector.
8160RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8161 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8162 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8163 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8164 // Compute the actual arguments.
8165 CallArgList args;
8166
8167 // First argument: the receiver / super-call structure.
8168 if (!isSuper)
8169 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8170 args.add(RValue::get(arg0), arg0Type);
8171
8172 // Second argument: a pointer to the message ref structure. Leave
8173 // the actual argument value blank for now.
8174 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8175
8176 llvm::append_range(args, formalArgs);
8177
8178 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8179
8180 NullReturnState nullReturn;
8181
8182 // Find the function to call and the mangled name for the message
8183 // ref structure. Using a different mangled name wouldn't actually
8184 // be a problem; it would just be a waste.
8185 //
8186 // The runtime currently never uses vtable dispatch for anything
8187 // except normal, non-super message-sends.
8188 // FIXME: don't use this for that.
8189 llvm::FunctionCallee fn = nullptr;
8190 std::string messageRefName("_");
8191 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8192 if (isSuper) {
8193 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8194 messageRefName += "objc_msgSendSuper2_stret_fixup";
8195 } else {
8196 nullReturn.init(CGF, arg0);
8197 fn = ObjCTypes.getMessageSendStretFixupFn();
8198 messageRefName += "objc_msgSend_stret_fixup";
8199 }
8200 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8201 fn = ObjCTypes.getMessageSendFpretFixupFn();
8202 messageRefName += "objc_msgSend_fpret_fixup";
8203 } else {
8204 if (isSuper) {
8205 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8206 messageRefName += "objc_msgSendSuper2_fixup";
8207 } else {
8208 fn = ObjCTypes.getMessageSendFixupFn();
8209 messageRefName += "objc_msgSend_fixup";
8210 }
8211 }
8212 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
8213 messageRefName += '_';
8214
8215 // Append the selector name, except use underscores anywhere we
8216 // would have used colons.
8217 appendSelectorForMessageRefTable(messageRefName, selector);
8218
8219 llvm::GlobalVariable *messageRef =
8220 CGM.getModule().getGlobalVariable(messageRefName);
8221 if (!messageRef) {
8222 // Build the message ref structure.
8223 ConstantInitBuilder builder(CGM);
8224 auto values = builder.beginStruct();
8225 values.add(cast<llvm::Constant>(fn.getCallee()));
8226 values.add(GetMethodVarName(selector));
8227 messageRef = values.finishAndCreateGlobal(
8228 messageRefName, CharUnits::fromQuantity(16),
8229 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8230 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8231 messageRef->setSection(GetSectionName("__objc_msgrefs", "coalesced"));
8232 }
8233
8234 bool requiresnullCheck = false;
8235 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8236 for (const auto *ParamDecl : method->parameters()) {
8237 if (ParamDecl->isDestroyedInCallee()) {
8238 if (!nullReturn.NullBB)
8239 nullReturn.init(CGF, arg0);
8240 requiresnullCheck = true;
8241 break;
8242 }
8243 }
8244
8245 Address mref =
8246 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8247 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8248
8249 // Update the message ref argument.
8250 args[1].setRValue(RValue::get(mref, CGF));
8251
8252 // Load the function to call from the message ref table.
8253 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8254 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
8255
8256 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8257 CGCallee callee(CGCalleeInfo(), calleePtr);
8258
8259 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8260 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8261 requiresnullCheck ? method : nullptr);
8262}
8263
8264/// Generate code for a message send expression in the nonfragile abi.
8265CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8266 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8267 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8268 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8269 return isVTableDispatchedSelector(Sel)
8270 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8271 CGF.getContext().getObjCIdType(), false,
8272 CallArgs, Method)
8273 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8274 CGF.getContext().getObjCIdType(), false,
8275 CallArgs, Method, Class, ObjCTypes);
8276}
8277
8278llvm::Constant *
8279CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8280 bool metaclass,
8281 ForDefinition_t isForDefinition) {
8282 auto prefix =
8283 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8284 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8285 isForDefinition, ID->isWeakImported(),
8286 !isForDefinition &&
8287 CGM.getTriple().isOSBinFormatCOFF() &&
8288 ID->hasAttr<DLLImportAttr>());
8289}
8290
8291llvm::Constant *
8292CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8293 ForDefinition_t IsForDefinition,
8294 bool Weak, bool DLLImport) {
8295 llvm::GlobalValue::LinkageTypes L =
8296 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8297 : llvm::GlobalValue::ExternalLinkage;
8298
8299 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8300 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8301 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8302 nullptr, Name);
8303
8304 if (DLLImport)
8305 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8306
8307 if (GV) {
8308 GV->replaceAllUsesWith(NewGV);
8309 GV->eraseFromParent();
8310 }
8311 GV = NewGV;
8312 CGM.getModule().insertGlobalVariable(GV);
8313 }
8314
8315 assert(GV->getLinkage() == L);
8316 return GV;
8317}
8318
8319llvm::Constant *
8320CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8321 llvm::Constant *ClassGV =
8322 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8323
8324 if (!ID->hasAttr<ObjCClassStubAttr>())
8325 return ClassGV;
8326
8327 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8328
8329 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8330 // must set the least significant bit set to 1.
8331 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8332 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8333}
8334
8335llvm::Value *
8336CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8337 const ObjCInterfaceDecl *ID,
8338 llvm::GlobalVariable *Entry) {
8339 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8340 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8341 // a special runtime function.
8342 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8343 "load_classref_result");
8344 }
8345
8346 CharUnits Align = CGF.getPointerAlign();
8347 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8348}
8349
8350llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8351 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8352 llvm::GlobalVariable *&Entry = ClassReferences[II];
8353
8354 if (!Entry) {
8355 llvm::Constant *ClassGV;
8356 if (ID) {
8357 ClassGV = GetClassGlobalForClassRef(ID);
8358 } else {
8359 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8360 NotForDefinition);
8361 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8362 "classref was emitted with the wrong type?");
8363 }
8364
8365 std::string SectionName =
8366 GetSectionName("__objc_classrefs", "regular,no_dead_strip");
8367 Entry = new llvm::GlobalVariable(
8368 CGM.getModule(), ClassGV->getType(), false,
8369 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8370 "OBJC_CLASSLIST_REFERENCES_$_");
8371 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8372 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8373 Entry->setSection(SectionName);
8374
8375 CGM.addCompilerUsedGlobal(Entry);
8376 }
8377
8378 return EmitLoadOfClassRef(CGF, ID, Entry);
8379}
8380
8381llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8382 const ObjCInterfaceDecl *ID) {
8383 // If the class has the objc_runtime_visible attribute, we need to
8384 // use the Objective-C runtime to get the class.
8385 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8386 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8387
8388 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8389}
8390
8391llvm::Value *
8392CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8393 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
8394 return EmitClassRefFromId(CGF, II, nullptr);
8395}
8396
8397llvm::Value *
8398CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8399 const ObjCInterfaceDecl *ID) {
8400 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8401
8402 if (!Entry) {
8403 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8404 std::string SectionName =
8405 GetSectionName("__objc_superrefs", "regular,no_dead_strip");
8406 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8407 llvm::GlobalValue::PrivateLinkage, ClassGV,
8408 "OBJC_CLASSLIST_SUP_REFS_$_");
8409 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8410 Entry->setSection(SectionName);
8411 CGM.addCompilerUsedGlobal(Entry);
8412 }
8413
8414 return EmitLoadOfClassRef(CGF, ID, Entry);
8415}
8416
8417/// EmitMetaClassRef - Return a Value * of the address of _class_t
8418/// meta-data
8419///
8420llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8421 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8422 CharUnits Align = CGF.getPointerAlign();
8423 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8424 if (!Entry) {
8425 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8426 std::string SectionName =
8427 GetSectionName("__objc_superrefs", "regular,no_dead_strip");
8428 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8429 false, llvm::GlobalValue::PrivateLinkage,
8430 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
8431 Entry->setAlignment(Align.getAsAlign());
8432 Entry->setSection(SectionName);
8433 CGM.addCompilerUsedGlobal(Entry);
8434 }
8435
8436 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8437}
8438
8439/// GetClass - Return a reference to the class for the given interface
8440/// decl.
8441llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8442 const ObjCInterfaceDecl *ID) {
8443 if (ID->isWeakImported()) {
8444 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8445 (void)ClassGV;
8446 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8447 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8448 }
8449
8450 return EmitClassRef(CGF, ID);
8451}
8452
8453/// Generates a message send where the super is the receiver. This is
8454/// a message send to self with special delivery semantics indicating
8455/// which class's method should be called.
8456CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8457 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8458 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8459 llvm::Value *Receiver, bool IsClassMessage,
8460 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8461 // ...
8462 // Create and init a super structure; this is a (receiver, class)
8463 // pair we will pass to objc_msgSendSuper.
8464 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8465 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super");
8466
8467 llvm::Value *ReceiverAsObject =
8468 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8469 CGF.Builder.CreateStore(ReceiverAsObject,
8470 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8471
8472 // If this is a class message the metaclass is passed as the target.
8473 llvm::Value *Target;
8474 if (IsClassMessage)
8475 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8476 else
8477 Target = EmitSuperClassRef(CGF, Class);
8478
8479 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8480 // ObjCTypes types.
8481 llvm::Type *ClassTy =
8482 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8483 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8484 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8485
8486 return (isVTableDispatchedSelector(Sel))
8487 ? EmitVTableMessageSend(
8488 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8489 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8490 : EmitMessageSend(CGF, Return, ResultType, Sel,
8491 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8492 true, CallArgs, Method, Class, ObjCTypes);
8493}
8494
8495llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8496 Selector Sel) {
8497 Address Addr = EmitSelectorAddr(Sel);
8498
8499 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8500 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8501 llvm::MDNode::get(VMContext, {}));
8502 return LI;
8503}
8504
8505ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8506 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8507 CharUnits Align = CGM.getPointerAlign();
8508 if (!Entry) {
8509 std::string SectionName =
8510 GetSectionName("__objc_selrefs", "literal_pointers,no_dead_strip");
8511 Entry = new llvm::GlobalVariable(
8512 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8513 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8514 "OBJC_SELECTOR_REFERENCES_");
8515 Entry->setExternallyInitialized(true);
8516 Entry->setSection(SectionName);
8517 Entry->setAlignment(Align.getAsAlign());
8518 CGM.addCompilerUsedGlobal(Entry);
8519 }
8520
8521 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8522}
8523
8524/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
8525/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
8526///
8527void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8528 llvm::Value *src, Address dst,
8529 llvm::Value *ivarOffset) {
8530 llvm::Type *SrcTy = src->getType();
8531 if (!isa<llvm::PointerType>(SrcTy)) {
8532 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8533 assert(Size <= 8 && "does not support size > 8");
8534 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8535 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8536 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8537 }
8538 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8539 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8540 ObjCTypes.PtrObjectPtrTy);
8541 llvm::Value *args[] = {src, dstVal, ivarOffset};
8542 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8543}
8544
8545/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
8546/// objc_assign_strongCast (id src, id *dst)
8547///
8548void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8549 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8550 llvm::Type *SrcTy = src->getType();
8551 if (!isa<llvm::PointerType>(SrcTy)) {
8552 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8553 assert(Size <= 8 && "does not support size > 8");
8554 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8555 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8556 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8557 }
8558 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8559 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8560 ObjCTypes.PtrObjectPtrTy);
8561 llvm::Value *args[] = {src, dstVal};
8562 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8563 "weakassign");
8564}
8565
8566void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8567 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8568 llvm::Value *Size) {
8569 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8570 SrcPtr.emitRawPointer(CGF), Size};
8571 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8572}
8573
8574/// EmitObjCWeakRead - Code gen for loading value of a __weak
8575/// object: objc_read_weak (id *src)
8576///
8577llvm::Value *
8578CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8579 Address AddrWeakObj) {
8580 llvm::Type *DestTy = AddrWeakObj.getElementType();
8581 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8582 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8583 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8584 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread");
8585 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8586 return read_weak;
8587}
8588
8589/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
8590/// objc_assign_weak (id src, id *dst)
8591///
8592void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8593 llvm::Value *src, Address dst) {
8594 llvm::Type *SrcTy = src->getType();
8595 if (!isa<llvm::PointerType>(SrcTy)) {
8596 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8597 assert(Size <= 8 && "does not support size > 8");
8598 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8599 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8600 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8601 }
8602 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8603 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8604 ObjCTypes.PtrObjectPtrTy);
8605 llvm::Value *args[] = {src, dstVal};
8606 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8607 "weakassign");
8608}
8609
8610/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
8611/// objc_assign_global (id src, id *dst)
8612///
8613void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8614 llvm::Value *src, Address dst,
8615 bool threadlocal) {
8616 llvm::Type *SrcTy = src->getType();
8617 if (!isa<llvm::PointerType>(SrcTy)) {
8618 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8619 assert(Size <= 8 && "does not support size > 8");
8620 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8621 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8622 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8623 }
8624 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8625 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8626 ObjCTypes.PtrObjectPtrTy);
8627 llvm::Value *args[] = {src, dstVal};
8628 if (!threadlocal)
8629 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8630 "globalassign");
8631 else
8632 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8633 "threadlocalassign");
8634}
8635
8636void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8637 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8638 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8639 ObjCTypes.getSyncExitFn());
8640}
8641
8642llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8643 // There's a particular fixed type info for 'id'.
8644 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8645 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
8646 if (!IDEHType) {
8647 IDEHType = new llvm::GlobalVariable(
8648 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8649 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id");
8650 if (CGM.getTriple().isOSBinFormatCOFF())
8651 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id"));
8652 }
8653 return IDEHType;
8654 }
8655
8656 // All other types should be Objective-C interface pointer types.
8657 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8658 assert(PT && "Invalid @catch type.");
8659
8660 const ObjCInterfaceType *IT = PT->getInterfaceType();
8661 assert(IT && "Invalid @catch type.");
8662
8663 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8664}
8665
8666void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8667 const ObjCAtTryStmt &S) {
8668 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8669 ObjCTypes.getObjCEndCatchFn(),
8670 ObjCTypes.getExceptionRethrowFn());
8671}
8672
8673/// EmitThrowStmt - Generate code for a throw statement.
8674void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8675 const ObjCAtThrowStmt &S,
8676 bool ClearInsertionPoint) {
8677 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8678 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8679 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8680 llvm::CallBase *Call =
8681 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8682 Call->setDoesNotReturn();
8683 } else {
8684 llvm::CallBase *Call =
8685 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8686 Call->setDoesNotReturn();
8687 }
8688
8689 CGF.Builder.CreateUnreachable();
8690 if (ClearInsertionPoint)
8691 CGF.Builder.ClearInsertionPoint();
8692}
8693
8694llvm::Constant *
8695CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8696 ForDefinition_t IsForDefinition) {
8697 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8698 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8699
8700 // If we don't need a definition, return the entry if found or check
8701 // if we use an external reference.
8702 if (!IsForDefinition) {
8703 if (Entry)
8704 return Entry;
8705
8706 // If this type (or a super class) has the __objc_exception__
8707 // attribute, emit an external reference.
8708 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8709 std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();
8710 Entry = new llvm::GlobalVariable(
8711 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8712 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8713 CGM.setGVProperties(Entry, ID);
8714 return Entry;
8715 }
8716 }
8717
8718 // Otherwise we need to either make a new entry or fill in the initializer.
8719 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
8720
8721 std::string VTableName = "objc_ehtype_vtable";
8722 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8723 if (!VTableGV) {
8724 VTableGV = new llvm::GlobalVariable(
8725 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8726 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8727 if (CGM.getTriple().isOSBinFormatCOFF())
8728 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8729 }
8730
8731 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8732 llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(
8733 VTableGV->getValueType(), VTableGV, VTableIdx);
8734
8735 ConstantInitBuilder builder(CGM);
8736 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8737 const PointerAuthSchema &TypeInfoSchema =
8738 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8739 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8740
8741 values.add(GetClassName(ClassName));
8742 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8743
8744 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8745 ? llvm::GlobalValue::ExternalLinkage
8746 : llvm::GlobalValue::WeakAnyLinkage;
8747 if (Entry) {
8748 values.finishAndSetAsInitializer(Entry);
8749 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8750 } else {
8751 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_" + ClassName,
8752 CGM.getPointerAlign(),
8753 /*constant*/ false, L);
8754 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8755 CGM.setGVProperties(Entry, ID);
8756 }
8757 assert(Entry->getLinkage() == L);
8758
8759 if (!CGM.getTriple().isOSBinFormatCOFF())
8760 if (ID->getVisibility() == HiddenVisibility)
8761 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8762
8763 if (IsForDefinition)
8764 if (CGM.getTriple().isOSBinFormatMachO())
8765 Entry->setSection("__DATA,__objc_const");
8766
8767 return Entry;
8768}
8769
8770/* *** */
8771
8772CodeGen::CGObjCRuntime *
8773CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8774 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8775 case ObjCRuntime::FragileMacOSX:
8776 return new CGObjCMac(CGM);
8777
8778 case ObjCRuntime::MacOSX:
8779 case ObjCRuntime::iOS:
8780 case ObjCRuntime::WatchOS:
8781 return new CGObjCNonFragileABIMac(CGM);
8782
8783 case ObjCRuntime::GNUstep:
8784 case ObjCRuntime::GCC:
8785 case ObjCRuntime::ObjFW:
8786 llvm_unreachable("these runtimes are not Mac runtimes");
8787 }
8788 llvm_unreachable("bad runtime");
8789}
8790
8791// Public wrapper function for external compilers (e.g., Swift) to access
8792// the Mac runtime's GetDirectMethodCallee functionality.
8793llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8794 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8795 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8796 // This function should only be called when targeting Darwin platforms,
8797 // which always use the Mac runtime.
8798 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8799 "getObjCDirectMethodCallee requires Mac ObjC runtime");
8800 CGObjCCommonMac *MacRuntime =
8801 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8802 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8803 ClassObjectCanBeUnrealized);
8804}
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 llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
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.
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
#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:227
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:805
const LangOptions & getLangOpts() const
Definition ASTContext.h:959
SelectorTable & Selectors
Definition ASTContext.h:806
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
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
Definition CharUnits.h:189
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition CharUnits.h:58
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition CharUnits.h:53
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:146
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Definition CGBuilder.h:388
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Definition CGBuilder.h:302
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition CGBuilder.h:229
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:118
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Definition CGBuilder.h:138
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition CGCall.h:137
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:302
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Definition CGCall.h:311
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:1349
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:3574
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:158
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:5427
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:58
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:204
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:2276
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:643
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:1840
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:1857
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:1835
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:2553
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:1825
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:1873
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
Definition CGCall.cpp:747
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
Definition CGCall.cpp:563
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:375
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:576
bool hasAttr() const
Definition DeclBase.h:585
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3281
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
Definition Decl.cpp:4747
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
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:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
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:948
method_range methods() const
Definition DeclObjC.h:1016
prop_range properties() const
Definition DeclObjC.h:967
const ObjCInterfaceDecl * getClassInterface() const
Definition DeclObjC.h:2486
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2597
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
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:1810
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
Definition DeclObjC.h:1987
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
ImplicitParamDecl * getSelfDecl() const
Definition DeclObjC.h:418
param_const_iterator param_end() const
Definition DeclObjC.h:358
param_const_iterator param_begin() const
Definition DeclObjC.h:354
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition DeclObjC.cpp:906
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:868
Selector getSelector() const
Definition DeclObjC.h:327
ImplicitParamDecl * getCmdDecl() const
Definition DeclObjC.h:420
bool isInstanceMethod() const
Definition DeclObjC.h:426
QualType getReturnType() const
Definition DeclObjC.h:329
bool isClassMethod() const
Definition DeclObjC.h:434
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition TypeBase.h:8129
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Definition TypeBase.h:8091
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Definition TypeBase.h:8112
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition DeclObjC.h:2250
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCProtocolList::iterator protocol_iterator
Definition DeclObjC.h:2158
protocol_iterator protocol_begin() const
Definition DeclObjC.h:2165
protocol_range protocols() const
Definition DeclObjC.h:2161
protocol_iterator protocol_end() const
Definition DeclObjC.h:2172
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:3383
A (possibly-)qualified type.
Definition TypeBase.h:937
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1449
bool isObjCGCStrong() const
true when Type is objc's strong.
Definition TypeBase.h:1444
bool isObjCGCWeak() const
true when Type is objc's weak.
Definition TypeBase.h:1439
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:367
field_range fields() const
Definition Decl.h:4546
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:1802
bool isUnion() const
Definition Decl.h:3946
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:490
unsigned getCharWidth() const
Definition TargetInfo.h:521
bool isBlockPointerType() const
Definition TypeBase.h:8693
bool isVoidType() const
Definition TypeBase.h:9039
bool isArrayType() const
Definition TypeBase.h:8772
CanQualType getCanonicalTypeUnqualified() const
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8873
bool isObjCIdType() const
Definition TypeBase.h:8885
bool isObjCObjectPointerType() const
Definition TypeBase.h:8852
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8879
bool isObjCClassType() const
Definition TypeBase.h:8891
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2976
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
Definition TypeBase.h:2983
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9266
bool isRecordType() const
Definition TypeBase.h:8800
bool isUnionType() const
Definition Type.cpp:755
QualType getType() const
Definition Decl.h:723
#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:1449
@ 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...
The JSON file list parser is used to communicate input to InstallAPI.
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:830
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.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Type
The name was classified as a type.
Definition Sema.h:564
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:279
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5966
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5972
@ 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.