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