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