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