1c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===// 2c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// 3c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// The LLVM Compiler Infrastructure 4c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// 5c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// License. See LICENSE.TXT for details. 7c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// 8c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===----------------------------------------------------------------------===// 9c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides Objective-C code generation targeting the Apple runtime. 11c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// 12c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===----------------------------------------------------------------------===// 13c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 14c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar#include "CGObjCRuntime.h" 15f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 16198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar#include "CGRecordLayout.h" 17f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar#include "CodeGenModule.h" 18b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar#include "CodeGenFunction.h" 19d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall#include "CGBlocks.h" 2036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CGCleanup.h" 21bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar#include "clang/AST/ASTContext.h" 22e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/Decl.h" 236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar#include "clang/AST/DeclObjC.h" 2419cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "clang/AST/RecordLayout.h" 2516f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h" 26f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar#include "clang/Basic/LangOptions.h" 2706057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth#include "clang/Frontend/CodeGenOptions.h" 28f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 2987bb5822bfa4baea23a3d9273df266777f3ab796John McCall#include "llvm/InlineAsm.h" 3087bb5822bfa4baea23a3d9273df266777f3ab796John McCall#include "llvm/IntrinsicInst.h" 3169243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson#include "llvm/LLVMContext.h" 32bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar#include "llvm/Module.h" 330c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar#include "llvm/ADT/DenseSet.h" 34330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/ADT/SetVector.h" 35330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/ADT/SmallString.h" 36191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian#include "llvm/ADT/SmallPtrSet.h" 378e3f86193995c47ee0d229e4336c3382410f09f5John McCall#include "llvm/Support/CallSite.h" 38330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/Support/raw_ostream.h" 394e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar#include "llvm/Target/TargetData.h" 40f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin#include <cstdio> 41c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 42c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarusing namespace clang; 4346f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbarusing namespace CodeGen; 44c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 459777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar 46c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarnamespace { 47bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbartypedef std::vector<llvm::Constant*> ConstantVector; 49ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar 506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// FIXME: We should find a nicer way to make the labels for metadata, string 516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// concatenation is lame. 526efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 53ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass ObjCCommonTypesHelper { 54a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonprotected: 55a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::LLVMContext &VMContext; 566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianprivate: 580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // The types of these functions don't really matter because we 590774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // should always bitcast before calling them. 600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall 610774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSend (id, SEL, ...) 620774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 630774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The default messenger, used for sends whose ABI is unchanged from 640774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// the all-integer/pointer case. 65d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendFn() const { 66f85e193739c953358c865005855253af4f68a497John McCall // Add the non-lazy-bind attribute, since objc_msgSend is likely to 67f85e193739c953358c865005855253af4f68a497John McCall // be called a lot. 689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 700774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 71f85e193739c953358c865005855253af4f68a497John McCall "objc_msgSend", 72f85e193739c953358c865005855253af4f68a497John McCall llvm::Attribute::NonLazyBind); 73d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 750774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSend_stret (id, SEL, ...) 760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 770774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used when the return value is an aggregate returned 780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// by indirect reference in the first argument, and therefore the 790774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// self and selector parameters are shifted over by one. 80d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendStretFn() const { 819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 820774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, 830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSend_stret"); 856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 86d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 880774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 890774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 900774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used when the return value is returned on the x87 910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// floating-point stack; without a special entrypoint, the nil case 920774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// would be unbalanced. 93d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendFpretFn() const { 949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 950774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get( 960032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Type::getDoubleTy(VMContext), 970774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 980774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSend_fpret"); 996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 100d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1020774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 1030774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1040774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used for super calls, which have different dispatch 1050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// semantics. The class passed is the superclass of the current 1060774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// class. 107d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFn() const { 1089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 10996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1100774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 1110774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSendSuper"); 112d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 1150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1160774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// A slightly different messenger used for super calls. The class 1170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// passed is the current class. 118d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFn2() const { 1199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 12096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1210774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 1220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSendSuper2"); 123d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1250774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super, 1260774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// SEL op, ...) 1270774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1280774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used for super calls which return an aggregate indirectly. 129d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperStretFn() const { 1309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 131a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 1320774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, true), 1336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_msgSendSuper_stret"); 134d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1360774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 1370774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// SEL op, ...) 1380774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1390774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// objc_msgSendSuper_stret with the super2 semantics. 140d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperStretFn2() const { 1419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 142a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 1430774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, true), 1446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_msgSendSuper2_stret"); 145d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 147d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFpretFn() const { 148d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian // There is no objc_msgSendSuper_fpret? How can that work? 149d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return getMessageSendSuperFn(); 150d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 152d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFpretFn2() const { 153d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian // There is no objc_msgSendSuper_fpret? How can that work? 154d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return getMessageSendSuperFn2(); 155d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 157ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected: 158ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian CodeGen::CodeGenModule &CGM; 1596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 160bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic: 1619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 1629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Int8PtrTy; 1636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1642bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 1659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ObjectPtrTy; 1666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1676d657c4809d9128be88705d32768de007b988212Fariborz Jahanian /// PtrObjectPtrTy - LLVM type for id * 1689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *PtrObjectPtrTy; 1696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1704e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 1719cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SelectorPtrTy; 1726efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolPtrTy - LLVM type for external protocol handles 1736efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// (typeof(Protocol)) 1749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ExternalProtocolPtrTy; 1756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 17619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar // SuperCTy - clang type for struct objc_super. 17719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar QualType SuperCTy; 17819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar // SuperPtrCTy - clang type for struct objc_super *. 17919cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar QualType SuperPtrCTy; 1806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 181e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar /// SuperTy - LLVM type for struct objc_super. 1829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SuperTy; 18314c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar /// SuperPtrTy - LLVM type for struct objc_super *. 1849cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SuperPtrTy; 1856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 18630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 18730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// in GCC parlance). 1889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *PropertyTy; 1896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 19030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyListTy - LLVM type for struct objc_property_list 19130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// (_prop_list_t in GCC parlance). 1929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *PropertyListTy; 19330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 1949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *PropertyListPtrTy; 1956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 19630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // MethodTy - LLVM type for struct objc_method. 1979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodTy; 1986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 199d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian /// CacheTy - LLVM type for struct objc_cache. 2009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *CacheTy; 201d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian /// CachePtrTy - LLVM type for struct objc_cache *. 2029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *CachePtrTy; 2039d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 20472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getGetPropertyFn() { 20572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner CodeGen::CodeGenTypes &Types = CGM.getTypes(); 20672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner ASTContext &Ctx = CGM.getContext(); 20772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // id objc_getProperty (id, SEL, ptrdiff_t, bool) 2085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,4> Params; 209ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 210ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 21172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 21272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(SelType); 213ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 21472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 2152acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 21604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall Types.GetFunctionType(Types.getFunctionInfo(IdType, Params, 217264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FunctionType::ExtInfo()), 218264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola false); 21972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 22072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 2216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 22272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getSetPropertyFn() { 22372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner CodeGen::CodeGenTypes &Types = CGM.getTypes(); 22472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner ASTContext &Ctx = CGM.getContext(); 22572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 2265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,6> Params; 227ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 228ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 22972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 23072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(SelType); 231ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 23272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 23372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 23472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 2352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 23604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 237264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FunctionType::ExtInfo()), 238264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola false); 23972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 24072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 2416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2426cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 2436cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian llvm::Constant *getCopyStructFn() { 2446cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian CodeGen::CodeGenTypes &Types = CGM.getTypes(); 2456cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian ASTContext &Ctx = CGM.getContext(); 2466cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian // void objc_copyStruct (void *, const void *, size_t, bool, bool) 2475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,5> Params; 2486cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 2496cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 2506cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.LongTy); 2516cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.BoolTy); 2526cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.BoolTy); 2532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 2546cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 2556cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian FunctionType::ExtInfo()), 2566cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian false); 2576cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); 2586cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian } 2596cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 26072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getEnumerationMutationFn() { 261c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar CodeGen::CodeGenTypes &Types = CGM.getTypes(); 262c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar ASTContext &Ctx = CGM.getContext(); 26372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // void objc_enumerationMutation (id) 2645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,1> Params; 265ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); 2662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 26704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 268264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FunctionType::ExtInfo()), 269264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola false); 27072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 27172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 2726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 273db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 27472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getGcReadWeakFn() { 27572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // id objc_read_weak (id *) 2769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy->getPointerTo() }; 2776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::FunctionType *FTy = 2780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 27972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 2806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 2816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 282db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignWeakFn -- LLVM objc_assign_weak function. 28396508e1fea58347b6401ca9a4728c0b268174603Chris Lattner llvm::Constant *getGcAssignWeakFn() { 28496508e1fea58347b6401ca9a4728c0b268174603Chris Lattner // id objc_assign_weak (id, id *) 2859cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 28696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner llvm::FunctionType *FTy = 2870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 28896508e1fea58347b6401ca9a4728c0b268174603Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 28996508e1fea58347b6401ca9a4728c0b268174603Chris Lattner } 2906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 291db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignGlobalFn -- LLVM objc_assign_global function. 292bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignGlobalFn() { 293bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner // id objc_assign_global(id, id *) 2949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 295a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 2960774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 297bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 298bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 2996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 300021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function. 301021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Constant *getGcAssignThreadLocalFn() { 302021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian // id objc_assign_threadlocal(id src, id * dest) 3039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 304021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::FunctionType *FTy = 3050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 306021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal"); 307021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian } 308021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian 309db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 310bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignIvarFn() { 3116c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian // id objc_assign_ivar(id, id *, ptrdiff_t) 3129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(), 3139cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CGM.PtrDiffTy }; 314a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 3150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 316bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 317bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 3186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 319082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function. 320082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Constant *GcMemmoveCollectableFn() { 321082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian // void *objc_memmove_collectable(void *dst, const void *src, size_t size) 3229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy }; 3230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false); 324082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 325082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian } 3266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 327db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 328bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignStrongCastFn() { 329021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian // id objc_assign_strongCast(id, id *) 3309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 331a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 3320774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 333bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 334bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 335f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson 336f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson /// ExceptionThrowFn - LLVM objc_exception_throw function. 337bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getExceptionThrowFn() { 338bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner // void objc_exception_throw(id) 3399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 340bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::FunctionType *FTy = 3410774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, args, false); 342bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 343bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 3446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 34569677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian /// ExceptionRethrowFn - LLVM objc_exception_rethrow function. 34669677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian llvm::Constant *getExceptionRethrowFn() { 34769677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian // void objc_exception_rethrow(void) 3480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false); 34969677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow"); 35069677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian } 35169677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian 3521c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar /// SyncEnterFn - LLVM object_sync_enter function. 353b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner llvm::Constant *getSyncEnterFn() { 354b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner // void objc_sync_enter (id) 3559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 356b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner llvm::FunctionType *FTy = 3570774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, args, false); 358b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 359b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner } 3606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3611c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar /// SyncExitFn - LLVM object_sync_exit function. 362bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getSyncExitFn() { 363bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner // void objc_sync_exit (id) 3649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 365bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::FunctionType *FTy = 3660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, args, false); 367bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 368bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 3696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 370d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFn(bool IsSuper) const { 371d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 3724176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 374d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFn2(bool IsSuper) const { 375d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 3764176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 378d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendStretFn(bool IsSuper) const { 379d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 3804176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 382d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendStretFn2(bool IsSuper) const { 383d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 3844176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 386d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFpretFn(bool IsSuper) const { 387d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 3884176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 390d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFpretFn2(bool IsSuper) const { 391d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 3924176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 3936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 394d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 395d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian ~ObjCCommonTypesHelper(){} 396d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian}; 397ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian 398d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// ObjCTypesHelper - Helper class that encapsulates lazy 399d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// construction of varies types used during ObjC generation. 400d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianclass ObjCTypesHelper : public ObjCCommonTypesHelper { 401ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 4024e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// SymtabTy - LLVM type for struct objc_symtab. 4039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SymtabTy; 40427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// SymtabPtrTy - LLVM type for struct objc_symtab *. 4059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SymtabPtrTy; 4064e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// ModuleTy - LLVM type for struct objc_module. 4079cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ModuleTy; 408259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 4096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolTy - LLVM type for struct objc_protocol. 4109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolTy; 4116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 4129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolPtrTy; 4136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionTy - LLVM type for struct 4146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_protocol_extension. 4159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolExtensionTy; 4166efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionTy - LLVM type for struct 4176efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_protocol_extension *. 4189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolExtensionPtrTy; 4196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionTy - LLVM type for struct 4206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description. 4219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodDescriptionTy; 4226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionListTy - LLVM type for struct 4236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description_list. 4249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodDescriptionListTy; 4256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionListPtrTy - LLVM type for struct 4266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description_list *. 4279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodDescriptionListPtrTy; 4286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolListTy - LLVM type for struct objc_property_list. 4299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolListTy; 4306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 4319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolListPtrTy; 43286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar /// CategoryTy - LLVM type for struct objc_category. 4339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *CategoryTy; 43427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassTy - LLVM type for struct objc_class. 4359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassTy; 43627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassPtrTy - LLVM type for struct objc_class *. 4379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassPtrTy; 43827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassExtensionTy - LLVM type for struct objc_class_ext. 4399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassExtensionTy; 44027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 4419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassExtensionPtrTy; 44227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // IvarTy - LLVM type for struct objc_ivar. 4439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarTy; 44427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListTy - LLVM type for struct objc_ivar_list. 4459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListTy; 44627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 4479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListPtrTy; 44827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// MethodListTy - LLVM type for struct objc_method_list. 4499cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListTy; 45027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// MethodListPtrTy - LLVM type for struct objc_method_list *. 4519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListPtrTy; 4526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 453124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 4549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ExceptionDataTy; 4559d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 456124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 45734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionTryEnterFn() { 4589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 459a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 4600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, false), 4616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_try_enter"); 46234b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 463124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 464124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 46534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionTryExitFn() { 4669cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 467a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 4680774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, false), 4696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_try_exit"); 47034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 471124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 472124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionExtractFn - LLVM objc_exception_extract function. 47334b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionExtractFn() { 4749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 47596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 4760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 47734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner "objc_exception_extract"); 47834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 4796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 480124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionMatchFn - LLVM objc_exception_match function. 48134b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionMatchFn() { 4829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy }; 4836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return CGM.CreateRuntimeFunction( 4840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.Int32Ty, params, false), 4856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_match"); 4866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 48734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 4886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 489124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// SetJmpFn - LLVM _setjmp function. 49034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getSetJmpFn() { 4910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // This is specifically the prototype for x86. 4929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() }; 4930774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, 4940774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 4950774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "_setjmp"); 49634b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 4976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 498bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic: 499bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 500ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ~ObjCTypesHelper() {} 501bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}; 502bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 50330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 504ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian/// modern abi 50530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 50683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanianpublic: 5076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 508d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // MethodListnfABITy - LLVM for struct _method_list_t 5099cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodListnfABITy; 5106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 511d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 5129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListnfABIPtrTy; 5136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 514d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolnfABITy = LLVM for struct _protocol_t 5159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolnfABITy; 5166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 517948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 5189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolnfABIPtrTy; 519948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 520d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 5219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolListnfABITy; 5226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 523d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 5249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolListnfABIPtrTy; 5256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 526d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ClassnfABITy - LLVM for struct _class_t 5279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassnfABITy; 5286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 529aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // ClassnfABIPtrTy - LLVM for struct _class_t* 5309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassnfABIPtrTy; 5316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 532d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarnfABITy - LLVM for struct _ivar_t 5339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarnfABITy; 5346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 535d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarListnfABITy - LLVM for struct _ivar_list_t 5369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarListnfABITy; 5376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 538d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 5399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListnfABIPtrTy; 5406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 541d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ClassRonfABITy - LLVM for struct _class_ro_t 5429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassRonfABITy; 5436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 544d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 5459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ImpnfABITy; 5466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 547d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // CategorynfABITy - LLVM for struct _category_t 5489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *CategorynfABITy; 5496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5502e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // New types for nonfragile abi messaging. 5516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5522e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefTy - LLVM for: 5532e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _message_ref_t { 5542e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // IMP messenger; 5552e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 5562e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 5579cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MessageRefTy; 55883a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // MessageRefCTy - clang type for struct _message_ref_t 55983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian QualType MessageRefCTy; 5606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefPtrTy - LLVM for struct _message_ref_t* 5629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MessageRefPtrTy; 56383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // MessageRefCPtrTy - clang type for struct _message_ref_t* 56483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian QualType MessageRefCPtrTy; 5656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 566ef163782d227f064df5988d46487609324a0169eFariborz Jahanian // MessengerTy - Type of the messenger (shown as IMP above) 5679cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::FunctionType *MessengerTy; 5686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5692e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefTy - LLVM for: 5702e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _super_message_ref_t { 5712e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SUPER_IMP messenger; 5722e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 5732e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 5749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SuperMessageRefTy; 5756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5762e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 5779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SuperMessageRefPtrTy; 5788ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar 5791c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendFixupFn() { 5801c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 5819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 58296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 5830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 5841c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_fixup"); 5851c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 5866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5871c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendFpretFixupFn() { 5881c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 5899cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 59096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 5910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 5921c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_fpret_fixup"); 5931c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 5946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5951c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendStretFixupFn() { 5961c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 5979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 59896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 5990774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6001c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_stret_fixup"); 6011c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6031c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendSuper2FixupFn() { 6046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // id objc_msgSendSuper2_fixup (struct objc_super *, 6051c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // struct _super_message_ref_t*, ...) 6069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 60796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6080774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6091c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSendSuper2_fixup"); 6101c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6121c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendSuper2StretFixupFn() { 6136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 6141c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // struct _super_message_ref_t*, ...) 6159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 61696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6181c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSendSuper2_stret_fixup"); 6191c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6218a56911956aa875922a5faa3787c6829e7f7011fChris Lattner llvm::Constant *getObjCEndCatchFn() { 6220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false), 6238a56911956aa875922a5faa3787c6829e7f7011fChris Lattner "objc_end_catch"); 6246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6258a56911956aa875922a5faa3787c6829e7f7011fChris Lattner } 6266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6278a56911956aa875922a5faa3787c6829e7f7011fChris Lattner llvm::Constant *getObjCBeginCatchFn() { 6289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy }; 62996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 6300774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 6318a56911956aa875922a5faa3787c6829e7f7011fChris Lattner "objc_begin_catch"); 6328a56911956aa875922a5faa3787c6829e7f7011fChris Lattner } 633e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 6349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *EHTypeTy; 6359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *EHTypePtrTy; 6369d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 63730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 63830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ~ObjCNonFragileABITypesHelper(){} 639ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 6406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 641ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCCommonMac : public CodeGen::CGObjCRuntime { 6429397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanianpublic: 6439397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // FIXME - accessibility 644a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian class GC_IVAR { 645820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian public: 6468b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned ivar_bytepos; 6478b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned ivar_size; 6488b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 6496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ivar_bytepos(bytepos), ivar_size(size) {} 6500941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar 6510941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar // Allow sorting based on byte pos. 6520941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar bool operator<(const GC_IVAR &b) const { 6530941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar return ivar_bytepos < b.ivar_bytepos; 6540941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar } 655a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian }; 6566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6579397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian class SKIP_SCAN { 6588b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar public: 6598b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned skip; 6608b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned scan; 6616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 6628b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar : skip(_skip), scan(_scan) {} 6639397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian }; 6646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 665ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected: 666ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian CodeGen::CodeGenModule &CGM; 66769243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson llvm::LLVMContext &VMContext; 668ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME! May not be needing this after all. 669bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned ObjCABI; 6706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // gc ivar layout bitmap calculation helper caches. 6725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<GC_IVAR, 16> SkipIvars; 6735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<GC_IVAR, 16> IvarsInfo; 6746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 675242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// LazySymbols - Symbols to generate a lazy reference for. See 676242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// DefinedSymbols and FinishModule(). 677330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::SetVector<IdentifierInfo*> LazySymbols; 6786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 679242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// DefinedSymbols - External symbols which are defined by this 680242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// module. The symbols in this list and LazySymbols are used to add 681242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// special linker symbols which ensure that Objective-C modules are 682242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// linked properly. 683330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::SetVector<IdentifierInfo*> DefinedSymbols; 6846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6854e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// ClassNames - uniqued class names. 6866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 6876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 688259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar /// MethodVarNames - uniqued method variable names. 689259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 6906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 691b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian /// DefinedCategoryNames - list of category names in form Class_Category. 692b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian llvm::SetVector<std::string> DefinedCategoryNames; 693b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian 6946efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodVarTypes - uniqued method type signatures. We have to use 6956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// a StringMap here because have no other unique reference. 6966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 6976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 698c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar /// MethodDefinitions - map of methods which have been defined in 699c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar /// this translation unit. 700c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 7016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 702c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar /// PropertyNames - uniqued method variable names. 703c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 7046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 70527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassReferences - uniqued class references. 70627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 7076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 708259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar /// SelectorReferences - uniqued selector references. 709259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 7106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// Protocols - Protocols for which an objc_protocol structure has 7126efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// been emitted. Forward declarations are handled by creating an 7136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// empty structure whose initializer is filled in when/if defined. 7146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 7156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// DefinedProtocols - Protocols which have actually been 7170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// defined. We should not need this, see FIXME in GenerateProtocol. 7180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 7196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 72027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// DefinedClasses - List of defined classes. 72127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar std::vector<llvm::GlobalValue*> DefinedClasses; 72274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 72374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 72474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar std::vector<llvm::GlobalValue*> DefinedNonLazyClasses; 7256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 72627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// DefinedCategories - List of defined categories. 72727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar std::vector<llvm::GlobalValue*> DefinedCategories; 7286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 72974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 73074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar std::vector<llvm::GlobalValue*> DefinedNonLazyCategories; 7316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 73256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetNameForMethod - Return a name for the given method. 73356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// \param[out] NameOut - The return value. 73456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian void GetNameForMethod(const ObjCMethodDecl *OMD, 73556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const ObjCContainerDecl *CD, 7365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> &NameOut); 7376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 73856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetMethodVarName - Return a unique constant for the given 73956210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// selector's name. The return value has type char *. 74056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetMethodVarName(Selector Sel); 74156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 7426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 74356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetMethodVarType - Return a unique constant for the given 74456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// selector's name. The return value has type char *. 7456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 74656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian // FIXME: This is a horrible name. 74756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 7483e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar llvm::Constant *GetMethodVarType(const FieldDecl *D); 7496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 75056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetPropertyName - Return a unique constant for the given 75156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// name. The return value has type char *. 75256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 7536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 75456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian // FIXME: This can be dropped once string functions are unified. 75556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 75656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const Decl *Container); 7576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 758058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian /// GetClassName - Return a unique constant for the given selector's 759058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian /// name. The return value has type char *. 760058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::Constant *GetClassName(IdentifierInfo *Ident); 7616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7629d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD); 7639d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 764d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// BuildIvarLayout - Builds ivar layout bitmap for the class 765d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// implementation for the __strong or __weak case. 766d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// 767c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 768c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian bool ForStrongLayout); 76993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 770b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); 7716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 772d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar void BuildAggrIvarRecordLayout(const RecordType *RT, 7736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, bool ForStrongLayout, 7746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool &HasUnion); 7755a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbar void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 776c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian const llvm::StructLayout *Layout, 777a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian const RecordDecl *RD, 778db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const SmallVectorImpl<const FieldDecl*> &RecFields, 779d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian unsigned int BytePos, bool ForStrongLayout, 78081adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian bool &HasUnion); 781c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian 782d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian /// GetIvarLayoutName - Returns a unique constant for the given 783d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian /// ivar layout bitmap. 784d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 785d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes); 7866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7875de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian /// EmitPropertyList - Emit the given property list. The return 7885de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian /// value has type PropertyListPtrTy. 7895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitPropertyList(Twine Name, 7906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container, 7915de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian const ObjCContainerDecl *OCD, 7925de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes); 7936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 794191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian /// PushProtocolProperties - Push protocol's property on the input stack. 795191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 796191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian std::vector<llvm::Constant*> &Properties, 797191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const Decl *Container, 798191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const ObjCProtocolDecl *PROTO, 799191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes); 800191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian 801da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetProtocolRef - Return a reference to the internal protocol 802da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// description, creating an empty one if it has not been 803da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// defined. The return value has type ProtocolPtrTy. 804da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 805b21f07e056b6c9918bf938f19ca561c60f778695Fariborz Jahanian 806fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// CreateMetadataVar - Create a global variable with internal 807fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// linkage for use by the Objective-C runtime. 808fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// 809fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// This is a convenience wrapper which not only creates the 810fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// variable, but also sets the section and alignment and adds the 811ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner /// global to the "llvm.used" list. 81235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// 81335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Name - The variable name. 81435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Init - The variable initializer; this is also used to 81535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// define the type of the variable. 81635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Section - The section the variable should go into, or 0. 81735bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Align - The alignment for the variable, or 0. 81835bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param AddToUsed - Whether the variable should be added to 819c15830694f2bd01080e6c39a88c5b8ff2288af18Daniel Dunbar /// "llvm.used". 8205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::GlobalVariable *CreateMetadataVar(Twine Name, 821fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar llvm::Constant *Init, 822fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar const char *Section, 82335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar unsigned Align, 82435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar bool AddToUsed); 825fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar 826944c84313da15477eb18d90babb0890d10d98082John McCall CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 827944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 828944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 829944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Sel, 830944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Arg0, 831944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 832944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 833944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 834944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *OMD, 835944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCCommonTypesHelper &ObjCTypes); 8363e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar 837fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar /// EmitImageInfo - Emit the image info marker used to encode some module 838fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar /// level information. 839fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar void EmitImageInfo(); 840fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar 841ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 84269243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : 8431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CGM(cgm), VMContext(cgm.getLLVMContext()) { } 8446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 8450d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); 8466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 847493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 848493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian const ObjCContainerDecl *CD=0); 8496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 850da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 8516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 852da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocol - Get the protocol object for the given 853da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// declaration, emitting it if necessary. The return value has type 854da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// ProtocolPtrTy. 855da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 8566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 857da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocolRef - Get a forward reference to the protocol 858da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// object for the given declaration, emitting it if needed. These 859da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// forward references will be filled in with empty bodies if no 860da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// definition is seen. The return value has type ProtocolPtrTy. 861da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 8626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, 8636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo); 86489ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian 865ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 8666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 867ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCMac : public CGObjCCommonMac { 868ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate: 869ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCTypesHelper ObjCTypes; 870f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 8714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// EmitModuleInfo - Another marker encoding module level 8726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar /// information. 8734e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar void EmitModuleInfo(); 8744e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 87527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitModuleSymols - Emit module symbols, the list of defined 87627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// classes and categories. The result has type SymtabPtrTy. 8774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar llvm::Constant *EmitModuleSymbols(); 8784e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 879f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar /// FinishModule - Write out global data structures at the end of 880f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar /// processing a translation unit. 881f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar void FinishModule(); 8826efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 88327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitClassExtension - Generate the class extension structure used 88427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// to store the weak ivar layout and properties. The return value 88527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// has type ClassExtensionPtrTy. 88627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 88727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 88827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 88927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// for the given class. 8906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitClassRef(CGBuilderTy &Builder, 89127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID); 892b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 893f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 894f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II); 895f85e193739c953358c865005855253af4f68a497John McCall 896f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 897f85e193739c953358c865005855253af4f68a497John McCall 898b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian /// EmitSuperClassRef - Emits reference to class's main metadata class. 899b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID); 90027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 90127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitIvarList - Emit the ivar list for the given 90227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// implementation. If ForClass is true the list of class ivars 90327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// (i.e. metaclass ivars) is emitted, otherwise the list of 90427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// interface ivars will be emitted. The return value has type 90527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListPtrTy. 90627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 90746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian bool ForClass); 9086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 909f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// EmitMetaClass - Emit a forward reference to the class structure 910f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// for the metaclass of the given interface. The return value has 911f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// type ClassPtrTy. 912f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 913f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 91427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMetaClass - Emit a class structure for the metaclass of the 915f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// given implementation. The return value has type ClassPtrTy. 91627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 91727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *Protocols, 918ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods); 9196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 920ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 9216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 922ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 92327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 92427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMethodList - Emit the method list for the given 925af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar /// implementation. The return value has type MethodListPtrTy. 9265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodList(Twine Name, 92786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar const char *Section, 928ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods); 92927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 93027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMethodDescList - Emit a method description list for a list of 9316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar /// method declarations. 9326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - TypeName: The name for the type containing the methods. 9336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - IsProtocol: True iff these methods are for a protocol. 9346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - ClassMethds: True iff these are class methods. 9356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - Required: When true, only "required" methods are 9366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// listed. Similarly, when false only "optional" methods are 9376efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// listed. For classes this should always be true. 9386efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - begin, end: The method list to output. 9396efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// 9406efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// The return value has type MethodDescriptionListPtrTy. 9415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodDescList(Twine Name, 942ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const char *Section, 943ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods); 9446efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 9450c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// GetOrEmitProtocol - Get the protocol object for the given 9460c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// declaration, emitting it if necessary. The return value has type 9470c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// ProtocolPtrTy. 948da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 9490c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 9500c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// GetOrEmitProtocolRef - Get a forward reference to the protocol 9510c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// object for the given declaration, emitting it if needed. These 9520c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// forward references will be filled in with empty bodies if no 9530c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// definition is seen. The return value has type ProtocolPtrTy. 954da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 9550c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 9566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// EmitProtocolExtension - Generate the protocol extension 9576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// structure used to store optional instance and class methods, and 9586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// protocol properties. The return value has type 9596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionPtrTy. 960ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant * 961ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar EmitProtocolExtension(const ObjCProtocolDecl *PD, 962ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &OptInstanceMethods, 963ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &OptClassMethods); 9646efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 9656efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// EmitProtocolList - Generate the list of referenced 9666efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// protocols. The return value has type ProtocolListPtrTy. 9675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitProtocolList(Twine Name, 968dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 969dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator end); 9706efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 97127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 97227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// for the given selector. 97303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 97403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval=false); 9756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 9766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarpublic: 977c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar CGObjCMac(CodeGen::CodeGenModule &cgm); 978c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 979aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Function *ModuleInitFunction(); 9806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 9818f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 982ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 9837f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 9847f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 985f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 986df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 987c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 988df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 9898f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar 9906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual CodeGen::RValue 9918f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 992ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 9937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 9947f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 995f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar const ObjCInterfaceDecl *Class, 9967ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 997f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 99819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar bool IsClassMessage, 999d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 1000d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method); 10016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 100245d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar virtual llvm::Value *GetClass(CGBuilderTy &Builder, 100327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID); 1004c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 100503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 100603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval = false); 1007df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1008df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1009df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// untyped one. 1010df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1011df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 1012df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1013cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian virtual llvm::Constant *GetEHType(QualType T); 10145a180397870944548aaadeaebf58e415885b9489John McCall 10157ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 10167ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar 10177ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1018c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 101945d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1020af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar const ObjCProtocolDecl *PD); 10216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 102274391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *GetPropertyGetFunction(); 102374391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *GetPropertySetFunction(); 10248fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetGetStructFunction(); 10258fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetSetStructFunction(); 102674391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *EnumerationMutationFunction(); 10276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1029f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S); 1030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S); 1032f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S); 103364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 103464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson const ObjCAtThrowStmt &S); 10353e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 10366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *AddrWeakObj); 10373e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 10386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *src, llvm::Value *dst); 103958626500527695865683d1d65053743de8770b60Fariborz Jahanian virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1040021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dest, 1041021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal = false); 10427eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 10436c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dest, 10446c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset); 104558626500527695865683d1d65053743de8770b60Fariborz Jahanian virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 104658626500527695865683d1d65053743de8770b60Fariborz Jahanian llvm::Value *src, llvm::Value *dest); 1047082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1048082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Value *dest, llvm::Value *src, 104955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size); 10506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1051598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1052598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 1053598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 1054598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 1055598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers); 1056f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 10572a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 1058f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar); 10596f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 10606f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian /// GetClassGlobal - Return the global variable for the Objective-C 10616f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian /// class of the given name. 10626f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { 1063b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("CGObjCMac::GetClassGlobal"); 10646f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian } 1065c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}; 10666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 106730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass CGObjCNonFragileABIMac : public CGObjCCommonMac { 1068ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate: 106930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ObjCNonFragileABITypesHelper ObjCTypes; 1070aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::GlobalVariable* ObjCEmptyCacheVar; 1071aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::GlobalVariable* ObjCEmptyVtableVar; 10726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 10731139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// SuperClassReferences - uniqued super class references. 10741139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 10756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 10767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// MetaClassReferences - uniqued meta class references. 10777a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 1078e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 1079e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar /// EHTypeReferences - uniqued class ehtype references. 1080e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 10816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1082944c84313da15477eb18d90babb0890d10d98082John McCall /// VTableDispatchMethods - List of methods for which we generate 1083944c84313da15477eb18d90babb0890d10d98082John McCall /// vtable-based message dispatch. 1084944c84313da15477eb18d90babb0890d10d98082John McCall llvm::DenseSet<Selector> VTableDispatchMethods; 10856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1086a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian /// DefinedMetaClasses - List of defined meta-classes. 1087a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian std::vector<llvm::GlobalValue*> DefinedMetaClasses; 1088a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 1089944c84313da15477eb18d90babb0890d10d98082John McCall /// isVTableDispatchedSelector - Returns true if SEL is a 1090944c84313da15477eb18d90babb0890d10d98082John McCall /// vtable-based selector. 1091944c84313da15477eb18d90babb0890d10d98082John McCall bool isVTableDispatchedSelector(Selector Sel); 10926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1093aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian /// FinishNonFragileABIModule - Write out global data structures at the end of 1094aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian /// processing a translation unit. 1095aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian void FinishNonFragileABIModule(); 10968158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 1097463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar /// AddModuleClassList - Add the given list of class pointers to the 1098463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar /// module with the provided symbol and section names. 1099463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container, 1100463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SymbolName, 1101463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SectionName); 1102463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar 11036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 11046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceStart, 11056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceSize, 11066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID); 110784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 11086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *IsAGV, 110984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian llvm::Constant *SuperClassGV, 1110cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian llvm::Constant *ClassRoGV, 1111cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian bool HiddenVisibility); 11126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1113493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 11146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 11153819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 11166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1117493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian /// EmitMethodList - Emit the method list for the given 1118493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian /// implementation. The return value has type MethodListnfABITy. 11195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodList(Twine Name, 1120493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian const char *Section, 112198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian const ConstantVector &Methods); 112298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// EmitIvarList - Emit the ivar list for the given 112398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// implementation. If ForClass is true the list of class ivars 112498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// (i.e. metaclass ivars) is emitted, otherwise the list of 112598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// interface ivars will be emitted. The return value has type 112698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// IvarListnfABIPtrTy. 112798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 11286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1129ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 11302fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian const ObjCIvarDecl *Ivar, 11311bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian unsigned long int offset); 11326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1133da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocol - Get the protocol object for the given 1134da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// declaration, emitting it if necessary. The return value has type 1135da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// ProtocolPtrTy. 1136da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 11376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1138da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1139da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// object for the given declaration, emitting it if needed. These 1140da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// forward references will be filled in with empty bodies if no 1141da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// definition is seen. The return value has type ProtocolPtrTy. 1142da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 11436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1144da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// EmitProtocolList - Generate the list of referenced 1145da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// protocols. The return value has type ProtocolListPtrTy. 11465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitProtocolList(Twine Name, 1147da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCProtocolDecl::protocol_iterator begin, 11484655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian ObjCProtocolDecl::protocol_iterator end); 11496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1150944c84313da15477eb18d90babb0890d10d98082John McCall CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF, 1151944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 1152944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 1153944c84313da15477eb18d90babb0890d10d98082John McCall Selector Sel, 1154944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Receiver, 1155944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 1156944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 1157944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 1158944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *Method); 11596f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 11605a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar /// GetClassGlobal - Return the global variable for the Objective-C 11615a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar /// class of the given name. 11620f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 11636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 11640e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 11651139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// for the given class reference. 11666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitClassRef(CGBuilderTy &Builder, 11671139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar const ObjCInterfaceDecl *ID); 1168f85e193739c953358c865005855253af4f68a497John McCall 1169f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 1170f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II); 1171f85e193739c953358c865005855253af4f68a497John McCall 1172f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 11736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 11741139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 11751139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// for the given super class reference. 11766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 11776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID); 11786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 11797a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// EmitMetaClassRef - Return a Value * of the address of _class_t 11807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// meta-data 11816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 11827a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian const ObjCInterfaceDecl *ID); 11837a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian 1184ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 1185ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// the given ivar. 1186ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// 11875e88beaa0a86b162dfb9f53891adfdfbe925cc64Daniel Dunbar llvm::GlobalVariable * ObjCIvarOffsetVariable( 11886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID, 11896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCIvarDecl *Ivar); 11906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 119126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 119226cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian /// for the given selector. 119303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 119403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval=false); 1195e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 11968158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 1197e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar /// interface. The return value has type EHTypePtrTy. 11985a180397870944548aaadeaebf58e415885b9489John McCall llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 11998158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar bool ForDefinition); 12006ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 12016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *getMetaclassSymbolPrefix() const { 12026ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar return "OBJC_METACLASS_$_"; 12036ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar } 12046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12056ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar const char *getClassSymbolPrefix() const { 12066ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar return "OBJC_CLASS_$_"; 12076ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar } 12086ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 12099f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar void GetClassSizeInfo(const ObjCImplementationDecl *OID, 1210b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceStart, 1211b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceSize); 12126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12134523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian // Shamelessly stolen from Analysis/CFRefCount.cpp 121474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar Selector GetNullarySelector(const char* name) const { 12154523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian IdentifierInfo* II = &CGM.getContext().Idents.get(name); 12164523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian return CGM.getContext().Selectors.getSelector(0, &II); 12174523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian } 12186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 121974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar Selector GetUnarySelector(const char* name) const { 12204523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian IdentifierInfo* II = &CGM.getContext().Idents.get(name); 12214523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian return CGM.getContext().Selectors.getSelector(1, &II); 12224523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian } 1223b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar 122474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// ImplementationIsNonLazy - Check whether the given category or 122574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// class implementation is "non-lazy". 1226ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz Jahanian bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 122774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 1228ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 122930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 1230aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // FIXME. All stubs for now! 1231aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Function *ModuleInitFunction(); 12326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1233aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1234ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 1235aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian QualType ResultType, 1236aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian Selector Sel, 1237aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::Value *Receiver, 1238df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 1239c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 1240df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 12416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual CodeGen::RValue 1243aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1244ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 1245aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian QualType ResultType, 1246aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian Selector Sel, 1247aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian const ObjCInterfaceDecl *Class, 12487ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 1249aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::Value *Receiver, 1250aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian bool IsClassMessage, 1251d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 1252d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method); 12536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1254aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value *GetClass(CGBuilderTy &Builder, 12550e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian const ObjCInterfaceDecl *ID); 12566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 125703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 125803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lvalue = false) 125903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian { return EmitSelector(Builder, Sel, lvalue); } 1260df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1261df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1262df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// untyped one. 1263df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1264df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method) 1265df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian { return EmitSelector(Builder, Method->getSelector()); } 12666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1267eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 12686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1269aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1270aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 12718cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian const ObjCProtocolDecl *PD); 12726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1273cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian virtual llvm::Constant *GetEHType(QualType T); 12745a180397870944548aaadeaebf58e415885b9489John McCall 12756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual llvm::Constant *GetPropertyGetFunction() { 127672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getGetPropertyFn(); 1277f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian } 12786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual llvm::Constant *GetPropertySetFunction() { 12796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return ObjCTypes.getSetPropertyFn(); 1280f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian } 12816cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 12828fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetSetStructFunction() { 12838fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall return ObjCTypes.getCopyStructFn(); 12848fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall } 12858fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetGetStructFunction() { 12866cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return ObjCTypes.getCopyStructFn(); 12876cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian } 12886cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 128974391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *EnumerationMutationFunction() { 129072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getEnumerationMutationFn(); 129128ed0847480b76ce76a7e605156608b1cea80e53Daniel Dunbar } 12926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1293f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S); 1295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1296f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S); 1297aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1298f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson const ObjCAtThrowStmt &S); 1299aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 13006948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *AddrWeakObj); 1301aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 13026948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *src, llvm::Value *dst); 1303aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1304021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dest, 1305021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal = false); 1306aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 13076c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dest, 13086c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset); 1309aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 13106948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *src, llvm::Value *dest); 1311082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1312082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Value *dest, llvm::Value *src, 131355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size); 1314598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1315598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 1316598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 1317598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 1318598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers); 1319f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 13202a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 1321f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar); 1322ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 13236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1324cba681af356e24ec4335bcf2b6bb6515072ace99John McCall/// A helper class for performing the null-initialization of a return 1325cba681af356e24ec4335bcf2b6bb6515072ace99John McCall/// value. 1326cba681af356e24ec4335bcf2b6bb6515072ace99John McCallstruct NullReturnState { 1327cba681af356e24ec4335bcf2b6bb6515072ace99John McCall llvm::BasicBlock *NullBB; 1328cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1329cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullReturnState() : NullBB(0) {} 1330cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1331cba681af356e24ec4335bcf2b6bb6515072ace99John McCall void init(CodeGenFunction &CGF, llvm::Value *receiver) { 1332cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Make blocks for the null-init and call edges. 1333cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullBB = CGF.createBasicBlock("msgSend.nullinit"); 1334cba681af356e24ec4335bcf2b6bb6515072ace99John McCall llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call"); 1335cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1336cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Check for a null receiver and, if there is one, jump to the 1337cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // null-init test. 1338cba681af356e24ec4335bcf2b6bb6515072ace99John McCall llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver); 1339cba681af356e24ec4335bcf2b6bb6515072ace99John McCall CGF.Builder.CreateCondBr(isNull, NullBB, callBB); 1340cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1341cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Otherwise, start performing the call. 1342cba681af356e24ec4335bcf2b6bb6515072ace99John McCall CGF.EmitBlock(callBB); 1343cba681af356e24ec4335bcf2b6bb6515072ace99John McCall } 1344cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1345cba681af356e24ec4335bcf2b6bb6515072ace99John McCall RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType) { 1346cba681af356e24ec4335bcf2b6bb6515072ace99John McCall if (!NullBB) return result; 1347cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1348cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Finish the call path. 1349cba681af356e24ec4335bcf2b6bb6515072ace99John McCall llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont"); 1350cba681af356e24ec4335bcf2b6bb6515072ace99John McCall if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB); 1351cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1352cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Emit the null-init block and perform the null-initialization there. 1353cba681af356e24ec4335bcf2b6bb6515072ace99John McCall CGF.EmitBlock(NullBB); 1354cba681af356e24ec4335bcf2b6bb6515072ace99John McCall assert(result.isAggregate() && "null init of non-aggregate result?"); 1355cba681af356e24ec4335bcf2b6bb6515072ace99John McCall CGF.EmitNullInitialization(result.getAggregateAddr(), resultType); 1356cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1357cba681af356e24ec4335bcf2b6bb6515072ace99John McCall // Jump to the continuation block. 1358cba681af356e24ec4335bcf2b6bb6515072ace99John McCall CGF.EmitBlock(contBB); 1359cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1360cba681af356e24ec4335bcf2b6bb6515072ace99John McCall return result; 1361cba681af356e24ec4335bcf2b6bb6515072ace99John McCall } 1362cba681af356e24ec4335bcf2b6bb6515072ace99John McCall}; 1363cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1364c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} // end anonymous namespace 1365bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 1366bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** Helper Functions *** */ 1367bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 1368bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// getConstantGEP() - Help routine to construct simple GEPs. 1369a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonstatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext, 13706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *C, 1371bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned idx0, 1372bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned idx1) { 1373bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar llvm::Value *Idxs[] = { 13740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0), 13750032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1) 1376bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar }; 1377a5c04344fa70d6eec34344760c1fe511e16f2d76Jay Foad return llvm::ConstantExpr::getGetElementPtr(C, Idxs); 1378bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 1379bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 13808158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// hasObjCExceptionAttribute - Return true if this class or any super 13818158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// class has the __objc_exception__ attribute. 13826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstatic bool hasObjCExceptionAttribute(ASTContext &Context, 138368584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor const ObjCInterfaceDecl *OID) { 138440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (OID->hasAttr<ObjCExceptionAttr>()) 13858158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return true; 13868158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 138768584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor return hasObjCExceptionAttribute(Context, Super); 13888158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return false; 13898158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar} 13908158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 1391bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** CGObjCMac Public Interface *** */ 13926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1393ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 13941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCTypes(cgm) { 1395ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCABI = 1; 13966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar EmitImageInfo(); 1397c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1398c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1399ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// GetClass - Return a reference to the class for the given interface 1400ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// decl. 140145d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbarllvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 140227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID) { 140327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return EmitClassRef(Builder, ID); 1404c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1405c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1406c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// GetSelector - Return the pointer to the unique'd string for this selector. 140703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel, 140803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval) { 140903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return EmitSelector(Builder, Sel, lval); 1410c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1411df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 14126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar *Method) { 1413df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian return EmitSelector(Builder, Method->getSelector()); 1414df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian} 1415c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1416cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanianllvm::Constant *CGObjCMac::GetEHType(QualType T) { 14179d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian if (T->isObjCIdType() || 14189d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian T->isObjCQualifiedIdType()) { 14199d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor( 142001a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true); 14219d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian } 1422cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian if (T->isObjCClassType() || 1423cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian T->isObjCQualifiedClassType()) { 1424cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor( 142501a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true); 1426cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian } 1427cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian if (T->isObjCObjectPointerType()) 1428cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true); 1429cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian 14305a180397870944548aaadeaebf58e415885b9489John McCall llvm_unreachable("asking for catch type for ObjC type in fragile runtime"); 14315a180397870944548aaadeaebf58e415885b9489John McCall return 0; 14325a180397870944548aaadeaebf58e415885b9489John McCall} 14335a180397870944548aaadeaebf58e415885b9489John McCall 1434bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// Generate a constant CFString object. 14356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/* 14366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct __builtin_CFString { 14376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const int *isa; // point to __CFConstantStringClassReference 14386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int flags; 14396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *str; 14406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long length; 14416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar }; 1442bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar*/ 1443bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 144433e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/// or Generate a constant NSString object. 144533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/* 144633e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian struct __builtin_NSString { 144733e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian const int *isa; // point to __NSConstantStringClassReference 144833e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian const char *str; 144933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian unsigned int length; 145033e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian }; 145133e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian*/ 145233e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian 1453aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GenerateConstantString( 14540d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall const StringLiteral *SL) { 145533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian return (CGM.getLangOptions().NoConstantCFStrings == 0 ? 145633e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian CGM.GetAddrOfConstantCFString(SL) : 14574c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian CGM.GetAddrOfConstantString(SL)); 1458c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1459c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1460c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// Generates a message send where the super is the receiver. This is 1461c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// a message send to self with special delivery semantics indicating 1462c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// which class's method should be called. 14638f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue 14648f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1465ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 14667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 14677f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1468f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar const ObjCInterfaceDecl *Class, 14697ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 1470f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 147119cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar bool IsClassMessage, 1472d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CodeGen::CallArgList &CallArgs, 1473d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 1474e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar // Create and init a super structure; this is a (receiver, class) 1475e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar // pair we will pass to objc_msgSendSuper. 14766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *ObjCSuper = 1477604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 14786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *ReceiverAsObject = 1479e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 14806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateStore(ReceiverAsObject, 1481e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 1482e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar 1483f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // If this is a class message the metaclass is passed as the target. 1484f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Target; 1485f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar if (IsClassMessage) { 14867ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (isCategoryImpl) { 14877ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // Message sent to 'super' in a class method defined in a category 14887ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // implementation requires an odd treatment. 14897ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // If we are in a class method, we must retrieve the 14907ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // _metaclass_ for the current class, pointed at by 14917ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // the class's "isa" pointer. The following assumes that 14927ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // isa" is the first ivar in a class (which it must be). 14937ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 14947ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateStructGEP(Target, 0); 14957ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateLoad(Target); 1496b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 14977ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 14987ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 14997ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 15007ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = Super; 15016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1502182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian } 1503182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian else if (isCategoryImpl) 1504182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1505182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian else { 1506b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::Value *ClassPtr = EmitSuperClassRef(Class); 1507b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1); 1508b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Target = CGF.Builder.CreateLoad(ClassPtr); 1509f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 1510f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 1511f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ObjCTypes types. 15122acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ClassTy = 151319cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 15140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Target = CGF.Builder.CreateBitCast(Target, ClassTy); 15156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateStore(Target, 1516f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 1517944c84313da15477eb18d90babb0890d10d98082John McCall return EmitMessageSend(CGF, Return, ResultType, 1518944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 1519944c84313da15477eb18d90babb0890d10d98082John McCall ObjCSuper, ObjCTypes.SuperPtrCTy, 1520944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method, ObjCTypes); 1521c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 15226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 15236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// Generate code for a message send expression. 15248f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1525ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 15267f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 15277f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1528f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 1529df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 1530c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 1531df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method) { 1532944c84313da15477eb18d90babb0890d10d98082John McCall return EmitMessageSend(CGF, Return, ResultType, 1533944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 1534944c84313da15477eb18d90babb0890d10d98082John McCall Receiver, CGF.getContext().getObjCIdType(), 1535944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method, ObjCTypes); 153614c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar} 153714c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar 1538d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue 1539944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1540944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 1541944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 1542944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Sel, 1543944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Arg0, 1544944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 1545944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 1546944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 1547944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *Method, 1548944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCCommonTypesHelper &ObjCTypes) { 154919cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar CallArgList ActualArgs; 1550d019d96e1ea39cec32f1320b1f9f772aae28247eFariborz Jahanian if (!IsSuper) 1551578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy); 155204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman ActualArgs.add(RValue::get(Arg0), Arg0Ty); 155304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType()); 1554f85e193739c953358c865005855253af4f68a497John McCall ActualArgs.addFrom(CallArgs); 15556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1556541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar CodeGenTypes &Types = CGM.getTypes(); 155704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, 1558264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FunctionType::ExtInfo()); 15592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 15606793966aa221764f579cc8436bd641e1ec339c6dDaniel Dunbar Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 15616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 15627e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson if (Method) 15637e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson assert(CGM.getContext().getCanonicalType(Method->getResultType()) == 15647e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson CGM.getContext().getCanonicalType(ResultType) && 15657e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson "Result type mismatch!"); 15667e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson 1567cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullReturnState nullReturn; 1568cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1569d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *Fn = NULL; 1570dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar if (CGM.ReturnTypeUsesSRet(FnInfo)) { 1571cba681af356e24ec4335bcf2b6bb6515072ace99John McCall if (!IsSuper) nullReturn.init(CGF, Arg0); 1572d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 15736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ObjCTypes.getSendStretFn(IsSuper); 1574dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { 1575dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper) 1576dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar : ObjCTypes.getSendFpretFn(IsSuper); 15775669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar } else { 1578d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 15796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ObjCTypes.getSendFn(IsSuper); 15805669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar } 1581dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); 1582cba681af356e24ec4335bcf2b6bb6515072ace99John McCall RValue rvalue = CGF.EmitCall(FnInfo, Fn, Return, ActualArgs); 1583cba681af356e24ec4335bcf2b6bb6515072ace99John McCall return nullReturn.complete(CGF, rvalue, ResultType); 1584c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1585c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 158693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { 158793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (FQT.isObjCGCStrong()) 158893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Strong; 158993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 1590f85e193739c953358c865005855253af4f68a497John McCall if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak) 159193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Weak; 159293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 159393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) 159493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Strong; 159593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 159693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (const PointerType *PT = FQT->getAs<PointerType>()) 159793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 159893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 159993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::GCNone; 160093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian} 160193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 16026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, 16036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 16046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *nullPtr = 160544034db24bf59a53aa7699f4bbf59b939710bb3cFariborz Jahanian llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext)); 16066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1607e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() == LangOptions::NonGC && 1608f85e193739c953358c865005855253af4f68a497John McCall !CGM.getLangOptions().ObjCAutoRefCount) 16096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return nullPtr; 16106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1611a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian bool hasUnion = false; 161293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars.clear(); 161393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo.clear(); 1614bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 1615bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 161693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 161781979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian // __isa is the first field in block descriptor and must assume by runtime's 161881979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian // convention that it is GC'able. 161981979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian IvarsInfo.push_back(GC_IVAR(0, 1)); 16206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 16226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Calculate the basic layout of the block structure. 16246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const llvm::StructLayout *layout = 16256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getTargetData().getStructLayout(blockInfo.StructureType); 16266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore the optional 'this' capture: C++ objects are not assumed 16286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to be GC'ed. 16296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Walk the captured variables. 16316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 16326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 16336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 16346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 16356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 16376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore constant captures. 16396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 16406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); 16426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // __block variables are passed by their descriptor address. 16446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 16456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); 1646c5904b40c3d76b612fb09c6d2717f646a0af6670Fariborz Jahanian continue; 16476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 16486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(!type->isArrayType() && "array variable should not be caught"); 16506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (const RecordType *record = type->getAs<RecordType>()) { 16516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion); 1652e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian continue; 1653e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian } 1654a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian 16556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); 16566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned fieldSize = CGM.getContext().getTypeSize(type); 16576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (GCAttr == Qualifiers::Strong) 16596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall IvarsInfo.push_back(GC_IVAR(fieldOffset, 16606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fieldSize / WordSizeInBits)); 166193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) 16626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall SkipIvars.push_back(GC_IVAR(fieldOffset, 16636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fieldSize / ByteSizeInBits)); 166493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian } 166593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 166693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (IvarsInfo.empty()) 16676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return nullPtr; 16686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Sort on byte position; captures might not be allocated in order, 16706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // and unions can do funny things. 16716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 16726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end()); 167393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 167493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian std::string BitMap; 1675b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 167693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (CGM.getLangOptions().ObjCGCBitmapPrint) { 167793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("\n block variable layout for block: "); 167893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian const unsigned char *s = (unsigned char*)BitMap.c_str(); 167993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian for (unsigned i = 0; i < BitMap.size(); i++) 168093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (!(s[i] & 0xf0)) 168193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 168293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian else 168393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 168493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("\n"); 168593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian } 168693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 168793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return C; 168889ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian} 168989ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian 16906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 1691af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar const ObjCProtocolDecl *PD) { 1692c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar // FIXME: I don't understand why gcc generates this, or where it is 1693f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // resolved. Investigate. Its also wasteful to look this up over and over. 1694c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1695c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar 16963c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 16976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar ObjCTypes.ExternalProtocolPtrTy); 16986efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 16996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 1700da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 1701f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need this, the protocol decl should contain enough 1702f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // information to tell us whether this was a declaration or a definition. 17030c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar DefinedProtocols.insert(PD->getIdentifier()); 17040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 17050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // If we have generated a forward reference to this protocol, emit 17060c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // it now. Otherwise do nothing, the protocol objects are lazily 17070c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // emitted. 17086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (Protocols.count(PD->getIdentifier())) 17090c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar GetOrEmitProtocol(PD); 17100c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar} 17110c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 1712da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 17130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar if (DefinedProtocols.count(PD->getIdentifier())) 17140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return GetOrEmitProtocol(PD); 1715f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 17160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return GetOrEmitProtocolRef(PD); 17170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar} 17180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 17196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 17206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 17216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol { 17226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_extension *isa; 17236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarchar *protocol_name; 17246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_list *protocol_list; 17256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *instance_methods; 17266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *class_methods 17276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar}; 17286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 17296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarSee EmitProtocolExtension(). 17306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 17310c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 17320c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 17330c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 17340c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Early exit if a defining object has already been generated. 17350c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar if (Entry && Entry->hasInitializer()) 17360c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return Entry; 17370c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 1738242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // FIXME: I don't understand why gcc generates this, or where it is 1739f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // resolved. Investigate. Its also wasteful to look this up over and over. 1740242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1741242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 1742ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar // Construct method lists. 1743ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1744ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 17456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::instmeth_iterator 174617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 1747ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ObjCMethodDecl *MD = *i; 1748ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *C = GetMethodDescriptionConstant(MD); 1749f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 1750f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 1751f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 1752ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1753ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar OptInstanceMethods.push_back(C); 1754ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 1755ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar InstanceMethods.push_back(C); 17566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1757ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 1758ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar 17596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::classmeth_iterator 176017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 1761ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ObjCMethodDecl *MD = *i; 1762ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *C = GetMethodDescriptionConstant(MD); 1763f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 1764f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 1765f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 1766ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1767ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar OptClassMethods.push_back(C); 1768ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 1769ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ClassMethods.push_back(C); 17706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1771ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 1772ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar 17731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 17741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods), 17751d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(PD->getIdentifier()), 17769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(), 1777dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar PD->protocol_begin(), 17781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer PD->protocol_end()), 17799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(), 1780ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 17811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer InstanceMethods), 17829c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(), 1783ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 17841d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ClassMethods) 17851d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 178608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 17876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Values); 17886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 17896efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (Entry) { 17900c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Already created, fix the linkage and update the initializer. 17910c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 17926efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setInitializer(Init); 17936efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } else { 17946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 17951c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 17966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalValue::InternalLinkage, 17976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 17989c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01L_OBJC_PROTOCOL_" + PD->getName()); 17996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 18006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // FIXME: Is this necessary? Why only for protocol? 18016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setAlignment(4); 18026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } 1803ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 18040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 18050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return Entry; 18066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 18076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 18096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 18106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (!Entry) { 18120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // We use the initializer as a marker of whether this is a forward 18130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // reference or not. At module finalization we add the empty 18140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // contents for protocols which were referenced but never defined. 18156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 18161c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 18170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 18180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 0, 18199c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01L_OBJC_PROTOCOL_" + PD->getName()); 18206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 18216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // FIXME: Is this necessary? Why only for protocol? 18226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setAlignment(4); 18236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } 18246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 18256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar return Entry; 18266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 18276efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 18296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct _objc_protocol_extension { 18306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; 18316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description_list *optional_instance_methods; 18326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description_list *optional_class_methods; 18336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_property_list *instance_properties; 18346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 18356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 1836ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant * 1837ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 1838ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &OptInstanceMethods, 1839ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &OptClassMethods) { 18406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint64_t Size = 18419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 18421d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 18431d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.IntTy, Size), 18446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 18459c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 1846ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 18471d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer OptInstanceMethods), 18489c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(), 1849ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 18501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer OptClassMethods), 18511d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD, 18521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes) 18531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 18546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 185527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null if no extension bits are used. 18566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (Values[1]->isNullValue() && Values[2]->isNullValue() && 18576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Values[3]->isNullValue()) 1858c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 18596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 186108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 18626efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 186363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar // No special section, but goes in llvm.used 18649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(), 18656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 186663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar 0, 0, true); 18676efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 18686efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18696efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 18706efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct objc_protocol_list { 18716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_protocol_list *next; 18726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long count; 18736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Protocol *list[]; 18746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 18756efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 1876dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbarllvm::Constant * 18775f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCMac::EmitProtocolList(Twine Name, 1878dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 1879dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator end) { 18806efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar std::vector<llvm::Constant*> ProtocolRefs; 18816efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 1882dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar for (; begin != end; ++begin) 1883dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ProtocolRefs.push_back(GetProtocolRef(*begin)); 18846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 18856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Just return null for empty protocol lists 18866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (ProtocolRefs.empty()) 1887c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 18886efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 188927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // This list is null terminated. 1890c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 18916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 1892c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 189327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // This field is only used by the runtime. 1894c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 18954a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, 18966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs.size() - 1); 18976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = 18986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 18996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs.size()), 19006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar ProtocolRefs); 19016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1902c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 19036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 190463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 190558a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, false); 19063c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 1907c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1908c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1909191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanianvoid CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 1910191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian std::vector<llvm::Constant*> &Properties, 1911191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const Decl *Container, 1912191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const ObjCProtocolDecl *PROTO, 1913191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes) { 1914191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), 1915191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian E = PROTO->protocol_end(); P != E; ++P) 1916191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 1917191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), 1918191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian E = PROTO->prop_end(); I != E; ++I) { 1919191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian const ObjCPropertyDecl *PD = *I; 1920191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian if (!PropertySet.insert(PD->getIdentifier())) 1921191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian continue; 19221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Prop[] = { 19231d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyName(PD->getIdentifier()), 19241d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyTypeString(PD, Container) 19251d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 1926191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); 1927191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian } 1928191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian} 1929191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian 19306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 1931c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar struct _objc_property { 19326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char * const name; 19336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char * const attributes; 1934c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar }; 1935c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 1936c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar struct _objc_property_list { 19376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t entsize; // sizeof (struct _objc_property) 19386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t prop_count; 19396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_property[prop_count]; 1940c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar }; 1941c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar*/ 19425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, 19436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container, 19446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCContainerDecl *OCD, 19456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCommonTypesHelper &ObjCTypes) { 19461d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer std::vector<llvm::Constant*> Properties; 1947191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 19486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 19496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar E = OCD->prop_end(); I != E; ++I) { 195093983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff const ObjCPropertyDecl *PD = *I; 1951191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian PropertySet.insert(PD->getIdentifier()); 19521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Prop[] = { 19531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyName(PD->getIdentifier()), 19541d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyTypeString(PD, Container) 19551d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 195608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 1957c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar Prop)); 1958c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar } 19596afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) { 196053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek for (ObjCInterfaceDecl::all_protocol_iterator 196153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek P = OID->all_referenced_protocol_begin(), 196253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek E = OID->all_referenced_protocol_end(); P != E; ++P) 19636afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), 19646afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian ObjCTypes); 19656afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian } 19666afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) { 19676afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(), 19686afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian E = CD->protocol_end(); P != E; ++P) 19696afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), 19706afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian ObjCTypes); 19716afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian } 1972c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 1973c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar // Return null for empty list. 1974c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar if (Properties.empty()) 1975c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1976c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 19776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned PropertySize = 19789408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 1979c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 19804a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 19814a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 19826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 1983c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar Properties.size()); 19847db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Properties); 1985c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 1986c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 19876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 19886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CreateMetadataVar(Name, Init, 19896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (ObjCABI == 2) ? "__DATA, __objc_const" : 19900bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__property,regular,no_dead_strip", 19916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (ObjCABI == 2) ? 8 : 4, 19920bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar true); 19933c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 1994c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 1995c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 1996c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar/* 19976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct objc_method_description_list { 19986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int count; 19996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description list[]; 20006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 20016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 2002ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant * 2003ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 20041d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Desc[] = { 20056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 20061d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 20071d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD) 20081d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 2009f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!Desc[1]) 2010f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 2011f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 201208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 2013ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Desc); 2014ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar} 20156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodDescList(Twine Name, 2017ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const char *Section, 2018ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods) { 20196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Return null for empty list. 20206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (Methods.empty()) 2021c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 20226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 2023c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 20244a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 20256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 20266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Methods.size()); 20277db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[1] = llvm::ConstantArray::get(AT, Methods); 2028c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 20296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20300bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 20316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, 20326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar ObjCTypes.MethodDescriptionListPtrTy); 2033c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2034c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 203586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar/* 203686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar struct _objc_category { 20376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *category_name; 20386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *class_name; 20396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *instance_methods; 20406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *class_methods; 20416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_protocol_list *protocols; 20426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; // <rdar://4585769> 20436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_property_list *instance_properties; 204486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar }; 20456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 20467ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbarvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 20479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 204886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 2049f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This is poor design, the OCD should have a pointer to the category 2050f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // decl. Additionally, note that Category can be null for the @implementation 2051f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // w/o an @interface case. Sema should just create one for us as it does for 2052f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // @implementation so everyone else can live life under a clear blue sky. 205386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 20546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCategoryDecl *Category = 205586e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar Interface->FindCategoryDeclaration(OCD->getIdentifier()); 20569c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar 20579c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::SmallString<256> ExtName; 20589c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' 20599c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar << OCD->getName(); 206086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 2061c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 20626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::instmeth_iterator 206317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 2064c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Instance methods should always be defined. 2065c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(GetMethodConstant(*i)); 2066c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 20676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::classmeth_iterator 206817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 2069c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Class methods should always be defined. 2070c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods.push_back(GetMethodConstant(*i)); 2071c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2072c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2073c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[7]; 207486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values[0] = GetClassName(OCD->getIdentifier()); 207586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values[1] = GetClassName(Interface->getIdentifier()); 2076679cd7fcbd341fa3747e598f537601db421b1002Fariborz Jahanian LazySymbols.insert(Interface->getIdentifier()); 20776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = 20789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(), 2079c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 2080c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods); 20816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[3] = 20829c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(), 20830bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 2084c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods); 2085ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (Category) { 20866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = 20879c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(), 2088ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Category->protocol_begin(), 2089ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Category->protocol_end()); 2090ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 2091c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 2092ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 20934a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 209486e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar 209586e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar // If there is no category @interface then there can be no properties. 209686e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar if (Category) { 20979c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 20985de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian OCD, Category, ObjCTypes); 209986e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar } else { 2100c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 210186e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar } 21026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 210308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 210486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values); 210586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 21066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 21079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init, 210863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__category,regular,no_dead_strip", 210958a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 211086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar DefinedCategories.push_back(GV); 2111b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian DefinedCategoryNames.insert(ExtName.str()); 211264089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 211364089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 2114c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2115c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 211627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Get from somewhere? 211727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarenum ClassFlags { 211827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Factory = 0x00001, 211927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Meta = 0x00002, 212027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // <rdr://5142207> 212127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_HasCXXStructors = 0x02000, 212227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Hidden = 0x20000, 212327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_ABI2_Hidden = 0x00010, 212427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 212527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}; 212627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 212727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 212827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct _objc_class { 21296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Class isa; 21306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Class super_class; 21316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *name; 21326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long version; 21336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long info; 21346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long instance_size; 21356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_ivar_list *ivars; 21366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *methods; 21376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_cache *cache; 21386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_protocol_list *protocols; 21396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // Objective-C 1.0 extensions (<rdr://4585769>) 21406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *ivar_layout; 21416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_class_ext *ext; 214227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 214327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 214427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar See EmitClassExtension(); 21456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 214627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 2147242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar DefinedSymbols.insert(ID->getIdentifier()); 2148242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 21498ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner std::string ClassName = ID->getNameAsString(); 215027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // FIXME: Gross 21516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCInterfaceDecl *Interface = 215227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 21536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Protocols = 21549c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(), 215553b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek Interface->all_referenced_protocol_begin(), 215653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek Interface->all_referenced_protocol_end()); 215727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned Flags = eClassFlags_Factory; 2158f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 2159109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian Flags |= eClassFlags_HasCXXStructors; 21606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned Size = 21615f022d82696c84e4d127c558871d68ac6273274eKen Dyck CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity(); 216227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 216327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // FIXME: Set CXX-structors flag. 21641fb0caaa7bef765b85972274e3b434af2572c141John McCall if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 216527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Flags |= eClassFlags_Hidden; 216627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2167c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 21686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::instmeth_iterator 216917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 2170c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Instance methods should always be defined. 2171c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(GetMethodConstant(*i)); 2172c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 21736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::classmeth_iterator 217417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 2175c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Class methods should always be defined. 2176c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods.push_back(GetMethodConstant(*i)); 2177c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2178c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 21796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::propimpl_iterator 218017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 2181c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ObjCPropertyImplDecl *PID = *i; 2182c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2183c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 2184c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ObjCPropertyDecl *PD = PID->getPropertyDecl(); 2185c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2186c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 2187c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (llvm::Constant *C = GetMethodConstant(MD)) 2188c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(C); 2189c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 2190c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (llvm::Constant *C = GetMethodConstant(MD)) 2191c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(C); 2192c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2193c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2194c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2195c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[12]; 21965384b0990ea6995121fd4bad0855e96d41dcad18Daniel Dunbar Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 219727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 2198242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Record a reference to the super class. 2199242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar LazySymbols.insert(Super->getIdentifier()); 2200242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 22016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 1] = 22023c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 220327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 220427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } else { 2205c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 220627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 220727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 2] = GetClassName(ID->getIdentifier()); 220827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Version is always 0. 22094a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 22104a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 22114a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 221246b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian Values[ 6] = EmitIvarList(ID, false); 22136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 7] = 22149c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(), 2215c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar "__OBJC,__inst_meth,regular,no_dead_strip", 2216c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods); 221727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // cache is always NULL. 2218c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 221927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 9] = Protocols; 22206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[10] = BuildIvarLayout(ID, true); 222127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[11] = EmitClassExtension(ID); 222208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 222327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values); 2224b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian std::string Name("\01L_OBJC_CLASS_"); 2225b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Name += ClassName; 2226b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian const char *Section = "__OBJC,__class,regular,no_dead_strip"; 2227b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian // Check for a forward reference. 2228b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2229b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian if (GV) { 2230b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2231b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian "Forward metaclass reference has incorrect type."); 2232b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2233b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setInitializer(Init); 2234b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setSection(Section); 2235b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setAlignment(4); 2236b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian CGM.AddUsedGlobal(GV); 2237b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } 2238b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian else 2239b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV = CreateMetadataVar(Name, Init, Section, 4, true); 224027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar DefinedClasses.push_back(GV); 224164089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 224264089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 224327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 224427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 224527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 224627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *Protocols, 2247ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods) { 224827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned Flags = eClassFlags_Meta; 22499408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 225027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 22511fb0caaa7bef765b85972274e3b434af2572c141John McCall if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 225227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Flags |= eClassFlags_Hidden; 22536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2254c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[12]; 225527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // The isa for the metaclass is the root of the hierarchy. 225627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *Root = ID->getClassInterface(); 225727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 225827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Root = Super; 22596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 0] = 22603c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 226127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 226286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // The super class for the metaclass is emitted as the name of the 226386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // super class. The runtime fixes this up to point to the 226486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // *metaclass* for the super class. 226527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 22666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 1] = 22673c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 226827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 226927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } else { 2270c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 227127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 227227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 2] = GetClassName(ID->getIdentifier()); 227327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Version is always 0. 22744a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 22754a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 22764a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 227746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian Values[ 6] = EmitIvarList(ID, true); 22786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 7] = 2279d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 22800bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__cls_meth,regular,no_dead_strip", 2281c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar Methods); 228227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // cache is always NULL. 2283c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 228427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 9] = Protocols; 228527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // ivar_layout for metaclass is always NULL. 2286c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 228727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // The class extension is always unused for metaclasses. 2288c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 228908e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 229027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values); 229127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2292f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar std::string Name("\01L_OBJC_METACLASS_"); 22938ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner Name += ID->getNameAsCString(); 2294f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2295f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Check for a forward reference. 2296f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2297f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar if (GV) { 2298f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2299f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar "Forward metaclass reference has incorrect type."); 2300f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2301f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar GV->setInitializer(Init); 2302f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 23031c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2304f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalValue::InternalLinkage, 23051c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Init, Name); 2306f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 230727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 230858a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar GV->setAlignment(4); 2309ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 231027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 231127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return GV; 231227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 231327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 23146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 2315d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 2316f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2317f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: Should we look these up somewhere other than the module. Its a bit 2318f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // silly since we only generate these while processing an implementation, so 2319f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // exactly one pointer would work if know when we entered/exitted an 2320f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // implementation block. 2321f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2322f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Check for an existing forward reference. 2323b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian // Previously, metaclass with internal linkage may have been defined. 2324b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian // pass 'true' as 2nd argument so it is returned. 23256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 23266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar true)) { 2327f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2328f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar "Forward metaclass reference has incorrect type."); 2329f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar return GV; 2330f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 2331f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Generate as an external reference to keep a consistent 2332f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // module. This will be patched up when we emit the metaclass. 23331c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2334f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalValue::ExternalLinkage, 2335b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 0, 2336b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Name); 2337b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } 2338b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian} 2339b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 2340b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanianllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { 2341b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString(); 2342b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 2343b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2344b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian true)) { 2345b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2346b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian "Forward class metadata reference has incorrect type."); 2347b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian return GV; 2348b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } else { 2349b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2350b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::GlobalValue::ExternalLinkage, 2351f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 0, 23521c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Name); 2353f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 2354f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar} 2355f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 235627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 235727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_class_ext { 23586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; 23596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *weak_ivar_layout; 23606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_property_list *properties; 236127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 236227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/ 236327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant * 236427f9d77b61b377b21ccda536122f2be6fa715751Daniel DunbarCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 23656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint64_t Size = 23669408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 236727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2368c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 23694a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2370c71303de3e295d19c3617b6738da009f6e679337Fariborz Jahanian Values[1] = BuildIvarLayout(ID, false); 23719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 23725de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian ID, ID->getClassInterface(), ObjCTypes); 237327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 237427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null if no extension bits are used. 237527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Values[1]->isNullValue() && Values[2]->isNullValue()) 2376c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 237727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 23786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 237908e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 23809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(), 23816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, "__OBJC,__class_ext,regular,no_dead_strip", 23820bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 238327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 238427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 238527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 238627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_ivar { 23876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *ivar_name; 23886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *ivar_type; 23896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int ivar_offset; 239027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 239127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 239227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_ivar_list { 23936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int ivar_count; 23946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_ivar list[count]; 239527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 23966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 239727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 239846b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian bool ForClass) { 23991d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer std::vector<llvm::Constant*> Ivars; 240027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 240127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // When emitting the root class GCC emits ivar entries for the 240227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // actual class structure. It is not clear if we need to follow this 240327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // behavior; for now lets try and get away with not doing it. If so, 240427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // the cleanest solution would be to make up an ObjCInterfaceDecl 240527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // for the class. 240627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ForClass) 2407c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 24086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2409db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OID = ID->getClassInterface(); 24106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2411db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 2412bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) { 24138e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian // Ignore unnamed bit-fields. 24148e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian if (!IVD->getDeclName()) 24156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar continue; 24161d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Ivar[] = { 24171d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarName(IVD->getIdentifier()), 24181d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(IVD), 24191d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.IntTy, 24201d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ComputeIvarBaseOffset(CGM, OID, IVD)) 24211d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 242208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 242327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 242427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 242527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null for empty list. 242627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Ivars.empty()) 2427c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 242827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2429c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 24304a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 243196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 243227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Ivars.size()); 24337db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[1] = llvm::ConstantArray::get(AT, Ivars); 2434c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 243527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 243663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar llvm::GlobalVariable *GV; 243763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (ForClass) 24389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(), 24396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, "__OBJC,__class_vars,regular,no_dead_strip", 244058a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 244163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar else 24429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(), 244363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Init, "__OBJC,__instance_vars,regular,no_dead_strip", 24440bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 24453c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 244627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 244727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 244827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 244927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_method { 24506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SEL method_name; 24516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *method_types; 24526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar void *method; 245327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 24546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 245527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_method_list { 24566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_list *obsolete; 24576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int count; 24586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method methods_list[count]; 245927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 246027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/ 246127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2462c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// GetMethodConstant - Return a struct objc_method constant for the 2463c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// given method if it has been defined. The result is null if the 2464c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// method has not been defined. The return value has type MethodPtrTy. 2465ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 24669d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *Fn = GetMethodDefinition(MD); 2467c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (!Fn) 2468c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar return 0; 24696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 24701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Method[] = { 24713c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 24721d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 24731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD), 24741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 24751d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 247608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 2477c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar} 247827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 24795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodList(Twine Name, 2480c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar const char *Section, 2481ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const ConstantVector &Methods) { 248227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null for empty list. 248327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Methods.empty()) 2484c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 248527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2486c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 2487c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 24884a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 248996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 249027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Methods.size()); 24917db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Methods); 2492c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 249327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 24940bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2495c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy); 2496b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar} 2497b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2498493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 24996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCContainerDecl *CD) { 2500c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar llvm::SmallString<256> Name; 2501679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian GetNameForMethod(OMD, CD, Name); 2502b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2503541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar CodeGenTypes &Types = CGM.getTypes(); 25042acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *MethodTy = 2505541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 25066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Function *Method = 250745c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar llvm::Function::Create(MethodTy, 2508b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar llvm::GlobalValue::InternalLinkage, 2509c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar Name.str(), 2510b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar &CGM.getModule()); 2511c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar MethodDefinitions.insert(std::make_pair(OMD, Method)); 2512b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2513b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar return Method; 2514c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2515c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 2516fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbarllvm::GlobalVariable * 25175f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCCommonMac::CreateMetadataVar(Twine Name, 2518fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar llvm::Constant *Init, 2519fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar const char *Section, 252035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar unsigned Align, 252135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar bool AddToUsed) { 25222acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = Init->getType(); 25236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 25241c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Ty, false, 2525ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner llvm::GlobalValue::InternalLinkage, Init, Name); 2526fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar if (Section) 2527fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar GV->setSection(Section); 252835bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar if (Align) 252935bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar GV->setAlignment(Align); 253035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar if (AddToUsed) 2531ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 2532fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar return GV; 2533fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar} 2534fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar 25356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCMac::ModuleInitFunction() { 2536f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar // Abuse this interface function as a place to finalize. 2537f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar FinishModule(); 2538c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar return NULL; 2539c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2540c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 254174391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertyGetFunction() { 254272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getGetPropertyFn(); 254349f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar} 254449f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar 254574391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertySetFunction() { 254672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getSetPropertyFn(); 254749f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar} 254849f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar 25498fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetGetStructFunction() { 25508fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall return ObjCTypes.getCopyStructFn(); 25518fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall} 25528fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetSetStructFunction() { 25536cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return ObjCTypes.getCopyStructFn(); 25546cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian} 25556cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 255674391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::EnumerationMutationFunction() { 255772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getEnumerationMutationFn(); 25582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson} 25592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 2560f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) { 2561f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return EmitTryOrSynchronizedStmt(CGF, S); 2562f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 2563f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2564f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF, 2565f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S) { 2566f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return EmitTryOrSynchronizedStmt(CGF, S); 2567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 2568f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2569cc5052999cd064584492ba15a808b6e1cee6d931John McCallnamespace { 25701f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct PerformFragileFinally : EHScopeStack::Cleanup { 2571cc5052999cd064584492ba15a808b6e1cee6d931John McCall const Stmt &S; 25720b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot; 2573cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *CallTryExitVar; 2574cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *ExceptionData; 2575cc5052999cd064584492ba15a808b6e1cee6d931John McCall ObjCTypesHelper &ObjCTypes; 2576cc5052999cd064584492ba15a808b6e1cee6d931John McCall PerformFragileFinally(const Stmt *S, 25770b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot, 2578cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *CallTryExitVar, 2579cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *ExceptionData, 2580cc5052999cd064584492ba15a808b6e1cee6d931John McCall ObjCTypesHelper *ObjCTypes) 25810b2517299415ab1c28b9cb87d536ccea84317a10John McCall : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar), 2582cc5052999cd064584492ba15a808b6e1cee6d931John McCall ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {} 2583cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2584ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 2585cc5052999cd064584492ba15a808b6e1cee6d931John McCall // Check whether we need to call objc_exception_try_exit. 2586cc5052999cd064584492ba15a808b6e1cee6d931John McCall // In optimized code, this branch will always be folded. 2587cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::BasicBlock *FinallyCallExit = 2588cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.createBasicBlock("finally.call_exit"); 2589cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::BasicBlock *FinallyNoCallExit = 2590cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.createBasicBlock("finally.no_call_exit"); 2591cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar), 2592cc5052999cd064584492ba15a808b6e1cee6d931John McCall FinallyCallExit, FinallyNoCallExit); 2593cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2594cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitBlock(FinallyCallExit); 2595cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData) 2596cc5052999cd064584492ba15a808b6e1cee6d931John McCall ->setDoesNotThrow(); 2597cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2598cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitBlock(FinallyNoCallExit); 2599cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2600cc5052999cd064584492ba15a808b6e1cee6d931John McCall if (isa<ObjCAtTryStmt>(S)) { 2601cc5052999cd064584492ba15a808b6e1cee6d931John McCall if (const ObjCAtFinallyStmt* FinallyStmt = 2602d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall cast<ObjCAtTryStmt>(S).getFinallyStmt()) { 2603d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Save the current cleanup destination in case there's 2604d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // control flow inside the finally statement. 2605d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall llvm::Value *CurCleanupDest = 2606d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot()); 2607d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall 2608cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitStmt(FinallyStmt->getFinallyBody()); 2609cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2610d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall if (CGF.HaveInsertPoint()) { 2611d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateStore(CurCleanupDest, 2612d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.getNormalCleanupDestSlot()); 2613d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } else { 2614d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Currently, the end of the cleanup must always exist. 2615d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.EnsureInsertPoint(); 2616d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } 2617d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } 2618cc5052999cd064584492ba15a808b6e1cee6d931John McCall } else { 2619cc5052999cd064584492ba15a808b6e1cee6d931John McCall // Emit objc_sync_exit(expr); as finally's sole statement for 2620cc5052999cd064584492ba15a808b6e1cee6d931John McCall // @synchronized. 26210b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot); 2622cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg) 2623cc5052999cd064584492ba15a808b6e1cee6d931John McCall ->setDoesNotThrow(); 2624cc5052999cd064584492ba15a808b6e1cee6d931John McCall } 2625cc5052999cd064584492ba15a808b6e1cee6d931John McCall } 2626cc5052999cd064584492ba15a808b6e1cee6d931John McCall }; 262787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 262887bb5822bfa4baea23a3d9273df266777f3ab796John McCall class FragileHazards { 262987bb5822bfa4baea23a3d9273df266777f3ab796John McCall CodeGenFunction &CGF; 26305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Value*, 20> Locals; 263187bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry; 263287bb5822bfa4baea23a3d9273df266777f3ab796John McCall 263387bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::InlineAsm *ReadHazard; 263487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::InlineAsm *WriteHazard; 263587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 263687bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::FunctionType *GetAsmFnType(); 263787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 263887bb5822bfa4baea23a3d9273df266777f3ab796John McCall void collectLocals(); 263987bb5822bfa4baea23a3d9273df266777f3ab796John McCall void emitReadHazard(CGBuilderTy &Builder); 264087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 264187bb5822bfa4baea23a3d9273df266777f3ab796John McCall public: 264287bb5822bfa4baea23a3d9273df266777f3ab796John McCall FragileHazards(CodeGenFunction &CGF); 26430b2517299415ab1c28b9cb87d536ccea84317a10John McCall 264487bb5822bfa4baea23a3d9273df266777f3ab796John McCall void emitWriteHazard(); 26450b2517299415ab1c28b9cb87d536ccea84317a10John McCall void emitHazardsInNewBlocks(); 264687bb5822bfa4baea23a3d9273df266777f3ab796John McCall }; 264787bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 264887bb5822bfa4baea23a3d9273df266777f3ab796John McCall 264987bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Create the fragile-ABI read and write hazards based on the current 265087bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// state of the function, which is presumed to be immediately prior 265187bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// to a @try block. These hazards are used to maintain correct 265287bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// semantics in the face of optimization and the fragile ABI's 265387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// cavalier use of setjmp/longjmp. 265487bb5822bfa4baea23a3d9273df266777f3ab796John McCallFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { 265587bb5822bfa4baea23a3d9273df266777f3ab796John McCall collectLocals(); 265687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 265787bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 265887bb5822bfa4baea23a3d9273df266777f3ab796John McCall 265987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Collect all the blocks in the function. 266087bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::Function::iterator 266187bb5822bfa4baea23a3d9273df266777f3ab796John McCall I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I) 266287bb5822bfa4baea23a3d9273df266777f3ab796John McCall BlocksBeforeTry.insert(&*I); 266387bb5822bfa4baea23a3d9273df266777f3ab796John McCall 266487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::FunctionType *AsmFnTy = GetAsmFnType(); 266587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 266687bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create a read hazard for the allocas. This inhibits dead-store 266787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // optimizations and forces the values to memory. This hazard is 266887bb5822bfa4baea23a3d9273df266777f3ab796John McCall // inserted before any 'throwing' calls in the protected scope to 266987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // reflect the possibility that the variables might be read from the 267087bb5822bfa4baea23a3d9273df266777f3ab796John McCall // catch block if the call throws. 267187bb5822bfa4baea23a3d9273df266777f3ab796John McCall { 267287bb5822bfa4baea23a3d9273df266777f3ab796John McCall std::string Constraint; 267387bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 267487bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (I) Constraint += ','; 267587bb5822bfa4baea23a3d9273df266777f3ab796John McCall Constraint += "*m"; 267687bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 267787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 267887bb5822bfa4baea23a3d9273df266777f3ab796John McCall ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 267987bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 268087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 268187bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create a write hazard for the allocas. This inhibits folding 268287bb5822bfa4baea23a3d9273df266777f3ab796John McCall // loads across the hazard. This hazard is inserted at the 268387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // beginning of the catch path to reflect the possibility that the 268487bb5822bfa4baea23a3d9273df266777f3ab796John McCall // variables might have been written within the protected scope. 268587bb5822bfa4baea23a3d9273df266777f3ab796John McCall { 268687bb5822bfa4baea23a3d9273df266777f3ab796John McCall std::string Constraint; 268787bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 268887bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (I) Constraint += ','; 268987bb5822bfa4baea23a3d9273df266777f3ab796John McCall Constraint += "=*m"; 269087bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 269187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 269287bb5822bfa4baea23a3d9273df266777f3ab796John McCall WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 269387bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 269487bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 269587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 269687bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit a write hazard at the current location. 269787bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitWriteHazard() { 269887bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 269987bb5822bfa4baea23a3d9273df266777f3ab796John McCall 27004c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow(); 270187bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 270287bb5822bfa4baea23a3d9273df266777f3ab796John McCall 270387bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) { 270487bb5822bfa4baea23a3d9273df266777f3ab796John McCall assert(!Locals.empty()); 27054c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow(); 270687bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 270787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 270887bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit read hazards in all the protected blocks, i.e. all the blocks 270987bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// which have been inserted since the beginning of the try. 27100b2517299415ab1c28b9cb87d536ccea84317a10John McCallvoid FragileHazards::emitHazardsInNewBlocks() { 271187bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 271287bb5822bfa4baea23a3d9273df266777f3ab796John McCall 271387bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGBuilderTy Builder(CGF.getLLVMContext()); 271487bb5822bfa4baea23a3d9273df266777f3ab796John McCall 271587bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Iterate through all blocks, skipping those prior to the try. 271687bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::Function::iterator 271787bb5822bfa4baea23a3d9273df266777f3ab796John McCall FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) { 271887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::BasicBlock &BB = *FI; 271987bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (BlocksBeforeTry.count(&BB)) continue; 272087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 272187bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Walk through all the calls in the block. 272287bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::BasicBlock::iterator 272387bb5822bfa4baea23a3d9273df266777f3ab796John McCall BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) { 272487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::Instruction &I = *BI; 272587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 272687bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Ignore instructions that aren't non-intrinsic calls. 272787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // These are the only calls that can possibly call longjmp. 272887bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue; 272987bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (isa<llvm::IntrinsicInst>(I)) 273087bb5822bfa4baea23a3d9273df266777f3ab796John McCall continue; 273187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 273287bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Ignore call sites marked nounwind. This may be questionable, 273387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // since 'nounwind' doesn't necessarily mean 'does not call longjmp'. 273487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::CallSite CS(&I); 273587bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (CS.doesNotThrow()) continue; 273687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 27370b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Insert a read hazard before the call. This will ensure that 27380b2517299415ab1c28b9cb87d536ccea84317a10John McCall // any writes to the locals are performed before making the 27390b2517299415ab1c28b9cb87d536ccea84317a10John McCall // call. If the call throws, then this is sufficient to 27400b2517299415ab1c28b9cb87d536ccea84317a10John McCall // guarantee correctness as long as it doesn't also write to any 27410b2517299415ab1c28b9cb87d536ccea84317a10John McCall // locals. 274287bb5822bfa4baea23a3d9273df266777f3ab796John McCall Builder.SetInsertPoint(&BB, BI); 274387bb5822bfa4baea23a3d9273df266777f3ab796John McCall emitReadHazard(Builder); 274487bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 274587bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 274687bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 274787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 274887bb5822bfa4baea23a3d9273df266777f3ab796John McCallstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) { 274987bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (V) S.insert(V); 275087bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 275187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 275287bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::collectLocals() { 275387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Compute a set of allocas to ignore. 275487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::DenseSet<llvm::Value*> AllocasToIgnore; 275587bb5822bfa4baea23a3d9273df266777f3ab796John McCall addIfPresent(AllocasToIgnore, CGF.ReturnValue); 275687bb5822bfa4baea23a3d9273df266777f3ab796John McCall addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest); 275787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 275887bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Collect all the allocas currently in the function. This is 275987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // probably way too aggressive. 276087bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock(); 276187bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::BasicBlock::iterator 276287bb5822bfa4baea23a3d9273df266777f3ab796John McCall I = Entry.begin(), E = Entry.end(); I != E; ++I) 276387bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I)) 276487bb5822bfa4baea23a3d9273df266777f3ab796John McCall Locals.push_back(&*I); 276587bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 276687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 276787bb5822bfa4baea23a3d9273df266777f3ab796John McCallllvm::FunctionType *FragileHazards::GetAsmFnType() { 27685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type *, 16> tys(Locals.size()); 27690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall for (unsigned i = 0, e = Locals.size(); i != e; ++i) 27700774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall tys[i] = Locals[i]->getType(); 27710774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return llvm::FunctionType::get(CGF.VoidTy, tys, false); 2772cc5052999cd064584492ba15a808b6e1cee6d931John McCall} 2773cc5052999cd064584492ba15a808b6e1cee6d931John McCall 27746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/* 277518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 27766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Objective-C setjmp-longjmp (sjlj) Exception Handling 27776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar -- 277818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 2779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall A catch buffer is a setjmp buffer plus: 2780f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - a pointer to the exception that was caught 2781f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - a pointer to the previous exception data buffer 2782f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - two pointers of reserved storage 2783f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Therefore catch buffers form a stack, with a pointer to the top 2784f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall of the stack kept in thread-local storage. 2785f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2786f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_try_enter pushes a catch buffer onto the EH stack. 2787f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_try_exit pops the given catch buffer, which is 2788f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall required to be the top of the EH stack. 2789f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_throw pops the top of the EH stack, writes the 2790f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall thrown exception into the appropriate field, and longjmps 2791f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall to the setjmp buffer. It crashes the process (with a printf 2792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall and an abort()) if there are no catch buffers on the stack. 2793f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_extract just reads the exception pointer out of the 2794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall catch buffer. 2795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall There's no reason an implementation couldn't use a light-weight 2797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall setjmp here --- something like __builtin_setjmp, but API-compatible 2798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall with the heavyweight setjmp. This will be more important if we ever 2799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall want to implement correct ObjC/C++ exception interactions for the 2800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall fragile ABI. 2801f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2802f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Note that for this use of setjmp/longjmp to be correct, we may need 2803f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall to mark some local variables volatile: if a non-volatile local 2804f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall variable is modified between the setjmp and the longjmp, it has 2805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall indeterminate value. For the purposes of LLVM IR, it may be 2806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall sufficient to make loads and stores within the @try (to variables 2807f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall declared outside the @try) volatile. This is necessary for 2808f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall optimized correctness, but is not currently being done; this is 2809f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall being tracked as rdar://problem/8160285 2810f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 28116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar The basic framework for a @try-catch-finally is as follows: 28126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar { 281318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar objc_exception_data d; 281418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar id _rethrow = null; 2815190d00e1396214c77539c7095756b9ea38160463Anders Carlsson bool _call_try_exit = true; 28166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 281718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar objc_exception_try_enter(&d); 281818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar if (!setjmp(d.jmp_buf)) { 28196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... try body ... 282018ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar } else { 28216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // exception path 28226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar id _caught = objc_exception_extract(&d); 28236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // enter new try scope for handlers 28256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (!setjmp(d.jmp_buf)) { 28266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... match exception and execute catch blocks ... 28276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // fell off end, rethrow. 28296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _rethrow = _caught; 28306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... jump-through-finally to finally_rethrow ... 28316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } else { 28326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // exception in catch block 28336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _rethrow = objc_exception_extract(&d); 28346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _call_try_exit = false; 28356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... jump-through-finally to finally_rethrow ... 28366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 283718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar } 2838898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar ... jump-through-finally to finally_end ... 283918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 28406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally: 2841190d00e1396214c77539c7095756b9ea38160463Anders Carlsson if (_call_try_exit) 28426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar objc_exception_try_exit(&d); 2843190d00e1396214c77539c7095756b9ea38160463Anders Carlsson 284418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar ... finally block .... 2845898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar ... dispatch to finally destination ... 2846898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 28476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally_rethrow: 2848898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar objc_exception_throw(_rethrow); 2849898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 28506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally_end: 28516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 28526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar This framework differs slightly from the one gcc uses, in that gcc 28546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uses _rethrow to determine if objc_exception_try_exit should be called 28556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar and if the object should be rethrown. This breaks in the face of 28566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar throwing nil and introduces unnecessary branches. 28576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar We specialize this framework for a few particular circumstances: 28596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - If there are no catch blocks, then we avoid emitting the second 28616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar exception handling context. 28626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 28646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar e)) we avoid emitting the code to rethrow an uncaught exception. 286518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 28666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - FIXME: If there is no @finally block we can do a few more 28676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar simplifications. 28686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 28696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Rethrows and Jumps-Through-Finally 28706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar -- 28716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2872f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall '@throw;' is supported by pushing the currently-caught exception 2873f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall onto ObjCEHStack while the @catch blocks are emitted. 2874f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2875f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Branches through the @finally block are handled with an ordinary 2876f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC 2877f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall exceptions are not compatible with C++ exceptions, and this is 2878f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall hardly the only place where this will go wrong. 2879f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2880f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall @synchronized(expr) { stmt; } is emitted as if it were: 2881f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall id synch_value = expr; 2882f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_sync_enter(synch_value); 2883f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall @try { stmt; } @finally { objc_sync_exit(synch_value); } 288418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar*/ 288518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 2886bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanianvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 2887bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian const Stmt &S) { 2888bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian bool isTry = isa<ObjCAtTryStmt>(S); 2889f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2890f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // A destination for the fall-through edges of the catch handlers to 2891f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // jump to. 2892f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::JumpDest FinallyEnd = 2893f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.getJumpDestInCurrentScope("finally.end"); 2894f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2895f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // A destination for the rethrow edge of the catch handlers to jump 2896f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // to. 2897f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::JumpDest FinallyRethrow = 2898f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.getJumpDestInCurrentScope("finally.rethrow"); 28996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 29001c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar // For @synchronized, call objc_sync_enter(sync.expr). The 29011c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar // evaluation of the expression must occur before we enter the 29020b2517299415ab1c28b9cb87d536ccea84317a10John McCall // @synchronized. We can't avoid a temp here because we need the 29030b2517299415ab1c28b9cb87d536ccea84317a10John McCall // value to be preserved. If the backend ever does liveness 29040b2517299415ab1c28b9cb87d536ccea84317a10John McCall // correctly after setjmp, this will be unnecessary. 29050b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot = 0; 29061c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar if (!isTry) { 29070b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArg = 29081c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 29091c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 2910f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg) 2911f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 29120b2517299415ab1c28b9cb87d536ccea84317a10John McCall 29130b2517299415ab1c28b9cb87d536ccea84317a10John McCall SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg"); 29140b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(SyncArg, SyncArgSlot); 29151c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar } 2916898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 29170b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Allocate memory for the setjmp buffer. This needs to be kept 29180b2517299415ab1c28b9cb87d536ccea84317a10John McCall // live throughout the try and catch blocks. 29190b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 29200b2517299415ab1c28b9cb87d536ccea84317a10John McCall "exceptiondata.ptr"); 29210b2517299415ab1c28b9cb87d536ccea84317a10John McCall 292287bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create the fragile hazards. Note that this will not capture any 292387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // of the allocas required for exception processing, but will 292487bb5822bfa4baea23a3d9273df266777f3ab796John McCall // capture the current basic block (which extends all the way to the 292587bb5822bfa4baea23a3d9273df266777f3ab796John McCall // setjmp call) as "before the @try". 292687bb5822bfa4baea23a3d9273df266777f3ab796John McCall FragileHazards Hazards(CGF); 292787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 2928f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create a flag indicating whether the cleanup needs to call 2929f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // objc_exception_try_exit. This is true except when 2930f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - no catches match and we're branching through the cleanup 2931f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // just to rethrow the exception, or 2932f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - a catch matched and we're falling out of the catch handler. 29330b2517299415ab1c28b9cb87d536ccea84317a10John McCall // The setjmp-safety rule here is that we should always store to this 29340b2517299415ab1c28b9cb87d536ccea84317a10John McCall // variable in a place that dominates the branch through the cleanup 29350b2517299415ab1c28b9cb87d536ccea84317a10John McCall // without passing through any setjmps. 2936f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), 2937190d00e1396214c77539c7095756b9ea38160463Anders Carlsson "_call_try_exit"); 2938f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 29399e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // A slot containing the exception to rethrow. Only needed when we 29409e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // have both a @catch and a @finally. 29419e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::Value *PropagatingExnVar = 0; 29429e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 2943f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Push a normal cleanup to leave the try scope. 29441f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S, 29450b2517299415ab1c28b9cb87d536ccea84317a10John McCall SyncArgSlot, 29461f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CallTryExitVar, 29471f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall ExceptionData, 29481f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall &ObjCTypes); 29496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2950f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Enter a try block: 2951f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - Call objc_exception_try_enter to push ExceptionData on top of 2952f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the EH stack. 2953f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 2954f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 2955898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 2956f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - Call setjmp on the exception data buffer. 2957f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); 2958f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; 2959f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *SetJmpBuffer = 29600f6ac7cf7bc6a02c1a5c19d2c90ec0d1dd7786e7Jay Foad CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer"); 2961f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *SetJmpResult = 2962f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); 2963f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall SetJmpResult->setDoesNotThrow(); 2964f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2965f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If setjmp returned 0, enter the protected block; otherwise, 2966f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // branch to the handler. 296755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 296855e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 2969f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *DidCatch = 2970d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 2971d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock); 297280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 2973f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the protected block. 297480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(TryBlock); 29750b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 29766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 2977f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 29780b2517299415ab1c28b9cb87d536ccea84317a10John McCall 29790b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP(); 29806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2981f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the exception handler block. 2982e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar CGF.EmitBlock(TryHandler); 298355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar 298487bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Don't optimize loads of the in-scope locals across this point. 298587bb5822bfa4baea23a3d9273df266777f3ab796John McCall Hazards.emitWriteHazard(); 298687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 2987f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // For a @synchronized (or a @try with no catches), just branch 2988f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // through the cleanup to the rethrow block. 2989f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) { 2990f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Tell the cleanup not to re-pop the exit. 29910b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 2992f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyRethrow); 2993f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2994f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, we have to match against the caught exceptions. 2995f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 29960b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Retrieve the exception object. We may emit multiple blocks but 29970b2517299415ab1c28b9cb87d536ccea84317a10John McCall // nothing can cross this so the value is already in SSA form. 29980b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::CallInst *Caught = 29990b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 30000b2517299415ab1c28b9cb87d536ccea84317a10John McCall ExceptionData, "caught"); 30010b2517299415ab1c28b9cb87d536ccea84317a10John McCall Caught->setDoesNotThrow(); 30020b2517299415ab1c28b9cb87d536ccea84317a10John McCall 3003f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Push the exception to rethrow onto the EH value stack for the 3004f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // benefit of any @throws in the handlers. 3005f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.ObjCEHValueStack.push_back(Caught); 3006f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 30078f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S); 3008f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 30090b2517299415ab1c28b9cb87d536ccea84317a10John McCall bool HasFinally = (AtTryStmt->getFinallyStmt() != 0); 30100b2517299415ab1c28b9cb87d536ccea84317a10John McCall 30110b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::BasicBlock *CatchBlock = 0; 30120b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::BasicBlock *CatchHandler = 0; 30130b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (HasFinally) { 30149e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Save the currently-propagating exception before 30159e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // objc_exception_try_enter clears the exception slot. 30169e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(), 30179e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall "propagating_exception"); 30189e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateStore(Caught, PropagatingExnVar); 30199e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 30200b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Enter a new exception try block (in case a @catch block 30210b2517299415ab1c28b9cb87d536ccea84317a10John McCall // throws an exception). 30220b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 30230b2517299415ab1c28b9cb87d536ccea84317a10John McCall ->setDoesNotThrow(); 30240b2517299415ab1c28b9cb87d536ccea84317a10John McCall 30250b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::CallInst *SetJmpResult = 30260b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, 30270b2517299415ab1c28b9cb87d536ccea84317a10John McCall "setjmp.result"); 30280b2517299415ab1c28b9cb87d536ccea84317a10John McCall SetJmpResult->setDoesNotThrow(); 30290b2517299415ab1c28b9cb87d536ccea84317a10John McCall 30300b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *Threw = 30310b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 30326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30330b2517299415ab1c28b9cb87d536ccea84317a10John McCall CatchBlock = CGF.createBasicBlock("catch"); 30340b2517299415ab1c28b9cb87d536ccea84317a10John McCall CatchHandler = CGF.createBasicBlock("catch_for_catch"); 30350b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 303680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 30370b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(CatchBlock); 30380b2517299415ab1c28b9cb87d536ccea84317a10John McCall } 30396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30400b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar); 30416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 304255e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // Handle catch list. As a special case we check if everything is 304355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // matched and avoid generating code for falling off the end if 304455e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // so. 304555e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar bool AllMatched = false; 30468f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) { 30478f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I); 304880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 3049c00d8e18ad3d903acfeb5d05163ce90713066a3fDouglas Gregor const VarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 305014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff const ObjCObjectPointerType *OPT = 0; 3051129271a42975f8b9d42adc707be9883db91c8a5dDaniel Dunbar 305280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // catch(...) always matches. 305355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar if (!CatchParam) { 305455e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar AllMatched = true; 305555e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar } else { 3056183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>(); 30576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3058f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // catch(id e) always matches under this ABI, since only 3059f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ObjC exceptions end up here in the first place. 306097f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar // FIXME: For the time being we also match id<X>; this should 306197f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar // be rejected by Sema instead. 3062818e96f5a42b2a9adea4ac0050340469b49d70efEli Friedman if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())) 306355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar AllMatched = true; 306480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 30656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3066f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If this is a catch-all, we don't need to test anything. 30676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (AllMatched) { 3068f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3069f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3070dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson if (CatchParam) { 3071b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall CGF.EmitAutoVarDecl(*CatchParam); 3072a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 3073f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3074f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // These types work out because ConvertType(id) == i8*. 30757ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 3076dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson } 30776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3078dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson CGF.EmitStmt(CatchStmt->getCatchBody()); 3079f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3080f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The scope of the catch variable ends right here. 3081f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchVarCleanups.ForceCleanup(); 3082f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3083f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyEnd); 308480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson break; 308580f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 30866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 308714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff assert(OPT && "Unexpected non-object pointer type in @catch"); 3088506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall const ObjCObjectType *ObjTy = OPT->getObjectType(); 3089f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3090f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // FIXME: @catch (Class c) ? 3091506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *IDecl = ObjTy->getInterface(); 3092506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall assert(IDecl && "Catch parameter must have Objective-C type!"); 309380f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 309480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // Check if the @catch block matches the exception object. 3095506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl); 30966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3097f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Match = 309834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 309934b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner Class, Caught, "match"); 3100f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Match->setDoesNotThrow(); 31016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3102f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match"); 3103f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next"); 31046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 31056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 3106e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar MatchedBlock, NextCatchBlock); 31076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 310880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // Emit the @catch block. 310980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(MatchedBlock); 3110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Collect any cleanups for the catch variable. The scope lasts until 3112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the end of the catch body. 31130b2517299415ab1c28b9cb87d536ccea84317a10John McCall CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3114f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3115b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall CGF.EmitAutoVarDecl(*CatchParam); 3116a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 311718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 3118f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Initialize the catch variable. 31196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *Tmp = 31206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateBitCast(Caught, 3121578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer CGF.ConvertType(CatchParam->getType())); 31227ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 31236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3124dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson CGF.EmitStmt(CatchStmt->getCatchBody()); 3125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We're done with the catch variable. 3127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchVarCleanups.ForceCleanup(); 3128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3129f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyEnd); 31306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 313180f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(NextCatchBlock); 313280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 313380f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 3134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.ObjCEHValueStack.pop_back(); 3135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 31360b2517299415ab1c28b9cb87d536ccea84317a10John McCall // If nothing wanted anything to do with the caught exception, 31370b2517299415ab1c28b9cb87d536ccea84317a10John McCall // kill the extract call. 31380b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (Caught->use_empty()) 31390b2517299415ab1c28b9cb87d536ccea84317a10John McCall Caught->eraseFromParent(); 31400b2517299415ab1c28b9cb87d536ccea84317a10John McCall 31410b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (!AllMatched) 3142f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyRethrow); 31436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 31440b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (HasFinally) { 31450b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Emit the exception handler for the @catch blocks. 31460b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(CatchHandler); 3147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 31480b2517299415ab1c28b9cb87d536ccea84317a10John McCall // In theory we might now need a write hazard, but actually it's 31490b2517299415ab1c28b9cb87d536ccea84317a10John McCall // unnecessary because there's no local-accessing code between 31500b2517299415ab1c28b9cb87d536ccea84317a10John McCall // the try's write hazard and here. 31510b2517299415ab1c28b9cb87d536ccea84317a10John McCall //Hazards.emitWriteHazard(); 3152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 31539e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Extract the new exception and save it to the 31549e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // propagating-exception slot. 31559e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall assert(PropagatingExnVar); 31569e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::CallInst *NewCaught = 31579e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 31589e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall ExceptionData, "caught"); 31599e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall NewCaught->setDoesNotThrow(); 31609e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateStore(NewCaught, PropagatingExnVar); 31619e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 31620b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Don't pop the catch handler; the throw already did. 31630b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 31640b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBranchThroughCleanup(FinallyRethrow); 31650b2517299415ab1c28b9cb87d536ccea84317a10John McCall } 316680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 31676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 316887bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Insert read hazards as required in the new blocks. 31690b2517299415ab1c28b9cb87d536ccea84317a10John McCall Hazards.emitHazardsInNewBlocks(); 317087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 3171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Pop the cleanup. 31720b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.restoreIP(TryFallthroughIP); 31730b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (CGF.HaveInsertPoint()) 31740b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 3175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.PopCleanupBlock(); 31760b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(FinallyEnd.getBlock(), true); 31776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the rethrow block. 317987bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 3180ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall CGF.EmitBlock(FinallyRethrow.getBlock(), true); 3181f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (CGF.HaveInsertPoint()) { 31829e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // If we have a propagating-exception variable, check it. 31839e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::Value *PropagatingExn; 31849e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall if (PropagatingExnVar) { 31859e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar); 31869e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 31879e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Otherwise, just look in the buffer for the exception to throw. 31889e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall } else { 31899e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::CallInst *Caught = 31909e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 31919e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall ExceptionData); 31929e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall Caught->setDoesNotThrow(); 31939e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExn = Caught; 31949e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall } 31950b2517299415ab1c28b9cb87d536ccea84317a10John McCall 31969e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn) 3197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 3198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateUnreachable(); 3199f2878e5dffd20bf0a97fb0b30a376f2d60963593Fariborz Jahanian } 320080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 320187bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGF.Builder.restoreIP(SavedIP); 320264d5d6c5903157c521af496479d06dc26032d718Anders Carlsson} 320364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson 320464d5d6c5903157c521af496479d06dc26032d718Anders Carlssonvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 3205898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar const ObjCAtThrowStmt &S) { 32062b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson llvm::Value *ExceptionAsObject; 32076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 32082b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson if (const Expr *ThrowExpr = S.getThrowExpr()) { 32092b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 32106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ExceptionAsObject = 3211578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 32122b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson } else { 32136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 321418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar "Unexpected rethrow outside @catch block."); 3215273558fbd891a0872e620e0d3d109b92c1160d72Anders Carlsson ExceptionAsObject = CGF.ObjCEHValueStack.back(); 32162b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson } 32176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3218f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject) 3219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotReturn(); 322080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.Builder.CreateUnreachable(); 3221a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 3222a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 3223a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar CGF.Builder.ClearInsertionPoint(); 322464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson} 322564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson 32263e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak 32276dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// object: objc_read_weak (id *src) 32286dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// 32293e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 32301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *AddrWeakObj) { 32312acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type* DestTy = 32326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 32336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, 32346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.PtrObjectPtrTy); 323572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 32363e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian AddrWeakObj, "weakread"); 32378339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 32386dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian return read_weak; 32396dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian} 32406dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian 32413e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 32423e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// objc_assign_weak (id src, id *dst) 32433e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// 32443e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 32451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 32462acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 32470a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 32489408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 32490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 32500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 32516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 32523b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 32533b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3254dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3255dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 325696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 32573e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian src, dst, "weakassign"); 32583e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian return; 32593e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian} 32603e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian 326158626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 326258626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_global (id src, id *dst) 326358626500527695865683d1d65053743de8770b60Fariborz Jahanian/// 326458626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 3265021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dst, 3266021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal) { 32672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 32680a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 32699408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 32700a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 32710a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 32726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 32733b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 32743b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3275dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3276dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3277021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian if (!threadlocal) 3278021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 3279021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "globalassign"); 3280021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian else 3281021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 3282021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "threadlocalassign"); 328358626500527695865683d1d65053743de8770b60Fariborz Jahanian return; 328458626500527695865683d1d65053743de8770b60Fariborz Jahanian} 328558626500527695865683d1d65053743de8770b60Fariborz Jahanian 32867eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 32876c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) 32887eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// 32897eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanianvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 32906c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dst, 32916c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset) { 32926c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); 32932acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 32940a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 32959408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 32960a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 32970a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 32986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 32993b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 33003b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 33017eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 33027eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 33036c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 33046c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian src, dst, ivarOffset); 33057eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian return; 33067eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian} 33077eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian 330858626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 330958626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst) 331058626500527695865683d1d65053743de8770b60Fariborz Jahanian/// 331158626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 33121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 33132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 33140a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 33159408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 33160a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 33170a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 33186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 33193b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 33203b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3321dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3322dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3323bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 332458626500527695865683d1d65053743de8770b60Fariborz Jahanian src, dst, "weakassign"); 332558626500527695865683d1d65053743de8770b60Fariborz Jahanian return; 332658626500527695865683d1d65053743de8770b60Fariborz Jahanian} 332758626500527695865683d1d65053743de8770b60Fariborz Jahanian 3328082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 33296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *DestPtr, 33306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *SrcPtr, 333155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size) { 3332082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 3333082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 3334082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 333555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian DestPtr, SrcPtr, size); 3336082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return; 3337082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian} 3338082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian 33390bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// EmitObjCValueForIvar - Code Gen for ivar reference. 33400bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// 3341598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 3342598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 3343598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 3344598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 3345598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers) { 3346c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall const ObjCInterfaceDecl *ID = 3347c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall ObjectTy->getAs<ObjCObjectType>()->getInterface(); 33489777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 33499777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar EmitIvarOffset(CGF, ID, Ivar)); 33500bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian} 33510bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian 3352f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 33532a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 3354f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar) { 33559777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 33564a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson return llvm::ConstantInt::get( 33576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getTypes().ConvertType(CGM.getContext().LongTy), 33586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Offset); 3359f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian} 3360f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian 3361f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** Private Interface *** */ 3362f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 3363f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// EmitImageInfo - Emit the image info marker used to encode some module 3364f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// level information. 3365f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// 3366f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// See: <rdr://4810609&4810587&4810587> 3367f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// struct IMAGE_INFO { 3368f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// unsigned version; 3369f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// unsigned flags; 3370f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// }; 3371f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarenum ImageInfoFlags { 3372fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar eImageInfo_FixAndContinue = (1 << 0), 33736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar eImageInfo_GarbageCollected = (1 << 1), 33746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar eImageInfo_GCOnly = (1 << 2), 3375c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 3376c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar 3377fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar // A flag indicating that the module has no instances of a @synthesize of a 3378fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar // superclass variable. <rdar://problem/6803242> 3379c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar eImageInfo_CorrectedSynthesize = (1 << 4) 3380f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}; 3381f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 3382fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbarvoid CGObjCCommonMac::EmitImageInfo() { 3383f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar unsigned version = 0; // Version is unused? 3384f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar unsigned flags = 0; 3385f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 3386f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar // FIXME: Fix and continue? 3387e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() != LangOptions::NonGC) 3388f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar flags |= eImageInfo_GarbageCollected; 3389e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) 3390f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar flags |= eImageInfo_GCOnly; 33916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3392c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar // We never allow @synthesize of a superclass property. 3393c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar flags |= eImageInfo_CorrectedSynthesize; 3394f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 33952acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext); 339677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner 3397f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar // Emitted as int[2]; 3398f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar llvm::Constant *values[2] = { 339977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, version), 340077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, flags) 3401f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar }; 340277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2); 3403f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 340463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar const char *Section; 340563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (ObjCABI == 1) 340663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Section = "__OBJC, __image_info,regular"; 340763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar else 340863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Section = "__DATA, __objc_imageinfo, regular, no_dead_strip"; 34096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 341063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar("\01L_OBJC_IMAGE_INFO", 341197357602a289749d59520ac4ac31149f8d32e12eJay Foad llvm::ConstantArray::get(AT, values), 341263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Section, 341363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar 0, 341463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar true); 341563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar GV->setConstant(true); 3416f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar} 3417f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 34184e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 34194e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// struct objc_module { 34204e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// unsigned long version; 34214e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// unsigned long size; 34224e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// const char *name; 34234e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// Symtab symtab; 34244e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// }; 34254e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 34264e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// FIXME: Get from somewhere 34274e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarstatic const int ModuleVersion = 7; 34284e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 34294e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarvoid CGObjCMac::EmitModuleInfo() { 34309408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 34316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 34321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 34331d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion), 34341d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.LongTy, Size), 34351d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer // This used to be the filename, now it is unused. <rdr://4327263> 34361d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(&CGM.getContext().Idents.get("")), 34371d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer EmitModuleSymbols() 34381d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 34396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CreateMetadataVar("\01L_OBJC_MODULES", 344008e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 344163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__module_info,regular,no_dead_strip", 344258a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 34434e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 34444e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 34454e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarllvm::Constant *CGObjCMac::EmitModuleSymbols() { 344627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned NumClasses = DefinedClasses.size(); 344727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned NumCategories = DefinedCategories.size(); 344827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3449242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Return null if no symbols were defined. 3450242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar if (!NumClasses && !NumCategories) 3451c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 3452242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 3453c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[5]; 34544a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 3455c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 34564a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 34574a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 345827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 345986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // The runtime expects exactly the list of defined classes followed 346086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // by the list of defined categories, in a single array. 346127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 346286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar for (unsigned i=0; i<NumClasses; i++) 34633c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 346486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar ObjCTypes.Int8PtrTy); 346586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar for (unsigned i=0; i<NumCategories; i++) 34666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Symbols[NumClasses + i] = 34673c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(DefinedCategories[i], 346886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar ObjCTypes.Int8PtrTy); 346986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 34706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = 347196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 347227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar NumClasses + NumCategories), 347327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Symbols); 347427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3475c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 347627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 34774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar llvm::GlobalVariable *GV = 347863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 347963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__symbols,regular,no_dead_strip", 34800bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 34813c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 348227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 348327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3484f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder, 3485f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II) { 3486f85e193739c953358c865005855253af4f68a497John McCall LazySymbols.insert(II); 3487f85e193739c953358c865005855253af4f68a497John McCall 3488f85e193739c953358c865005855253af4f68a497John McCall llvm::GlobalVariable *&Entry = ClassReferences[II]; 3489f85e193739c953358c865005855253af4f68a497John McCall 349027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (!Entry) { 34916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 3492f85e193739c953358c865005855253af4f68a497John McCall llvm::ConstantExpr::getBitCast(GetClassName(II), 3493f85e193739c953358c865005855253af4f68a497John McCall ObjCTypes.ClassPtrTy); 34946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 3495f85e193739c953358c865005855253af4f68a497John McCall CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 3496f85e193739c953358c865005855253af4f68a497John McCall "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 3497f85e193739c953358c865005855253af4f68a497John McCall 4, true); 349827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 3499f85e193739c953358c865005855253af4f68a497John McCall 3500578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 35014e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 35024e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 3503f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 3504f85e193739c953358c865005855253af4f68a497John McCall const ObjCInterfaceDecl *ID) { 3505f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, ID->getIdentifier()); 3506f85e193739c953358c865005855253af4f68a497John McCall} 3507f85e193739c953358c865005855253af4f68a497John McCall 3508f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) { 3509f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 3510f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, II); 3511f85e193739c953358c865005855253af4f68a497John McCall} 3512f85e193739c953358c865005855253af4f68a497John McCall 351303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel, 351403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lvalue) { 3515259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 35166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3517259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar if (!Entry) { 35186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 35193c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 3520259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar ObjCTypes.SelectorPtrTy); 35216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 352263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 352363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__message_refs,literal_pointers,no_dead_strip", 35240bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 3525259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar } 3526259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 352703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian if (lvalue) 352803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return Entry; 3529578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 3530259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar} 3531259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 3532058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 35336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalVariable *&Entry = ClassNames[Ident]; 35344e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 353563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 35366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 35379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::ConstantArray::get(VMContext, 35389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Ident->getNameStart()), 3539af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3540af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_classname,cstring_literals" : 3541af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 3542b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 35434e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 3544a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 35454e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 35464e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 35479d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidisllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 35489d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 35499d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis I = MethodDefinitions.find(MD); 35509d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis if (I != MethodDefinitions.end()) 35519d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis return I->second; 35529d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 35539d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis return NULL; 35549d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis} 35559d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 3556d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// GetIvarLayoutName - Returns a unique constant for the given 3557d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// ivar layout bitmap. 3558d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 35596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCommonTypesHelper &ObjCTypes) { 3560c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3561d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian} 3562d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian 3563d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 35646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, 3565d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar bool ForStrongLayout, 3566d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar bool &HasUnion) { 3567d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar const RecordDecl *RD = RT->getDecl(); 3568d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar // FIXME - Use iterator. 3569db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end()); 35702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 35716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const llvm::StructLayout *RecLayout = 3572d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 35736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3574d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 3575d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 3576d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar} 3577d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar 35785a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 35796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const llvm::StructLayout *Layout, 35806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const RecordDecl *RD, 3581db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const SmallVectorImpl<const FieldDecl*> &RecFields, 35826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, bool ForStrongLayout, 35836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool &HasUnion) { 3584820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian bool IsUnion = (RD && RD->isUnion()); 3585820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t MaxUnionIvarSize = 0; 3586820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t MaxSkippedUnionIvarSize = 0; 3587db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *MaxField = 0; 3588db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *MaxSkippedField = 0; 3589db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *LastFieldBitfieldOrUnnamed = 0; 3590900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar uint64_t MaxFieldOffset = 0; 3591900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar uint64_t MaxSkippedFieldOffset = 0; 35920dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis uint64_t LastBitfieldOrUnnamedOffset = 0; 3593f85e193739c953358c865005855253af4f68a497John McCall uint64_t FirstFieldDelta = 0; 35946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3595a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian if (RecFields.empty()) 3596a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian return; 3597bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 3598bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 3599f85e193739c953358c865005855253af4f68a497John McCall if (!RD && CGM.getLangOptions().ObjCAutoRefCount) { 3600db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *FirstField = RecFields[0]; 3601f85e193739c953358c865005855253af4f68a497John McCall FirstFieldDelta = 3602f85e193739c953358c865005855253af4f68a497John McCall ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField)); 3603f85e193739c953358c865005855253af4f68a497John McCall } 3604f85e193739c953358c865005855253af4f68a497John McCall 3605f1690858344968358131f8d5690d9ee458883000Chris Lattner for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 3606db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *Field = RecFields[i]; 3607e05cc98e97ec910829beccd0d890a002ce5ab909Daniel Dunbar uint64_t FieldOffset; 3608fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson if (RD) { 3609f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar // Note that 'i' here is actually the field index inside RD of Field, 3610f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar // although this dependency is hidden. 3611f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); 3612f85e193739c953358c865005855253af4f68a497John McCall FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta; 3613fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson } else 3614f85e193739c953358c865005855253af4f68a497John McCall FieldOffset = 3615f85e193739c953358c865005855253af4f68a497John McCall ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta; 361625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar 3617a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian // Skip over unnamed or bitfields 36187fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian if (!Field->getIdentifier() || Field->isBitField()) { 36190dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastFieldBitfieldOrUnnamed = Field; 36200dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastBitfieldOrUnnamedOffset = FieldOffset; 3621a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian continue; 36227fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian } 362325d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar 36240dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastFieldBitfieldOrUnnamed = 0; 3625a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian QualType FQT = Field->getType(); 3626667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian if (FQT->isRecordType() || FQT->isUnionType()) { 3627a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian if (FQT->isUnionType()) 3628a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian HasUnion = true; 3629820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian 36306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), 363125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar BytePos + FieldOffset, 3632d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 3633a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian continue; 3634a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian } 36356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3636f1690858344968358131f8d5690d9ee458883000Chris Lattner if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 36376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ConstantArrayType *CArray = 36385e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar dyn_cast_or_null<ConstantArrayType>(Array); 36397fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian uint64_t ElCount = CArray->getSize().getZExtValue(); 36405e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar assert(CArray && "only array with known element size is supported"); 3641820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian FQT = CArray->getElementType(); 3642667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3643667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian const ConstantArrayType *CArray = 36445e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar dyn_cast_or_null<ConstantArrayType>(Array); 36457fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian ElCount *= CArray->getSize().getZExtValue(); 3646667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian FQT = CArray->getElementType(); 3647667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian } 36486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 36496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert(!FQT->isUnionType() && 3650820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian "layout for array of unions not supported"); 3651f96bdf409fc9e5570e35aaf8a9167265e63d58d8Fariborz Jahanian if (FQT->isRecordType() && ElCount) { 365281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int OldIndex = IvarsInfo.size() - 1; 365381adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int OldSkIndex = SkipIvars.size() -1; 36546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 36556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = FQT->getAs<RecordType>(); 365625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 3657d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 36586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3659820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // Replicate layout information for each array element. Note that 3660820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // one element is already done. 3661820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t ElIx = 1; 36626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (int FirstIndex = IvarsInfo.size() - 1, 36636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 3664c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 36658b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar for (int i = OldIndex+1; i <= FirstIndex; ++i) 36668b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 36678b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar IvarsInfo[i].ivar_size)); 36688b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 36698b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 36708b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar SkipIvars[i].ivar_size)); 3671820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3672820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian continue; 3673820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3674a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian } 3675820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // At this point, we are done with Record/Union and array there of. 3676820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // For other arrays we are down to its element type. 36770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 36785e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar 36798b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 36800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 36810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 3682487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (IsUnion) { 36838b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 3684487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (UnionIvarSize > MaxUnionIvarSize) { 3685820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxUnionIvarSize = UnionIvarSize; 3686820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxField = Field; 3687900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar MaxFieldOffset = FieldOffset; 3688820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3689487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar } else { 369025d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 36918b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar FieldSize / WordSizeInBits)); 3692820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 36936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } else if ((ForStrongLayout && 36940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) 36950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { 3696487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (IsUnion) { 3697f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: Why the asymmetry? We divide by word size in bits on other 3698f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // side. 36998b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar uint64_t UnionIvarSize = FieldSize; 3700487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (UnionIvarSize > MaxSkippedUnionIvarSize) { 3701820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxSkippedUnionIvarSize = UnionIvarSize; 3702820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxSkippedField = Field; 3703900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar MaxSkippedFieldOffset = FieldOffset; 3704820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3705487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar } else { 37068b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar // FIXME: Why the asymmetry, we divide by byte size in bits here? 370725d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 37088b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar FieldSize / ByteSizeInBits)); 3709820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3710820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3711820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3712d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar 37130dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis if (LastFieldBitfieldOrUnnamed) { 37140dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis if (LastFieldBitfieldOrUnnamed->isBitField()) { 37150dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis // Last field was a bitfield. Must update skip info. 3716a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith uint64_t BitFieldSize 3717a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); 37180dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis GC_IVAR skivar; 37190dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; 37200dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 37210dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis + ((BitFieldSize % ByteSizeInBits) != 0); 37220dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis SkipIvars.push_back(skivar); 37230dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis } else { 37240dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); 37250dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis // Last field was unnamed. Must update skip info. 37260dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis unsigned FieldSize 37270dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); 37280dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, 37290dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis FieldSize / ByteSizeInBits)); 37300dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis } 37317fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian } 37326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 37338b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar if (MaxField) 37346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 37358b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar MaxUnionIvarSize)); 37368b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar if (MaxSkippedField) 3737900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 37388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar MaxSkippedUnionIvarSize)); 3739d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian} 3740d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian 3741b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// BuildIvarLayoutBitmap - This routine is the horsework for doing all 3742b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the computations and returning the layout bitmap (for ivar or blocks) in 3743b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the given argument BitMap string container. Routine reads 3744b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// two containers, IvarsInfo and SkipIvars which are assumed to be 3745b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// filled already by the caller. 3746b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) { 37479397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int WordsToScan, WordsToSkip; 37482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 374993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 37509397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Build the string of skip/scan nibbles 37515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<SKIP_SCAN, 32> SkipScanIvars; 37526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int WordSize = 375393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 37549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if (IvarsInfo[0].ivar_bytepos == 0) { 37559397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = 0; 37569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[0].ivar_size; 375731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else { 37589397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 37599397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[0].ivar_size; 37609397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 376131682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 37626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int TailPrevGCObjC = 376393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 376431682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 37659397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // consecutive 'scanned' object pointers. 37669397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan += IvarsInfo[i].ivar_size; 376731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else { 37689397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Skip over 'gc'able object pointer which lay over each other. 37699397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 37709397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian continue; 37719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Must skip over 1 or more words. We save current skip/scan values 37729397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // and start a new pair. 3773c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 3774c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = WordsToSkip; 3775c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = WordsToScan; 377681adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 377793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 37789397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Skip the hole. 3779c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 3780c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = 0; 378181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 37829397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = 0; 37839397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[i].ivar_size; 37849397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 37859397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 378631682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (WordsToScan > 0) { 3787c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 3788c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = WordsToSkip; 3789c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = WordsToScan; 379081adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 37919397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 379293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 379331682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (!SkipIvars.empty()) { 379481adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian unsigned int LastIndex = SkipIvars.size()-1; 37956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int LastByteSkipped = 379693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 379781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian LastIndex = IvarsInfo.size()-1; 37986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int LastByteScanned = 379993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[LastIndex].ivar_bytepos + 380093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[LastIndex].ivar_size * WordSize; 38019397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Compute number of bytes to skip at the tail end of the last ivar scanned. 380254d76db0aa7107597cac0b80d8e138a37e6d1de9Benjamin Kramer if (LastByteSkipped > LastByteScanned) { 38039397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 3804c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 3805c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = TotalWords - (LastByteScanned/WordSize); 3806c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = 0; 380781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 38089397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 38119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // as 0xMN. 381281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int SkipScan = SkipScanIvars.size()-1; 381331682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (int i = 0; i <= SkipScan; i++) { 38149397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 38159397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 38169397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // 0xM0 followed by 0x0N detected. 38179397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 38189397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (int j = i+1; j < SkipScan; j++) 38199397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian SkipScanIvars[j] = SkipScanIvars[j+1]; 38209397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian --SkipScan; 38219397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38229397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 382393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 38249397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Generate the string. 382531682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (int i = 0; i <= SkipScan; i++) { 38269397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned char byte; 38279397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 38289397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 38299397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 38309397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 383193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 38329397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // first skip big. 38339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (unsigned int ix = 0; ix < skip_big; ix++) 38349397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += (unsigned char)(0xf0); 383593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 38369397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // next (skip small, scan) 383731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (skip_small) { 38389397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte = skip_small << 4; 383931682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (scan_big > 0) { 38409397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte |= 0xf; 38419397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian --scan_big; 384231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else if (scan_small) { 38439397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte |= scan_small; 38449397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian scan_small = 0; 38459397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38469397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += byte; 38479397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38489397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // next scan big 38499397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (unsigned int ix = 0; ix < scan_big; ix++) 38509397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += (unsigned char)(0x0f); 38519397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // last scan small 385231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (scan_small) { 38539397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte = scan_small; 38549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += byte; 38559397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 38579397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // null terminate string. 3858667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian unsigned char zero = 0; 3859667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian BitMap += zero; 386093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 386193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian llvm::GlobalVariable * Entry = 386293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 386393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian llvm::ConstantArray::get(VMContext, BitMap.c_str()), 3864af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3865af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_classname,cstring_literals" : 3866af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 386793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 1, true); 386893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return getConstantGEP(VMContext, Entry, 0, 0); 386993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian} 38706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 387193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// BuildIvarLayout - Builds ivar layout bitmap for the class 387293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// implementation for the __strong or __weak case. 387393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// The layout map displays which words in ivar list must be skipped 387493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// and which must be scanned by GC (see below). String is built of bytes. 387593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 387693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// of words to skip and right nibble is count of words to scan. So, each 387793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// nibble represents up to 15 workds to skip or scan. Skipping the rest is 387893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// represented by a 0x00 byte which also ends the string. 387993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 1. when ForStrongLayout is true, following ivars are scanned: 388093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - id, Class 388193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - object * 388293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __strong anything 388393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 388493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 2. When ForStrongLayout is false, following ivars are scanned: 388593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __weak anything 388693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 388793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayout( 388893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian const ObjCImplementationDecl *OMD, 388993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian bool ForStrongLayout) { 389093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian bool hasUnion = false; 389193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 38922acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 3893e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() == LangOptions::NonGC && 3894f85e193739c953358c865005855253af4f68a497John McCall !CGM.getLangOptions().ObjCAutoRefCount) 389593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 389693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 3897db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 3898db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const FieldDecl*, 32> RecFields; 3899bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian if (CGM.getLangOptions().ObjCAutoRefCount) { 3900db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); 3901bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) 3902bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian RecFields.push_back(cast<FieldDecl>(IVD)); 3903bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian } 3904bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian else { 3905db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const ObjCIvarDecl*, 32> Ivars; 3906f85e193739c953358c865005855253af4f68a497John McCall CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars); 390793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 3908db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose // FIXME: This is not ideal; we shouldn't have to do this copy. 3909db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose RecFields.append(Ivars.begin(), Ivars.end()); 3910bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian } 391193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 391293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (RecFields.empty()) 391393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 391493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 391593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars.clear(); 391693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo.clear(); 391793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 391893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); 391993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (IvarsInfo.empty()) 392093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 3921b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian // Sort on byte position in case we encounterred a union nested in 3922b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian // the ivar list. 3923b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian if (hasUnion && !IvarsInfo.empty()) 3924b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian std::sort(IvarsInfo.begin(), IvarsInfo.end()); 3925b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian if (hasUnion && !SkipIvars.empty()) 3926b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian std::sort(SkipIvars.begin(), SkipIvars.end()); 3927b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian 392893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian std::string BitMap; 3929b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 393093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 393193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (CGM.getLangOptions().ObjCGCBitmapPrint) { 39326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar printf("\n%s ivar layout for class '%s': ", 39333d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian ForStrongLayout ? "strong" : "weak", 39344087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar OMD->getClassInterface()->getName().data()); 39353d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian const unsigned char *s = (unsigned char*)BitMap.c_str(); 39363d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian for (unsigned i = 0; i < BitMap.size(); i++) 39373d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian if (!(s[i] & 0xf0)) 39383d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 39393d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian else 39403d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 39413d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("\n"); 39423d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian } 394393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return C; 3944d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian} 3945d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian 394656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 3947259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 3948259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 394963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar // FIXME: Avoid std::string copying. 395063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 39516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_", 39520032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantArray::get(VMContext, Sel.getAsString()), 3953af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3954af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methname,cstring_literals" : 3955af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 3956b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 3957259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 3958a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 39596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 39606efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 396127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Merge into a single cstring creation function. 396256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 396327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 396427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 396527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 39663e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbarllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 39677794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel std::string TypeStr; 39687794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 39697794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 39707794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 39716efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 397263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 397363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 39740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantArray::get(VMContext, TypeStr), 3975af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3976af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methtype,cstring_literals" : 3977af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 3978b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 39796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3980a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 3981259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar} 3982259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 398356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) { 398427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar std::string TypeStr; 3985f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (CGM.getContext().getObjCEncodingForMethodDecl( 3986f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor const_cast<ObjCMethodDecl*>(D), 3987f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor TypeStr)) 3988f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 39897794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 39907794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 39917794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 3992b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar if (!Entry) 3993b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 39940032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantArray::get(VMContext, TypeStr), 3995af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3996af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methtype,cstring_literals" : 3997af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 3998b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 39997794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 4000a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 400127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 400227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4003c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function. 400456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 4005c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 40066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 400763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 40086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", 40099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::ConstantArray::get(VMContext, 40109c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Ident->getNameStart()), 401163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__TEXT,__cstring,cstring_literals", 4012b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 4013c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 4014a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 4015c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 4016c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 4017c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function. 4018c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar// FIXME: This Decl should be more precise. 401963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbarllvm::Constant * 40206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 40216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container) { 4022c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar std::string TypeStr; 4023c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 4024c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 4025c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 4026c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 40276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 402856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const ObjCContainerDecl *CD, 40295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> &Name) { 4030c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar llvm::raw_svector_ostream OS(Name); 4031679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian assert (CD && "Missing container decl in GetNameForMethod"); 4032c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 4033c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar << '[' << CD->getName(); 40346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (const ObjCCategoryImplDecl *CID = 4035c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 4036900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << '(' << CID << ')'; 4037c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar OS << ' ' << D->getSelector().getAsString() << ']'; 4038b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar} 4039b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 4040f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarvoid CGObjCMac::FinishModule() { 40414e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar EmitModuleInfo(); 40424e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 40430c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Emit the dummy bodies for any protocols which were referenced but 40440c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // never defined. 40456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 4046ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner I = Protocols.begin(), e = Protocols.end(); I != e; ++I) { 4047ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner if (I->second->hasInitializer()) 40480c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar continue; 40494e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 40501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[5]; 4051c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 4052ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner Values[1] = GetClassName(I->first); 4053c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 40540c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Values[3] = Values[4] = 4055c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 4056ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner I->second->setLinkage(llvm::GlobalValue::InternalLinkage); 405708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 40580c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Values)); 4059ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(I->second); 40600c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar } 40610c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 4062242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Add assembler directives to add lazy undefined symbol references 4063242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // for classes which are referenced but not defined. This is 4064242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // important for correct linker interaction. 4065330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar // 4066330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar // FIXME: It would be nice if we had an LLVM construct for this. 4067330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar if (!LazySymbols.empty() || !DefinedSymbols.empty()) { 4068330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::SmallString<256> Asm; 4069330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar Asm += CGM.getModule().getModuleInlineAsm(); 4070330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar if (!Asm.empty() && Asm.back() != '\n') 4071330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar Asm += '\n'; 4072330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar 4073330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::raw_svector_ostream OS(Asm); 4074330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(), 4075330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar e = DefinedSymbols.end(); I != e; ++I) 407601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n" 407701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "\t.globl .objc_class_name_" << (*I)->getName() << "\n"; 4078afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(), 4079b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian e = LazySymbols.end(); I != e; ++I) { 4080afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n"; 4081b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian } 4082b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian 4083b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian for (size_t i = 0; i < DefinedCategoryNames.size(); ++i) { 4084b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n" 4085b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n"; 4086b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian } 4087afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner 4088330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar CGM.getModule().setModuleInlineAsm(OS.str()); 4089242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar } 4090f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar} 4091f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 40926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 4093ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian : CGObjCCommonMac(cgm), 40941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCTypes(cgm) { 4095aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 4096ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCABI = 2; 4097ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian} 4098ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian 4099f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** */ 4100f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 4101ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 41021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : VMContext(cgm.getLLVMContext()), CGM(cgm) { 41034e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar CodeGen::CodeGenTypes &Types = CGM.getTypes(); 41044e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar ASTContext &Ctx = CGM.getContext(); 41056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 410627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ShortTy = Types.ConvertType(Ctx.ShortTy); 41076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar IntTy = Types.ConvertType(Ctx.IntTy); 41084e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar LongTy = Types.ConvertType(Ctx.LongTy); 41090a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian LongLongTy = Types.ConvertType(Ctx.LongLongTy); 41103c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 41116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 41124e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 411396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 41144e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 41156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4116f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: It would be nice to unify this with the opaque type, so that the IR 4117f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // comes out a bit cleaner. 41182acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 411996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 41206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4121ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // I'm not sure I like this. The implicit coordination is a bit 4122ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // gross. We should solve this in a reasonable fashion because this 4123ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // is a pretty common task (match some runtime data structure with 4124ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // an LLVM data structure). 41256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4126ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME: This is leaked. 4127ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME: Merge with rewriter code? 41286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4129ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // struct _objc_super { 4130ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // id self; 4131ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // Class cls; 4132ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // } 4133465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4134daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar Ctx.getTranslationUnitDecl(), 4135ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara SourceLocation(), SourceLocation(), 41366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar &Ctx.Idents.get("_objc_super")); 4137ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 41387a614d8380297fcd2bc23986241905d97222948cRichard Smith Ctx.getObjCIdType(), 0, 0, false, false)); 4139ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 41407a614d8380297fcd2bc23986241905d97222948cRichard Smith Ctx.getObjCClassType(), 0, 0, false, false)); 4141838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor RD->completeDefinition(); 41426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4143ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperCTy = Ctx.getTagDeclType(RD); 4144ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperPtrCTy = Ctx.getPointerType(SuperCTy); 41456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4146ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 41476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 41486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 414930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_t { 415030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *name; 41516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // char *attributes; 415230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 4153c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner PropertyTy = llvm::StructType::create("struct._prop_t", 4154c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, NULL); 41556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 415630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_list_t { 4157d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // uint32_t entsize; // sizeof(struct _prop_t) 415830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t count_of_properties; 4159d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _prop_t prop_list[count_of_properties]; 416030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 41619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner PropertyListTy = 4162c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._prop_list_t", IntTy, IntTy, 4163c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(PropertyTy, 0), NULL); 416430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_list_t * 416596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 41666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 416730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _objc_method { 416830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // SEL _cmd; 416930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *method_type; 417030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *_imp; 417130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 4172c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodTy = llvm::StructType::create("struct._objc_method", 4173c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner SelectorPtrTy, Int8PtrTy, Int8PtrTy, 4174c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner NULL); 41756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4176d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _objc_cache * 4177c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); 417896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 41799d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 4180ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian} 41814e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 41826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 41831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : ObjCCommonTypesHelper(cgm) { 418410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description { 418510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // SEL name; 418610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *types; 418710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 41886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionTy = 4189c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_method_description", 4190c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner SelectorPtrTy, Int8PtrTy, NULL); 41916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 419210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list { 419310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // int count; 419410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description[1]; 419510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 41966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionListTy = 4197c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_method_description_list", 4198c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, 4199c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(MethodDescriptionTy, 0),NULL); 42006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 420110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list * 42026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionListPtrTy = 420396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::PointerType::getUnqual(MethodDescriptionListTy); 42046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 42056efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Protocol description structures 42066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 420710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension { 420810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // uint32_t size; // sizeof(struct _objc_protocol_extension) 420910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *optional_instance_methods; 421010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *optional_class_methods; 421110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_property_list *instance_properties; 421210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 42136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolExtensionTy = 4214c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_protocol_extension", 4215c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, MethodDescriptionListPtrTy, 4216c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodDescriptionListPtrTy, PropertyListPtrTy, 4217c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner NULL); 42186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 421910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension * 422096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 42216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 42220c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Handle recursive construction of Protocol and ProtocolList types 42236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 42249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolTy = 4225c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol"); 42266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 42279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListTy = 4228c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 42299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), 4230ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian LongTy, 42319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::ArrayType::get(ProtocolTy, 0), 4232ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian NULL); 42336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 423410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol { 423510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension *isa; 423610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *protocol_name; 423710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol **_objc_protocol_list; 423810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *instance_methods; 423910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *class_methods; 424010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 42419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 42429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ProtocolListTy), 42439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodDescriptionListPtrTy, 42449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodDescriptionListPtrTy, 42459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 42469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 424710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_list * 424896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 42496efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 425096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 425127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 425227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Class description structures 425327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 425410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar { 425510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_name; 425610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_type; 425710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // int ivar_offset; 425810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 4259c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IvarTy = llvm::StructType::create("struct._objc_ivar", 4260c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, IntTy, NULL); 426127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 426210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar_list * 42639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListTy = 4264c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_ivar_list"); 426596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 426627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 426710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list * 42689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListTy = 4269c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_method_list"); 427096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 427127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 427210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class_extension * 42736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ClassExtensionTy = 4274c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_class_extension", 4275c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, Int8PtrTy, PropertyListPtrTy, NULL); 427696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 427727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4278c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassTy = llvm::StructType::create(VMContext, "struct._objc_class"); 427927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 428010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class { 428110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // Class isa; 428210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // Class super_class; 428310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *name; 428410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long version; 428510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long info; 428610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long instance_size; 428710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar_list *ivars; 428810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *methods; 428910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_cache *cache; 429010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_list *protocols; 429110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_layout; 429210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class_ext *ext; 429310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // }; 42949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 42959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassTy), 42969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner Int8PtrTy, 42979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 42989cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 42999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 43009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListPtrTy, 43019cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListPtrTy, 43029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CachePtrTy, 43039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListPtrTy, 43049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner Int8PtrTy, 43059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassExtensionPtrTy, 43069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 43079cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 430896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 430927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 431010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_category { 431110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *category_name; 431210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *class_name; 431310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *instance_method; 431410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *class_method; 431510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // uint32_t size; // sizeof(struct _objc_category) 431610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_property_list *instance_properties;// category's @property 431710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 43189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CategoryTy = 4319c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_category", 4320c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, MethodListPtrTy, 4321c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListPtrTy, ProtocolListPtrTy, 4322c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, PropertyListPtrTy, NULL); 432386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 432427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Global metadata structures 432527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 432610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_symtab { 432710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long sel_ref_cnt; 432810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // SEL *refs; 432910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // short cls_def_cnt; 433010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // short cat_def_cnt; 433110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *defs[cls_def_cnt + cat_def_cnt]; 433210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 43339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner SymtabTy = 4334c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_symtab", 4335c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner LongTy, SelectorPtrTy, ShortTy, ShortTy, 4336c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(Int8PtrTy, 0), NULL); 433796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 433827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4339db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // struct _objc_module { 4340db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // long version; 4341db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // long size; // sizeof(struct _objc_module) 4342db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // char *name; 4343db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // struct _objc_symtab* symtab; 4344db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // } 43456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ModuleTy = 4346c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_module", 4347c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL); 434814c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar 43496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4350f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This is the size of the setjmp buffer and should be target 4351f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // specific. 18 is what's used on 32-bit X86. 4352124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson uint64_t SetJmpBufferSize = 18; 43536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4354124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson // Exceptions 43559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *StackPtrTy = llvm::ArrayType::get( 43563c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer llvm::Type::getInt8PtrTy(VMContext), 4); 43576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 43586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ExceptionDataTy = 4359c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_exception_data", 43609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 43619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner SetJmpBufferSize), 43629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner StackPtrTy, NULL); 4363124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 4364bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 4365bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 43666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 43671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : ObjCCommonTypesHelper(cgm) { 436830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _method_list_t { 436930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t entsize; // sizeof(struct _objc_method) 437030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t method_count; 437130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _objc_method method_list[method_count]; 437230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 43739cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListnfABITy = 4374c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__method_list_t", IntTy, IntTy, 4375c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(MethodTy, 0), NULL); 4376d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct method_list_t * 437796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 43786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 437930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _protocol_t { 438030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // id isa; // NULL 438130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const char * const protocol_name; 4382d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _protocol_list_t * protocol_list; // super protocols 438330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t * const instance_methods; 438430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t * const class_methods; 438530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t *optionalInstanceMethods; 438630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t *optionalClassMethods; 4387d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _prop_list_t * properties; 438830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint32_t size; // sizeof(struct _protocol_t) 438930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint32_t flags; // = 0 439030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 43916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4392d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // Holder for struct _protocol_list_t * 43939cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListnfABITy = 4394c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 43959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 43969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolnfABITy = 4397c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy, 4398c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(ProtocolListnfABITy), 4399c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4400c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4401c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner PropertyListPtrTy, IntTy, IntTy, NULL); 4402948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 4403948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // struct _protocol_t* 440496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 44056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4406da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // struct _protocol_list_t { 4407d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // long protocol_count; // Note, this is 32/64 bit 4408948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // struct _protocol_t *[protocol_count]; 440930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 44109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListnfABITy->setBody(LongTy, 44119cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::ArrayType::get(ProtocolnfABIPtrTy, 0), 44129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 44136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4414d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _objc_protocol_list* 441596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 44166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 441730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _ivar_t { 441830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // unsigned long int *offset; // pointer to ivar offset location 441930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *name; 442030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *type; 442130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t alignment; 442230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t size; 442330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 44249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarnfABITy = 4425c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._ivar_t", 4426c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(LongTy), 4427c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); 44286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 442930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _ivar_list_t { 443030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32 entsize; // sizeof(struct _ivar_t) 443130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32 count; 443230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _iver_t list[count]; 443330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 44349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListnfABITy = 4435c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy, 4436c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(IvarnfABITy, 0), NULL); 44376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 443896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 44396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4440d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_ro_t { 444130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const flags; 444230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const instanceStart; 444330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const instanceSize; 444430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const reserved; // only when building for 64bit targets 444530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint8_t * const ivarLayout; 444630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const char *const name; 444730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _method_list_t * const baseMethods; 444830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _objc_protocol_list *const baseProtocols; 444930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _ivar_list_t *const ivars; 445030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint8_t * const weakIvarLayout; 445130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _prop_list_t * const properties; 445230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 44536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4454d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // FIXME. Add 'reserved' field in 64bit abi mode! 4455c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassRonfABITy = llvm::StructType::create("struct._class_ro_t", 4456c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, IntTy, IntTy, Int8PtrTy, 4457c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, MethodListnfABIPtrTy, 4458c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ProtocolListnfABIPtrTy, 4459c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IvarListnfABIPtrTy, 4460c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, PropertyListPtrTy, NULL); 44616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4462d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 44639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 44640774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 44650774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall ->getPointerTo(); 44666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4467d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t { 4468d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t *isa; 4469d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t * const superclass; 4470d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // void *cache; 4471d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IMP *vtable; 4472d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct class_ro_t *ro; 4473d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // } 44746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4475c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t"); 44769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 44779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassnfABITy), 44789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CachePtrTy, 44799cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ImpnfABITy), 44809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassRonfABITy), 44819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 44826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4483aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // LLVM for struct _class_t * 448496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 44856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4486d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _category_t { 4487d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const char * const name; 4488d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t *const cls; 4489d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _method_list_t * const instance_methods; 4490d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _method_list_t * const class_methods; 4491d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _protocol_list_t * const protocols; 4492d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _prop_list_t * const properties; 449345c2ba0c13f353a8bab6cc01b30b3a13f3404c1eFariborz Jahanian // } 4494c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner CategorynfABITy = llvm::StructType::create("struct._category_t", 4495c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, ClassnfABIPtrTy, 4496c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, 4497c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, 4498c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ProtocolListnfABIPtrTy, 4499c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner PropertyListPtrTy, 4500c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner NULL); 45016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 45022e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // New types for nonfragile abi messaging. 450383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian CodeGen::CodeGenTypes &Types = CGM.getTypes(); 450483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian ASTContext &Ctx = CGM.getContext(); 45056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 45062e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefTy - LLVM for: 45072e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _message_ref_t { 45082e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // IMP messenger; 45092e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 45102e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 45116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 451283a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // First the clang type for struct _message_ref_t 4513465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4514daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar Ctx.getTranslationUnitDecl(), 4515ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara SourceLocation(), SourceLocation(), 451683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian &Ctx.Idents.get("_message_ref_t")); 4517ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 45187a614d8380297fcd2bc23986241905d97222948cRichard Smith Ctx.VoidPtrTy, 0, 0, false, false)); 4519ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 45207a614d8380297fcd2bc23986241905d97222948cRichard Smith Ctx.getObjCSelType(), 0, 0, false, false)); 4521838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor RD->completeDefinition(); 45226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 452383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefCTy = Ctx.getTagDeclType(RD); 452483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 452583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 45266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 45272e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefPtrTy - LLVM for struct _message_ref_t* 452896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 45296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 45302e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefTy - LLVM for: 45312e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _super_message_ref_t { 45322e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SUPER_IMP messenger; 45332e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 45342e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 45359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner SuperMessageRefTy = 4536c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._super_message_ref_t", 4537c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ImpnfABITy, SelectorPtrTy, NULL); 45386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 45392e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 45406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 45419d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 4542e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 4543e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // struct objc_typeinfo { 4544e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // const void** vtable; // objc_ehtype_vtable + 2 4545e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // const char* name; // c++ typeinfo string 4546e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // Class cls; 4547e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // }; 45489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner EHTypeTy = 4549c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_typeinfo", 4550c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(Int8PtrTy), 4551c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, ClassnfABIPtrTy, NULL); 455296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 4553bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 4554bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 45556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 4556aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian FinishNonFragileABIModule(); 45576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4558aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian return NULL; 4559aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 4560aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 45616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCNonFragileABIMac::AddModuleClassList(const 45626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::vector<llvm::GlobalValue*> 45636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar &Container, 4564463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SymbolName, 4565463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SectionName) { 4566463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar unsigned NumClasses = Container.size(); 45676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4568463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar if (!NumClasses) 4569463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar return; 45706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4571463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar std::vector<llvm::Constant*> Symbols(NumClasses); 4572463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar for (unsigned i=0; i<NumClasses; i++) 45733c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 4574463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar ObjCTypes.Int8PtrTy); 45756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant* Init = 457696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 4577463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar NumClasses), 4578463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar Symbols); 45796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4580463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar llvm::GlobalVariable *GV = 45811c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4582463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar llvm::GlobalValue::InternalLinkage, 4583463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar Init, 45841c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson SymbolName); 45854b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 4586463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar GV->setSection(SectionName); 4587ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 4588463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar} 45896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4590aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 4591aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // nonfragile abi has no module definition. 45926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4593463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar // Build list of all implemented class addresses in array 4594f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // L_OBJC_LABEL_CLASS_$. 45956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedClasses, 4596463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "\01L_OBJC_LABEL_CLASS_$", 4597463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "__DATA, __objc_classlist, regular, no_dead_strip"); 4598a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 4599a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian for (unsigned i = 0; i < DefinedClasses.size(); i++) { 4600a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian llvm::GlobalValue *IMPLGV = DefinedClasses[i]; 4601a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4602a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian continue; 4603a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4604a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian } 4605a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 46060e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) { 46070e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; 46080e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 46090e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian continue; 46100e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 46110e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian } 4612a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 46136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedNonLazyClasses, 461474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 461574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "__DATA, __objc_nlclslist, regular, no_dead_strip"); 46166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4617f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // Build list of all implemented category addresses in array 4618f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // L_OBJC_LABEL_CATEGORY_$. 46196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedCategories, 4620463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "\01L_OBJC_LABEL_CATEGORY_$", 4621463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "__DATA, __objc_catlist, regular, no_dead_strip"); 46226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedNonLazyCategories, 462374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 462474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 46256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4626fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar EmitImageInfo(); 4627aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 4628aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 4629944c84313da15477eb18d90babb0890d10d98082John McCall/// isVTableDispatchedSelector - Returns true if SEL is not in the list of 4630944c84313da15477eb18d90babb0890d10d98082John McCall/// VTableDispatchMethods; false otherwise. What this means is that 46316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// except for the 19 selectors in the list, we generate 32bit-style 4632d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// message dispatch call for all the rest. 4633944c84313da15477eb18d90babb0890d10d98082John McCallbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) { 4634944c84313da15477eb18d90babb0890d10d98082John McCall // At various points we've experimented with using vtable-based 4635944c84313da15477eb18d90babb0890d10d98082John McCall // dispatch for all methods. 4636f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { 4637f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar default: 4638944c84313da15477eb18d90babb0890d10d98082John McCall llvm_unreachable("Invalid dispatch method!"); 4639f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar case CodeGenOptions::Legacy: 4640776dbf9704353515b422ee13e481194c937ba01dFariborz Jahanian return false; 4641944c84313da15477eb18d90babb0890d10d98082John McCall case CodeGenOptions::NonLegacy: 4642944c84313da15477eb18d90babb0890d10d98082John McCall return true; 4643f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar case CodeGenOptions::Mixed: 4644f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar break; 4645f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar } 4646f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar 4647f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar // If so, see whether this selector is in the white-list of things which must 4648f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar // use the new dispatch convention. We lazily build a dense set for this. 4649944c84313da15477eb18d90babb0890d10d98082John McCall if (VTableDispatchMethods.empty()) { 4650944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("alloc")); 4651944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("class")); 4652944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("self")); 4653944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("isFlipped")); 4654944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("length")); 4655944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("count")); 4656944c84313da15477eb18d90babb0890d10d98082John McCall 4657944c84313da15477eb18d90babb0890d10d98082John McCall // These are vtable-based if GC is disabled. 4658944c84313da15477eb18d90babb0890d10d98082John McCall // Optimistically use vtable dispatch for hybrid compiles. 4659e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() != LangOptions::GCOnly) { 4660944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("retain")); 4661944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("release")); 4662944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("autorelease")); 4663944c84313da15477eb18d90babb0890d10d98082John McCall } 4664944c84313da15477eb18d90babb0890d10d98082John McCall 4665944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("allocWithZone")); 4666944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 4667944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 4668944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("objectForKey")); 4669944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 4670944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isEqualToString")); 4671944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isEqual")); 4672944c84313da15477eb18d90babb0890d10d98082John McCall 4673944c84313da15477eb18d90babb0890d10d98082John McCall // These are vtable-based if GC is enabled. 4674944c84313da15477eb18d90babb0890d10d98082John McCall // Optimistically use vtable dispatch for hybrid compiles. 4675e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor if (CGM.getLangOptions().getGC() != LangOptions::NonGC) { 4676944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("hash")); 4677944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("addObject")); 4678944c84313da15477eb18d90babb0890d10d98082John McCall 4679944c84313da15477eb18d90babb0890d10d98082John McCall // "countByEnumeratingWithState:objects:count" 4680944c84313da15477eb18d90babb0890d10d98082John McCall IdentifierInfo *KeyIdents[] = { 4681944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("countByEnumeratingWithState"), 4682944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("objects"), 4683944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("count") 4684944c84313da15477eb18d90babb0890d10d98082John McCall }; 4685944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert( 4686944c84313da15477eb18d90babb0890d10d98082John McCall CGM.getContext().Selectors.getSelector(3, KeyIdents)); 4687944c84313da15477eb18d90babb0890d10d98082John McCall } 4688d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 4689f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar 4690944c84313da15477eb18d90babb0890d10d98082John McCall return VTableDispatchMethods.count(Sel); 4691d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian} 4692d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian 4693058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian// Metadata flags 4694058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianenum MetaDataDlags { 4695058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS = 0x0, 4696058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS_META = 0x1, 4697058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS_ROOT = 0x2, 4698493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian OBJC2_CLS_HIDDEN = 0x10, 4699f85e193739c953358c865005855253af4f68a497John McCall CLS_EXCEPTION = 0x20, 4700f85e193739c953358c865005855253af4f68a497John McCall 4701f85e193739c953358c865005855253af4f68a497John McCall /// (Obsolete) ARC-specific: this class has a .release_ivars method 4702f85e193739c953358c865005855253af4f68a497John McCall CLS_HAS_IVAR_RELEASER = 0x40, 4703f85e193739c953358c865005855253af4f68a497John McCall /// class was compiled with -fobjc-arr 4704f85e193739c953358c865005855253af4f68a497John McCall CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 4705058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}; 4706058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassRoTInitializer - generate meta-data for: 4707058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_ro_t { 4708058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const flags; 4709058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const instanceStart; 4710058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const instanceSize; 4711058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const reserved; // only when building for 64bit targets 4712058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const uint8_t * const ivarLayout; 4713058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const char *const name; 4714058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _method_list_t * const baseMethods; 4715da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _protocol_list_t *const baseProtocols; 4716058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _ivar_list_t *const ivars; 4717058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const uint8_t * const weakIvarLayout; 4718058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _prop_list_t * const properties; 4719058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// } 4720058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// 4721058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 47226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned flags, 47236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceStart, 47246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceSize, 47256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID) { 4726058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian std::string ClassName = ID->getNameAsString(); 47271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[10]; // 11 for 64bit targets! 4728f85e193739c953358c865005855253af4f68a497John McCall 4729f85e193739c953358c865005855253af4f68a497John McCall if (CGM.getLangOptions().ObjCAutoRefCount) 4730f85e193739c953358c865005855253af4f68a497John McCall flags |= CLS_COMPILED_BY_ARC; 4731f85e193739c953358c865005855253af4f68a497John McCall 47324a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 47334a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 47344a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 4735058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian // FIXME. For 64bit targets add 0 here. 47366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 47376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : BuildIvarLayout(ID, true); 4738058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values[ 4] = GetClassName(ID->getIdentifier()); 4739493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // const struct _method_list_t * const baseMethods; 4740493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian std::vector<llvm::Constant*> Methods; 4741493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian std::string MethodListName("\01l_OBJC_$_"); 4742493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (flags & CLS_META) { 4743493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 47446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::classmeth_iterator 474517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 4746493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Class methods should always be defined. 4747493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 4748493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 4749493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } else { 4750493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 47516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::instmeth_iterator 475217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 4753493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Instance methods should always be defined. 4754493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 4755493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 47566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::propimpl_iterator 475717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 4758939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian ObjCPropertyImplDecl *PID = *i; 47596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4760939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 4761939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian ObjCPropertyDecl *PD = PID->getPropertyDecl(); 47626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4763939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 4764939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (llvm::Constant *C = GetMethodConstant(MD)) 4765939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian Methods.push_back(C); 4766939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 4767939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (llvm::Constant *C = GetMethodConstant(MD)) 4768939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian Methods.push_back(C); 4769939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian } 4770939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian } 4771493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 47726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 5] = EmitMethodList(MethodListName, 47736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", Methods); 47746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4775da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4776da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 47776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 47789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + OID->getName(), 477953b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek OID->all_referenced_protocol_begin(), 478053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek OID->all_referenced_protocol_end()); 47816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 478298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian if (flags & CLS_META) 4783c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 478498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian else 478598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Values[ 7] = EmitIvarList(ID); 47866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 47876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : BuildIvarLayout(ID, false); 47885de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian if (flags & CLS_META) 4789c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 47905de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian else 47919c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 47929c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ID, ID->getClassInterface(), ObjCTypes); 479308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 4794058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values); 4795058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *CLASS_RO_GV = 47966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false, 47976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::InternalLinkage, 47986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 47996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (flags & CLS_META) ? 48006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 48016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string("\01l_OBJC_CLASS_RO_$_")+ClassName); 480209796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian CLASS_RO_GV->setAlignment( 48034b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy)); 48041bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian CLASS_RO_GV->setSection("__DATA, __objc_const"); 4805058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian return CLASS_RO_GV; 4806f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian 4807058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian} 4808058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian 4809058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassMetaData - This routine defines that to-level meta-data 4810058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// for the given ClassName for: 4811058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t { 4812058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t *isa; 4813058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t * const superclass; 4814058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// void *cache; 4815058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// IMP *vtable; 4816058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct class_ro_t *ro; 4817058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// } 4818058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// 481984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 48206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string &ClassName, 48216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *IsAGV, 48226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *SuperClassGV, 48236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *ClassRoGV, 48246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool HiddenVisibility) { 48251d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 48261d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer IsAGV, 48271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer SuperClassGV, 48281d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCEmptyCacheVar, // &ObjCEmptyCacheVar 48291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCEmptyVtableVar, // &ObjCEmptyVtableVar 48301d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ClassRoGV // &CLASS_RO_GV 48311d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 48326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (!Values[1]) 48336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 48346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 4835058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values); 48365a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 48375a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar GV->setInitializer(Init); 4838dd0db2a60b65e7eaa852b77c8b9f607640eb50b9Fariborz Jahanian GV->setSection("__DATA, __objc_data"); 483909796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 48404b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 4841cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (HiddenVisibility) 4842cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 484384394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian return GV; 4844058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian} 4845058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian 48466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarbool 4847ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz JahanianCGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 484817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis return OD->getClassMethod(GetNullarySelector("load")) != 0; 484974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar} 485074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 48519f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbarvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 4852b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceStart, 4853b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceSize) { 48546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ASTRecordLayout &RL = 4855b4c79e027fdcc752b5a377611fd4cfbb21611a05Daniel Dunbar CGM.getContext().getASTObjCImplementationLayout(OID); 48566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 48576e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar // InstanceSize is really instance end. 4858ec2990351335f163601b98e39b52425e2e9f931eKen Dyck InstanceSize = RL.getDataSize().getQuantity(); 48596e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar 48606e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar // If there are no fields, the start is the same as the end. 48616e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar if (!RL.getFieldCount()) 48626e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar InstanceStart = InstanceSize; 48636e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar else 4864fb67ccd9da412d652d62e2ac9675b0f1b14fdc73Ken Dyck InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 4865b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar} 4866b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar 4867aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 4868aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian std::string ClassName = ID->getNameAsString(); 4869aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian if (!ObjCEmptyCacheVar) { 4870aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyCacheVar = new llvm::GlobalVariable( 48716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 48726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.CacheTy, 48736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 48746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 48756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 48766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_objc_empty_cache"); 48776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4878aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyVtableVar = new llvm::GlobalVariable( 48796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 48806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ImpnfABITy, 48816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 48826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 48836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 48846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_objc_empty_vtable"); 48856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 48866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert(ID->getClassInterface() && 4887493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 48886c1aac8883ef2732a2d8543d7ac2a5ca9a199f86Daniel Dunbar // FIXME: Is this correct (that meta class size is never computed)? 48896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t InstanceStart = 48909408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 4891058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian uint32_t InstanceSize = InstanceStart; 4892058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian uint32_t flags = CLS_META; 48936ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 48946ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ObjCClassName(getClassSymbolPrefix()); 48956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4896058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *SuperClassGV, *IsAGV; 48976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 48986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool classIsHidden = 48991fb0caaa7bef765b85972274e3b434af2572c141John McCall ID->getClassInterface()->getVisibility() == HiddenVisibility; 4900cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (classIsHidden) 4901493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian flags |= OBJC2_CLS_HIDDEN; 4902f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 4903109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian flags |= eClassFlags_ABI2_HasCXXStructors; 4904493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!ID->getClassInterface()->getSuperClass()) { 4905058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian // class is root 4906058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian flags |= CLS_ROOT; 49075a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 49080f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 4909058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian } else { 491084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Has a root. Current class is not a root. 4911fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian const ObjCInterfaceDecl *Root = ID->getClassInterface(); 4912fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 4913fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian Root = Super; 49140f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 49150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Root->isWeakImported()) 49160e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4917fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian // work on super class metadata symbol. 49186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string SuperClassName = 49190e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian ObjCMetaClassName + 49200e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian ID->getClassInterface()->getSuperClass()->getNameAsString(); 49210f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian SuperClassGV = GetClassGlobal(SuperClassName); 49220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 4923a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4924058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian } 4925058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 4926058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian InstanceStart, 4927058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian InstanceSize,ID); 492884394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian std::string TClassName = ObjCMetaClassName + ClassName; 49296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *MetaTClass = 4930cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 4931cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian classIsHidden); 4932a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian DefinedMetaClasses.push_back(MetaTClass); 49336ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 493484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Metadata for the class 493584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian flags = CLS; 4936cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (classIsHidden) 4937493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian flags |= OBJC2_CLS_HIDDEN; 4938f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 4939109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian flags |= eClassFlags_ABI2_HasCXXStructors; 49408158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 494168584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) 49428158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar flags |= CLS_EXCEPTION; 49438158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 4944493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!ID->getClassInterface()->getSuperClass()) { 494584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian flags |= CLS_ROOT; 494684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian SuperClassGV = 0; 4947b7b58b1fcd3007730fd46471583543c9b57c7693Chris Lattner } else { 494884394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Has a root. Current class is not a root. 4949fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian std::string RootClassName = 495084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian ID->getClassInterface()->getSuperClass()->getNameAsString(); 49515a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 49520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 4953a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 495484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian } 49559f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar GetClassSizeInfo(ID, InstanceStart, InstanceSize); 495684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian CLASS_RO_GV = BuildClassRoTInitializer(flags, 4957f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian InstanceStart, 49586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar InstanceSize, 4959f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian ID); 49606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 496184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian TClassName = ObjCClassName + ClassName; 49626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *ClassMD = 4963cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 4964cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian classIsHidden); 4965f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian DefinedClasses.push_back(ClassMD); 49668158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 496774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar // Determine if this class is also "non-lazy". 496874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar if (ImplementationIsNonLazy(ID)) 496974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar DefinedNonLazyClasses.push_back(ClassMD); 497074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 49718158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // Force the definition of the EHType if necessary. 49728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (flags & CLS_EXCEPTION) 49738158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar GetInterfaceEHType(ID->getClassInterface(), true); 497464089cece350472c04b420c497ae391443353325Fariborz Jahanian // Make sure method definition entries are all clear for next implementation. 497564089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 4976aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 4977aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 49788cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// GenerateProtocolRef - This routine is called to generate code for 49798cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// a protocol reference expression; as in: 49808cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @code 49818cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @protocol(Proto1); 49828cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @endcode 49838cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 49848cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// which will hold address of the protocol meta-data. 49858cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// 49868cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 49876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 49886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4989960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // This routine is called for @protocol only. So, we must build definition 4990960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // of protocol's meta-data (not a reference to it!) 4991960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // 49926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 49936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 49946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ExternalProtocolPtrTy); 49956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 49968cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 49974087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar ProtocolName += PD->getName(); 49986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 49998cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 50008cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian if (PTGV) 5001578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(PTGV); 50028cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV = new llvm::GlobalVariable( 50036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 50046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init->getType(), false, 50056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::WeakAnyLinkage, 50066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 50076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolName); 50088cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 50098cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5010ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(PTGV); 5011578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(PTGV); 50128cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian} 50138cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian 5014eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// GenerateCategory - Build metadata for a category implementation. 5015eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _category_t { 5016eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const char * const name; 5017eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _class_t *const cls; 5018eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _method_list_t * const instance_methods; 5019eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _method_list_t * const class_methods; 5020eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _protocol_list_t * const protocols; 5021eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _prop_list_t * const properties; 5022eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// } 5023eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// 502474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbarvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 5025eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 5026f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 50276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string ExtCatName(Prefix + Interface->getNameAsString()+ 50286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_$_" + OCD->getNameAsString()); 50296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string ExtClassName(getClassSymbolPrefix() + 50306ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar Interface->getNameAsString()); 50316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 50321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[6]; 5033eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values[0] = GetClassName(OCD->getIdentifier()); 5034eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian // meta-class entry symbol 50355a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 50360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Interface->isWeakImported()) 50372cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 50382cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian 5039eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values[1] = ClassGV; 5040f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian std::vector<llvm::Constant*> Methods; 5041f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian std::string MethodListName(Prefix); 50426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 5043f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian "_$_" + OCD->getNameAsString(); 50446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 50456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::instmeth_iterator 504617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 5047f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian // Instance methods should always be defined. 5048f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 5049f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian } 50506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 50516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = EmitMethodList(MethodListName, 50526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", 5053f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods); 5054f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian 5055f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian MethodListName = Prefix; 5056f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 5057f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian OCD->getNameAsString(); 5058f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.clear(); 50596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::classmeth_iterator 506017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 5061f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian // Class methods should always be defined. 5062f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 5063f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian } 50646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 50656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[3] = EmitMethodList(MethodListName, 50666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", 5067f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods); 50686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCategoryDecl *Category = 50695de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian Interface->FindCategoryDeclaration(OCD->getIdentifier()); 5070943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian if (Category) { 50719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::SmallString<256> ExtName; 50729c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" 50739c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar << OCD->getName(); 5074943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 50759c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + Interface->getName() + "_$_" 50769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + Category->getName(), 5077943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Category->protocol_begin(), 5078943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Category->protocol_end()); 50799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 50809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar OCD, Category, ObjCTypes); 5081b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 5082c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 5083c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 5084943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian } 50856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 50866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 50876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 5088eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values); 5089eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian llvm::GlobalVariable *GCATV 50906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy, 5091eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian false, 5092eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 5093eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Init, 50941c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson ExtCatName); 509509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GCATV->setAlignment( 50964b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy)); 50971bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian GCATV->setSection("__DATA, __objc_const"); 5098ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GCATV); 5099eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian DefinedCategories.push_back(GCATV); 510074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 510174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar // Determine if this category is also "non-lazy". 510274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar if (ImplementationIsNonLazy(OCD)) 510374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar DefinedNonLazyCategories.push_back(GCATV); 510464089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 510564089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 5106eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian} 5107493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian 5108493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// GetMethodConstant - Return a struct objc_method constant for the 5109493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// given method if it has been defined. The result is null if the 5110493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// method has not been defined. The return value has type MethodPtrTy. 5111493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 51126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCMethodDecl *MD) { 51139d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *Fn = GetMethodDefinition(MD); 5114493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!Fn) 5115493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian return 0; 51166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 51171d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Method[] = { 51183c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 51191d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 51201d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD), 51211d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 51221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 512308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 5124493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian} 5125493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian 5126493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// EmitMethodList - Build meta-data for method declarations 5127493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _method_list_t { 5128493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// uint32_t entsize; // sizeof(struct _objc_method) 5129493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// uint32_t method_count; 5130493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _objc_method method_list[method_count]; 5131493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// } 5132493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// 51335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(Twine Name, 51349c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar const char *Section, 51359c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar const ConstantVector &Methods) { 5136493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Return null for empty list. 5137493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (Methods.empty()) 5138c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 51396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5140c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 5141493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // sizeof(struct _objc_method) 51429408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 51434a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5144493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // method_count 51454a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 514696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 5147493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.size()); 51487db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Methods); 5149c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 51506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5151493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian llvm::GlobalVariable *GV = 51521c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5153c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::GlobalValue::InternalLinkage, Init, Name); 5154c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 5155493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian GV->setSection(Section); 5156ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 5157c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); 5158493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian} 515998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian 5160ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// ObjCIvarOffsetVariable - Returns the ivar offset variable for 5161ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// the given ivar. 5162e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::GlobalVariable * 5163e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 5164e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCIvarDecl *Ivar) { 5165e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); 5166a81419d0b53a40399a589a2fcc13f1ed2ec28f75Daniel Dunbar std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 51676ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor '.' + Ivar->getNameAsString(); 51686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *IvarOffsetGV = 5169ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian CGM.getModule().getGlobalVariable(Name); 5170ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian if (!IvarOffsetGV) 51716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarOffsetGV = 51721c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, 5173ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian false, 5174ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian llvm::GlobalValue::ExternalLinkage, 5175ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian 0, 51761c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Name); 5177ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian return IvarOffsetGV; 5178ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian} 5179ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian 5180e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::Constant * 5181e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 5182e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCIvarDecl *Ivar, 5183e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar unsigned long int Offset) { 5184737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 51856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 5186737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar Offset)); 518709796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian IvarOffsetGV->setAlignment( 51884b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy)); 5189737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar 5190f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 5191f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // well (i.e., in ObjCIvarOffsetVariable). 5192737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 5193737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar Ivar->getAccessControl() == ObjCIvarDecl::Package || 51941fb0caaa7bef765b85972274e3b434af2572c141John McCall ID->getVisibility() == HiddenVisibility) 51952fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 519604d4078425614bf9fd58d606335c1f5f74ee7fa4Daniel Dunbar else 519777c9fd2eee4cdac3c5a38a353788f308990598afFariborz Jahanian IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 51981f382510495b581e3028d670a23c7dcf5440be62Bill Wendling IvarOffsetGV->setSection("__DATA, __objc_ivar"); 519945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian return IvarOffsetGV; 52001bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian} 52011bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian 520298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// EmitIvarList - Emit the ivar list for the given 52031139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar/// implementation. The return value has type 520498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// IvarListnfABIPtrTy. 520598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_t { 520698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// unsigned long int *offset; // pointer to ivar offset location 520798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// char *name; 520898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// char *type; 520998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32_t alignment; 521098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32_t size; 521198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// } 521298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_list_t { 521398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32 entsize; // sizeof(struct _ivar_t) 521498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32 count; 521598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _iver_t list[count]; 521698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// } 521798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// 52183e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar 521998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 52206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID) { 52216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer std::vector<llvm::Constant*> Ivars; 52236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5224db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OID = ID->getClassInterface(); 522598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 52266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52271bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian // FIXME. Consolidate this with similar code in GenerateClass. 52286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5229db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 5230bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) { 52318e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian // Ignore unnamed bit-fields. 52328e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian if (!IVD->getDeclName()) 52338e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian continue; 52341d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Ivar[5]; 52356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 52369f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar ComputeIvarBaseOffset(CGM, ID, IVD)); 52373fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 52383fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar Ivar[2] = GetMethodVarType(IVD); 52392acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *FieldTy = 52403fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar CGM.getTypes().ConvertTypeForMem(IVD->getType()); 52419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 524298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian unsigned Align = CGM.getContext().getPreferredTypeAlign( 52436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IVD->getType().getTypePtr()) >> 3; 524498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Align = llvm::Log2_32(Align); 52454a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 524691636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // NOTE. Size of a bitfield does not match gcc's, because of the 524791636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // way bitfields are treated special in each. But I am told that 524891636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // 'size' for bitfield ivars is ignored by the runtime so it does 524991636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // not matter. If it matters, there is enough info to get the 525091636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // bitfield right! 52514a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 525208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 525398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian } 525498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian // Return null for empty list. 525598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian if (Ivars.empty()) 5256c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 5257c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner 5258c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 52599408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 52604a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 52614a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 526296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 526398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Ivars.size()); 52647db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Ivars); 5265c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 526698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 526798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::GlobalVariable *GV = 52681c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 526998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 527098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Init, 52719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Prefix + OID->getName()); 527209796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 52734b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(Init->getType())); 52741bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian GV->setSection("__DATA, __objc_const"); 52756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5276ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 52773c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); 5278da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5279da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5280da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 52816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 5282da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 52836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5284da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (!Entry) { 5285da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // We use the initializer as a marker of whether this is a forward 5286da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // reference or not. At module finalization we add the empty 5287da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // contents for protocols which were referenced but never defined. 52886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 52896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, 52906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 52916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 52929c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 5293da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5294da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 52956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5296da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5297da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5298da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5299da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// GetOrEmitProtocol - Generate the protocol meta-data: 5300da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code 5301da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t { 5302da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// id isa; // NULL 5303da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const char * const protocol_name; 5304da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _protocol_list_t * protocol_list; // super protocols 5305da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t * const instance_methods; 5306da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t * const class_methods; 5307da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t *optionalInstanceMethods; 5308da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t *optionalClassMethods; 5309da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _prop_list_t * properties; 5310da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const uint32_t size; // sizeof(struct _protocol_t) 5311da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const uint32_t flags; // = 0 5312da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// } 5313da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode 5314da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// 5315da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5316da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 53176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 5318da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 53196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5320da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Early exit if a defining object has already been generated. 5321da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (Entry && Entry->hasInitializer()) 5322da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5323da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5324da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Construct method lists. 5325da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 5326da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 53276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::instmeth_iterator 532817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 5329da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCMethodDecl *MD = *i; 53303819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *C = GetMethodDescriptionConstant(MD); 5331f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 5332f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 5333f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 5334da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5335da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptInstanceMethods.push_back(C); 5336da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 5337da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian InstanceMethods.push_back(C); 53386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 5339da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 53406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::classmeth_iterator 534217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 5343da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCMethodDecl *MD = *i; 53443819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *C = GetMethodDescriptionConstant(MD); 5345f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 5346f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 5347f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 5348da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5349da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptClassMethods.push_back(C); 5350da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 5351da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ClassMethods.push_back(C); 53526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 5353da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 53546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53551d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[10]; 5356da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // isa is NULL 5357c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 5358da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Values[1] = GetClassName(PD->getIdentifier()); 53599c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), 53609c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar PD->protocol_begin(), 53619c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar PD->protocol_end()); 53626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53633819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 53649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5365da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5366da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian InstanceMethods); 53676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 53689c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5369da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5370da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ClassMethods); 53713819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 53729c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5373da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5374da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptInstanceMethods); 53756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 53769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5377da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5378da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptClassMethods); 53799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(), 5380da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 0, PD, ObjCTypes); 53816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t Size = 53829408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 53834a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5384c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 538508e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 5386da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Values); 53876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5388da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (Entry) { 5389da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Already created, fix the linkage and update the initializer. 5390286acbdbe0c82e9a6bcad5fca3c4fa582f3f1a2cMike Stump Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 5391da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setInitializer(Init); 5392da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 53936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 53949c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 53959c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar false, llvm::GlobalValue::WeakAnyLinkage, Init, 53969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 539709796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian Entry->setAlignment( 53984b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy)); 5399da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5400da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 54018448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 5402ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 5403ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner 54048448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian // Use this protocol meta-data to build protocol list table in section 54058448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian // __DATA, __objc_protolist 54069c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::GlobalVariable *PTGV = 54079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 54089c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar false, llvm::GlobalValue::WeakAnyLinkage, Entry, 54099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName()); 541009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian PTGV->setAlignment( 54114b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 54120bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 54138448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5414ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(PTGV); 5415da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5416da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5417da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5418da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// EmitProtocolList - Generate protocol list meta-data: 5419da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code 5420da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_list_t { 5421da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// long protocol_count; // Note, this is 32/64 bit 5422da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t[protocol_count]; 5423da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// } 5424da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode 5425da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// 5426da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant * 54275f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCNonFragileABIMac::EmitProtocolList(Twine Name, 54289c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 54299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ObjCProtocolDecl::protocol_iterator end) { 5430da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian std::vector<llvm::Constant*> ProtocolRefs; 54316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5432da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Just return null for empty protocol lists 54336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (begin == end) 5434c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 54356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5436948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // FIXME: We shouldn't need to do this lookup here, should we? 54379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::SmallString<256> TmpName; 54389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Name.toVector(TmpName); 54399c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::GlobalVariable *GV = 54409c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar CGM.getModule().getGlobalVariable(TmpName.str(), true); 5441da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (GV) 54429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); 54436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5444948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar for (; begin != end; ++begin) 5445948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 5446948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 5447da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // This list is null terminated. 5448c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson ProtocolRefs.push_back(llvm::Constant::getNullValue( 54496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ProtocolnfABIPtrTy)); 54506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5451c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 5452a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson Values[0] = 54534a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 54546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[1] = 54557db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson llvm::ConstantArray::get( 545696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 54576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs.size()), 54586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs); 54596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5460c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 54611c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5462da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 5463c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner Init, Name); 5464da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian GV->setSection("__DATA, __objc_const"); 546509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 54664b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(Init->getType())); 5467ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 54686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, 5469948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar ObjCTypes.ProtocolListnfABIPtrTy); 5470da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5471da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 54723819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// GetMethodDescriptionConstant - This routine build following meta-data: 54733819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// struct _objc_method { 54743819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// SEL _cmd; 54753819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// char *method_type; 54763819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// char *_imp; 54773819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// } 54783819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian 54793819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanianllvm::Constant * 54803819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz JahanianCGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 54811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Desc[3]; 5482a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson Desc[0] = 54836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 54846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.SelectorPtrTy); 54853819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Desc[1] = GetMethodVarType(MD); 5486f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!Desc[1]) 5487f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 5488f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 54898cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian // Protocol methods have no implementation. So, this entry is always NULL. 5490c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 549108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 54923819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian} 549345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian 549445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 549545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// This code gen. amounts to generating code for: 549645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @code 549745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 549845012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @encode 54996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// 5500598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 5501506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall CodeGen::CodeGenFunction &CGF, 5502506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall QualType ObjectTy, 5503506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall llvm::Value *BaseValue, 5504506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall const ObjCIvarDecl *Ivar, 5505506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall unsigned CVRQualifiers) { 5506506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface(); 55079777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 55089777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar EmitIvarOffset(CGF, ID, Ivar)); 550945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian} 551045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian 5511f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 55126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 55136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *Interface, 55146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCIvarDecl *Ivar) { 55152da84ff228a231adbd3f6f236b857f752d02959aDaniel Dunbar return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); 5516f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian} 5517f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian 5518b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCallstatic void appendSelectorForMessageRefTable(std::string &buffer, 5519b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall Selector selector) { 5520b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (selector.isUnarySelector()) { 5521b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += selector.getNameForSlot(0); 5522b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall return; 5523b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } 55246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5525b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) { 5526b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += selector.getNameForSlot(i); 5527b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += '_'; 5528b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } 5529b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall} 5530b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5531944c84313da15477eb18d90babb0890d10d98082John McCall/// Emit a "v-table" message send. We emit a weak hidden-visibility 5532944c84313da15477eb18d90babb0890d10d98082John McCall/// struct, initially containing the selector pointer and a pointer to 5533944c84313da15477eb18d90babb0890d10d98082John McCall/// a "fixup" variant of the appropriate objc_msgSend. To call, we 5534944c84313da15477eb18d90babb0890d10d98082John McCall/// load and call the function pointer, passing the address of the 5535944c84313da15477eb18d90babb0890d10d98082John McCall/// struct as the second parameter. The runtime determines whether 5536944c84313da15477eb18d90babb0890d10d98082John McCall/// the selector is currently emitted using vtable dispatch; if so, it 5537944c84313da15477eb18d90babb0890d10d98082John McCall/// substitutes a stub function which simply tail-calls through the 5538944c84313da15477eb18d90babb0890d10d98082John McCall/// appropriate vtable slot, and if not, it substitues a stub function 5539944c84313da15477eb18d90babb0890d10d98082John McCall/// which tail-calls objc_msgSend. Both stubs adjust the selector 5540944c84313da15477eb18d90babb0890d10d98082John McCall/// argument to correctly point to the selector. 5541944c84313da15477eb18d90babb0890d10d98082John McCallRValue 5542944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, 5543944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot returnSlot, 5544944c84313da15477eb18d90babb0890d10d98082John McCall QualType resultType, 5545944c84313da15477eb18d90babb0890d10d98082John McCall Selector selector, 5546944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *arg0, 5547944c84313da15477eb18d90babb0890d10d98082John McCall QualType arg0Type, 5548944c84313da15477eb18d90babb0890d10d98082John McCall bool isSuper, 5549944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &formalArgs, 5550944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *method) { 5551b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Compute the actual arguments. 5552b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CallArgList args; 5553b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5554944c84313da15477eb18d90babb0890d10d98082John McCall // First argument: the receiver / super-call structure. 5555b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (!isSuper) 5556944c84313da15477eb18d90babb0890d10d98082John McCall arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy); 5557944c84313da15477eb18d90babb0890d10d98082John McCall args.add(RValue::get(arg0), arg0Type); 5558b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5559944c84313da15477eb18d90babb0890d10d98082John McCall // Second argument: a pointer to the message ref structure. Leave 5560944c84313da15477eb18d90babb0890d10d98082John McCall // the actual argument value blank for now. 5561b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy); 5562b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5563b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args.insert(args.end(), formalArgs.begin(), formalArgs.end()); 5564b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5565b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall const CGFunctionInfo &fnInfo = 5566b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CGM.getTypes().getFunctionInfo(resultType, args, 5567b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall FunctionType::ExtInfo()); 5568b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5569cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullReturnState nullReturn; 5570cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 5571944c84313da15477eb18d90babb0890d10d98082John McCall // Find the function to call and the mangled name for the message 5572944c84313da15477eb18d90babb0890d10d98082John McCall // ref structure. Using a different mangled name wouldn't actually 5573944c84313da15477eb18d90babb0890d10d98082John McCall // be a problem; it would just be a waste. 5574944c84313da15477eb18d90babb0890d10d98082John McCall // 5575944c84313da15477eb18d90babb0890d10d98082John McCall // The runtime currently never uses vtable dispatch for anything 5576944c84313da15477eb18d90babb0890d10d98082John McCall // except normal, non-super message-sends. 5577944c84313da15477eb18d90babb0890d10d98082John McCall // FIXME: don't use this for that. 5578b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Constant *fn = 0; 5579b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall std::string messageRefName("\01l_"); 5580b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (CGM.ReturnTypeUsesSRet(fnInfo)) { 5581b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (isSuper) { 5582b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 5583b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSendSuper2_stret_fixup"; 55849b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } else { 5585cba681af356e24ec4335bcf2b6bb6515072ace99John McCall nullReturn.init(CGF, arg0); 5586b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendStretFixupFn(); 5587b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_stret_fixup"; 55889b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } 5589b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) { 5590b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendFpretFixupFn(); 5591b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_fpret_fixup"; 5592b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 5593b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (isSuper) { 5594b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendSuper2FixupFn(); 5595b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSendSuper2_fixup"; 55969b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } else { 5597b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendFixupFn(); 5598b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_fixup"; 55999b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } 560083a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian } 5601b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 5602b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += '_'; 5603b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5604b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Append the selector name, except use underscores anywhere we 5605b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // would have used colons. 5606b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall appendSelectorForMessageRefTable(messageRefName, selector); 5607b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5608b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::GlobalVariable *messageRef 5609b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall = CGM.getModule().getGlobalVariable(messageRefName); 5610b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (!messageRef) { 5611944c84313da15477eb18d90babb0890d10d98082John McCall // Build the message ref structure. 5612b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Constant *values[] = { fn, GetMethodVarName(selector) }; 5613c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(values); 5614b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef = new llvm::GlobalVariable(CGM.getModule(), 5615b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall init->getType(), 5616b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall /*constant*/ false, 5617b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::GlobalValue::WeakAnyLinkage, 5618b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall init, 5619b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName); 5620b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); 5621b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setAlignment(16); 5622b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setSection("__DATA, __objc_msgrefs, coalesced"); 562383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian } 5624b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Value *mref = 5625b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); 56266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5627944c84313da15477eb18d90babb0890d10d98082John McCall // Update the message ref argument. 5628b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args[1].RV = RValue::get(mref); 5629b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5630b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Load the function to call from the message ref table. 5631b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0); 5632b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall callee = CGF.Builder.CreateLoad(callee, "msgSend_fn"); 5633b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5634b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall bool variadic = method ? method->isVariadic() : false; 56352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *fnType = 5636b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CGF.getTypes().GetFunctionType(fnInfo, variadic); 5637b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall callee = CGF.Builder.CreateBitCast(callee, 5638b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::PointerType::getUnqual(fnType)); 5639b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5640cba681af356e24ec4335bcf2b6bb6515072ace99John McCall RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args); 5641cba681af356e24ec4335bcf2b6bb6515072ace99John McCall return nullReturn.complete(CGF, result, resultType); 56424655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian} 56434655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian 56444655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian/// Generate code for a message send expression in the nonfragile abi. 5645d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue 5646d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 5647ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 5648d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar QualType ResultType, 5649d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar Selector Sel, 5650d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar llvm::Value *Receiver, 5651d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 5652c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 5653d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 5654944c84313da15477eb18d90babb0890d10d98082John McCall return isVTableDispatchedSelector(Sel) 5655944c84313da15477eb18d90babb0890d10d98082John McCall ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 56566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Receiver, CGF.getContext().getObjCIdType(), 5657944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method) 5658944c84313da15477eb18d90babb0890d10d98082John McCall : EmitMessageSend(CGF, Return, ResultType, 5659944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 56606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Receiver, CGF.getContext().getObjCIdType(), 5661944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method, ObjCTypes); 56624655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian} 56634655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian 56645a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbarllvm::GlobalVariable * 56650f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz JahanianCGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 56665a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 56675a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 5668dfff23060b4a3add79a3bb68ccec606ade4f39bfDaniel Dunbar if (!GV) { 56696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, 56701c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson false, llvm::GlobalValue::ExternalLinkage, 56711c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson 0, Name); 56725a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar } 56735a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 56745a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar return GV; 56755a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar} 56765a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 5677f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder, 5678f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II) { 5679f85e193739c953358c865005855253af4f68a497John McCall llvm::GlobalVariable *&Entry = ClassReferences[II]; 5680f85e193739c953358c865005855253af4f68a497John McCall 56810e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian if (!Entry) { 5682f85e193739c953358c865005855253af4f68a497John McCall std::string ClassName(getClassSymbolPrefix() + II->getName().str()); 56835a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 56846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 5685f85e193739c953358c865005855253af4f68a497John McCall new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5686f85e193739c953358c865005855253af4f68a497John McCall false, llvm::GlobalValue::InternalLinkage, 5687f85e193739c953358c865005855253af4f68a497John McCall ClassGV, 5688f85e193739c953358c865005855253af4f68a497John McCall "\01L_OBJC_CLASSLIST_REFERENCES_$_"); 56890e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian Entry->setAlignment( 5690f85e193739c953358c865005855253af4f68a497John McCall CGM.getTargetData().getABITypeAlignment( 5691f85e193739c953358c865005855253af4f68a497John McCall ObjCTypes.ClassnfABIPtrTy)); 56921139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 5693ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 56941139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar } 5695f85e193739c953358c865005855253af4f68a497John McCall 5696578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 56971139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar} 56980e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 5699f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 5700f85e193739c953358c865005855253af4f68a497John McCall const ObjCInterfaceDecl *ID) { 5701f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, ID->getIdentifier()); 5702f85e193739c953358c865005855253af4f68a497John McCall} 5703f85e193739c953358c865005855253af4f68a497John McCall 5704f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef( 5705f85e193739c953358c865005855253af4f68a497John McCall CGBuilderTy &Builder) { 5706f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 5707f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, II); 5708f85e193739c953358c865005855253af4f68a497John McCall} 5709f85e193739c953358c865005855253af4f68a497John McCall 57101139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbarllvm::Value * 57116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 57121139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar const ObjCInterfaceDecl *ID) { 57131139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 57146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57151139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar if (!Entry) { 57161139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 57171139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 57186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 57196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 57201c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson false, llvm::GlobalValue::InternalLinkage, 57216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ClassGV, 57221c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 57231139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setAlignment( 57244b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment( 57256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ClassnfABIPtrTy)); 57261139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5727ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 57280e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian } 57296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5730578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 57310e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian} 57320e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 57337a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// EmitMetaClassRef - Return a Value * of the address of _class_t 57347a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// meta-data 57357a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// 57366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 57376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID) { 57387a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 57397a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian if (Entry) 5740578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 57416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57426ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 57430f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 57446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 57451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, 57467a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 57476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MetaClassGV, 57481c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 57497a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian Entry->setAlignment( 57504b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment( 57516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ClassnfABIPtrTy)); 57526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 575333af70f0f003d9765b92621f4fdd801e2b6c0ae7Daniel Dunbar Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5754ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 57556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5756578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 57577a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian} 57587a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian 57590e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// GetClass - Return a reference to the class for the given interface 57600e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// decl. 57610e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 57620e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian const ObjCInterfaceDecl *ID) { 57630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->isWeakImported()) { 5764269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5765269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5766269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5767269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian } 5768269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian 57690e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian return EmitClassRef(Builder, ID); 57700e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian} 57710e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 57727a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// Generates a message send where the super is the receiver. This is 57737a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// a message send to self with special delivery semantics indicating 57747a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// which class's method should be called. 57757a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCodeGen::RValue 57767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 5777ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 57786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar QualType ResultType, 57796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Selector Sel, 57806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *Class, 57816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool isCategoryImpl, 57826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *Receiver, 57836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool IsClassMessage, 5784d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CodeGen::CallArgList &CallArgs, 5785d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 57867a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // ... 57877a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // Create and init a super structure; this is a (receiver, class) 57887a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // pair we will pass to objc_msgSendSuper. 57897a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::Value *ObjCSuper = 5790604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 57916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57927a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::Value *ReceiverAsObject = 57937a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 57947a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStore(ReceiverAsObject, 57957a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 57966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57977a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // If this is a class message the metaclass is passed as the target. 57987ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *Target; 57997ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (IsClassMessage) { 58007ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (isCategoryImpl) { 58017ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // Message sent to "super' in a class method defined in 58027ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // a category implementation. 58031139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Target = EmitClassRef(CGF.Builder, Class); 58047ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateStructGEP(Target, 0); 58057ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateLoad(Target); 5806b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else 58077ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = EmitMetaClassRef(CGF.Builder, Class); 5808b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else 58091139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Target = EmitSuperClassRef(CGF.Builder, Class); 58106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5811f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 5812f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ObjCTypes types. 58132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ClassTy = 58147a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 58157a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian Target = CGF.Builder.CreateBitCast(Target, ClassTy); 58167a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStore(Target, 58177a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 58186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5819944c84313da15477eb18d90babb0890d10d98082John McCall return (isVTableDispatchedSelector(Sel)) 5820944c84313da15477eb18d90babb0890d10d98082John McCall ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 58216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCSuper, ObjCTypes.SuperPtrCTy, 5822944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method) 5823944c84313da15477eb18d90babb0890d10d98082John McCall : EmitMessageSend(CGF, Return, ResultType, 5824944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 58256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCSuper, ObjCTypes.SuperPtrCTy, 5826944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method, ObjCTypes); 58277a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian} 582826cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian 58296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 583003b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian Selector Sel, bool lval) { 583126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 58326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 583326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian if (!Entry) { 58346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 58356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 58366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.SelectorPtrTy); 58376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 58386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 58396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::InternalLinkage, 58406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); 5841d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 5842ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 584326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian } 58446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 584503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian if (lval) 584603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return Entry; 5847578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 584826cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian} 58496948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 58506c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t) 58516948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 58526948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 58531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, 58546c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *dst, 58556c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset) { 58562acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 58570a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 58589408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 58590a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 58600a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 58610a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 58623b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 58633b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 58646948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 58656948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 58666c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 58676c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian src, dst, ivarOffset); 58686948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 58696948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 58706948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 58716948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 58726948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst) 58736948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 58746948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 58756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 58761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 58772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 58780a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 58799408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 58800a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 58810a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 58826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 58833b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 58843b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 58856948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 58866948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5887bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 58886948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src, dst, "weakassign"); 58896948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 58906948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 58916948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 5892082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 58936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 58946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *DestPtr, 58956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *SrcPtr, 589655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *Size) { 5897082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 5898082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 5899082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 590055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian DestPtr, SrcPtr, Size); 5901082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return; 5902082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian} 5903082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian 59046948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak 59056948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// object: objc_read_weak (id *src) 59066948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 59076948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 59086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 59091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *AddrWeakObj) { 59102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type* DestTy = 59116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 59126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 591372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 59146948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian AddrWeakObj, "weakread"); 59158339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 59166948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return read_weak; 59176948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 59186948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 59196948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 59206948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_weak (id src, id *dst) 59216948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 59226948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 59231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 59242acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 59250a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 59269408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 59270a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 59280a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 59290a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 59303b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 59313b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 59326948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 59336948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 593496508e1fea58347b6401ca9a4728c0b268174603Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 59356948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src, dst, "weakassign"); 59366948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 59376948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 59386948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 59396948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 59406948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_global (id src, id *dst) 59416948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 59426948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 5943021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dst, 5944021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal) { 59452acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 59460a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 59479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 59480a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 59490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 59500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 59513b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 59523b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 59536948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 59546948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5955021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian if (!threadlocal) 5956021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 5957021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "globalassign"); 5958021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian else 5959021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 5960021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "threadlocalassign"); 59616948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 59626948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 596326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian 59646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid 5965f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 5966f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S) { 596705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall EmitAtSynchronizedStmt(CGF, S, 596805dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 596905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 5970f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 59714ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar 59725a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant * 5973cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz JahanianCGObjCNonFragileABIMac::GetEHType(QualType T) { 59745a180397870944548aaadeaebf58e415885b9489John McCall // There's a particular fixed type info for 'id'. 59755a180397870944548aaadeaebf58e415885b9489John McCall if (T->isObjCIdType() || 59765a180397870944548aaadeaebf58e415885b9489John McCall T->isObjCQualifiedIdType()) { 59775a180397870944548aaadeaebf58e415885b9489John McCall llvm::Constant *IDEHType = 59785a180397870944548aaadeaebf58e415885b9489John McCall CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 59795a180397870944548aaadeaebf58e415885b9489John McCall if (!IDEHType) 59805a180397870944548aaadeaebf58e415885b9489John McCall IDEHType = 59815a180397870944548aaadeaebf58e415885b9489John McCall new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 59825a180397870944548aaadeaebf58e415885b9489John McCall false, 59835a180397870944548aaadeaebf58e415885b9489John McCall llvm::GlobalValue::ExternalLinkage, 59845a180397870944548aaadeaebf58e415885b9489John McCall 0, "OBJC_EHTYPE_id"); 59855a180397870944548aaadeaebf58e415885b9489John McCall return IDEHType; 59865a180397870944548aaadeaebf58e415885b9489John McCall } 59875a180397870944548aaadeaebf58e415885b9489John McCall 59885a180397870944548aaadeaebf58e415885b9489John McCall // All other types should be Objective-C interface pointer types. 59895a180397870944548aaadeaebf58e415885b9489John McCall const ObjCObjectPointerType *PT = 59905a180397870944548aaadeaebf58e415885b9489John McCall T->getAs<ObjCObjectPointerType>(); 59915a180397870944548aaadeaebf58e415885b9489John McCall assert(PT && "Invalid @catch type."); 59925a180397870944548aaadeaebf58e415885b9489John McCall const ObjCInterfaceType *IT = PT->getInterfaceType(); 59935a180397870944548aaadeaebf58e415885b9489John McCall assert(IT && "Invalid @catch type."); 59945a180397870944548aaadeaebf58e415885b9489John McCall return GetInterfaceEHType(IT->getDecl(), false); 59955a180397870944548aaadeaebf58e415885b9489John McCall} 59965a180397870944548aaadeaebf58e415885b9489John McCall 5997f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 5998f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S) { 599905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall EmitTryCatchStmt(CGF, S, 600005dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 600105dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 600205dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 60038ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar} 60048ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar 6005f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson/// EmitThrowStmt - Generate code for a throw statement. 6006f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlssonvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 6007f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson const ObjCAtThrowStmt &S) { 6008f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson if (const Expr *ThrowExpr = S.getThrowExpr()) { 60092b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 6010578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 60114c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception) 60127ec404c40e42ce274d956a289ffa91e8f4befc43John McCall .setDoesNotReturn(); 6013f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 60144c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn()) 60157ec404c40e42ce274d956a289ffa91e8f4befc43John McCall .setDoesNotReturn(); 6016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 60174ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar 60187ec404c40e42ce274d956a289ffa91e8f4befc43John McCall CGF.Builder.CreateUnreachable(); 6019f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson CGF.Builder.ClearInsertionPoint(); 6020f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson} 6021e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 60225a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant * 60236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 60248158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar bool ForDefinition) { 6025e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 60267e075cb62c06e0b0023fd12875c95da9c5ddefb7Daniel Dunbar 60278158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // If we don't need a definition, return the entry if found or check 60288158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // if we use an external reference. 60298158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (!ForDefinition) { 60308158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (Entry) 60318158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return Entry; 60328158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 60338158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // If this type (or a super class) has the __objc_exception__ 60348158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // attribute, emit an external reference. 603568584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 60366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return Entry = 60371c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 60388158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 60396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 60409c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ("OBJC_EHTYPE_$_" + 604101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar ID->getIdentifier()->getName())); 60428158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 60436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 60448158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // Otherwise we need to either make a new entry or fill in the 60458158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // initializer. 60468158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 60476ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 6048e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar std::string VTableName = "objc_ehtype_vtable"; 60496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *VTableGV = 6050e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar CGM.getModule().getGlobalVariable(VTableName); 6051e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar if (!VTableGV) 60526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, 60536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 6054e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::GlobalValue::ExternalLinkage, 60551c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson 0, VTableName); 6056e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 605777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *VTableIdx = 605877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2); 6059e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 60601d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 60611d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx), 60621d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(ID->getIdentifier()), 60631d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassGlobal(ClassName) 60641d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 6065a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::Constant *Init = 606608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 6067e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 60688158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (Entry) { 60698158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setInitializer(Init); 60708158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } else { 60711c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 60728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar llvm::GlobalValue::WeakAnyLinkage, 60736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 60749c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ("OBJC_EHTYPE_$_" + 607501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar ID->getIdentifier()->getName())); 60768158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 60778158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 60781fb0caaa7bef765b85972274e3b434af2572c141John McCall if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility) 60796ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 60804b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar Entry->setAlignment(CGM.getTargetData().getABITypeAlignment( 60814b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar ObjCTypes.EHTypeTy)); 60828158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 60838158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (ForDefinition) { 60848158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setSection("__DATA,__objc_const"); 60858158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 60868158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } else { 60878158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setSection("__DATA,__datacoal_nt,coalesced"); 60888158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 6089e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 6090e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar return Entry; 6091e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar} 60926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6093bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** */ 6094bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 60956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CGObjCRuntime * 60966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 609760be607e5d71627bf3dab8f51c3fdca74267c692David Chisnall if (CGM.getLangOptions().ObjCNonFragileABI) 609860be607e5d71627bf3dab8f51c3fdca74267c692David Chisnall return new CGObjCNonFragileABIMac(CGM); 6099c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar return new CGObjCMac(CGM); 6100c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 6101