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