1 //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This provides Objective-C code generation targetting the Apple runtime.
12 //===----------------------------------------------------------------------===//
14 #include "CGObjCRuntime.h"
16 #include "CodeGenModule.h"
17 #include "CodeGenFunction.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/RecordLayout.h"
22 #include "clang/AST/StmtObjC.h"
23 #include "clang/Basic/LangOptions.h"
25 #include "llvm/Intrinsics.h"
26 #include "llvm/LLVMContext.h"
27 #include "llvm/Module.h"
28 #include "llvm/ADT/DenseSet.h"
29 #include "llvm/ADT/SetVector.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Target/TargetData.h"
35 using namespace clang;
36 using namespace CodeGen;
38 // Common CGObjCRuntime functions, these don't belong here, but they
39 // don't belong in CGObjCRuntime either so we will live with it for
42 /// FindIvarInterface - Find the interface containing the ivar.
44 /// FIXME: We shouldn't need to do this, the containing context should
46 static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
47 const ObjCInterfaceDecl *OID,
48 const ObjCIvarDecl *OIVD,
50 // FIXME: The index here is closely tied to how
51 // ASTContext::getObjCLayout is implemented. This should be fixed to
52 // get the information from the layout directly.
54 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
55 Context.ShallowCollectObjCIvars(OID, Ivars);
56 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
62 // Otherwise check in the super class.
63 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
64 return FindIvarInterface(Context, Super, OIVD, Index);
69 static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
70 const ObjCInterfaceDecl *OID,
71 const ObjCImplementationDecl *ID,
72 const ObjCIvarDecl *Ivar) {
74 const ObjCInterfaceDecl *Container =
75 FindIvarInterface(CGM.getContext(), OID, Ivar, Index);
76 assert(Container && "Unable to find ivar container");
78 // If we know have an implementation (and the ivar is in it) then
79 // look up in the implementation layout.
80 const ASTRecordLayout *RL;
81 if (ID && ID->getClassInterface() == Container)
82 RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
84 RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
85 return RL->getFieldOffset(Index);
88 uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
89 const ObjCInterfaceDecl *OID,
90 const ObjCIvarDecl *Ivar) {
91 return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
94 uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
95 const ObjCImplementationDecl *OID,
96 const ObjCIvarDecl *Ivar) {
97 return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
100 LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
101 const ObjCInterfaceDecl *OID,
102 llvm::Value *BaseValue,
103 const ObjCIvarDecl *Ivar,
104 unsigned CVRQualifiers,
105 llvm::Value *Offset) {
106 // Compute (type*) ( (char *) BaseValue + Offset)
107 const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
108 QualType IvarTy = Ivar->getType();
109 const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
110 llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
111 V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
112 V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
114 Qualifiers Quals = CGF.MakeQualifiers(IvarTy);
115 Quals.addCVRQualifiers(CVRQualifiers);
117 if (Ivar->isBitField()) {
118 // We need to compute the bit offset for the bit-field, the offset
119 // is to the byte. Note, there is a subtle invariant here: we can
120 // only call this routine on non-sythesized ivars but we may be
121 // called for synthesized ivars. However, a synthesized ivar can
122 // never be a bit-field so this is safe.
123 uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8;
125 uint64_t BitFieldSize =
126 Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
127 return LValue::MakeBitfield(V, BitOffset, BitFieldSize,
128 IvarTy->isSignedIntegerType(),
129 Quals.getCVRQualifiers());
133 LValue LV = LValue::MakeAddr(V, Quals);
141 typedef std::vector<llvm::Constant*> ConstantVector;
143 // FIXME: We should find a nicer way to make the labels for metadata, string
144 // concatenation is lame.
146 class ObjCCommonTypesHelper {
148 llvm::LLVMContext &VMContext;
151 llvm::Constant *getMessageSendFn() const {
152 // id objc_msgSend (id, SEL, ...)
153 std::vector<const llvm::Type*> Params;
154 Params.push_back(ObjectPtrTy);
155 Params.push_back(SelectorPtrTy);
157 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
162 llvm::Constant *getMessageSendStretFn() const {
163 // id objc_msgSend_stret (id, SEL, ...)
164 std::vector<const llvm::Type*> Params;
165 Params.push_back(ObjectPtrTy);
166 Params.push_back(SelectorPtrTy);
168 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
170 "objc_msgSend_stret");
174 llvm::Constant *getMessageSendFpretFn() const {
175 // FIXME: This should be long double on x86_64?
176 // [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
177 std::vector<const llvm::Type*> Params;
178 Params.push_back(ObjectPtrTy);
179 Params.push_back(SelectorPtrTy);
181 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
182 llvm::Type::getDoubleTy(VMContext),
185 "objc_msgSend_fpret");
189 llvm::Constant *getMessageSendSuperFn() const {
190 // id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
191 const char *SuperName = "objc_msgSendSuper";
192 std::vector<const llvm::Type*> Params;
193 Params.push_back(SuperPtrTy);
194 Params.push_back(SelectorPtrTy);
195 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
200 llvm::Constant *getMessageSendSuperFn2() const {
201 // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
202 const char *SuperName = "objc_msgSendSuper2";
203 std::vector<const llvm::Type*> Params;
204 Params.push_back(SuperPtrTy);
205 Params.push_back(SelectorPtrTy);
206 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
211 llvm::Constant *getMessageSendSuperStretFn() const {
212 // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
214 std::vector<const llvm::Type*> Params;
215 Params.push_back(Int8PtrTy);
216 Params.push_back(SuperPtrTy);
217 Params.push_back(SelectorPtrTy);
218 return CGM.CreateRuntimeFunction(
219 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
221 "objc_msgSendSuper_stret");
224 llvm::Constant *getMessageSendSuperStretFn2() const {
225 // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
227 std::vector<const llvm::Type*> Params;
228 Params.push_back(Int8PtrTy);
229 Params.push_back(SuperPtrTy);
230 Params.push_back(SelectorPtrTy);
231 return CGM.CreateRuntimeFunction(
232 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
234 "objc_msgSendSuper2_stret");
237 llvm::Constant *getMessageSendSuperFpretFn() const {
238 // There is no objc_msgSendSuper_fpret? How can that work?
239 return getMessageSendSuperFn();
242 llvm::Constant *getMessageSendSuperFpretFn2() const {
243 // There is no objc_msgSendSuper_fpret? How can that work?
244 return getMessageSendSuperFn2();
248 CodeGen::CodeGenModule &CGM;
251 const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
252 const llvm::Type *Int8PtrTy;
254 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
255 const llvm::Type *ObjectPtrTy;
257 /// PtrObjectPtrTy - LLVM type for id *
258 const llvm::Type *PtrObjectPtrTy;
260 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
261 const llvm::Type *SelectorPtrTy;
262 /// ProtocolPtrTy - LLVM type for external protocol handles
263 /// (typeof(Protocol))
264 const llvm::Type *ExternalProtocolPtrTy;
266 // SuperCTy - clang type for struct objc_super.
268 // SuperPtrCTy - clang type for struct objc_super *.
269 QualType SuperPtrCTy;
271 /// SuperTy - LLVM type for struct objc_super.
272 const llvm::StructType *SuperTy;
273 /// SuperPtrTy - LLVM type for struct objc_super *.
274 const llvm::Type *SuperPtrTy;
276 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
277 /// in GCC parlance).
278 const llvm::StructType *PropertyTy;
280 /// PropertyListTy - LLVM type for struct objc_property_list
281 /// (_prop_list_t in GCC parlance).
282 const llvm::StructType *PropertyListTy;
283 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
284 const llvm::Type *PropertyListPtrTy;
286 // MethodTy - LLVM type for struct objc_method.
287 const llvm::StructType *MethodTy;
289 /// CacheTy - LLVM type for struct objc_cache.
290 const llvm::Type *CacheTy;
291 /// CachePtrTy - LLVM type for struct objc_cache *.
292 const llvm::Type *CachePtrTy;
294 llvm::Constant *getGetPropertyFn() {
295 CodeGen::CodeGenTypes &Types = CGM.getTypes();
296 ASTContext &Ctx = CGM.getContext();
297 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
298 llvm::SmallVector<QualType,16> Params;
299 QualType IdType = Ctx.getObjCIdType();
300 QualType SelType = Ctx.getObjCSelType();
301 Params.push_back(IdType);
302 Params.push_back(SelType);
303 Params.push_back(Ctx.LongTy);
304 Params.push_back(Ctx.BoolTy);
305 const llvm::FunctionType *FTy =
306 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params), false);
307 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
310 llvm::Constant *getSetPropertyFn() {
311 CodeGen::CodeGenTypes &Types = CGM.getTypes();
312 ASTContext &Ctx = CGM.getContext();
313 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
314 llvm::SmallVector<QualType,16> Params;
315 QualType IdType = Ctx.getObjCIdType();
316 QualType SelType = Ctx.getObjCSelType();
317 Params.push_back(IdType);
318 Params.push_back(SelType);
319 Params.push_back(Ctx.LongTy);
320 Params.push_back(IdType);
321 Params.push_back(Ctx.BoolTy);
322 Params.push_back(Ctx.BoolTy);
323 const llvm::FunctionType *FTy =
324 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
325 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
328 llvm::Constant *getEnumerationMutationFn() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
331 // void objc_enumerationMutation (id)
332 llvm::SmallVector<QualType,16> Params;
333 Params.push_back(Ctx.getObjCIdType());
334 const llvm::FunctionType *FTy =
335 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
336 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
339 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
340 llvm::Constant *getGcReadWeakFn() {
341 // id objc_read_weak (id *)
342 std::vector<const llvm::Type*> Args;
343 Args.push_back(ObjectPtrTy->getPointerTo());
344 llvm::FunctionType *FTy =
345 llvm::FunctionType::get(ObjectPtrTy, Args, false);
346 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
349 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
350 llvm::Constant *getGcAssignWeakFn() {
351 // id objc_assign_weak (id, id *)
352 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
353 Args.push_back(ObjectPtrTy->getPointerTo());
354 llvm::FunctionType *FTy =
355 llvm::FunctionType::get(ObjectPtrTy, Args, false);
356 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
359 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
360 llvm::Constant *getGcAssignGlobalFn() {
361 // id objc_assign_global(id, id *)
362 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
363 Args.push_back(ObjectPtrTy->getPointerTo());
364 llvm::FunctionType *FTy =
365 llvm::FunctionType::get(ObjectPtrTy, Args, false);
366 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
369 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
370 llvm::Constant *getGcAssignIvarFn() {
371 // id objc_assign_ivar(id, id *, ptrdiff_t)
372 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
373 Args.push_back(ObjectPtrTy->getPointerTo());
374 Args.push_back(LongTy);
375 llvm::FunctionType *FTy =
376 llvm::FunctionType::get(ObjectPtrTy, Args, false);
377 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
380 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
381 llvm::Constant *GcMemmoveCollectableFn() {
382 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
383 std::vector<const llvm::Type*> Args(1, Int8PtrTy);
384 Args.push_back(Int8PtrTy);
385 Args.push_back(LongTy);
386 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
387 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
390 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
391 llvm::Constant *getGcAssignStrongCastFn() {
392 // id objc_assign_global(id, id *)
393 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
394 Args.push_back(ObjectPtrTy->getPointerTo());
395 llvm::FunctionType *FTy =
396 llvm::FunctionType::get(ObjectPtrTy, Args, false);
397 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
400 /// ExceptionThrowFn - LLVM objc_exception_throw function.
401 llvm::Constant *getExceptionThrowFn() {
402 // void objc_exception_throw(id)
403 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
404 llvm::FunctionType *FTy =
405 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
406 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
409 /// SyncEnterFn - LLVM object_sync_enter function.
410 llvm::Constant *getSyncEnterFn() {
411 // void objc_sync_enter (id)
412 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
413 llvm::FunctionType *FTy =
414 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
415 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
418 /// SyncExitFn - LLVM object_sync_exit function.
419 llvm::Constant *getSyncExitFn() {
420 // void objc_sync_exit (id)
421 std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
422 llvm::FunctionType *FTy =
423 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
424 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
427 llvm::Constant *getSendFn(bool IsSuper) const {
428 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
431 llvm::Constant *getSendFn2(bool IsSuper) const {
432 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
435 llvm::Constant *getSendStretFn(bool IsSuper) const {
436 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
439 llvm::Constant *getSendStretFn2(bool IsSuper) const {
440 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
443 llvm::Constant *getSendFpretFn(bool IsSuper) const {
444 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
447 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
448 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
451 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
452 ~ObjCCommonTypesHelper(){}
455 /// ObjCTypesHelper - Helper class that encapsulates lazy
456 /// construction of varies types used during ObjC generation.
457 class ObjCTypesHelper : public ObjCCommonTypesHelper {
459 /// SymtabTy - LLVM type for struct objc_symtab.
460 const llvm::StructType *SymtabTy;
461 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
462 const llvm::Type *SymtabPtrTy;
463 /// ModuleTy - LLVM type for struct objc_module.
464 const llvm::StructType *ModuleTy;
466 /// ProtocolTy - LLVM type for struct objc_protocol.
467 const llvm::StructType *ProtocolTy;
468 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
469 const llvm::Type *ProtocolPtrTy;
470 /// ProtocolExtensionTy - LLVM type for struct
471 /// objc_protocol_extension.
472 const llvm::StructType *ProtocolExtensionTy;
473 /// ProtocolExtensionTy - LLVM type for struct
474 /// objc_protocol_extension *.
475 const llvm::Type *ProtocolExtensionPtrTy;
476 /// MethodDescriptionTy - LLVM type for struct
477 /// objc_method_description.
478 const llvm::StructType *MethodDescriptionTy;
479 /// MethodDescriptionListTy - LLVM type for struct
480 /// objc_method_description_list.
481 const llvm::StructType *MethodDescriptionListTy;
482 /// MethodDescriptionListPtrTy - LLVM type for struct
483 /// objc_method_description_list *.
484 const llvm::Type *MethodDescriptionListPtrTy;
485 /// ProtocolListTy - LLVM type for struct objc_property_list.
486 const llvm::Type *ProtocolListTy;
487 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
488 const llvm::Type *ProtocolListPtrTy;
489 /// CategoryTy - LLVM type for struct objc_category.
490 const llvm::StructType *CategoryTy;
491 /// ClassTy - LLVM type for struct objc_class.
492 const llvm::StructType *ClassTy;
493 /// ClassPtrTy - LLVM type for struct objc_class *.
494 const llvm::Type *ClassPtrTy;
495 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
496 const llvm::StructType *ClassExtensionTy;
497 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
498 const llvm::Type *ClassExtensionPtrTy;
499 // IvarTy - LLVM type for struct objc_ivar.
500 const llvm::StructType *IvarTy;
501 /// IvarListTy - LLVM type for struct objc_ivar_list.
502 const llvm::Type *IvarListTy;
503 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
504 const llvm::Type *IvarListPtrTy;
505 /// MethodListTy - LLVM type for struct objc_method_list.
506 const llvm::Type *MethodListTy;
507 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
508 const llvm::Type *MethodListPtrTy;
510 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
511 const llvm::Type *ExceptionDataTy;
513 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
514 llvm::Constant *getExceptionTryEnterFn() {
515 std::vector<const llvm::Type*> Params;
516 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
517 return CGM.CreateRuntimeFunction(
518 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
520 "objc_exception_try_enter");
523 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
524 llvm::Constant *getExceptionTryExitFn() {
525 std::vector<const llvm::Type*> Params;
526 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
527 return CGM.CreateRuntimeFunction(
528 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
530 "objc_exception_try_exit");
533 /// ExceptionExtractFn - LLVM objc_exception_extract function.
534 llvm::Constant *getExceptionExtractFn() {
535 std::vector<const llvm::Type*> Params;
536 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
537 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
539 "objc_exception_extract");
543 /// ExceptionMatchFn - LLVM objc_exception_match function.
544 llvm::Constant *getExceptionMatchFn() {
545 std::vector<const llvm::Type*> Params;
546 Params.push_back(ClassPtrTy);
547 Params.push_back(ObjectPtrTy);
548 return CGM.CreateRuntimeFunction(
549 llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
551 "objc_exception_match");
555 /// SetJmpFn - LLVM _setjmp function.
556 llvm::Constant *getSetJmpFn() {
557 std::vector<const llvm::Type*> Params;
558 Params.push_back(llvm::Type::getInt32PtrTy(VMContext));
560 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
567 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
568 ~ObjCTypesHelper() {}
571 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
573 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
576 // MethodListnfABITy - LLVM for struct _method_list_t
577 const llvm::StructType *MethodListnfABITy;
579 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
580 const llvm::Type *MethodListnfABIPtrTy;
582 // ProtocolnfABITy = LLVM for struct _protocol_t
583 const llvm::StructType *ProtocolnfABITy;
585 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
586 const llvm::Type *ProtocolnfABIPtrTy;
588 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
589 const llvm::StructType *ProtocolListnfABITy;
591 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
592 const llvm::Type *ProtocolListnfABIPtrTy;
594 // ClassnfABITy - LLVM for struct _class_t
595 const llvm::StructType *ClassnfABITy;
597 // ClassnfABIPtrTy - LLVM for struct _class_t*
598 const llvm::Type *ClassnfABIPtrTy;
600 // IvarnfABITy - LLVM for struct _ivar_t
601 const llvm::StructType *IvarnfABITy;
603 // IvarListnfABITy - LLVM for struct _ivar_list_t
604 const llvm::StructType *IvarListnfABITy;
606 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
607 const llvm::Type *IvarListnfABIPtrTy;
609 // ClassRonfABITy - LLVM for struct _class_ro_t
610 const llvm::StructType *ClassRonfABITy;
612 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
613 const llvm::Type *ImpnfABITy;
615 // CategorynfABITy - LLVM for struct _category_t
616 const llvm::StructType *CategorynfABITy;
618 // New types for nonfragile abi messaging.
620 // MessageRefTy - LLVM for:
621 // struct _message_ref_t {
625 const llvm::StructType *MessageRefTy;
626 // MessageRefCTy - clang type for struct _message_ref_t
627 QualType MessageRefCTy;
629 // MessageRefPtrTy - LLVM for struct _message_ref_t*
630 const llvm::Type *MessageRefPtrTy;
631 // MessageRefCPtrTy - clang type for struct _message_ref_t*
632 QualType MessageRefCPtrTy;
634 // MessengerTy - Type of the messenger (shown as IMP above)
635 const llvm::FunctionType *MessengerTy;
637 // SuperMessageRefTy - LLVM for:
638 // struct _super_message_ref_t {
639 // SUPER_IMP messenger;
642 const llvm::StructType *SuperMessageRefTy;
644 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
645 const llvm::Type *SuperMessageRefPtrTy;
647 llvm::Constant *getMessageSendFixupFn() {
648 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
649 std::vector<const llvm::Type*> Params;
650 Params.push_back(ObjectPtrTy);
651 Params.push_back(MessageRefPtrTy);
652 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
654 "objc_msgSend_fixup");
657 llvm::Constant *getMessageSendFpretFixupFn() {
658 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
659 std::vector<const llvm::Type*> Params;
660 Params.push_back(ObjectPtrTy);
661 Params.push_back(MessageRefPtrTy);
662 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
664 "objc_msgSend_fpret_fixup");
667 llvm::Constant *getMessageSendStretFixupFn() {
668 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
669 std::vector<const llvm::Type*> Params;
670 Params.push_back(ObjectPtrTy);
671 Params.push_back(MessageRefPtrTy);
672 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
674 "objc_msgSend_stret_fixup");
677 llvm::Constant *getMessageSendIdFixupFn() {
678 // id objc_msgSendId_fixup(id, struct message_ref_t*, ...)
679 std::vector<const llvm::Type*> Params;
680 Params.push_back(ObjectPtrTy);
681 Params.push_back(MessageRefPtrTy);
682 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
684 "objc_msgSendId_fixup");
687 llvm::Constant *getMessageSendIdStretFixupFn() {
688 // id objc_msgSendId_stret_fixup(id, struct message_ref_t*, ...)
689 std::vector<const llvm::Type*> Params;
690 Params.push_back(ObjectPtrTy);
691 Params.push_back(MessageRefPtrTy);
692 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
694 "objc_msgSendId_stret_fixup");
696 llvm::Constant *getMessageSendSuper2FixupFn() {
697 // id objc_msgSendSuper2_fixup (struct objc_super *,
698 // struct _super_message_ref_t*, ...)
699 std::vector<const llvm::Type*> Params;
700 Params.push_back(SuperPtrTy);
701 Params.push_back(SuperMessageRefPtrTy);
702 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
704 "objc_msgSendSuper2_fixup");
707 llvm::Constant *getMessageSendSuper2StretFixupFn() {
708 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
709 // struct _super_message_ref_t*, ...)
710 std::vector<const llvm::Type*> Params;
711 Params.push_back(SuperPtrTy);
712 Params.push_back(SuperMessageRefPtrTy);
713 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
715 "objc_msgSendSuper2_stret_fixup");
720 /// EHPersonalityPtr - LLVM value for an i8* to the Objective-C
721 /// exception personality function.
722 llvm::Value *getEHPersonalityPtr() {
723 llvm::Constant *Personality =
724 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
726 "__objc_personality_v0");
727 return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy);
730 llvm::Constant *getUnwindResumeOrRethrowFn() {
731 std::vector<const llvm::Type*> Params;
732 Params.push_back(Int8PtrTy);
733 return CGM.CreateRuntimeFunction(
734 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
736 "_Unwind_Resume_or_Rethrow");
739 llvm::Constant *getObjCEndCatchFn() {
740 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
746 llvm::Constant *getObjCBeginCatchFn() {
747 std::vector<const llvm::Type*> Params;
748 Params.push_back(Int8PtrTy);
749 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
754 const llvm::StructType *EHTypeTy;
755 const llvm::Type *EHTypePtrTy;
757 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
758 ~ObjCNonFragileABITypesHelper(){}
761 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
763 // FIXME - accessibility
766 unsigned ivar_bytepos;
768 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
769 : ivar_bytepos(bytepos), ivar_size(size) {}
771 // Allow sorting based on byte pos.
772 bool operator<(const GC_IVAR &b) const {
773 return ivar_bytepos < b.ivar_bytepos;
781 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
782 : skip(_skip), scan(_scan) {}
786 CodeGen::CodeGenModule &CGM;
787 llvm::LLVMContext &VMContext;
788 // FIXME! May not be needing this after all.
791 // gc ivar layout bitmap calculation helper caches.
792 llvm::SmallVector<GC_IVAR, 16> SkipIvars;
793 llvm::SmallVector<GC_IVAR, 16> IvarsInfo;
795 /// LazySymbols - Symbols to generate a lazy reference for. See
796 /// DefinedSymbols and FinishModule().
797 llvm::SetVector<IdentifierInfo*> LazySymbols;
799 /// DefinedSymbols - External symbols which are defined by this
800 /// module. The symbols in this list and LazySymbols are used to add
801 /// special linker symbols which ensure that Objective-C modules are
803 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
805 /// ClassNames - uniqued class names.
806 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
808 /// MethodVarNames - uniqued method variable names.
809 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
811 /// MethodVarTypes - uniqued method type signatures. We have to use
812 /// a StringMap here because have no other unique reference.
813 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
815 /// MethodDefinitions - map of methods which have been defined in
816 /// this translation unit.
817 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
819 /// PropertyNames - uniqued method variable names.
820 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
822 /// ClassReferences - uniqued class references.
823 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
825 /// SelectorReferences - uniqued selector references.
826 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
828 /// Protocols - Protocols for which an objc_protocol structure has
829 /// been emitted. Forward declarations are handled by creating an
830 /// empty structure whose initializer is filled in when/if defined.
831 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
833 /// DefinedProtocols - Protocols which have actually been
834 /// defined. We should not need this, see FIXME in GenerateProtocol.
835 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
837 /// DefinedClasses - List of defined classes.
838 std::vector<llvm::GlobalValue*> DefinedClasses;
840 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
841 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
843 /// DefinedCategories - List of defined categories.
844 std::vector<llvm::GlobalValue*> DefinedCategories;
846 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
847 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
849 /// GetNameForMethod - Return a name for the given method.
850 /// \param[out] NameOut - The return value.
851 void GetNameForMethod(const ObjCMethodDecl *OMD,
852 const ObjCContainerDecl *CD,
853 llvm::SmallVectorImpl<char> &NameOut);
855 /// GetMethodVarName - Return a unique constant for the given
856 /// selector's name. The return value has type char *.
857 llvm::Constant *GetMethodVarName(Selector Sel);
858 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
859 llvm::Constant *GetMethodVarName(const std::string &Name);
861 /// GetMethodVarType - Return a unique constant for the given
862 /// selector's name. The return value has type char *.
864 // FIXME: This is a horrible name.
865 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
866 llvm::Constant *GetMethodVarType(const FieldDecl *D);
868 /// GetPropertyName - Return a unique constant for the given
869 /// name. The return value has type char *.
870 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
872 // FIXME: This can be dropped once string functions are unified.
873 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
874 const Decl *Container);
876 /// GetClassName - Return a unique constant for the given selector's
877 /// name. The return value has type char *.
878 llvm::Constant *GetClassName(IdentifierInfo *Ident);
880 /// BuildIvarLayout - Builds ivar layout bitmap for the class
881 /// implementation for the __strong or __weak case.
883 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
884 bool ForStrongLayout);
886 void BuildAggrIvarRecordLayout(const RecordType *RT,
887 unsigned int BytePos, bool ForStrongLayout,
889 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
890 const llvm::StructLayout *Layout,
891 const RecordDecl *RD,
892 const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
893 unsigned int BytePos, bool ForStrongLayout,
896 /// GetIvarLayoutName - Returns a unique constant for the given
897 /// ivar layout bitmap.
898 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
899 const ObjCCommonTypesHelper &ObjCTypes);
901 /// EmitPropertyList - Emit the given property list. The return
902 /// value has type PropertyListPtrTy.
903 llvm::Constant *EmitPropertyList(llvm::Twine Name,
904 const Decl *Container,
905 const ObjCContainerDecl *OCD,
906 const ObjCCommonTypesHelper &ObjCTypes);
908 /// GetProtocolRef - Return a reference to the internal protocol
909 /// description, creating an empty one if it has not been
910 /// defined. The return value has type ProtocolPtrTy.
911 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
913 /// CreateMetadataVar - Create a global variable with internal
914 /// linkage for use by the Objective-C runtime.
916 /// This is a convenience wrapper which not only creates the
917 /// variable, but also sets the section and alignment and adds the
918 /// global to the "llvm.used" list.
920 /// \param Name - The variable name.
921 /// \param Init - The variable initializer; this is also used to
922 /// define the type of the variable.
923 /// \param Section - The section the variable should go into, or 0.
924 /// \param Align - The alignment for the variable, or 0.
925 /// \param AddToUsed - Whether the variable should be added to
927 llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name,
928 llvm::Constant *Init,
933 CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
939 const CallArgList &CallArgs,
940 const ObjCMethodDecl *OMD,
941 const ObjCCommonTypesHelper &ObjCTypes);
944 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
945 CGM(cgm), VMContext(cgm.getLLVMContext()) { }
947 virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *SL);
949 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
950 const ObjCContainerDecl *CD=0);
952 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
954 /// GetOrEmitProtocol - Get the protocol object for the given
955 /// declaration, emitting it if necessary. The return value has type
957 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
959 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
960 /// object for the given declaration, emitting it if needed. These
961 /// forward references will be filled in with empty bodies if no
962 /// definition is seen. The return value has type ProtocolPtrTy.
963 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
966 class CGObjCMac : public CGObjCCommonMac {
968 ObjCTypesHelper ObjCTypes;
969 /// EmitImageInfo - Emit the image info marker used to encode some module
970 /// level information.
971 void EmitImageInfo();
973 /// EmitModuleInfo - Another marker encoding module level
975 void EmitModuleInfo();
977 /// EmitModuleSymols - Emit module symbols, the list of defined
978 /// classes and categories. The result has type SymtabPtrTy.
979 llvm::Constant *EmitModuleSymbols();
981 /// FinishModule - Write out global data structures at the end of
982 /// processing a translation unit.
985 /// EmitClassExtension - Generate the class extension structure used
986 /// to store the weak ivar layout and properties. The return value
987 /// has type ClassExtensionPtrTy.
988 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
990 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
991 /// for the given class.
992 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
993 const ObjCInterfaceDecl *ID);
995 /// EmitSuperClassRef - Emits reference to class's main metadata class.
996 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
998 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1004 const CallArgList &CallArgs);
1006 /// EmitIvarList - Emit the ivar list for the given
1007 /// implementation. If ForClass is true the list of class ivars
1008 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1009 /// interface ivars will be emitted. The return value has type
1011 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1014 /// EmitMetaClass - Emit a forward reference to the class structure
1015 /// for the metaclass of the given interface. The return value has
1016 /// type ClassPtrTy.
1017 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1019 /// EmitMetaClass - Emit a class structure for the metaclass of the
1020 /// given implementation. The return value has type ClassPtrTy.
1021 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1022 llvm::Constant *Protocols,
1023 const ConstantVector &Methods);
1025 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1027 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1029 /// EmitMethodList - Emit the method list for the given
1030 /// implementation. The return value has type MethodListPtrTy.
1031 llvm::Constant *EmitMethodList(llvm::Twine Name,
1032 const char *Section,
1033 const ConstantVector &Methods);
1035 /// EmitMethodDescList - Emit a method description list for a list of
1036 /// method declarations.
1037 /// - TypeName: The name for the type containing the methods.
1038 /// - IsProtocol: True iff these methods are for a protocol.
1039 /// - ClassMethds: True iff these are class methods.
1040 /// - Required: When true, only "required" methods are
1041 /// listed. Similarly, when false only "optional" methods are
1042 /// listed. For classes this should always be true.
1043 /// - begin, end: The method list to output.
1045 /// The return value has type MethodDescriptionListPtrTy.
1046 llvm::Constant *EmitMethodDescList(llvm::Twine Name,
1047 const char *Section,
1048 const ConstantVector &Methods);
1050 /// GetOrEmitProtocol - Get the protocol object for the given
1051 /// declaration, emitting it if necessary. The return value has type
1053 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1055 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1056 /// object for the given declaration, emitting it if needed. These
1057 /// forward references will be filled in with empty bodies if no
1058 /// definition is seen. The return value has type ProtocolPtrTy.
1059 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1061 /// EmitProtocolExtension - Generate the protocol extension
1062 /// structure used to store optional instance and class methods, and
1063 /// protocol properties. The return value has type
1064 /// ProtocolExtensionPtrTy.
1066 EmitProtocolExtension(const ObjCProtocolDecl *PD,
1067 const ConstantVector &OptInstanceMethods,
1068 const ConstantVector &OptClassMethods);
1070 /// EmitProtocolList - Generate the list of referenced
1071 /// protocols. The return value has type ProtocolListPtrTy.
1072 llvm::Constant *EmitProtocolList(llvm::Twine Name,
1073 ObjCProtocolDecl::protocol_iterator begin,
1074 ObjCProtocolDecl::protocol_iterator end);
1076 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1077 /// for the given selector.
1078 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
1081 CGObjCMac(CodeGen::CodeGenModule &cgm);
1083 virtual llvm::Function *ModuleInitFunction();
1085 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1086 QualType ResultType,
1088 llvm::Value *Receiver,
1089 bool IsClassMessage,
1090 const CallArgList &CallArgs,
1091 const ObjCMethodDecl *Method);
1093 virtual CodeGen::RValue
1094 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1095 QualType ResultType,
1097 const ObjCInterfaceDecl *Class,
1098 bool isCategoryImpl,
1099 llvm::Value *Receiver,
1100 bool IsClassMessage,
1101 const CallArgList &CallArgs,
1102 const ObjCMethodDecl *Method);
1104 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1105 const ObjCInterfaceDecl *ID);
1107 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
1109 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1111 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1112 const ObjCMethodDecl *Method);
1114 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1116 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1118 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1119 const ObjCProtocolDecl *PD);
1121 virtual llvm::Constant *GetPropertyGetFunction();
1122 virtual llvm::Constant *GetPropertySetFunction();
1123 virtual llvm::Constant *EnumerationMutationFunction();
1125 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1127 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1128 const ObjCAtThrowStmt &S);
1129 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1130 llvm::Value *AddrWeakObj);
1131 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1132 llvm::Value *src, llvm::Value *dst);
1133 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1134 llvm::Value *src, llvm::Value *dest);
1135 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1136 llvm::Value *src, llvm::Value *dest,
1137 llvm::Value *ivarOffset);
1138 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1139 llvm::Value *src, llvm::Value *dest);
1140 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1141 llvm::Value *dest, llvm::Value *src,
1144 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1146 llvm::Value *BaseValue,
1147 const ObjCIvarDecl *Ivar,
1148 unsigned CVRQualifiers);
1149 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1150 const ObjCInterfaceDecl *Interface,
1151 const ObjCIvarDecl *Ivar);
1154 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1156 ObjCNonFragileABITypesHelper ObjCTypes;
1157 llvm::GlobalVariable* ObjCEmptyCacheVar;
1158 llvm::GlobalVariable* ObjCEmptyVtableVar;
1160 /// SuperClassReferences - uniqued super class references.
1161 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1163 /// MetaClassReferences - uniqued meta class references.
1164 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1166 /// EHTypeReferences - uniqued class ehtype references.
1167 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1169 /// NonLegacyDispatchMethods - List of methods for which we do *not* generate
1170 /// legacy messaging dispatch.
1171 llvm::DenseSet<Selector> NonLegacyDispatchMethods;
1173 /// DefinedMetaClasses - List of defined meta-classes.
1174 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1176 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of
1177 /// NonLegacyDispatchMethods; false otherwise.
1178 bool LegacyDispatchedSelector(Selector Sel);
1180 /// FinishNonFragileABIModule - Write out global data structures at the end of
1181 /// processing a translation unit.
1182 void FinishNonFragileABIModule();
1184 /// AddModuleClassList - Add the given list of class pointers to the
1185 /// module with the provided symbol and section names.
1186 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
1187 const char *SymbolName,
1188 const char *SectionName);
1190 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1191 unsigned InstanceStart,
1192 unsigned InstanceSize,
1193 const ObjCImplementationDecl *ID);
1194 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1195 llvm::Constant *IsAGV,
1196 llvm::Constant *SuperClassGV,
1197 llvm::Constant *ClassRoGV,
1198 bool HiddenVisibility);
1200 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1202 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1204 /// EmitMethodList - Emit the method list for the given
1205 /// implementation. The return value has type MethodListnfABITy.
1206 llvm::Constant *EmitMethodList(llvm::Twine Name,
1207 const char *Section,
1208 const ConstantVector &Methods);
1209 /// EmitIvarList - Emit the ivar list for the given
1210 /// implementation. If ForClass is true the list of class ivars
1211 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1212 /// interface ivars will be emitted. The return value has type
1213 /// IvarListnfABIPtrTy.
1214 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1216 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1217 const ObjCIvarDecl *Ivar,
1218 unsigned long int offset);
1220 /// GetOrEmitProtocol - Get the protocol object for the given
1221 /// declaration, emitting it if necessary. The return value has type
1223 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1225 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1226 /// object for the given declaration, emitting it if needed. These
1227 /// forward references will be filled in with empty bodies if no
1228 /// definition is seen. The return value has type ProtocolPtrTy.
1229 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1231 /// EmitProtocolList - Generate the list of referenced
1232 /// protocols. The return value has type ProtocolListPtrTy.
1233 llvm::Constant *EmitProtocolList(llvm::Twine Name,
1234 ObjCProtocolDecl::protocol_iterator begin,
1235 ObjCProtocolDecl::protocol_iterator end);
1237 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1238 QualType ResultType,
1240 llvm::Value *Receiver,
1243 const CallArgList &CallArgs);
1245 /// GetClassGlobal - Return the global variable for the Objective-C
1246 /// class of the given name.
1247 llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1249 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1250 /// for the given class reference.
1251 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1252 const ObjCInterfaceDecl *ID);
1254 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1255 /// for the given super class reference.
1256 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
1257 const ObjCInterfaceDecl *ID);
1259 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1261 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
1262 const ObjCInterfaceDecl *ID);
1264 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1267 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1268 const ObjCInterfaceDecl *ID,
1269 const ObjCIvarDecl *Ivar);
1271 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1272 /// for the given selector.
1273 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
1275 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1276 /// interface. The return value has type EHTypePtrTy.
1277 llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1278 bool ForDefinition);
1280 const char *getMetaclassSymbolPrefix() const {
1281 return "OBJC_METACLASS_$_";
1284 const char *getClassSymbolPrefix() const {
1285 return "OBJC_CLASS_$_";
1288 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1289 uint32_t &InstanceStart,
1290 uint32_t &InstanceSize);
1292 // Shamelessly stolen from Analysis/CFRefCount.cpp
1293 Selector GetNullarySelector(const char* name) const {
1294 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1295 return CGM.getContext().Selectors.getSelector(0, &II);
1298 Selector GetUnarySelector(const char* name) const {
1299 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1300 return CGM.getContext().Selectors.getSelector(1, &II);
1303 /// ImplementationIsNonLazy - Check whether the given category or
1304 /// class implementation is "non-lazy".
1305 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1308 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1309 // FIXME. All stubs for now!
1310 virtual llvm::Function *ModuleInitFunction();
1312 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1313 QualType ResultType,
1315 llvm::Value *Receiver,
1316 bool IsClassMessage,
1317 const CallArgList &CallArgs,
1318 const ObjCMethodDecl *Method);
1320 virtual CodeGen::RValue
1321 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1322 QualType ResultType,
1324 const ObjCInterfaceDecl *Class,
1325 bool isCategoryImpl,
1326 llvm::Value *Receiver,
1327 bool IsClassMessage,
1328 const CallArgList &CallArgs,
1329 const ObjCMethodDecl *Method);
1331 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1332 const ObjCInterfaceDecl *ID);
1334 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
1335 { return EmitSelector(Builder, Sel); }
1337 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1339 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1340 const ObjCMethodDecl *Method)
1341 { return EmitSelector(Builder, Method->getSelector()); }
1343 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1345 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1346 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1347 const ObjCProtocolDecl *PD);
1349 virtual llvm::Constant *GetPropertyGetFunction() {
1350 return ObjCTypes.getGetPropertyFn();
1352 virtual llvm::Constant *GetPropertySetFunction() {
1353 return ObjCTypes.getSetPropertyFn();
1355 virtual llvm::Constant *EnumerationMutationFunction() {
1356 return ObjCTypes.getEnumerationMutationFn();
1359 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1361 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1362 const ObjCAtThrowStmt &S);
1363 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1364 llvm::Value *AddrWeakObj);
1365 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1366 llvm::Value *src, llvm::Value *dst);
1367 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1368 llvm::Value *src, llvm::Value *dest);
1369 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1370 llvm::Value *src, llvm::Value *dest,
1371 llvm::Value *ivarOffset);
1372 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1373 llvm::Value *src, llvm::Value *dest);
1374 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1375 llvm::Value *dest, llvm::Value *src,
1377 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1379 llvm::Value *BaseValue,
1380 const ObjCIvarDecl *Ivar,
1381 unsigned CVRQualifiers);
1382 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1383 const ObjCInterfaceDecl *Interface,
1384 const ObjCIvarDecl *Ivar);
1387 } // end anonymous namespace
1389 /* *** Helper Functions *** */
1391 /// getConstantGEP() - Help routine to construct simple GEPs.
1392 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1396 llvm::Value *Idxs[] = {
1397 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1398 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1400 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
1403 /// hasObjCExceptionAttribute - Return true if this class or any super
1404 /// class has the __objc_exception__ attribute.
1405 static bool hasObjCExceptionAttribute(ASTContext &Context,
1406 const ObjCInterfaceDecl *OID) {
1407 if (OID->hasAttr<ObjCExceptionAttr>())
1409 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1410 return hasObjCExceptionAttribute(Context, Super);
1414 /* *** CGObjCMac Public Interface *** */
1416 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1422 /// GetClass - Return a reference to the class for the given interface
1424 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
1425 const ObjCInterfaceDecl *ID) {
1426 return EmitClassRef(Builder, ID);
1429 /// GetSelector - Return the pointer to the unique'd string for this selector.
1430 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) {
1431 return EmitSelector(Builder, Sel);
1433 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
1435 return EmitSelector(Builder, Method->getSelector());
1438 /// Generate a constant CFString object.
1440 struct __builtin_CFString {
1441 const int *isa; // point to __CFConstantStringClassReference
1448 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1449 const ObjCStringLiteral *SL) {
1450 return CGM.GetAddrOfConstantCFString(SL->getString());
1453 /// Generates a message send where the super is the receiver. This is
1454 /// a message send to self with special delivery semantics indicating
1455 /// which class's method should be called.
1457 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1458 QualType ResultType,
1460 const ObjCInterfaceDecl *Class,
1461 bool isCategoryImpl,
1462 llvm::Value *Receiver,
1463 bool IsClassMessage,
1464 const CodeGen::CallArgList &CallArgs,
1465 const ObjCMethodDecl *Method) {
1466 // Create and init a super structure; this is a (receiver, class)
1467 // pair we will pass to objc_msgSendSuper.
1468 llvm::Value *ObjCSuper =
1469 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
1470 llvm::Value *ReceiverAsObject =
1471 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1472 CGF.Builder.CreateStore(ReceiverAsObject,
1473 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1475 // If this is a class message the metaclass is passed as the target.
1476 llvm::Value *Target;
1477 if (IsClassMessage) {
1478 if (isCategoryImpl) {
1479 // Message sent to 'super' in a class method defined in a category
1480 // implementation requires an odd treatment.
1481 // If we are in a class method, we must retrieve the
1482 // _metaclass_ for the current class, pointed at by
1483 // the class's "isa" pointer. The following assumes that
1484 // isa" is the first ivar in a class (which it must be).
1485 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1486 Target = CGF.Builder.CreateStructGEP(Target, 0);
1487 Target = CGF.Builder.CreateLoad(Target);
1489 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1490 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1491 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1495 else if (isCategoryImpl)
1496 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1498 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1499 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1500 Target = CGF.Builder.CreateLoad(ClassPtr);
1502 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1504 const llvm::Type *ClassTy =
1505 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1506 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1507 CGF.Builder.CreateStore(Target,
1508 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1509 return EmitLegacyMessageSend(CGF, ResultType,
1510 EmitSelector(CGF.Builder, Sel),
1511 ObjCSuper, ObjCTypes.SuperPtrCTy,
1512 true, CallArgs, Method, ObjCTypes);
1515 /// Generate code for a message send expression.
1516 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1517 QualType ResultType,
1519 llvm::Value *Receiver,
1520 bool IsClassMessage,
1521 const CallArgList &CallArgs,
1522 const ObjCMethodDecl *Method) {
1523 return EmitLegacyMessageSend(CGF, ResultType,
1524 EmitSelector(CGF.Builder, Sel),
1525 Receiver, CGF.getContext().getObjCIdType(),
1526 false, CallArgs, Method, ObjCTypes);
1530 CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
1531 QualType ResultType,
1536 const CallArgList &CallArgs,
1537 const ObjCMethodDecl *Method,
1538 const ObjCCommonTypesHelper &ObjCTypes) {
1539 CallArgList ActualArgs;
1541 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
1542 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
1543 ActualArgs.push_back(std::make_pair(RValue::get(Sel),
1544 CGF.getContext().getObjCSelType()));
1545 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
1547 CodeGenTypes &Types = CGM.getTypes();
1548 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
1549 const llvm::FunctionType *FTy =
1550 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
1552 llvm::Constant *Fn = NULL;
1553 if (CGM.ReturnTypeUsesSret(FnInfo)) {
1554 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1555 : ObjCTypes.getSendStretFn(IsSuper);
1556 } else if (ResultType->isFloatingType()) {
1558 if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
1559 BuiltinType::Kind k = BT->getKind();
1560 Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper)
1561 : ObjCTypes.getSendFn2(IsSuper);
1563 Fn = ObjCTypes.getSendFn2(IsSuper);
1566 // FIXME. This currently matches gcc's API for x86-32. May need to change
1567 // for others if we have their API.
1568 Fn = ObjCTypes.getSendFpretFn(IsSuper);
1570 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1571 : ObjCTypes.getSendFn(IsSuper);
1573 assert(Fn && "EmitLegacyMessageSend - unknown API");
1574 Fn = llvm::ConstantExpr::getBitCast(Fn,
1575 llvm::PointerType::getUnqual(FTy));
1576 return CGF.EmitCall(FnInfo, Fn, ActualArgs);
1579 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1580 const ObjCProtocolDecl *PD) {
1581 // FIXME: I don't understand why gcc generates this, or where it is
1582 // resolved. Investigate. Its also wasteful to look this up over and over.
1583 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1585 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
1586 ObjCTypes.ExternalProtocolPtrTy);
1589 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1590 // FIXME: We shouldn't need this, the protocol decl should contain enough
1591 // information to tell us whether this was a declaration or a definition.
1592 DefinedProtocols.insert(PD->getIdentifier());
1594 // If we have generated a forward reference to this protocol, emit
1595 // it now. Otherwise do nothing, the protocol objects are lazily
1597 if (Protocols.count(PD->getIdentifier()))
1598 GetOrEmitProtocol(PD);
1601 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
1602 if (DefinedProtocols.count(PD->getIdentifier()))
1603 return GetOrEmitProtocol(PD);
1604 return GetOrEmitProtocolRef(PD);
1608 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
1609 struct _objc_protocol {
1610 struct _objc_protocol_extension *isa;
1611 char *protocol_name;
1612 struct _objc_protocol_list *protocol_list;
1613 struct _objc__method_prototype_list *instance_methods;
1614 struct _objc__method_prototype_list *class_methods
1617 See EmitProtocolExtension().
1619 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
1620 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1622 // Early exit if a defining object has already been generated.
1623 if (Entry && Entry->hasInitializer())
1626 // FIXME: I don't understand why gcc generates this, or where it is
1627 // resolved. Investigate. Its also wasteful to look this up over and over.
1628 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1630 // Construct method lists.
1631 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1632 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
1633 for (ObjCProtocolDecl::instmeth_iterator
1634 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1635 ObjCMethodDecl *MD = *i;
1636 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1637 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1638 OptInstanceMethods.push_back(C);
1640 InstanceMethods.push_back(C);
1644 for (ObjCProtocolDecl::classmeth_iterator
1645 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1646 ObjCMethodDecl *MD = *i;
1647 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1648 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1649 OptClassMethods.push_back(C);
1651 ClassMethods.push_back(C);
1655 std::vector<llvm::Constant*> Values(5);
1656 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
1657 Values[1] = GetClassName(PD->getIdentifier());
1659 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1660 PD->protocol_begin(),
1661 PD->protocol_end());
1663 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1664 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1667 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1668 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1670 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
1674 // Already created, fix the linkage and update the initializer.
1675 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
1676 Entry->setInitializer(Init);
1679 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1680 llvm::GlobalValue::InternalLinkage,
1682 "\01L_OBJC_PROTOCOL_" + PD->getName());
1683 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1684 Entry->setAlignment(4);
1685 // FIXME: Is this necessary? Why only for protocol?
1686 Entry->setAlignment(4);
1688 CGM.AddUsedGlobal(Entry);
1693 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
1694 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1697 // We use the initializer as a marker of whether this is a forward
1698 // reference or not. At module finalization we add the empty
1699 // contents for protocols which were referenced but never defined.
1701 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1702 llvm::GlobalValue::ExternalLinkage,
1704 "\01L_OBJC_PROTOCOL_" + PD->getName());
1705 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1706 Entry->setAlignment(4);
1707 // FIXME: Is this necessary? Why only for protocol?
1708 Entry->setAlignment(4);
1715 struct _objc_protocol_extension {
1717 struct objc_method_description_list *optional_instance_methods;
1718 struct objc_method_description_list *optional_class_methods;
1719 struct objc_property_list *instance_properties;
1723 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
1724 const ConstantVector &OptInstanceMethods,
1725 const ConstantVector &OptClassMethods) {
1727 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
1728 std::vector<llvm::Constant*> Values(4);
1729 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
1731 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
1733 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1734 OptInstanceMethods);
1736 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
1737 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1739 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),
1742 // Return null if no extension bits are used.
1743 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
1744 Values[3]->isNullValue())
1745 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
1747 llvm::Constant *Init =
1748 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
1750 // No special section, but goes in llvm.used
1751 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
1757 struct objc_protocol_list {
1758 struct objc_protocol_list *next;
1764 CGObjCMac::EmitProtocolList(llvm::Twine Name,
1765 ObjCProtocolDecl::protocol_iterator begin,
1766 ObjCProtocolDecl::protocol_iterator end) {
1767 std::vector<llvm::Constant*> ProtocolRefs;
1769 for (; begin != end; ++begin)
1770 ProtocolRefs.push_back(GetProtocolRef(*begin));
1772 // Just return null for empty protocol lists
1773 if (ProtocolRefs.empty())
1774 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1776 // This list is null terminated.
1777 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
1779 std::vector<llvm::Constant*> Values(3);
1780 // This field is only used by the runtime.
1781 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1782 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
1783 ProtocolRefs.size() - 1);
1785 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
1786 ProtocolRefs.size()),
1789 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
1790 llvm::GlobalVariable *GV =
1791 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1793 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
1797 struct _objc_property {
1798 const char * const name;
1799 const char * const attributes;
1802 struct _objc_property_list {
1803 uint32_t entsize; // sizeof (struct _objc_property)
1804 uint32_t prop_count;
1805 struct _objc_property[prop_count];
1808 llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name,
1809 const Decl *Container,
1810 const ObjCContainerDecl *OCD,
1811 const ObjCCommonTypesHelper &ObjCTypes) {
1812 std::vector<llvm::Constant*> Properties, Prop(2);
1813 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
1814 E = OCD->prop_end(); I != E; ++I) {
1815 const ObjCPropertyDecl *PD = *I;
1816 Prop[0] = GetPropertyName(PD->getIdentifier());
1817 Prop[1] = GetPropertyTypeString(PD, Container);
1818 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
1822 // Return null for empty list.
1823 if (Properties.empty())
1824 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
1826 unsigned PropertySize =
1827 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
1828 std::vector<llvm::Constant*> Values(3);
1829 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
1830 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
1831 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
1833 Values[2] = llvm::ConstantArray::get(AT, Properties);
1834 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
1836 llvm::GlobalVariable *GV =
1837 CreateMetadataVar(Name, Init,
1838 (ObjCABI == 2) ? "__DATA, __objc_const" :
1839 "__OBJC,__property,regular,no_dead_strip",
1840 (ObjCABI == 2) ? 8 : 4,
1842 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
1846 struct objc_method_description_list {
1848 struct objc_method_description list[];
1852 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
1853 std::vector<llvm::Constant*> Desc(2);
1855 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1856 ObjCTypes.SelectorPtrTy);
1857 Desc[1] = GetMethodVarType(MD);
1858 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
1862 llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name,
1863 const char *Section,
1864 const ConstantVector &Methods) {
1865 // Return null for empty list.
1866 if (Methods.empty())
1867 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
1869 std::vector<llvm::Constant*> Values(2);
1870 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1871 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
1873 Values[1] = llvm::ConstantArray::get(AT, Methods);
1874 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
1876 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
1877 return llvm::ConstantExpr::getBitCast(GV,
1878 ObjCTypes.MethodDescriptionListPtrTy);
1882 struct _objc_category {
1883 char *category_name;
1885 struct _objc_method_list *instance_methods;
1886 struct _objc_method_list *class_methods;
1887 struct _objc_protocol_list *protocols;
1888 uint32_t size; // <rdar://4585769>
1889 struct _objc_property_list *instance_properties;
1892 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
1893 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
1895 // FIXME: This is poor design, the OCD should have a pointer to the category
1896 // decl. Additionally, note that Category can be null for the @implementation
1897 // w/o an @interface case. Sema should just create one for us as it does for
1898 // @implementation so everyone else can live life under a clear blue sky.
1899 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
1900 const ObjCCategoryDecl *Category =
1901 Interface->FindCategoryDeclaration(OCD->getIdentifier());
1903 llvm::SmallString<256> ExtName;
1904 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
1907 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1908 for (ObjCCategoryImplDecl::instmeth_iterator
1909 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
1910 // Instance methods should always be defined.
1911 InstanceMethods.push_back(GetMethodConstant(*i));
1913 for (ObjCCategoryImplDecl::classmeth_iterator
1914 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
1915 // Class methods should always be defined.
1916 ClassMethods.push_back(GetMethodConstant(*i));
1919 std::vector<llvm::Constant*> Values(7);
1920 Values[0] = GetClassName(OCD->getIdentifier());
1921 Values[1] = GetClassName(Interface->getIdentifier());
1922 LazySymbols.insert(Interface->getIdentifier());
1924 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
1925 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1928 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
1929 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1933 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
1934 Category->protocol_begin(),
1935 Category->protocol_end());
1937 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1939 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
1941 // If there is no category @interface then there can be no properties.
1943 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
1944 OCD, Category, ObjCTypes);
1946 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
1949 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
1952 llvm::GlobalVariable *GV =
1953 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
1954 "__OBJC,__category,regular,no_dead_strip",
1956 DefinedCategories.push_back(GV);
1959 // FIXME: Get from somewhere?
1961 eClassFlags_Factory = 0x00001,
1962 eClassFlags_Meta = 0x00002,
1964 eClassFlags_HasCXXStructors = 0x02000,
1965 eClassFlags_Hidden = 0x20000,
1966 eClassFlags_ABI2_Hidden = 0x00010,
1967 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
1971 struct _objc_class {
1978 struct _objc_ivar_list *ivars;
1979 struct _objc_method_list *methods;
1980 struct _objc_cache *cache;
1981 struct _objc_protocol_list *protocols;
1982 // Objective-C 1.0 extensions (<rdr://4585769>)
1983 const char *ivar_layout;
1984 struct _objc_class_ext *ext;
1987 See EmitClassExtension();
1989 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
1990 DefinedSymbols.insert(ID->getIdentifier());
1992 std::string ClassName = ID->getNameAsString();
1994 ObjCInterfaceDecl *Interface =
1995 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
1996 llvm::Constant *Protocols =
1997 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
1998 Interface->protocol_begin(),
1999 Interface->protocol_end());
2000 unsigned Flags = eClassFlags_Factory;
2002 CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
2004 // FIXME: Set CXX-structors flag.
2005 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
2006 Flags |= eClassFlags_Hidden;
2008 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2009 for (ObjCImplementationDecl::instmeth_iterator
2010 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2011 // Instance methods should always be defined.
2012 InstanceMethods.push_back(GetMethodConstant(*i));
2014 for (ObjCImplementationDecl::classmeth_iterator
2015 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2016 // Class methods should always be defined.
2017 ClassMethods.push_back(GetMethodConstant(*i));
2020 for (ObjCImplementationDecl::propimpl_iterator
2021 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2022 ObjCPropertyImplDecl *PID = *i;
2024 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2025 ObjCPropertyDecl *PD = PID->getPropertyDecl();
2027 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2028 if (llvm::Constant *C = GetMethodConstant(MD))
2029 InstanceMethods.push_back(C);
2030 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2031 if (llvm::Constant *C = GetMethodConstant(MD))
2032 InstanceMethods.push_back(C);
2036 std::vector<llvm::Constant*> Values(12);
2037 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
2038 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2039 // Record a reference to the super class.
2040 LazySymbols.insert(Super->getIdentifier());
2043 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2044 ObjCTypes.ClassPtrTy);
2046 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2048 Values[ 2] = GetClassName(ID->getIdentifier());
2049 // Version is always 0.
2050 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2051 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2052 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2053 Values[ 6] = EmitIvarList(ID, false);
2055 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2056 "__OBJC,__inst_meth,regular,no_dead_strip",
2058 // cache is always NULL.
2059 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2060 Values[ 9] = Protocols;
2061 Values[10] = BuildIvarLayout(ID, true);
2062 Values[11] = EmitClassExtension(ID);
2063 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2065 std::string Name("\01L_OBJC_CLASS_");
2067 const char *Section = "__OBJC,__class,regular,no_dead_strip";
2068 // Check for a forward reference.
2069 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2071 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2072 "Forward metaclass reference has incorrect type.");
2073 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2074 GV->setInitializer(Init);
2075 GV->setSection(Section);
2076 GV->setAlignment(4);
2077 CGM.AddUsedGlobal(GV);
2080 GV = CreateMetadataVar(Name, Init, Section, 4, true);
2081 DefinedClasses.push_back(GV);
2084 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
2085 llvm::Constant *Protocols,
2086 const ConstantVector &Methods) {
2087 unsigned Flags = eClassFlags_Meta;
2088 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
2090 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
2091 Flags |= eClassFlags_Hidden;
2093 std::vector<llvm::Constant*> Values(12);
2094 // The isa for the metaclass is the root of the hierarchy.
2095 const ObjCInterfaceDecl *Root = ID->getClassInterface();
2096 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
2099 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
2100 ObjCTypes.ClassPtrTy);
2101 // The super class for the metaclass is emitted as the name of the
2102 // super class. The runtime fixes this up to point to the
2103 // *metaclass* for the super class.
2104 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
2106 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2107 ObjCTypes.ClassPtrTy);
2109 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2111 Values[ 2] = GetClassName(ID->getIdentifier());
2112 // Version is always 0.
2113 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2114 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2115 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2116 Values[ 6] = EmitIvarList(ID, true);
2118 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
2119 "__OBJC,__cls_meth,regular,no_dead_strip",
2121 // cache is always NULL.
2122 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2123 Values[ 9] = Protocols;
2124 // ivar_layout for metaclass is always NULL.
2125 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2126 // The class extension is always unused for metaclasses.
2127 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2128 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2131 std::string Name("\01L_OBJC_METACLASS_");
2132 Name += ID->getNameAsCString();
2134 // Check for a forward reference.
2135 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2137 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2138 "Forward metaclass reference has incorrect type.");
2139 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2140 GV->setInitializer(Init);
2142 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2143 llvm::GlobalValue::InternalLinkage,
2146 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
2147 GV->setAlignment(4);
2148 CGM.AddUsedGlobal(GV);
2153 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2154 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2156 // FIXME: Should we look these up somewhere other than the module. Its a bit
2157 // silly since we only generate these while processing an implementation, so
2158 // exactly one pointer would work if know when we entered/exitted an
2159 // implementation block.
2161 // Check for an existing forward reference.
2162 // Previously, metaclass with internal linkage may have been defined.
2163 // pass 'true' as 2nd argument so it is returned.
2164 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2166 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2167 "Forward metaclass reference has incorrect type.");
2170 // Generate as an external reference to keep a consistent
2171 // module. This will be patched up when we emit the metaclass.
2172 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2173 llvm::GlobalValue::ExternalLinkage,
2179 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2180 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2182 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2184 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2185 "Forward class metadata reference has incorrect type.");
2188 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2189 llvm::GlobalValue::ExternalLinkage,
2196 struct objc_class_ext {
2198 const char *weak_ivar_layout;
2199 struct _objc_property_list *properties;
2203 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
2205 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
2207 std::vector<llvm::Constant*> Values(3);
2208 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2209 Values[1] = BuildIvarLayout(ID, false);
2210 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
2211 ID, ID->getClassInterface(), ObjCTypes);
2213 // Return null if no extension bits are used.
2214 if (Values[1]->isNullValue() && Values[2]->isNullValue())
2215 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2217 llvm::Constant *Init =
2218 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
2219 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
2220 Init, "__OBJC,__class_ext,regular,no_dead_strip",
2231 struct objc_ivar_list {
2233 struct objc_ivar list[count];
2236 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
2238 std::vector<llvm::Constant*> Ivars, Ivar(3);
2240 // When emitting the root class GCC emits ivar entries for the
2241 // actual class structure. It is not clear if we need to follow this
2242 // behavior; for now lets try and get away with not doing it. If so,
2243 // the cleanest solution would be to make up an ObjCInterfaceDecl
2246 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2248 ObjCInterfaceDecl *OID =
2249 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2251 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
2252 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
2254 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
2255 ObjCIvarDecl *IVD = OIvars[i];
2256 // Ignore unnamed bit-fields.
2257 if (!IVD->getDeclName())
2259 Ivar[0] = GetMethodVarName(IVD->getIdentifier());
2260 Ivar[1] = GetMethodVarType(IVD);
2261 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy,
2262 ComputeIvarBaseOffset(CGM, OID, IVD));
2263 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
2266 // Return null for empty list.
2268 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2270 std::vector<llvm::Constant*> Values(2);
2271 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
2272 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
2274 Values[1] = llvm::ConstantArray::get(AT, Ivars);
2275 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2277 llvm::GlobalVariable *GV;
2279 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
2280 Init, "__OBJC,__class_vars,regular,no_dead_strip",
2283 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
2284 Init, "__OBJC,__instance_vars,regular,no_dead_strip",
2286 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
2290 struct objc_method {
2296 struct objc_method_list {
2297 struct objc_method_list *obsolete;
2299 struct objc_method methods_list[count];
2303 /// GetMethodConstant - Return a struct objc_method constant for the
2304 /// given method if it has been defined. The result is null if the
2305 /// method has not been defined. The return value has type MethodPtrTy.
2306 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
2307 // FIXME: Use DenseMap::lookup
2308 llvm::Function *Fn = MethodDefinitions[MD];
2312 std::vector<llvm::Constant*> Method(3);
2314 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2315 ObjCTypes.SelectorPtrTy);
2316 Method[1] = GetMethodVarType(MD);
2317 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
2318 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2321 llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name,
2322 const char *Section,
2323 const ConstantVector &Methods) {
2324 // Return null for empty list.
2325 if (Methods.empty())
2326 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
2328 std::vector<llvm::Constant*> Values(3);
2329 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2330 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2331 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
2333 Values[2] = llvm::ConstantArray::get(AT, Methods);
2334 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2336 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2337 return llvm::ConstantExpr::getBitCast(GV,
2338 ObjCTypes.MethodListPtrTy);
2341 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
2342 const ObjCContainerDecl *CD) {
2343 llvm::SmallString<256> Name;
2344 GetNameForMethod(OMD, CD, Name);
2346 CodeGenTypes &Types = CGM.getTypes();
2347 const llvm::FunctionType *MethodTy =
2348 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
2349 llvm::Function *Method =
2350 llvm::Function::Create(MethodTy,
2351 llvm::GlobalValue::InternalLinkage,
2354 MethodDefinitions.insert(std::make_pair(OMD, Method));
2359 llvm::GlobalVariable *
2360 CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name,
2361 llvm::Constant *Init,
2362 const char *Section,
2365 const llvm::Type *Ty = Init->getType();
2366 llvm::GlobalVariable *GV =
2367 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2368 llvm::GlobalValue::InternalLinkage, Init, Name);
2370 GV->setSection(Section);
2372 GV->setAlignment(Align);
2374 CGM.AddUsedGlobal(GV);
2378 llvm::Function *CGObjCMac::ModuleInitFunction() {
2379 // Abuse this interface function as a place to finalize.
2384 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
2385 return ObjCTypes.getGetPropertyFn();
2388 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
2389 return ObjCTypes.getSetPropertyFn();
2392 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
2393 return ObjCTypes.getEnumerationMutationFn();
2398 Objective-C setjmp-longjmp (sjlj) Exception Handling
2401 The basic framework for a @try-catch-finally is as follows:
2403 objc_exception_data d;
2405 bool _call_try_exit = true;
2407 objc_exception_try_enter(&d);
2408 if (!setjmp(d.jmp_buf)) {
2412 id _caught = objc_exception_extract(&d);
2414 // enter new try scope for handlers
2415 if (!setjmp(d.jmp_buf)) {
2416 ... match exception and execute catch blocks ...
2418 // fell off end, rethrow.
2420 ... jump-through-finally to finally_rethrow ...
2422 // exception in catch block
2423 _rethrow = objc_exception_extract(&d);
2424 _call_try_exit = false;
2425 ... jump-through-finally to finally_rethrow ...
2428 ... jump-through-finally to finally_end ...
2432 objc_exception_try_exit(&d);
2434 ... finally block ....
2435 ... dispatch to finally destination ...
2438 objc_exception_throw(_rethrow);
2443 This framework differs slightly from the one gcc uses, in that gcc
2444 uses _rethrow to determine if objc_exception_try_exit should be called
2445 and if the object should be rethrown. This breaks in the face of
2446 throwing nil and introduces unnecessary branches.
2448 We specialize this framework for a few particular circumstances:
2450 - If there are no catch blocks, then we avoid emitting the second
2451 exception handling context.
2453 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
2454 e)) we avoid emitting the code to rethrow an uncaught exception.
2456 - FIXME: If there is no @finally block we can do a few more
2459 Rethrows and Jumps-Through-Finally
2462 Support for implicit rethrows and jumping through the finally block is
2463 handled by storing the current exception-handling context in
2466 In order to implement proper @finally semantics, we support one basic
2467 mechanism for jumping through the finally block to an arbitrary
2468 destination. Constructs which generate exits from a @try or @catch
2469 block use this mechanism to implement the proper semantics by chaining
2470 jumps, as necessary.
2472 This mechanism works like the one used for indirect goto: we
2473 arbitrarily assign an ID to each destination and store the ID for the
2474 destination in a variable prior to entering the finally block. At the
2475 end of the finally block we simply create a switch to the proper
2478 Code gen for @synchronized(expr) stmt;
2479 Effectively generating code for:
2480 objc_sync_enter(expr);
2481 @try stmt @finally { objc_sync_exit(expr); }
2484 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
2486 bool isTry = isa<ObjCAtTryStmt>(S);
2487 // Create various blocks we refer to for handling @finally.
2488 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
2489 llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit");
2490 llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
2491 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
2492 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
2494 // For @synchronized, call objc_sync_enter(sync.expr). The
2495 // evaluation of the expression must occur before we enter the
2496 // @synchronized. We can safely avoid a temp here because jumps into
2497 // @synchronized are illegal & this will dominate uses.
2498 llvm::Value *SyncArg = 0;
2501 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
2502 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
2503 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
2506 // Push an EH context entry, used for handling rethrows and jumps
2508 CGF.PushCleanupBlock(FinallyBlock);
2510 CGF.ObjCEHValueStack.push_back(0);
2512 // Allocate memory for the exception data and rethrow pointer.
2513 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
2514 "exceptiondata.ptr");
2515 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy,
2517 llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca(
2518 llvm::Type::getInt1Ty(VMContext),
2520 CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext),
2523 // Enter a new try block and call setjmp.
2524 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
2525 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
2527 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
2528 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
2529 JmpBufPtr, "result");
2531 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
2532 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
2533 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
2534 TryHandler, TryBlock);
2536 // Emit the @try block.
2537 CGF.EmitBlock(TryBlock);
2538 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
2539 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
2540 CGF.EmitBranchThroughCleanup(FinallyEnd);
2542 // Emit the "exception in @try" block.
2543 CGF.EmitBlock(TryHandler);
2545 // Retrieve the exception object. We may emit multiple blocks but
2546 // nothing can cross this so the value is already in SSA form.
2547 llvm::Value *Caught =
2548 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
2549 ExceptionData, "caught");
2550 CGF.ObjCEHValueStack.back() = Caught;
2552 CGF.Builder.CreateStore(Caught, RethrowPtr);
2553 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
2555 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2556 } else if (const ObjCAtCatchStmt* CatchStmt =
2557 cast<ObjCAtTryStmt>(S).getCatchStmts()) {
2558 // Enter a new exception try block (in case a @catch block throws
2560 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
2562 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
2563 JmpBufPtr, "result");
2564 llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw");
2566 llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch");
2567 llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler");
2568 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
2570 CGF.EmitBlock(CatchBlock);
2572 // Handle catch list. As a special case we check if everything is
2573 // matched and avoid generating code for falling off the end if
2575 bool AllMatched = false;
2576 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
2577 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch");
2579 const ParmVarDecl *CatchParam = CatchStmt->getCatchParamDecl();
2580 const ObjCObjectPointerType *OPT = 0;
2582 // catch(...) always matches.
2586 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
2588 // catch(id e) always matches.
2589 // FIXME: For the time being we also match id<X>; this should
2590 // be rejected by Sema instead.
2591 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
2597 CGF.EmitLocalBlockVarDecl(*CatchParam);
2598 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
2599 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
2602 CGF.EmitStmt(CatchStmt->getCatchBody());
2603 CGF.EmitBranchThroughCleanup(FinallyEnd);
2607 assert(OPT && "Unexpected non-object pointer type in @catch");
2608 QualType T = OPT->getPointeeType();
2609 const ObjCInterfaceType *ObjCType = T->getAs<ObjCInterfaceType>();
2610 assert(ObjCType && "Catch parameter must have Objective-C type!");
2612 // Check if the @catch block matches the exception object.
2613 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
2615 llvm::Value *Match =
2616 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
2617 Class, Caught, "match");
2619 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched");
2621 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
2622 MatchedBlock, NextCatchBlock);
2624 // Emit the @catch block.
2625 CGF.EmitBlock(MatchedBlock);
2626 CGF.EmitLocalBlockVarDecl(*CatchParam);
2627 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
2630 CGF.Builder.CreateBitCast(Caught,
2631 CGF.ConvertType(CatchParam->getType()),
2633 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
2635 CGF.EmitStmt(CatchStmt->getCatchBody());
2636 CGF.EmitBranchThroughCleanup(FinallyEnd);
2638 CGF.EmitBlock(NextCatchBlock);
2642 // None of the handlers caught the exception, so store it to be
2643 // rethrown at the end of the @finally block.
2644 CGF.Builder.CreateStore(Caught, RethrowPtr);
2645 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2648 // Emit the exception handler for the @catch blocks.
2649 CGF.EmitBlock(CatchHandler);
2650 CGF.Builder.CreateStore(
2651 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
2654 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
2656 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2658 CGF.Builder.CreateStore(Caught, RethrowPtr);
2659 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
2661 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2664 // Pop the exception-handling stack entry. It is important to do
2665 // this now, because the code in the @finally block is not in this
2667 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
2669 CGF.ObjCEHValueStack.pop_back();
2671 // Emit the @finally block.
2672 CGF.EmitBlock(FinallyBlock);
2673 llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp");
2675 CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit);
2677 CGF.EmitBlock(FinallyExit);
2678 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData);
2680 CGF.EmitBlock(FinallyNoExit);
2682 if (const ObjCAtFinallyStmt* FinallyStmt =
2683 cast<ObjCAtTryStmt>(S).getFinallyStmt())
2684 CGF.EmitStmt(FinallyStmt->getFinallyBody());
2686 // Emit objc_sync_exit(expr); as finally's sole statement for
2688 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg);
2691 // Emit the switch block
2692 if (Info.SwitchBlock)
2693 CGF.EmitBlock(Info.SwitchBlock);
2695 CGF.EmitBlock(Info.EndBlock);
2697 CGF.EmitBlock(FinallyRethrow);
2698 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(),
2699 CGF.Builder.CreateLoad(RethrowPtr));
2700 CGF.Builder.CreateUnreachable();
2702 CGF.EmitBlock(FinallyEnd);
2705 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
2706 const ObjCAtThrowStmt &S) {
2707 llvm::Value *ExceptionAsObject;
2709 if (const Expr *ThrowExpr = S.getThrowExpr()) {
2710 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
2712 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
2714 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
2715 "Unexpected rethrow outside @catch block.");
2716 ExceptionAsObject = CGF.ObjCEHValueStack.back();
2719 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
2720 CGF.Builder.CreateUnreachable();
2722 // Clear the insertion point to indicate we are in unreachable code.
2723 CGF.Builder.ClearInsertionPoint();
2726 /// EmitObjCWeakRead - Code gen for loading value of a __weak
2727 /// object: objc_read_weak (id *src)
2729 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
2730 llvm::Value *AddrWeakObj) {
2731 const llvm::Type* DestTy =
2732 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
2733 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
2734 ObjCTypes.PtrObjectPtrTy);
2735 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
2736 AddrWeakObj, "weakread");
2737 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
2741 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
2742 /// objc_assign_weak (id src, id *dst)
2744 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
2745 llvm::Value *src, llvm::Value *dst) {
2746 const llvm::Type * SrcTy = src->getType();
2747 if (!isa<llvm::PointerType>(SrcTy)) {
2748 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
2749 assert(Size <= 8 && "does not support size > 8");
2750 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
2751 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
2752 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
2754 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
2755 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
2756 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
2757 src, dst, "weakassign");
2761 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
2762 /// objc_assign_global (id src, id *dst)
2764 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
2765 llvm::Value *src, llvm::Value *dst) {
2766 const llvm::Type * SrcTy = src->getType();
2767 if (!isa<llvm::PointerType>(SrcTy)) {
2768 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
2769 assert(Size <= 8 && "does not support size > 8");
2770 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
2771 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
2772 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
2774 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
2775 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
2776 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
2777 src, dst, "globalassign");
2781 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
2782 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
2784 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
2785 llvm::Value *src, llvm::Value *dst,
2786 llvm::Value *ivarOffset) {
2787 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
2788 const llvm::Type * SrcTy = src->getType();
2789 if (!isa<llvm::PointerType>(SrcTy)) {
2790 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
2791 assert(Size <= 8 && "does not support size > 8");
2792 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
2793 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
2794 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
2796 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
2797 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
2798 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
2799 src, dst, ivarOffset);
2803 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
2804 /// objc_assign_strongCast (id src, id *dst)
2806 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
2807 llvm::Value *src, llvm::Value *dst) {
2808 const llvm::Type * SrcTy = src->getType();
2809 if (!isa<llvm::PointerType>(SrcTy)) {
2810 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
2811 assert(Size <= 8 && "does not support size > 8");
2812 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
2813 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
2814 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
2816 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
2817 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
2818 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
2819 src, dst, "weakassign");
2823 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
2824 llvm::Value *DestPtr,
2825 llvm::Value *SrcPtr,
2827 // Get size info for this aggregate.
2828 std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
2829 unsigned long size = TypeInfo.first/8;
2830 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
2831 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
2832 llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
2833 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
2834 DestPtr, SrcPtr, N);
2838 /// EmitObjCValueForIvar - Code Gen for ivar reference.
2840 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
2842 llvm::Value *BaseValue,
2843 const ObjCIvarDecl *Ivar,
2844 unsigned CVRQualifiers) {
2845 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
2846 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2847 EmitIvarOffset(CGF, ID, Ivar));
2850 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
2851 const ObjCInterfaceDecl *Interface,
2852 const ObjCIvarDecl *Ivar) {
2853 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
2854 return llvm::ConstantInt::get(
2855 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
2859 /* *** Private Interface *** */
2861 /// EmitImageInfo - Emit the image info marker used to encode some module
2862 /// level information.
2864 /// See: <rdr://4810609&4810587&4810587>
2865 /// struct IMAGE_INFO {
2866 /// unsigned version;
2869 enum ImageInfoFlags {
2870 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what
2872 eImageInfo_GarbageCollected = (1 << 1),
2873 eImageInfo_GCOnly = (1 << 2),
2874 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set.
2876 // A flag indicating that the module has no instances of an
2877 // @synthesize of a superclass variable. <rdar://problem/6803242>
2878 eImageInfo_CorrectedSynthesize = (1 << 4)
2881 void CGObjCMac::EmitImageInfo() {
2882 unsigned version = 0; // Version is unused?
2885 // FIXME: Fix and continue?
2886 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
2887 flags |= eImageInfo_GarbageCollected;
2888 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
2889 flags |= eImageInfo_GCOnly;
2891 // We never allow @synthesize of a superclass property.
2892 flags |= eImageInfo_CorrectedSynthesize;
2894 // Emitted as int[2];
2895 llvm::Constant *values[2] = {
2896 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), version),
2897 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags)
2899 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 2);
2901 const char *Section;
2903 Section = "__OBJC, __image_info,regular";
2905 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
2906 llvm::GlobalVariable *GV =
2907 CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
2908 llvm::ConstantArray::get(AT, values, 2),
2912 GV->setConstant(true);
2916 // struct objc_module {
2917 // unsigned long version;
2918 // unsigned long size;
2919 // const char *name;
2923 // FIXME: Get from somewhere
2924 static const int ModuleVersion = 7;
2926 void CGObjCMac::EmitModuleInfo() {
2927 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
2929 std::vector<llvm::Constant*> Values(4);
2930 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
2931 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2932 // This used to be the filename, now it is unused. <rdr://4327263>
2933 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
2934 Values[3] = EmitModuleSymbols();
2935 CreateMetadataVar("\01L_OBJC_MODULES",
2936 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
2937 "__OBJC,__module_info,regular,no_dead_strip",
2941 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
2942 unsigned NumClasses = DefinedClasses.size();
2943 unsigned NumCategories = DefinedCategories.size();
2945 // Return null if no symbols were defined.
2946 if (!NumClasses && !NumCategories)
2947 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
2949 std::vector<llvm::Constant*> Values(5);
2950 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2951 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
2952 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
2953 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
2955 // The runtime expects exactly the list of defined classes followed
2956 // by the list of defined categories, in a single array.
2957 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
2958 for (unsigned i=0; i<NumClasses; i++)
2959 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
2960 ObjCTypes.Int8PtrTy);
2961 for (unsigned i=0; i<NumCategories; i++)
2962 Symbols[NumClasses + i] =
2963 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
2964 ObjCTypes.Int8PtrTy);
2967 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2968 NumClasses + NumCategories),
2971 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2973 llvm::GlobalVariable *GV =
2974 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
2975 "__OBJC,__symbols,regular,no_dead_strip",
2977 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
2980 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
2981 const ObjCInterfaceDecl *ID) {
2982 LazySymbols.insert(ID->getIdentifier());
2984 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
2987 llvm::Constant *Casted =
2988 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
2989 ObjCTypes.ClassPtrTy);
2991 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
2992 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
2996 return Builder.CreateLoad(Entry, "tmp");
2999 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
3000 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
3003 llvm::Constant *Casted =
3004 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3005 ObjCTypes.SelectorPtrTy);
3007 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
3008 "__OBJC,__message_refs,literal_pointers,no_dead_strip",
3012 return Builder.CreateLoad(Entry, "tmp");
3015 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
3016 llvm::GlobalVariable *&Entry = ClassNames[Ident];
3019 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3020 llvm::ConstantArray::get(VMContext,
3021 Ident->getNameStart()),
3022 "__TEXT,__cstring,cstring_literals",
3025 return getConstantGEP(VMContext, Entry, 0, 0);
3028 /// GetIvarLayoutName - Returns a unique constant for the given
3029 /// ivar layout bitmap.
3030 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
3031 const ObjCCommonTypesHelper &ObjCTypes) {
3032 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3035 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
3036 if (FQT.isObjCGCStrong())
3037 return Qualifiers::Strong;
3039 if (FQT.isObjCGCWeak())
3040 return Qualifiers::Weak;
3042 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
3043 return Qualifiers::Strong;
3045 if (const PointerType *PT = FQT->getAs<PointerType>())
3046 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
3048 return Qualifiers::GCNone;
3051 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
3052 unsigned int BytePos,
3053 bool ForStrongLayout,
3055 const RecordDecl *RD = RT->getDecl();
3056 // FIXME - Use iterator.
3057 llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
3058 const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
3059 const llvm::StructLayout *RecLayout =
3060 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
3062 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3063 ForStrongLayout, HasUnion);
3066 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
3067 const llvm::StructLayout *Layout,
3068 const RecordDecl *RD,
3069 const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
3070 unsigned int BytePos, bool ForStrongLayout,
3072 bool IsUnion = (RD && RD->isUnion());
3073 uint64_t MaxUnionIvarSize = 0;
3074 uint64_t MaxSkippedUnionIvarSize = 0;
3075 FieldDecl *MaxField = 0;
3076 FieldDecl *MaxSkippedField = 0;
3077 FieldDecl *LastFieldBitfield = 0;
3078 uint64_t MaxFieldOffset = 0;
3079 uint64_t MaxSkippedFieldOffset = 0;
3080 uint64_t LastBitfieldOffset = 0;
3082 if (RecFields.empty())
3084 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
3085 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
3087 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3088 FieldDecl *Field = RecFields[i];
3089 uint64_t FieldOffset;
3091 if (Field->isBitField()) {
3092 CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
3094 const llvm::Type *Ty =
3095 CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
3097 CGM.getTypes().getTargetData().getTypeAllocSize(Ty);
3098 FieldOffset = Info.FieldNo * TypeSize;
3101 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
3103 FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
3105 // Skip over unnamed or bitfields
3106 if (!Field->getIdentifier() || Field->isBitField()) {
3107 LastFieldBitfield = Field;
3108 LastBitfieldOffset = FieldOffset;
3112 LastFieldBitfield = 0;
3113 QualType FQT = Field->getType();
3114 if (FQT->isRecordType() || FQT->isUnionType()) {
3115 if (FQT->isUnionType())
3118 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
3119 BytePos + FieldOffset,
3120 ForStrongLayout, HasUnion);
3124 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3125 const ConstantArrayType *CArray =
3126 dyn_cast_or_null<ConstantArrayType>(Array);
3127 uint64_t ElCount = CArray->getSize().getZExtValue();
3128 assert(CArray && "only array with known element size is supported");
3129 FQT = CArray->getElementType();
3130 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3131 const ConstantArrayType *CArray =
3132 dyn_cast_or_null<ConstantArrayType>(Array);
3133 ElCount *= CArray->getSize().getZExtValue();
3134 FQT = CArray->getElementType();
3137 assert(!FQT->isUnionType() &&
3138 "layout for array of unions not supported");
3139 if (FQT->isRecordType()) {
3140 int OldIndex = IvarsInfo.size() - 1;
3141 int OldSkIndex = SkipIvars.size() -1;
3143 const RecordType *RT = FQT->getAs<RecordType>();
3144 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3145 ForStrongLayout, HasUnion);
3147 // Replicate layout information for each array element. Note that
3148 // one element is already done.
3150 for (int FirstIndex = IvarsInfo.size() - 1,
3151 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3152 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
3153 for (int i = OldIndex+1; i <= FirstIndex; ++i)
3154 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
3155 IvarsInfo[i].ivar_size));
3156 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
3157 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
3158 SkipIvars[i].ivar_size));
3163 // At this point, we are done with Record/Union and array there of.
3164 // For other arrays we are down to its element type.
3165 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
3167 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
3168 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
3169 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3171 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3172 if (UnionIvarSize > MaxUnionIvarSize) {
3173 MaxUnionIvarSize = UnionIvarSize;
3175 MaxFieldOffset = FieldOffset;
3178 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
3179 FieldSize / WordSizeInBits));
3181 } else if ((ForStrongLayout &&
3182 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
3183 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3185 // FIXME: Why the asymmetry? We divide by word size in bits on other
3187 uint64_t UnionIvarSize = FieldSize;
3188 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3189 MaxSkippedUnionIvarSize = UnionIvarSize;
3190 MaxSkippedField = Field;
3191 MaxSkippedFieldOffset = FieldOffset;
3194 // FIXME: Why the asymmetry, we divide by byte size in bits here?
3195 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
3196 FieldSize / ByteSizeInBits));
3201 if (LastFieldBitfield) {
3202 // Last field was a bitfield. Must update skip info.
3203 Expr *BitWidth = LastFieldBitfield->getBitWidth();
3204 uint64_t BitFieldSize =
3205 BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
3207 skivar.ivar_bytepos = BytePos + LastBitfieldOffset;
3208 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
3209 + ((BitFieldSize % ByteSizeInBits) != 0);
3210 SkipIvars.push_back(skivar);
3214 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
3216 if (MaxSkippedField)
3217 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
3218 MaxSkippedUnionIvarSize));
3221 /// BuildIvarLayout - Builds ivar layout bitmap for the class
3222 /// implementation for the __strong or __weak case.
3223 /// The layout map displays which words in ivar list must be skipped
3224 /// and which must be scanned by GC (see below). String is built of bytes.
3225 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
3226 /// of words to skip and right nibble is count of words to scan. So, each
3227 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
3228 /// represented by a 0x00 byte which also ends the string.
3229 /// 1. when ForStrongLayout is true, following ivars are scanned:
3232 /// - __strong anything
3234 /// 2. When ForStrongLayout is false, following ivars are scanned:
3235 /// - __weak anything
3237 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
3238 const ObjCImplementationDecl *OMD,
3239 bool ForStrongLayout) {
3240 bool hasUnion = false;
3242 unsigned int WordsToScan, WordsToSkip;
3243 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3244 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
3245 return llvm::Constant::getNullValue(PtrTy);
3247 llvm::SmallVector<FieldDecl*, 32> RecFields;
3248 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
3249 CGM.getContext().CollectObjCIvars(OI, RecFields);
3251 // Add this implementations synthesized ivars.
3252 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
3253 CGM.getContext().CollectSynthesizedIvars(OI, Ivars);
3254 for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
3255 RecFields.push_back(cast<FieldDecl>(Ivars[k]));
3257 if (RecFields.empty())
3258 return llvm::Constant::getNullValue(PtrTy);
3263 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
3264 if (IvarsInfo.empty())
3265 return llvm::Constant::getNullValue(PtrTy);
3267 // Sort on byte position in case we encounterred a union nested in
3269 if (hasUnion && !IvarsInfo.empty())
3270 std::sort(IvarsInfo.begin(), IvarsInfo.end());
3271 if (hasUnion && !SkipIvars.empty())
3272 std::sort(SkipIvars.begin(), SkipIvars.end());
3274 // Build the string of skip/scan nibbles
3275 llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars;
3276 unsigned int WordSize =
3277 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
3278 if (IvarsInfo[0].ivar_bytepos == 0) {
3280 WordsToScan = IvarsInfo[0].ivar_size;
3282 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
3283 WordsToScan = IvarsInfo[0].ivar_size;
3285 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
3286 unsigned int TailPrevGCObjC =
3287 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
3288 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
3289 // consecutive 'scanned' object pointers.
3290 WordsToScan += IvarsInfo[i].ivar_size;
3292 // Skip over 'gc'able object pointer which lay over each other.
3293 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
3295 // Must skip over 1 or more words. We save current skip/scan values
3296 // and start a new pair.
3298 SkScan.skip = WordsToSkip;
3299 SkScan.scan = WordsToScan;
3300 SkipScanIvars.push_back(SkScan);
3303 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
3305 SkipScanIvars.push_back(SkScan);
3307 WordsToScan = IvarsInfo[i].ivar_size;
3310 if (WordsToScan > 0) {
3312 SkScan.skip = WordsToSkip;
3313 SkScan.scan = WordsToScan;
3314 SkipScanIvars.push_back(SkScan);
3317 bool BytesSkipped = false;
3318 if (!SkipIvars.empty()) {
3319 unsigned int LastIndex = SkipIvars.size()-1;
3320 int LastByteSkipped =
3321 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
3322 LastIndex = IvarsInfo.size()-1;
3323 int LastByteScanned =
3324 IvarsInfo[LastIndex].ivar_bytepos +
3325 IvarsInfo[LastIndex].ivar_size * WordSize;
3326 BytesSkipped = (LastByteSkipped > LastByteScanned);
3327 // Compute number of bytes to skip at the tail end of the last ivar scanned.
3329 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
3331 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
3333 SkipScanIvars.push_back(SkScan);
3336 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
3338 int SkipScan = SkipScanIvars.size()-1;
3339 for (int i = 0; i <= SkipScan; i++) {
3340 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
3341 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
3342 // 0xM0 followed by 0x0N detected.
3343 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
3344 for (int j = i+1; j < SkipScan; j++)
3345 SkipScanIvars[j] = SkipScanIvars[j+1];
3350 // Generate the string.
3352 for (int i = 0; i <= SkipScan; i++) {
3354 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
3355 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
3356 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
3357 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
3359 if (skip_small > 0 || skip_big > 0)
3360 BytesSkipped = true;
3362 for (unsigned int ix = 0; ix < skip_big; ix++)
3363 BitMap += (unsigned char)(0xf0);
3365 // next (skip small, scan)
3367 byte = skip_small << 4;
3371 } else if (scan_small) {
3378 for (unsigned int ix = 0; ix < scan_big; ix++)
3379 BitMap += (unsigned char)(0x0f);
3386 // null terminate string.
3387 unsigned char zero = 0;
3390 if (CGM.getLangOptions().ObjCGCBitmapPrint) {
3391 printf("\n%s ivar layout for class '%s': ",
3392 ForStrongLayout ? "strong" : "weak",
3393 OMD->getClassInterface()->getNameAsCString());
3394 const unsigned char *s = (unsigned char*)BitMap.c_str();
3395 for (unsigned i = 0; i < BitMap.size(); i++)
3397 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
3399 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
3402 llvm::GlobalVariable * Entry =
3403 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3404 llvm::ConstantArray::get(VMContext, BitMap.c_str()),
3405 "__TEXT,__cstring,cstring_literals",
3407 return getConstantGEP(VMContext, Entry, 0, 0);
3410 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
3411 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
3413 // FIXME: Avoid std::string copying.
3415 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
3416 llvm::ConstantArray::get(VMContext, Sel.getAsString()),
3417 "__TEXT,__cstring,cstring_literals",
3420 return getConstantGEP(VMContext, Entry, 0, 0);
3423 // FIXME: Merge into a single cstring creation function.
3424 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
3425 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
3428 // FIXME: Merge into a single cstring creation function.
3429 llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) {
3430 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
3433 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
3434 std::string TypeStr;
3435 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
3437 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3440 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3441 llvm::ConstantArray::get(VMContext, TypeStr),
3442 "__TEXT,__cstring,cstring_literals",
3445 return getConstantGEP(VMContext, Entry, 0, 0);
3448 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
3449 std::string TypeStr;
3450 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
3453 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3456 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3457 llvm::ConstantArray::get(VMContext, TypeStr),
3458 "__TEXT,__cstring,cstring_literals",
3461 return getConstantGEP(VMContext, Entry, 0, 0);
3464 // FIXME: Merge into a single cstring creation function.
3465 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
3466 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
3469 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
3470 llvm::ConstantArray::get(VMContext,
3471 Ident->getNameStart()),
3472 "__TEXT,__cstring,cstring_literals",
3475 return getConstantGEP(VMContext, Entry, 0, 0);
3478 // FIXME: Merge into a single cstring creation function.
3479 // FIXME: This Decl should be more precise.
3481 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
3482 const Decl *Container) {
3483 std::string TypeStr;
3484 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
3485 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
3488 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
3489 const ObjCContainerDecl *CD,
3490 llvm::SmallVectorImpl<char> &Name) {
3491 llvm::raw_svector_ostream OS(Name);
3492 assert (CD && "Missing container decl in GetNameForMethod");
3493 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
3494 << '[' << CD->getName();
3495 if (const ObjCCategoryImplDecl *CID =
3496 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
3497 OS << '(' << CID->getNameAsString() << ')';
3498 OS << ' ' << D->getSelector().getAsString() << ']';
3501 void CGObjCMac::FinishModule() {
3504 // Emit the dummy bodies for any protocols which were referenced but
3506 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
3507 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
3508 if (I->second->hasInitializer())
3511 std::vector<llvm::Constant*> Values(5);
3512 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3513 Values[1] = GetClassName(I->first);
3514 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3515 Values[3] = Values[4] =
3516 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
3517 I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
3518 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
3520 CGM.AddUsedGlobal(I->second);
3523 // Add assembler directives to add lazy undefined symbol references
3524 // for classes which are referenced but not defined. This is
3525 // important for correct linker interaction.
3527 // FIXME: It would be nice if we had an LLVM construct for this.
3528 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
3529 llvm::SmallString<256> Asm;
3530 Asm += CGM.getModule().getModuleInlineAsm();
3531 if (!Asm.empty() && Asm.back() != '\n')
3534 llvm::raw_svector_ostream OS(Asm);
3535 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
3536 e = LazySymbols.end(); I != e; ++I)
3537 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
3538 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
3539 e = DefinedSymbols.end(); I != e; ++I)
3540 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
3541 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
3543 CGM.getModule().setModuleInlineAsm(OS.str());
3547 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
3548 : CGObjCCommonMac(cgm),
3550 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
3556 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
3557 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
3558 CodeGen::CodeGenTypes &Types = CGM.getTypes();
3559 ASTContext &Ctx = CGM.getContext();
3561 ShortTy = Types.ConvertType(Ctx.ShortTy);
3562 IntTy = Types.ConvertType(Ctx.IntTy);
3563 LongTy = Types.ConvertType(Ctx.LongTy);
3564 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
3565 Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3567 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
3568 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
3569 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
3571 // FIXME: It would be nice to unify this with the opaque type, so that the IR
3572 // comes out a bit cleaner.
3573 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
3574 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
3576 // I'm not sure I like this. The implicit coordination is a bit
3577 // gross. We should solve this in a reasonable fashion because this
3578 // is a pretty common task (match some runtime data structure with
3579 // an LLVM data structure).
3581 // FIXME: This is leaked.
3582 // FIXME: Merge with rewriter code?
3584 // struct _objc_super {
3588 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
3590 &Ctx.Idents.get("_objc_super"));
3591 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
3592 Ctx.getObjCIdType(), 0, 0, false));
3593 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
3594 Ctx.getObjCClassType(), 0, 0, false));
3595 RD->completeDefinition(Ctx);
3597 SuperCTy = Ctx.getTagDeclType(RD);
3598 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
3600 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
3601 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
3605 // char *attributes;
3607 PropertyTy = llvm::StructType::get(VMContext, Int8PtrTy, Int8PtrTy, NULL);
3608 CGM.getModule().addTypeName("struct._prop_t",
3611 // struct _prop_list_t {
3612 // uint32_t entsize; // sizeof(struct _prop_t)
3613 // uint32_t count_of_properties;
3614 // struct _prop_t prop_list[count_of_properties];
3616 PropertyListTy = llvm::StructType::get(VMContext, IntTy,
3618 llvm::ArrayType::get(PropertyTy, 0),
3620 CGM.getModule().addTypeName("struct._prop_list_t",
3622 // struct _prop_list_t *
3623 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
3625 // struct _objc_method {
3627 // char *method_type;
3630 MethodTy = llvm::StructType::get(VMContext, SelectorPtrTy,
3634 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
3636 // struct _objc_cache *
3637 CacheTy = llvm::OpaqueType::get(VMContext);
3638 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
3639 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
3642 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
3643 : ObjCCommonTypesHelper(cgm) {
3644 // struct _objc_method_description {
3648 MethodDescriptionTy =
3649 llvm::StructType::get(VMContext, SelectorPtrTy,
3652 CGM.getModule().addTypeName("struct._objc_method_description",
3653 MethodDescriptionTy);
3655 // struct _objc_method_description_list {
3657 // struct _objc_method_description[1];
3659 MethodDescriptionListTy =
3660 llvm::StructType::get(VMContext, IntTy,
3661 llvm::ArrayType::get(MethodDescriptionTy, 0),
3663 CGM.getModule().addTypeName("struct._objc_method_description_list",
3664 MethodDescriptionListTy);
3666 // struct _objc_method_description_list *
3667 MethodDescriptionListPtrTy =
3668 llvm::PointerType::getUnqual(MethodDescriptionListTy);
3670 // Protocol description structures
3672 // struct _objc_protocol_extension {
3673 // uint32_t size; // sizeof(struct _objc_protocol_extension)
3674 // struct _objc_method_description_list *optional_instance_methods;
3675 // struct _objc_method_description_list *optional_class_methods;
3676 // struct _objc_property_list *instance_properties;
3678 ProtocolExtensionTy =
3679 llvm::StructType::get(VMContext, IntTy,
3680 MethodDescriptionListPtrTy,
3681 MethodDescriptionListPtrTy,
3684 CGM.getModule().addTypeName("struct._objc_protocol_extension",
3685 ProtocolExtensionTy);
3687 // struct _objc_protocol_extension *
3688 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
3690 // Handle recursive construction of Protocol and ProtocolList types
3692 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(VMContext);
3693 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
3695 const llvm::Type *T =
3696 llvm::StructType::get(VMContext,
3697 llvm::PointerType::getUnqual(ProtocolListTyHolder),
3699 llvm::ArrayType::get(ProtocolTyHolder, 0),
3701 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
3703 // struct _objc_protocol {
3704 // struct _objc_protocol_extension *isa;
3705 // char *protocol_name;
3706 // struct _objc_protocol **_objc_protocol_list;
3707 // struct _objc_method_description_list *instance_methods;
3708 // struct _objc_method_description_list *class_methods;
3710 T = llvm::StructType::get(VMContext, ProtocolExtensionPtrTy,
3712 llvm::PointerType::getUnqual(ProtocolListTyHolder),
3713 MethodDescriptionListPtrTy,
3714 MethodDescriptionListPtrTy,
3716 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
3718 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
3719 CGM.getModule().addTypeName("struct._objc_protocol_list",
3721 // struct _objc_protocol_list *
3722 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
3724 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
3725 CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy);
3726 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
3728 // Class description structures
3730 // struct _objc_ivar {
3735 IvarTy = llvm::StructType::get(VMContext, Int8PtrTy,
3739 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
3741 // struct _objc_ivar_list *
3742 IvarListTy = llvm::OpaqueType::get(VMContext);
3743 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
3744 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
3746 // struct _objc_method_list *
3747 MethodListTy = llvm::OpaqueType::get(VMContext);
3748 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
3749 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
3751 // struct _objc_class_extension *
3753 llvm::StructType::get(VMContext, IntTy,
3757 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
3758 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
3760 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
3762 // struct _objc_class {
3764 // Class super_class;
3768 // long instance_size;
3769 // struct _objc_ivar_list *ivars;
3770 // struct _objc_method_list *methods;
3771 // struct _objc_cache *cache;
3772 // struct _objc_protocol_list *protocols;
3773 // char *ivar_layout;
3774 // struct _objc_class_ext *ext;
3776 T = llvm::StructType::get(VMContext,
3777 llvm::PointerType::getUnqual(ClassTyHolder),
3778 llvm::PointerType::getUnqual(ClassTyHolder),
3788 ClassExtensionPtrTy,
3790 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
3792 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
3793 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
3794 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
3796 // struct _objc_category {
3797 // char *category_name;
3798 // char *class_name;
3799 // struct _objc_method_list *instance_method;
3800 // struct _objc_method_list *class_method;
3801 // uint32_t size; // sizeof(struct _objc_category)
3802 // struct _objc_property_list *instance_properties;// category's @property
3804 CategoryTy = llvm::StructType::get(VMContext, Int8PtrTy,
3812 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
3814 // Global metadata structures
3816 // struct _objc_symtab {
3817 // long sel_ref_cnt;
3819 // short cls_def_cnt;
3820 // short cat_def_cnt;
3821 // char *defs[cls_def_cnt + cat_def_cnt];
3823 SymtabTy = llvm::StructType::get(VMContext, LongTy,
3827 llvm::ArrayType::get(Int8PtrTy, 0),
3829 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
3830 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
3832 // struct _objc_module {
3834 // long size; // sizeof(struct _objc_module)
3836 // struct _objc_symtab* symtab;
3839 llvm::StructType::get(VMContext, LongTy,
3844 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
3847 // FIXME: This is the size of the setjmp buffer and should be target
3848 // specific. 18 is what's used on 32-bit X86.
3849 uint64_t SetJmpBufferSize = 18;
3852 const llvm::Type *StackPtrTy = llvm::ArrayType::get(
3853 llvm::Type::getInt8PtrTy(VMContext), 4);
3856 llvm::StructType::get(VMContext, llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
3859 CGM.getModule().addTypeName("struct._objc_exception_data",
3864 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
3865 : ObjCCommonTypesHelper(cgm) {
3866 // struct _method_list_t {
3867 // uint32_t entsize; // sizeof(struct _objc_method)
3868 // uint32_t method_count;
3869 // struct _objc_method method_list[method_count];
3871 MethodListnfABITy = llvm::StructType::get(VMContext, IntTy,
3873 llvm::ArrayType::get(MethodTy, 0),
3875 CGM.getModule().addTypeName("struct.__method_list_t",
3877 // struct method_list_t *
3878 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
3880 // struct _protocol_t {
3882 // const char * const protocol_name;
3883 // const struct _protocol_list_t * protocol_list; // super protocols
3884 // const struct method_list_t * const instance_methods;
3885 // const struct method_list_t * const class_methods;
3886 // const struct method_list_t *optionalInstanceMethods;
3887 // const struct method_list_t *optionalClassMethods;
3888 // const struct _prop_list_t * properties;
3889 // const uint32_t size; // sizeof(struct _protocol_t)
3890 // const uint32_t flags; // = 0
3893 // Holder for struct _protocol_list_t *
3894 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
3896 ProtocolnfABITy = llvm::StructType::get(VMContext, ObjectPtrTy,
3898 llvm::PointerType::getUnqual(
3899 ProtocolListTyHolder),
3900 MethodListnfABIPtrTy,
3901 MethodListnfABIPtrTy,
3902 MethodListnfABIPtrTy,
3903 MethodListnfABIPtrTy,
3908 CGM.getModule().addTypeName("struct._protocol_t",
3911 // struct _protocol_t*
3912 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
3914 // struct _protocol_list_t {
3915 // long protocol_count; // Note, this is 32/64 bit
3916 // struct _protocol_t *[protocol_count];
3918 ProtocolListnfABITy = llvm::StructType::get(VMContext, LongTy,
3919 llvm::ArrayType::get(
3920 ProtocolnfABIPtrTy, 0),
3922 CGM.getModule().addTypeName("struct._objc_protocol_list",
3923 ProtocolListnfABITy);
3924 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(
3925 ProtocolListnfABITy);
3927 // struct _objc_protocol_list*
3928 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
3931 // unsigned long int *offset; // pointer to ivar offset location
3934 // uint32_t alignment;
3937 IvarnfABITy = llvm::StructType::get(VMContext,
3938 llvm::PointerType::getUnqual(LongTy),
3944 CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy);
3946 // struct _ivar_list_t {
3947 // uint32 entsize; // sizeof(struct _ivar_t)
3949 // struct _iver_t list[count];
3951 IvarListnfABITy = llvm::StructType::get(VMContext, IntTy,
3953 llvm::ArrayType::get(
3956 CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy);
3958 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
3960 // struct _class_ro_t {
3961 // uint32_t const flags;
3962 // uint32_t const instanceStart;
3963 // uint32_t const instanceSize;
3964 // uint32_t const reserved; // only when building for 64bit targets
3965 // const uint8_t * const ivarLayout;
3966 // const char *const name;
3967 // const struct _method_list_t * const baseMethods;
3968 // const struct _objc_protocol_list *const baseProtocols;
3969 // const struct _ivar_list_t *const ivars;
3970 // const uint8_t * const weakIvarLayout;
3971 // const struct _prop_list_t * const properties;
3974 // FIXME. Add 'reserved' field in 64bit abi mode!
3975 ClassRonfABITy = llvm::StructType::get(VMContext, IntTy,
3980 MethodListnfABIPtrTy,
3981 ProtocolListnfABIPtrTy,
3986 CGM.getModule().addTypeName("struct._class_ro_t",
3989 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
3990 std::vector<const llvm::Type*> Params;
3991 Params.push_back(ObjectPtrTy);
3992 Params.push_back(SelectorPtrTy);
3993 ImpnfABITy = llvm::PointerType::getUnqual(
3994 llvm::FunctionType::get(ObjectPtrTy, Params, false));
3996 // struct _class_t {
3997 // struct _class_t *isa;
3998 // struct _class_t * const superclass;
4001 // struct class_ro_t *ro;
4004 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
4006 llvm::StructType::get(VMContext,
4007 llvm::PointerType::getUnqual(ClassTyHolder),
4008 llvm::PointerType::getUnqual(ClassTyHolder),
4010 llvm::PointerType::getUnqual(ImpnfABITy),
4011 llvm::PointerType::getUnqual(ClassRonfABITy),
4013 CGM.getModule().addTypeName("struct._class_t", ClassnfABITy);
4015 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(
4018 // LLVM for struct _class_t *
4019 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
4021 // struct _category_t {
4022 // const char * const name;
4023 // struct _class_t *const cls;
4024 // const struct _method_list_t * const instance_methods;
4025 // const struct _method_list_t * const class_methods;
4026 // const struct _protocol_list_t * const protocols;
4027 // const struct _prop_list_t * const properties;
4029 CategorynfABITy = llvm::StructType::get(VMContext, Int8PtrTy,
4031 MethodListnfABIPtrTy,
4032 MethodListnfABIPtrTy,
4033 ProtocolListnfABIPtrTy,
4036 CGM.getModule().addTypeName("struct._category_t", CategorynfABITy);
4038 // New types for nonfragile abi messaging.
4039 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4040 ASTContext &Ctx = CGM.getContext();
4042 // MessageRefTy - LLVM for:
4043 // struct _message_ref_t {
4048 // First the clang type for struct _message_ref_t
4049 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
4051 &Ctx.Idents.get("_message_ref_t"));
4052 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
4053 Ctx.VoidPtrTy, 0, 0, false));
4054 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
4055 Ctx.getObjCSelType(), 0, 0, false));
4056 RD->completeDefinition(Ctx);
4058 MessageRefCTy = Ctx.getTagDeclType(RD);
4059 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
4060 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
4062 // MessageRefPtrTy - LLVM for struct _message_ref_t*
4063 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
4065 // SuperMessageRefTy - LLVM for:
4066 // struct _super_message_ref_t {
4067 // SUPER_IMP messenger;
4070 SuperMessageRefTy = llvm::StructType::get(VMContext, ImpnfABITy,
4073 CGM.getModule().addTypeName("struct._super_message_ref_t", SuperMessageRefTy);
4075 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
4076 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
4079 // struct objc_typeinfo {
4080 // const void** vtable; // objc_ehtype_vtable + 2
4081 // const char* name; // c++ typeinfo string
4084 EHTypeTy = llvm::StructType::get(VMContext,
4085 llvm::PointerType::getUnqual(Int8PtrTy),
4089 CGM.getModule().addTypeName("struct._objc_typeinfo", EHTypeTy);
4090 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4093 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4094 FinishNonFragileABIModule();
4099 void CGObjCNonFragileABIMac::AddModuleClassList(const
4100 std::vector<llvm::GlobalValue*>
4102 const char *SymbolName,
4103 const char *SectionName) {
4104 unsigned NumClasses = Container.size();
4109 std::vector<llvm::Constant*> Symbols(NumClasses);
4110 for (unsigned i=0; i<NumClasses; i++)
4111 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4112 ObjCTypes.Int8PtrTy);
4113 llvm::Constant* Init =
4114 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4118 llvm::GlobalVariable *GV =
4119 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4120 llvm::GlobalValue::InternalLinkage,
4123 GV->setAlignment(8);
4124 GV->setSection(SectionName);
4125 CGM.AddUsedGlobal(GV);
4128 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4129 // nonfragile abi has no module definition.
4131 // Build list of all implemented class addresses in array
4132 // L_OBJC_LABEL_CLASS_$.
4133 AddModuleClassList(DefinedClasses,
4134 "\01L_OBJC_LABEL_CLASS_$",
4135 "__DATA, __objc_classlist, regular, no_dead_strip");
4137 bool hasWeakImport = false;
4138 for (unsigned i = 0; i < DefinedClasses.size(); i++) {
4139 llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4140 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4142 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4143 hasWeakImport = true;
4146 if (hasWeakImport) {
4147 for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) {
4148 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
4149 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4151 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4155 AddModuleClassList(DefinedNonLazyClasses,
4156 "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
4157 "__DATA, __objc_nlclslist, regular, no_dead_strip");
4159 // Build list of all implemented category addresses in array
4160 // L_OBJC_LABEL_CATEGORY_$.
4161 AddModuleClassList(DefinedCategories,
4162 "\01L_OBJC_LABEL_CATEGORY_$",
4163 "__DATA, __objc_catlist, regular, no_dead_strip");
4164 AddModuleClassList(DefinedNonLazyCategories,
4165 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
4166 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
4168 // static int L_OBJC_IMAGE_INFO[2] = { 0, flags };
4169 // FIXME. flags can be 0 | 1 | 2 | 6. For now just use 0
4170 std::vector<llvm::Constant*> Values(2);
4171 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0);
4172 unsigned int flags = 0;
4173 // FIXME: Fix and continue?
4174 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
4175 flags |= eImageInfo_GarbageCollected;
4176 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
4177 flags |= eImageInfo_GCOnly;
4178 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
4179 llvm::Constant* Init = llvm::ConstantArray::get(
4180 llvm::ArrayType::get(ObjCTypes.IntTy, 2),
4182 llvm::GlobalVariable *IMGV =
4183 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4184 llvm::GlobalValue::InternalLinkage,
4186 "\01L_OBJC_IMAGE_INFO");
4187 IMGV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
4188 IMGV->setConstant(true);
4189 CGM.AddUsedGlobal(IMGV);
4192 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of
4193 /// NonLegacyDispatchMethods; false otherwise. What this means is that
4194 /// except for the 19 selectors in the list, we generate 32bit-style
4195 /// message dispatch call for all the rest.
4197 bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) {
4198 if (NonLegacyDispatchMethods.empty()) {
4199 NonLegacyDispatchMethods.insert(GetNullarySelector("alloc"));
4200 NonLegacyDispatchMethods.insert(GetNullarySelector("class"));
4201 NonLegacyDispatchMethods.insert(GetNullarySelector("self"));
4202 NonLegacyDispatchMethods.insert(GetNullarySelector("isFlipped"));
4203 NonLegacyDispatchMethods.insert(GetNullarySelector("length"));
4204 NonLegacyDispatchMethods.insert(GetNullarySelector("count"));
4205 NonLegacyDispatchMethods.insert(GetNullarySelector("retain"));
4206 NonLegacyDispatchMethods.insert(GetNullarySelector("release"));
4207 NonLegacyDispatchMethods.insert(GetNullarySelector("autorelease"));
4208 NonLegacyDispatchMethods.insert(GetNullarySelector("hash"));
4210 NonLegacyDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4211 NonLegacyDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4212 NonLegacyDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4213 NonLegacyDispatchMethods.insert(GetUnarySelector("objectForKey"));
4214 NonLegacyDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4215 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4216 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqual"));
4217 NonLegacyDispatchMethods.insert(GetUnarySelector("addObject"));
4218 // "countByEnumeratingWithState:objects:count"
4219 IdentifierInfo *KeyIdents[] = {
4220 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4221 &CGM.getContext().Idents.get("objects"),
4222 &CGM.getContext().Idents.get("count")
4224 NonLegacyDispatchMethods.insert(
4225 CGM.getContext().Selectors.getSelector(3, KeyIdents));
4227 return (NonLegacyDispatchMethods.count(Sel) == 0);
4231 enum MetaDataDlags {
4235 OBJC2_CLS_HIDDEN = 0x10,
4236 CLS_EXCEPTION = 0x20
4238 /// BuildClassRoTInitializer - generate meta-data for:
4239 /// struct _class_ro_t {
4240 /// uint32_t const flags;
4241 /// uint32_t const instanceStart;
4242 /// uint32_t const instanceSize;
4243 /// uint32_t const reserved; // only when building for 64bit targets
4244 /// const uint8_t * const ivarLayout;
4245 /// const char *const name;
4246 /// const struct _method_list_t * const baseMethods;
4247 /// const struct _protocol_list_t *const baseProtocols;
4248 /// const struct _ivar_list_t *const ivars;
4249 /// const uint8_t * const weakIvarLayout;
4250 /// const struct _prop_list_t * const properties;
4253 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
4255 unsigned InstanceStart,
4256 unsigned InstanceSize,
4257 const ObjCImplementationDecl *ID) {
4258 std::string ClassName = ID->getNameAsString();
4259 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets!
4260 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
4261 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
4262 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4263 // FIXME. For 64bit targets add 0 here.
4264 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4265 : BuildIvarLayout(ID, true);
4266 Values[ 4] = GetClassName(ID->getIdentifier());
4267 // const struct _method_list_t * const baseMethods;
4268 std::vector<llvm::Constant*> Methods;
4269 std::string MethodListName("\01l_OBJC_$_");
4270 if (flags & CLS_META) {
4271 MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
4272 for (ObjCImplementationDecl::classmeth_iterator
4273 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4274 // Class methods should always be defined.
4275 Methods.push_back(GetMethodConstant(*i));
4278 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
4279 for (ObjCImplementationDecl::instmeth_iterator
4280 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
4281 // Instance methods should always be defined.
4282 Methods.push_back(GetMethodConstant(*i));
4284 for (ObjCImplementationDecl::propimpl_iterator
4285 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
4286 ObjCPropertyImplDecl *PID = *i;
4288 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
4289 ObjCPropertyDecl *PD = PID->getPropertyDecl();
4291 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
4292 if (llvm::Constant *C = GetMethodConstant(MD))
4293 Methods.push_back(C);
4294 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
4295 if (llvm::Constant *C = GetMethodConstant(MD))
4296 Methods.push_back(C);
4300 Values[ 5] = EmitMethodList(MethodListName,
4301 "__DATA, __objc_const", Methods);
4303 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4304 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
4305 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
4307 OID->protocol_begin(),
4308 OID->protocol_end());
4310 if (flags & CLS_META)
4311 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
4313 Values[ 7] = EmitIvarList(ID);
4314 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4315 : BuildIvarLayout(ID, false);
4316 if (flags & CLS_META)
4317 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
4319 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
4320 ID, ID->getClassInterface(), ObjCTypes);
4321 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
4323 llvm::GlobalVariable *CLASS_RO_GV =
4324 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
4325 llvm::GlobalValue::InternalLinkage,
4327 (flags & CLS_META) ?
4328 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
4329 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
4330 CLASS_RO_GV->setAlignment(
4331 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassRonfABITy));
4332 CLASS_RO_GV->setSection("__DATA, __objc_const");
4337 /// BuildClassMetaData - This routine defines that to-level meta-data
4338 /// for the given ClassName for:
4339 /// struct _class_t {
4340 /// struct _class_t *isa;
4341 /// struct _class_t * const superclass;
4344 /// struct class_ro_t *ro;
4347 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
4348 std::string &ClassName,
4349 llvm::Constant *IsAGV,
4350 llvm::Constant *SuperClassGV,
4351 llvm::Constant *ClassRoGV,
4352 bool HiddenVisibility) {
4353 std::vector<llvm::Constant*> Values(5);
4355 Values[1] = SuperClassGV;
4357 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
4358 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar
4359 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar
4360 Values[4] = ClassRoGV; // &CLASS_RO_GV
4361 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
4363 llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
4364 GV->setInitializer(Init);
4365 GV->setSection("__DATA, __objc_data");
4367 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassnfABITy));
4368 if (HiddenVisibility)
4369 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4374 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
4375 return OD->getClassMethod(GetNullarySelector("load")) != 0;
4378 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
4379 uint32_t &InstanceStart,
4380 uint32_t &InstanceSize) {
4381 const ASTRecordLayout &RL =
4382 CGM.getContext().getASTObjCImplementationLayout(OID);
4384 // InstanceSize is really instance end.
4385 InstanceSize = llvm::RoundUpToAlignment(RL.getDataSize(), 8) / 8;
4387 // If there are no fields, the start is the same as the end.
4388 if (!RL.getFieldCount())
4389 InstanceStart = InstanceSize;
4391 InstanceStart = RL.getFieldOffset(0) / 8;
4394 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
4395 std::string ClassName = ID->getNameAsString();
4396 if (!ObjCEmptyCacheVar) {
4397 ObjCEmptyCacheVar = new llvm::GlobalVariable(
4401 llvm::GlobalValue::ExternalLinkage,
4403 "_objc_empty_cache");
4405 ObjCEmptyVtableVar = new llvm::GlobalVariable(
4407 ObjCTypes.ImpnfABITy,
4409 llvm::GlobalValue::ExternalLinkage,
4411 "_objc_empty_vtable");
4413 assert(ID->getClassInterface() &&
4414 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
4415 // FIXME: Is this correct (that meta class size is never computed)?
4416 uint32_t InstanceStart =
4417 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
4418 uint32_t InstanceSize = InstanceStart;
4419 uint32_t flags = CLS_META;
4420 std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
4421 std::string ObjCClassName(getClassSymbolPrefix());
4423 llvm::GlobalVariable *SuperClassGV, *IsAGV;
4425 bool classIsHidden =
4426 CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
4428 flags |= OBJC2_CLS_HIDDEN;
4429 if (!ID->getClassInterface()->getSuperClass()) {
4432 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
4433 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
4435 // Has a root. Current class is not a root.
4436 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4437 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4439 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
4440 // work on super class metadata symbol.
4441 std::string SuperClassName =
4442 ObjCMetaClassName + ID->getClassInterface()->getSuperClass()->getNameAsString();
4443 SuperClassGV = GetClassGlobal(SuperClassName);
4444 if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
4445 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4447 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
4450 std::string TClassName = ObjCMetaClassName + ClassName;
4451 llvm::GlobalVariable *MetaTClass =
4452 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
4454 DefinedMetaClasses.push_back(MetaTClass);
4456 // Metadata for the class
4459 flags |= OBJC2_CLS_HIDDEN;
4461 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
4462 flags |= CLS_EXCEPTION;
4464 if (!ID->getClassInterface()->getSuperClass()) {
4468 // Has a root. Current class is not a root.
4469 std::string RootClassName =
4470 ID->getClassInterface()->getSuperClass()->getNameAsString();
4471 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
4472 if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
4473 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4475 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
4476 CLASS_RO_GV = BuildClassRoTInitializer(flags,
4481 TClassName = ObjCClassName + ClassName;
4482 llvm::GlobalVariable *ClassMD =
4483 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
4485 DefinedClasses.push_back(ClassMD);
4487 // Determine if this class is also "non-lazy".
4488 if (ImplementationIsNonLazy(ID))
4489 DefinedNonLazyClasses.push_back(ClassMD);
4491 // Force the definition of the EHType if necessary.
4492 if (flags & CLS_EXCEPTION)
4493 GetInterfaceEHType(ID->getClassInterface(), true);
4496 /// GenerateProtocolRef - This routine is called to generate code for
4497 /// a protocol reference expression; as in:
4499 /// @protocol(Proto1);
4501 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
4502 /// which will hold address of the protocol meta-data.
4504 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
4505 const ObjCProtocolDecl *PD) {
4507 // This routine is called for @protocol only. So, we must build definition
4508 // of protocol's meta-data (not a reference to it!)
4510 llvm::Constant *Init =
4511 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
4512 ObjCTypes.ExternalProtocolPtrTy);
4514 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
4515 ProtocolName += PD->getNameAsCString();
4517 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
4519 return Builder.CreateLoad(PTGV, "tmp");
4520 PTGV = new llvm::GlobalVariable(
4522 Init->getType(), false,
4523 llvm::GlobalValue::WeakAnyLinkage,
4526 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
4527 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4528 CGM.AddUsedGlobal(PTGV);
4529 return Builder.CreateLoad(PTGV, "tmp");
4532 /// GenerateCategory - Build metadata for a category implementation.
4533 /// struct _category_t {
4534 /// const char * const name;
4535 /// struct _class_t *const cls;
4536 /// const struct _method_list_t * const instance_methods;
4537 /// const struct _method_list_t * const class_methods;
4538 /// const struct _protocol_list_t * const protocols;
4539 /// const struct _prop_list_t * const properties;
4542 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
4543 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
4544 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
4545 std::string ExtCatName(Prefix + Interface->getNameAsString()+
4546 "_$_" + OCD->getNameAsString());
4547 std::string ExtClassName(getClassSymbolPrefix() +
4548 Interface->getNameAsString());
4550 std::vector<llvm::Constant*> Values(6);
4551 Values[0] = GetClassName(OCD->getIdentifier());
4552 // meta-class entry symbol
4553 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
4554 if (Interface->hasAttr<WeakImportAttr>())
4555 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4557 Values[1] = ClassGV;
4558 std::vector<llvm::Constant*> Methods;
4559 std::string MethodListName(Prefix);
4560 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
4561 "_$_" + OCD->getNameAsString();
4563 for (ObjCCategoryImplDecl::instmeth_iterator
4564 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
4565 // Instance methods should always be defined.
4566 Methods.push_back(GetMethodConstant(*i));
4569 Values[2] = EmitMethodList(MethodListName,
4570 "__DATA, __objc_const",
4573 MethodListName = Prefix;
4574 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
4575 OCD->getNameAsString();
4577 for (ObjCCategoryImplDecl::classmeth_iterator
4578 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
4579 // Class methods should always be defined.
4580 Methods.push_back(GetMethodConstant(*i));
4583 Values[3] = EmitMethodList(MethodListName,
4584 "__DATA, __objc_const",
4586 const ObjCCategoryDecl *Category =
4587 Interface->FindCategoryDeclaration(OCD->getIdentifier());
4589 llvm::SmallString<256> ExtName;
4590 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
4592 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
4593 + Interface->getName() + "_$_"
4594 + Category->getName(),
4595 Category->protocol_begin(),
4596 Category->protocol_end());
4597 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
4598 OCD, Category, ObjCTypes);
4600 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
4601 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
4604 llvm::Constant *Init =
4605 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
4607 llvm::GlobalVariable *GCATV
4608 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
4610 llvm::GlobalValue::InternalLinkage,
4613 GCATV->setAlignment(
4614 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.CategorynfABITy));
4615 GCATV->setSection("__DATA, __objc_const");
4616 CGM.AddUsedGlobal(GCATV);
4617 DefinedCategories.push_back(GCATV);
4619 // Determine if this category is also "non-lazy".
4620 if (ImplementationIsNonLazy(OCD))
4621 DefinedNonLazyCategories.push_back(GCATV);
4624 /// GetMethodConstant - Return a struct objc_method constant for the
4625 /// given method if it has been defined. The result is null if the
4626 /// method has not been defined. The return value has type MethodPtrTy.
4627 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
4628 const ObjCMethodDecl *MD) {
4629 // FIXME: Use DenseMap::lookup
4630 llvm::Function *Fn = MethodDefinitions[MD];
4634 std::vector<llvm::Constant*> Method(3);
4636 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
4637 ObjCTypes.SelectorPtrTy);
4638 Method[1] = GetMethodVarType(MD);
4639 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
4640 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
4643 /// EmitMethodList - Build meta-data for method declarations
4644 /// struct _method_list_t {
4645 /// uint32_t entsize; // sizeof(struct _objc_method)
4646 /// uint32_t method_count;
4647 /// struct _objc_method method_list[method_count];
4650 llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name,
4651 const char *Section,
4652 const ConstantVector &Methods) {
4653 // Return null for empty list.
4654 if (Methods.empty())
4655 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
4657 std::vector<llvm::Constant*> Values(3);
4658 // sizeof(struct _objc_method)
4659 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
4660 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
4662 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
4663 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
4665 Values[2] = llvm::ConstantArray::get(AT, Methods);
4666 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
4668 llvm::GlobalVariable *GV =
4669 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4670 llvm::GlobalValue::InternalLinkage,
4674 CGM.getTargetData().getPrefTypeAlignment(Init->getType()));
4675 GV->setSection(Section);
4676 CGM.AddUsedGlobal(GV);
4677 return llvm::ConstantExpr::getBitCast(GV,
4678 ObjCTypes.MethodListnfABIPtrTy);
4681 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
4683 llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(
4684 const ObjCInterfaceDecl *ID,
4685 const ObjCIvarDecl *Ivar) {
4686 // FIXME: We shouldn't need to do this lookup.
4688 const ObjCInterfaceDecl *Container =
4689 FindIvarInterface(CGM.getContext(), ID, Ivar, Index);
4690 assert(Container && "Unable to find ivar container!");
4691 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
4692 '.' + Ivar->getNameAsString();
4693 llvm::GlobalVariable *IvarOffsetGV =
4694 CGM.getModule().getGlobalVariable(Name);
4697 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
4699 llvm::GlobalValue::ExternalLinkage,
4702 return IvarOffsetGV;
4705 llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
4706 const ObjCInterfaceDecl *ID,
4707 const ObjCIvarDecl *Ivar,
4708 unsigned long int Offset) {
4709 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
4710 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
4712 IvarOffsetGV->setAlignment(
4713 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy));
4715 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
4716 // well (i.e., in ObjCIvarOffsetVariable).
4717 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
4718 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
4719 CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden)
4720 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4722 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
4723 IvarOffsetGV->setSection("__DATA, __objc_const");
4724 return IvarOffsetGV;
4727 /// EmitIvarList - Emit the ivar list for the given
4728 /// implementation. The return value has type
4729 /// IvarListnfABIPtrTy.
4730 /// struct _ivar_t {
4731 /// unsigned long int *offset; // pointer to ivar offset location
4734 /// uint32_t alignment;
4737 /// struct _ivar_list_t {
4738 /// uint32 entsize; // sizeof(struct _ivar_t)
4740 /// struct _iver_t list[count];
4744 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
4745 const ObjCImplementationDecl *ID) {
4747 std::vector<llvm::Constant*> Ivars, Ivar(5);
4749 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4750 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
4752 // FIXME. Consolidate this with similar code in GenerateClass.
4754 // Collect declared and synthesized ivars in a small vector.
4755 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
4756 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
4758 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
4759 ObjCIvarDecl *IVD = OIvars[i];
4760 // Ignore unnamed bit-fields.
4761 if (!IVD->getDeclName())
4763 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
4764 ComputeIvarBaseOffset(CGM, ID, IVD));
4765 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
4766 Ivar[2] = GetMethodVarType(IVD);
4767 const llvm::Type *FieldTy =
4768 CGM.getTypes().ConvertTypeForMem(IVD->getType());
4769 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
4770 unsigned Align = CGM.getContext().getPreferredTypeAlign(
4771 IVD->getType().getTypePtr()) >> 3;
4772 Align = llvm::Log2_32(Align);
4773 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
4774 // NOTE. Size of a bitfield does not match gcc's, because of the
4775 // way bitfields are treated special in each. But I am told that
4776 // 'size' for bitfield ivars is ignored by the runtime so it does
4777 // not matter. If it matters, there is enough info to get the
4779 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
4780 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
4782 // Return null for empty list.
4784 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
4785 std::vector<llvm::Constant*> Values(3);
4786 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
4787 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
4788 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
4789 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
4791 Values[2] = llvm::ConstantArray::get(AT, Ivars);
4792 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
4793 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
4794 llvm::GlobalVariable *GV =
4795 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4796 llvm::GlobalValue::InternalLinkage,
4798 Prefix + OID->getName());
4800 CGM.getTargetData().getPrefTypeAlignment(Init->getType()));
4801 GV->setSection("__DATA, __objc_const");
4803 CGM.AddUsedGlobal(GV);
4804 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
4807 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
4808 const ObjCProtocolDecl *PD) {
4809 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
4812 // We use the initializer as a marker of whether this is a forward
4813 // reference or not. At module finalization we add the empty
4814 // contents for protocols which were referenced but never defined.
4816 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
4817 llvm::GlobalValue::ExternalLinkage,
4819 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
4820 Entry->setSection("__DATA,__datacoal_nt,coalesced");
4826 /// GetOrEmitProtocol - Generate the protocol meta-data:
4828 /// struct _protocol_t {
4830 /// const char * const protocol_name;
4831 /// const struct _protocol_list_t * protocol_list; // super protocols
4832 /// const struct method_list_t * const instance_methods;
4833 /// const struct method_list_t * const class_methods;
4834 /// const struct method_list_t *optionalInstanceMethods;
4835 /// const struct method_list_t *optionalClassMethods;
4836 /// const struct _prop_list_t * properties;
4837 /// const uint32_t size; // sizeof(struct _protocol_t)
4838 /// const uint32_t flags; // = 0
4843 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
4844 const ObjCProtocolDecl *PD) {
4845 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
4847 // Early exit if a defining object has already been generated.
4848 if (Entry && Entry->hasInitializer())
4851 // Construct method lists.
4852 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
4853 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
4854 for (ObjCProtocolDecl::instmeth_iterator
4855 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
4856 ObjCMethodDecl *MD = *i;
4857 llvm::Constant *C = GetMethodDescriptionConstant(MD);
4858 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
4859 OptInstanceMethods.push_back(C);
4861 InstanceMethods.push_back(C);
4865 for (ObjCProtocolDecl::classmeth_iterator
4866 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
4867 ObjCMethodDecl *MD = *i;
4868 llvm::Constant *C = GetMethodDescriptionConstant(MD);
4869 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
4870 OptClassMethods.push_back(C);
4872 ClassMethods.push_back(C);
4876 std::vector<llvm::Constant*> Values(10);
4878 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
4879 Values[1] = GetClassName(PD->getIdentifier());
4880 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
4881 PD->protocol_begin(),
4882 PD->protocol_end());
4884 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
4886 "__DATA, __objc_const",
4888 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
4890 "__DATA, __objc_const",
4892 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
4894 "__DATA, __objc_const",
4895 OptInstanceMethods);
4896 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
4898 "__DATA, __objc_const",
4900 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
4903 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
4904 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
4905 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
4906 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
4910 // Already created, fix the linkage and update the initializer.
4911 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
4912 Entry->setInitializer(Init);
4915 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
4916 false, llvm::GlobalValue::WeakAnyLinkage, Init,
4917 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
4918 Entry->setAlignment(
4919 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABITy));
4920 Entry->setSection("__DATA,__datacoal_nt,coalesced");
4922 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
4923 CGM.AddUsedGlobal(Entry);
4925 // Use this protocol meta-data to build protocol list table in section
4926 // __DATA, __objc_protolist
4927 llvm::GlobalVariable *PTGV =
4928 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
4929 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
4930 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
4932 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
4933 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
4934 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4935 CGM.AddUsedGlobal(PTGV);
4939 /// EmitProtocolList - Generate protocol list meta-data:
4941 /// struct _protocol_list_t {
4942 /// long protocol_count; // Note, this is 32/64 bit
4943 /// struct _protocol_t[protocol_count];
4948 CGObjCNonFragileABIMac::EmitProtocolList(llvm::Twine Name,
4949 ObjCProtocolDecl::protocol_iterator begin,
4950 ObjCProtocolDecl::protocol_iterator end) {
4951 std::vector<llvm::Constant*> ProtocolRefs;
4953 // Just return null for empty protocol lists
4955 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
4957 // FIXME: We shouldn't need to do this lookup here, should we?
4958 llvm::SmallString<256> TmpName;
4959 Name.toVector(TmpName);
4960 llvm::GlobalVariable *GV =
4961 CGM.getModule().getGlobalVariable(TmpName.str(), true);
4963 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
4965 for (; begin != end; ++begin)
4966 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
4968 // This list is null terminated.
4969 ProtocolRefs.push_back(llvm::Constant::getNullValue(
4970 ObjCTypes.ProtocolnfABIPtrTy));
4972 std::vector<llvm::Constant*> Values(2);
4974 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
4976 llvm::ConstantArray::get(
4977 llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
4978 ProtocolRefs.size()),
4981 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
4982 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4983 llvm::GlobalValue::InternalLinkage,
4986 GV->setSection("__DATA, __objc_const");
4988 CGM.getTargetData().getPrefTypeAlignment(Init->getType()));
4989 CGM.AddUsedGlobal(GV);
4990 return llvm::ConstantExpr::getBitCast(GV,
4991 ObjCTypes.ProtocolListnfABIPtrTy);
4994 /// GetMethodDescriptionConstant - This routine build following meta-data:
4995 /// struct _objc_method {
4997 /// char *method_type;
5002 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
5003 std::vector<llvm::Constant*> Desc(3);
5005 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5006 ObjCTypes.SelectorPtrTy);
5007 Desc[1] = GetMethodVarType(MD);
5008 // Protocol methods have no implementation. So, this entry is always NULL.
5009 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5010 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
5013 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
5014 /// This code gen. amounts to generating code for:
5016 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
5019 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5020 CodeGen::CodeGenFunction &CGF,
5022 llvm::Value *BaseValue,
5023 const ObjCIvarDecl *Ivar,
5024 unsigned CVRQualifiers) {
5025 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
5026 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5027 EmitIvarOffset(CGF, ID, Ivar));
5030 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
5031 CodeGen::CodeGenFunction &CGF,
5032 const ObjCInterfaceDecl *Interface,
5033 const ObjCIvarDecl *Ivar) {
5034 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5037 CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
5038 CodeGen::CodeGenFunction &CGF,
5039 QualType ResultType,
5041 llvm::Value *Receiver,
5044 const CallArgList &CallArgs) {
5045 // FIXME. Even though IsSuper is passes. This function doese not handle calls
5046 // to 'super' receivers.
5047 CodeGenTypes &Types = CGM.getTypes();
5048 llvm::Value *Arg0 = Receiver;
5050 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
5052 // Find the message function name.
5053 // FIXME. This is too much work to get the ABI-specific result type needed to
5054 // find the message name.
5055 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType,
5056 llvm::SmallVector<QualType, 16>());
5057 llvm::Constant *Fn = 0;
5058 std::string Name("\01l_");
5059 if (CGM.ReturnTypeUsesSret(FnInfo)) {
5061 // unlike what is documented. gcc never generates this API!!
5062 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) {
5063 Fn = ObjCTypes.getMessageSendIdStretFixupFn();
5064 // FIXME. Is there a better way of getting these names.
5065 // They are available in RuntimeFunctions vector pair.
5066 Name += "objc_msgSendId_stret_fixup";
5070 Fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5071 Name += "objc_msgSendSuper2_stret_fixup";
5073 Fn = ObjCTypes.getMessageSendStretFixupFn();
5074 Name += "objc_msgSend_stret_fixup";
5076 } else if (!IsSuper && ResultType->isFloatingType()) {
5077 if (ResultType->isSpecificBuiltinType(BuiltinType::LongDouble)) {
5078 Fn = ObjCTypes.getMessageSendFpretFixupFn();
5079 Name += "objc_msgSend_fpret_fixup";
5081 Fn = ObjCTypes.getMessageSendFixupFn();
5082 Name += "objc_msgSend_fixup";
5086 // unlike what is documented. gcc never generates this API!!
5087 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) {
5088 Fn = ObjCTypes.getMessageSendIdFixupFn();
5089 Name += "objc_msgSendId_fixup";
5093 Fn = ObjCTypes.getMessageSendSuper2FixupFn();
5094 Name += "objc_msgSendSuper2_fixup";
5096 Fn = ObjCTypes.getMessageSendFixupFn();
5097 Name += "objc_msgSend_fixup";
5100 assert(Fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5102 std::string SelName(Sel.getAsString());
5103 // Replace all ':' in selector name with '_' ouch!
5104 for (unsigned i = 0; i < SelName.size(); i++)
5105 if (SelName[i] == ':')
5108 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
5110 // Build message ref table entry.
5111 std::vector<llvm::Constant*> Values(2);
5113 Values[1] = GetMethodVarName(Sel);
5114 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
5115 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5116 llvm::GlobalValue::WeakAnyLinkage,
5119 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5120 GV->setAlignment(16);
5121 GV->setSection("__DATA, __objc_msgrefs, coalesced");
5123 llvm::Value *Arg1 = CGF.Builder.CreateBitCast(GV, ObjCTypes.MessageRefPtrTy);
5125 CallArgList ActualArgs;
5126 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
5127 ActualArgs.push_back(std::make_pair(RValue::get(Arg1),
5128 ObjCTypes.MessageRefCPtrTy));
5129 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
5130 const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs);
5131 llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0);
5132 Callee = CGF.Builder.CreateLoad(Callee);
5133 const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
5134 Callee = CGF.Builder.CreateBitCast(Callee,
5135 llvm::PointerType::getUnqual(FTy));
5136 return CGF.EmitCall(FnInfo1, Callee, ActualArgs);
5139 /// Generate code for a message send expression in the nonfragile abi.
5141 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5142 QualType ResultType,
5144 llvm::Value *Receiver,
5145 bool IsClassMessage,
5146 const CallArgList &CallArgs,
5147 const ObjCMethodDecl *Method) {
5148 return LegacyDispatchedSelector(Sel)
5149 ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
5150 Receiver, CGF.getContext().getObjCIdType(),
5151 false, CallArgs, Method, ObjCTypes)
5152 : EmitMessageSend(CGF, ResultType, Sel,
5153 Receiver, CGF.getContext().getObjCIdType(),
5157 llvm::GlobalVariable *
5158 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
5159 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
5162 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
5163 false, llvm::GlobalValue::ExternalLinkage,
5170 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5171 const ObjCInterfaceDecl *ID) {
5172 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
5175 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5176 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5178 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5179 false, llvm::GlobalValue::InternalLinkage,
5181 "\01L_OBJC_CLASSLIST_REFERENCES_$_");
5182 Entry->setAlignment(
5183 CGM.getTargetData().getPrefTypeAlignment(
5184 ObjCTypes.ClassnfABIPtrTy));
5185 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5186 CGM.AddUsedGlobal(Entry);
5189 return Builder.CreateLoad(Entry, "tmp");
5193 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
5194 const ObjCInterfaceDecl *ID) {
5195 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
5198 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5199 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5201 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5202 false, llvm::GlobalValue::InternalLinkage,
5204 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5205 Entry->setAlignment(
5206 CGM.getTargetData().getPrefTypeAlignment(
5207 ObjCTypes.ClassnfABIPtrTy));
5208 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5209 CGM.AddUsedGlobal(Entry);
5212 return Builder.CreateLoad(Entry, "tmp");
5215 /// EmitMetaClassRef - Return a Value * of the address of _class_t
5218 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
5219 const ObjCInterfaceDecl *ID) {
5220 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
5222 return Builder.CreateLoad(Entry, "tmp");
5224 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
5225 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
5227 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
5228 llvm::GlobalValue::InternalLinkage,
5230 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5231 Entry->setAlignment(
5232 CGM.getTargetData().getPrefTypeAlignment(
5233 ObjCTypes.ClassnfABIPtrTy));
5235 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5236 CGM.AddUsedGlobal(Entry);
5238 return Builder.CreateLoad(Entry, "tmp");
5241 /// GetClass - Return a reference to the class for the given interface
5243 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
5244 const ObjCInterfaceDecl *ID) {
5245 if (ID->hasAttr<WeakImportAttr>()) {
5246 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5247 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5248 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5251 return EmitClassRef(Builder, ID);
5254 /// Generates a message send where the super is the receiver. This is
5255 /// a message send to self with special delivery semantics indicating
5256 /// which class's method should be called.
5258 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
5259 QualType ResultType,
5261 const ObjCInterfaceDecl *Class,
5262 bool isCategoryImpl,
5263 llvm::Value *Receiver,
5264 bool IsClassMessage,
5265 const CodeGen::CallArgList &CallArgs,
5266 const ObjCMethodDecl *Method) {
5268 // Create and init a super structure; this is a (receiver, class)
5269 // pair we will pass to objc_msgSendSuper.
5270 llvm::Value *ObjCSuper =
5271 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
5273 llvm::Value *ReceiverAsObject =
5274 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
5275 CGF.Builder.CreateStore(ReceiverAsObject,
5276 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
5278 // If this is a class message the metaclass is passed as the target.
5279 llvm::Value *Target;
5280 if (IsClassMessage) {
5281 if (isCategoryImpl) {
5282 // Message sent to "super' in a class method defined in
5283 // a category implementation.
5284 Target = EmitClassRef(CGF.Builder, Class);
5285 Target = CGF.Builder.CreateStructGEP(Target, 0);
5286 Target = CGF.Builder.CreateLoad(Target);
5288 Target = EmitMetaClassRef(CGF.Builder, Class);
5290 Target = EmitSuperClassRef(CGF.Builder, Class);
5292 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
5294 const llvm::Type *ClassTy =
5295 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
5296 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
5297 CGF.Builder.CreateStore(Target,
5298 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
5300 return (LegacyDispatchedSelector(Sel))
5301 ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel),
5302 ObjCSuper, ObjCTypes.SuperPtrCTy,
5303 true, CallArgs, Method, ObjCTypes)
5304 : EmitMessageSend(CGF, ResultType, Sel,
5305 ObjCSuper, ObjCTypes.SuperPtrCTy,
5309 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
5311 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5314 llvm::Constant *Casted =
5315 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
5316 ObjCTypes.SelectorPtrTy);
5318 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
5319 llvm::GlobalValue::InternalLinkage,
5320 Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
5321 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5322 CGM.AddUsedGlobal(Entry);
5325 return Builder.CreateLoad(Entry, "tmp");
5327 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5328 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
5330 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5333 llvm::Value *ivarOffset) {
5334 const llvm::Type * SrcTy = src->getType();
5335 if (!isa<llvm::PointerType>(SrcTy)) {
5336 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5337 assert(Size <= 8 && "does not support size > 8");
5338 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5339 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5340 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5342 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5343 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5344 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
5345 src, dst, ivarOffset);
5349 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5350 /// objc_assign_strongCast (id src, id *dst)
5352 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
5353 CodeGen::CodeGenFunction &CGF,
5354 llvm::Value *src, llvm::Value *dst) {
5355 const llvm::Type * SrcTy = src->getType();
5356 if (!isa<llvm::PointerType>(SrcTy)) {
5357 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5358 assert(Size <= 8 && "does not support size > 8");
5359 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5360 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5361 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5363 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5364 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5365 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
5366 src, dst, "weakassign");
5370 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
5371 CodeGen::CodeGenFunction &CGF,
5372 llvm::Value *DestPtr,
5373 llvm::Value *SrcPtr,
5375 // Get size info for this aggregate.
5376 std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
5377 unsigned long size = TypeInfo.first/8;
5378 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
5379 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
5380 llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
5381 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
5382 DestPtr, SrcPtr, N);
5386 /// EmitObjCWeakRead - Code gen for loading value of a __weak
5387 /// object: objc_read_weak (id *src)
5389 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
5390 CodeGen::CodeGenFunction &CGF,
5391 llvm::Value *AddrWeakObj) {
5392 const llvm::Type* DestTy =
5393 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
5394 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
5395 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
5396 AddrWeakObj, "weakread");
5397 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
5401 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5402 /// objc_assign_weak (id src, id *dst)
5404 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5405 llvm::Value *src, llvm::Value *dst) {
5406 const llvm::Type * SrcTy = src->getType();
5407 if (!isa<llvm::PointerType>(SrcTy)) {
5408 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5409 assert(Size <= 8 && "does not support size > 8");
5410 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5411 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5412 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5414 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5415 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5416 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
5417 src, dst, "weakassign");
5421 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5422 /// objc_assign_global (id src, id *dst)
5424 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5425 llvm::Value *src, llvm::Value *dst) {
5426 const llvm::Type * SrcTy = src->getType();
5427 if (!isa<llvm::PointerType>(SrcTy)) {
5428 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5429 assert(Size <= 8 && "does not support size > 8");
5430 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5431 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5432 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5434 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5435 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5436 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
5437 src, dst, "globalassign");
5442 CGObjCNonFragileABIMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5444 bool isTry = isa<ObjCAtTryStmt>(S);
5445 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
5446 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
5447 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
5448 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
5449 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
5450 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
5452 // For @synchronized, call objc_sync_enter(sync.expr). The
5453 // evaluation of the expression must occur before we enter the
5454 // @synchronized. We can safely avoid a temp here because jumps into
5455 // @synchronized are illegal & this will dominate uses.
5456 llvm::Value *SyncArg = 0;
5459 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
5460 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5461 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
5464 // Push an EH context entry, used for handling rethrows and jumps
5466 CGF.PushCleanupBlock(FinallyBlock);
5468 CGF.setInvokeDest(TryHandler);
5470 CGF.EmitBlock(TryBlock);
5471 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
5472 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
5473 CGF.EmitBranchThroughCleanup(FinallyEnd);
5475 // Emit the exception handler.
5477 CGF.EmitBlock(TryHandler);
5479 llvm::Value *llvm_eh_exception =
5480 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
5481 llvm::Value *llvm_eh_selector =
5482 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
5483 llvm::Value *llvm_eh_typeid_for =
5484 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
5485 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
5486 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
5488 llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
5489 SelectorArgs.push_back(Exc);
5490 SelectorArgs.push_back(ObjCTypes.getEHPersonalityPtr());
5492 // Construct the lists of (type, catch body) to handle.
5493 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers;
5494 bool HasCatchAll = false;
5496 if (const ObjCAtCatchStmt* CatchStmt =
5497 cast<ObjCAtTryStmt>(S).getCatchStmts()) {
5498 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
5499 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
5500 Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody()));
5502 // catch(...) always matches.
5504 // Use i8* null here to signal this is a catch all, not a cleanup.
5505 llvm::Value *Null = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5506 SelectorArgs.push_back(Null);
5511 if (CatchDecl->getType()->isObjCIdType() ||
5512 CatchDecl->getType()->isObjCQualifiedIdType()) {
5513 llvm::Value *IDEHType =
5514 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
5517 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
5519 llvm::GlobalValue::ExternalLinkage,
5520 0, "OBJC_EHTYPE_id");
5521 SelectorArgs.push_back(IDEHType);
5523 // All other types should be Objective-C interface pointer types.
5524 const ObjCObjectPointerType *PT =
5525 CatchDecl->getType()->getAs<ObjCObjectPointerType>();
5526 assert(PT && "Invalid @catch type.");
5527 const ObjCInterfaceType *IT = PT->getInterfaceType();
5528 assert(IT && "Invalid @catch type.");
5529 llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false);
5530 SelectorArgs.push_back(EHType);
5536 // We use a cleanup unless there was already a catch all.
5538 // Even though this is a cleanup, treat it as a catch all to avoid the C++
5539 // personality behavior of terminating the process if only cleanups are
5540 // found in the exception handling stack.
5541 SelectorArgs.push_back(llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy));
5542 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
5545 llvm::Value *Selector =
5546 CGF.Builder.CreateCall(llvm_eh_selector,
5547 SelectorArgs.begin(), SelectorArgs.end(),
5549 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
5550 const ParmVarDecl *CatchParam = Handlers[i].first;
5551 const Stmt *CatchBody = Handlers[i].second;
5553 llvm::BasicBlock *Next = 0;
5555 // The last handler always matches.
5557 assert(CatchParam && "Only last handler can be a catch all.");
5559 llvm::BasicBlock *Match = CGF.createBasicBlock("match");
5560 Next = CGF.createBasicBlock("catch.next");
5562 CGF.Builder.CreateCall(llvm_eh_typeid_for,
5563 CGF.Builder.CreateBitCast(SelectorArgs[i+2],
5564 ObjCTypes.Int8PtrTy));
5565 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(Selector, Id),
5568 CGF.EmitBlock(Match);
5572 llvm::BasicBlock *MatchEnd = CGF.createBasicBlock("match.end");
5573 llvm::BasicBlock *MatchHandler = CGF.createBasicBlock("match.handler");
5575 // Cleanups must call objc_end_catch.
5577 // FIXME: It seems incorrect for objc_begin_catch to be inside this
5578 // context, but this matches gcc.
5579 CGF.PushCleanupBlock(MatchEnd);
5580 CGF.setInvokeDest(MatchHandler);
5582 llvm::Value *ExcObject =
5583 CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), Exc);
5585 // Bind the catch parameter if it exists.
5588 CGF.Builder.CreateBitCast(ExcObject,
5589 CGF.ConvertType(CatchParam->getType()));
5590 // CatchParam is a ParmVarDecl because of the grammar
5591 // construction used to handle this, but for codegen purposes
5592 // we treat this as a local decl.
5593 CGF.EmitLocalBlockVarDecl(*CatchParam);
5594 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
5597 CGF.ObjCEHValueStack.push_back(ExcObject);
5598 CGF.EmitStmt(CatchBody);
5599 CGF.ObjCEHValueStack.pop_back();
5601 CGF.EmitBranchThroughCleanup(FinallyEnd);
5603 CGF.EmitBlock(MatchHandler);
5605 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
5606 // We are required to emit this call to satisfy LLVM, even
5607 // though we don't use the result.
5608 llvm::SmallVector<llvm::Value*, 8> Args;
5609 Args.push_back(Exc);
5610 Args.push_back(ObjCTypes.getEHPersonalityPtr());
5611 Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
5613 CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
5614 CGF.Builder.CreateStore(Exc, RethrowPtr);
5615 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5617 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
5619 CGF.EmitBlock(MatchEnd);
5621 // Unfortunately, we also have to generate another EH frame here
5622 // in case this throws.
5623 llvm::BasicBlock *MatchEndHandler =
5624 CGF.createBasicBlock("match.end.handler");
5625 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
5626 CGF.Builder.CreateInvoke(ObjCTypes.getObjCEndCatchFn(),
5627 Cont, MatchEndHandler,
5628 Args.begin(), Args.begin());
5630 CGF.EmitBlock(Cont);
5631 if (Info.SwitchBlock)
5632 CGF.EmitBlock(Info.SwitchBlock);
5634 CGF.EmitBlock(Info.EndBlock);
5636 CGF.EmitBlock(MatchEndHandler);
5637 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
5638 // We are required to emit this call to satisfy LLVM, even
5639 // though we don't use the result.
5641 Args.push_back(Exc);
5642 Args.push_back(ObjCTypes.getEHPersonalityPtr());
5643 Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
5645 CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
5646 CGF.Builder.CreateStore(Exc, RethrowPtr);
5647 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5650 CGF.EmitBlock(Next);
5652 assert(!Next && "catchup should be last handler.");
5654 CGF.Builder.CreateStore(Exc, RethrowPtr);
5655 CGF.EmitBranchThroughCleanup(FinallyRethrow);
5659 // Pop the cleanup entry, the @finally is outside this cleanup
5661 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
5662 CGF.setInvokeDest(PrevLandingPad);
5664 CGF.EmitBlock(FinallyBlock);
5667 if (const ObjCAtFinallyStmt* FinallyStmt =
5668 cast<ObjCAtTryStmt>(S).getFinallyStmt())
5669 CGF.EmitStmt(FinallyStmt->getFinallyBody());
5671 // Emit 'objc_sync_exit(expr)' as finally's sole statement for
5673 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg);
5676 if (Info.SwitchBlock)
5677 CGF.EmitBlock(Info.SwitchBlock);
5679 CGF.EmitBlock(Info.EndBlock);
5681 // Branch around the rethrow code.
5682 CGF.EmitBranch(FinallyEnd);
5684 CGF.EmitBlock(FinallyRethrow);
5685 CGF.Builder.CreateCall(ObjCTypes.getUnwindResumeOrRethrowFn(),
5686 CGF.Builder.CreateLoad(RethrowPtr));
5687 CGF.Builder.CreateUnreachable();
5689 CGF.EmitBlock(FinallyEnd);
5692 /// EmitThrowStmt - Generate code for a throw statement.
5693 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5694 const ObjCAtThrowStmt &S) {
5695 llvm::Value *Exception;
5696 if (const Expr *ThrowExpr = S.getThrowExpr()) {
5697 Exception = CGF.EmitScalarExpr(ThrowExpr);
5699 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
5700 "Unexpected rethrow outside @catch block.");
5701 Exception = CGF.ObjCEHValueStack.back();
5704 llvm::Value *ExceptionAsObject =
5705 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
5706 llvm::BasicBlock *InvokeDest = CGF.getInvokeDest();
5708 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
5709 CGF.Builder.CreateInvoke(ObjCTypes.getExceptionThrowFn(),
5711 &ExceptionAsObject, &ExceptionAsObject + 1);
5712 CGF.EmitBlock(Cont);
5714 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
5715 CGF.Builder.CreateUnreachable();
5717 // Clear the insertion point to indicate we are in unreachable code.
5718 CGF.Builder.ClearInsertionPoint();
5722 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
5723 bool ForDefinition) {
5724 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
5726 // If we don't need a definition, return the entry if found or check
5727 // if we use an external reference.
5728 if (!ForDefinition) {
5732 // If this type (or a super class) has the __objc_exception__
5733 // attribute, emit an external reference.
5734 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
5736 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
5737 llvm::GlobalValue::ExternalLinkage,
5740 ID->getIdentifier()->getName()));
5743 // Otherwise we need to either make a new entry or fill in the
5745 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
5746 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5747 std::string VTableName = "objc_ehtype_vtable";
5748 llvm::GlobalVariable *VTableGV =
5749 CGM.getModule().getGlobalVariable(VTableName);
5751 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
5753 llvm::GlobalValue::ExternalLinkage,
5756 llvm::Value *VTableIdx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
5758 std::vector<llvm::Constant*> Values(3);
5759 Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1);
5760 Values[1] = GetClassName(ID->getIdentifier());
5761 Values[2] = GetClassGlobal(ClassName);
5762 llvm::Constant *Init =
5763 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
5766 Entry->setInitializer(Init);
5768 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
5769 llvm::GlobalValue::WeakAnyLinkage,
5772 ID->getIdentifier()->getName()));
5775 if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden)
5776 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5777 Entry->setAlignment(8);
5779 if (ForDefinition) {
5780 Entry->setSection("__DATA,__objc_const");
5781 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
5783 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5791 CodeGen::CGObjCRuntime *
5792 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
5793 return new CGObjCMac(CGM);
5796 CodeGen::CGObjCRuntime *
5797 CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) {
5798 return new CGObjCNonFragileABIMac(CGM);