clang API Documentation
00001 //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This provides Objective-C code generation targeting the Apple runtime. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "CGObjCRuntime.h" 00015 00016 #include "CGRecordLayout.h" 00017 #include "CodeGenModule.h" 00018 #include "CodeGenFunction.h" 00019 #include "CGBlocks.h" 00020 #include "CGCleanup.h" 00021 #include "clang/AST/ASTContext.h" 00022 #include "clang/AST/Decl.h" 00023 #include "clang/AST/DeclObjC.h" 00024 #include "clang/AST/RecordLayout.h" 00025 #include "clang/AST/StmtObjC.h" 00026 #include "clang/Basic/LangOptions.h" 00027 #include "clang/Frontend/CodeGenOptions.h" 00028 00029 #include "llvm/InlineAsm.h" 00030 #include "llvm/IntrinsicInst.h" 00031 #include "llvm/LLVMContext.h" 00032 #include "llvm/Module.h" 00033 #include "llvm/ADT/DenseSet.h" 00034 #include "llvm/ADT/SetVector.h" 00035 #include "llvm/ADT/SmallString.h" 00036 #include "llvm/ADT/SmallPtrSet.h" 00037 #include "llvm/Support/CallSite.h" 00038 #include "llvm/Support/raw_ostream.h" 00039 #include "llvm/Target/TargetData.h" 00040 #include <cstdio> 00041 00042 using namespace clang; 00043 using namespace CodeGen; 00044 00045 namespace { 00046 00047 // FIXME: We should find a nicer way to make the labels for metadata, string 00048 // concatenation is lame. 00049 00050 class ObjCCommonTypesHelper { 00051 protected: 00052 llvm::LLVMContext &VMContext; 00053 00054 private: 00055 // The types of these functions don't really matter because we 00056 // should always bitcast before calling them. 00057 00058 /// id objc_msgSend (id, SEL, ...) 00059 /// 00060 /// The default messenger, used for sends whose ABI is unchanged from 00061 /// the all-integer/pointer case. 00062 llvm::Constant *getMessageSendFn() const { 00063 // Add the non-lazy-bind attribute, since objc_msgSend is likely to 00064 // be called a lot. 00065 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 00066 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00067 params, true), 00068 "objc_msgSend", 00069 llvm::Attribute::NonLazyBind); 00070 } 00071 00072 /// void objc_msgSend_stret (id, SEL, ...) 00073 /// 00074 /// The messenger used when the return value is an aggregate returned 00075 /// by indirect reference in the first argument, and therefore the 00076 /// self and selector parameters are shifted over by one. 00077 llvm::Constant *getMessageSendStretFn() const { 00078 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 00079 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, 00080 params, true), 00081 "objc_msgSend_stret"); 00082 00083 } 00084 00085 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 00086 /// 00087 /// The messenger used when the return value is returned on the x87 00088 /// floating-point stack; without a special entrypoint, the nil case 00089 /// would be unbalanced. 00090 llvm::Constant *getMessageSendFpretFn() const { 00091 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 00092 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy, 00093 params, true), 00094 "objc_msgSend_fpret"); 00095 00096 } 00097 00098 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...) 00099 /// 00100 /// The messenger used when the return value is returned in two values on the 00101 /// x87 floating point stack; without a special entrypoint, the nil case 00102 /// would be unbalanced. Only used on 64-bit X86. 00103 llvm::Constant *getMessageSendFp2retFn() const { 00104 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 00105 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext); 00106 llvm::Type *resultType = 00107 llvm::StructType::get(longDoubleType, longDoubleType, NULL); 00108 00109 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType, 00110 params, true), 00111 "objc_msgSend_fp2ret"); 00112 } 00113 00114 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 00115 /// 00116 /// The messenger used for super calls, which have different dispatch 00117 /// semantics. The class passed is the superclass of the current 00118 /// class. 00119 llvm::Constant *getMessageSendSuperFn() const { 00120 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 00121 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00122 params, true), 00123 "objc_msgSendSuper"); 00124 } 00125 00126 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 00127 /// 00128 /// A slightly different messenger used for super calls. The class 00129 /// passed is the current class. 00130 llvm::Constant *getMessageSendSuperFn2() const { 00131 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 00132 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00133 params, true), 00134 "objc_msgSendSuper2"); 00135 } 00136 00137 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super, 00138 /// SEL op, ...) 00139 /// 00140 /// The messenger used for super calls which return an aggregate indirectly. 00141 llvm::Constant *getMessageSendSuperStretFn() const { 00142 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 00143 return CGM.CreateRuntimeFunction( 00144 llvm::FunctionType::get(CGM.VoidTy, params, true), 00145 "objc_msgSendSuper_stret"); 00146 } 00147 00148 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 00149 /// SEL op, ...) 00150 /// 00151 /// objc_msgSendSuper_stret with the super2 semantics. 00152 llvm::Constant *getMessageSendSuperStretFn2() const { 00153 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 00154 return CGM.CreateRuntimeFunction( 00155 llvm::FunctionType::get(CGM.VoidTy, params, true), 00156 "objc_msgSendSuper2_stret"); 00157 } 00158 00159 llvm::Constant *getMessageSendSuperFpretFn() const { 00160 // There is no objc_msgSendSuper_fpret? How can that work? 00161 return getMessageSendSuperFn(); 00162 } 00163 00164 llvm::Constant *getMessageSendSuperFpretFn2() const { 00165 // There is no objc_msgSendSuper_fpret? How can that work? 00166 return getMessageSendSuperFn2(); 00167 } 00168 00169 protected: 00170 CodeGen::CodeGenModule &CGM; 00171 00172 public: 00173 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 00174 llvm::Type *Int8PtrTy, *Int8PtrPtrTy; 00175 00176 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 00177 llvm::Type *ObjectPtrTy; 00178 00179 /// PtrObjectPtrTy - LLVM type for id * 00180 llvm::Type *PtrObjectPtrTy; 00181 00182 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 00183 llvm::Type *SelectorPtrTy; 00184 00185 private: 00186 /// ProtocolPtrTy - LLVM type for external protocol handles 00187 /// (typeof(Protocol)) 00188 llvm::Type *ExternalProtocolPtrTy; 00189 00190 public: 00191 llvm::Type *getExternalProtocolPtrTy() { 00192 if (!ExternalProtocolPtrTy) { 00193 // FIXME: It would be nice to unify this with the opaque type, so that the 00194 // IR comes out a bit cleaner. 00195 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00196 ASTContext &Ctx = CGM.getContext(); 00197 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 00198 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 00199 } 00200 00201 return ExternalProtocolPtrTy; 00202 } 00203 00204 // SuperCTy - clang type for struct objc_super. 00205 QualType SuperCTy; 00206 // SuperPtrCTy - clang type for struct objc_super *. 00207 QualType SuperPtrCTy; 00208 00209 /// SuperTy - LLVM type for struct objc_super. 00210 llvm::StructType *SuperTy; 00211 /// SuperPtrTy - LLVM type for struct objc_super *. 00212 llvm::Type *SuperPtrTy; 00213 00214 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 00215 /// in GCC parlance). 00216 llvm::StructType *PropertyTy; 00217 00218 /// PropertyListTy - LLVM type for struct objc_property_list 00219 /// (_prop_list_t in GCC parlance). 00220 llvm::StructType *PropertyListTy; 00221 /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 00222 llvm::Type *PropertyListPtrTy; 00223 00224 // MethodTy - LLVM type for struct objc_method. 00225 llvm::StructType *MethodTy; 00226 00227 /// CacheTy - LLVM type for struct objc_cache. 00228 llvm::Type *CacheTy; 00229 /// CachePtrTy - LLVM type for struct objc_cache *. 00230 llvm::Type *CachePtrTy; 00231 00232 llvm::Constant *getGetPropertyFn() { 00233 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00234 ASTContext &Ctx = CGM.getContext(); 00235 // id objc_getProperty (id, SEL, ptrdiff_t, bool) 00236 SmallVector<CanQualType,4> Params; 00237 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 00238 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 00239 Params.push_back(IdType); 00240 Params.push_back(SelType); 00241 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 00242 Params.push_back(Ctx.BoolTy); 00243 llvm::FunctionType *FTy = 00244 Types.GetFunctionType(Types.arrangeFunctionType(IdType, Params, 00245 FunctionType::ExtInfo(), 00246 RequiredArgs::All)); 00247 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 00248 } 00249 00250 llvm::Constant *getSetPropertyFn() { 00251 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00252 ASTContext &Ctx = CGM.getContext(); 00253 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 00254 SmallVector<CanQualType,6> Params; 00255 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 00256 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 00257 Params.push_back(IdType); 00258 Params.push_back(SelType); 00259 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 00260 Params.push_back(IdType); 00261 Params.push_back(Ctx.BoolTy); 00262 Params.push_back(Ctx.BoolTy); 00263 llvm::FunctionType *FTy = 00264 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params, 00265 FunctionType::ExtInfo(), 00266 RequiredArgs::All)); 00267 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 00268 } 00269 00270 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) { 00271 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00272 ASTContext &Ctx = CGM.getContext(); 00273 // void objc_setProperty_atomic(id self, SEL _cmd, 00274 // id newValue, ptrdiff_t offset); 00275 // void objc_setProperty_nonatomic(id self, SEL _cmd, 00276 // id newValue, ptrdiff_t offset); 00277 // void objc_setProperty_atomic_copy(id self, SEL _cmd, 00278 // id newValue, ptrdiff_t offset); 00279 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd, 00280 // id newValue, ptrdiff_t offset); 00281 00282 SmallVector<CanQualType,4> Params; 00283 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 00284 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 00285 Params.push_back(IdType); 00286 Params.push_back(SelType); 00287 Params.push_back(IdType); 00288 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 00289 llvm::FunctionType *FTy = 00290 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params, 00291 FunctionType::ExtInfo(), 00292 RequiredArgs::All)); 00293 const char *name; 00294 if (atomic && copy) 00295 name = "objc_setProperty_atomic_copy"; 00296 else if (atomic && !copy) 00297 name = "objc_setProperty_atomic"; 00298 else if (!atomic && copy) 00299 name = "objc_setProperty_nonatomic_copy"; 00300 else 00301 name = "objc_setProperty_nonatomic"; 00302 00303 return CGM.CreateRuntimeFunction(FTy, name); 00304 } 00305 00306 llvm::Constant *getCopyStructFn() { 00307 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00308 ASTContext &Ctx = CGM.getContext(); 00309 // void objc_copyStruct (void *, const void *, size_t, bool, bool) 00310 SmallVector<CanQualType,5> Params; 00311 Params.push_back(Ctx.VoidPtrTy); 00312 Params.push_back(Ctx.VoidPtrTy); 00313 Params.push_back(Ctx.LongTy); 00314 Params.push_back(Ctx.BoolTy); 00315 Params.push_back(Ctx.BoolTy); 00316 llvm::FunctionType *FTy = 00317 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params, 00318 FunctionType::ExtInfo(), 00319 RequiredArgs::All)); 00320 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); 00321 } 00322 00323 /// This routine declares and returns address of: 00324 /// void objc_copyCppObjectAtomic( 00325 /// void *dest, const void *src, 00326 /// void (*copyHelper) (void *dest, const void *source)); 00327 llvm::Constant *getCppAtomicObjectFunction() { 00328 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00329 ASTContext &Ctx = CGM.getContext(); 00330 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper); 00331 SmallVector<CanQualType,3> Params; 00332 Params.push_back(Ctx.VoidPtrTy); 00333 Params.push_back(Ctx.VoidPtrTy); 00334 Params.push_back(Ctx.VoidPtrTy); 00335 llvm::FunctionType *FTy = 00336 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params, 00337 FunctionType::ExtInfo(), 00338 RequiredArgs::All)); 00339 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic"); 00340 } 00341 00342 llvm::Constant *getEnumerationMutationFn() { 00343 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 00344 ASTContext &Ctx = CGM.getContext(); 00345 // void objc_enumerationMutation (id) 00346 SmallVector<CanQualType,1> Params; 00347 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); 00348 llvm::FunctionType *FTy = 00349 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params, 00350 FunctionType::ExtInfo(), 00351 RequiredArgs::All)); 00352 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 00353 } 00354 00355 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 00356 llvm::Constant *getGcReadWeakFn() { 00357 // id objc_read_weak (id *) 00358 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() }; 00359 llvm::FunctionType *FTy = 00360 llvm::FunctionType::get(ObjectPtrTy, args, false); 00361 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 00362 } 00363 00364 /// GcAssignWeakFn -- LLVM objc_assign_weak function. 00365 llvm::Constant *getGcAssignWeakFn() { 00366 // id objc_assign_weak (id, id *) 00367 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 00368 llvm::FunctionType *FTy = 00369 llvm::FunctionType::get(ObjectPtrTy, args, false); 00370 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 00371 } 00372 00373 /// GcAssignGlobalFn -- LLVM objc_assign_global function. 00374 llvm::Constant *getGcAssignGlobalFn() { 00375 // id objc_assign_global(id, id *) 00376 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 00377 llvm::FunctionType *FTy = 00378 llvm::FunctionType::get(ObjectPtrTy, args, false); 00379 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 00380 } 00381 00382 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function. 00383 llvm::Constant *getGcAssignThreadLocalFn() { 00384 // id objc_assign_threadlocal(id src, id * dest) 00385 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 00386 llvm::FunctionType *FTy = 00387 llvm::FunctionType::get(ObjectPtrTy, args, false); 00388 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal"); 00389 } 00390 00391 /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 00392 llvm::Constant *getGcAssignIvarFn() { 00393 // id objc_assign_ivar(id, id *, ptrdiff_t) 00394 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(), 00395 CGM.PtrDiffTy }; 00396 llvm::FunctionType *FTy = 00397 llvm::FunctionType::get(ObjectPtrTy, args, false); 00398 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 00399 } 00400 00401 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function. 00402 llvm::Constant *GcMemmoveCollectableFn() { 00403 // void *objc_memmove_collectable(void *dst, const void *src, size_t size) 00404 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy }; 00405 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false); 00406 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 00407 } 00408 00409 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 00410 llvm::Constant *getGcAssignStrongCastFn() { 00411 // id objc_assign_strongCast(id, id *) 00412 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 00413 llvm::FunctionType *FTy = 00414 llvm::FunctionType::get(ObjectPtrTy, args, false); 00415 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 00416 } 00417 00418 /// ExceptionThrowFn - LLVM objc_exception_throw function. 00419 llvm::Constant *getExceptionThrowFn() { 00420 // void objc_exception_throw(id) 00421 llvm::Type *args[] = { ObjectPtrTy }; 00422 llvm::FunctionType *FTy = 00423 llvm::FunctionType::get(CGM.VoidTy, args, false); 00424 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 00425 } 00426 00427 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function. 00428 llvm::Constant *getExceptionRethrowFn() { 00429 // void objc_exception_rethrow(void) 00430 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false); 00431 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow"); 00432 } 00433 00434 /// SyncEnterFn - LLVM object_sync_enter function. 00435 llvm::Constant *getSyncEnterFn() { 00436 // void objc_sync_enter (id) 00437 llvm::Type *args[] = { ObjectPtrTy }; 00438 llvm::FunctionType *FTy = 00439 llvm::FunctionType::get(CGM.VoidTy, args, false); 00440 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 00441 } 00442 00443 /// SyncExitFn - LLVM object_sync_exit function. 00444 llvm::Constant *getSyncExitFn() { 00445 // void objc_sync_exit (id) 00446 llvm::Type *args[] = { ObjectPtrTy }; 00447 llvm::FunctionType *FTy = 00448 llvm::FunctionType::get(CGM.VoidTy, args, false); 00449 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 00450 } 00451 00452 llvm::Constant *getSendFn(bool IsSuper) const { 00453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 00454 } 00455 00456 llvm::Constant *getSendFn2(bool IsSuper) const { 00457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 00458 } 00459 00460 llvm::Constant *getSendStretFn(bool IsSuper) const { 00461 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 00462 } 00463 00464 llvm::Constant *getSendStretFn2(bool IsSuper) const { 00465 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 00466 } 00467 00468 llvm::Constant *getSendFpretFn(bool IsSuper) const { 00469 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 00470 } 00471 00472 llvm::Constant *getSendFpretFn2(bool IsSuper) const { 00473 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 00474 } 00475 00476 llvm::Constant *getSendFp2retFn(bool IsSuper) const { 00477 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn(); 00478 } 00479 00480 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const { 00481 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn(); 00482 } 00483 00484 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 00485 ~ObjCCommonTypesHelper(){} 00486 }; 00487 00488 /// ObjCTypesHelper - Helper class that encapsulates lazy 00489 /// construction of varies types used during ObjC generation. 00490 class ObjCTypesHelper : public ObjCCommonTypesHelper { 00491 public: 00492 /// SymtabTy - LLVM type for struct objc_symtab. 00493 llvm::StructType *SymtabTy; 00494 /// SymtabPtrTy - LLVM type for struct objc_symtab *. 00495 llvm::Type *SymtabPtrTy; 00496 /// ModuleTy - LLVM type for struct objc_module. 00497 llvm::StructType *ModuleTy; 00498 00499 /// ProtocolTy - LLVM type for struct objc_protocol. 00500 llvm::StructType *ProtocolTy; 00501 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 00502 llvm::Type *ProtocolPtrTy; 00503 /// ProtocolExtensionTy - LLVM type for struct 00504 /// objc_protocol_extension. 00505 llvm::StructType *ProtocolExtensionTy; 00506 /// ProtocolExtensionTy - LLVM type for struct 00507 /// objc_protocol_extension *. 00508 llvm::Type *ProtocolExtensionPtrTy; 00509 /// MethodDescriptionTy - LLVM type for struct 00510 /// objc_method_description. 00511 llvm::StructType *MethodDescriptionTy; 00512 /// MethodDescriptionListTy - LLVM type for struct 00513 /// objc_method_description_list. 00514 llvm::StructType *MethodDescriptionListTy; 00515 /// MethodDescriptionListPtrTy - LLVM type for struct 00516 /// objc_method_description_list *. 00517 llvm::Type *MethodDescriptionListPtrTy; 00518 /// ProtocolListTy - LLVM type for struct objc_property_list. 00519 llvm::StructType *ProtocolListTy; 00520 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 00521 llvm::Type *ProtocolListPtrTy; 00522 /// CategoryTy - LLVM type for struct objc_category. 00523 llvm::StructType *CategoryTy; 00524 /// ClassTy - LLVM type for struct objc_class. 00525 llvm::StructType *ClassTy; 00526 /// ClassPtrTy - LLVM type for struct objc_class *. 00527 llvm::Type *ClassPtrTy; 00528 /// ClassExtensionTy - LLVM type for struct objc_class_ext. 00529 llvm::StructType *ClassExtensionTy; 00530 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 00531 llvm::Type *ClassExtensionPtrTy; 00532 // IvarTy - LLVM type for struct objc_ivar. 00533 llvm::StructType *IvarTy; 00534 /// IvarListTy - LLVM type for struct objc_ivar_list. 00535 llvm::Type *IvarListTy; 00536 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 00537 llvm::Type *IvarListPtrTy; 00538 /// MethodListTy - LLVM type for struct objc_method_list. 00539 llvm::Type *MethodListTy; 00540 /// MethodListPtrTy - LLVM type for struct objc_method_list *. 00541 llvm::Type *MethodListPtrTy; 00542 00543 /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 00544 llvm::Type *ExceptionDataTy; 00545 00546 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 00547 llvm::Constant *getExceptionTryEnterFn() { 00548 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 00549 return CGM.CreateRuntimeFunction( 00550 llvm::FunctionType::get(CGM.VoidTy, params, false), 00551 "objc_exception_try_enter"); 00552 } 00553 00554 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 00555 llvm::Constant *getExceptionTryExitFn() { 00556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 00557 return CGM.CreateRuntimeFunction( 00558 llvm::FunctionType::get(CGM.VoidTy, params, false), 00559 "objc_exception_try_exit"); 00560 } 00561 00562 /// ExceptionExtractFn - LLVM objc_exception_extract function. 00563 llvm::Constant *getExceptionExtractFn() { 00564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 00565 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00566 params, false), 00567 "objc_exception_extract"); 00568 } 00569 00570 /// ExceptionMatchFn - LLVM objc_exception_match function. 00571 llvm::Constant *getExceptionMatchFn() { 00572 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy }; 00573 return CGM.CreateRuntimeFunction( 00574 llvm::FunctionType::get(CGM.Int32Ty, params, false), 00575 "objc_exception_match"); 00576 00577 } 00578 00579 /// SetJmpFn - LLVM _setjmp function. 00580 llvm::Constant *getSetJmpFn() { 00581 // This is specifically the prototype for x86. 00582 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() }; 00583 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, 00584 params, false), 00585 "_setjmp", 00586 llvm::Attribute::ReturnsTwice); 00587 } 00588 00589 public: 00590 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 00591 ~ObjCTypesHelper() {} 00592 }; 00593 00594 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 00595 /// modern abi 00596 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 00597 public: 00598 00599 // MethodListnfABITy - LLVM for struct _method_list_t 00600 llvm::StructType *MethodListnfABITy; 00601 00602 // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 00603 llvm::Type *MethodListnfABIPtrTy; 00604 00605 // ProtocolnfABITy = LLVM for struct _protocol_t 00606 llvm::StructType *ProtocolnfABITy; 00607 00608 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 00609 llvm::Type *ProtocolnfABIPtrTy; 00610 00611 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 00612 llvm::StructType *ProtocolListnfABITy; 00613 00614 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 00615 llvm::Type *ProtocolListnfABIPtrTy; 00616 00617 // ClassnfABITy - LLVM for struct _class_t 00618 llvm::StructType *ClassnfABITy; 00619 00620 // ClassnfABIPtrTy - LLVM for struct _class_t* 00621 llvm::Type *ClassnfABIPtrTy; 00622 00623 // IvarnfABITy - LLVM for struct _ivar_t 00624 llvm::StructType *IvarnfABITy; 00625 00626 // IvarListnfABITy - LLVM for struct _ivar_list_t 00627 llvm::StructType *IvarListnfABITy; 00628 00629 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 00630 llvm::Type *IvarListnfABIPtrTy; 00631 00632 // ClassRonfABITy - LLVM for struct _class_ro_t 00633 llvm::StructType *ClassRonfABITy; 00634 00635 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 00636 llvm::Type *ImpnfABITy; 00637 00638 // CategorynfABITy - LLVM for struct _category_t 00639 llvm::StructType *CategorynfABITy; 00640 00641 // New types for nonfragile abi messaging. 00642 00643 // MessageRefTy - LLVM for: 00644 // struct _message_ref_t { 00645 // IMP messenger; 00646 // SEL name; 00647 // }; 00648 llvm::StructType *MessageRefTy; 00649 // MessageRefCTy - clang type for struct _message_ref_t 00650 QualType MessageRefCTy; 00651 00652 // MessageRefPtrTy - LLVM for struct _message_ref_t* 00653 llvm::Type *MessageRefPtrTy; 00654 // MessageRefCPtrTy - clang type for struct _message_ref_t* 00655 QualType MessageRefCPtrTy; 00656 00657 // MessengerTy - Type of the messenger (shown as IMP above) 00658 llvm::FunctionType *MessengerTy; 00659 00660 // SuperMessageRefTy - LLVM for: 00661 // struct _super_message_ref_t { 00662 // SUPER_IMP messenger; 00663 // SEL name; 00664 // }; 00665 llvm::StructType *SuperMessageRefTy; 00666 00667 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 00668 llvm::Type *SuperMessageRefPtrTy; 00669 00670 llvm::Constant *getMessageSendFixupFn() { 00671 // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 00672 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 00673 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00674 params, true), 00675 "objc_msgSend_fixup"); 00676 } 00677 00678 llvm::Constant *getMessageSendFpretFixupFn() { 00679 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 00680 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 00681 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00682 params, true), 00683 "objc_msgSend_fpret_fixup"); 00684 } 00685 00686 llvm::Constant *getMessageSendStretFixupFn() { 00687 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 00688 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 00689 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00690 params, true), 00691 "objc_msgSend_stret_fixup"); 00692 } 00693 00694 llvm::Constant *getMessageSendSuper2FixupFn() { 00695 // id objc_msgSendSuper2_fixup (struct objc_super *, 00696 // struct _super_message_ref_t*, ...) 00697 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 00698 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00699 params, true), 00700 "objc_msgSendSuper2_fixup"); 00701 } 00702 00703 llvm::Constant *getMessageSendSuper2StretFixupFn() { 00704 // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 00705 // struct _super_message_ref_t*, ...) 00706 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 00707 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 00708 params, true), 00709 "objc_msgSendSuper2_stret_fixup"); 00710 } 00711 00712 llvm::Constant *getObjCEndCatchFn() { 00713 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false), 00714 "objc_end_catch"); 00715 00716 } 00717 00718 llvm::Constant *getObjCBeginCatchFn() { 00719 llvm::Type *params[] = { Int8PtrTy }; 00720 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 00721 params, false), 00722 "objc_begin_catch"); 00723 } 00724 00725 llvm::StructType *EHTypeTy; 00726 llvm::Type *EHTypePtrTy; 00727 00728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 00729 ~ObjCNonFragileABITypesHelper(){} 00730 }; 00731 00732 class CGObjCCommonMac : public CodeGen::CGObjCRuntime { 00733 public: 00734 // FIXME - accessibility 00735 class GC_IVAR { 00736 public: 00737 unsigned ivar_bytepos; 00738 unsigned ivar_size; 00739 GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 00740 : ivar_bytepos(bytepos), ivar_size(size) {} 00741 00742 // Allow sorting based on byte pos. 00743 bool operator<(const GC_IVAR &b) const { 00744 return ivar_bytepos < b.ivar_bytepos; 00745 } 00746 }; 00747 00748 class SKIP_SCAN { 00749 public: 00750 unsigned skip; 00751 unsigned scan; 00752 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 00753 : skip(_skip), scan(_scan) {} 00754 }; 00755 00756 protected: 00757 llvm::LLVMContext &VMContext; 00758 // FIXME! May not be needing this after all. 00759 unsigned ObjCABI; 00760 00761 // gc ivar layout bitmap calculation helper caches. 00762 SmallVector<GC_IVAR, 16> SkipIvars; 00763 SmallVector<GC_IVAR, 16> IvarsInfo; 00764 00765 /// LazySymbols - Symbols to generate a lazy reference for. See 00766 /// DefinedSymbols and FinishModule(). 00767 llvm::SetVector<IdentifierInfo*> LazySymbols; 00768 00769 /// DefinedSymbols - External symbols which are defined by this 00770 /// module. The symbols in this list and LazySymbols are used to add 00771 /// special linker symbols which ensure that Objective-C modules are 00772 /// linked properly. 00773 llvm::SetVector<IdentifierInfo*> DefinedSymbols; 00774 00775 /// ClassNames - uniqued class names. 00776 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 00777 00778 /// MethodVarNames - uniqued method variable names. 00779 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 00780 00781 /// DefinedCategoryNames - list of category names in form Class_Category. 00782 llvm::SetVector<std::string> DefinedCategoryNames; 00783 00784 /// MethodVarTypes - uniqued method type signatures. We have to use 00785 /// a StringMap here because have no other unique reference. 00786 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 00787 00788 /// MethodDefinitions - map of methods which have been defined in 00789 /// this translation unit. 00790 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 00791 00792 /// PropertyNames - uniqued method variable names. 00793 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 00794 00795 /// ClassReferences - uniqued class references. 00796 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 00797 00798 /// SelectorReferences - uniqued selector references. 00799 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 00800 00801 /// Protocols - Protocols for which an objc_protocol structure has 00802 /// been emitted. Forward declarations are handled by creating an 00803 /// empty structure whose initializer is filled in when/if defined. 00804 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 00805 00806 /// DefinedProtocols - Protocols which have actually been 00807 /// defined. We should not need this, see FIXME in GenerateProtocol. 00808 llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 00809 00810 /// DefinedClasses - List of defined classes. 00811 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedClasses; 00812 00813 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 00814 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses; 00815 00816 /// DefinedCategories - List of defined categories. 00817 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedCategories; 00818 00819 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 00820 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories; 00821 00822 /// GetNameForMethod - Return a name for the given method. 00823 /// \param[out] NameOut - The return value. 00824 void GetNameForMethod(const ObjCMethodDecl *OMD, 00825 const ObjCContainerDecl *CD, 00826 SmallVectorImpl<char> &NameOut); 00827 00828 /// GetMethodVarName - Return a unique constant for the given 00829 /// selector's name. The return value has type char *. 00830 llvm::Constant *GetMethodVarName(Selector Sel); 00831 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 00832 00833 /// GetMethodVarType - Return a unique constant for the given 00834 /// method's type encoding string. The return value has type char *. 00835 00836 // FIXME: This is a horrible name. 00837 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D, 00838 bool Extended = false); 00839 llvm::Constant *GetMethodVarType(const FieldDecl *D); 00840 00841 /// GetPropertyName - Return a unique constant for the given 00842 /// name. The return value has type char *. 00843 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 00844 00845 // FIXME: This can be dropped once string functions are unified. 00846 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 00847 const Decl *Container); 00848 00849 /// GetClassName - Return a unique constant for the given selector's 00850 /// name. The return value has type char *. 00851 llvm::Constant *GetClassName(IdentifierInfo *Ident); 00852 00853 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD); 00854 00855 /// BuildIvarLayout - Builds ivar layout bitmap for the class 00856 /// implementation for the __strong or __weak case. 00857 /// 00858 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 00859 bool ForStrongLayout); 00860 00861 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); 00862 00863 void BuildAggrIvarRecordLayout(const RecordType *RT, 00864 unsigned int BytePos, bool ForStrongLayout, 00865 bool &HasUnion); 00866 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 00867 const llvm::StructLayout *Layout, 00868 const RecordDecl *RD, 00869 ArrayRef<const FieldDecl*> RecFields, 00870 unsigned int BytePos, bool ForStrongLayout, 00871 bool &HasUnion); 00872 00873 /// GetIvarLayoutName - Returns a unique constant for the given 00874 /// ivar layout bitmap. 00875 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 00876 const ObjCCommonTypesHelper &ObjCTypes); 00877 00878 /// EmitPropertyList - Emit the given property list. The return 00879 /// value has type PropertyListPtrTy. 00880 llvm::Constant *EmitPropertyList(Twine Name, 00881 const Decl *Container, 00882 const ObjCContainerDecl *OCD, 00883 const ObjCCommonTypesHelper &ObjCTypes); 00884 00885 /// EmitProtocolMethodTypes - Generate the array of extended method type 00886 /// strings. The return value has type Int8PtrPtrTy. 00887 llvm::Constant *EmitProtocolMethodTypes(Twine Name, 00888 ArrayRef<llvm::Constant*> MethodTypes, 00889 const ObjCCommonTypesHelper &ObjCTypes); 00890 00891 /// PushProtocolProperties - Push protocol's property on the input stack. 00892 void PushProtocolProperties( 00893 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 00894 llvm::SmallVectorImpl<llvm::Constant*> &Properties, 00895 const Decl *Container, 00896 const ObjCProtocolDecl *PROTO, 00897 const ObjCCommonTypesHelper &ObjCTypes); 00898 00899 /// GetProtocolRef - Return a reference to the internal protocol 00900 /// description, creating an empty one if it has not been 00901 /// defined. The return value has type ProtocolPtrTy. 00902 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 00903 00904 /// CreateMetadataVar - Create a global variable with internal 00905 /// linkage for use by the Objective-C runtime. 00906 /// 00907 /// This is a convenience wrapper which not only creates the 00908 /// variable, but also sets the section and alignment and adds the 00909 /// global to the "llvm.used" list. 00910 /// 00911 /// \param Name - The variable name. 00912 /// \param Init - The variable initializer; this is also used to 00913 /// define the type of the variable. 00914 /// \param Section - The section the variable should go into, or 0. 00915 /// \param Align - The alignment for the variable, or 0. 00916 /// \param AddToUsed - Whether the variable should be added to 00917 /// "llvm.used". 00918 llvm::GlobalVariable *CreateMetadataVar(Twine Name, 00919 llvm::Constant *Init, 00920 const char *Section, 00921 unsigned Align, 00922 bool AddToUsed); 00923 00924 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 00925 ReturnValueSlot Return, 00926 QualType ResultType, 00927 llvm::Value *Sel, 00928 llvm::Value *Arg0, 00929 QualType Arg0Ty, 00930 bool IsSuper, 00931 const CallArgList &CallArgs, 00932 const ObjCMethodDecl *OMD, 00933 const ObjCCommonTypesHelper &ObjCTypes); 00934 00935 /// EmitImageInfo - Emit the image info marker used to encode some module 00936 /// level information. 00937 void EmitImageInfo(); 00938 00939 public: 00940 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : 00941 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { } 00942 00943 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); 00944 00945 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 00946 const ObjCContainerDecl *CD=0); 00947 00948 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 00949 00950 /// GetOrEmitProtocol - Get the protocol object for the given 00951 /// declaration, emitting it if necessary. The return value has type 00952 /// ProtocolPtrTy. 00953 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 00954 00955 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 00956 /// object for the given declaration, emitting it if needed. These 00957 /// forward references will be filled in with empty bodies if no 00958 /// definition is seen. The return value has type ProtocolPtrTy. 00959 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 00960 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, 00961 const CGBlockInfo &blockInfo); 00962 00963 }; 00964 00965 class CGObjCMac : public CGObjCCommonMac { 00966 private: 00967 ObjCTypesHelper ObjCTypes; 00968 00969 /// EmitModuleInfo - Another marker encoding module level 00970 /// information. 00971 void EmitModuleInfo(); 00972 00973 /// EmitModuleSymols - Emit module symbols, the list of defined 00974 /// classes and categories. The result has type SymtabPtrTy. 00975 llvm::Constant *EmitModuleSymbols(); 00976 00977 /// FinishModule - Write out global data structures at the end of 00978 /// processing a translation unit. 00979 void FinishModule(); 00980 00981 /// EmitClassExtension - Generate the class extension structure used 00982 /// to store the weak ivar layout and properties. The return value 00983 /// has type ClassExtensionPtrTy. 00984 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 00985 00986 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 00987 /// for the given class. 00988 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 00989 const ObjCInterfaceDecl *ID); 00990 00991 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 00992 IdentifierInfo *II); 00993 00994 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 00995 00996 /// EmitSuperClassRef - Emits reference to class's main metadata class. 00997 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID); 00998 00999 /// EmitIvarList - Emit the ivar list for the given 01000 /// implementation. If ForClass is true the list of class ivars 01001 /// (i.e. metaclass ivars) is emitted, otherwise the list of 01002 /// interface ivars will be emitted. The return value has type 01003 /// IvarListPtrTy. 01004 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 01005 bool ForClass); 01006 01007 /// EmitMetaClass - Emit a forward reference to the class structure 01008 /// for the metaclass of the given interface. The return value has 01009 /// type ClassPtrTy. 01010 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 01011 01012 /// EmitMetaClass - Emit a class structure for the metaclass of the 01013 /// given implementation. The return value has type ClassPtrTy. 01014 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 01015 llvm::Constant *Protocols, 01016 ArrayRef<llvm::Constant*> Methods); 01017 01018 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 01019 01020 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 01021 01022 /// EmitMethodList - Emit the method list for the given 01023 /// implementation. The return value has type MethodListPtrTy. 01024 llvm::Constant *EmitMethodList(Twine Name, 01025 const char *Section, 01026 ArrayRef<llvm::Constant*> Methods); 01027 01028 /// EmitMethodDescList - Emit a method description list for a list of 01029 /// method declarations. 01030 /// - TypeName: The name for the type containing the methods. 01031 /// - IsProtocol: True iff these methods are for a protocol. 01032 /// - ClassMethds: True iff these are class methods. 01033 /// - Required: When true, only "required" methods are 01034 /// listed. Similarly, when false only "optional" methods are 01035 /// listed. For classes this should always be true. 01036 /// - begin, end: The method list to output. 01037 /// 01038 /// The return value has type MethodDescriptionListPtrTy. 01039 llvm::Constant *EmitMethodDescList(Twine Name, 01040 const char *Section, 01041 ArrayRef<llvm::Constant*> Methods); 01042 01043 /// GetOrEmitProtocol - Get the protocol object for the given 01044 /// declaration, emitting it if necessary. The return value has type 01045 /// ProtocolPtrTy. 01046 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 01047 01048 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 01049 /// object for the given declaration, emitting it if needed. These 01050 /// forward references will be filled in with empty bodies if no 01051 /// definition is seen. The return value has type ProtocolPtrTy. 01052 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 01053 01054 /// EmitProtocolExtension - Generate the protocol extension 01055 /// structure used to store optional instance and class methods, and 01056 /// protocol properties. The return value has type 01057 /// ProtocolExtensionPtrTy. 01058 llvm::Constant * 01059 EmitProtocolExtension(const ObjCProtocolDecl *PD, 01060 ArrayRef<llvm::Constant*> OptInstanceMethods, 01061 ArrayRef<llvm::Constant*> OptClassMethods, 01062 ArrayRef<llvm::Constant*> MethodTypesExt); 01063 01064 /// EmitProtocolList - Generate the list of referenced 01065 /// protocols. The return value has type ProtocolListPtrTy. 01066 llvm::Constant *EmitProtocolList(Twine Name, 01067 ObjCProtocolDecl::protocol_iterator begin, 01068 ObjCProtocolDecl::protocol_iterator end); 01069 01070 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 01071 /// for the given selector. 01072 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 01073 bool lval=false); 01074 01075 public: 01076 CGObjCMac(CodeGen::CodeGenModule &cgm); 01077 01078 virtual llvm::Function *ModuleInitFunction(); 01079 01080 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 01081 ReturnValueSlot Return, 01082 QualType ResultType, 01083 Selector Sel, 01084 llvm::Value *Receiver, 01085 const CallArgList &CallArgs, 01086 const ObjCInterfaceDecl *Class, 01087 const ObjCMethodDecl *Method); 01088 01089 virtual CodeGen::RValue 01090 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 01091 ReturnValueSlot Return, 01092 QualType ResultType, 01093 Selector Sel, 01094 const ObjCInterfaceDecl *Class, 01095 bool isCategoryImpl, 01096 llvm::Value *Receiver, 01097 bool IsClassMessage, 01098 const CallArgList &CallArgs, 01099 const ObjCMethodDecl *Method); 01100 01101 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 01102 const ObjCInterfaceDecl *ID); 01103 01104 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 01105 bool lval = false); 01106 01107 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 01108 /// untyped one. 01109 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 01110 const ObjCMethodDecl *Method); 01111 01112 virtual llvm::Constant *GetEHType(QualType T); 01113 01114 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 01115 01116 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 01117 01118 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {} 01119 01120 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 01121 const ObjCProtocolDecl *PD); 01122 01123 virtual llvm::Constant *GetPropertyGetFunction(); 01124 virtual llvm::Constant *GetPropertySetFunction(); 01125 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 01126 bool copy); 01127 virtual llvm::Constant *GetGetStructFunction(); 01128 virtual llvm::Constant *GetSetStructFunction(); 01129 virtual llvm::Constant *GetCppAtomicObjectFunction(); 01130 virtual llvm::Constant *EnumerationMutationFunction(); 01131 01132 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 01133 const ObjCAtTryStmt &S); 01134 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 01135 const ObjCAtSynchronizedStmt &S); 01136 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S); 01137 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 01138 const ObjCAtThrowStmt &S); 01139 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 01140 llvm::Value *AddrWeakObj); 01141 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 01142 llvm::Value *src, llvm::Value *dst); 01143 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 01144 llvm::Value *src, llvm::Value *dest, 01145 bool threadlocal = false); 01146 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 01147 llvm::Value *src, llvm::Value *dest, 01148 llvm::Value *ivarOffset); 01149 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 01150 llvm::Value *src, llvm::Value *dest); 01151 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 01152 llvm::Value *dest, llvm::Value *src, 01153 llvm::Value *size); 01154 01155 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 01156 QualType ObjectTy, 01157 llvm::Value *BaseValue, 01158 const ObjCIvarDecl *Ivar, 01159 unsigned CVRQualifiers); 01160 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 01161 const ObjCInterfaceDecl *Interface, 01162 const ObjCIvarDecl *Ivar); 01163 01164 /// GetClassGlobal - Return the global variable for the Objective-C 01165 /// class of the given name. 01166 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { 01167 llvm_unreachable("CGObjCMac::GetClassGlobal"); 01168 } 01169 }; 01170 01171 class CGObjCNonFragileABIMac : public CGObjCCommonMac { 01172 private: 01173 ObjCNonFragileABITypesHelper ObjCTypes; 01174 llvm::GlobalVariable* ObjCEmptyCacheVar; 01175 llvm::GlobalVariable* ObjCEmptyVtableVar; 01176 01177 /// SuperClassReferences - uniqued super class references. 01178 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 01179 01180 /// MetaClassReferences - uniqued meta class references. 01181 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 01182 01183 /// EHTypeReferences - uniqued class ehtype references. 01184 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 01185 01186 /// VTableDispatchMethods - List of methods for which we generate 01187 /// vtable-based message dispatch. 01188 llvm::DenseSet<Selector> VTableDispatchMethods; 01189 01190 /// DefinedMetaClasses - List of defined meta-classes. 01191 std::vector<llvm::GlobalValue*> DefinedMetaClasses; 01192 01193 /// isVTableDispatchedSelector - Returns true if SEL is a 01194 /// vtable-based selector. 01195 bool isVTableDispatchedSelector(Selector Sel); 01196 01197 /// FinishNonFragileABIModule - Write out global data structures at the end of 01198 /// processing a translation unit. 01199 void FinishNonFragileABIModule(); 01200 01201 /// AddModuleClassList - Add the given list of class pointers to the 01202 /// module with the provided symbol and section names. 01203 void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, 01204 const char *SymbolName, 01205 const char *SectionName); 01206 01207 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 01208 unsigned InstanceStart, 01209 unsigned InstanceSize, 01210 const ObjCImplementationDecl *ID); 01211 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 01212 llvm::Constant *IsAGV, 01213 llvm::Constant *SuperClassGV, 01214 llvm::Constant *ClassRoGV, 01215 bool HiddenVisibility); 01216 01217 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 01218 01219 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 01220 01221 /// EmitMethodList - Emit the method list for the given 01222 /// implementation. The return value has type MethodListnfABITy. 01223 llvm::Constant *EmitMethodList(Twine Name, 01224 const char *Section, 01225 ArrayRef<llvm::Constant*> Methods); 01226 /// EmitIvarList - Emit the ivar list for the given 01227 /// implementation. If ForClass is true the list of class ivars 01228 /// (i.e. metaclass ivars) is emitted, otherwise the list of 01229 /// interface ivars will be emitted. The return value has type 01230 /// IvarListnfABIPtrTy. 01231 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 01232 01233 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 01234 const ObjCIvarDecl *Ivar, 01235 unsigned long int offset); 01236 01237 /// GetOrEmitProtocol - Get the protocol object for the given 01238 /// declaration, emitting it if necessary. The return value has type 01239 /// ProtocolPtrTy. 01240 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 01241 01242 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 01243 /// object for the given declaration, emitting it if needed. These 01244 /// forward references will be filled in with empty bodies if no 01245 /// definition is seen. The return value has type ProtocolPtrTy. 01246 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 01247 01248 /// EmitProtocolList - Generate the list of referenced 01249 /// protocols. The return value has type ProtocolListPtrTy. 01250 llvm::Constant *EmitProtocolList(Twine Name, 01251 ObjCProtocolDecl::protocol_iterator begin, 01252 ObjCProtocolDecl::protocol_iterator end); 01253 01254 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF, 01255 ReturnValueSlot Return, 01256 QualType ResultType, 01257 Selector Sel, 01258 llvm::Value *Receiver, 01259 QualType Arg0Ty, 01260 bool IsSuper, 01261 const CallArgList &CallArgs, 01262 const ObjCMethodDecl *Method); 01263 01264 /// GetClassGlobal - Return the global variable for the Objective-C 01265 /// class of the given name. 01266 llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 01267 01268 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 01269 /// for the given class reference. 01270 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 01271 const ObjCInterfaceDecl *ID); 01272 01273 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 01274 IdentifierInfo *II); 01275 01276 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 01277 01278 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 01279 /// for the given super class reference. 01280 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 01281 const ObjCInterfaceDecl *ID); 01282 01283 /// EmitMetaClassRef - Return a Value * of the address of _class_t 01284 /// meta-data 01285 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 01286 const ObjCInterfaceDecl *ID); 01287 01288 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 01289 /// the given ivar. 01290 /// 01291 llvm::GlobalVariable * ObjCIvarOffsetVariable( 01292 const ObjCInterfaceDecl *ID, 01293 const ObjCIvarDecl *Ivar); 01294 01295 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 01296 /// for the given selector. 01297 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 01298 bool lval=false); 01299 01300 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 01301 /// interface. The return value has type EHTypePtrTy. 01302 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 01303 bool ForDefinition); 01304 01305 const char *getMetaclassSymbolPrefix() const { 01306 return "OBJC_METACLASS_$_"; 01307 } 01308 01309 const char *getClassSymbolPrefix() const { 01310 return "OBJC_CLASS_$_"; 01311 } 01312 01313 void GetClassSizeInfo(const ObjCImplementationDecl *OID, 01314 uint32_t &InstanceStart, 01315 uint32_t &InstanceSize); 01316 01317 // Shamelessly stolen from Analysis/CFRefCount.cpp 01318 Selector GetNullarySelector(const char* name) const { 01319 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 01320 return CGM.getContext().Selectors.getSelector(0, &II); 01321 } 01322 01323 Selector GetUnarySelector(const char* name) const { 01324 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 01325 return CGM.getContext().Selectors.getSelector(1, &II); 01326 } 01327 01328 /// ImplementationIsNonLazy - Check whether the given category or 01329 /// class implementation is "non-lazy". 01330 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 01331 01332 public: 01333 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 01334 // FIXME. All stubs for now! 01335 virtual llvm::Function *ModuleInitFunction(); 01336 01337 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 01338 ReturnValueSlot Return, 01339 QualType ResultType, 01340 Selector Sel, 01341 llvm::Value *Receiver, 01342 const CallArgList &CallArgs, 01343 const ObjCInterfaceDecl *Class, 01344 const ObjCMethodDecl *Method); 01345 01346 virtual CodeGen::RValue 01347 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 01348 ReturnValueSlot Return, 01349 QualType ResultType, 01350 Selector Sel, 01351 const ObjCInterfaceDecl *Class, 01352 bool isCategoryImpl, 01353 llvm::Value *Receiver, 01354 bool IsClassMessage, 01355 const CallArgList &CallArgs, 01356 const ObjCMethodDecl *Method); 01357 01358 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 01359 const ObjCInterfaceDecl *ID); 01360 01361 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 01362 bool lvalue = false) 01363 { return EmitSelector(Builder, Sel, lvalue); } 01364 01365 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 01366 /// untyped one. 01367 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 01368 const ObjCMethodDecl *Method) 01369 { return EmitSelector(Builder, Method->getSelector()); } 01370 01371 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 01372 01373 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 01374 01375 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {} 01376 01377 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 01378 const ObjCProtocolDecl *PD); 01379 01380 virtual llvm::Constant *GetEHType(QualType T); 01381 01382 virtual llvm::Constant *GetPropertyGetFunction() { 01383 return ObjCTypes.getGetPropertyFn(); 01384 } 01385 virtual llvm::Constant *GetPropertySetFunction() { 01386 return ObjCTypes.getSetPropertyFn(); 01387 } 01388 01389 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 01390 bool copy) { 01391 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy); 01392 } 01393 01394 virtual llvm::Constant *GetSetStructFunction() { 01395 return ObjCTypes.getCopyStructFn(); 01396 } 01397 virtual llvm::Constant *GetGetStructFunction() { 01398 return ObjCTypes.getCopyStructFn(); 01399 } 01400 virtual llvm::Constant *GetCppAtomicObjectFunction() { 01401 return ObjCTypes.getCppAtomicObjectFunction(); 01402 } 01403 01404 virtual llvm::Constant *EnumerationMutationFunction() { 01405 return ObjCTypes.getEnumerationMutationFn(); 01406 } 01407 01408 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 01409 const ObjCAtTryStmt &S); 01410 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 01411 const ObjCAtSynchronizedStmt &S); 01412 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 01413 const ObjCAtThrowStmt &S); 01414 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 01415 llvm::Value *AddrWeakObj); 01416 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 01417 llvm::Value *src, llvm::Value *dst); 01418 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 01419 llvm::Value *src, llvm::Value *dest, 01420 bool threadlocal = false); 01421 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 01422 llvm::Value *src, llvm::Value *dest, 01423 llvm::Value *ivarOffset); 01424 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 01425 llvm::Value *src, llvm::Value *dest); 01426 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 01427 llvm::Value *dest, llvm::Value *src, 01428 llvm::Value *size); 01429 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 01430 QualType ObjectTy, 01431 llvm::Value *BaseValue, 01432 const ObjCIvarDecl *Ivar, 01433 unsigned CVRQualifiers); 01434 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 01435 const ObjCInterfaceDecl *Interface, 01436 const ObjCIvarDecl *Ivar); 01437 }; 01438 01439 /// A helper class for performing the null-initialization of a return 01440 /// value. 01441 struct NullReturnState { 01442 llvm::BasicBlock *NullBB; 01443 llvm::BasicBlock *callBB; 01444 NullReturnState() : NullBB(0), callBB(0) {} 01445 01446 void init(CodeGenFunction &CGF, llvm::Value *receiver) { 01447 // Make blocks for the null-init and call edges. 01448 NullBB = CGF.createBasicBlock("msgSend.nullinit"); 01449 callBB = CGF.createBasicBlock("msgSend.call"); 01450 01451 // Check for a null receiver and, if there is one, jump to the 01452 // null-init test. 01453 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver); 01454 CGF.Builder.CreateCondBr(isNull, NullBB, callBB); 01455 01456 // Otherwise, start performing the call. 01457 CGF.EmitBlock(callBB); 01458 } 01459 01460 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType, 01461 const CallArgList &CallArgs, 01462 const ObjCMethodDecl *Method) { 01463 if (!NullBB) return result; 01464 01465 llvm::Value *NullInitPtr = 0; 01466 if (result.isScalar() && !resultType->isVoidType()) { 01467 NullInitPtr = CGF.CreateTempAlloca(result.getScalarVal()->getType()); 01468 CGF.Builder.CreateStore(result.getScalarVal(), NullInitPtr); 01469 } 01470 01471 // Finish the call path. 01472 llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont"); 01473 if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB); 01474 01475 // Emit the null-init block and perform the null-initialization there. 01476 CGF.EmitBlock(NullBB); 01477 01478 // Release consumed arguments along the null-receiver path. 01479 if (Method) { 01480 CallArgList::const_iterator I = CallArgs.begin(); 01481 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(), 01482 e = Method->param_end(); i != e; ++i, ++I) { 01483 const ParmVarDecl *ParamDecl = (*i); 01484 if (ParamDecl->hasAttr<NSConsumedAttr>()) { 01485 RValue RV = I->RV; 01486 assert(RV.isScalar() && 01487 "NullReturnState::complete - arg not on object"); 01488 CGF.EmitARCRelease(RV.getScalarVal(), true); 01489 } 01490 } 01491 } 01492 01493 if (result.isScalar()) { 01494 if (NullInitPtr) 01495 CGF.EmitNullInitialization(NullInitPtr, resultType); 01496 // Jump to the continuation block. 01497 CGF.EmitBlock(contBB); 01498 return NullInitPtr ? RValue::get(CGF.Builder.CreateLoad(NullInitPtr)) 01499 : result; 01500 } 01501 01502 if (!resultType->isAnyComplexType()) { 01503 assert(result.isAggregate() && "null init of non-aggregate result?"); 01504 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType); 01505 // Jump to the continuation block. 01506 CGF.EmitBlock(contBB); 01507 return result; 01508 } 01509 01510 // _Complex type 01511 // FIXME. Now easy to handle any other scalar type whose result is returned 01512 // in memory due to ABI limitations. 01513 CGF.EmitBlock(contBB); 01514 CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal(); 01515 llvm::Type *MemberType = CallCV.first->getType(); 01516 llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType); 01517 // Create phi instruction for scalar complex value. 01518 llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2); 01519 PHIReal->addIncoming(ZeroCV, NullBB); 01520 PHIReal->addIncoming(CallCV.first, callBB); 01521 llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2); 01522 PHIImag->addIncoming(ZeroCV, NullBB); 01523 PHIImag->addIncoming(CallCV.second, callBB); 01524 return RValue::getComplex(PHIReal, PHIImag); 01525 } 01526 }; 01527 01528 } // end anonymous namespace 01529 01530 /* *** Helper Functions *** */ 01531 01532 /// getConstantGEP() - Help routine to construct simple GEPs. 01533 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext, 01534 llvm::Constant *C, 01535 unsigned idx0, 01536 unsigned idx1) { 01537 llvm::Value *Idxs[] = { 01538 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0), 01539 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1) 01540 }; 01541 return llvm::ConstantExpr::getGetElementPtr(C, Idxs); 01542 } 01543 01544 /// hasObjCExceptionAttribute - Return true if this class or any super 01545 /// class has the __objc_exception__ attribute. 01546 static bool hasObjCExceptionAttribute(ASTContext &Context, 01547 const ObjCInterfaceDecl *OID) { 01548 if (OID->hasAttr<ObjCExceptionAttr>()) 01549 return true; 01550 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 01551 return hasObjCExceptionAttribute(Context, Super); 01552 return false; 01553 } 01554 01555 /* *** CGObjCMac Public Interface *** */ 01556 01557 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 01558 ObjCTypes(cgm) { 01559 ObjCABI = 1; 01560 EmitImageInfo(); 01561 } 01562 01563 /// GetClass - Return a reference to the class for the given interface 01564 /// decl. 01565 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 01566 const ObjCInterfaceDecl *ID) { 01567 return EmitClassRef(Builder, ID); 01568 } 01569 01570 /// GetSelector - Return the pointer to the unique'd string for this selector. 01571 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel, 01572 bool lval) { 01573 return EmitSelector(Builder, Sel, lval); 01574 } 01575 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 01576 *Method) { 01577 return EmitSelector(Builder, Method->getSelector()); 01578 } 01579 01580 llvm::Constant *CGObjCMac::GetEHType(QualType T) { 01581 if (T->isObjCIdType() || 01582 T->isObjCQualifiedIdType()) { 01583 return CGM.GetAddrOfRTTIDescriptor( 01584 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true); 01585 } 01586 if (T->isObjCClassType() || 01587 T->isObjCQualifiedClassType()) { 01588 return CGM.GetAddrOfRTTIDescriptor( 01589 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true); 01590 } 01591 if (T->isObjCObjectPointerType()) 01592 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true); 01593 01594 llvm_unreachable("asking for catch type for ObjC type in fragile runtime"); 01595 } 01596 01597 /// Generate a constant CFString object. 01598 /* 01599 struct __builtin_CFString { 01600 const int *isa; // point to __CFConstantStringClassReference 01601 int flags; 01602 const char *str; 01603 long length; 01604 }; 01605 */ 01606 01607 /// or Generate a constant NSString object. 01608 /* 01609 struct __builtin_NSString { 01610 const int *isa; // point to __NSConstantStringClassReference 01611 const char *str; 01612 unsigned int length; 01613 }; 01614 */ 01615 01616 llvm::Constant *CGObjCCommonMac::GenerateConstantString( 01617 const StringLiteral *SL) { 01618 return (CGM.getLangOpts().NoConstantCFStrings == 0 ? 01619 CGM.GetAddrOfConstantCFString(SL) : 01620 CGM.GetAddrOfConstantString(SL)); 01621 } 01622 01623 enum { 01624 kCFTaggedObjectID_Integer = (1 << 1) + 1 01625 }; 01626 01627 /// Generates a message send where the super is the receiver. This is 01628 /// a message send to self with special delivery semantics indicating 01629 /// which class's method should be called. 01630 CodeGen::RValue 01631 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 01632 ReturnValueSlot Return, 01633 QualType ResultType, 01634 Selector Sel, 01635 const ObjCInterfaceDecl *Class, 01636 bool isCategoryImpl, 01637 llvm::Value *Receiver, 01638 bool IsClassMessage, 01639 const CodeGen::CallArgList &CallArgs, 01640 const ObjCMethodDecl *Method) { 01641 // Create and init a super structure; this is a (receiver, class) 01642 // pair we will pass to objc_msgSendSuper. 01643 llvm::Value *ObjCSuper = 01644 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 01645 llvm::Value *ReceiverAsObject = 01646 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 01647 CGF.Builder.CreateStore(ReceiverAsObject, 01648 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 01649 01650 // If this is a class message the metaclass is passed as the target. 01651 llvm::Value *Target; 01652 if (IsClassMessage) { 01653 if (isCategoryImpl) { 01654 // Message sent to 'super' in a class method defined in a category 01655 // implementation requires an odd treatment. 01656 // If we are in a class method, we must retrieve the 01657 // _metaclass_ for the current class, pointed at by 01658 // the class's "isa" pointer. The following assumes that 01659 // isa" is the first ivar in a class (which it must be). 01660 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 01661 Target = CGF.Builder.CreateStructGEP(Target, 0); 01662 Target = CGF.Builder.CreateLoad(Target); 01663 } else { 01664 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 01665 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 01666 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 01667 Target = Super; 01668 } 01669 } 01670 else if (isCategoryImpl) 01671 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 01672 else { 01673 llvm::Value *ClassPtr = EmitSuperClassRef(Class); 01674 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1); 01675 Target = CGF.Builder.CreateLoad(ClassPtr); 01676 } 01677 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 01678 // ObjCTypes types. 01679 llvm::Type *ClassTy = 01680 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 01681 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 01682 CGF.Builder.CreateStore(Target, 01683 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 01684 return EmitMessageSend(CGF, Return, ResultType, 01685 EmitSelector(CGF.Builder, Sel), 01686 ObjCSuper, ObjCTypes.SuperPtrCTy, 01687 true, CallArgs, Method, ObjCTypes); 01688 } 01689 01690 /// Generate code for a message send expression. 01691 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 01692 ReturnValueSlot Return, 01693 QualType ResultType, 01694 Selector Sel, 01695 llvm::Value *Receiver, 01696 const CallArgList &CallArgs, 01697 const ObjCInterfaceDecl *Class, 01698 const ObjCMethodDecl *Method) { 01699 return EmitMessageSend(CGF, Return, ResultType, 01700 EmitSelector(CGF.Builder, Sel), 01701 Receiver, CGF.getContext().getObjCIdType(), 01702 false, CallArgs, Method, ObjCTypes); 01703 } 01704 01705 CodeGen::RValue 01706 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, 01707 ReturnValueSlot Return, 01708 QualType ResultType, 01709 llvm::Value *Sel, 01710 llvm::Value *Arg0, 01711 QualType Arg0Ty, 01712 bool IsSuper, 01713 const CallArgList &CallArgs, 01714 const ObjCMethodDecl *Method, 01715 const ObjCCommonTypesHelper &ObjCTypes) { 01716 CallArgList ActualArgs; 01717 if (!IsSuper) 01718 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy); 01719 ActualArgs.add(RValue::get(Arg0), Arg0Ty); 01720 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType()); 01721 ActualArgs.addFrom(CallArgs); 01722 01723 // If we're calling a method, use the formal signature. 01724 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); 01725 01726 if (Method) 01727 assert(CGM.getContext().getCanonicalType(Method->getResultType()) == 01728 CGM.getContext().getCanonicalType(ResultType) && 01729 "Result type mismatch!"); 01730 01731 NullReturnState nullReturn; 01732 01733 llvm::Constant *Fn = NULL; 01734 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { 01735 if (!IsSuper) nullReturn.init(CGF, Arg0); 01736 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 01737 : ObjCTypes.getSendStretFn(IsSuper); 01738 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { 01739 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper) 01740 : ObjCTypes.getSendFpretFn(IsSuper); 01741 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) { 01742 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper) 01743 : ObjCTypes.getSendFp2retFn(IsSuper); 01744 } else { 01745 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 01746 : ObjCTypes.getSendFn(IsSuper); 01747 } 01748 01749 bool requiresnullCheck = false; 01750 if (CGM.getLangOpts().ObjCAutoRefCount && Method) 01751 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(), 01752 e = Method->param_end(); i != e; ++i) { 01753 const ParmVarDecl *ParamDecl = (*i); 01754 if (ParamDecl->hasAttr<NSConsumedAttr>()) { 01755 if (!nullReturn.NullBB) 01756 nullReturn.init(CGF, Arg0); 01757 requiresnullCheck = true; 01758 break; 01759 } 01760 } 01761 01762 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType); 01763 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs); 01764 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs, 01765 requiresnullCheck ? Method : 0); 01766 } 01767 01768 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { 01769 if (FQT.isObjCGCStrong()) 01770 return Qualifiers::Strong; 01771 01772 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak) 01773 return Qualifiers::Weak; 01774 01775 // check for __unsafe_unretained 01776 if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone) 01777 return Qualifiers::GCNone; 01778 01779 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) 01780 return Qualifiers::Strong; 01781 01782 if (const PointerType *PT = FQT->getAs<PointerType>()) 01783 return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 01784 01785 return Qualifiers::GCNone; 01786 } 01787 01788 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, 01789 const CGBlockInfo &blockInfo) { 01790 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy); 01791 01792 if (CGM.getLangOpts().getGC() == LangOptions::NonGC && 01793 !CGM.getLangOpts().ObjCAutoRefCount) 01794 return nullPtr; 01795 01796 bool hasUnion = false; 01797 SkipIvars.clear(); 01798 IvarsInfo.clear(); 01799 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 01800 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 01801 01802 // __isa is the first field in block descriptor and must assume by runtime's 01803 // convention that it is GC'able. 01804 IvarsInfo.push_back(GC_IVAR(0, 1)); 01805 01806 const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 01807 01808 // Calculate the basic layout of the block structure. 01809 const llvm::StructLayout *layout = 01810 CGM.getTargetData().getStructLayout(blockInfo.StructureType); 01811 01812 // Ignore the optional 'this' capture: C++ objects are not assumed 01813 // to be GC'ed. 01814 01815 // Walk the captured variables. 01816 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 01817 ce = blockDecl->capture_end(); ci != ce; ++ci) { 01818 const VarDecl *variable = ci->getVariable(); 01819 QualType type = variable->getType(); 01820 01821 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 01822 01823 // Ignore constant captures. 01824 if (capture.isConstant()) continue; 01825 01826 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); 01827 01828 // __block variables are passed by their descriptor address. 01829 if (ci->isByRef()) { 01830 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); 01831 continue; 01832 } 01833 01834 assert(!type->isArrayType() && "array variable should not be caught"); 01835 if (const RecordType *record = type->getAs<RecordType>()) { 01836 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion); 01837 continue; 01838 } 01839 01840 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); 01841 unsigned fieldSize = CGM.getContext().getTypeSize(type); 01842 01843 if (GCAttr == Qualifiers::Strong) 01844 IvarsInfo.push_back(GC_IVAR(fieldOffset, 01845 fieldSize / WordSizeInBits)); 01846 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) 01847 SkipIvars.push_back(GC_IVAR(fieldOffset, 01848 fieldSize / ByteSizeInBits)); 01849 } 01850 01851 if (IvarsInfo.empty()) 01852 return nullPtr; 01853 01854 // Sort on byte position; captures might not be allocated in order, 01855 // and unions can do funny things. 01856 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 01857 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end()); 01858 01859 std::string BitMap; 01860 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 01861 if (CGM.getLangOpts().ObjCGCBitmapPrint) { 01862 printf("\n block variable layout for block: "); 01863 const unsigned char *s = (unsigned char*)BitMap.c_str(); 01864 for (unsigned i = 0, e = BitMap.size(); i < e; i++) 01865 if (!(s[i] & 0xf0)) 01866 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 01867 else 01868 printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 01869 printf("\n"); 01870 } 01871 01872 return C; 01873 } 01874 01875 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 01876 const ObjCProtocolDecl *PD) { 01877 // FIXME: I don't understand why gcc generates this, or where it is 01878 // resolved. Investigate. Its also wasteful to look this up over and over. 01879 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 01880 01881 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 01882 ObjCTypes.getExternalProtocolPtrTy()); 01883 } 01884 01885 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 01886 // FIXME: We shouldn't need this, the protocol decl should contain enough 01887 // information to tell us whether this was a declaration or a definition. 01888 DefinedProtocols.insert(PD->getIdentifier()); 01889 01890 // If we have generated a forward reference to this protocol, emit 01891 // it now. Otherwise do nothing, the protocol objects are lazily 01892 // emitted. 01893 if (Protocols.count(PD->getIdentifier())) 01894 GetOrEmitProtocol(PD); 01895 } 01896 01897 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 01898 if (DefinedProtocols.count(PD->getIdentifier())) 01899 return GetOrEmitProtocol(PD); 01900 01901 return GetOrEmitProtocolRef(PD); 01902 } 01903 01904 /* 01905 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 01906 struct _objc_protocol { 01907 struct _objc_protocol_extension *isa; 01908 char *protocol_name; 01909 struct _objc_protocol_list *protocol_list; 01910 struct _objc__method_prototype_list *instance_methods; 01911 struct _objc__method_prototype_list *class_methods 01912 }; 01913 01914 See EmitProtocolExtension(). 01915 */ 01916 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 01917 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()]; 01918 01919 // Early exit if a defining object has already been generated. 01920 if (Entry && Entry->hasInitializer()) 01921 return Entry; 01922 01923 // Use the protocol definition, if there is one. 01924 if (const ObjCProtocolDecl *Def = PD->getDefinition()) 01925 PD = Def; 01926 01927 // FIXME: I don't understand why gcc generates this, or where it is 01928 // resolved. Investigate. Its also wasteful to look this up over and over. 01929 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 01930 01931 // Construct method lists. 01932 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 01933 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 01934 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt; 01935 for (ObjCProtocolDecl::instmeth_iterator 01936 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 01937 ObjCMethodDecl *MD = *i; 01938 llvm::Constant *C = GetMethodDescriptionConstant(MD); 01939 if (!C) 01940 return GetOrEmitProtocolRef(PD); 01941 01942 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 01943 OptInstanceMethods.push_back(C); 01944 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 01945 } else { 01946 InstanceMethods.push_back(C); 01947 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 01948 } 01949 } 01950 01951 for (ObjCProtocolDecl::classmeth_iterator 01952 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 01953 ObjCMethodDecl *MD = *i; 01954 llvm::Constant *C = GetMethodDescriptionConstant(MD); 01955 if (!C) 01956 return GetOrEmitProtocolRef(PD); 01957 01958 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 01959 OptClassMethods.push_back(C); 01960 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 01961 } else { 01962 ClassMethods.push_back(C); 01963 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 01964 } 01965 } 01966 01967 MethodTypesExt.insert(MethodTypesExt.end(), 01968 OptMethodTypesExt.begin(), OptMethodTypesExt.end()); 01969 01970 llvm::Constant *Values[] = { 01971 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods, 01972 MethodTypesExt), 01973 GetClassName(PD->getIdentifier()), 01974 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(), 01975 PD->protocol_begin(), 01976 PD->protocol_end()), 01977 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(), 01978 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 01979 InstanceMethods), 01980 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(), 01981 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 01982 ClassMethods) 01983 }; 01984 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 01985 Values); 01986 01987 if (Entry) { 01988 // Already created, fix the linkage and update the initializer. 01989 Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 01990 Entry->setInitializer(Init); 01991 } else { 01992 Entry = 01993 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 01994 llvm::GlobalValue::InternalLinkage, 01995 Init, 01996 "\01L_OBJC_PROTOCOL_" + PD->getName()); 01997 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 01998 // FIXME: Is this necessary? Why only for protocol? 01999 Entry->setAlignment(4); 02000 02001 Protocols[PD->getIdentifier()] = Entry; 02002 } 02003 CGM.AddUsedGlobal(Entry); 02004 02005 return Entry; 02006 } 02007 02008 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 02009 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 02010 02011 if (!Entry) { 02012 // We use the initializer as a marker of whether this is a forward 02013 // reference or not. At module finalization we add the empty 02014 // contents for protocols which were referenced but never defined. 02015 Entry = 02016 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 02017 llvm::GlobalValue::ExternalLinkage, 02018 0, 02019 "\01L_OBJC_PROTOCOL_" + PD->getName()); 02020 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 02021 // FIXME: Is this necessary? Why only for protocol? 02022 Entry->setAlignment(4); 02023 } 02024 02025 return Entry; 02026 } 02027 02028 /* 02029 struct _objc_protocol_extension { 02030 uint32_t size; 02031 struct objc_method_description_list *optional_instance_methods; 02032 struct objc_method_description_list *optional_class_methods; 02033 struct objc_property_list *instance_properties; 02034 const char ** extendedMethodTypes; 02035 }; 02036 */ 02037 llvm::Constant * 02038 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 02039 ArrayRef<llvm::Constant*> OptInstanceMethods, 02040 ArrayRef<llvm::Constant*> OptClassMethods, 02041 ArrayRef<llvm::Constant*> MethodTypesExt) { 02042 uint64_t Size = 02043 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 02044 llvm::Constant *Values[] = { 02045 llvm::ConstantInt::get(ObjCTypes.IntTy, Size), 02046 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 02047 + PD->getName(), 02048 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 02049 OptInstanceMethods), 02050 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(), 02051 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 02052 OptClassMethods), 02053 EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD, 02054 ObjCTypes), 02055 EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(), 02056 MethodTypesExt, ObjCTypes) 02057 }; 02058 02059 // Return null if no extension bits are used. 02060 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 02061 Values[3]->isNullValue() && Values[4]->isNullValue()) 02062 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 02063 02064 llvm::Constant *Init = 02065 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 02066 02067 // No special section, but goes in llvm.used 02068 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(), 02069 Init, 02070 0, 0, true); 02071 } 02072 02073 /* 02074 struct objc_protocol_list { 02075 struct objc_protocol_list *next; 02076 long count; 02077 Protocol *list[]; 02078 }; 02079 */ 02080 llvm::Constant * 02081 CGObjCMac::EmitProtocolList(Twine Name, 02082 ObjCProtocolDecl::protocol_iterator begin, 02083 ObjCProtocolDecl::protocol_iterator end) { 02084 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs; 02085 02086 for (; begin != end; ++begin) 02087 ProtocolRefs.push_back(GetProtocolRef(*begin)); 02088 02089 // Just return null for empty protocol lists 02090 if (ProtocolRefs.empty()) 02091 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 02092 02093 // This list is null terminated. 02094 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 02095 02096 llvm::Constant *Values[3]; 02097 // This field is only used by the runtime. 02098 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 02099 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, 02100 ProtocolRefs.size() - 1); 02101 Values[2] = 02102 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 02103 ProtocolRefs.size()), 02104 ProtocolRefs); 02105 02106 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 02107 llvm::GlobalVariable *GV = 02108 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 02109 4, false); 02110 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 02111 } 02112 02113 void CGObjCCommonMac:: 02114 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet, 02115 llvm::SmallVectorImpl<llvm::Constant*> &Properties, 02116 const Decl *Container, 02117 const ObjCProtocolDecl *PROTO, 02118 const ObjCCommonTypesHelper &ObjCTypes) { 02119 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), 02120 E = PROTO->protocol_end(); P != E; ++P) 02121 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 02122 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), 02123 E = PROTO->prop_end(); I != E; ++I) { 02124 const ObjCPropertyDecl *PD = &*I; 02125 if (!PropertySet.insert(PD->getIdentifier())) 02126 continue; 02127 llvm::Constant *Prop[] = { 02128 GetPropertyName(PD->getIdentifier()), 02129 GetPropertyTypeString(PD, Container) 02130 }; 02131 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); 02132 } 02133 } 02134 02135 /* 02136 struct _objc_property { 02137 const char * const name; 02138 const char * const attributes; 02139 }; 02140 02141 struct _objc_property_list { 02142 uint32_t entsize; // sizeof (struct _objc_property) 02143 uint32_t prop_count; 02144 struct _objc_property[prop_count]; 02145 }; 02146 */ 02147 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, 02148 const Decl *Container, 02149 const ObjCContainerDecl *OCD, 02150 const ObjCCommonTypesHelper &ObjCTypes) { 02151 llvm::SmallVector<llvm::Constant*, 16> Properties; 02152 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 02153 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 02154 E = OCD->prop_end(); I != E; ++I) { 02155 const ObjCPropertyDecl *PD = &*I; 02156 PropertySet.insert(PD->getIdentifier()); 02157 llvm::Constant *Prop[] = { 02158 GetPropertyName(PD->getIdentifier()), 02159 GetPropertyTypeString(PD, Container) 02160 }; 02161 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 02162 Prop)); 02163 } 02164 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) { 02165 for (ObjCInterfaceDecl::all_protocol_iterator 02166 P = OID->all_referenced_protocol_begin(), 02167 E = OID->all_referenced_protocol_end(); P != E; ++P) 02168 PushProtocolProperties(PropertySet, Properties, Container, (*P), 02169 ObjCTypes); 02170 } 02171 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) { 02172 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(), 02173 E = CD->protocol_end(); P != E; ++P) 02174 PushProtocolProperties(PropertySet, Properties, Container, (*P), 02175 ObjCTypes); 02176 } 02177 02178 // Return null for empty list. 02179 if (Properties.empty()) 02180 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 02181 02182 unsigned PropertySize = 02183 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 02184 llvm::Constant *Values[3]; 02185 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 02186 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 02187 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 02188 Properties.size()); 02189 Values[2] = llvm::ConstantArray::get(AT, Properties); 02190 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 02191 02192 llvm::GlobalVariable *GV = 02193 CreateMetadataVar(Name, Init, 02194 (ObjCABI == 2) ? "__DATA, __objc_const" : 02195 "__OBJC,__property,regular,no_dead_strip", 02196 (ObjCABI == 2) ? 8 : 4, 02197 true); 02198 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 02199 } 02200 02201 llvm::Constant * 02202 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name, 02203 ArrayRef<llvm::Constant*> MethodTypes, 02204 const ObjCCommonTypesHelper &ObjCTypes) { 02205 // Return null for empty list. 02206 if (MethodTypes.empty()) 02207 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy); 02208 02209 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 02210 MethodTypes.size()); 02211 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes); 02212 02213 llvm::GlobalVariable *GV = 02214 CreateMetadataVar(Name, Init, 02215 (ObjCABI == 2) ? "__DATA, __objc_const" : 0, 02216 (ObjCABI == 2) ? 8 : 4, 02217 true); 02218 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy); 02219 } 02220 02221 /* 02222 struct objc_method_description_list { 02223 int count; 02224 struct objc_method_description list[]; 02225 }; 02226 */ 02227 llvm::Constant * 02228 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 02229 llvm::Constant *Desc[] = { 02230 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 02231 ObjCTypes.SelectorPtrTy), 02232 GetMethodVarType(MD) 02233 }; 02234 if (!Desc[1]) 02235 return 0; 02236 02237 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 02238 Desc); 02239 } 02240 02241 llvm::Constant * 02242 CGObjCMac::EmitMethodDescList(Twine Name, const char *Section, 02243 ArrayRef<llvm::Constant*> Methods) { 02244 // Return null for empty list. 02245 if (Methods.empty()) 02246 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 02247 02248 llvm::Constant *Values[2]; 02249 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 02250 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 02251 Methods.size()); 02252 Values[1] = llvm::ConstantArray::get(AT, Methods); 02253 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 02254 02255 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 02256 return llvm::ConstantExpr::getBitCast(GV, 02257 ObjCTypes.MethodDescriptionListPtrTy); 02258 } 02259 02260 /* 02261 struct _objc_category { 02262 char *category_name; 02263 char *class_name; 02264 struct _objc_method_list *instance_methods; 02265 struct _objc_method_list *class_methods; 02266 struct _objc_protocol_list *protocols; 02267 uint32_t size; // <rdar://4585769> 02268 struct _objc_property_list *instance_properties; 02269 }; 02270 */ 02271 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 02272 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 02273 02274 // FIXME: This is poor design, the OCD should have a pointer to the category 02275 // decl. Additionally, note that Category can be null for the @implementation 02276 // w/o an @interface case. Sema should just create one for us as it does for 02277 // @implementation so everyone else can live life under a clear blue sky. 02278 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 02279 const ObjCCategoryDecl *Category = 02280 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 02281 02282 SmallString<256> ExtName; 02283 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' 02284 << OCD->getName(); 02285 02286 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods; 02287 for (ObjCCategoryImplDecl::instmeth_iterator 02288 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 02289 // Instance methods should always be defined. 02290 InstanceMethods.push_back(GetMethodConstant(*i)); 02291 } 02292 for (ObjCCategoryImplDecl::classmeth_iterator 02293 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 02294 // Class methods should always be defined. 02295 ClassMethods.push_back(GetMethodConstant(*i)); 02296 } 02297 02298 llvm::Constant *Values[7]; 02299 Values[0] = GetClassName(OCD->getIdentifier()); 02300 Values[1] = GetClassName(Interface->getIdentifier()); 02301 LazySymbols.insert(Interface->getIdentifier()); 02302 Values[2] = 02303 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(), 02304 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 02305 InstanceMethods); 02306 Values[3] = 02307 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(), 02308 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 02309 ClassMethods); 02310 if (Category) { 02311 Values[4] = 02312 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(), 02313 Category->protocol_begin(), 02314 Category->protocol_end()); 02315 } else { 02316 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 02317 } 02318 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 02319 02320 // If there is no category @interface then there can be no properties. 02321 if (Category) { 02322 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 02323 OCD, Category, ObjCTypes); 02324 } else { 02325 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 02326 } 02327 02328 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 02329 Values); 02330 02331 llvm::GlobalVariable *GV = 02332 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init, 02333 "__OBJC,__category,regular,no_dead_strip", 02334 4, true); 02335 DefinedCategories.push_back(GV); 02336 DefinedCategoryNames.insert(ExtName.str()); 02337 // method definition entries must be clear for next implementation. 02338 MethodDefinitions.clear(); 02339 } 02340 02341 // FIXME: Get from somewhere? 02342 enum ClassFlags { 02343 eClassFlags_Factory = 0x00001, 02344 eClassFlags_Meta = 0x00002, 02345 // <rdr://5142207> 02346 eClassFlags_HasCXXStructors = 0x02000, 02347 eClassFlags_Hidden = 0x20000, 02348 eClassFlags_ABI2_Hidden = 0x00010, 02349 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 02350 }; 02351 02352 /* 02353 struct _objc_class { 02354 Class isa; 02355 Class super_class; 02356 const char *name; 02357 long version; 02358 long info; 02359 long instance_size; 02360 struct _objc_ivar_list *ivars; 02361 struct _objc_method_list *methods; 02362 struct _objc_cache *cache; 02363 struct _objc_protocol_list *protocols; 02364 // Objective-C 1.0 extensions (<rdr://4585769>) 02365 const char *ivar_layout; 02366 struct _objc_class_ext *ext; 02367 }; 02368 02369 See EmitClassExtension(); 02370 */ 02371 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 02372 DefinedSymbols.insert(ID->getIdentifier()); 02373 02374 std::string ClassName = ID->getNameAsString(); 02375 // FIXME: Gross 02376 ObjCInterfaceDecl *Interface = 02377 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 02378 llvm::Constant *Protocols = 02379 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(), 02380 Interface->all_referenced_protocol_begin(), 02381 Interface->all_referenced_protocol_end()); 02382 unsigned Flags = eClassFlags_Factory; 02383 if (ID->hasCXXStructors()) 02384 Flags |= eClassFlags_HasCXXStructors; 02385 unsigned Size = 02386 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity(); 02387 02388 // FIXME: Set CXX-structors flag. 02389 if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 02390 Flags |= eClassFlags_Hidden; 02391 02392 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods; 02393 for (ObjCImplementationDecl::instmeth_iterator 02394 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 02395 // Instance methods should always be defined. 02396 InstanceMethods.push_back(GetMethodConstant(*i)); 02397 } 02398 for (ObjCImplementationDecl::classmeth_iterator 02399 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 02400 // Class methods should always be defined. 02401 ClassMethods.push_back(GetMethodConstant(*i)); 02402 } 02403 02404 for (ObjCImplementationDecl::propimpl_iterator 02405 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 02406 ObjCPropertyImplDecl *PID = &*i; 02407 02408 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 02409 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 02410 02411 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 02412 if (llvm::Constant *C = GetMethodConstant(MD)) 02413 InstanceMethods.push_back(C); 02414 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 02415 if (llvm::Constant *C = GetMethodConstant(MD)) 02416 InstanceMethods.push_back(C); 02417 } 02418 } 02419 02420 llvm::Constant *Values[12]; 02421 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 02422 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 02423 // Record a reference to the super class. 02424 LazySymbols.insert(Super->getIdentifier()); 02425 02426 Values[ 1] = 02427 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 02428 ObjCTypes.ClassPtrTy); 02429 } else { 02430 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 02431 } 02432 Values[ 2] = GetClassName(ID->getIdentifier()); 02433 // Version is always 0. 02434 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 02435 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 02436 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 02437 Values[ 6] = EmitIvarList(ID, false); 02438 Values[ 7] = 02439 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(), 02440 "__OBJC,__inst_meth,regular,no_dead_strip", 02441 InstanceMethods); 02442 // cache is always NULL. 02443 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 02444 Values[ 9] = Protocols; 02445 Values[10] = BuildIvarLayout(ID, true); 02446 Values[11] = EmitClassExtension(ID); 02447 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 02448 Values); 02449 std::string Name("\01L_OBJC_CLASS_"); 02450 Name += ClassName; 02451 const char *Section = "__OBJC,__class,regular,no_dead_strip"; 02452 // Check for a forward reference. 02453 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 02454 if (GV) { 02455 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 02456 "Forward metaclass reference has incorrect type."); 02457 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 02458 GV->setInitializer(Init); 02459 GV->setSection(Section); 02460 GV->setAlignment(4); 02461 CGM.AddUsedGlobal(GV); 02462 } 02463 else 02464 GV = CreateMetadataVar(Name, Init, Section, 4, true); 02465 DefinedClasses.push_back(GV); 02466 // method definition entries must be clear for next implementation. 02467 MethodDefinitions.clear(); 02468 } 02469 02470 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 02471 llvm::Constant *Protocols, 02472 ArrayRef<llvm::Constant*> Methods) { 02473 unsigned Flags = eClassFlags_Meta; 02474 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 02475 02476 if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 02477 Flags |= eClassFlags_Hidden; 02478 02479 llvm::Constant *Values[12]; 02480 // The isa for the metaclass is the root of the hierarchy. 02481 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 02482 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 02483 Root = Super; 02484 Values[ 0] = 02485 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 02486 ObjCTypes.ClassPtrTy); 02487 // The super class for the metaclass is emitted as the name of the 02488 // super class. The runtime fixes this up to point to the 02489 // *metaclass* for the super class. 02490 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 02491 Values[ 1] = 02492 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 02493 ObjCTypes.ClassPtrTy); 02494 } else { 02495 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 02496 } 02497 Values[ 2] = GetClassName(ID->getIdentifier()); 02498 // Version is always 0. 02499 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 02500 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 02501 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 02502 Values[ 6] = EmitIvarList(ID, true); 02503 Values[ 7] = 02504 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 02505 "__OBJC,__cls_meth,regular,no_dead_strip", 02506 Methods); 02507 // cache is always NULL. 02508 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 02509 Values[ 9] = Protocols; 02510 // ivar_layout for metaclass is always NULL. 02511 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 02512 // The class extension is always unused for metaclasses. 02513 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 02514 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 02515 Values); 02516 02517 std::string Name("\01L_OBJC_METACLASS_"); 02518 Name += ID->getNameAsCString(); 02519 02520 // Check for a forward reference. 02521 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 02522 if (GV) { 02523 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 02524 "Forward metaclass reference has incorrect type."); 02525 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 02526 GV->setInitializer(Init); 02527 } else { 02528 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 02529 llvm::GlobalValue::InternalLinkage, 02530 Init, Name); 02531 } 02532 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 02533 GV->setAlignment(4); 02534 CGM.AddUsedGlobal(GV); 02535 02536 return GV; 02537 } 02538 02539 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 02540 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 02541 02542 // FIXME: Should we look these up somewhere other than the module. Its a bit 02543 // silly since we only generate these while processing an implementation, so 02544 // exactly one pointer would work if know when we entered/exitted an 02545 // implementation block. 02546 02547 // Check for an existing forward reference. 02548 // Previously, metaclass with internal linkage may have been defined. 02549 // pass 'true' as 2nd argument so it is returned. 02550 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 02551 true)) { 02552 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 02553 "Forward metaclass reference has incorrect type."); 02554 return GV; 02555 } else { 02556 // Generate as an external reference to keep a consistent 02557 // module. This will be patched up when we emit the metaclass. 02558 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 02559 llvm::GlobalValue::ExternalLinkage, 02560 0, 02561 Name); 02562 } 02563 } 02564 02565 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { 02566 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString(); 02567 02568 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 02569 true)) { 02570 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 02571 "Forward class metadata reference has incorrect type."); 02572 return GV; 02573 } else { 02574 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 02575 llvm::GlobalValue::ExternalLinkage, 02576 0, 02577 Name); 02578 } 02579 } 02580 02581 /* 02582 struct objc_class_ext { 02583 uint32_t size; 02584 const char *weak_ivar_layout; 02585 struct _objc_property_list *properties; 02586 }; 02587 */ 02588 llvm::Constant * 02589 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 02590 uint64_t Size = 02591 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 02592 02593 llvm::Constant *Values[3]; 02594 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 02595 Values[1] = BuildIvarLayout(ID, false); 02596 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 02597 ID, ID->getClassInterface(), ObjCTypes); 02598 02599 // Return null if no extension bits are used. 02600 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 02601 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 02602 02603 llvm::Constant *Init = 02604 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 02605 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(), 02606 Init, "__OBJC,__class_ext,regular,no_dead_strip", 02607 4, true); 02608 } 02609 02610 /* 02611 struct objc_ivar { 02612 char *ivar_name; 02613 char *ivar_type; 02614 int ivar_offset; 02615 }; 02616 02617 struct objc_ivar_list { 02618 int ivar_count; 02619 struct objc_ivar list[count]; 02620 }; 02621 */ 02622 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 02623 bool ForClass) { 02624 std::vector<llvm::Constant*> Ivars; 02625 02626 // When emitting the root class GCC emits ivar entries for the 02627 // actual class structure. It is not clear if we need to follow this 02628 // behavior; for now lets try and get away with not doing it. If so, 02629 // the cleanest solution would be to make up an ObjCInterfaceDecl 02630 // for the class. 02631 if (ForClass) 02632 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 02633 02634 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 02635 02636 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 02637 IVD; IVD = IVD->getNextIvar()) { 02638 // Ignore unnamed bit-fields. 02639 if (!IVD->getDeclName()) 02640 continue; 02641 llvm::Constant *Ivar[] = { 02642 GetMethodVarName(IVD->getIdentifier()), 02643 GetMethodVarType(IVD), 02644 llvm::ConstantInt::get(ObjCTypes.IntTy, 02645 ComputeIvarBaseOffset(CGM, OID, IVD)) 02646 }; 02647 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 02648 } 02649 02650 // Return null for empty list. 02651 if (Ivars.empty()) 02652 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 02653 02654 llvm::Constant *Values[2]; 02655 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 02656 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 02657 Ivars.size()); 02658 Values[1] = llvm::ConstantArray::get(AT, Ivars); 02659 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 02660 02661 llvm::GlobalVariable *GV; 02662 if (ForClass) 02663 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(), 02664 Init, "__OBJC,__class_vars,regular,no_dead_strip", 02665 4, true); 02666 else 02667 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(), 02668 Init, "__OBJC,__instance_vars,regular,no_dead_strip", 02669 4, true); 02670 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 02671 } 02672 02673 /* 02674 struct objc_method { 02675 SEL method_name; 02676 char *method_types; 02677 void *method; 02678 }; 02679 02680 struct objc_method_list { 02681 struct objc_method_list *obsolete; 02682 int count; 02683 struct objc_method methods_list[count]; 02684 }; 02685 */ 02686 02687 /// GetMethodConstant - Return a struct objc_method constant for the 02688 /// given method if it has been defined. The result is null if the 02689 /// method has not been defined. The return value has type MethodPtrTy. 02690 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 02691 llvm::Function *Fn = GetMethodDefinition(MD); 02692 if (!Fn) 02693 return 0; 02694 02695 llvm::Constant *Method[] = { 02696 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 02697 ObjCTypes.SelectorPtrTy), 02698 GetMethodVarType(MD), 02699 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 02700 }; 02701 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 02702 } 02703 02704 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name, 02705 const char *Section, 02706 ArrayRef<llvm::Constant*> Methods) { 02707 // Return null for empty list. 02708 if (Methods.empty()) 02709 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 02710 02711 llvm::Constant *Values[3]; 02712 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 02713 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 02714 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 02715 Methods.size()); 02716 Values[2] = llvm::ConstantArray::get(AT, Methods); 02717 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 02718 02719 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 02720 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy); 02721 } 02722 02723 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 02724 const ObjCContainerDecl *CD) { 02725 SmallString<256> Name; 02726 GetNameForMethod(OMD, CD, Name); 02727 02728 CodeGenTypes &Types = CGM.getTypes(); 02729 llvm::FunctionType *MethodTy = 02730 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); 02731 llvm::Function *Method = 02732 llvm::Function::Create(MethodTy, 02733 llvm::GlobalValue::InternalLinkage, 02734 Name.str(), 02735 &CGM.getModule()); 02736 MethodDefinitions.insert(std::make_pair(OMD, Method)); 02737 02738 return Method; 02739 } 02740 02741 llvm::GlobalVariable * 02742 CGObjCCommonMac::CreateMetadataVar(Twine Name, 02743 llvm::Constant *Init, 02744 const char *Section, 02745 unsigned Align, 02746 bool AddToUsed) { 02747 llvm::Type *Ty = Init->getType(); 02748 llvm::GlobalVariable *GV = 02749 new llvm::GlobalVariable(CGM.getModule(), Ty, false, 02750 llvm::GlobalValue::InternalLinkage, Init, Name); 02751 if (Section) 02752 GV->setSection(Section); 02753 if (Align) 02754 GV->setAlignment(Align); 02755 if (AddToUsed) 02756 CGM.AddUsedGlobal(GV); 02757 return GV; 02758 } 02759 02760 llvm::Function *CGObjCMac::ModuleInitFunction() { 02761 // Abuse this interface function as a place to finalize. 02762 FinishModule(); 02763 return NULL; 02764 } 02765 02766 llvm::Constant *CGObjCMac::GetPropertyGetFunction() { 02767 return ObjCTypes.getGetPropertyFn(); 02768 } 02769 02770 llvm::Constant *CGObjCMac::GetPropertySetFunction() { 02771 return ObjCTypes.getSetPropertyFn(); 02772 } 02773 02774 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic, 02775 bool copy) { 02776 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy); 02777 } 02778 02779 llvm::Constant *CGObjCMac::GetGetStructFunction() { 02780 return ObjCTypes.getCopyStructFn(); 02781 } 02782 llvm::Constant *CGObjCMac::GetSetStructFunction() { 02783 return ObjCTypes.getCopyStructFn(); 02784 } 02785 02786 llvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() { 02787 return ObjCTypes.getCppAtomicObjectFunction(); 02788 } 02789 02790 llvm::Constant *CGObjCMac::EnumerationMutationFunction() { 02791 return ObjCTypes.getEnumerationMutationFn(); 02792 } 02793 02794 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) { 02795 return EmitTryOrSynchronizedStmt(CGF, S); 02796 } 02797 02798 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF, 02799 const ObjCAtSynchronizedStmt &S) { 02800 return EmitTryOrSynchronizedStmt(CGF, S); 02801 } 02802 02803 namespace { 02804 struct PerformFragileFinally : EHScopeStack::Cleanup { 02805 const Stmt &S; 02806 llvm::Value *SyncArgSlot; 02807 llvm::Value *CallTryExitVar; 02808 llvm::Value *ExceptionData; 02809 ObjCTypesHelper &ObjCTypes; 02810 PerformFragileFinally(const Stmt *S, 02811 llvm::Value *SyncArgSlot, 02812 llvm::Value *CallTryExitVar, 02813 llvm::Value *ExceptionData, 02814 ObjCTypesHelper *ObjCTypes) 02815 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar), 02816 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {} 02817 02818 void Emit(CodeGenFunction &CGF, Flags flags) { 02819 // Check whether we need to call objc_exception_try_exit. 02820 // In optimized code, this branch will always be folded. 02821 llvm::BasicBlock *FinallyCallExit = 02822 CGF.createBasicBlock("finally.call_exit"); 02823 llvm::BasicBlock *FinallyNoCallExit = 02824 CGF.createBasicBlock("finally.no_call_exit"); 02825 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar), 02826 FinallyCallExit, FinallyNoCallExit); 02827 02828 CGF.EmitBlock(FinallyCallExit); 02829 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData) 02830 ->setDoesNotThrow(); 02831 02832 CGF.EmitBlock(FinallyNoCallExit); 02833 02834 if (isa<ObjCAtTryStmt>(S)) { 02835 if (const ObjCAtFinallyStmt* FinallyStmt = 02836 cast<ObjCAtTryStmt>(S).getFinallyStmt()) { 02837 // Save the current cleanup destination in case there's 02838 // control flow inside the finally statement. 02839 llvm::Value *CurCleanupDest = 02840 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot()); 02841 02842 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 02843 02844 if (CGF.HaveInsertPoint()) { 02845 CGF.Builder.CreateStore(CurCleanupDest, 02846 CGF.getNormalCleanupDestSlot()); 02847 } else { 02848 // Currently, the end of the cleanup must always exist. 02849 CGF.EnsureInsertPoint(); 02850 } 02851 } 02852 } else { 02853 // Emit objc_sync_exit(expr); as finally's sole statement for 02854 // @synchronized. 02855 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot); 02856 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg) 02857 ->setDoesNotThrow(); 02858 } 02859 } 02860 }; 02861 02862 class FragileHazards { 02863 CodeGenFunction &CGF; 02864 SmallVector<llvm::Value*, 20> Locals; 02865 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry; 02866 02867 llvm::InlineAsm *ReadHazard; 02868 llvm::InlineAsm *WriteHazard; 02869 02870 llvm::FunctionType *GetAsmFnType(); 02871 02872 void collectLocals(); 02873 void emitReadHazard(CGBuilderTy &Builder); 02874 02875 public: 02876 FragileHazards(CodeGenFunction &CGF); 02877 02878 void emitWriteHazard(); 02879 void emitHazardsInNewBlocks(); 02880 }; 02881 } 02882 02883 /// Create the fragile-ABI read and write hazards based on the current 02884 /// state of the function, which is presumed to be immediately prior 02885 /// to a @try block. These hazards are used to maintain correct 02886 /// semantics in the face of optimization and the fragile ABI's 02887 /// cavalier use of setjmp/longjmp. 02888 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { 02889 collectLocals(); 02890 02891 if (Locals.empty()) return; 02892 02893 // Collect all the blocks in the function. 02894 for (llvm::Function::iterator 02895 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I) 02896 BlocksBeforeTry.insert(&*I); 02897 02898 llvm::FunctionType *AsmFnTy = GetAsmFnType(); 02899 02900 // Create a read hazard for the allocas. This inhibits dead-store 02901 // optimizations and forces the values to memory. This hazard is 02902 // inserted before any 'throwing' calls in the protected scope to 02903 // reflect the possibility that the variables might be read from the 02904 // catch block if the call throws. 02905 { 02906 std::string Constraint; 02907 for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 02908 if (I) Constraint += ','; 02909 Constraint += "*m"; 02910 } 02911 02912 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 02913 } 02914 02915 // Create a write hazard for the allocas. This inhibits folding 02916 // loads across the hazard. This hazard is inserted at the 02917 // beginning of the catch path to reflect the possibility that the 02918 // variables might have been written within the protected scope. 02919 { 02920 std::string Constraint; 02921 for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 02922 if (I) Constraint += ','; 02923 Constraint += "=*m"; 02924 } 02925 02926 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 02927 } 02928 } 02929 02930 /// Emit a write hazard at the current location. 02931 void FragileHazards::emitWriteHazard() { 02932 if (Locals.empty()) return; 02933 02934 CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow(); 02935 } 02936 02937 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) { 02938 assert(!Locals.empty()); 02939 Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow(); 02940 } 02941 02942 /// Emit read hazards in all the protected blocks, i.e. all the blocks 02943 /// which have been inserted since the beginning of the try. 02944 void FragileHazards::emitHazardsInNewBlocks() { 02945 if (Locals.empty()) return; 02946 02947 CGBuilderTy Builder(CGF.getLLVMContext()); 02948 02949 // Iterate through all blocks, skipping those prior to the try. 02950 for (llvm::Function::iterator 02951 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) { 02952 llvm::BasicBlock &BB = *FI; 02953 if (BlocksBeforeTry.count(&BB)) continue; 02954 02955 // Walk through all the calls in the block. 02956 for (llvm::BasicBlock::iterator 02957 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) { 02958 llvm::Instruction &I = *BI; 02959 02960 // Ignore instructions that aren't non-intrinsic calls. 02961 // These are the only calls that can possibly call longjmp. 02962 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue; 02963 if (isa<llvm::IntrinsicInst>(I)) 02964 continue; 02965 02966 // Ignore call sites marked nounwind. This may be questionable, 02967 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'. 02968 llvm::CallSite CS(&I); 02969 if (CS.doesNotThrow()) continue; 02970 02971 // Insert a read hazard before the call. This will ensure that 02972 // any writes to the locals are performed before making the 02973 // call. If the call throws, then this is sufficient to 02974 // guarantee correctness as long as it doesn't also write to any 02975 // locals. 02976 Builder.SetInsertPoint(&BB, BI); 02977 emitReadHazard(Builder); 02978 } 02979 } 02980 } 02981 02982 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) { 02983 if (V) S.insert(V); 02984 } 02985 02986 void FragileHazards::collectLocals() { 02987 // Compute a set of allocas to ignore. 02988 llvm::DenseSet<llvm::Value*> AllocasToIgnore; 02989 addIfPresent(AllocasToIgnore, CGF.ReturnValue); 02990 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest); 02991 02992 // Collect all the allocas currently in the function. This is 02993 // probably way too aggressive. 02994 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock(); 02995 for (llvm::BasicBlock::iterator 02996 I = Entry.begin(), E = Entry.end(); I != E; ++I) 02997 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I)) 02998 Locals.push_back(&*I); 02999 } 03000 03001 llvm::FunctionType *FragileHazards::GetAsmFnType() { 03002 SmallVector<llvm::Type *, 16> tys(Locals.size()); 03003 for (unsigned i = 0, e = Locals.size(); i != e; ++i) 03004 tys[i] = Locals[i]->getType(); 03005 return llvm::FunctionType::get(CGF.VoidTy, tys, false); 03006 } 03007 03008 /* 03009 03010 Objective-C setjmp-longjmp (sjlj) Exception Handling 03011 -- 03012 03013 A catch buffer is a setjmp buffer plus: 03014 - a pointer to the exception that was caught 03015 - a pointer to the previous exception data buffer 03016 - two pointers of reserved storage 03017 Therefore catch buffers form a stack, with a pointer to the top 03018 of the stack kept in thread-local storage. 03019 03020 objc_exception_try_enter pushes a catch buffer onto the EH stack. 03021 objc_exception_try_exit pops the given catch buffer, which is 03022 required to be the top of the EH stack. 03023 objc_exception_throw pops the top of the EH stack, writes the 03024 thrown exception into the appropriate field, and longjmps 03025 to the setjmp buffer. It crashes the process (with a printf 03026 and an abort()) if there are no catch buffers on the stack. 03027 objc_exception_extract just reads the exception pointer out of the 03028 catch buffer. 03029 03030 There's no reason an implementation couldn't use a light-weight 03031 setjmp here --- something like __builtin_setjmp, but API-compatible 03032 with the heavyweight setjmp. This will be more important if we ever 03033 want to implement correct ObjC/C++ exception interactions for the 03034 fragile ABI. 03035 03036 Note that for this use of setjmp/longjmp to be correct, we may need 03037 to mark some local variables volatile: if a non-volatile local 03038 variable is modified between the setjmp and the longjmp, it has 03039 indeterminate value. For the purposes of LLVM IR, it may be 03040 sufficient to make loads and stores within the @try (to variables 03041 declared outside the @try) volatile. This is necessary for 03042 optimized correctness, but is not currently being done; this is 03043 being tracked as rdar://problem/8160285 03044 03045 The basic framework for a @try-catch-finally is as follows: 03046 { 03047 objc_exception_data d; 03048 id _rethrow = null; 03049 bool _call_try_exit = true; 03050 03051 objc_exception_try_enter(&d); 03052 if (!setjmp(d.jmp_buf)) { 03053 ... try body ... 03054 } else { 03055 // exception path 03056 id _caught = objc_exception_extract(&d); 03057 03058 // enter new try scope for handlers 03059 if (!setjmp(d.jmp_buf)) { 03060 ... match exception and execute catch blocks ... 03061 03062 // fell off end, rethrow. 03063 _rethrow = _caught; 03064 ... jump-through-finally to finally_rethrow ... 03065 } else { 03066 // exception in catch block 03067 _rethrow = objc_exception_extract(&d); 03068 _call_try_exit = false; 03069 ... jump-through-finally to finally_rethrow ... 03070 } 03071 } 03072 ... jump-through-finally to finally_end ... 03073 03074 finally: 03075 if (_call_try_exit) 03076 objc_exception_try_exit(&d); 03077 03078 ... finally block .... 03079 ... dispatch to finally destination ... 03080 03081 finally_rethrow: 03082 objc_exception_throw(_rethrow); 03083 03084 finally_end: 03085 } 03086 03087 This framework differs slightly from the one gcc uses, in that gcc 03088 uses _rethrow to determine if objc_exception_try_exit should be called 03089 and if the object should be rethrown. This breaks in the face of 03090 throwing nil and introduces unnecessary branches. 03091 03092 We specialize this framework for a few particular circumstances: 03093 03094 - If there are no catch blocks, then we avoid emitting the second 03095 exception handling context. 03096 03097 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 03098 e)) we avoid emitting the code to rethrow an uncaught exception. 03099 03100 - FIXME: If there is no @finally block we can do a few more 03101 simplifications. 03102 03103 Rethrows and Jumps-Through-Finally 03104 -- 03105 03106 '@throw;' is supported by pushing the currently-caught exception 03107 onto ObjCEHStack while the @catch blocks are emitted. 03108 03109 Branches through the @finally block are handled with an ordinary 03110 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC 03111 exceptions are not compatible with C++ exceptions, and this is 03112 hardly the only place where this will go wrong. 03113 03114 @synchronized(expr) { stmt; } is emitted as if it were: 03115 id synch_value = expr; 03116 objc_sync_enter(synch_value); 03117 @try { stmt; } @finally { objc_sync_exit(synch_value); } 03118 */ 03119 03120 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 03121 const Stmt &S) { 03122 bool isTry = isa<ObjCAtTryStmt>(S); 03123 03124 // A destination for the fall-through edges of the catch handlers to 03125 // jump to. 03126 CodeGenFunction::JumpDest FinallyEnd = 03127 CGF.getJumpDestInCurrentScope("finally.end"); 03128 03129 // A destination for the rethrow edge of the catch handlers to jump 03130 // to. 03131 CodeGenFunction::JumpDest FinallyRethrow = 03132 CGF.getJumpDestInCurrentScope("finally.rethrow"); 03133 03134 // For @synchronized, call objc_sync_enter(sync.expr). The 03135 // evaluation of the expression must occur before we enter the 03136 // @synchronized. We can't avoid a temp here because we need the 03137 // value to be preserved. If the backend ever does liveness 03138 // correctly after setjmp, this will be unnecessary. 03139 llvm::Value *SyncArgSlot = 0; 03140 if (!isTry) { 03141 llvm::Value *SyncArg = 03142 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 03143 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 03144 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg) 03145 ->setDoesNotThrow(); 03146 03147 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg"); 03148 CGF.Builder.CreateStore(SyncArg, SyncArgSlot); 03149 } 03150 03151 // Allocate memory for the setjmp buffer. This needs to be kept 03152 // live throughout the try and catch blocks. 03153 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 03154 "exceptiondata.ptr"); 03155 03156 // Create the fragile hazards. Note that this will not capture any 03157 // of the allocas required for exception processing, but will 03158 // capture the current basic block (which extends all the way to the 03159 // setjmp call) as "before the @try". 03160 FragileHazards Hazards(CGF); 03161 03162 // Create a flag indicating whether the cleanup needs to call 03163 // objc_exception_try_exit. This is true except when 03164 // - no catches match and we're branching through the cleanup 03165 // just to rethrow the exception, or 03166 // - a catch matched and we're falling out of the catch handler. 03167 // The setjmp-safety rule here is that we should always store to this 03168 // variable in a place that dominates the branch through the cleanup 03169 // without passing through any setjmps. 03170 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), 03171 "_call_try_exit"); 03172 03173 // A slot containing the exception to rethrow. Only needed when we 03174 // have both a @catch and a @finally. 03175 llvm::Value *PropagatingExnVar = 0; 03176 03177 // Push a normal cleanup to leave the try scope. 03178 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S, 03179 SyncArgSlot, 03180 CallTryExitVar, 03181 ExceptionData, 03182 &ObjCTypes); 03183 03184 // Enter a try block: 03185 // - Call objc_exception_try_enter to push ExceptionData on top of 03186 // the EH stack. 03187 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 03188 ->setDoesNotThrow(); 03189 03190 // - Call setjmp on the exception data buffer. 03191 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); 03192 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; 03193 llvm::Value *SetJmpBuffer = 03194 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer"); 03195 llvm::CallInst *SetJmpResult = 03196 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); 03197 SetJmpResult->setDoesNotThrow(); 03198 SetJmpResult->setCanReturnTwice(); 03199 03200 // If setjmp returned 0, enter the protected block; otherwise, 03201 // branch to the handler. 03202 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 03203 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 03204 llvm::Value *DidCatch = 03205 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 03206 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock); 03207 03208 // Emit the protected block. 03209 CGF.EmitBlock(TryBlock); 03210 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 03211 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 03212 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 03213 03214 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP(); 03215 03216 // Emit the exception handler block. 03217 CGF.EmitBlock(TryHandler); 03218 03219 // Don't optimize loads of the in-scope locals across this point. 03220 Hazards.emitWriteHazard(); 03221 03222 // For a @synchronized (or a @try with no catches), just branch 03223 // through the cleanup to the rethrow block. 03224 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) { 03225 // Tell the cleanup not to re-pop the exit. 03226 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 03227 CGF.EmitBranchThroughCleanup(FinallyRethrow); 03228 03229 // Otherwise, we have to match against the caught exceptions. 03230 } else { 03231 // Retrieve the exception object. We may emit multiple blocks but 03232 // nothing can cross this so the value is already in SSA form. 03233 llvm::CallInst *Caught = 03234 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 03235 ExceptionData, "caught"); 03236 Caught->setDoesNotThrow(); 03237 03238 // Push the exception to rethrow onto the EH value stack for the 03239 // benefit of any @throws in the handlers. 03240 CGF.ObjCEHValueStack.push_back(Caught); 03241 03242 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S); 03243 03244 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0); 03245 03246 llvm::BasicBlock *CatchBlock = 0; 03247 llvm::BasicBlock *CatchHandler = 0; 03248 if (HasFinally) { 03249 // Save the currently-propagating exception before 03250 // objc_exception_try_enter clears the exception slot. 03251 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(), 03252 "propagating_exception"); 03253 CGF.Builder.CreateStore(Caught, PropagatingExnVar); 03254 03255 // Enter a new exception try block (in case a @catch block 03256 // throws an exception). 03257 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 03258 ->setDoesNotThrow(); 03259 03260 llvm::CallInst *SetJmpResult = 03261 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, 03262 "setjmp.result"); 03263 SetJmpResult->setDoesNotThrow(); 03264 SetJmpResult->setCanReturnTwice(); 03265 03266 llvm::Value *Threw = 03267 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 03268 03269 CatchBlock = CGF.createBasicBlock("catch"); 03270 CatchHandler = CGF.createBasicBlock("catch_for_catch"); 03271 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 03272 03273 CGF.EmitBlock(CatchBlock); 03274 } 03275 03276 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar); 03277 03278 // Handle catch list. As a special case we check if everything is 03279 // matched and avoid generating code for falling off the end if 03280 // so. 03281 bool AllMatched = false; 03282 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) { 03283 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I); 03284 03285 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 03286 const ObjCObjectPointerType *OPT = 0; 03287 03288 // catch(...) always matches. 03289 if (!CatchParam) { 03290 AllMatched = true; 03291 } else { 03292 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>(); 03293 03294 // catch(id e) always matches under this ABI, since only 03295 // ObjC exceptions end up here in the first place. 03296 // FIXME: For the time being we also match id<X>; this should 03297 // be rejected by Sema instead. 03298 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())) 03299 AllMatched = true; 03300 } 03301 03302 // If this is a catch-all, we don't need to test anything. 03303 if (AllMatched) { 03304 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 03305 03306 if (CatchParam) { 03307 CGF.EmitAutoVarDecl(*CatchParam); 03308 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 03309 03310 // These types work out because ConvertType(id) == i8*. 03311 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 03312 } 03313 03314 CGF.EmitStmt(CatchStmt->getCatchBody()); 03315 03316 // The scope of the catch variable ends right here. 03317 CatchVarCleanups.ForceCleanup(); 03318 03319 CGF.EmitBranchThroughCleanup(FinallyEnd); 03320 break; 03321 } 03322 03323 assert(OPT && "Unexpected non-object pointer type in @catch"); 03324 const ObjCObjectType *ObjTy = OPT->getObjectType(); 03325 03326 // FIXME: @catch (Class c) ? 03327 ObjCInterfaceDecl *IDecl = ObjTy->getInterface(); 03328 assert(IDecl && "Catch parameter must have Objective-C type!"); 03329 03330 // Check if the @catch block matches the exception object. 03331 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl); 03332 03333 llvm::CallInst *Match = 03334 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 03335 Class, Caught, "match"); 03336 Match->setDoesNotThrow(); 03337 03338 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match"); 03339 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next"); 03340 03341 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 03342 MatchedBlock, NextCatchBlock); 03343 03344 // Emit the @catch block. 03345 CGF.EmitBlock(MatchedBlock); 03346 03347 // Collect any cleanups for the catch variable. The scope lasts until 03348 // the end of the catch body. 03349 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 03350 03351 CGF.EmitAutoVarDecl(*CatchParam); 03352 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 03353 03354 // Initialize the catch variable. 03355 llvm::Value *Tmp = 03356 CGF.Builder.CreateBitCast(Caught, 03357 CGF.ConvertType(CatchParam->getType())); 03358 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 03359 03360 CGF.EmitStmt(CatchStmt->getCatchBody()); 03361 03362 // We're done with the catch variable. 03363 CatchVarCleanups.ForceCleanup(); 03364 03365 CGF.EmitBranchThroughCleanup(FinallyEnd); 03366 03367 CGF.EmitBlock(NextCatchBlock); 03368 } 03369 03370 CGF.ObjCEHValueStack.pop_back(); 03371 03372 // If nothing wanted anything to do with the caught exception, 03373 // kill the extract call. 03374 if (Caught->use_empty()) 03375 Caught->eraseFromParent(); 03376 03377 if (!AllMatched) 03378 CGF.EmitBranchThroughCleanup(FinallyRethrow); 03379 03380 if (HasFinally) { 03381 // Emit the exception handler for the @catch blocks. 03382 CGF.EmitBlock(CatchHandler); 03383 03384 // In theory we might now need a write hazard, but actually it's 03385 // unnecessary because there's no local-accessing code between 03386 // the try's write hazard and here. 03387 //Hazards.emitWriteHazard(); 03388 03389 // Extract the new exception and save it to the 03390 // propagating-exception slot. 03391 assert(PropagatingExnVar); 03392 llvm::CallInst *NewCaught = 03393 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 03394 ExceptionData, "caught"); 03395 NewCaught->setDoesNotThrow(); 03396 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar); 03397 03398 // Don't pop the catch handler; the throw already did. 03399 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 03400 CGF.EmitBranchThroughCleanup(FinallyRethrow); 03401 } 03402 } 03403 03404 // Insert read hazards as required in the new blocks. 03405 Hazards.emitHazardsInNewBlocks(); 03406 03407 // Pop the cleanup. 03408 CGF.Builder.restoreIP(TryFallthroughIP); 03409 if (CGF.HaveInsertPoint()) 03410 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 03411 CGF.PopCleanupBlock(); 03412 CGF.EmitBlock(FinallyEnd.getBlock(), true); 03413 03414 // Emit the rethrow block. 03415 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 03416 CGF.EmitBlock(FinallyRethrow.getBlock(), true); 03417 if (CGF.HaveInsertPoint()) { 03418 // If we have a propagating-exception variable, check it. 03419 llvm::Value *PropagatingExn; 03420 if (PropagatingExnVar) { 03421 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar); 03422 03423 // Otherwise, just look in the buffer for the exception to throw. 03424 } else { 03425 llvm::CallInst *Caught = 03426 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 03427 ExceptionData); 03428 Caught->setDoesNotThrow(); 03429 PropagatingExn = Caught; 03430 } 03431 03432 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn) 03433 ->setDoesNotThrow(); 03434 CGF.Builder.CreateUnreachable(); 03435 } 03436 03437 CGF.Builder.restoreIP(SavedIP); 03438 } 03439 03440 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 03441 const ObjCAtThrowStmt &S) { 03442 llvm::Value *ExceptionAsObject; 03443 03444 if (const Expr *ThrowExpr = S.getThrowExpr()) { 03445 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 03446 ExceptionAsObject = 03447 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 03448 } else { 03449 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 03450 "Unexpected rethrow outside @catch block."); 03451 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 03452 } 03453 03454 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject) 03455 ->setDoesNotReturn(); 03456 CGF.Builder.CreateUnreachable(); 03457 03458 // Clear the insertion point to indicate we are in unreachable code. 03459 CGF.Builder.ClearInsertionPoint(); 03460 } 03461 03462 /// EmitObjCWeakRead - Code gen for loading value of a __weak 03463 /// object: objc_read_weak (id *src) 03464 /// 03465 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 03466 llvm::Value *AddrWeakObj) { 03467 llvm::Type* DestTy = 03468 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 03469 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, 03470 ObjCTypes.PtrObjectPtrTy); 03471 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 03472 AddrWeakObj, "weakread"); 03473 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 03474 return read_weak; 03475 } 03476 03477 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 03478 /// objc_assign_weak (id src, id *dst) 03479 /// 03480 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 03481 llvm::Value *src, llvm::Value *dst) { 03482 llvm::Type * SrcTy = src->getType(); 03483 if (!isa<llvm::PointerType>(SrcTy)) { 03484 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 03485 assert(Size <= 8 && "does not support size > 8"); 03486 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 03487 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 03488 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 03489 } 03490 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 03491 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 03492 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 03493 src, dst, "weakassign"); 03494 return; 03495 } 03496 03497 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 03498 /// objc_assign_global (id src, id *dst) 03499 /// 03500 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 03501 llvm::Value *src, llvm::Value *dst, 03502 bool threadlocal) { 03503 llvm::Type * SrcTy = src->getType(); 03504 if (!isa<llvm::PointerType>(SrcTy)) { 03505 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 03506 assert(Size <= 8 && "does not support size > 8"); 03507 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 03508 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 03509 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 03510 } 03511 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 03512 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 03513 if (!threadlocal) 03514 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 03515 src, dst, "globalassign"); 03516 else 03517 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 03518 src, dst, "threadlocalassign"); 03519 return; 03520 } 03521 03522 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 03523 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) 03524 /// 03525 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 03526 llvm::Value *src, llvm::Value *dst, 03527 llvm::Value *ivarOffset) { 03528 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); 03529 llvm::Type * SrcTy = src->getType(); 03530 if (!isa<llvm::PointerType>(SrcTy)) { 03531 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 03532 assert(Size <= 8 && "does not support size > 8"); 03533 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 03534 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 03535 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 03536 } 03537 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 03538 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 03539 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 03540 src, dst, ivarOffset); 03541 return; 03542 } 03543 03544 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 03545 /// objc_assign_strongCast (id src, id *dst) 03546 /// 03547 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 03548 llvm::Value *src, llvm::Value *dst) { 03549 llvm::Type * SrcTy = src->getType(); 03550 if (!isa<llvm::PointerType>(SrcTy)) { 03551 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 03552 assert(Size <= 8 && "does not support size > 8"); 03553 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 03554 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 03555 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 03556 } 03557 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 03558 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 03559 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 03560 src, dst, "weakassign"); 03561 return; 03562 } 03563 03564 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 03565 llvm::Value *DestPtr, 03566 llvm::Value *SrcPtr, 03567 llvm::Value *size) { 03568 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 03569 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 03570 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 03571 DestPtr, SrcPtr, size); 03572 return; 03573 } 03574 03575 /// EmitObjCValueForIvar - Code Gen for ivar reference. 03576 /// 03577 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 03578 QualType ObjectTy, 03579 llvm::Value *BaseValue, 03580 const ObjCIvarDecl *Ivar, 03581 unsigned CVRQualifiers) { 03582 const ObjCInterfaceDecl *ID = 03583 ObjectTy->getAs<ObjCObjectType>()->getInterface(); 03584 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 03585 EmitIvarOffset(CGF, ID, Ivar)); 03586 } 03587 03588 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 03589 const ObjCInterfaceDecl *Interface, 03590 const ObjCIvarDecl *Ivar) { 03591 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 03592 return llvm::ConstantInt::get( 03593 CGM.getTypes().ConvertType(CGM.getContext().LongTy), 03594 Offset); 03595 } 03596 03597 /* *** Private Interface *** */ 03598 03599 /// EmitImageInfo - Emit the image info marker used to encode some module 03600 /// level information. 03601 /// 03602 /// See: <rdr://4810609&4810587&4810587> 03603 /// struct IMAGE_INFO { 03604 /// unsigned version; 03605 /// unsigned flags; 03606 /// }; 03607 enum ImageInfoFlags { 03608 eImageInfo_FixAndContinue = (1 << 0), 03609 eImageInfo_GarbageCollected = (1 << 1), 03610 eImageInfo_GCOnly = (1 << 2), 03611 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 03612 03613 // A flag indicating that the module has no instances of a @synthesize of a 03614 // superclass variable. <rdar://problem/6803242> 03615 eImageInfo_CorrectedSynthesize = (1 << 4), 03616 eImageInfo_ImageIsSimulated = (1 << 5) 03617 }; 03618 03619 void CGObjCCommonMac::EmitImageInfo() { 03620 unsigned version = 0; // Version is unused? 03621 const char *Section = (ObjCABI == 1) ? 03622 "__OBJC, __image_info,regular" : 03623 "__DATA, __objc_imageinfo, regular, no_dead_strip"; 03624 03625 // Generate module-level named metadata to convey this information to the 03626 // linker and code-gen. 03627 llvm::Module &Mod = CGM.getModule(); 03628 03629 // Add the ObjC ABI version to the module flags. 03630 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI); 03631 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version", 03632 version); 03633 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section", 03634 llvm::MDString::get(VMContext,Section)); 03635 03636 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 03637 // Non-GC overrides those files which specify GC. 03638 Mod.addModuleFlag(llvm::Module::Override, 03639 "Objective-C Garbage Collection", (uint32_t)0); 03640 } else { 03641 // Add the ObjC garbage collection value. 03642 Mod.addModuleFlag(llvm::Module::Error, 03643 "Objective-C Garbage Collection", 03644 eImageInfo_GarbageCollected); 03645 03646 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 03647 // Add the ObjC GC Only value. 03648 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only", 03649 eImageInfo_GCOnly); 03650 03651 // Require that GC be specified and set to eImageInfo_GarbageCollected. 03652 llvm::Value *Ops[2] = { 03653 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"), 03654 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 03655 eImageInfo_GarbageCollected) 03656 }; 03657 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only", 03658 llvm::MDNode::get(VMContext, Ops)); 03659 } 03660 } 03661 03662 // Indicate whether we're compiling this to run on a simulator. 03663 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 03664 if (Triple.getOS() == llvm::Triple::IOS && 03665 (Triple.getArch() == llvm::Triple::x86 || 03666 Triple.getArch() == llvm::Triple::x86_64)) 03667 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated", 03668 eImageInfo_ImageIsSimulated); 03669 } 03670 03671 // struct objc_module { 03672 // unsigned long version; 03673 // unsigned long size; 03674 // const char *name; 03675 // Symtab symtab; 03676 // }; 03677 03678 // FIXME: Get from somewhere 03679 static const int ModuleVersion = 7; 03680 03681 void CGObjCMac::EmitModuleInfo() { 03682 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 03683 03684 llvm::Constant *Values[] = { 03685 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion), 03686 llvm::ConstantInt::get(ObjCTypes.LongTy, Size), 03687 // This used to be the filename, now it is unused. <rdr://4327263> 03688 GetClassName(&CGM.getContext().Idents.get("")), 03689 EmitModuleSymbols() 03690 }; 03691 CreateMetadataVar("\01L_OBJC_MODULES", 03692 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 03693 "__OBJC,__module_info,regular,no_dead_strip", 03694 4, true); 03695 } 03696 03697 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 03698 unsigned NumClasses = DefinedClasses.size(); 03699 unsigned NumCategories = DefinedCategories.size(); 03700 03701 // Return null if no symbols were defined. 03702 if (!NumClasses && !NumCategories) 03703 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 03704 03705 llvm::Constant *Values[5]; 03706 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 03707 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 03708 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 03709 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 03710 03711 // The runtime expects exactly the list of defined classes followed 03712 // by the list of defined categories, in a single array. 03713 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories); 03714 for (unsigned i=0; i<NumClasses; i++) 03715 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 03716 ObjCTypes.Int8PtrTy); 03717 for (unsigned i=0; i<NumCategories; i++) 03718 Symbols[NumClasses + i] = 03719 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 03720 ObjCTypes.Int8PtrTy); 03721 03722 Values[4] = 03723 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 03724 Symbols.size()), 03725 Symbols); 03726 03727 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 03728 03729 llvm::GlobalVariable *GV = 03730 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 03731 "__OBJC,__symbols,regular,no_dead_strip", 03732 4, true); 03733 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 03734 } 03735 03736 llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder, 03737 IdentifierInfo *II) { 03738 LazySymbols.insert(II); 03739 03740 llvm::GlobalVariable *&Entry = ClassReferences[II]; 03741 03742 if (!Entry) { 03743 llvm::Constant *Casted = 03744 llvm::ConstantExpr::getBitCast(GetClassName(II), 03745 ObjCTypes.ClassPtrTy); 03746 Entry = 03747 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 03748 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 03749 4, true); 03750 } 03751 03752 return Builder.CreateLoad(Entry); 03753 } 03754 03755 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 03756 const ObjCInterfaceDecl *ID) { 03757 return EmitClassRefFromId(Builder, ID->getIdentifier()); 03758 } 03759 03760 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) { 03761 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 03762 return EmitClassRefFromId(Builder, II); 03763 } 03764 03765 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel, 03766 bool lvalue) { 03767 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 03768 03769 if (!Entry) { 03770 llvm::Constant *Casted = 03771 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 03772 ObjCTypes.SelectorPtrTy); 03773 Entry = 03774 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 03775 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 03776 4, true); 03777 } 03778 03779 if (lvalue) 03780 return Entry; 03781 return Builder.CreateLoad(Entry); 03782 } 03783 03784 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 03785 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 03786 03787 if (!Entry) 03788 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 03789 llvm::ConstantDataArray::getString(VMContext, 03790 Ident->getNameStart()), 03791 ((ObjCABI == 2) ? 03792 "__TEXT,__objc_classname,cstring_literals" : 03793 "__TEXT,__cstring,cstring_literals"), 03794 1, true); 03795 03796 return getConstantGEP(VMContext, Entry, 0, 0); 03797 } 03798 03799 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 03800 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 03801 I = MethodDefinitions.find(MD); 03802 if (I != MethodDefinitions.end()) 03803 return I->second; 03804 03805 return NULL; 03806 } 03807 03808 /// GetIvarLayoutName - Returns a unique constant for the given 03809 /// ivar layout bitmap. 03810 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 03811 const ObjCCommonTypesHelper &ObjCTypes) { 03812 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 03813 } 03814 03815 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 03816 unsigned int BytePos, 03817 bool ForStrongLayout, 03818 bool &HasUnion) { 03819 const RecordDecl *RD = RT->getDecl(); 03820 // FIXME - Use iterator. 03821 SmallVector<const FieldDecl*, 16> Fields; 03822 for (RecordDecl::field_iterator i = RD->field_begin(), 03823 e = RD->field_end(); i != e; ++i) 03824 Fields.push_back(&*i); 03825 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 03826 const llvm::StructLayout *RecLayout = 03827 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 03828 03829 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 03830 ForStrongLayout, HasUnion); 03831 } 03832 03833 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 03834 const llvm::StructLayout *Layout, 03835 const RecordDecl *RD, 03836 ArrayRef<const FieldDecl*> RecFields, 03837 unsigned int BytePos, bool ForStrongLayout, 03838 bool &HasUnion) { 03839 bool IsUnion = (RD && RD->isUnion()); 03840 uint64_t MaxUnionIvarSize = 0; 03841 uint64_t MaxSkippedUnionIvarSize = 0; 03842 const FieldDecl *MaxField = 0; 03843 const FieldDecl *MaxSkippedField = 0; 03844 const FieldDecl *LastFieldBitfieldOrUnnamed = 0; 03845 uint64_t MaxFieldOffset = 0; 03846 uint64_t MaxSkippedFieldOffset = 0; 03847 uint64_t LastBitfieldOrUnnamedOffset = 0; 03848 uint64_t FirstFieldDelta = 0; 03849 03850 if (RecFields.empty()) 03851 return; 03852 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 03853 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 03854 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) { 03855 const FieldDecl *FirstField = RecFields[0]; 03856 FirstFieldDelta = 03857 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField)); 03858 } 03859 03860 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 03861 const FieldDecl *Field = RecFields[i]; 03862 uint64_t FieldOffset; 03863 if (RD) { 03864 // Note that 'i' here is actually the field index inside RD of Field, 03865 // although this dependency is hidden. 03866 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); 03867 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta; 03868 } else 03869 FieldOffset = 03870 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta; 03871 03872 // Skip over unnamed or bitfields 03873 if (!Field->getIdentifier() || Field->isBitField()) { 03874 LastFieldBitfieldOrUnnamed = Field; 03875 LastBitfieldOrUnnamedOffset = FieldOffset; 03876 continue; 03877 } 03878 03879 LastFieldBitfieldOrUnnamed = 0; 03880 QualType FQT = Field->getType(); 03881 if (FQT->isRecordType() || FQT->isUnionType()) { 03882 if (FQT->isUnionType()) 03883 HasUnion = true; 03884 03885 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), 03886 BytePos + FieldOffset, 03887 ForStrongLayout, HasUnion); 03888 continue; 03889 } 03890 03891 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 03892 const ConstantArrayType *CArray = 03893 dyn_cast_or_null<ConstantArrayType>(Array); 03894 uint64_t ElCount = CArray->getSize().getZExtValue(); 03895 assert(CArray && "only array with known element size is supported"); 03896 FQT = CArray->getElementType(); 03897 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 03898 const ConstantArrayType *CArray = 03899 dyn_cast_or_null<ConstantArrayType>(Array); 03900 ElCount *= CArray->getSize().getZExtValue(); 03901 FQT = CArray->getElementType(); 03902 } 03903 03904 assert(!FQT->isUnionType() && 03905 "layout for array of unions not supported"); 03906 if (FQT->isRecordType() && ElCount) { 03907 int OldIndex = IvarsInfo.size() - 1; 03908 int OldSkIndex = SkipIvars.size() -1; 03909 03910 const RecordType *RT = FQT->getAs<RecordType>(); 03911 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 03912 ForStrongLayout, HasUnion); 03913 03914 // Replicate layout information for each array element. Note that 03915 // one element is already done. 03916 uint64_t ElIx = 1; 03917 for (int FirstIndex = IvarsInfo.size() - 1, 03918 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 03919 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 03920 for (int i = OldIndex+1; i <= FirstIndex; ++i) 03921 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 03922 IvarsInfo[i].ivar_size)); 03923 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 03924 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 03925 SkipIvars[i].ivar_size)); 03926 } 03927 continue; 03928 } 03929 } 03930 // At this point, we are done with Record/Union and array there of. 03931 // For other arrays we are down to its element type. 03932 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 03933 03934 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 03935 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 03936 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 03937 if (IsUnion) { 03938 uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 03939 if (UnionIvarSize > MaxUnionIvarSize) { 03940 MaxUnionIvarSize = UnionIvarSize; 03941 MaxField = Field; 03942 MaxFieldOffset = FieldOffset; 03943 } 03944 } else { 03945 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 03946 FieldSize / WordSizeInBits)); 03947 } 03948 } else if ((ForStrongLayout && 03949 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) 03950 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { 03951 if (IsUnion) { 03952 // FIXME: Why the asymmetry? We divide by word size in bits on other 03953 // side. 03954 uint64_t UnionIvarSize = FieldSize; 03955 if (UnionIvarSize > MaxSkippedUnionIvarSize) { 03956 MaxSkippedUnionIvarSize = UnionIvarSize; 03957 MaxSkippedField = Field; 03958 MaxSkippedFieldOffset = FieldOffset; 03959 } 03960 } else { 03961 // FIXME: Why the asymmetry, we divide by byte size in bits here? 03962 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 03963 FieldSize / ByteSizeInBits)); 03964 } 03965 } 03966 } 03967 03968 if (LastFieldBitfieldOrUnnamed) { 03969 if (LastFieldBitfieldOrUnnamed->isBitField()) { 03970 // Last field was a bitfield. Must update skip info. 03971 uint64_t BitFieldSize 03972 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); 03973 GC_IVAR skivar; 03974 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; 03975 skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 03976 + ((BitFieldSize % ByteSizeInBits) != 0); 03977 SkipIvars.push_back(skivar); 03978 } else { 03979 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); 03980 // Last field was unnamed. Must update skip info. 03981 unsigned FieldSize 03982 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); 03983 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, 03984 FieldSize / ByteSizeInBits)); 03985 } 03986 } 03987 03988 if (MaxField) 03989 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 03990 MaxUnionIvarSize)); 03991 if (MaxSkippedField) 03992 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 03993 MaxSkippedUnionIvarSize)); 03994 } 03995 03996 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all 03997 /// the computations and returning the layout bitmap (for ivar or blocks) in 03998 /// the given argument BitMap string container. Routine reads 03999 /// two containers, IvarsInfo and SkipIvars which are assumed to be 04000 /// filled already by the caller. 04001 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { 04002 unsigned int WordsToScan, WordsToSkip; 04003 llvm::Type *PtrTy = CGM.Int8PtrTy; 04004 04005 // Build the string of skip/scan nibbles 04006 SmallVector<SKIP_SCAN, 32> SkipScanIvars; 04007 unsigned int WordSize = 04008 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 04009 if (IvarsInfo[0].ivar_bytepos == 0) { 04010 WordsToSkip = 0; 04011 WordsToScan = IvarsInfo[0].ivar_size; 04012 } else { 04013 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 04014 WordsToScan = IvarsInfo[0].ivar_size; 04015 } 04016 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 04017 unsigned int TailPrevGCObjC = 04018 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 04019 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 04020 // consecutive 'scanned' object pointers. 04021 WordsToScan += IvarsInfo[i].ivar_size; 04022 } else { 04023 // Skip over 'gc'able object pointer which lay over each other. 04024 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 04025 continue; 04026 // Must skip over 1 or more words. We save current skip/scan values 04027 // and start a new pair. 04028 SKIP_SCAN SkScan; 04029 SkScan.skip = WordsToSkip; 04030 SkScan.scan = WordsToScan; 04031 SkipScanIvars.push_back(SkScan); 04032 04033 // Skip the hole. 04034 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 04035 SkScan.scan = 0; 04036 SkipScanIvars.push_back(SkScan); 04037 WordsToSkip = 0; 04038 WordsToScan = IvarsInfo[i].ivar_size; 04039 } 04040 } 04041 if (WordsToScan > 0) { 04042 SKIP_SCAN SkScan; 04043 SkScan.skip = WordsToSkip; 04044 SkScan.scan = WordsToScan; 04045 SkipScanIvars.push_back(SkScan); 04046 } 04047 04048 if (!SkipIvars.empty()) { 04049 unsigned int LastIndex = SkipIvars.size()-1; 04050 int LastByteSkipped = 04051 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 04052 LastIndex = IvarsInfo.size()-1; 04053 int LastByteScanned = 04054 IvarsInfo[LastIndex].ivar_bytepos + 04055 IvarsInfo[LastIndex].ivar_size * WordSize; 04056 // Compute number of bytes to skip at the tail end of the last ivar scanned. 04057 if (LastByteSkipped > LastByteScanned) { 04058 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 04059 SKIP_SCAN SkScan; 04060 SkScan.skip = TotalWords - (LastByteScanned/WordSize); 04061 SkScan.scan = 0; 04062 SkipScanIvars.push_back(SkScan); 04063 } 04064 } 04065 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 04066 // as 0xMN. 04067 int SkipScan = SkipScanIvars.size()-1; 04068 for (int i = 0; i <= SkipScan; i++) { 04069 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 04070 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 04071 // 0xM0 followed by 0x0N detected. 04072 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 04073 for (int j = i+1; j < SkipScan; j++) 04074 SkipScanIvars[j] = SkipScanIvars[j+1]; 04075 --SkipScan; 04076 } 04077 } 04078 04079 // Generate the string. 04080 for (int i = 0; i <= SkipScan; i++) { 04081 unsigned char byte; 04082 unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 04083 unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 04084 unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 04085 unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 04086 04087 // first skip big. 04088 for (unsigned int ix = 0; ix < skip_big; ix++) 04089 BitMap += (unsigned char)(0xf0); 04090 04091 // next (skip small, scan) 04092 if (skip_small) { 04093 byte = skip_small << 4; 04094 if (scan_big > 0) { 04095 byte |= 0xf; 04096 --scan_big; 04097 } else if (scan_small) { 04098 byte |= scan_small; 04099 scan_small = 0; 04100 } 04101 BitMap += byte; 04102 } 04103 // next scan big 04104 for (unsigned int ix = 0; ix < scan_big; ix++) 04105 BitMap += (unsigned char)(0x0f); 04106 // last scan small 04107 if (scan_small) { 04108 byte = scan_small; 04109 BitMap += byte; 04110 } 04111 } 04112 // null terminate string. 04113 unsigned char zero = 0; 04114 BitMap += zero; 04115 04116 llvm::GlobalVariable * Entry = 04117 CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 04118 llvm::ConstantDataArray::getString(VMContext, BitMap,false), 04119 ((ObjCABI == 2) ? 04120 "__TEXT,__objc_classname,cstring_literals" : 04121 "__TEXT,__cstring,cstring_literals"), 04122 1, true); 04123 return getConstantGEP(VMContext, Entry, 0, 0); 04124 } 04125 04126 /// BuildIvarLayout - Builds ivar layout bitmap for the class 04127 /// implementation for the __strong or __weak case. 04128 /// The layout map displays which words in ivar list must be skipped 04129 /// and which must be scanned by GC (see below). String is built of bytes. 04130 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 04131 /// of words to skip and right nibble is count of words to scan. So, each 04132 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is 04133 /// represented by a 0x00 byte which also ends the string. 04134 /// 1. when ForStrongLayout is true, following ivars are scanned: 04135 /// - id, Class 04136 /// - object * 04137 /// - __strong anything 04138 /// 04139 /// 2. When ForStrongLayout is false, following ivars are scanned: 04140 /// - __weak anything 04141 /// 04142 llvm::Constant *CGObjCCommonMac::BuildIvarLayout( 04143 const ObjCImplementationDecl *OMD, 04144 bool ForStrongLayout) { 04145 bool hasUnion = false; 04146 04147 llvm::Type *PtrTy = CGM.Int8PtrTy; 04148 if (CGM.getLangOpts().getGC() == LangOptions::NonGC && 04149 !CGM.getLangOpts().ObjCAutoRefCount) 04150 return llvm::Constant::getNullValue(PtrTy); 04151 04152 const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 04153 SmallVector<const FieldDecl*, 32> RecFields; 04154 if (CGM.getLangOpts().ObjCAutoRefCount) { 04155 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); 04156 IVD; IVD = IVD->getNextIvar()) 04157 RecFields.push_back(cast<FieldDecl>(IVD)); 04158 } 04159 else { 04160 SmallVector<const ObjCIvarDecl*, 32> Ivars; 04161 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars); 04162 04163 // FIXME: This is not ideal; we shouldn't have to do this copy. 04164 RecFields.append(Ivars.begin(), Ivars.end()); 04165 } 04166 04167 if (RecFields.empty()) 04168 return llvm::Constant::getNullValue(PtrTy); 04169 04170 SkipIvars.clear(); 04171 IvarsInfo.clear(); 04172 04173 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); 04174 if (IvarsInfo.empty()) 04175 return llvm::Constant::getNullValue(PtrTy); 04176 // Sort on byte position in case we encounterred a union nested in 04177 // the ivar list. 04178 if (hasUnion && !IvarsInfo.empty()) 04179 std::sort(IvarsInfo.begin(), IvarsInfo.end()); 04180 if (hasUnion && !SkipIvars.empty()) 04181 std::sort(SkipIvars.begin(), SkipIvars.end()); 04182 04183 std::string BitMap; 04184 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 04185 04186 if (CGM.getLangOpts().ObjCGCBitmapPrint) { 04187 printf("\n%s ivar layout for class '%s': ", 04188 ForStrongLayout ? "strong" : "weak", 04189 OMD->getClassInterface()->getName().data()); 04190 const unsigned char *s = (unsigned char*)BitMap.c_str(); 04191 for (unsigned i = 0, e = BitMap.size(); i < e; i++) 04192 if (!(s[i] & 0xf0)) 04193 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 04194 else 04195 printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 04196 printf("\n"); 04197 } 04198 return C; 04199 } 04200 04201 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 04202 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 04203 04204 // FIXME: Avoid std::string in "Sel.getAsString()" 04205 if (!Entry) 04206 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_", 04207 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()), 04208 ((ObjCABI == 2) ? 04209 "__TEXT,__objc_methname,cstring_literals" : 04210 "__TEXT,__cstring,cstring_literals"), 04211 1, true); 04212 04213 return getConstantGEP(VMContext, Entry, 0, 0); 04214 } 04215 04216 // FIXME: Merge into a single cstring creation function. 04217 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 04218 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 04219 } 04220 04221 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 04222 std::string TypeStr; 04223 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 04224 04225 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 04226 04227 if (!Entry) 04228 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 04229 llvm::ConstantDataArray::getString(VMContext, TypeStr), 04230 ((ObjCABI == 2) ? 04231 "__TEXT,__objc_methtype,cstring_literals" : 04232 "__TEXT,__cstring,cstring_literals"), 04233 1, true); 04234 04235 return getConstantGEP(VMContext, Entry, 0, 0); 04236 } 04237 04238 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 04239 bool Extended) { 04240 std::string TypeStr; 04241 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended)) 04242 return 0; 04243 04244 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 04245 04246 if (!Entry) 04247 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 04248 llvm::ConstantDataArray::getString(VMContext, TypeStr), 04249 ((ObjCABI == 2) ? 04250 "__TEXT,__objc_methtype,cstring_literals" : 04251 "__TEXT,__cstring,cstring_literals"), 04252 1, true); 04253 04254 return getConstantGEP(VMContext, Entry, 0, 0); 04255 } 04256 04257 // FIXME: Merge into a single cstring creation function. 04258 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 04259 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 04260 04261 if (!Entry) 04262 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", 04263 llvm::ConstantDataArray::getString(VMContext, 04264 Ident->getNameStart()), 04265 "__TEXT,__cstring,cstring_literals", 04266 1, true); 04267 04268 return getConstantGEP(VMContext, Entry, 0, 0); 04269 } 04270 04271 // FIXME: Merge into a single cstring creation function. 04272 // FIXME: This Decl should be more precise. 04273 llvm::Constant * 04274 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 04275 const Decl *Container) { 04276 std::string TypeStr; 04277 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 04278 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 04279 } 04280 04281 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 04282 const ObjCContainerDecl *CD, 04283 SmallVectorImpl<char> &Name) { 04284 llvm::raw_svector_ostream OS(Name); 04285 assert (CD && "Missing container decl in GetNameForMethod"); 04286 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 04287 << '[' << CD->getName(); 04288 if (const ObjCCategoryImplDecl *CID = 04289 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 04290 OS << '(' << *CID << ')'; 04291 OS << ' ' << D->getSelector().getAsString() << ']'; 04292 } 04293 04294 void CGObjCMac::FinishModule() { 04295 EmitModuleInfo(); 04296 04297 // Emit the dummy bodies for any protocols which were referenced but 04298 // never defined. 04299 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 04300 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) { 04301 if (I->second->hasInitializer()) 04302 continue; 04303 04304 llvm::Constant *Values[5]; 04305 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 04306 Values[1] = GetClassName(I->first); 04307 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 04308 Values[3] = Values[4] = 04309 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 04310 I->second->setLinkage(llvm::GlobalValue::InternalLinkage); 04311 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 04312 Values)); 04313 CGM.AddUsedGlobal(I->second); 04314 } 04315 04316 // Add assembler directives to add lazy undefined symbol references 04317 // for classes which are referenced but not defined. This is 04318 // important for correct linker interaction. 04319 // 04320 // FIXME: It would be nice if we had an LLVM construct for this. 04321 if (!LazySymbols.empty() || !DefinedSymbols.empty()) { 04322 SmallString<256> Asm; 04323 Asm += CGM.getModule().getModuleInlineAsm(); 04324 if (!Asm.empty() && Asm.back() != '\n') 04325 Asm += '\n'; 04326 04327 llvm::raw_svector_ostream OS(Asm); 04328 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(), 04329 e = DefinedSymbols.end(); I != e; ++I) 04330 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n" 04331 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n"; 04332 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(), 04333 e = LazySymbols.end(); I != e; ++I) { 04334 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n"; 04335 } 04336 04337 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) { 04338 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n" 04339 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n"; 04340 } 04341 04342 CGM.getModule().setModuleInlineAsm(OS.str()); 04343 } 04344 } 04345 04346 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 04347 : CGObjCCommonMac(cgm), 04348 ObjCTypes(cgm) { 04349 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 04350 ObjCABI = 2; 04351 } 04352 04353 /* *** */ 04354 04355 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 04356 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0) 04357 { 04358 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 04359 ASTContext &Ctx = CGM.getContext(); 04360 04361 ShortTy = Types.ConvertType(Ctx.ShortTy); 04362 IntTy = Types.ConvertType(Ctx.IntTy); 04363 LongTy = Types.ConvertType(Ctx.LongTy); 04364 LongLongTy = Types.ConvertType(Ctx.LongLongTy); 04365 Int8PtrTy = CGM.Int8PtrTy; 04366 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 04367 04368 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 04369 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 04370 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 04371 04372 // I'm not sure I like this. The implicit coordination is a bit 04373 // gross. We should solve this in a reasonable fashion because this 04374 // is a pretty common task (match some runtime data structure with 04375 // an LLVM data structure). 04376 04377 // FIXME: This is leaked. 04378 // FIXME: Merge with rewriter code? 04379 04380 // struct _objc_super { 04381 // id self; 04382 // Class cls; 04383 // } 04384 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 04385 Ctx.getTranslationUnitDecl(), 04386 SourceLocation(), SourceLocation(), 04387 &Ctx.Idents.get("_objc_super")); 04388 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 04389 Ctx.getObjCIdType(), 0, 0, false, false)); 04390 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 04391 Ctx.getObjCClassType(), 0, 0, false, false)); 04392 RD->completeDefinition(); 04393 04394 SuperCTy = Ctx.getTagDeclType(RD); 04395 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 04396 04397 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 04398 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 04399 04400 // struct _prop_t { 04401 // char *name; 04402 // char *attributes; 04403 // } 04404 PropertyTy = llvm::StructType::create("struct._prop_t", 04405 Int8PtrTy, Int8PtrTy, NULL); 04406 04407 // struct _prop_list_t { 04408 // uint32_t entsize; // sizeof(struct _prop_t) 04409 // uint32_t count_of_properties; 04410 // struct _prop_t prop_list[count_of_properties]; 04411 // } 04412 PropertyListTy = 04413 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy, 04414 llvm::ArrayType::get(PropertyTy, 0), NULL); 04415 // struct _prop_list_t * 04416 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 04417 04418 // struct _objc_method { 04419 // SEL _cmd; 04420 // char *method_type; 04421 // char *_imp; 04422 // } 04423 MethodTy = llvm::StructType::create("struct._objc_method", 04424 SelectorPtrTy, Int8PtrTy, Int8PtrTy, 04425 NULL); 04426 04427 // struct _objc_cache * 04428 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); 04429 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 04430 04431 } 04432 04433 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 04434 : ObjCCommonTypesHelper(cgm) { 04435 // struct _objc_method_description { 04436 // SEL name; 04437 // char *types; 04438 // } 04439 MethodDescriptionTy = 04440 llvm::StructType::create("struct._objc_method_description", 04441 SelectorPtrTy, Int8PtrTy, NULL); 04442 04443 // struct _objc_method_description_list { 04444 // int count; 04445 // struct _objc_method_description[1]; 04446 // } 04447 MethodDescriptionListTy = 04448 llvm::StructType::create("struct._objc_method_description_list", 04449 IntTy, 04450 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL); 04451 04452 // struct _objc_method_description_list * 04453 MethodDescriptionListPtrTy = 04454 llvm::PointerType::getUnqual(MethodDescriptionListTy); 04455 04456 // Protocol description structures 04457 04458 // struct _objc_protocol_extension { 04459 // uint32_t size; // sizeof(struct _objc_protocol_extension) 04460 // struct _objc_method_description_list *optional_instance_methods; 04461 // struct _objc_method_description_list *optional_class_methods; 04462 // struct _objc_property_list *instance_properties; 04463 // const char ** extendedMethodTypes; 04464 // } 04465 ProtocolExtensionTy = 04466 llvm::StructType::create("struct._objc_protocol_extension", 04467 IntTy, MethodDescriptionListPtrTy, 04468 MethodDescriptionListPtrTy, PropertyListPtrTy, 04469 Int8PtrPtrTy, NULL); 04470 04471 // struct _objc_protocol_extension * 04472 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 04473 04474 // Handle recursive construction of Protocol and ProtocolList types 04475 04476 ProtocolTy = 04477 llvm::StructType::create(VMContext, "struct._objc_protocol"); 04478 04479 ProtocolListTy = 04480 llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 04481 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), 04482 LongTy, 04483 llvm::ArrayType::get(ProtocolTy, 0), 04484 NULL); 04485 04486 // struct _objc_protocol { 04487 // struct _objc_protocol_extension *isa; 04488 // char *protocol_name; 04489 // struct _objc_protocol **_objc_protocol_list; 04490 // struct _objc_method_description_list *instance_methods; 04491 // struct _objc_method_description_list *class_methods; 04492 // } 04493 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 04494 llvm::PointerType::getUnqual(ProtocolListTy), 04495 MethodDescriptionListPtrTy, 04496 MethodDescriptionListPtrTy, 04497 NULL); 04498 04499 // struct _objc_protocol_list * 04500 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 04501 04502 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 04503 04504 // Class description structures 04505 04506 // struct _objc_ivar { 04507 // char *ivar_name; 04508 // char *ivar_type; 04509 // int ivar_offset; 04510 // } 04511 IvarTy = llvm::StructType::create("struct._objc_ivar", 04512 Int8PtrTy, Int8PtrTy, IntTy, NULL); 04513 04514 // struct _objc_ivar_list * 04515 IvarListTy = 04516 llvm::StructType::create(VMContext, "struct._objc_ivar_list"); 04517 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 04518 04519 // struct _objc_method_list * 04520 MethodListTy = 04521 llvm::StructType::create(VMContext, "struct._objc_method_list"); 04522 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 04523 04524 // struct _objc_class_extension * 04525 ClassExtensionTy = 04526 llvm::StructType::create("struct._objc_class_extension", 04527 IntTy, Int8PtrTy, PropertyListPtrTy, NULL); 04528 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 04529 04530 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class"); 04531 04532 // struct _objc_class { 04533 // Class isa; 04534 // Class super_class; 04535 // char *name; 04536 // long version; 04537 // long info; 04538 // long instance_size; 04539 // struct _objc_ivar_list *ivars; 04540 // struct _objc_method_list *methods; 04541 // struct _objc_cache *cache; 04542 // struct _objc_protocol_list *protocols; 04543 // char *ivar_layout; 04544 // struct _objc_class_ext *ext; 04545 // }; 04546 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 04547 llvm::PointerType::getUnqual(ClassTy), 04548 Int8PtrTy, 04549 LongTy, 04550 LongTy, 04551 LongTy, 04552 IvarListPtrTy, 04553 MethodListPtrTy, 04554 CachePtrTy, 04555 ProtocolListPtrTy, 04556 Int8PtrTy, 04557 ClassExtensionPtrTy, 04558 NULL); 04559 04560 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 04561 04562 // struct _objc_category { 04563 // char *category_name; 04564 // char *class_name; 04565 // struct _objc_method_list *instance_method; 04566 // struct _objc_method_list *class_method; 04567 // uint32_t size; // sizeof(struct _objc_category) 04568 // struct _objc_property_list *instance_properties;// category's @property 04569 // } 04570 CategoryTy = 04571 llvm::StructType::create("struct._objc_category", 04572 Int8PtrTy, Int8PtrTy, MethodListPtrTy, 04573 MethodListPtrTy, ProtocolListPtrTy, 04574 IntTy, PropertyListPtrTy, NULL); 04575 04576 // Global metadata structures 04577 04578 // struct _objc_symtab { 04579 // long sel_ref_cnt; 04580 // SEL *refs; 04581 // short cls_def_cnt; 04582 // short cat_def_cnt; 04583 // char *defs[cls_def_cnt + cat_def_cnt]; 04584 // } 04585 SymtabTy = 04586 llvm::StructType::create("struct._objc_symtab", 04587 LongTy, SelectorPtrTy, ShortTy, ShortTy, 04588 llvm::ArrayType::get(Int8PtrTy, 0), NULL); 04589 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 04590 04591 // struct _objc_module { 04592 // long version; 04593 // long size; // sizeof(struct _objc_module) 04594 // char *name; 04595 // struct _objc_symtab* symtab; 04596 // } 04597 ModuleTy = 04598 llvm::StructType::create("struct._objc_module", 04599 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL); 04600 04601 04602 // FIXME: This is the size of the setjmp buffer and should be target 04603 // specific. 18 is what's used on 32-bit X86. 04604 uint64_t SetJmpBufferSize = 18; 04605 04606 // Exceptions 04607 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 04608 04609 ExceptionDataTy = 04610 llvm::StructType::create("struct._objc_exception_data", 04611 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize), 04612 StackPtrTy, NULL); 04613 04614 } 04615 04616 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 04617 : ObjCCommonTypesHelper(cgm) { 04618 // struct _method_list_t { 04619 // uint32_t entsize; // sizeof(struct _objc_method) 04620 // uint32_t method_count; 04621 // struct _objc_method method_list[method_count]; 04622 // } 04623 MethodListnfABITy = 04624 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy, 04625 llvm::ArrayType::get(MethodTy, 0), NULL); 04626 // struct method_list_t * 04627 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 04628 04629 // struct _protocol_t { 04630 // id isa; // NULL 04631 // const char * const protocol_name; 04632 // const struct _protocol_list_t * protocol_list; // super protocols 04633 // const struct method_list_t * const instance_methods; 04634 // const struct method_list_t * const class_methods; 04635 // const struct method_list_t *optionalInstanceMethods; 04636 // const struct method_list_t *optionalClassMethods; 04637 // const struct _prop_list_t * properties; 04638 // const uint32_t size; // sizeof(struct _protocol_t) 04639 // const uint32_t flags; // = 0 04640 // const char ** extendedMethodTypes; 04641 // } 04642 04643 // Holder for struct _protocol_list_t * 04644 ProtocolListnfABITy = 04645 llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 04646 04647 ProtocolnfABITy = 04648 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy, 04649 llvm::PointerType::getUnqual(ProtocolListnfABITy), 04650 MethodListnfABIPtrTy, MethodListnfABIPtrTy, 04651 MethodListnfABIPtrTy, MethodListnfABIPtrTy, 04652 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, 04653 NULL); 04654 04655 // struct _protocol_t* 04656 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 04657 04658 // struct _protocol_list_t { 04659 // long protocol_count; // Note, this is 32/64 bit 04660 // struct _protocol_t *[protocol_count]; 04661 // } 04662 ProtocolListnfABITy->setBody(LongTy, 04663 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0), 04664 NULL); 04665 04666 // struct _objc_protocol_list* 04667 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 04668 04669 // struct _ivar_t { 04670 // unsigned long int *offset; // pointer to ivar offset location 04671 // char *name; 04672 // char *type; 04673 // uint32_t alignment; 04674 // uint32_t size; 04675 // } 04676 IvarnfABITy = 04677 llvm::StructType::create("struct._ivar_t", 04678 llvm::PointerType::getUnqual(LongTy), 04679 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); 04680 04681 // struct _ivar_list_t { 04682 // uint32 entsize; // sizeof(struct _ivar_t) 04683 // uint32 count; 04684 // struct _iver_t list[count]; 04685 // } 04686 IvarListnfABITy = 04687 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy, 04688 llvm::ArrayType::get(IvarnfABITy, 0), NULL); 04689 04690 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 04691 04692 // struct _class_ro_t { 04693 // uint32_t const flags; 04694 // uint32_t const instanceStart; 04695 // uint32_t const instanceSize; 04696 // uint32_t const reserved; // only when building for 64bit targets 04697 // const uint8_t * const ivarLayout; 04698 // const char *const name; 04699 // const struct _method_list_t * const baseMethods; 04700 // const struct _objc_protocol_list *const baseProtocols; 04701 // const struct _ivar_list_t *const ivars; 04702 // const uint8_t * const weakIvarLayout; 04703 // const struct _prop_list_t * const properties; 04704 // } 04705 04706 // FIXME. Add 'reserved' field in 64bit abi mode! 04707 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t", 04708 IntTy, IntTy, IntTy, Int8PtrTy, 04709 Int8PtrTy, MethodListnfABIPtrTy, 04710 ProtocolListnfABIPtrTy, 04711 IvarListnfABIPtrTy, 04712 Int8PtrTy, PropertyListPtrTy, NULL); 04713 04714 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 04715 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 04716 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 04717 ->getPointerTo(); 04718 04719 // struct _class_t { 04720 // struct _class_t *isa; 04721 // struct _class_t * const superclass; 04722 // void *cache; 04723 // IMP *vtable; 04724 // struct class_ro_t *ro; 04725 // } 04726 04727 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t"); 04728 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 04729 llvm::PointerType::getUnqual(ClassnfABITy), 04730 CachePtrTy, 04731 llvm::PointerType::getUnqual(ImpnfABITy), 04732 llvm::PointerType::getUnqual(ClassRonfABITy), 04733 NULL); 04734 04735 // LLVM for struct _class_t * 04736 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 04737 04738 // struct _category_t { 04739 // const char * const name; 04740 // struct _class_t *const cls; 04741 // const struct _method_list_t * const instance_methods; 04742 // const struct _method_list_t * const class_methods; 04743 // const struct _protocol_list_t * const protocols; 04744 // const struct _prop_list_t * const properties; 04745 // } 04746 CategorynfABITy = llvm::StructType::create("struct._category_t", 04747 Int8PtrTy, ClassnfABIPtrTy, 04748 MethodListnfABIPtrTy, 04749 MethodListnfABIPtrTy, 04750 ProtocolListnfABIPtrTy, 04751 PropertyListPtrTy, 04752 NULL); 04753 04754 // New types for nonfragile abi messaging. 04755 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 04756 ASTContext &Ctx = CGM.getContext(); 04757 04758 // MessageRefTy - LLVM for: 04759 // struct _message_ref_t { 04760 // IMP messenger; 04761 // SEL name; 04762 // }; 04763 04764 // First the clang type for struct _message_ref_t 04765 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 04766 Ctx.getTranslationUnitDecl(), 04767 SourceLocation(), SourceLocation(), 04768 &Ctx.Idents.get("_message_ref_t")); 04769 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 04770 Ctx.VoidPtrTy, 0, 0, false, false)); 04771 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 04772 Ctx.getObjCSelType(), 0, 0, false, false)); 04773 RD->completeDefinition(); 04774 04775 MessageRefCTy = Ctx.getTagDeclType(RD); 04776 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 04777 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 04778 04779 // MessageRefPtrTy - LLVM for struct _message_ref_t* 04780 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 04781 04782 // SuperMessageRefTy - LLVM for: 04783 // struct _super_message_ref_t { 04784 // SUPER_IMP messenger; 04785 // SEL name; 04786 // }; 04787 SuperMessageRefTy = 04788 llvm::StructType::create("struct._super_message_ref_t", 04789 ImpnfABITy, SelectorPtrTy, NULL); 04790 04791 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 04792 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 04793 04794 04795 // struct objc_typeinfo { 04796 // const void** vtable; // objc_ehtype_vtable + 2 04797 // const char* name; // c++ typeinfo string 04798 // Class cls; 04799 // }; 04800 EHTypeTy = 04801 llvm::StructType::create("struct._objc_typeinfo", 04802 llvm::PointerType::getUnqual(Int8PtrTy), 04803 Int8PtrTy, ClassnfABIPtrTy, NULL); 04804 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 04805 } 04806 04807 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 04808 FinishNonFragileABIModule(); 04809 04810 return NULL; 04811 } 04812 04813 void CGObjCNonFragileABIMac:: 04814 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, 04815 const char *SymbolName, 04816 const char *SectionName) { 04817 unsigned NumClasses = Container.size(); 04818 04819 if (!NumClasses) 04820 return; 04821 04822 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 04823 for (unsigned i=0; i<NumClasses; i++) 04824 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 04825 ObjCTypes.Int8PtrTy); 04826 llvm::Constant *Init = 04827 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 04828 Symbols.size()), 04829 Symbols); 04830 04831 llvm::GlobalVariable *GV = 04832 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 04833 llvm::GlobalValue::InternalLinkage, 04834 Init, 04835 SymbolName); 04836 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 04837 GV->setSection(SectionName); 04838 CGM.AddUsedGlobal(GV); 04839 } 04840 04841 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 04842 // nonfragile abi has no module definition. 04843 04844 // Build list of all implemented class addresses in array 04845 // L_OBJC_LABEL_CLASS_$. 04846 AddModuleClassList(DefinedClasses, 04847 "\01L_OBJC_LABEL_CLASS_$", 04848 "__DATA, __objc_classlist, regular, no_dead_strip"); 04849 04850 for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) { 04851 llvm::GlobalValue *IMPLGV = DefinedClasses[i]; 04852 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 04853 continue; 04854 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 04855 } 04856 04857 for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) { 04858 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; 04859 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 04860 continue; 04861 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 04862 } 04863 04864 AddModuleClassList(DefinedNonLazyClasses, 04865 "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 04866 "__DATA, __objc_nlclslist, regular, no_dead_strip"); 04867 04868 // Build list of all implemented category addresses in array 04869 // L_OBJC_LABEL_CATEGORY_$. 04870 AddModuleClassList(DefinedCategories, 04871 "\01L_OBJC_LABEL_CATEGORY_$", 04872 "__DATA, __objc_catlist, regular, no_dead_strip"); 04873 AddModuleClassList(DefinedNonLazyCategories, 04874 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 04875 "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 04876 04877 EmitImageInfo(); 04878 } 04879 04880 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of 04881 /// VTableDispatchMethods; false otherwise. What this means is that 04882 /// except for the 19 selectors in the list, we generate 32bit-style 04883 /// message dispatch call for all the rest. 04884 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) { 04885 // At various points we've experimented with using vtable-based 04886 // dispatch for all methods. 04887 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { 04888 case CodeGenOptions::Legacy: 04889 return false; 04890 case CodeGenOptions::NonLegacy: 04891 return true; 04892 case CodeGenOptions::Mixed: 04893 break; 04894 } 04895 04896 // If so, see whether this selector is in the white-list of things which must 04897 // use the new dispatch convention. We lazily build a dense set for this. 04898 if (VTableDispatchMethods.empty()) { 04899 VTableDispatchMethods.insert(GetNullarySelector("alloc")); 04900 VTableDispatchMethods.insert(GetNullarySelector("class")); 04901 VTableDispatchMethods.insert(GetNullarySelector("self")); 04902 VTableDispatchMethods.insert(GetNullarySelector("isFlipped")); 04903 VTableDispatchMethods.insert(GetNullarySelector("length")); 04904 VTableDispatchMethods.insert(GetNullarySelector("count")); 04905 04906 // These are vtable-based if GC is disabled. 04907 // Optimistically use vtable dispatch for hybrid compiles. 04908 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 04909 VTableDispatchMethods.insert(GetNullarySelector("retain")); 04910 VTableDispatchMethods.insert(GetNullarySelector("release")); 04911 VTableDispatchMethods.insert(GetNullarySelector("autorelease")); 04912 } 04913 04914 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone")); 04915 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 04916 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 04917 VTableDispatchMethods.insert(GetUnarySelector("objectForKey")); 04918 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 04919 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString")); 04920 VTableDispatchMethods.insert(GetUnarySelector("isEqual")); 04921 04922 // These are vtable-based if GC is enabled. 04923 // Optimistically use vtable dispatch for hybrid compiles. 04924 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 04925 VTableDispatchMethods.insert(GetNullarySelector("hash")); 04926 VTableDispatchMethods.insert(GetUnarySelector("addObject")); 04927 04928 // "countByEnumeratingWithState:objects:count" 04929 IdentifierInfo *KeyIdents[] = { 04930 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 04931 &CGM.getContext().Idents.get("objects"), 04932 &CGM.getContext().Idents.get("count") 04933 }; 04934 VTableDispatchMethods.insert( 04935 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 04936 } 04937 } 04938 04939 return VTableDispatchMethods.count(Sel); 04940 } 04941 04942 // Metadata flags 04943 enum MetaDataDlags { 04944 CLS = 0x0, 04945 CLS_META = 0x1, 04946 CLS_ROOT = 0x2, 04947 OBJC2_CLS_HIDDEN = 0x10, 04948 CLS_EXCEPTION = 0x20, 04949 04950 /// (Obsolete) ARC-specific: this class has a .release_ivars method 04951 CLS_HAS_IVAR_RELEASER = 0x40, 04952 /// class was compiled with -fobjc-arr 04953 CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 04954 }; 04955 /// BuildClassRoTInitializer - generate meta-data for: 04956 /// struct _class_ro_t { 04957 /// uint32_t const flags; 04958 /// uint32_t const instanceStart; 04959 /// uint32_t const instanceSize; 04960 /// uint32_t const reserved; // only when building for 64bit targets 04961 /// const uint8_t * const ivarLayout; 04962 /// const char *const name; 04963 /// const struct _method_list_t * const baseMethods; 04964 /// const struct _protocol_list_t *const baseProtocols; 04965 /// const struct _ivar_list_t *const ivars; 04966 /// const uint8_t * const weakIvarLayout; 04967 /// const struct _prop_list_t * const properties; 04968 /// } 04969 /// 04970 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 04971 unsigned flags, 04972 unsigned InstanceStart, 04973 unsigned InstanceSize, 04974 const ObjCImplementationDecl *ID) { 04975 std::string ClassName = ID->getNameAsString(); 04976 llvm::Constant *Values[10]; // 11 for 64bit targets! 04977 04978 if (CGM.getLangOpts().ObjCAutoRefCount) 04979 flags |= CLS_COMPILED_BY_ARC; 04980 04981 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 04982 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 04983 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 04984 // FIXME. For 64bit targets add 0 here. 04985 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 04986 : BuildIvarLayout(ID, true); 04987 Values[ 4] = GetClassName(ID->getIdentifier()); 04988 // const struct _method_list_t * const baseMethods; 04989 std::vector<llvm::Constant*> Methods; 04990 std::string MethodListName("\01l_OBJC_$_"); 04991 if (flags & CLS_META) { 04992 MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 04993 for (ObjCImplementationDecl::classmeth_iterator 04994 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 04995 // Class methods should always be defined. 04996 Methods.push_back(GetMethodConstant(*i)); 04997 } 04998 } else { 04999 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 05000 for (ObjCImplementationDecl::instmeth_iterator 05001 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 05002 // Instance methods should always be defined. 05003 Methods.push_back(GetMethodConstant(*i)); 05004 } 05005 for (ObjCImplementationDecl::propimpl_iterator 05006 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 05007 ObjCPropertyImplDecl *PID = &*i; 05008 05009 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 05010 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 05011 05012 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 05013 if (llvm::Constant *C = GetMethodConstant(MD)) 05014 Methods.push_back(C); 05015 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 05016 if (llvm::Constant *C = GetMethodConstant(MD)) 05017 Methods.push_back(C); 05018 } 05019 } 05020 } 05021 Values[ 5] = EmitMethodList(MethodListName, 05022 "__DATA, __objc_const", Methods); 05023 05024 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 05025 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 05026 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 05027 + OID->getName(), 05028 OID->all_referenced_protocol_begin(), 05029 OID->all_referenced_protocol_end()); 05030 05031 if (flags & CLS_META) 05032 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 05033 else 05034 Values[ 7] = EmitIvarList(ID); 05035 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 05036 : BuildIvarLayout(ID, false); 05037 if (flags & CLS_META) 05038 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 05039 else 05040 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 05041 ID, ID->getClassInterface(), ObjCTypes); 05042 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 05043 Values); 05044 llvm::GlobalVariable *CLASS_RO_GV = 05045 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false, 05046 llvm::GlobalValue::InternalLinkage, 05047 Init, 05048 (flags & CLS_META) ? 05049 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 05050 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName); 05051 CLASS_RO_GV->setAlignment( 05052 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy)); 05053 CLASS_RO_GV->setSection("__DATA, __objc_const"); 05054 return CLASS_RO_GV; 05055 05056 } 05057 05058 /// BuildClassMetaData - This routine defines that to-level meta-data 05059 /// for the given ClassName for: 05060 /// struct _class_t { 05061 /// struct _class_t *isa; 05062 /// struct _class_t * const superclass; 05063 /// void *cache; 05064 /// IMP *vtable; 05065 /// struct class_ro_t *ro; 05066 /// } 05067 /// 05068 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 05069 std::string &ClassName, 05070 llvm::Constant *IsAGV, 05071 llvm::Constant *SuperClassGV, 05072 llvm::Constant *ClassRoGV, 05073 bool HiddenVisibility) { 05074 llvm::Constant *Values[] = { 05075 IsAGV, 05076 SuperClassGV, 05077 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar 05078 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar 05079 ClassRoGV // &CLASS_RO_GV 05080 }; 05081 if (!Values[1]) 05082 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 05083 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 05084 Values); 05085 llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 05086 GV->setInitializer(Init); 05087 GV->setSection("__DATA, __objc_data"); 05088 GV->setAlignment( 05089 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 05090 if (HiddenVisibility) 05091 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 05092 return GV; 05093 } 05094 05095 bool 05096 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 05097 return OD->getClassMethod(GetNullarySelector("load")) != 0; 05098 } 05099 05100 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 05101 uint32_t &InstanceStart, 05102 uint32_t &InstanceSize) { 05103 const ASTRecordLayout &RL = 05104 CGM.getContext().getASTObjCImplementationLayout(OID); 05105 05106 // InstanceSize is really instance end. 05107 InstanceSize = RL.getDataSize().getQuantity(); 05108 05109 // If there are no fields, the start is the same as the end. 05110 if (!RL.getFieldCount()) 05111 InstanceStart = InstanceSize; 05112 else 05113 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 05114 } 05115 05116 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 05117 std::string ClassName = ID->getNameAsString(); 05118 if (!ObjCEmptyCacheVar) { 05119 ObjCEmptyCacheVar = new llvm::GlobalVariable( 05120 CGM.getModule(), 05121 ObjCTypes.CacheTy, 05122 false, 05123 llvm::GlobalValue::ExternalLinkage, 05124 0, 05125 "_objc_empty_cache"); 05126 05127 ObjCEmptyVtableVar = new llvm::GlobalVariable( 05128 CGM.getModule(), 05129 ObjCTypes.ImpnfABITy, 05130 false, 05131 llvm::GlobalValue::ExternalLinkage, 05132 0, 05133 "_objc_empty_vtable"); 05134 } 05135 assert(ID->getClassInterface() && 05136 "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 05137 // FIXME: Is this correct (that meta class size is never computed)? 05138 uint32_t InstanceStart = 05139 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 05140 uint32_t InstanceSize = InstanceStart; 05141 uint32_t flags = CLS_META; 05142 std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 05143 std::string ObjCClassName(getClassSymbolPrefix()); 05144 05145 llvm::GlobalVariable *SuperClassGV, *IsAGV; 05146 05147 bool classIsHidden = 05148 ID->getClassInterface()->getVisibility() == HiddenVisibility; 05149 if (classIsHidden) 05150 flags |= OBJC2_CLS_HIDDEN; 05151 if (ID->hasCXXStructors()) 05152 flags |= eClassFlags_ABI2_HasCXXStructors; 05153 if (!ID->getClassInterface()->getSuperClass()) { 05154 // class is root 05155 flags |= CLS_ROOT; 05156 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 05157 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 05158 } else { 05159 // Has a root. Current class is not a root. 05160 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 05161 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 05162 Root = Super; 05163 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 05164 if (Root->isWeakImported()) 05165 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 05166 // work on super class metadata symbol. 05167 std::string SuperClassName = 05168 ObjCMetaClassName + 05169 ID->getClassInterface()->getSuperClass()->getNameAsString(); 05170 SuperClassGV = GetClassGlobal(SuperClassName); 05171 if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 05172 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 05173 } 05174 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 05175 InstanceStart, 05176 InstanceSize,ID); 05177 std::string TClassName = ObjCMetaClassName + ClassName; 05178 llvm::GlobalVariable *MetaTClass = 05179 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 05180 classIsHidden); 05181 DefinedMetaClasses.push_back(MetaTClass); 05182 05183 // Metadata for the class 05184 flags = CLS; 05185 if (classIsHidden) 05186 flags |= OBJC2_CLS_HIDDEN; 05187 if (ID->hasCXXStructors()) 05188 flags |= eClassFlags_ABI2_HasCXXStructors; 05189 05190 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) 05191 flags |= CLS_EXCEPTION; 05192 05193 if (!ID->getClassInterface()->getSuperClass()) { 05194 flags |= CLS_ROOT; 05195 SuperClassGV = 0; 05196 } else { 05197 // Has a root. Current class is not a root. 05198 std::string RootClassName = 05199 ID->getClassInterface()->getSuperClass()->getNameAsString(); 05200 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 05201 if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 05202 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 05203 } 05204 GetClassSizeInfo(ID, InstanceStart, InstanceSize); 05205 CLASS_RO_GV = BuildClassRoTInitializer(flags, 05206 InstanceStart, 05207 InstanceSize, 05208 ID); 05209 05210 TClassName = ObjCClassName + ClassName; 05211 llvm::GlobalVariable *ClassMD = 05212 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 05213 classIsHidden); 05214 DefinedClasses.push_back(ClassMD); 05215 05216 // Determine if this class is also "non-lazy". 05217 if (ImplementationIsNonLazy(ID)) 05218 DefinedNonLazyClasses.push_back(ClassMD); 05219 05220 // Force the definition of the EHType if necessary. 05221 if (flags & CLS_EXCEPTION) 05222 GetInterfaceEHType(ID->getClassInterface(), true); 05223 // Make sure method definition entries are all clear for next implementation. 05224 MethodDefinitions.clear(); 05225 } 05226 05227 /// GenerateProtocolRef - This routine is called to generate code for 05228 /// a protocol reference expression; as in: 05229 /// @code 05230 /// @protocol(Proto1); 05231 /// @endcode 05232 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 05233 /// which will hold address of the protocol meta-data. 05234 /// 05235 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 05236 const ObjCProtocolDecl *PD) { 05237 05238 // This routine is called for @protocol only. So, we must build definition 05239 // of protocol's meta-data (not a reference to it!) 05240 // 05241 llvm::Constant *Init = 05242 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 05243 ObjCTypes.getExternalProtocolPtrTy()); 05244 05245 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 05246 ProtocolName += PD->getName(); 05247 05248 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 05249 if (PTGV) 05250 return Builder.CreateLoad(PTGV); 05251 PTGV = new llvm::GlobalVariable( 05252 CGM.getModule(), 05253 Init->getType(), false, 05254 llvm::GlobalValue::WeakAnyLinkage, 05255 Init, 05256 ProtocolName); 05257 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 05258 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 05259 CGM.AddUsedGlobal(PTGV); 05260 return Builder.CreateLoad(PTGV); 05261 } 05262 05263 /// GenerateCategory - Build metadata for a category implementation. 05264 /// struct _category_t { 05265 /// const char * const name; 05266 /// struct _class_t *const cls; 05267 /// const struct _method_list_t * const instance_methods; 05268 /// const struct _method_list_t * const class_methods; 05269 /// const struct _protocol_list_t * const protocols; 05270 /// const struct _prop_list_t * const properties; 05271 /// } 05272 /// 05273 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 05274 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 05275 const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 05276 std::string ExtCatName(Prefix + Interface->getNameAsString()+ 05277 "_$_" + OCD->getNameAsString()); 05278 std::string ExtClassName(getClassSymbolPrefix() + 05279 Interface->getNameAsString()); 05280 05281 llvm::Constant *Values[6]; 05282 Values[0] = GetClassName(OCD->getIdentifier()); 05283 // meta-class entry symbol 05284 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 05285 if (Interface->isWeakImported()) 05286 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 05287 05288 Values[1] = ClassGV; 05289 std::vector<llvm::Constant*> Methods; 05290 std::string MethodListName(Prefix); 05291 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 05292 "_$_" + OCD->getNameAsString(); 05293 05294 for (ObjCCategoryImplDecl::instmeth_iterator 05295 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 05296 // Instance methods should always be defined. 05297 Methods.push_back(GetMethodConstant(*i)); 05298 } 05299 05300 Values[2] = EmitMethodList(MethodListName, 05301 "__DATA, __objc_const", 05302 Methods); 05303 05304 MethodListName = Prefix; 05305 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 05306 OCD->getNameAsString(); 05307 Methods.clear(); 05308 for (ObjCCategoryImplDecl::classmeth_iterator 05309 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 05310 // Class methods should always be defined. 05311 Methods.push_back(GetMethodConstant(*i)); 05312 } 05313 05314 Values[3] = EmitMethodList(MethodListName, 05315 "__DATA, __objc_const", 05316 Methods); 05317 const ObjCCategoryDecl *Category = 05318 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 05319 if (Category) { 05320 SmallString<256> ExtName; 05321 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" 05322 << OCD->getName(); 05323 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 05324 + Interface->getName() + "_$_" 05325 + Category->getName(), 05326 Category->protocol_begin(), 05327 Category->protocol_end()); 05328 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 05329 OCD, Category, ObjCTypes); 05330 } else { 05331 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 05332 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 05333 } 05334 05335 llvm::Constant *Init = 05336 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 05337 Values); 05338 llvm::GlobalVariable *GCATV 05339 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy, 05340 false, 05341 llvm::GlobalValue::InternalLinkage, 05342 Init, 05343 ExtCatName); 05344 GCATV->setAlignment( 05345 CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy)); 05346 GCATV->setSection("__DATA, __objc_const"); 05347 CGM.AddUsedGlobal(GCATV); 05348 DefinedCategories.push_back(GCATV); 05349 05350 // Determine if this category is also "non-lazy". 05351 if (ImplementationIsNonLazy(OCD)) 05352 DefinedNonLazyCategories.push_back(GCATV); 05353 // method definition entries must be clear for next implementation. 05354 MethodDefinitions.clear(); 05355 } 05356 05357 /// GetMethodConstant - Return a struct objc_method constant for the 05358 /// given method if it has been defined. The result is null if the 05359 /// method has not been defined. The return value has type MethodPtrTy. 05360 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 05361 const ObjCMethodDecl *MD) { 05362 llvm::Function *Fn = GetMethodDefinition(MD); 05363 if (!Fn) 05364 return 0; 05365 05366 llvm::Constant *Method[] = { 05367 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 05368 ObjCTypes.SelectorPtrTy), 05369 GetMethodVarType(MD), 05370 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 05371 }; 05372 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 05373 } 05374 05375 /// EmitMethodList - Build meta-data for method declarations 05376 /// struct _method_list_t { 05377 /// uint32_t entsize; // sizeof(struct _objc_method) 05378 /// uint32_t method_count; 05379 /// struct _objc_method method_list[method_count]; 05380 /// } 05381 /// 05382 llvm::Constant * 05383 CGObjCNonFragileABIMac::EmitMethodList(Twine Name, 05384 const char *Section, 05385 ArrayRef<llvm::Constant*> Methods) { 05386 // Return null for empty list. 05387 if (Methods.empty()) 05388 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 05389 05390 llvm::Constant *Values[3]; 05391 // sizeof(struct _objc_method) 05392 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 05393 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 05394 // method_count 05395 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 05396 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 05397 Methods.size()); 05398 Values[2] = llvm::ConstantArray::get(AT, Methods); 05399 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 05400 05401 llvm::GlobalVariable *GV = 05402 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 05403 llvm::GlobalValue::InternalLinkage, Init, Name); 05404 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 05405 GV->setSection(Section); 05406 CGM.AddUsedGlobal(GV); 05407 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); 05408 } 05409 05410 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 05411 /// the given ivar. 05412 llvm::GlobalVariable * 05413 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 05414 const ObjCIvarDecl *Ivar) { 05415 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); 05416 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 05417 '.' + Ivar->getNameAsString(); 05418 llvm::GlobalVariable *IvarOffsetGV = 05419 CGM.getModule().getGlobalVariable(Name); 05420 if (!IvarOffsetGV) 05421 IvarOffsetGV = 05422 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, 05423 false, 05424 llvm::GlobalValue::ExternalLinkage, 05425 0, 05426 Name); 05427 return IvarOffsetGV; 05428 } 05429 05430 llvm::Constant * 05431 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 05432 const ObjCIvarDecl *Ivar, 05433 unsigned long int Offset) { 05434 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 05435 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 05436 Offset)); 05437 IvarOffsetGV->setAlignment( 05438 CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy)); 05439 05440 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 05441 // well (i.e., in ObjCIvarOffsetVariable). 05442 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 05443 Ivar->getAccessControl() == ObjCIvarDecl::Package || 05444 ID->getVisibility() == HiddenVisibility) 05445 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 05446 else 05447 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 05448 IvarOffsetGV->setSection("__DATA, __objc_ivar"); 05449 return IvarOffsetGV; 05450 } 05451 05452 /// EmitIvarList - Emit the ivar list for the given 05453 /// implementation. The return value has type 05454 /// IvarListnfABIPtrTy. 05455 /// struct _ivar_t { 05456 /// unsigned long int *offset; // pointer to ivar offset location 05457 /// char *name; 05458 /// char *type; 05459 /// uint32_t alignment; 05460 /// uint32_t size; 05461 /// } 05462 /// struct _ivar_list_t { 05463 /// uint32 entsize; // sizeof(struct _ivar_t) 05464 /// uint32 count; 05465 /// struct _iver_t list[count]; 05466 /// } 05467 /// 05468 05469 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 05470 const ObjCImplementationDecl *ID) { 05471 05472 std::vector<llvm::Constant*> Ivars; 05473 05474 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 05475 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 05476 05477 // FIXME. Consolidate this with similar code in GenerateClass. 05478 05479 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 05480 IVD; IVD = IVD->getNextIvar()) { 05481 // Ignore unnamed bit-fields. 05482 if (!IVD->getDeclName()) 05483 continue; 05484 llvm::Constant *Ivar[5]; 05485 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 05486 ComputeIvarBaseOffset(CGM, ID, IVD)); 05487 Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 05488 Ivar[2] = GetMethodVarType(IVD); 05489 llvm::Type *FieldTy = 05490 CGM.getTypes().ConvertTypeForMem(IVD->getType()); 05491 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 05492 unsigned Align = CGM.getContext().getPreferredTypeAlign( 05493 IVD->getType().getTypePtr()) >> 3; 05494 Align = llvm::Log2_32(Align); 05495 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 05496 // NOTE. Size of a bitfield does not match gcc's, because of the 05497 // way bitfields are treated special in each. But I am told that 05498 // 'size' for bitfield ivars is ignored by the runtime so it does 05499 // not matter. If it matters, there is enough info to get the 05500 // bitfield right! 05501 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 05502 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 05503 } 05504 // Return null for empty list. 05505 if (Ivars.empty()) 05506 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 05507 05508 llvm::Constant *Values[3]; 05509 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 05510 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 05511 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 05512 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 05513 Ivars.size()); 05514 Values[2] = llvm::ConstantArray::get(AT, Ivars); 05515 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 05516 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 05517 llvm::GlobalVariable *GV = 05518 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 05519 llvm::GlobalValue::InternalLinkage, 05520 Init, 05521 Prefix + OID->getName()); 05522 GV->setAlignment( 05523 CGM.getTargetData().getABITypeAlignment(Init->getType())); 05524 GV->setSection("__DATA, __objc_const"); 05525 05526 CGM.AddUsedGlobal(GV); 05527 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); 05528 } 05529 05530 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 05531 const ObjCProtocolDecl *PD) { 05532 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 05533 05534 if (!Entry) { 05535 // We use the initializer as a marker of whether this is a forward 05536 // reference or not. At module finalization we add the empty 05537 // contents for protocols which were referenced but never defined. 05538 Entry = 05539 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, 05540 llvm::GlobalValue::ExternalLinkage, 05541 0, 05542 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 05543 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 05544 } 05545 05546 return Entry; 05547 } 05548 05549 /// GetOrEmitProtocol - Generate the protocol meta-data: 05550 /// @code 05551 /// struct _protocol_t { 05552 /// id isa; // NULL 05553 /// const char * const protocol_name; 05554 /// const struct _protocol_list_t * protocol_list; // super protocols 05555 /// const struct method_list_t * const instance_methods; 05556 /// const struct method_list_t * const class_methods; 05557 /// const struct method_list_t *optionalInstanceMethods; 05558 /// const struct method_list_t *optionalClassMethods; 05559 /// const struct _prop_list_t * properties; 05560 /// const uint32_t size; // sizeof(struct _protocol_t) 05561 /// const uint32_t flags; // = 0 05562 /// const char ** extendedMethodTypes; 05563 /// } 05564 /// @endcode 05565 /// 05566 05567 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 05568 const ObjCProtocolDecl *PD) { 05569 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()]; 05570 05571 // Early exit if a defining object has already been generated. 05572 if (Entry && Entry->hasInitializer()) 05573 return Entry; 05574 05575 // Use the protocol definition, if there is one. 05576 if (const ObjCProtocolDecl *Def = PD->getDefinition()) 05577 PD = Def; 05578 05579 // Construct method lists. 05580 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 05581 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 05582 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt; 05583 for (ObjCProtocolDecl::instmeth_iterator 05584 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 05585 ObjCMethodDecl *MD = *i; 05586 llvm::Constant *C = GetMethodDescriptionConstant(MD); 05587 if (!C) 05588 return GetOrEmitProtocolRef(PD); 05589 05590 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 05591 OptInstanceMethods.push_back(C); 05592 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 05593 } else { 05594 InstanceMethods.push_back(C); 05595 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 05596 } 05597 } 05598 05599 for (ObjCProtocolDecl::classmeth_iterator 05600 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 05601 ObjCMethodDecl *MD = *i; 05602 llvm::Constant *C = GetMethodDescriptionConstant(MD); 05603 if (!C) 05604 return GetOrEmitProtocolRef(PD); 05605 05606 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 05607 OptClassMethods.push_back(C); 05608 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 05609 } else { 05610 ClassMethods.push_back(C); 05611 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 05612 } 05613 } 05614 05615 MethodTypesExt.insert(MethodTypesExt.end(), 05616 OptMethodTypesExt.begin(), OptMethodTypesExt.end()); 05617 05618 llvm::Constant *Values[11]; 05619 // isa is NULL 05620 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 05621 Values[1] = GetClassName(PD->getIdentifier()); 05622 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), 05623 PD->protocol_begin(), 05624 PD->protocol_end()); 05625 05626 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 05627 + PD->getName(), 05628 "__DATA, __objc_const", 05629 InstanceMethods); 05630 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 05631 + PD->getName(), 05632 "__DATA, __objc_const", 05633 ClassMethods); 05634 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 05635 + PD->getName(), 05636 "__DATA, __objc_const", 05637 OptInstanceMethods); 05638 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 05639 + PD->getName(), 05640 "__DATA, __objc_const", 05641 OptClassMethods); 05642 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(), 05643 0, PD, ObjCTypes); 05644 uint32_t Size = 05645 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 05646 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 05647 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 05648 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 05649 + PD->getName(), 05650 MethodTypesExt, ObjCTypes); 05651 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 05652 Values); 05653 05654 if (Entry) { 05655 // Already created, fix the linkage and update the initializer. 05656 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 05657 Entry->setInitializer(Init); 05658 } else { 05659 Entry = 05660 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 05661 false, llvm::GlobalValue::WeakAnyLinkage, Init, 05662 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 05663 Entry->setAlignment( 05664 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy)); 05665 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 05666 05667 Protocols[PD->getIdentifier()] = Entry; 05668 } 05669 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 05670 CGM.AddUsedGlobal(Entry); 05671 05672 // Use this protocol meta-data to build protocol list table in section 05673 // __DATA, __objc_protolist 05674 llvm::GlobalVariable *PTGV = 05675 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 05676 false, llvm::GlobalValue::WeakAnyLinkage, Entry, 05677 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName()); 05678 PTGV->setAlignment( 05679 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 05680 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 05681 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 05682 CGM.AddUsedGlobal(PTGV); 05683 return Entry; 05684 } 05685 05686 /// EmitProtocolList - Generate protocol list meta-data: 05687 /// @code 05688 /// struct _protocol_list_t { 05689 /// long protocol_count; // Note, this is 32/64 bit 05690 /// struct _protocol_t[protocol_count]; 05691 /// } 05692 /// @endcode 05693 /// 05694 llvm::Constant * 05695 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name, 05696 ObjCProtocolDecl::protocol_iterator begin, 05697 ObjCProtocolDecl::protocol_iterator end) { 05698 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs; 05699 05700 // Just return null for empty protocol lists 05701 if (begin == end) 05702 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 05703 05704 // FIXME: We shouldn't need to do this lookup here, should we? 05705 SmallString<256> TmpName; 05706 Name.toVector(TmpName); 05707 llvm::GlobalVariable *GV = 05708 CGM.getModule().getGlobalVariable(TmpName.str(), true); 05709 if (GV) 05710 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); 05711 05712 for (; begin != end; ++begin) 05713 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 05714 05715 // This list is null terminated. 05716 ProtocolRefs.push_back(llvm::Constant::getNullValue( 05717 ObjCTypes.ProtocolnfABIPtrTy)); 05718 05719 llvm::Constant *Values[2]; 05720 Values[0] = 05721 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 05722 Values[1] = 05723 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 05724 ProtocolRefs.size()), 05725 ProtocolRefs); 05726 05727 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 05728 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 05729 llvm::GlobalValue::InternalLinkage, 05730 Init, Name); 05731 GV->setSection("__DATA, __objc_const"); 05732 GV->setAlignment( 05733 CGM.getTargetData().getABITypeAlignment(Init->getType())); 05734 CGM.AddUsedGlobal(GV); 05735 return llvm::ConstantExpr::getBitCast(GV, 05736 ObjCTypes.ProtocolListnfABIPtrTy); 05737 } 05738 05739 /// GetMethodDescriptionConstant - This routine build following meta-data: 05740 /// struct _objc_method { 05741 /// SEL _cmd; 05742 /// char *method_type; 05743 /// char *_imp; 05744 /// } 05745 05746 llvm::Constant * 05747 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 05748 llvm::Constant *Desc[3]; 05749 Desc[0] = 05750 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 05751 ObjCTypes.SelectorPtrTy); 05752 Desc[1] = GetMethodVarType(MD); 05753 if (!Desc[1]) 05754 return 0; 05755 05756 // Protocol methods have no implementation. So, this entry is always NULL. 05757 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 05758 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 05759 } 05760 05761 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 05762 /// This code gen. amounts to generating code for: 05763 /// @code 05764 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 05765 /// @encode 05766 /// 05767 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 05768 CodeGen::CodeGenFunction &CGF, 05769 QualType ObjectTy, 05770 llvm::Value *BaseValue, 05771 const ObjCIvarDecl *Ivar, 05772 unsigned CVRQualifiers) { 05773 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface(); 05774 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar); 05775 if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset)) 05776 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 05777 llvm::MDNode::get(VMContext, 05778 ArrayRef<llvm::Value*>())); 05779 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 05780 Offset); 05781 } 05782 05783 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 05784 CodeGen::CodeGenFunction &CGF, 05785 const ObjCInterfaceDecl *Interface, 05786 const ObjCIvarDecl *Ivar) { 05787 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); 05788 } 05789 05790 static void appendSelectorForMessageRefTable(std::string &buffer, 05791 Selector selector) { 05792 if (selector.isUnarySelector()) { 05793 buffer += selector.getNameForSlot(0); 05794 return; 05795 } 05796 05797 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) { 05798 buffer += selector.getNameForSlot(i); 05799 buffer += '_'; 05800 } 05801 } 05802 05803 /// Emit a "v-table" message send. We emit a weak hidden-visibility 05804 /// struct, initially containing the selector pointer and a pointer to 05805 /// a "fixup" variant of the appropriate objc_msgSend. To call, we 05806 /// load and call the function pointer, passing the address of the 05807 /// struct as the second parameter. The runtime determines whether 05808 /// the selector is currently emitted using vtable dispatch; if so, it 05809 /// substitutes a stub function which simply tail-calls through the 05810 /// appropriate vtable slot, and if not, it substitues a stub function 05811 /// which tail-calls objc_msgSend. Both stubs adjust the selector 05812 /// argument to correctly point to the selector. 05813 RValue 05814 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, 05815 ReturnValueSlot returnSlot, 05816 QualType resultType, 05817 Selector selector, 05818 llvm::Value *arg0, 05819 QualType arg0Type, 05820 bool isSuper, 05821 const CallArgList &formalArgs, 05822 const ObjCMethodDecl *method) { 05823 // Compute the actual arguments. 05824 CallArgList args; 05825 05826 // First argument: the receiver / super-call structure. 05827 if (!isSuper) 05828 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy); 05829 args.add(RValue::get(arg0), arg0Type); 05830 05831 // Second argument: a pointer to the message ref structure. Leave 05832 // the actual argument value blank for now. 05833 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy); 05834 05835 args.insert(args.end(), formalArgs.begin(), formalArgs.end()); 05836 05837 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args); 05838 05839 NullReturnState nullReturn; 05840 05841 // Find the function to call and the mangled name for the message 05842 // ref structure. Using a different mangled name wouldn't actually 05843 // be a problem; it would just be a waste. 05844 // 05845 // The runtime currently never uses vtable dispatch for anything 05846 // except normal, non-super message-sends. 05847 // FIXME: don't use this for that. 05848 llvm::Constant *fn = 0; 05849 std::string messageRefName("\01l_"); 05850 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { 05851 if (isSuper) { 05852 fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 05853 messageRefName += "objc_msgSendSuper2_stret_fixup"; 05854 } else { 05855 nullReturn.init(CGF, arg0); 05856 fn = ObjCTypes.getMessageSendStretFixupFn(); 05857 messageRefName += "objc_msgSend_stret_fixup"; 05858 } 05859 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) { 05860 fn = ObjCTypes.getMessageSendFpretFixupFn(); 05861 messageRefName += "objc_msgSend_fpret_fixup"; 05862 } else { 05863 if (isSuper) { 05864 fn = ObjCTypes.getMessageSendSuper2FixupFn(); 05865 messageRefName += "objc_msgSendSuper2_fixup"; 05866 } else { 05867 fn = ObjCTypes.getMessageSendFixupFn(); 05868 messageRefName += "objc_msgSend_fixup"; 05869 } 05870 } 05871 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 05872 messageRefName += '_'; 05873 05874 // Append the selector name, except use underscores anywhere we 05875 // would have used colons. 05876 appendSelectorForMessageRefTable(messageRefName, selector); 05877 05878 llvm::GlobalVariable *messageRef 05879 = CGM.getModule().getGlobalVariable(messageRefName); 05880 if (!messageRef) { 05881 // Build the message ref structure. 05882 llvm::Constant *values[] = { fn, GetMethodVarName(selector) }; 05883 llvm::Constant *init = llvm::ConstantStruct::getAnon(values); 05884 messageRef = new llvm::GlobalVariable(CGM.getModule(), 05885 init->getType(), 05886 /*constant*/ false, 05887 llvm::GlobalValue::WeakAnyLinkage, 05888 init, 05889 messageRefName); 05890 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); 05891 messageRef->setAlignment(16); 05892 messageRef->setSection("__DATA, __objc_msgrefs, coalesced"); 05893 } 05894 05895 bool requiresnullCheck = false; 05896 if (CGM.getLangOpts().ObjCAutoRefCount && method) 05897 for (ObjCMethodDecl::param_const_iterator i = method->param_begin(), 05898 e = method->param_end(); i != e; ++i) { 05899 const ParmVarDecl *ParamDecl = (*i); 05900 if (ParamDecl->hasAttr<NSConsumedAttr>()) { 05901 if (!nullReturn.NullBB) 05902 nullReturn.init(CGF, arg0); 05903 requiresnullCheck = true; 05904 break; 05905 } 05906 } 05907 05908 llvm::Value *mref = 05909 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); 05910 05911 // Update the message ref argument. 05912 args[1].RV = RValue::get(mref); 05913 05914 // Load the function to call from the message ref table. 05915 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0); 05916 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn"); 05917 05918 callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType); 05919 05920 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args); 05921 return nullReturn.complete(CGF, result, resultType, formalArgs, 05922 requiresnullCheck ? method : 0); 05923 } 05924 05925 /// Generate code for a message send expression in the nonfragile abi. 05926 CodeGen::RValue 05927 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 05928 ReturnValueSlot Return, 05929 QualType ResultType, 05930 Selector Sel, 05931 llvm::Value *Receiver, 05932 const CallArgList &CallArgs, 05933 const ObjCInterfaceDecl *Class, 05934 const ObjCMethodDecl *Method) { 05935 return isVTableDispatchedSelector(Sel) 05936 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 05937 Receiver, CGF.getContext().getObjCIdType(), 05938 false, CallArgs, Method) 05939 : EmitMessageSend(CGF, Return, ResultType, 05940 EmitSelector(CGF.Builder, Sel), 05941 Receiver, CGF.getContext().getObjCIdType(), 05942 false, CallArgs, Method, ObjCTypes); 05943 } 05944 05945 llvm::GlobalVariable * 05946 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 05947 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 05948 05949 if (!GV) { 05950 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, 05951 false, llvm::GlobalValue::ExternalLinkage, 05952 0, Name); 05953 } 05954 05955 return GV; 05956 } 05957 05958 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder, 05959 IdentifierInfo *II) { 05960 llvm::GlobalVariable *&Entry = ClassReferences[II]; 05961 05962 if (!Entry) { 05963 std::string ClassName(getClassSymbolPrefix() + II->getName().str()); 05964 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 05965 Entry = 05966 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 05967 false, llvm::GlobalValue::InternalLinkage, 05968 ClassGV, 05969 "\01L_OBJC_CLASSLIST_REFERENCES_$_"); 05970 Entry->setAlignment( 05971 CGM.getTargetData().getABITypeAlignment( 05972 ObjCTypes.ClassnfABIPtrTy)); 05973 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 05974 CGM.AddUsedGlobal(Entry); 05975 } 05976 05977 return Builder.CreateLoad(Entry); 05978 } 05979 05980 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 05981 const ObjCInterfaceDecl *ID) { 05982 return EmitClassRefFromId(Builder, ID->getIdentifier()); 05983 } 05984 05985 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef( 05986 CGBuilderTy &Builder) { 05987 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 05988 return EmitClassRefFromId(Builder, II); 05989 } 05990 05991 llvm::Value * 05992 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 05993 const ObjCInterfaceDecl *ID) { 05994 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 05995 05996 if (!Entry) { 05997 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 05998 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 05999 Entry = 06000 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 06001 false, llvm::GlobalValue::InternalLinkage, 06002 ClassGV, 06003 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 06004 Entry->setAlignment( 06005 CGM.getTargetData().getABITypeAlignment( 06006 ObjCTypes.ClassnfABIPtrTy)); 06007 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 06008 CGM.AddUsedGlobal(Entry); 06009 } 06010 06011 return Builder.CreateLoad(Entry); 06012 } 06013 06014 /// EmitMetaClassRef - Return a Value * of the address of _class_t 06015 /// meta-data 06016 /// 06017 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 06018 const ObjCInterfaceDecl *ID) { 06019 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 06020 if (Entry) 06021 return Builder.CreateLoad(Entry); 06022 06023 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 06024 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 06025 Entry = 06026 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, 06027 llvm::GlobalValue::InternalLinkage, 06028 MetaClassGV, 06029 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 06030 Entry->setAlignment( 06031 CGM.getTargetData().getABITypeAlignment( 06032 ObjCTypes.ClassnfABIPtrTy)); 06033 06034 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 06035 CGM.AddUsedGlobal(Entry); 06036 06037 return Builder.CreateLoad(Entry); 06038 } 06039 06040 /// GetClass - Return a reference to the class for the given interface 06041 /// decl. 06042 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 06043 const ObjCInterfaceDecl *ID) { 06044 if (ID->isWeakImported()) { 06045 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 06046 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 06047 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 06048 } 06049 06050 return EmitClassRef(Builder, ID); 06051 } 06052 06053 /// Generates a message send where the super is the receiver. This is 06054 /// a message send to self with special delivery semantics indicating 06055 /// which class's method should be called. 06056 CodeGen::RValue 06057 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 06058 ReturnValueSlot Return, 06059 QualType ResultType, 06060 Selector Sel, 06061 const ObjCInterfaceDecl *Class, 06062 bool isCategoryImpl, 06063 llvm::Value *Receiver, 06064 bool IsClassMessage, 06065 const CodeGen::CallArgList &CallArgs, 06066 const ObjCMethodDecl *Method) { 06067 // ... 06068 // Create and init a super structure; this is a (receiver, class) 06069 // pair we will pass to objc_msgSendSuper. 06070 llvm::Value *ObjCSuper = 06071 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 06072 06073 llvm::Value *ReceiverAsObject = 06074 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 06075 CGF.Builder.CreateStore(ReceiverAsObject, 06076 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 06077 06078 // If this is a class message the metaclass is passed as the target. 06079 llvm::Value *Target; 06080 if (IsClassMessage) { 06081 if (isCategoryImpl) { 06082 // Message sent to "super' in a class method defined in 06083 // a category implementation. 06084 Target = EmitClassRef(CGF.Builder, Class); 06085 Target = CGF.Builder.CreateStructGEP(Target, 0); 06086 Target = CGF.Builder.CreateLoad(Target); 06087 } else 06088 Target = EmitMetaClassRef(CGF.Builder, Class); 06089 } else 06090 Target = EmitSuperClassRef(CGF.Builder, Class); 06091 06092 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 06093 // ObjCTypes types. 06094 llvm::Type *ClassTy = 06095 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 06096 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 06097 CGF.Builder.CreateStore(Target, 06098 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 06099 06100 return (isVTableDispatchedSelector(Sel)) 06101 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 06102 ObjCSuper, ObjCTypes.SuperPtrCTy, 06103 true, CallArgs, Method) 06104 : EmitMessageSend(CGF, Return, ResultType, 06105 EmitSelector(CGF.Builder, Sel), 06106 ObjCSuper, ObjCTypes.SuperPtrCTy, 06107 true, CallArgs, Method, ObjCTypes); 06108 } 06109 06110 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 06111 Selector Sel, bool lval) { 06112 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 06113 06114 if (!Entry) { 06115 llvm::Constant *Casted = 06116 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 06117 ObjCTypes.SelectorPtrTy); 06118 Entry = 06119 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 06120 llvm::GlobalValue::InternalLinkage, 06121 Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); 06122 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 06123 CGM.AddUsedGlobal(Entry); 06124 } 06125 06126 if (lval) 06127 return Entry; 06128 llvm::LoadInst* LI = Builder.CreateLoad(Entry); 06129 06130 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 06131 llvm::MDNode::get(VMContext, 06132 ArrayRef<llvm::Value*>())); 06133 return LI; 06134 } 06135 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 06136 /// objc_assign_ivar (id src, id *dst, ptrdiff_t) 06137 /// 06138 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 06139 llvm::Value *src, 06140 llvm::Value *dst, 06141 llvm::Value *ivarOffset) { 06142 llvm::Type * SrcTy = src->getType(); 06143 if (!isa<llvm::PointerType>(SrcTy)) { 06144 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 06145 assert(Size <= 8 && "does not support size > 8"); 06146 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 06147 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 06148 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 06149 } 06150 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 06151 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 06152 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 06153 src, dst, ivarOffset); 06154 return; 06155 } 06156 06157 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 06158 /// objc_assign_strongCast (id src, id *dst) 06159 /// 06160 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 06161 CodeGen::CodeGenFunction &CGF, 06162 llvm::Value *src, llvm::Value *dst) { 06163 llvm::Type * SrcTy = src->getType(); 06164 if (!isa<llvm::PointerType>(SrcTy)) { 06165 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 06166 assert(Size <= 8 && "does not support size > 8"); 06167 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 06168 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 06169 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 06170 } 06171 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 06172 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 06173 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 06174 src, dst, "weakassign"); 06175 return; 06176 } 06177 06178 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 06179 CodeGen::CodeGenFunction &CGF, 06180 llvm::Value *DestPtr, 06181 llvm::Value *SrcPtr, 06182 llvm::Value *Size) { 06183 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 06184 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 06185 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 06186 DestPtr, SrcPtr, Size); 06187 return; 06188 } 06189 06190 /// EmitObjCWeakRead - Code gen for loading value of a __weak 06191 /// object: objc_read_weak (id *src) 06192 /// 06193 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 06194 CodeGen::CodeGenFunction &CGF, 06195 llvm::Value *AddrWeakObj) { 06196 llvm::Type* DestTy = 06197 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 06198 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 06199 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 06200 AddrWeakObj, "weakread"); 06201 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 06202 return read_weak; 06203 } 06204 06205 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 06206 /// objc_assign_weak (id src, id *dst) 06207 /// 06208 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 06209 llvm::Value *src, llvm::Value *dst) { 06210 llvm::Type * SrcTy = src->getType(); 06211 if (!isa<llvm::PointerType>(SrcTy)) { 06212 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 06213 assert(Size <= 8 && "does not support size > 8"); 06214 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 06215 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 06216 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 06217 } 06218 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 06219 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 06220 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 06221 src, dst, "weakassign"); 06222 return; 06223 } 06224 06225 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 06226 /// objc_assign_global (id src, id *dst) 06227 /// 06228 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 06229 llvm::Value *src, llvm::Value *dst, 06230 bool threadlocal) { 06231 llvm::Type * SrcTy = src->getType(); 06232 if (!isa<llvm::PointerType>(SrcTy)) { 06233 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 06234 assert(Size <= 8 && "does not support size > 8"); 06235 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 06236 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 06237 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 06238 } 06239 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 06240 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 06241 if (!threadlocal) 06242 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 06243 src, dst, "globalassign"); 06244 else 06245 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 06246 src, dst, "threadlocalassign"); 06247 return; 06248 } 06249 06250 void 06251 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 06252 const ObjCAtSynchronizedStmt &S) { 06253 EmitAtSynchronizedStmt(CGF, S, 06254 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 06255 cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 06256 } 06257 06258 llvm::Constant * 06259 CGObjCNonFragileABIMac::GetEHType(QualType T) { 06260 // There's a particular fixed type info for 'id'. 06261 if (T->isObjCIdType() || 06262 T->isObjCQualifiedIdType()) { 06263 llvm::Constant *IDEHType = 06264 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 06265 if (!IDEHType) 06266 IDEHType = 06267 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 06268 false, 06269 llvm::GlobalValue::ExternalLinkage, 06270 0, "OBJC_EHTYPE_id"); 06271 return IDEHType; 06272 } 06273 06274 // All other types should be Objective-C interface pointer types. 06275 const ObjCObjectPointerType *PT = 06276 T->getAs<ObjCObjectPointerType>(); 06277 assert(PT && "Invalid @catch type."); 06278 const ObjCInterfaceType *IT = PT->getInterfaceType(); 06279 assert(IT && "Invalid @catch type."); 06280 return GetInterfaceEHType(IT->getDecl(), false); 06281 } 06282 06283 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 06284 const ObjCAtTryStmt &S) { 06285 EmitTryCatchStmt(CGF, S, 06286 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 06287 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 06288 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 06289 } 06290 06291 /// EmitThrowStmt - Generate code for a throw statement. 06292 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 06293 const ObjCAtThrowStmt &S) { 06294 if (const Expr *ThrowExpr = S.getThrowExpr()) { 06295 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 06296 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 06297 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception) 06298 .setDoesNotReturn(); 06299 } else { 06300 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn()) 06301 .setDoesNotReturn(); 06302 } 06303 06304 CGF.Builder.CreateUnreachable(); 06305 CGF.Builder.ClearInsertionPoint(); 06306 } 06307 06308 llvm::Constant * 06309 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 06310 bool ForDefinition) { 06311 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 06312 06313 // If we don't need a definition, return the entry if found or check 06314 // if we use an external reference. 06315 if (!ForDefinition) { 06316 if (Entry) 06317 return Entry; 06318 06319 // If this type (or a super class) has the __objc_exception__ 06320 // attribute, emit an external reference. 06321 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 06322 return Entry = 06323 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 06324 llvm::GlobalValue::ExternalLinkage, 06325 0, 06326 ("OBJC_EHTYPE_$_" + 06327 ID->getIdentifier()->getName())); 06328 } 06329 06330 // Otherwise we need to either make a new entry or fill in the 06331 // initializer. 06332 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 06333 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 06334 std::string VTableName = "objc_ehtype_vtable"; 06335 llvm::GlobalVariable *VTableGV = 06336 CGM.getModule().getGlobalVariable(VTableName); 06337 if (!VTableGV) 06338 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, 06339 false, 06340 llvm::GlobalValue::ExternalLinkage, 06341 0, VTableName); 06342 06343 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 06344 06345 llvm::Constant *Values[] = { 06346 llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx), 06347 GetClassName(ID->getIdentifier()), 06348 GetClassGlobal(ClassName) 06349 }; 06350 llvm::Constant *Init = 06351 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 06352 06353 if (Entry) { 06354 Entry->setInitializer(Init); 06355 } else { 06356 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 06357 llvm::GlobalValue::WeakAnyLinkage, 06358 Init, 06359 ("OBJC_EHTYPE_$_" + 06360 ID->getIdentifier()->getName())); 06361 } 06362 06363 if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility) 06364 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 06365 Entry->setAlignment(CGM.getTargetData().getABITypeAlignment( 06366 ObjCTypes.EHTypeTy)); 06367 06368 if (ForDefinition) { 06369 Entry->setSection("__DATA,__objc_const"); 06370 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 06371 } else { 06372 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 06373 } 06374 06375 return Entry; 06376 } 06377 06378 /* *** */ 06379 06380 CodeGen::CGObjCRuntime * 06381 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 06382 if (CGM.getLangOpts().ObjCNonFragileABI) 06383 return new CGObjCNonFragileABIMac(CGM); 06384 return new CGObjCMac(CGM); 06385 }