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 45c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarnamespace { 46bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// FIXME: We should find a nicer way to make the labels for metadata, string 486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// concatenation is lame. 496efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 50ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass ObjCCommonTypesHelper { 51a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonprotected: 52a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::LLVMContext &VMContext; 536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 54d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianprivate: 550774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // The types of these functions don't really matter because we 560774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // should always bitcast before calling them. 570774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall 580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSend (id, SEL, ...) 590774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The default messenger, used for sends whose ABI is unchanged from 610774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// the all-integer/pointer case. 62d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendFn() const { 63f85e193739c953358c865005855253af4f68a497John McCall // Add the non-lazy-bind attribute, since objc_msgSend is likely to 64f85e193739c953358c865005855253af4f68a497John McCall // be called a lot. 659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 670774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 68f85e193739c953358c865005855253af4f68a497John McCall "objc_msgSend", 69f85e193739c953358c865005855253af4f68a497John McCall llvm::Attribute::NonLazyBind); 70d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 720774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSend_stret (id, SEL, ...) 730774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used when the return value is an aggregate returned 750774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// by indirect reference in the first argument, and therefore the 760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// self and selector parameters are shifted over by one. 77d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendStretFn() const { 789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 790774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, 800774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 810774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSend_stret"); 826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 83d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 850774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 860774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used when the return value is returned on the x87 880774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// floating-point stack; without a special entrypoint, the nil case 890774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// would be unbalanced. 90d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendFpretFn() const { 919cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 928b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy, 938b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner params, true), 940774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSend_fpret"); 956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 96d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 98eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...) 99eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson /// 100eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson /// The messenger used when the return value is returned in two values on the 101eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson /// x87 floating point stack; without a special entrypoint, the nil case 102eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson /// would be unbalanced. Only used on 64-bit X86. 103eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Constant *getMessageSendFp2retFn() const { 104eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 105eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext); 106eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Type *resultType = 107eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::StructType::get(longDoubleType, longDoubleType, NULL); 108eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson 109eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType, 110eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson params, true), 111eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson "objc_msgSend_fp2ret"); 112eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson } 113eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson 1140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 1150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1160774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used for super calls, which have different dispatch 1170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// semantics. The class passed is the superclass of the current 1180774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// class. 119d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFn() const { 1209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 12196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 1230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSendSuper"); 124d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1260774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 1270774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1280774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// A slightly different messenger used for super calls. The class 1290774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// passed is the current class. 130d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFn2() const { 1319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy }; 13296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1330774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 1340774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall "objc_msgSendSuper2"); 135d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1370774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super, 1380774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// SEL op, ...) 1390774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1400774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// The messenger used for super calls which return an aggregate indirectly. 141d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperStretFn() const { 1429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 143a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 1440774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, true), 1456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_msgSendSuper_stret"); 146d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 1490774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// SEL op, ...) 1500774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// 1510774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall /// objc_msgSendSuper_stret with the super2 semantics. 152d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperStretFn2() const { 1539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy }; 154a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 1550774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, true), 1566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_msgSendSuper2_stret"); 157d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 159d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFpretFn() const { 160d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian // There is no objc_msgSendSuper_fpret? How can that work? 161d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return getMessageSendSuperFn(); 162d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 164d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getMessageSendSuperFpretFn2() const { 165d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian // There is no objc_msgSendSuper_fpret? How can that work? 166d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return getMessageSendSuperFn2(); 167d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 1686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 169ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected: 170ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian CodeGen::CodeGenModule &CGM; 1716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 172bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic: 1739cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 174dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::Type *Int8PtrTy, *Int8PtrPtrTy; 1756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1762bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 1779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ObjectPtrTy; 1786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1796d657c4809d9128be88705d32768de007b988212Fariborz Jahanian /// PtrObjectPtrTy - LLVM type for id * 1809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *PtrObjectPtrTy; 1816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1824e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 1839cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SelectorPtrTy; 1844c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor 1854c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregorprivate: 1866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolPtrTy - LLVM type for external protocol handles 1876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// (typeof(Protocol)) 1889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ExternalProtocolPtrTy; 1894c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor 1904c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregorpublic: 1914c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor llvm::Type *getExternalProtocolPtrTy() { 1924c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor if (!ExternalProtocolPtrTy) { 1934c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor // FIXME: It would be nice to unify this with the opaque type, so that the 1944c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor // IR comes out a bit cleaner. 1954c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor CodeGen::CodeGenTypes &Types = CGM.getTypes(); 1964c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor ASTContext &Ctx = CGM.getContext(); 1974c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 1984c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 1994c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor } 2004c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor 2014c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor return ExternalProtocolPtrTy; 2024c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor } 2034c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor 20419cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar // SuperCTy - clang type for struct objc_super. 20519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar QualType SuperCTy; 20619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar // SuperPtrCTy - clang type for struct objc_super *. 20719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar QualType SuperPtrCTy; 2086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 209e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar /// SuperTy - LLVM type for struct objc_super. 2109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SuperTy; 21114c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar /// SuperPtrTy - LLVM type for struct objc_super *. 2129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SuperPtrTy; 2136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 21430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 21530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// in GCC parlance). 2169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *PropertyTy; 2176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 21830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyListTy - LLVM type for struct objc_property_list 21930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// (_prop_list_t in GCC parlance). 2209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *PropertyListTy; 22130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 2229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *PropertyListPtrTy; 2236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 22430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // MethodTy - LLVM type for struct objc_method. 2259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodTy; 2266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 227d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian /// CacheTy - LLVM type for struct objc_cache. 2289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *CacheTy; 229d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian /// CachePtrTy - LLVM type for struct objc_cache *. 2309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *CachePtrTy; 2319d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 23272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getGetPropertyFn() { 23372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner CodeGen::CodeGenTypes &Types = CGM.getTypes(); 23472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner ASTContext &Ctx = CGM.getContext(); 23572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // id objc_getProperty (id, SEL, ptrdiff_t, bool) 2365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,4> Params; 237ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 238ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 23972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 24072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(SelType); 241ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 24272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 2432acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 2440f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params, 2450f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 2460f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All)); 24772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 24872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 2496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 25072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getSetPropertyFn() { 25172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner CodeGen::CodeGenTypes &Types = CGM.getTypes(); 25272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner ASTContext &Ctx = CGM.getContext(); 25372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 2545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,6> Params; 255ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 256ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 25772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 25872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(SelType); 259ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 26072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(IdType); 26172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 26272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner Params.push_back(Ctx.BoolTy); 2632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 2640f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params, 2650f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 2660f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All)); 26772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 26872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 2696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 270ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) { 271ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek CodeGen::CodeGenTypes &Types = CGM.getTypes(); 272ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ASTContext &Ctx = CGM.getContext(); 273ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // void objc_setProperty_atomic(id self, SEL _cmd, 274ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // id newValue, ptrdiff_t offset); 275ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // void objc_setProperty_nonatomic(id self, SEL _cmd, 276ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // id newValue, ptrdiff_t offset); 277ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // void objc_setProperty_atomic_copy(id self, SEL _cmd, 278ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // id newValue, ptrdiff_t offset); 279ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // void objc_setProperty_nonatomic_copy(id self, SEL _cmd, 280ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // id newValue, ptrdiff_t offset); 281ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 282ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SmallVector<CanQualType,4> Params; 283ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 284ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 285ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(IdType); 286ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(SelType); 287ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(IdType); 288ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); 289ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek llvm::FunctionType *FTy = 2900f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params, 2910f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 2920f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All)); 293ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek const char *name; 294ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (atomic && copy) 295ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek name = "objc_setProperty_atomic_copy"; 296ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else if (atomic && !copy) 297ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek name = "objc_setProperty_atomic"; 298ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else if (!atomic && copy) 299ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek name = "objc_setProperty_nonatomic_copy"; 300ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else 301ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek name = "objc_setProperty_nonatomic"; 302ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 303ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return CGM.CreateRuntimeFunction(FTy, name); 304ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 3056cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 3066cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian llvm::Constant *getCopyStructFn() { 3076cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian CodeGen::CodeGenTypes &Types = CGM.getTypes(); 3086cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian ASTContext &Ctx = CGM.getContext(); 3096cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian // void objc_copyStruct (void *, const void *, size_t, bool, bool) 3105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,5> Params; 3116cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 3126cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 3136cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.LongTy); 3146cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.BoolTy); 3156cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian Params.push_back(Ctx.BoolTy); 3162acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 3170f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params, 3180f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 3190f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All)); 3206cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); 3216cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian } 3226cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 323e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian /// This routine declares and returns address of: 324e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian /// void objc_copyCppObjectAtomic( 325e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian /// void *dest, const void *src, 326e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian /// void (*copyHelper) (void *dest, const void *source)); 327e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian llvm::Constant *getCppAtomicObjectFunction() { 328e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian CodeGen::CodeGenTypes &Types = CGM.getTypes(); 329e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian ASTContext &Ctx = CGM.getContext(); 330e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper); 331e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian SmallVector<CanQualType,3> Params; 332e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 333e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 334e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian Params.push_back(Ctx.VoidPtrTy); 335e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian llvm::FunctionType *FTy = 3360f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params, 3370f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 3380f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All)); 339e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic"); 340e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian } 341e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian 34272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getEnumerationMutationFn() { 343c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar CodeGen::CodeGenTypes &Types = CGM.getTypes(); 344c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar ASTContext &Ctx = CGM.getContext(); 34572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // void objc_enumerationMutation (id) 3465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CanQualType,1> Params; 347ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); 3482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 3490f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params, 350de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 351de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall RequiredArgs::All)); 35272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 35372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner } 3546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 355db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 35672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Constant *getGcReadWeakFn() { 35772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner // id objc_read_weak (id *) 3589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy->getPointerTo() }; 3596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::FunctionType *FTy = 3600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 36172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 3626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 3636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 364db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignWeakFn -- LLVM objc_assign_weak function. 36596508e1fea58347b6401ca9a4728c0b268174603Chris Lattner llvm::Constant *getGcAssignWeakFn() { 36696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner // id objc_assign_weak (id, id *) 3679cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 36896508e1fea58347b6401ca9a4728c0b268174603Chris Lattner llvm::FunctionType *FTy = 3690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 37096508e1fea58347b6401ca9a4728c0b268174603Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 37196508e1fea58347b6401ca9a4728c0b268174603Chris Lattner } 3726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 373db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignGlobalFn -- LLVM objc_assign_global function. 374bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignGlobalFn() { 375bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner // id objc_assign_global(id, id *) 3769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 377a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 3780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 379bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 380bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 3816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 382021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function. 383021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Constant *getGcAssignThreadLocalFn() { 384021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian // id objc_assign_threadlocal(id src, id * dest) 3859cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 386021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::FunctionType *FTy = 3870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 388021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal"); 389021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian } 390021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian 391db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 392bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignIvarFn() { 3936c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian // id objc_assign_ivar(id, id *, ptrdiff_t) 3949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(), 3959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CGM.PtrDiffTy }; 396a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 3970774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 398bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 399bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 4006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 401082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function. 402082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Constant *GcMemmoveCollectableFn() { 403082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian // void *objc_memmove_collectable(void *dst, const void *src, size_t size) 4049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy }; 4050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false); 406082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 407082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian } 4086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 409db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 410bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getGcAssignStrongCastFn() { 411021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian // id objc_assign_strongCast(id, id *) 4129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() }; 413a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::FunctionType *FTy = 4140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(ObjectPtrTy, args, false); 415bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 416bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 417f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson 418f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson /// ExceptionThrowFn - LLVM objc_exception_throw function. 419bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getExceptionThrowFn() { 420bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner // void objc_exception_throw(id) 4219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 422bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::FunctionType *FTy = 4230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, args, false); 424bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 425bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 4266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 42769677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian /// ExceptionRethrowFn - LLVM objc_exception_rethrow function. 42869677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian llvm::Constant *getExceptionRethrowFn() { 42969677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian // void objc_exception_rethrow(void) 4300774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false); 43169677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow"); 43269677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian } 43369677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian 4341c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar /// SyncEnterFn - LLVM object_sync_enter function. 435b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner llvm::Constant *getSyncEnterFn() { 4362d234d73f687428c89f8a99af94f123012f05551Aaron Ballman // int objc_sync_enter (id) 4379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 438b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner llvm::FunctionType *FTy = 4392d234d73f687428c89f8a99af94f123012f05551Aaron Ballman llvm::FunctionType::get(CGM.IntTy, args, false); 440b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 441b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner } 4426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4431c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar /// SyncExitFn - LLVM object_sync_exit function. 444bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::Constant *getSyncExitFn() { 4452d234d73f687428c89f8a99af94f123012f05551Aaron Ballman // int objc_sync_exit (id) 4469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *args[] = { ObjectPtrTy }; 447bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner llvm::FunctionType *FTy = 4482d234d73f687428c89f8a99af94f123012f05551Aaron Ballman llvm::FunctionType::get(CGM.IntTy, args, false); 449bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 450bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner } 4516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 452d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFn(bool IsSuper) const { 453d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 4544176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 456d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFn2(bool IsSuper) const { 457d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 4584176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 460d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendStretFn(bool IsSuper) const { 461d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 4624176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 464d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendStretFn2(bool IsSuper) const { 465d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 4664176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 468d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFpretFn(bool IsSuper) const { 469d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 4704176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 472d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *getSendFpretFn2(bool IsSuper) const { 473d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 4744176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner } 4756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 476eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Constant *getSendFp2retFn(bool IsSuper) const { 477eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn(); 478eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson } 479eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson 480eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson llvm::Constant *getSendFp2RetFn2(bool IsSuper) const { 481eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn(); 482eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson } 483eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson 484d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 485d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian ~ObjCCommonTypesHelper(){} 486d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian}; 487ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian 488d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// ObjCTypesHelper - Helper class that encapsulates lazy 489d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// construction of varies types used during ObjC generation. 490d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianclass ObjCTypesHelper : public ObjCCommonTypesHelper { 491ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 4924e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// SymtabTy - LLVM type for struct objc_symtab. 4939cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SymtabTy; 49427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// SymtabPtrTy - LLVM type for struct objc_symtab *. 4959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SymtabPtrTy; 4964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// ModuleTy - LLVM type for struct objc_module. 4979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ModuleTy; 498259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 4996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolTy - LLVM type for struct objc_protocol. 5009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolTy; 5016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 5029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolPtrTy; 5036efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionTy - LLVM type for struct 5046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_protocol_extension. 5059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolExtensionTy; 5066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionTy - LLVM type for struct 5076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_protocol_extension *. 5089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolExtensionPtrTy; 5096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionTy - LLVM type for struct 5106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description. 5119cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodDescriptionTy; 5126efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionListTy - LLVM type for struct 5136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description_list. 5149cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodDescriptionListTy; 5156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodDescriptionListPtrTy - LLVM type for struct 5166efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// objc_method_description_list *. 5179cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodDescriptionListPtrTy; 5186efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolListTy - LLVM type for struct objc_property_list. 5199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolListTy; 5206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 5219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolListPtrTy; 52286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar /// CategoryTy - LLVM type for struct objc_category. 5239cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *CategoryTy; 52427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassTy - LLVM type for struct objc_class. 5259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassTy; 52627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassPtrTy - LLVM type for struct objc_class *. 5279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassPtrTy; 52827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassExtensionTy - LLVM type for struct objc_class_ext. 5299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassExtensionTy; 53027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 5319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassExtensionPtrTy; 53227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // IvarTy - LLVM type for struct objc_ivar. 5339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarTy; 53427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListTy - LLVM type for struct objc_ivar_list. 5359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListTy; 53627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 5379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListPtrTy; 53827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// MethodListTy - LLVM type for struct objc_method_list. 5399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListTy; 54027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// MethodListPtrTy - LLVM type for struct objc_method_list *. 5419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListPtrTy; 5426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 543124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 5449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ExceptionDataTy; 5459d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 546124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 54734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionTryEnterFn() { 5489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 549a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 5500774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, false), 5516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_try_enter"); 55234b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 553124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 554124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 55534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionTryExitFn() { 5569cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 557a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return CGM.CreateRuntimeFunction( 5580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.VoidTy, params, false), 5596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_try_exit"); 56034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 561124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 562124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionExtractFn - LLVM objc_exception_extract function. 56334b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionExtractFn() { 5649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; 56596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 5660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 56734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner "objc_exception_extract"); 56834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 5696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 570124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// ExceptionMatchFn - LLVM objc_exception_match function. 57134b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getExceptionMatchFn() { 5729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy }; 5736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return CGM.CreateRuntimeFunction( 5740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall llvm::FunctionType::get(CGM.Int32Ty, params, false), 5756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "objc_exception_match"); 5766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 57734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 5786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 579124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson /// SetJmpFn - LLVM _setjmp function. 58034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner llvm::Constant *getSetJmpFn() { 5810774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // This is specifically the prototype for x86. 5829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() }; 5830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, 5840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 585a9e269e661ca7def681b69f2b88acf0c1fa3e654Bill Wendling "_setjmp", 586a9e269e661ca7def681b69f2b88acf0c1fa3e654Bill Wendling llvm::Attribute::ReturnsTwice); 58734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner } 5886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 589bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic: 590bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 591ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ~ObjCTypesHelper() {} 592bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}; 593bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 59430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 595ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian/// modern abi 59630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 59783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanianpublic: 5986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 599d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // MethodListnfABITy - LLVM for struct _method_list_t 6009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MethodListnfABITy; 6016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 602d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 6039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MethodListnfABIPtrTy; 6046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 605d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolnfABITy = LLVM for struct _protocol_t 6069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolnfABITy; 6076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 608948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 6099cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolnfABIPtrTy; 610948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 611d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 6129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ProtocolListnfABITy; 6136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 614d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 6159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ProtocolListnfABIPtrTy; 6166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 617d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ClassnfABITy - LLVM for struct _class_t 6189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassnfABITy; 6196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 620aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // ClassnfABIPtrTy - LLVM for struct _class_t* 6219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ClassnfABIPtrTy; 6226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 623d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarnfABITy - LLVM for struct _ivar_t 6249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarnfABITy; 6256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 626d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarListnfABITy - LLVM for struct _ivar_list_t 6279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *IvarListnfABITy; 6286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 629d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 6309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IvarListnfABIPtrTy; 6316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 632d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ClassRonfABITy - LLVM for struct _class_ro_t 6339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ClassRonfABITy; 6346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 635d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 6369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ImpnfABITy; 6376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 638d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // CategorynfABITy - LLVM for struct _category_t 6399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *CategorynfABITy; 6406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6412e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // New types for nonfragile abi messaging. 6426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6432e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefTy - LLVM for: 6442e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _message_ref_t { 6452e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // IMP messenger; 6462e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 6472e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 6489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *MessageRefTy; 64983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // MessageRefCTy - clang type for struct _message_ref_t 65083a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian QualType MessageRefCTy; 6516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6522e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefPtrTy - LLVM for struct _message_ref_t* 6539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *MessageRefPtrTy; 65483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // MessageRefCPtrTy - clang type for struct _message_ref_t* 65583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian QualType MessageRefCPtrTy; 6566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 657ef163782d227f064df5988d46487609324a0169eFariborz Jahanian // MessengerTy - Type of the messenger (shown as IMP above) 6589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::FunctionType *MessengerTy; 6596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6602e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefTy - LLVM for: 6612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _super_message_ref_t { 6622e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SUPER_IMP messenger; 6632e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 6642e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 6659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *SuperMessageRefTy; 6666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6672e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 6689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *SuperMessageRefPtrTy; 6698ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar 6701c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendFixupFn() { 6711c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 6729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 67396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6751c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_fixup"); 6761c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6781c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendFpretFixupFn() { 6791c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 6809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 68196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6820774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6831c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_fpret_fixup"); 6841c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6861c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendStretFixupFn() { 6871c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 6889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy }; 68996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6900774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 6911c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSend_stret_fixup"); 6921c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 6936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6941c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendSuper2FixupFn() { 6956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // id objc_msgSendSuper2_fixup (struct objc_super *, 6961c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // struct _super_message_ref_t*, ...) 6979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 69896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 6990774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 7001c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSendSuper2_fixup"); 7011c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 7026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7031c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner llvm::Constant *getMessageSendSuper2StretFixupFn() { 7046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 7051c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner // struct _super_message_ref_t*, ...) 7069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy }; 70796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 7080774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, true), 7091c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner "objc_msgSendSuper2_stret_fixup"); 7101c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner } 7116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7128a56911956aa875922a5faa3787c6829e7f7011fChris Lattner llvm::Constant *getObjCEndCatchFn() { 7130774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false), 7148a56911956aa875922a5faa3787c6829e7f7011fChris Lattner "objc_end_catch"); 7156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7168a56911956aa875922a5faa3787c6829e7f7011fChris Lattner } 7176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7188a56911956aa875922a5faa3787c6829e7f7011fChris Lattner llvm::Constant *getObjCBeginCatchFn() { 7199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { Int8PtrTy }; 72096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 7210774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall params, false), 7228a56911956aa875922a5faa3787c6829e7f7011fChris Lattner "objc_begin_catch"); 7238a56911956aa875922a5faa3787c6829e7f7011fChris Lattner } 724e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 7259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *EHTypeTy; 7269cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *EHTypePtrTy; 7279d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 72830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 72930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ~ObjCNonFragileABITypesHelper(){} 730ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 7316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 732ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCCommonMac : public CodeGen::CGObjCRuntime { 7339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanianpublic: 7349397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // FIXME - accessibility 735a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian class GC_IVAR { 736820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian public: 7378b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned ivar_bytepos; 7388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned ivar_size; 7398b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 7406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ivar_bytepos(bytepos), ivar_size(size) {} 7410941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar 7420941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar // Allow sorting based on byte pos. 7430941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar bool operator<(const GC_IVAR &b) const { 7440941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar return ivar_bytepos < b.ivar_bytepos; 7450941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar } 746a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian }; 7476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7489397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian class SKIP_SCAN { 7498b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar public: 7508b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned skip; 7518b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned scan; 7526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 7538b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar : skip(_skip), scan(_scan) {} 7549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian }; 7556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 756ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected: 75769243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson llvm::LLVMContext &VMContext; 758ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME! May not be needing this after all. 759bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned ObjCABI; 7606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7619397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // gc ivar layout bitmap calculation helper caches. 7625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<GC_IVAR, 16> SkipIvars; 7635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<GC_IVAR, 16> IvarsInfo; 7646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 765242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// LazySymbols - Symbols to generate a lazy reference for. See 766242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// DefinedSymbols and FinishModule(). 767330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::SetVector<IdentifierInfo*> LazySymbols; 7686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 769242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// DefinedSymbols - External symbols which are defined by this 770242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// module. The symbols in this list and LazySymbols are used to add 771242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// special linker symbols which ensure that Objective-C modules are 772242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar /// linked properly. 773330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::SetVector<IdentifierInfo*> DefinedSymbols; 7746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 7754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// ClassNames - uniqued class names. 7766efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 7776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 778259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar /// MethodVarNames - uniqued method variable names. 779259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 7806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 781b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian /// DefinedCategoryNames - list of category names in form Class_Category. 782b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian llvm::SetVector<std::string> DefinedCategoryNames; 783b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian 7846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// MethodVarTypes - uniqued method type signatures. We have to use 7856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// a StringMap here because have no other unique reference. 7866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 7876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 788c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar /// MethodDefinitions - map of methods which have been defined in 789c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar /// this translation unit. 790c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 7916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 792c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar /// PropertyNames - uniqued method variable names. 793c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 7946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 79527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// ClassReferences - uniqued class references. 79627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 7976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 798259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar /// SelectorReferences - uniqued selector references. 799259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 8006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 8016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// Protocols - Protocols for which an objc_protocol structure has 8026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// been emitted. Forward declarations are handled by creating an 8036efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// empty structure whose initializer is filled in when/if defined. 8046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 8056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 8060c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// DefinedProtocols - Protocols which have actually been 8070c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// defined. We should not need this, see FIXME in GenerateProtocol. 8080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 8096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 81027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// DefinedClasses - List of defined classes. 8111e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling llvm::SmallVector<llvm::GlobalValue*, 16> DefinedClasses; 81274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 81374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 8141e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses; 8156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 81627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// DefinedCategories - List of defined categories. 8171e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling llvm::SmallVector<llvm::GlobalValue*, 16> DefinedCategories; 8186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 81974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 8201e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories; 8216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 82256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetNameForMethod - Return a name for the given method. 82356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// \param[out] NameOut - The return value. 82456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian void GetNameForMethod(const ObjCMethodDecl *OMD, 82556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const ObjCContainerDecl *CD, 8265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> &NameOut); 8276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 82856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetMethodVarName - Return a unique constant for the given 82956210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// selector's name. The return value has type char *. 83056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetMethodVarName(Selector Sel); 83156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 8326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 83356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetMethodVarType - Return a unique constant for the given 834dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson /// method's type encoding string. The return value has type char *. 8356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 83656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian // FIXME: This is a horrible name. 837dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D, 838dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson bool Extended = false); 8393e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar llvm::Constant *GetMethodVarType(const FieldDecl *D); 8406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 84156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// GetPropertyName - Return a unique constant for the given 84256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian /// name. The return value has type char *. 84356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 8446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 84556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian // FIXME: This can be dropped once string functions are unified. 84656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 84756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const Decl *Container); 8486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 849058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian /// GetClassName - Return a unique constant for the given selector's 850058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian /// name. The return value has type char *. 851058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::Constant *GetClassName(IdentifierInfo *Ident); 8526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 8539d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD); 8549d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 855d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// BuildIvarLayout - Builds ivar layout bitmap for the class 856d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// implementation for the __strong or __weak case. 857d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian /// 858c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 859c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian bool ForStrongLayout); 86093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 861b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); 8626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 863d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar void BuildAggrIvarRecordLayout(const RecordType *RT, 8646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, bool ForStrongLayout, 8656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool &HasUnion); 8665a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbar void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 867c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian const llvm::StructLayout *Layout, 868a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian const RecordDecl *RD, 869795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling ArrayRef<const FieldDecl*> RecFields, 870d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian unsigned int BytePos, bool ForStrongLayout, 87181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian bool &HasUnion); 872c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian 873d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian /// GetIvarLayoutName - Returns a unique constant for the given 874d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian /// ivar layout bitmap. 875d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 876d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes); 8776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 8785de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian /// EmitPropertyList - Emit the given property list. The return 8795de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian /// value has type PropertyListPtrTy. 8805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitPropertyList(Twine Name, 8816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container, 8825de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian const ObjCContainerDecl *OCD, 8835de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian const ObjCCommonTypesHelper &ObjCTypes); 8846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 885dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson /// EmitProtocolMethodTypes - Generate the array of extended method type 886dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson /// strings. The return value has type Int8PtrPtrTy. 887dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::Constant *EmitProtocolMethodTypes(Twine Name, 888bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> MethodTypes, 889dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson const ObjCCommonTypesHelper &ObjCTypes); 890dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 891191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian /// PushProtocolProperties - Push protocol's property on the input stack. 8923964e62786b0912fecc82d776daac236e05fc792Bill Wendling void PushProtocolProperties( 8933964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 8943964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVectorImpl<llvm::Constant*> &Properties, 8953964e62786b0912fecc82d776daac236e05fc792Bill Wendling const Decl *Container, 8963964e62786b0912fecc82d776daac236e05fc792Bill Wendling const ObjCProtocolDecl *PROTO, 8973964e62786b0912fecc82d776daac236e05fc792Bill Wendling const ObjCCommonTypesHelper &ObjCTypes); 898191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian 899da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetProtocolRef - Return a reference to the internal protocol 900da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// description, creating an empty one if it has not been 901da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// defined. The return value has type ProtocolPtrTy. 902da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 903b21f07e056b6c9918bf938f19ca561c60f778695Fariborz Jahanian 904fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// CreateMetadataVar - Create a global variable with internal 905fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// linkage for use by the Objective-C runtime. 906fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// 907fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// This is a convenience wrapper which not only creates the 908fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar /// variable, but also sets the section and alignment and adds the 909ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner /// global to the "llvm.used" list. 91035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// 91135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Name - The variable name. 91235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Init - The variable initializer; this is also used to 91335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// define the type of the variable. 91435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Section - The section the variable should go into, or 0. 91535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param Align - The alignment for the variable, or 0. 91635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar /// \param AddToUsed - Whether the variable should be added to 917c15830694f2bd01080e6c39a88c5b8ff2288af18Daniel Dunbar /// "llvm.used". 9185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::GlobalVariable *CreateMetadataVar(Twine Name, 919fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar llvm::Constant *Init, 920fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar const char *Section, 92135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar unsigned Align, 92235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar bool AddToUsed); 923fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar 924944c84313da15477eb18d90babb0890d10d98082John McCall CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 925944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 926944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 927944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Sel, 928944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Arg0, 929944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 930944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 931944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 932944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *OMD, 933944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCCommonTypesHelper &ObjCTypes); 9343e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar 935fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar /// EmitImageInfo - Emit the image info marker used to encode some module 936fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar /// level information. 937fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar void EmitImageInfo(); 938fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar 939ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 94069243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : 941de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { } 9426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 9430d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); 944ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 945493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 946493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian const ObjCContainerDecl *CD=0); 9476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 948da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 9496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 950da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocol - Get the protocol object for the given 951da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// declaration, emitting it if necessary. The return value has type 952da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// ProtocolPtrTy. 953da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 9546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 955da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocolRef - Get a forward reference to the protocol 956da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// object for the given declaration, emitting it if needed. These 957da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// forward references will be filled in with empty bodies if no 958da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// definition is seen. The return value has type ProtocolPtrTy. 959da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 9606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, 9616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo); 96289ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian 963ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 9646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 965ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCMac : public CGObjCCommonMac { 966ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate: 967ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCTypesHelper ObjCTypes; 968f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 9694e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar /// EmitModuleInfo - Another marker encoding module level 9706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar /// information. 9714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar void EmitModuleInfo(); 9724e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 97327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitModuleSymols - Emit module symbols, the list of defined 97427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// classes and categories. The result has type SymtabPtrTy. 9754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar llvm::Constant *EmitModuleSymbols(); 9764e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 977f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar /// FinishModule - Write out global data structures at the end of 978f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar /// processing a translation unit. 979f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar void FinishModule(); 9806efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 98127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitClassExtension - Generate the class extension structure used 98227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// to store the weak ivar layout and properties. The return value 98327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// has type ClassExtensionPtrTy. 98427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 98527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 98627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 98727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// for the given class. 9886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitClassRef(CGBuilderTy &Builder, 98927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID); 990b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 991f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 992f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II); 993f85e193739c953358c865005855253af4f68a497John McCall 994f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 995f85e193739c953358c865005855253af4f68a497John McCall 996b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian /// EmitSuperClassRef - Emits reference to class's main metadata class. 997b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID); 99827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 99927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitIvarList - Emit the ivar list for the given 100027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// implementation. If ForClass is true the list of class ivars 100127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// (i.e. metaclass ivars) is emitted, otherwise the list of 100227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// interface ivars will be emitted. The return value has type 100327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// IvarListPtrTy. 100427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 100546b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian bool ForClass); 10066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1007f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// EmitMetaClass - Emit a forward reference to the class structure 1008f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// for the metaclass of the given interface. The return value has 1009f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// type ClassPtrTy. 1010f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 1011f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 101227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMetaClass - Emit a class structure for the metaclass of the 1013f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar /// given implementation. The return value has type ClassPtrTy. 101427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 101527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *Protocols, 1016bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods); 10176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1018ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 10196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1020ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 102127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 102227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMethodList - Emit the method list for the given 1023af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar /// implementation. The return value has type MethodListPtrTy. 10245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodList(Twine Name, 102586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar const char *Section, 1026bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods); 102727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 102827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitMethodDescList - Emit a method description list for a list of 10296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar /// method declarations. 10306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - TypeName: The name for the type containing the methods. 10316efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - IsProtocol: True iff these methods are for a protocol. 10326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - ClassMethds: True iff these are class methods. 10336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - Required: When true, only "required" methods are 10346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// listed. Similarly, when false only "optional" methods are 10356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// listed. For classes this should always be true. 10366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// - begin, end: The method list to output. 10376efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// 10386efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// The return value has type MethodDescriptionListPtrTy. 10395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodDescList(Twine Name, 1040ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar const char *Section, 1041bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods); 10426efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 10430c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// GetOrEmitProtocol - Get the protocol object for the given 10440c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// declaration, emitting it if necessary. The return value has type 10450c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// ProtocolPtrTy. 1046da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 10470c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 10480c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// GetOrEmitProtocolRef - Get a forward reference to the protocol 10490c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// object for the given declaration, emitting it if needed. These 10500c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// forward references will be filled in with empty bodies if no 10510c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar /// definition is seen. The return value has type ProtocolPtrTy. 1052da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 10530c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 10546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// EmitProtocolExtension - Generate the protocol extension 10556efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// structure used to store optional instance and class methods, and 10566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// protocol properties. The return value has type 10576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// ProtocolExtensionPtrTy. 1058ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant * 1059ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar EmitProtocolExtension(const ObjCProtocolDecl *PD, 1060bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> OptInstanceMethods, 1061bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> OptClassMethods, 1062bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> MethodTypesExt); 10636efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 10646efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// EmitProtocolList - Generate the list of referenced 10656efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar /// protocols. The return value has type ProtocolListPtrTy. 10665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitProtocolList(Twine Name, 1067dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 1068dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator end); 10696efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 107027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 107127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar /// for the given selector. 107203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 107303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval=false); 10746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 10756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarpublic: 1076c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar CGObjCMac(CodeGen::CodeGenModule &cgm); 1077c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1078aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Function *ModuleInitFunction(); 10796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 10808f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1081ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 10827f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 10837f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1084f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 1085df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 1086c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 1087df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 10888f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar 10896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual CodeGen::RValue 10908f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1091ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 10927f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 10937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1094f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar const ObjCInterfaceDecl *Class, 10957ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 1096f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 109719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar bool IsClassMessage, 1098d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 1099d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method); 11006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 110145d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar virtual llvm::Value *GetClass(CGBuilderTy &Builder, 110227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID); 1103c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 110403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 110503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval = false); 1106df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1107df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1108df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// untyped one. 1109df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1110df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 1111df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1112cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian virtual llvm::Constant *GetEHType(QualType T); 11135a180397870944548aaadeaebf58e415885b9489John McCall 11147ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 11157ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar 11167ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1117c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 111885fdea03687e45dfde025867fe98ea24ac74c501Daniel Dunbar virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {} 111929254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall 112045d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1121af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar const ObjCProtocolDecl *PD); 11226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 112374391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *GetPropertyGetFunction(); 112474391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *GetPropertySetFunction(); 1125ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 1126ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool copy); 11278fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetGetStructFunction(); 11288fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetSetStructFunction(); 1129e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian virtual llvm::Constant *GetCppAtomicObjectFunction(); 113074391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *EnumerationMutationFunction(); 11316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1133f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S); 1134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S); 1136f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S); 113764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 113864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson const ObjCAtThrowStmt &S); 11393e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 11406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *AddrWeakObj); 11413e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 11426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *src, llvm::Value *dst); 114358626500527695865683d1d65053743de8770b60Fariborz Jahanian virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1144021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dest, 1145021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal = false); 11467eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 11476c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dest, 11486c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset); 114958626500527695865683d1d65053743de8770b60Fariborz Jahanian virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 115058626500527695865683d1d65053743de8770b60Fariborz Jahanian llvm::Value *src, llvm::Value *dest); 1151082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1152082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Value *dest, llvm::Value *src, 115355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size); 11546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1155598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1156598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 1157598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 1158598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 1159598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers); 1160f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 11612a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 1162f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar); 11636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 11646f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian /// GetClassGlobal - Return the global variable for the Objective-C 11656f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian /// class of the given name. 11666f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { 1167b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("CGObjCMac::GetClassGlobal"); 11686f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian } 1169c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}; 11706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 117130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass CGObjCNonFragileABIMac : public CGObjCCommonMac { 1172ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate: 117330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian ObjCNonFragileABITypesHelper ObjCTypes; 1174aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::GlobalVariable* ObjCEmptyCacheVar; 1175aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::GlobalVariable* ObjCEmptyVtableVar; 11766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 11771139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// SuperClassReferences - uniqued super class references. 11781139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 11796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 11807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// MetaClassReferences - uniqued meta class references. 11817a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 1182e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 1183e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar /// EHTypeReferences - uniqued class ehtype references. 1184e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 11856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1186944c84313da15477eb18d90babb0890d10d98082John McCall /// VTableDispatchMethods - List of methods for which we generate 1187944c84313da15477eb18d90babb0890d10d98082John McCall /// vtable-based message dispatch. 1188944c84313da15477eb18d90babb0890d10d98082John McCall llvm::DenseSet<Selector> VTableDispatchMethods; 11896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1190a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian /// DefinedMetaClasses - List of defined meta-classes. 1191a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian std::vector<llvm::GlobalValue*> DefinedMetaClasses; 1192a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 1193944c84313da15477eb18d90babb0890d10d98082John McCall /// isVTableDispatchedSelector - Returns true if SEL is a 1194944c84313da15477eb18d90babb0890d10d98082John McCall /// vtable-based selector. 1195944c84313da15477eb18d90babb0890d10d98082John McCall bool isVTableDispatchedSelector(Selector Sel); 11966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1197aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian /// FinishNonFragileABIModule - Write out global data structures at the end of 1198aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian /// processing a translation unit. 1199aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian void FinishNonFragileABIModule(); 12008158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 1201463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar /// AddModuleClassList - Add the given list of class pointers to the 1202463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar /// module with the provided symbol and section names. 1203bb02855f46423d2034918b75b157f886bb04bcccBill Wendling void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, 1204463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SymbolName, 1205463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar const char *SectionName); 1206463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar 12076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 12086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceStart, 12096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceSize, 12106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID); 121184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 12126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *IsAGV, 121384394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian llvm::Constant *SuperClassGV, 1214cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian llvm::Constant *ClassRoGV, 1215cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian bool HiddenVisibility); 12166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1217493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 12186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12193819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 12206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1221493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian /// EmitMethodList - Emit the method list for the given 1222493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian /// implementation. The return value has type MethodListnfABITy. 12235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitMethodList(Twine Name, 1224493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian const char *Section, 1225bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods); 122698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// EmitIvarList - Emit the ivar list for the given 122798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// implementation. If ForClass is true the list of class ivars 122898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// (i.e. metaclass ivars) is emitted, otherwise the list of 122998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// interface ivars will be emitted. The return value has type 123098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian /// IvarListnfABIPtrTy. 123198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 12326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1233ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 12342fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian const ObjCIvarDecl *Ivar, 12351bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian unsigned long int offset); 12366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1237da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocol - Get the protocol object for the given 1238da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// declaration, emitting it if necessary. The return value has type 1239da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// ProtocolPtrTy. 1240da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 12416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1242da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1243da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// object for the given declaration, emitting it if needed. These 1244da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// forward references will be filled in with empty bodies if no 1245da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// definition is seen. The return value has type ProtocolPtrTy. 1246da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 12476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1248da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// EmitProtocolList - Generate the list of referenced 1249da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian /// protocols. The return value has type ProtocolListPtrTy. 12505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Constant *EmitProtocolList(Twine Name, 1251da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCProtocolDecl::protocol_iterator begin, 12524655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian ObjCProtocolDecl::protocol_iterator end); 12536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1254944c84313da15477eb18d90babb0890d10d98082John McCall CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF, 1255944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 1256944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 1257944c84313da15477eb18d90babb0890d10d98082John McCall Selector Sel, 1258944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Receiver, 1259944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 1260944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 1261944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 1262944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *Method); 12636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 12645a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar /// GetClassGlobal - Return the global variable for the Objective-C 12655a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar /// class of the given name. 12660f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 12676f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian 12680e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 12691139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// for the given class reference. 12706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitClassRef(CGBuilderTy &Builder, 12711139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar const ObjCInterfaceDecl *ID); 1272f85e193739c953358c865005855253af4f68a497John McCall 1273f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder, 1274f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II); 1275f85e193739c953358c865005855253af4f68a497John McCall 1276f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder); 12776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12781139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 12791139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar /// for the given super class reference. 12806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 12816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID); 12826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 12837a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// EmitMetaClassRef - Return a Value * of the address of _class_t 12847a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian /// meta-data 12856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 12867a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian const ObjCInterfaceDecl *ID); 12877a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian 1288ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 1289ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// the given ivar. 1290ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian /// 12915e88beaa0a86b162dfb9f53891adfdfbe925cc64Daniel Dunbar llvm::GlobalVariable * ObjCIvarOffsetVariable( 12926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID, 12936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCIvarDecl *Ivar); 12946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 129526cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 129626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian /// for the given selector. 129703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 129803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval=false); 1299e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 13008158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 1301e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar /// interface. The return value has type EHTypePtrTy. 13025a180397870944548aaadeaebf58e415885b9489John McCall llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 13038158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar bool ForDefinition); 13046ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 13056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *getMetaclassSymbolPrefix() const { 13066ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar return "OBJC_METACLASS_$_"; 13076ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar } 13086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 13096ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar const char *getClassSymbolPrefix() const { 13106ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar return "OBJC_CLASS_$_"; 13116ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar } 13126ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 13139f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar void GetClassSizeInfo(const ObjCImplementationDecl *OID, 1314b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceStart, 1315b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceSize); 13166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 13174523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian // Shamelessly stolen from Analysis/CFRefCount.cpp 131874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar Selector GetNullarySelector(const char* name) const { 13194523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian IdentifierInfo* II = &CGM.getContext().Idents.get(name); 13204523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian return CGM.getContext().Selectors.getSelector(0, &II); 13214523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian } 13226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 132374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar Selector GetUnarySelector(const char* name) const { 13244523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian IdentifierInfo* II = &CGM.getContext().Idents.get(name); 13254523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian return CGM.getContext().Selectors.getSelector(1, &II); 13264523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian } 1327b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar 132874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// ImplementationIsNonLazy - Check whether the given category or 132974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar /// class implementation is "non-lazy". 1330ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz Jahanian bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 133174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 1332ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic: 133330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 1334aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // FIXME. All stubs for now! 1335aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Function *ModuleInitFunction(); 13366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1337aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1338ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 1339aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian QualType ResultType, 1340aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian Selector Sel, 1341aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::Value *Receiver, 1342df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 1343c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 1344df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method); 13456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 13466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual CodeGen::RValue 1347aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1348ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 1349aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian QualType ResultType, 1350aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian Selector Sel, 1351aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian const ObjCInterfaceDecl *Class, 13527ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 1353aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian llvm::Value *Receiver, 1354aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian bool IsClassMessage, 1355d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 1356d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method); 13576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1358aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value *GetClass(CGBuilderTy &Builder, 13590e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian const ObjCInterfaceDecl *ID); 13606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 136103b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 136203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lvalue = false) 136303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian { return EmitSelector(Builder, Sel, lvalue); } 1364df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian 1365df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1366df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian /// untyped one. 1367df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1368df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method) 1369df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian { return EmitSelector(Builder, Method->getSelector()); } 13706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1371eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 13726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1373aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 137429254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall 137585fdea03687e45dfde025867fe98ea24ac74c501Daniel Dunbar virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {} 137629254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall 1377aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 13788cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian const ObjCProtocolDecl *PD); 13796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1380cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian virtual llvm::Constant *GetEHType(QualType T); 13815a180397870944548aaadeaebf58e415885b9489John McCall 13826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual llvm::Constant *GetPropertyGetFunction() { 138372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getGetPropertyFn(); 1384f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian } 13856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar virtual llvm::Constant *GetPropertySetFunction() { 13866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return ObjCTypes.getSetPropertyFn(); 1387f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian } 13886cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 1389ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 1390ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool copy) { 1391ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy); 1392ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1393ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 13948fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetSetStructFunction() { 13958fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall return ObjCTypes.getCopyStructFn(); 13968fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall } 13978fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall virtual llvm::Constant *GetGetStructFunction() { 13986cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return ObjCTypes.getCopyStructFn(); 13996cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian } 1400e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian virtual llvm::Constant *GetCppAtomicObjectFunction() { 1401e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian return ObjCTypes.getCppAtomicObjectFunction(); 1402e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian } 14036cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 140474391b48b4791cded373683a3baf67314f358d50Chris Lattner virtual llvm::Constant *EnumerationMutationFunction() { 140572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getEnumerationMutationFn(); 140628ed0847480b76ce76a7e605156608b1cea80e53Daniel Dunbar } 14076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1408f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1409f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S); 1410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S); 1412aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1413f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson const ObjCAtThrowStmt &S); 1414aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 14156948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *AddrWeakObj); 1416aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 14176948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *src, llvm::Value *dst); 1418aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1419021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dest, 1420021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal = false); 1421aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 14226c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dest, 14236c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset); 1424aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 14256948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian llvm::Value *src, llvm::Value *dest); 1426082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1427082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian llvm::Value *dest, llvm::Value *src, 142855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size); 1429598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1430598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 1431598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 1432598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 1433598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers); 1434f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 14352a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 1436f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar); 1437ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}; 14384e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14394e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian/// A helper class for performing the null-initialization of a return 14404e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian/// value. 14414e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanianstruct NullReturnState { 14424e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::BasicBlock *NullBB; 14434e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::BasicBlock *callBB; 14444e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian NullReturnState() : NullBB(0), callBB(0) {} 14454e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14464e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian void init(CodeGenFunction &CGF, llvm::Value *receiver) { 14474e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Make blocks for the null-init and call edges. 14484e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian NullBB = CGF.createBasicBlock("msgSend.nullinit"); 14494e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian callBB = CGF.createBasicBlock("msgSend.call"); 14504e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14514e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Check for a null receiver and, if there is one, jump to the 14524e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // null-init test. 14534e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver); 14544e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.Builder.CreateCondBr(isNull, NullBB, callBB); 14554e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14564e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Otherwise, start performing the call. 14574e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.EmitBlock(callBB); 14584e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian } 14594e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14603c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType, 14613c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian const CallArgList &CallArgs, 14623c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian const ObjCMethodDecl *Method) { 14634e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian if (!NullBB) return result; 14643c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 14653c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian llvm::Value *NullInitPtr = 0; 14663c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (result.isScalar() && !resultType->isVoidType()) { 14673c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian NullInitPtr = CGF.CreateTempAlloca(result.getScalarVal()->getType()); 14683c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian CGF.Builder.CreateStore(result.getScalarVal(), NullInitPtr); 14693c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 14704e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14714e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Finish the call path. 14724e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont"); 14734e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB); 14744e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 14754e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Emit the null-init block and perform the null-initialization there. 14764e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.EmitBlock(NullBB); 14773c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 14783c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian // Release consumed arguments along the null-receiver path. 14793c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (Method) { 14803c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian CallArgList::const_iterator I = CallArgs.begin(); 14813c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(), 14823c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian e = Method->param_end(); i != e; ++i, ++I) { 14833c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian const ParmVarDecl *ParamDecl = (*i); 14843c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (ParamDecl->hasAttr<NSConsumedAttr>()) { 14853c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian RValue RV = I->RV; 14863c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian assert(RV.isScalar() && 14873c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian "NullReturnState::complete - arg not on object"); 14883c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian CGF.EmitARCRelease(RV.getScalarVal(), true); 14893c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 14903c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 14913c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 14923c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 14933c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (result.isScalar()) { 14943c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (NullInitPtr) 14953c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian CGF.EmitNullInitialization(NullInitPtr, resultType); 14963c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian // Jump to the continuation block. 14973c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian CGF.EmitBlock(contBB); 14983c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian return NullInitPtr ? RValue::get(CGF.Builder.CreateLoad(NullInitPtr)) 14993c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian : result; 15003c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 15013c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 15024e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian if (!resultType->isAnyComplexType()) { 15034e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian assert(result.isAggregate() && "null init of non-aggregate result?"); 15044e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.EmitNullInitialization(result.getAggregateAddr(), resultType); 15054e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Jump to the continuation block. 15064e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.EmitBlock(contBB); 15074e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian return result; 15084e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian } 15094e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 15104e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // _Complex type 15114e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // FIXME. Now easy to handle any other scalar type whose result is returned 15124e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // in memory due to ABI limitations. 15134e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CGF.EmitBlock(contBB); 15144e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal(); 15154e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::Type *MemberType = CallCV.first->getType(); 15164e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType); 15174e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian // Create phi instruction for scalar complex value. 15184e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2); 15194e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian PHIReal->addIncoming(ZeroCV, NullBB); 15204e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian PHIReal->addIncoming(CallCV.first, callBB); 15214e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2); 15224e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian PHIImag->addIncoming(ZeroCV, NullBB); 15234e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian PHIImag->addIncoming(CallCV.second, callBB); 15244e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian return RValue::getComplex(PHIReal, PHIImag); 15254e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian } 15264e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian}; 15274e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian 1528c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} // end anonymous namespace 1529bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 1530bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** Helper Functions *** */ 1531bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 1532bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// getConstantGEP() - Help routine to construct simple GEPs. 1533a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonstatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext, 15346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *C, 1535bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned idx0, 1536bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar unsigned idx1) { 1537bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar llvm::Value *Idxs[] = { 15380032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0), 15390032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1) 1540bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar }; 1541a5c04344fa70d6eec34344760c1fe511e16f2d76Jay Foad return llvm::ConstantExpr::getGetElementPtr(C, Idxs); 1542bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 1543bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 15448158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// hasObjCExceptionAttribute - Return true if this class or any super 15458158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// class has the __objc_exception__ attribute. 15466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstatic bool hasObjCExceptionAttribute(ASTContext &Context, 154768584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor const ObjCInterfaceDecl *OID) { 154840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (OID->hasAttr<ObjCExceptionAttr>()) 15498158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return true; 15508158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 155168584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor return hasObjCExceptionAttribute(Context, Super); 15528158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return false; 15538158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar} 15548158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 1555bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** CGObjCMac Public Interface *** */ 15566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1557ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCTypes(cgm) { 1559ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCABI = 1; 15606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar EmitImageInfo(); 1561c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1562c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1563ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// GetClass - Return a reference to the class for the given interface 1564ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// decl. 156545d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbarllvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 156627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *ID) { 156727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return EmitClassRef(Builder, ID); 1568c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1569c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1570c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// GetSelector - Return the pointer to the unique'd string for this selector. 157103b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel, 157203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lval) { 157303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return EmitSelector(Builder, Sel, lval); 1574c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1575df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 15766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar *Method) { 1577df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian return EmitSelector(Builder, Method->getSelector()); 1578df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian} 1579c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1580cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanianllvm::Constant *CGObjCMac::GetEHType(QualType T) { 15819d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian if (T->isObjCIdType() || 15829d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian T->isObjCQualifiedIdType()) { 15839d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor( 158401a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true); 15859d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian } 1586cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian if (T->isObjCClassType() || 1587cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian T->isObjCQualifiedClassType()) { 1588cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor( 158901a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true); 1590cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian } 1591cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian if (T->isObjCObjectPointerType()) 1592cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true); 1593cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian 15945a180397870944548aaadeaebf58e415885b9489John McCall llvm_unreachable("asking for catch type for ObjC type in fragile runtime"); 15955a180397870944548aaadeaebf58e415885b9489John McCall} 15965a180397870944548aaadeaebf58e415885b9489John McCall 1597bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// Generate a constant CFString object. 15986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/* 15996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct __builtin_CFString { 16006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const int *isa; // point to __CFConstantStringClassReference 16016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int flags; 16026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *str; 16036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long length; 16046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar }; 1605bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar*/ 1606bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 160733e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/// or Generate a constant NSString object. 160833e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/* 160933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian struct __builtin_NSString { 161033e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian const int *isa; // point to __NSConstantStringClassReference 161133e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian const char *str; 161233e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian unsigned int length; 161333e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian }; 161433e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian*/ 161533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian 1616aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GenerateConstantString( 16170d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall const StringLiteral *SL) { 16184e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie return (CGM.getLangOpts().NoConstantCFStrings == 0 ? 161933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian CGM.GetAddrOfConstantCFString(SL) : 16204c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian CGM.GetAddrOfConstantString(SL)); 1621c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1622c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 1623ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekenum { 1624ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek kCFTaggedObjectID_Integer = (1 << 1) + 1 1625ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}; 1626ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1627c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// Generates a message send where the super is the receiver. This is 1628c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// a message send to self with special delivery semantics indicating 1629c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// which class's method should be called. 16308f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue 16318f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1632ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 16337f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 16347f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1635f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar const ObjCInterfaceDecl *Class, 16367ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian bool isCategoryImpl, 1637f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 163819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar bool IsClassMessage, 1639d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CodeGen::CallArgList &CallArgs, 1640d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 1641e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar // Create and init a super structure; this is a (receiver, class) 1642e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar // pair we will pass to objc_msgSendSuper. 16436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *ObjCSuper = 1644604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 16456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *ReceiverAsObject = 1646e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 16476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateStore(ReceiverAsObject, 1648e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 1649e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar 1650f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // If this is a class message the metaclass is passed as the target. 1651f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Target; 1652f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar if (IsClassMessage) { 16537ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (isCategoryImpl) { 16547ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // Message sent to 'super' in a class method defined in a category 16557ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // implementation requires an odd treatment. 16567ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // If we are in a class method, we must retrieve the 16577ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // _metaclass_ for the current class, pointed at by 16587ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // the class's "isa" pointer. The following assumes that 16597ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // isa" is the first ivar in a class (which it must be). 16607ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 16617ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateStructGEP(Target, 0); 16627ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateLoad(Target); 1663b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 16647ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 16657ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 16667ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 16677ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = Super; 16686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1669182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian } 1670182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian else if (isCategoryImpl) 1671182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1672182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian else { 1673b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::Value *ClassPtr = EmitSuperClassRef(Class); 1674b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1); 1675b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Target = CGF.Builder.CreateLoad(ClassPtr); 1676f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 1677f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 1678f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ObjCTypes types. 16792acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ClassTy = 168019cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 16810c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Target = CGF.Builder.CreateBitCast(Target, ClassTy); 16826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateStore(Target, 1683f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 1684944c84313da15477eb18d90babb0890d10d98082John McCall return EmitMessageSend(CGF, Return, ResultType, 1685944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 1686944c84313da15477eb18d90babb0890d10d98082John McCall ObjCSuper, ObjCTypes.SuperPtrCTy, 1687944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method, ObjCTypes); 1688c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 16896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 16906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// Generate code for a message send expression. 16918f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1692ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 16937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar QualType ResultType, 16947f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector Sel, 1695f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::Value *Receiver, 1696df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const CallArgList &CallArgs, 1697c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 1698df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian const ObjCMethodDecl *Method) { 1699944c84313da15477eb18d90babb0890d10d98082John McCall return EmitMessageSend(CGF, Return, ResultType, 1700944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 1701944c84313da15477eb18d90babb0890d10d98082John McCall Receiver, CGF.getContext().getObjCIdType(), 1702944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method, ObjCTypes); 170314c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar} 170414c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar 1705d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue 1706944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1707944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot Return, 1708944c84313da15477eb18d90babb0890d10d98082John McCall QualType ResultType, 1709944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Sel, 1710944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *Arg0, 1711944c84313da15477eb18d90babb0890d10d98082John McCall QualType Arg0Ty, 1712944c84313da15477eb18d90babb0890d10d98082John McCall bool IsSuper, 1713944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &CallArgs, 1714944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *Method, 1715944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCCommonTypesHelper &ObjCTypes) { 171619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar CallArgList ActualArgs; 1717d019d96e1ea39cec32f1320b1f9f772aae28247eFariborz Jahanian if (!IsSuper) 1718578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy); 171904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman ActualArgs.add(RValue::get(Arg0), Arg0Ty); 172004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType()); 1721f85e193739c953358c865005855253af4f68a497John McCall ActualArgs.addFrom(CallArgs); 17226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 1723de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // If we're calling a method, use the formal signature. 1724de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs); 17256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 17267e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson if (Method) 17277e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson assert(CGM.getContext().getCanonicalType(Method->getResultType()) == 17287e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson CGM.getContext().getCanonicalType(ResultType) && 17297e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson "Result type mismatch!"); 17307e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson 1731cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullReturnState nullReturn; 1732cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 1733d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian llvm::Constant *Fn = NULL; 1734de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { 17354e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian if (!IsSuper) nullReturn.init(CGF, Arg0); 1736d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 17376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ObjCTypes.getSendStretFn(IsSuper); 1738dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { 1739dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper) 1740dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar : ObjCTypes.getSendFpretFn(IsSuper); 1741eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) { 1742eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper) 1743eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson : ObjCTypes.getSendFp2retFn(IsSuper); 17445669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar } else { 1745d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 17466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : ObjCTypes.getSendFn(IsSuper); 17475669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar } 17483c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 17493c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian bool requiresnullCheck = false; 17504e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCAutoRefCount && Method) 17513c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(), 17523c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian e = Method->param_end(); i != e; ++i) { 17533c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian const ParmVarDecl *ParamDecl = (*i); 17543c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (ParamDecl->hasAttr<NSConsumedAttr>()) { 17553c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian if (!nullReturn.NullBB) 17563c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian nullReturn.init(CGF, Arg0); 17573c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian requiresnullCheck = true; 17583c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian break; 17593c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 17603c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian } 17613c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian 1762de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType); 1763de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs); 17643c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian return nullReturn.complete(CGF, rvalue, ResultType, CallArgs, 17653c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian requiresnullCheck ? Method : 0); 1766c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 1767c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 176893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { 176993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (FQT.isObjCGCStrong()) 177093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Strong; 177193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 1772f85e193739c953358c865005855253af4f68a497John McCall if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak) 177393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Weak; 177493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 1775ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian // check for __unsafe_unretained 1776ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone) 1777ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian return Qualifiers::GCNone; 1778ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian 177993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) 178093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::Strong; 178193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 178293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (const PointerType *PT = FQT->getAs<PointerType>()) 178393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 178493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 178593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return Qualifiers::GCNone; 178693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian} 178793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 17886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, 17896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 17908b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy); 17916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 17924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::NonGC && 17934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie !CGM.getLangOpts().ObjCAutoRefCount) 17946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return nullPtr; 17956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1796a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian bool hasUnion = false; 179793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars.clear(); 179893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo.clear(); 1799bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 1800bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 180193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 180281979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian // __isa is the first field in block descriptor and must assume by runtime's 180381979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian // convention that it is GC'able. 180481979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian IvarsInfo.push_back(GC_IVAR(0, 1)); 18056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 18076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Calculate the basic layout of the block structure. 18096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const llvm::StructLayout *layout = 18106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getTargetData().getStructLayout(blockInfo.StructureType); 18116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore the optional 'this' capture: C++ objects are not assumed 18136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to be GC'ed. 18146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Walk the captured variables. 18166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 18176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 18186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 18196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 18206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 18226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore constant captures. 18246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 18256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); 18276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // __block variables are passed by their descriptor address. 18296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 18306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); 1831c5904b40c3d76b612fb09c6d2717f646a0af6670Fariborz Jahanian continue; 18326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 18336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(!type->isArrayType() && "array variable should not be caught"); 18356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (const RecordType *record = type->getAs<RecordType>()) { 18366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion); 1837e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian continue; 1838e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian } 1839a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian 18406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); 18416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned fieldSize = CGM.getContext().getTypeSize(type); 18426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (GCAttr == Qualifiers::Strong) 18446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall IvarsInfo.push_back(GC_IVAR(fieldOffset, 18456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fieldSize / WordSizeInBits)); 184693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) 18476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall SkipIvars.push_back(GC_IVAR(fieldOffset, 18486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fieldSize / ByteSizeInBits)); 184993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian } 185093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 185193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (IvarsInfo.empty()) 18526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return nullPtr; 18536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 18546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Sort on byte position; captures might not be allocated in order, 18556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // and unions can do funny things. 18566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 18576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end()); 185893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 185993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian std::string BitMap; 1860b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 18614e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCGCBitmapPrint) { 186293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("\n block variable layout for block: "); 186331ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky const unsigned char *s = (const unsigned char*)BitMap.c_str(); 186413562a1f30df391607604fb6bf345af42b0d831dBill Wendling for (unsigned i = 0, e = BitMap.size(); i < e; i++) 186593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (!(s[i] & 0xf0)) 186693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 186793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian else 186893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 186993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian printf("\n"); 187093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian } 187193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 187293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return C; 187389ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian} 187489ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian 18756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 1876af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar const ObjCProtocolDecl *PD) { 1877c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar // FIXME: I don't understand why gcc generates this, or where it is 1878f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // resolved. Investigate. Its also wasteful to look this up over and over. 1879c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1880c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar 18813c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 18824c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor ObjCTypes.getExternalProtocolPtrTy()); 18836efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 18846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 1885da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 1886f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need this, the protocol decl should contain enough 1887f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // information to tell us whether this was a declaration or a definition. 18880c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar DefinedProtocols.insert(PD->getIdentifier()); 18890c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 18900c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // If we have generated a forward reference to this protocol, emit 18910c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // it now. Otherwise do nothing, the protocol objects are lazily 18920c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // emitted. 18936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (Protocols.count(PD->getIdentifier())) 18940c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar GetOrEmitProtocol(PD); 18950c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar} 18960c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 1897da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 18980c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar if (DefinedProtocols.count(PD->getIdentifier())) 18990c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return GetOrEmitProtocol(PD); 1900f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 19010c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return GetOrEmitProtocolRef(PD); 19020c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar} 19030c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 19046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 19056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 19066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol { 19076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_extension *isa; 19086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarchar *protocol_name; 19096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_list *protocol_list; 19106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *instance_methods; 19116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *class_methods 19126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar}; 19136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 19146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarSee EmitProtocolExtension(). 19156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 19160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 191750651b951c216573175e2145f32df2c4658ba3f9John McCall llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()]; 19180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 19190c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Early exit if a defining object has already been generated. 19200c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar if (Entry && Entry->hasInitializer()) 19210c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return Entry; 19220c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 19231d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor // Use the protocol definition, if there is one. 19241d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor if (const ObjCProtocolDecl *Def = PD->getDefinition()) 19251d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor PD = Def; 19261d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor 1927242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // FIXME: I don't understand why gcc generates this, or where it is 1928f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // resolved. Investigate. Its also wasteful to look this up over and over. 1929242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1930242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 1931ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar // Construct method lists. 1932ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1933ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 1934dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt; 19356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::instmeth_iterator 193617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 1937ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ObjCMethodDecl *MD = *i; 1938ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *C = GetMethodDescriptionConstant(MD); 1939f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 1940f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 1941f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 1942ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1943ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar OptInstanceMethods.push_back(C); 1944dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 1945ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 1946ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar InstanceMethods.push_back(C); 1947dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.push_back(GetMethodVarType(MD, true)); 19486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1949ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 1950ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar 19516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::classmeth_iterator 195217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 1953ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ObjCMethodDecl *MD = *i; 1954ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar llvm::Constant *C = GetMethodDescriptionConstant(MD); 1955f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 1956f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 1957f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 1958ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1959ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar OptClassMethods.push_back(C); 1960dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 1961ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 1962ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar ClassMethods.push_back(C); 1963dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.push_back(GetMethodVarType(MD, true)); 19646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 1965ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 1966ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar 1967dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.insert(MethodTypesExt.end(), 1968dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.begin(), OptMethodTypesExt.end()); 1969dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 19701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 1971dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods, 1972dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt), 19731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(PD->getIdentifier()), 19749c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(), 1975dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar PD->protocol_begin(), 19761d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer PD->protocol_end()), 19779c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(), 1978ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 19791d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer InstanceMethods), 19809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(), 1981ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 19821d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ClassMethods) 19831d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 198408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 19856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Values); 19866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 19876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (Entry) { 19880c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Already created, fix the linkage and update the initializer. 19890c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 19906efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setInitializer(Init); 19916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } else { 19926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 19931c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 19946efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalValue::InternalLinkage, 19956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 19969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01L_OBJC_PROTOCOL_" + PD->getName()); 19976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 19986efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // FIXME: Is this necessary? Why only for protocol? 19996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setAlignment(4); 200050651b951c216573175e2145f32df2c4658ba3f9John McCall 200150651b951c216573175e2145f32df2c4658ba3f9John McCall Protocols[PD->getIdentifier()] = Entry; 20026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } 2003ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 20040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 20050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar return Entry; 20066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 20076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 20096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 20106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (!Entry) { 20120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // We use the initializer as a marker of whether this is a forward 20130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // reference or not. At module finalization we add the empty 20140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // contents for protocols which were referenced but never defined. 20156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 20161c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 20170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 20180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 0, 20199c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01L_OBJC_PROTOCOL_" + PD->getName()); 20206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 20216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // FIXME: Is this necessary? Why only for protocol? 20226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Entry->setAlignment(4); 20236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar } 20246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 20256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar return Entry; 20266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 20276efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 20296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct _objc_protocol_extension { 20306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; 20316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description_list *optional_instance_methods; 20326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description_list *optional_class_methods; 20336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_property_list *instance_properties; 2034dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson const char ** extendedMethodTypes; 20356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 20366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 2037ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant * 2038ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 2039bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> OptInstanceMethods, 2040bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> OptClassMethods, 2041bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> MethodTypesExt) { 20426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint64_t Size = 20439408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 20441d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 20451d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.IntTy, Size), 20466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 20479c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 2048ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 20491d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer OptInstanceMethods), 20509c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(), 2051ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 20521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer OptClassMethods), 20531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD, 2054dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson ObjCTypes), 2055dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(), 2056dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt, ObjCTypes) 20571d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 20586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 205927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null if no extension bits are used. 20606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (Values[1]->isNullValue() && Values[2]->isNullValue() && 2061dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson Values[3]->isNullValue() && Values[4]->isNullValue()) 2062c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 20636efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 206508e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 20666efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 206763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar // No special section, but goes in llvm.used 20689c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(), 20696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 207063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar 0, 0, true); 20716efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 20726efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20736efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 20746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct objc_protocol_list { 20753964e62786b0912fecc82d776daac236e05fc792Bill Wendling struct objc_protocol_list *next; 20763964e62786b0912fecc82d776daac236e05fc792Bill Wendling long count; 20773964e62786b0912fecc82d776daac236e05fc792Bill Wendling Protocol *list[]; 20786efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 20796efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 2080dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbarllvm::Constant * 20815f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCMac::EmitProtocolList(Twine Name, 2082dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 2083dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ObjCProtocolDecl::protocol_iterator end) { 20843964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs; 20856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 2086dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar for (; begin != end; ++begin) 2087dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar ProtocolRefs.push_back(GetProtocolRef(*begin)); 20886efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 20896efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Just return null for empty protocol lists 20906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (ProtocolRefs.empty()) 2091c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 20926efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 209327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // This list is null terminated. 2094c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 20956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 2096c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 209727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // This field is only used by the runtime. 2098c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 20994a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, 21006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs.size() - 1); 21016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = 21026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 21036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolRefs.size()), 21046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar ProtocolRefs); 21056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2106c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 21076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 210863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 210958a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, false); 21103c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 2111c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2112c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 2113bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingvoid CGObjCCommonMac:: 2114bb02855f46423d2034918b75b157f886bb04bcccBill WendlingPushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet, 21153964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVectorImpl<llvm::Constant*> &Properties, 2116bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const Decl *Container, 2117bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const ObjCProtocolDecl *PROTO, 2118bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const ObjCCommonTypesHelper &ObjCTypes) { 2119191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), 2120191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian E = PROTO->protocol_end(); P != E; ++P) 2121191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 2122191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), 2123191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian E = PROTO->prop_end(); I != E; ++I) { 2124581deb3da481053c4993c7600f97acf7768caac5David Blaikie const ObjCPropertyDecl *PD = *I; 2125191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian if (!PropertySet.insert(PD->getIdentifier())) 2126191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian continue; 21271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Prop[] = { 21281d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyName(PD->getIdentifier()), 21291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyTypeString(PD, Container) 21301d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 2131191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); 2132191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian } 2133191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian} 2134191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian 21356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/* 2136c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar struct _objc_property { 21373964e62786b0912fecc82d776daac236e05fc792Bill Wendling const char * const name; 21383964e62786b0912fecc82d776daac236e05fc792Bill Wendling const char * const attributes; 2139c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar }; 2140c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 2141c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar struct _objc_property_list { 21423964e62786b0912fecc82d776daac236e05fc792Bill Wendling uint32_t entsize; // sizeof (struct _objc_property) 21433964e62786b0912fecc82d776daac236e05fc792Bill Wendling uint32_t prop_count; 21443964e62786b0912fecc82d776daac236e05fc792Bill Wendling struct _objc_property[prop_count]; 2145c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar }; 2146c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar*/ 21475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, 21486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container, 21496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCContainerDecl *OCD, 21506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCommonTypesHelper &ObjCTypes) { 21513964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVector<llvm::Constant*, 16> Properties; 2152191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 21536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 21546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar E = OCD->prop_end(); I != E; ++I) { 2155581deb3da481053c4993c7600f97acf7768caac5David Blaikie const ObjCPropertyDecl *PD = *I; 2156191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian PropertySet.insert(PD->getIdentifier()); 21571d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Prop[] = { 21581d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyName(PD->getIdentifier()), 21591d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetPropertyTypeString(PD, Container) 21601d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 216108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 2162c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar Prop)); 2163c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar } 21646afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) { 216553b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek for (ObjCInterfaceDecl::all_protocol_iterator 216653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek P = OID->all_referenced_protocol_begin(), 216753b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek E = OID->all_referenced_protocol_end(); P != E; ++P) 21686afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), 21696afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian ObjCTypes); 21706afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian } 21716afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) { 21726afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(), 21736afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian E = CD->protocol_end(); P != E; ++P) 21746afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian PushProtocolProperties(PropertySet, Properties, Container, (*P), 21756afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian ObjCTypes); 21766afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian } 2177c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 2178c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar // Return null for empty list. 2179c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar if (Properties.empty()) 2180c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 2181c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 21826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned PropertySize = 21839408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 2184c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 21854a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 21864a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 21876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 2188c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar Properties.size()); 21897db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Properties); 2190c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 2191c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 21926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 21936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CreateMetadataVar(Name, Init, 21946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (ObjCABI == 2) ? "__DATA, __objc_const" : 21950bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__property,regular,no_dead_strip", 21966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (ObjCABI == 2) ? 8 : 4, 21970bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar true); 21983c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 2199c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 2200c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 2201bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant * 2202bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCCommonMac::EmitProtocolMethodTypes(Twine Name, 2203bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> MethodTypes, 2204bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const ObjCCommonTypesHelper &ObjCTypes) { 2205dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson // Return null for empty list. 2206dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson if (MethodTypes.empty()) 2207dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy); 2208dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 2209dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 2210dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypes.size()); 2211dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes); 2212dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 2213dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::GlobalVariable *GV = 2214dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson CreateMetadataVar(Name, Init, 2215dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson (ObjCABI == 2) ? "__DATA, __objc_const" : 0, 2216dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson (ObjCABI == 2) ? 8 : 4, 2217dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson true); 2218dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy); 2219dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson} 2220dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 2221c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar/* 22226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar struct objc_method_description_list { 22236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int count; 22246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_description list[]; 22256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar }; 22266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/ 2227ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant * 2228ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 22291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Desc[] = { 22306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 22311d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 22321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD) 22331d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 2234f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!Desc[1]) 2235f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 2236f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 223708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 2238ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Desc); 2239ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar} 22406efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 2241bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant * 2242bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCMac::EmitMethodDescList(Twine Name, const char *Section, 2243bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods) { 22446efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Return null for empty list. 22456efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar if (Methods.empty()) 2246c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 22476efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 2248c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 22494a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 22506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 22516efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar Methods.size()); 22527db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[1] = llvm::ConstantArray::get(AT, Methods); 2253c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 22546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 22550bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 22566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, 22576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar ObjCTypes.MethodDescriptionListPtrTy); 2258c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2259c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 226086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar/* 226186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar struct _objc_category { 22626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *category_name; 22636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *class_name; 22646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *instance_methods; 22656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *class_methods; 22666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_protocol_list *protocols; 22676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; // <rdar://4585769> 22686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_property_list *instance_properties; 226986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar }; 22706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 22717ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbarvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 22729408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 227386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 2274f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This is poor design, the OCD should have a pointer to the category 2275f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // decl. Additionally, note that Category can be null for the @implementation 2276f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // w/o an @interface case. Sema should just create one for us as it does for 2277f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // @implementation so everyone else can live life under a clear blue sky. 227886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 22796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCategoryDecl *Category = 228086e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar Interface->FindCategoryDeclaration(OCD->getIdentifier()); 22819c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar 2282f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> ExtName; 22839c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' 22849c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar << OCD->getName(); 228586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 22863964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods; 22876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::instmeth_iterator 228817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 2289c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Instance methods should always be defined. 2290c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(GetMethodConstant(*i)); 2291c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 22926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::classmeth_iterator 229317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 2294c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Class methods should always be defined. 2295c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods.push_back(GetMethodConstant(*i)); 2296c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2297c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2298c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[7]; 229986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values[0] = GetClassName(OCD->getIdentifier()); 230086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values[1] = GetClassName(Interface->getIdentifier()); 2301679cd7fcbd341fa3747e598f537601db421b1002Fariborz Jahanian LazySymbols.insert(Interface->getIdentifier()); 23026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = 23039c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(), 2304c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar "__OBJC,__cat_inst_meth,regular,no_dead_strip", 2305c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods); 23066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[3] = 23079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(), 23080bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__cat_cls_meth,regular,no_dead_strip", 2309c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods); 2310ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar if (Category) { 23116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = 23129c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(), 2313ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Category->protocol_begin(), 2314ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar Category->protocol_end()); 2315ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } else { 2316c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 2317ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar } 23184a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 231986e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar 232086e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar // If there is no category @interface then there can be no properties. 232186e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar if (Category) { 23229c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 23235de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian OCD, Category, ObjCTypes); 232486e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar } else { 2325c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 232686e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar } 23276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 232808e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 232986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar Values); 233086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 23316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 23329c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init, 233363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__category,regular,no_dead_strip", 233458a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 233586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar DefinedCategories.push_back(GV); 2336b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian DefinedCategoryNames.insert(ExtName.str()); 233764089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 233864089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 2339c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2340c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 234127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Get from somewhere? 234227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarenum ClassFlags { 234327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Factory = 0x00001, 234427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Meta = 0x00002, 234527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // <rdr://5142207> 234627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_HasCXXStructors = 0x02000, 234727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_Hidden = 0x20000, 234827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_ABI2_Hidden = 0x00010, 234927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 235027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}; 235127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 235227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 235327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct _objc_class { 23546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Class isa; 23556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Class super_class; 23566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *name; 23576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long version; 23586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long info; 23596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar long instance_size; 23606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_ivar_list *ivars; 23616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_method_list *methods; 23626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_cache *cache; 23636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_protocol_list *protocols; 23646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // Objective-C 1.0 extensions (<rdr://4585769>) 23656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *ivar_layout; 23666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_class_ext *ext; 236727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 236827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 236927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar See EmitClassExtension(); 23706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 237127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 2372242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar DefinedSymbols.insert(ID->getIdentifier()); 2373242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 23748ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner std::string ClassName = ID->getNameAsString(); 237527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // FIXME: Gross 23766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCInterfaceDecl *Interface = 237727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 23786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Protocols = 23799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(), 238053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek Interface->all_referenced_protocol_begin(), 238153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek Interface->all_referenced_protocol_end()); 238227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned Flags = eClassFlags_Factory; 2383f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 2384109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian Flags |= eClassFlags_HasCXXStructors; 23856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned Size = 23865f022d82696c84e4d127c558871d68ac6273274eKen Dyck CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity(); 238727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 238827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // FIXME: Set CXX-structors flag. 23891fb0caaa7bef765b85972274e3b434af2572c141John McCall if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 239027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Flags |= eClassFlags_Hidden; 239127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 23923964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods; 23936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::instmeth_iterator 239417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 2395c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Instance methods should always be defined. 2396c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(GetMethodConstant(*i)); 2397c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 23986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::classmeth_iterator 239917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 2400c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar // Class methods should always be defined. 2401c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ClassMethods.push_back(GetMethodConstant(*i)); 2402c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2403c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 24046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::propimpl_iterator 240517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 2406581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCPropertyImplDecl *PID = *i; 2407c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2408c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 2409c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar ObjCPropertyDecl *PD = PID->getPropertyDecl(); 2410c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2411c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 2412c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (llvm::Constant *C = GetMethodConstant(MD)) 2413c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(C); 2414c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 2415c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (llvm::Constant *C = GetMethodConstant(MD)) 2416c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods.push_back(C); 2417c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2418c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar } 2419c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar 2420c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[12]; 24215384b0990ea6995121fd4bad0855e96d41dcad18Daniel Dunbar Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 242227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 2423242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Record a reference to the super class. 2424242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar LazySymbols.insert(Super->getIdentifier()); 2425242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 24266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 1] = 24273c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 242827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 242927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } else { 2430c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 243127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 243227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 2] = GetClassName(ID->getIdentifier()); 243327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Version is always 0. 24344a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 24354a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 24364a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 243746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian Values[ 6] = EmitIvarList(ID, false); 24386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 7] = 24399c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(), 2440c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar "__OBJC,__inst_meth,regular,no_dead_strip", 2441c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar InstanceMethods); 244227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // cache is always NULL. 2443c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 244427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 9] = Protocols; 24456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[10] = BuildIvarLayout(ID, true); 244627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[11] = EmitClassExtension(ID); 244708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 244827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values); 2449b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian std::string Name("\01L_OBJC_CLASS_"); 2450b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Name += ClassName; 2451b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian const char *Section = "__OBJC,__class,regular,no_dead_strip"; 2452b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian // Check for a forward reference. 2453b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2454b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian if (GV) { 2455b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2456b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian "Forward metaclass reference has incorrect type."); 2457b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2458b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setInitializer(Init); 2459b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setSection(Section); 2460b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV->setAlignment(4); 2461b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian CGM.AddUsedGlobal(GV); 2462b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } 2463b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian else 2464b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian GV = CreateMetadataVar(Name, Init, Section, 4, true); 246527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar DefinedClasses.push_back(GV); 246664089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 246764089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 246827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 246927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 247027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 247127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar llvm::Constant *Protocols, 2472bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods) { 247327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned Flags = eClassFlags_Meta; 24749408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 247527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 24761fb0caaa7bef765b85972274e3b434af2572c141John McCall if (ID->getClassInterface()->getVisibility() == HiddenVisibility) 247727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Flags |= eClassFlags_Hidden; 24786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2479c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[12]; 248027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // The isa for the metaclass is the root of the hierarchy. 248127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar const ObjCInterfaceDecl *Root = ID->getClassInterface(); 248227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 248327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Root = Super; 24846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 0] = 24853c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 248627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 248786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // The super class for the metaclass is emitted as the name of the 248886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // super class. The runtime fixes this up to point to the 248986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // *metaclass* for the super class. 249027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 24916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 1] = 24923c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 249327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ObjCTypes.ClassPtrTy); 249427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } else { 2495c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 249627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 249727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 2] = GetClassName(ID->getIdentifier()); 249827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Version is always 0. 24994a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 25004a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 25014a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 250246b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian Values[ 6] = EmitIvarList(ID, true); 25036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 7] = 2504d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 25050bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar "__OBJC,__cls_meth,regular,no_dead_strip", 2506c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar Methods); 250727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // cache is always NULL. 2508c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 250927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values[ 9] = Protocols; 251027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // ivar_layout for metaclass is always NULL. 2511c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 251227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // The class extension is always unused for metaclasses. 2513c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 251408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 251527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Values); 251627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2517f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar std::string Name("\01L_OBJC_METACLASS_"); 251894be8ea90795d00fe2a97fea9a9a727911a70997Benjamin Kramer Name += ID->getName(); 2519f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2520f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Check for a forward reference. 2521f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2522f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar if (GV) { 2523f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2524f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar "Forward metaclass reference has incorrect type."); 2525f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2526f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar GV->setInitializer(Init); 2527f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 25281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2529f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalValue::InternalLinkage, 25301c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Init, Name); 2531f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 253227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 253358a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar GV->setAlignment(4); 2534ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 253527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 253627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return GV; 253727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 253827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 25396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 2540d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 2541f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2542f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: Should we look these up somewhere other than the module. Its a bit 2543f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // silly since we only generate these while processing an implementation, so 2544f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // exactly one pointer would work if know when we entered/exitted an 2545f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // implementation block. 2546f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 2547f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Check for an existing forward reference. 2548b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian // Previously, metaclass with internal linkage may have been defined. 2549b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian // pass 'true' as 2nd argument so it is returned. 25506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 25516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar true)) { 2552f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2553f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar "Forward metaclass reference has incorrect type."); 2554f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar return GV; 2555f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 2556f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // Generate as an external reference to keep a consistent 2557f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar // module. This will be patched up when we emit the metaclass. 25581c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2559f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar llvm::GlobalValue::ExternalLinkage, 2560b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 0, 2561b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian Name); 2562b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } 2563b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian} 2564b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 2565b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanianllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { 2566b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString(); 2567b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian 2568b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2569b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian true)) { 2570b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2571b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian "Forward class metadata reference has incorrect type."); 2572b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian return GV; 2573b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian } else { 2574b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2575b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian llvm::GlobalValue::ExternalLinkage, 2576f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 0, 25771c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Name); 2578f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } 2579f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar} 2580f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 258127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 258227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_class_ext { 25836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t size; 25846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const char *weak_ivar_layout; 25856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct _objc_property_list *properties; 258627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 258727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/ 258827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant * 258927f9d77b61b377b21ccda536122f2be6fa715751Daniel DunbarCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 25906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint64_t Size = 25919408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 259227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2593c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 25944a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2595c71303de3e295d19c3617b6738da009f6e679337Fariborz Jahanian Values[1] = BuildIvarLayout(ID, false); 25969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 25975de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian ID, ID->getClassInterface(), ObjCTypes); 259827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 259927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null if no extension bits are used. 260027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Values[1]->isNullValue() && Values[2]->isNullValue()) 2601c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 260227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 26036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 260408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 26059c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(), 26066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, "__OBJC,__class_ext,regular,no_dead_strip", 26070bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 260827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 260927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 261027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 261127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_ivar { 2612795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling char *ivar_name; 2613795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling char *ivar_type; 2614795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling int ivar_offset; 261527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 261627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 261727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_ivar_list { 2618795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling int ivar_count; 2619795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling struct objc_ivar list[count]; 262027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 26216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/ 262227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 262346b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian bool ForClass) { 26241d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer std::vector<llvm::Constant*> Ivars; 262527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 262627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // When emitting the root class GCC emits ivar entries for the 262727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // actual class structure. It is not clear if we need to follow this 262827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // behavior; for now lets try and get away with not doing it. If so, 262927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // the cleanest solution would be to make up an ObjCInterfaceDecl 263027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // for the class. 263127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (ForClass) 2632c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 26336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2634db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OID = ID->getClassInterface(); 26356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 2636db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 2637bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) { 26388e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian // Ignore unnamed bit-fields. 26398e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian if (!IVD->getDeclName()) 26406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar continue; 26411d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Ivar[] = { 26421d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarName(IVD->getIdentifier()), 26431d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(IVD), 26441d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.IntTy, 26451d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ComputeIvarBaseOffset(CGM, OID, IVD)) 26461d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 264708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 264827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 264927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 265027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null for empty list. 265127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Ivars.empty()) 2652c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 265327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2654c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 26554a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 265696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 265727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Ivars.size()); 26587db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[1] = llvm::ConstantArray::get(AT, Ivars); 2659c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 266027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 266163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar llvm::GlobalVariable *GV; 266263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (ForClass) 26639c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(), 26646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, "__OBJC,__class_vars,regular,no_dead_strip", 266558a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 266663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar else 26679c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(), 266863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Init, "__OBJC,__instance_vars,regular,no_dead_strip", 26690bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 26703c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 267127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 267227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 267327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/* 267427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_method { 26756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SEL method_name; 26766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar char *method_types; 26776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar void *method; 267827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 26796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 268027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar struct objc_method_list { 26816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method_list *obsolete; 26826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int count; 26836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar struct objc_method methods_list[count]; 268427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar }; 268527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/ 268627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2687c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// GetMethodConstant - Return a struct objc_method constant for the 2688c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// given method if it has been defined. The result is null if the 2689c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// method has not been defined. The return value has type MethodPtrTy. 2690ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 26919d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *Fn = GetMethodDefinition(MD); 2692c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar if (!Fn) 2693c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar return 0; 26946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 26951d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Method[] = { 26963c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 26971d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 26981d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD), 26991d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 27001d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 270108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 2702c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar} 270327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 27045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodList(Twine Name, 2705c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar const char *Section, 2706bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods) { 270727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Return null for empty list. 270827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (Methods.empty()) 2709c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 271027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 2711c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 2712c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 27134a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 271496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 271527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Methods.size()); 27167db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Methods); 2717c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 271827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 27190bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2720c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy); 2721b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar} 2722b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2723493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 27246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCContainerDecl *CD) { 2725f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Name; 2726679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian GetNameForMethod(OMD, CD, Name); 2727b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2728541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar CodeGenTypes &Types = CGM.getTypes(); 27292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *MethodTy = 2730de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); 27316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Function *Method = 273245c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar llvm::Function::Create(MethodTy, 2733b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar llvm::GlobalValue::InternalLinkage, 2734c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar Name.str(), 2735b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar &CGM.getModule()); 2736c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar MethodDefinitions.insert(std::make_pair(OMD, Method)); 2737b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 2738b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar return Method; 2739c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2740c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 2741fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbarllvm::GlobalVariable * 27425f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCCommonMac::CreateMetadataVar(Twine Name, 2743fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar llvm::Constant *Init, 2744fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar const char *Section, 274535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar unsigned Align, 274635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar bool AddToUsed) { 27472acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = Init->getType(); 27486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *GV = 27491c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Ty, false, 2750ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner llvm::GlobalValue::InternalLinkage, Init, Name); 2751fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar if (Section) 2752fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar GV->setSection(Section); 275335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar if (Align) 275435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar GV->setAlignment(Align); 275535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar if (AddToUsed) 2756ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 2757fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar return GV; 2758fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar} 2759fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar 27606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCMac::ModuleInitFunction() { 2761f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar // Abuse this interface function as a place to finalize. 2762f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar FinishModule(); 2763c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar return NULL; 2764c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 2765c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar 276674391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertyGetFunction() { 276772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getGetPropertyFn(); 276849f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar} 276949f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar 277074391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertySetFunction() { 277172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getSetPropertyFn(); 277249f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar} 277349f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar 2774ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekllvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic, 2775ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool copy) { 2776ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy); 2777ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 2778ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 27798fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetGetStructFunction() { 27808fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall return ObjCTypes.getCopyStructFn(); 27818fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall} 27828fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetSetStructFunction() { 27836cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian return ObjCTypes.getCopyStructFn(); 27846cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian} 27856cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian 2786e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanianllvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() { 2787e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian return ObjCTypes.getCppAtomicObjectFunction(); 2788e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian} 2789e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian 279074391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::EnumerationMutationFunction() { 279172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner return ObjCTypes.getEnumerationMutationFn(); 27922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson} 27932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 2794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) { 2795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return EmitTryOrSynchronizedStmt(CGF, S); 2796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 2797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF, 2799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S) { 2800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return EmitTryOrSynchronizedStmt(CGF, S); 2801f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 2802f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2803cc5052999cd064584492ba15a808b6e1cee6d931John McCallnamespace { 28041f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct PerformFragileFinally : EHScopeStack::Cleanup { 2805cc5052999cd064584492ba15a808b6e1cee6d931John McCall const Stmt &S; 28060b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot; 2807cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *CallTryExitVar; 2808cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *ExceptionData; 2809cc5052999cd064584492ba15a808b6e1cee6d931John McCall ObjCTypesHelper &ObjCTypes; 2810cc5052999cd064584492ba15a808b6e1cee6d931John McCall PerformFragileFinally(const Stmt *S, 28110b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot, 2812cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *CallTryExitVar, 2813cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::Value *ExceptionData, 2814cc5052999cd064584492ba15a808b6e1cee6d931John McCall ObjCTypesHelper *ObjCTypes) 28150b2517299415ab1c28b9cb87d536ccea84317a10John McCall : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar), 2816cc5052999cd064584492ba15a808b6e1cee6d931John McCall ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {} 2817cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2818ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 2819cc5052999cd064584492ba15a808b6e1cee6d931John McCall // Check whether we need to call objc_exception_try_exit. 2820cc5052999cd064584492ba15a808b6e1cee6d931John McCall // In optimized code, this branch will always be folded. 2821cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::BasicBlock *FinallyCallExit = 2822cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.createBasicBlock("finally.call_exit"); 2823cc5052999cd064584492ba15a808b6e1cee6d931John McCall llvm::BasicBlock *FinallyNoCallExit = 2824cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.createBasicBlock("finally.no_call_exit"); 2825cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar), 2826cc5052999cd064584492ba15a808b6e1cee6d931John McCall FinallyCallExit, FinallyNoCallExit); 2827cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2828cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitBlock(FinallyCallExit); 2829cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData) 2830cc5052999cd064584492ba15a808b6e1cee6d931John McCall ->setDoesNotThrow(); 2831cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2832cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitBlock(FinallyNoCallExit); 2833cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2834cc5052999cd064584492ba15a808b6e1cee6d931John McCall if (isa<ObjCAtTryStmt>(S)) { 2835cc5052999cd064584492ba15a808b6e1cee6d931John McCall if (const ObjCAtFinallyStmt* FinallyStmt = 2836d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall cast<ObjCAtTryStmt>(S).getFinallyStmt()) { 2837d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Save the current cleanup destination in case there's 2838d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // control flow inside the finally statement. 2839d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall llvm::Value *CurCleanupDest = 2840d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot()); 2841d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall 2842cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.EmitStmt(FinallyStmt->getFinallyBody()); 2843cc5052999cd064584492ba15a808b6e1cee6d931John McCall 2844d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall if (CGF.HaveInsertPoint()) { 2845d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateStore(CurCleanupDest, 2846d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.getNormalCleanupDestSlot()); 2847d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } else { 2848d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Currently, the end of the cleanup must always exist. 2849d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.EnsureInsertPoint(); 2850d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } 2851d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall } 2852cc5052999cd064584492ba15a808b6e1cee6d931John McCall } else { 2853cc5052999cd064584492ba15a808b6e1cee6d931John McCall // Emit objc_sync_exit(expr); as finally's sole statement for 2854cc5052999cd064584492ba15a808b6e1cee6d931John McCall // @synchronized. 28550b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot); 2856cc5052999cd064584492ba15a808b6e1cee6d931John McCall CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg) 2857cc5052999cd064584492ba15a808b6e1cee6d931John McCall ->setDoesNotThrow(); 2858cc5052999cd064584492ba15a808b6e1cee6d931John McCall } 2859cc5052999cd064584492ba15a808b6e1cee6d931John McCall } 2860cc5052999cd064584492ba15a808b6e1cee6d931John McCall }; 286187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 286287bb5822bfa4baea23a3d9273df266777f3ab796John McCall class FragileHazards { 286387bb5822bfa4baea23a3d9273df266777f3ab796John McCall CodeGenFunction &CGF; 28645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Value*, 20> Locals; 286587bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry; 286687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 286787bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::InlineAsm *ReadHazard; 286887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::InlineAsm *WriteHazard; 286987bb5822bfa4baea23a3d9273df266777f3ab796John McCall 287087bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::FunctionType *GetAsmFnType(); 287187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 287287bb5822bfa4baea23a3d9273df266777f3ab796John McCall void collectLocals(); 287387bb5822bfa4baea23a3d9273df266777f3ab796John McCall void emitReadHazard(CGBuilderTy &Builder); 287487bb5822bfa4baea23a3d9273df266777f3ab796John McCall 287587bb5822bfa4baea23a3d9273df266777f3ab796John McCall public: 287687bb5822bfa4baea23a3d9273df266777f3ab796John McCall FragileHazards(CodeGenFunction &CGF); 28770b2517299415ab1c28b9cb87d536ccea84317a10John McCall 287887bb5822bfa4baea23a3d9273df266777f3ab796John McCall void emitWriteHazard(); 28790b2517299415ab1c28b9cb87d536ccea84317a10John McCall void emitHazardsInNewBlocks(); 288087bb5822bfa4baea23a3d9273df266777f3ab796John McCall }; 288187bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 288287bb5822bfa4baea23a3d9273df266777f3ab796John McCall 288387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Create the fragile-ABI read and write hazards based on the current 288487bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// state of the function, which is presumed to be immediately prior 288587bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// to a @try block. These hazards are used to maintain correct 288687bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// semantics in the face of optimization and the fragile ABI's 288787bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// cavalier use of setjmp/longjmp. 288887bb5822bfa4baea23a3d9273df266777f3ab796John McCallFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { 288987bb5822bfa4baea23a3d9273df266777f3ab796John McCall collectLocals(); 289087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 289187bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 289287bb5822bfa4baea23a3d9273df266777f3ab796John McCall 289387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Collect all the blocks in the function. 289487bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::Function::iterator 289587bb5822bfa4baea23a3d9273df266777f3ab796John McCall I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I) 289687bb5822bfa4baea23a3d9273df266777f3ab796John McCall BlocksBeforeTry.insert(&*I); 289787bb5822bfa4baea23a3d9273df266777f3ab796John McCall 289887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::FunctionType *AsmFnTy = GetAsmFnType(); 289987bb5822bfa4baea23a3d9273df266777f3ab796John McCall 290087bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create a read hazard for the allocas. This inhibits dead-store 290187bb5822bfa4baea23a3d9273df266777f3ab796John McCall // optimizations and forces the values to memory. This hazard is 290287bb5822bfa4baea23a3d9273df266777f3ab796John McCall // inserted before any 'throwing' calls in the protected scope to 290387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // reflect the possibility that the variables might be read from the 290487bb5822bfa4baea23a3d9273df266777f3ab796John McCall // catch block if the call throws. 290587bb5822bfa4baea23a3d9273df266777f3ab796John McCall { 290687bb5822bfa4baea23a3d9273df266777f3ab796John McCall std::string Constraint; 290787bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 290887bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (I) Constraint += ','; 290987bb5822bfa4baea23a3d9273df266777f3ab796John McCall Constraint += "*m"; 291087bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 291187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 291287bb5822bfa4baea23a3d9273df266777f3ab796John McCall ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 291387bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 291487bb5822bfa4baea23a3d9273df266777f3ab796John McCall 291587bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create a write hazard for the allocas. This inhibits folding 291687bb5822bfa4baea23a3d9273df266777f3ab796John McCall // loads across the hazard. This hazard is inserted at the 291787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // beginning of the catch path to reflect the possibility that the 291887bb5822bfa4baea23a3d9273df266777f3ab796John McCall // variables might have been written within the protected scope. 291987bb5822bfa4baea23a3d9273df266777f3ab796John McCall { 292087bb5822bfa4baea23a3d9273df266777f3ab796John McCall std::string Constraint; 292187bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 292287bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (I) Constraint += ','; 292387bb5822bfa4baea23a3d9273df266777f3ab796John McCall Constraint += "=*m"; 292487bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 292587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 292687bb5822bfa4baea23a3d9273df266777f3ab796John McCall WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 292787bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 292887bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 292987bb5822bfa4baea23a3d9273df266777f3ab796John McCall 293087bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit a write hazard at the current location. 293187bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitWriteHazard() { 293287bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 293387bb5822bfa4baea23a3d9273df266777f3ab796John McCall 29344c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow(); 293587bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 293687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 293787bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) { 293887bb5822bfa4baea23a3d9273df266777f3ab796John McCall assert(!Locals.empty()); 29394c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow(); 294087bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 294187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 294287bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit read hazards in all the protected blocks, i.e. all the blocks 294387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// which have been inserted since the beginning of the try. 29440b2517299415ab1c28b9cb87d536ccea84317a10John McCallvoid FragileHazards::emitHazardsInNewBlocks() { 294587bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (Locals.empty()) return; 294687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 294787bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGBuilderTy Builder(CGF.getLLVMContext()); 294887bb5822bfa4baea23a3d9273df266777f3ab796John McCall 294987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Iterate through all blocks, skipping those prior to the try. 295087bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::Function::iterator 295187bb5822bfa4baea23a3d9273df266777f3ab796John McCall FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) { 295287bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::BasicBlock &BB = *FI; 295387bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (BlocksBeforeTry.count(&BB)) continue; 295487bb5822bfa4baea23a3d9273df266777f3ab796John McCall 295587bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Walk through all the calls in the block. 295687bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::BasicBlock::iterator 295787bb5822bfa4baea23a3d9273df266777f3ab796John McCall BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) { 295887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::Instruction &I = *BI; 295987bb5822bfa4baea23a3d9273df266777f3ab796John McCall 296087bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Ignore instructions that aren't non-intrinsic calls. 296187bb5822bfa4baea23a3d9273df266777f3ab796John McCall // These are the only calls that can possibly call longjmp. 296287bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue; 296387bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (isa<llvm::IntrinsicInst>(I)) 296487bb5822bfa4baea23a3d9273df266777f3ab796John McCall continue; 296587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 296687bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Ignore call sites marked nounwind. This may be questionable, 296787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // since 'nounwind' doesn't necessarily mean 'does not call longjmp'. 296887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::CallSite CS(&I); 296987bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (CS.doesNotThrow()) continue; 297087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 29710b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Insert a read hazard before the call. This will ensure that 29720b2517299415ab1c28b9cb87d536ccea84317a10John McCall // any writes to the locals are performed before making the 29730b2517299415ab1c28b9cb87d536ccea84317a10John McCall // call. If the call throws, then this is sufficient to 29740b2517299415ab1c28b9cb87d536ccea84317a10John McCall // guarantee correctness as long as it doesn't also write to any 29750b2517299415ab1c28b9cb87d536ccea84317a10John McCall // locals. 297687bb5822bfa4baea23a3d9273df266777f3ab796John McCall Builder.SetInsertPoint(&BB, BI); 297787bb5822bfa4baea23a3d9273df266777f3ab796John McCall emitReadHazard(Builder); 297887bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 297987bb5822bfa4baea23a3d9273df266777f3ab796John McCall } 298087bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 298187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 298287bb5822bfa4baea23a3d9273df266777f3ab796John McCallstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) { 298387bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (V) S.insert(V); 298487bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 298587bb5822bfa4baea23a3d9273df266777f3ab796John McCall 298687bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::collectLocals() { 298787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Compute a set of allocas to ignore. 298887bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::DenseSet<llvm::Value*> AllocasToIgnore; 298987bb5822bfa4baea23a3d9273df266777f3ab796John McCall addIfPresent(AllocasToIgnore, CGF.ReturnValue); 299087bb5822bfa4baea23a3d9273df266777f3ab796John McCall addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest); 299187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 299287bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Collect all the allocas currently in the function. This is 299387bb5822bfa4baea23a3d9273df266777f3ab796John McCall // probably way too aggressive. 299487bb5822bfa4baea23a3d9273df266777f3ab796John McCall llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock(); 299587bb5822bfa4baea23a3d9273df266777f3ab796John McCall for (llvm::BasicBlock::iterator 299687bb5822bfa4baea23a3d9273df266777f3ab796John McCall I = Entry.begin(), E = Entry.end(); I != E; ++I) 299787bb5822bfa4baea23a3d9273df266777f3ab796John McCall if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I)) 299887bb5822bfa4baea23a3d9273df266777f3ab796John McCall Locals.push_back(&*I); 299987bb5822bfa4baea23a3d9273df266777f3ab796John McCall} 300087bb5822bfa4baea23a3d9273df266777f3ab796John McCall 300187bb5822bfa4baea23a3d9273df266777f3ab796John McCallllvm::FunctionType *FragileHazards::GetAsmFnType() { 30025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type *, 16> tys(Locals.size()); 30030774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall for (unsigned i = 0, e = Locals.size(); i != e; ++i) 30040774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall tys[i] = Locals[i]->getType(); 30050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall return llvm::FunctionType::get(CGF.VoidTy, tys, false); 3006cc5052999cd064584492ba15a808b6e1cee6d931John McCall} 3007cc5052999cd064584492ba15a808b6e1cee6d931John McCall 30086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/* 300918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 30106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Objective-C setjmp-longjmp (sjlj) Exception Handling 30116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar -- 301218ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 3013f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall A catch buffer is a setjmp buffer plus: 3014f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - a pointer to the exception that was caught 3015f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - a pointer to the previous exception data buffer 3016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall - two pointers of reserved storage 3017f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Therefore catch buffers form a stack, with a pointer to the top 3018f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall of the stack kept in thread-local storage. 3019f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3020f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_try_enter pushes a catch buffer onto the EH stack. 3021f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_try_exit pops the given catch buffer, which is 3022f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall required to be the top of the EH stack. 3023f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_throw pops the top of the EH stack, writes the 3024f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall thrown exception into the appropriate field, and longjmps 3025f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall to the setjmp buffer. It crashes the process (with a printf 3026f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall and an abort()) if there are no catch buffers on the stack. 3027f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_exception_extract just reads the exception pointer out of the 3028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall catch buffer. 3029f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall There's no reason an implementation couldn't use a light-weight 3031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall setjmp here --- something like __builtin_setjmp, but API-compatible 3032f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall with the heavyweight setjmp. This will be more important if we ever 3033f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall want to implement correct ObjC/C++ exception interactions for the 3034f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall fragile ABI. 3035f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3036f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Note that for this use of setjmp/longjmp to be correct, we may need 3037f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall to mark some local variables volatile: if a non-volatile local 3038f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall variable is modified between the setjmp and the longjmp, it has 3039f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall indeterminate value. For the purposes of LLVM IR, it may be 3040f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall sufficient to make loads and stores within the @try (to variables 3041f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall declared outside the @try) volatile. This is necessary for 3042f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall optimized correctness, but is not currently being done; this is 3043f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall being tracked as rdar://problem/8160285 3044f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 30456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar The basic framework for a @try-catch-finally is as follows: 30466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar { 304718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar objc_exception_data d; 304818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar id _rethrow = null; 3049190d00e1396214c77539c7095756b9ea38160463Anders Carlsson bool _call_try_exit = true; 30506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 305118ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar objc_exception_try_enter(&d); 305218ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar if (!setjmp(d.jmp_buf)) { 30536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... try body ... 305418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar } else { 30556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // exception path 30566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar id _caught = objc_exception_extract(&d); 30576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // enter new try scope for handlers 30596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (!setjmp(d.jmp_buf)) { 30606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... match exception and execute catch blocks ... 30616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // fell off end, rethrow. 30636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _rethrow = _caught; 30646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... jump-through-finally to finally_rethrow ... 30656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } else { 30666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // exception in catch block 30676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _rethrow = objc_exception_extract(&d); 30686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar _call_try_exit = false; 30696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ... jump-through-finally to finally_rethrow ... 30706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 307118ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar } 3072898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar ... jump-through-finally to finally_end ... 307318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 30746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally: 3075190d00e1396214c77539c7095756b9ea38160463Anders Carlsson if (_call_try_exit) 30766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar objc_exception_try_exit(&d); 3077190d00e1396214c77539c7095756b9ea38160463Anders Carlsson 307818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar ... finally block .... 3079898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar ... dispatch to finally destination ... 3080898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 30816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally_rethrow: 3082898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar objc_exception_throw(_rethrow); 3083898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 30846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar finally_end: 30856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 30866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar This framework differs slightly from the one gcc uses, in that gcc 30886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uses _rethrow to determine if objc_exception_try_exit should be called 30896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar and if the object should be rethrown. This breaks in the face of 30906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar throwing nil and introduces unnecessary branches. 30916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar We specialize this framework for a few particular circumstances: 30936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - If there are no catch blocks, then we avoid emitting the second 30956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar exception handling context. 30966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 30976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 30986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar e)) we avoid emitting the code to rethrow an uncaught exception. 309918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 31006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar - FIXME: If there is no @finally block we can do a few more 31016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar simplifications. 31026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 31036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Rethrows and Jumps-Through-Finally 31046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar -- 31056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3106f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall '@throw;' is supported by pushing the currently-caught exception 3107f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall onto ObjCEHStack while the @catch blocks are emitted. 3108f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3109f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Branches through the @finally block are handled with an ordinary 3110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC 3111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall exceptions are not compatible with C++ exceptions, and this is 3112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall hardly the only place where this will go wrong. 3113f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3114f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall @synchronized(expr) { stmt; } is emitted as if it were: 3115f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall id synch_value = expr; 3116f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall objc_sync_enter(synch_value); 3117f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall @try { stmt; } @finally { objc_sync_exit(synch_value); } 311818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar*/ 311918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 3120bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanianvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 3121bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian const Stmt &S) { 3122bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian bool isTry = isa<ObjCAtTryStmt>(S); 3123f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3124f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // A destination for the fall-through edges of the catch handlers to 3125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // jump to. 3126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::JumpDest FinallyEnd = 3127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.getJumpDestInCurrentScope("finally.end"); 3128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3129f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // A destination for the rethrow edge of the catch handlers to jump 3130f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // to. 3131f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::JumpDest FinallyRethrow = 3132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.getJumpDestInCurrentScope("finally.rethrow"); 31336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 31341c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar // For @synchronized, call objc_sync_enter(sync.expr). The 31351c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar // evaluation of the expression must occur before we enter the 31360b2517299415ab1c28b9cb87d536ccea84317a10John McCall // @synchronized. We can't avoid a temp here because we need the 31370b2517299415ab1c28b9cb87d536ccea84317a10John McCall // value to be preserved. If the backend ever does liveness 31380b2517299415ab1c28b9cb87d536ccea84317a10John McCall // correctly after setjmp, this will be unnecessary. 31390b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArgSlot = 0; 31401c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar if (!isTry) { 31410b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *SyncArg = 31421c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 31431c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 3144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg) 3145f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 31460b2517299415ab1c28b9cb87d536ccea84317a10John McCall 31470b2517299415ab1c28b9cb87d536ccea84317a10John McCall SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg"); 31480b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(SyncArg, SyncArgSlot); 31491c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar } 3150898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 31510b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Allocate memory for the setjmp buffer. This needs to be kept 31520b2517299415ab1c28b9cb87d536ccea84317a10John McCall // live throughout the try and catch blocks. 31530b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 31540b2517299415ab1c28b9cb87d536ccea84317a10John McCall "exceptiondata.ptr"); 31550b2517299415ab1c28b9cb87d536ccea84317a10John McCall 315687bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Create the fragile hazards. Note that this will not capture any 315787bb5822bfa4baea23a3d9273df266777f3ab796John McCall // of the allocas required for exception processing, but will 315887bb5822bfa4baea23a3d9273df266777f3ab796John McCall // capture the current basic block (which extends all the way to the 315987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // setjmp call) as "before the @try". 316087bb5822bfa4baea23a3d9273df266777f3ab796John McCall FragileHazards Hazards(CGF); 316187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 3162f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create a flag indicating whether the cleanup needs to call 3163f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // objc_exception_try_exit. This is true except when 3164f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - no catches match and we're branching through the cleanup 3165f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // just to rethrow the exception, or 3166f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - a catch matched and we're falling out of the catch handler. 31670b2517299415ab1c28b9cb87d536ccea84317a10John McCall // The setjmp-safety rule here is that we should always store to this 31680b2517299415ab1c28b9cb87d536ccea84317a10John McCall // variable in a place that dominates the branch through the cleanup 31690b2517299415ab1c28b9cb87d536ccea84317a10John McCall // without passing through any setjmps. 3170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), 3171190d00e1396214c77539c7095756b9ea38160463Anders Carlsson "_call_try_exit"); 3172f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 31739e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // A slot containing the exception to rethrow. Only needed when we 31749e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // have both a @catch and a @finally. 31759e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::Value *PropagatingExnVar = 0; 31769e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 3177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Push a normal cleanup to leave the try scope. 31781f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S, 31790b2517299415ab1c28b9cb87d536ccea84317a10John McCall SyncArgSlot, 31801f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CallTryExitVar, 31811f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall ExceptionData, 31821f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall &ObjCTypes); 31836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3184f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Enter a try block: 3185f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - Call objc_exception_try_enter to push ExceptionData on top of 3186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the EH stack. 3187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 3188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 3189898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 3190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - Call setjmp on the exception data buffer. 3191f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); 3192f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; 3193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *SetJmpBuffer = 31940f6ac7cf7bc6a02c1a5c19d2c90ec0d1dd7786e7Jay Foad CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer"); 3195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *SetJmpResult = 3196f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); 3197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall SetJmpResult->setDoesNotThrow(); 31986446c3e3600032c5f17ca2324a4581b9301afa59Bill Wendling SetJmpResult->setCanReturnTwice(); 3199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3200f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If setjmp returned 0, enter the protected block; otherwise, 3201f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // branch to the handler. 320255e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 320355e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 3204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *DidCatch = 3205d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 3206d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock); 320780f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 3208f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the protected block. 320980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(TryBlock); 32100b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 32116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 3212f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 32130b2517299415ab1c28b9cb87d536ccea84317a10John McCall 32140b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP(); 32156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3216f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the exception handler block. 3217e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar CGF.EmitBlock(TryHandler); 321855e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar 321987bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Don't optimize loads of the in-scope locals across this point. 322087bb5822bfa4baea23a3d9273df266777f3ab796John McCall Hazards.emitWriteHazard(); 322187bb5822bfa4baea23a3d9273df266777f3ab796John McCall 3222f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // For a @synchronized (or a @try with no catches), just branch 3223f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // through the cleanup to the rethrow block. 3224f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) { 3225f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Tell the cleanup not to re-pop the exit. 32260b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 3227f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyRethrow); 3228f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, we have to match against the caught exceptions. 3230f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 32310b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Retrieve the exception object. We may emit multiple blocks but 32320b2517299415ab1c28b9cb87d536ccea84317a10John McCall // nothing can cross this so the value is already in SSA form. 32330b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::CallInst *Caught = 32340b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 32350b2517299415ab1c28b9cb87d536ccea84317a10John McCall ExceptionData, "caught"); 32360b2517299415ab1c28b9cb87d536ccea84317a10John McCall Caught->setDoesNotThrow(); 32370b2517299415ab1c28b9cb87d536ccea84317a10John McCall 3238f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Push the exception to rethrow onto the EH value stack for the 3239f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // benefit of any @throws in the handlers. 3240f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.ObjCEHValueStack.push_back(Caught); 3241f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 32428f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S); 3243f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 32440b2517299415ab1c28b9cb87d536ccea84317a10John McCall bool HasFinally = (AtTryStmt->getFinallyStmt() != 0); 32450b2517299415ab1c28b9cb87d536ccea84317a10John McCall 32460b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::BasicBlock *CatchBlock = 0; 32470b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::BasicBlock *CatchHandler = 0; 32480b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (HasFinally) { 32499e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Save the currently-propagating exception before 32509e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // objc_exception_try_enter clears the exception slot. 32519e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(), 32529e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall "propagating_exception"); 32539e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateStore(Caught, PropagatingExnVar); 32549e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 32550b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Enter a new exception try block (in case a @catch block 32560b2517299415ab1c28b9cb87d536ccea84317a10John McCall // throws an exception). 32570b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 32580b2517299415ab1c28b9cb87d536ccea84317a10John McCall ->setDoesNotThrow(); 32590b2517299415ab1c28b9cb87d536ccea84317a10John McCall 32600b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::CallInst *SetJmpResult = 32610b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, 32620b2517299415ab1c28b9cb87d536ccea84317a10John McCall "setjmp.result"); 32630b2517299415ab1c28b9cb87d536ccea84317a10John McCall SetJmpResult->setDoesNotThrow(); 32646446c3e3600032c5f17ca2324a4581b9301afa59Bill Wendling SetJmpResult->setCanReturnTwice(); 32650b2517299415ab1c28b9cb87d536ccea84317a10John McCall 32660b2517299415ab1c28b9cb87d536ccea84317a10John McCall llvm::Value *Threw = 32670b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 32686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 32690b2517299415ab1c28b9cb87d536ccea84317a10John McCall CatchBlock = CGF.createBasicBlock("catch"); 32700b2517299415ab1c28b9cb87d536ccea84317a10John McCall CatchHandler = CGF.createBasicBlock("catch_for_catch"); 32710b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 327280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 32730b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(CatchBlock); 32740b2517299415ab1c28b9cb87d536ccea84317a10John McCall } 32756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 32760b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar); 32776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 327855e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // Handle catch list. As a special case we check if everything is 327955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // matched and avoid generating code for falling off the end if 328055e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar // so. 328155e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar bool AllMatched = false; 32828f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) { 32838f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I); 328480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 3285c00d8e18ad3d903acfeb5d05163ce90713066a3fDouglas Gregor const VarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 328614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff const ObjCObjectPointerType *OPT = 0; 3287129271a42975f8b9d42adc707be9883db91c8a5dDaniel Dunbar 328880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // catch(...) always matches. 328955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar if (!CatchParam) { 329055e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar AllMatched = true; 329155e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar } else { 3292183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>(); 32936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // catch(id e) always matches under this ABI, since only 3295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ObjC exceptions end up here in the first place. 329697f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar // FIXME: For the time being we also match id<X>; this should 329797f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar // be rejected by Sema instead. 3298818e96f5a42b2a9adea4ac0050340469b49d70efEli Friedman if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())) 329955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar AllMatched = true; 330080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 33016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3302f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If this is a catch-all, we don't need to test anything. 33036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (AllMatched) { 3304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3306dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson if (CatchParam) { 3307b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall CGF.EmitAutoVarDecl(*CatchParam); 3308a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 3309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3310f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // These types work out because ConvertType(id) == i8*. 33117ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 3312dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson } 33136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3314dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson CGF.EmitStmt(CatchStmt->getCatchBody()); 3315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The scope of the catch variable ends right here. 3317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchVarCleanups.ForceCleanup(); 3318f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3319f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyEnd); 332080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson break; 332180f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 33226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 332314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff assert(OPT && "Unexpected non-object pointer type in @catch"); 3324506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall const ObjCObjectType *ObjTy = OPT->getObjectType(); 3325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // FIXME: @catch (Class c) ? 3327506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *IDecl = ObjTy->getInterface(); 3328506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall assert(IDecl && "Catch parameter must have Objective-C type!"); 332980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 333080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // Check if the @catch block matches the exception object. 3331506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl); 33326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Match = 333434b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 333534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner Class, Caught, "match"); 3336f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Match->setDoesNotThrow(); 33376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3338f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match"); 3339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next"); 33406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 33416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 3342e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar MatchedBlock, NextCatchBlock); 33436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 334480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson // Emit the @catch block. 334580f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(MatchedBlock); 3346f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3347f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Collect any cleanups for the catch variable. The scope lasts until 3348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the end of the catch body. 33490b2517299415ab1c28b9cb87d536ccea84317a10John McCall CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3350f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3351b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall CGF.EmitAutoVarDecl(*CatchParam); 3352a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 335318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar 3354f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Initialize the catch variable. 33556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *Tmp = 33566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGF.Builder.CreateBitCast(Caught, 3357578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer CGF.ConvertType(CatchParam->getType())); 33587ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 33596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3360dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson CGF.EmitStmt(CatchStmt->getCatchBody()); 3361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3362f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We're done with the catch variable. 3363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchVarCleanups.ForceCleanup(); 3364f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 3365f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyEnd); 33666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 336780f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.EmitBlock(NextCatchBlock); 336880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 336980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 3370f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.ObjCEHValueStack.pop_back(); 3371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 33720b2517299415ab1c28b9cb87d536ccea84317a10John McCall // If nothing wanted anything to do with the caught exception, 33730b2517299415ab1c28b9cb87d536ccea84317a10John McCall // kill the extract call. 33740b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (Caught->use_empty()) 33750b2517299415ab1c28b9cb87d536ccea84317a10John McCall Caught->eraseFromParent(); 33760b2517299415ab1c28b9cb87d536ccea84317a10John McCall 33770b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (!AllMatched) 3378f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson CGF.EmitBranchThroughCleanup(FinallyRethrow); 33796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 33800b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (HasFinally) { 33810b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Emit the exception handler for the @catch blocks. 33820b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(CatchHandler); 3383f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 33840b2517299415ab1c28b9cb87d536ccea84317a10John McCall // In theory we might now need a write hazard, but actually it's 33850b2517299415ab1c28b9cb87d536ccea84317a10John McCall // unnecessary because there's no local-accessing code between 33860b2517299415ab1c28b9cb87d536ccea84317a10John McCall // the try's write hazard and here. 33870b2517299415ab1c28b9cb87d536ccea84317a10John McCall //Hazards.emitWriteHazard(); 3388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 33899e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Extract the new exception and save it to the 33909e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // propagating-exception slot. 33919e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall assert(PropagatingExnVar); 33929e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::CallInst *NewCaught = 33939e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 33949e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall ExceptionData, "caught"); 33959e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall NewCaught->setDoesNotThrow(); 33969e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateStore(NewCaught, PropagatingExnVar); 33979e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 33980b2517299415ab1c28b9cb87d536ccea84317a10John McCall // Don't pop the catch handler; the throw already did. 33990b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 34000b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBranchThroughCleanup(FinallyRethrow); 34010b2517299415ab1c28b9cb87d536ccea84317a10John McCall } 340280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson } 34036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 340487bb5822bfa4baea23a3d9273df266777f3ab796John McCall // Insert read hazards as required in the new blocks. 34050b2517299415ab1c28b9cb87d536ccea84317a10John McCall Hazards.emitHazardsInNewBlocks(); 340687bb5822bfa4baea23a3d9273df266777f3ab796John McCall 3407f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Pop the cleanup. 34080b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.restoreIP(TryFallthroughIP); 34090b2517299415ab1c28b9cb87d536ccea84317a10John McCall if (CGF.HaveInsertPoint()) 34100b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 3411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.PopCleanupBlock(); 34120b2517299415ab1c28b9cb87d536ccea84317a10John McCall CGF.EmitBlock(FinallyEnd.getBlock(), true); 34136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3414f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the rethrow block. 341587bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 3416ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall CGF.EmitBlock(FinallyRethrow.getBlock(), true); 3417f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (CGF.HaveInsertPoint()) { 34189e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // If we have a propagating-exception variable, check it. 34199e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::Value *PropagatingExn; 34209e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall if (PropagatingExnVar) { 34219e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar); 34229e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall 34239e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall // Otherwise, just look in the buffer for the exception to throw. 34249e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall } else { 34259e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall llvm::CallInst *Caught = 34269e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 34279e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall ExceptionData); 34289e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall Caught->setDoesNotThrow(); 34299e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall PropagatingExn = Caught; 34309e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall } 34310b2517299415ab1c28b9cb87d536ccea84317a10John McCall 34329e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn) 3433f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 3434f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateUnreachable(); 3435f2878e5dffd20bf0a97fb0b30a376f2d60963593Fariborz Jahanian } 343680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson 343787bb5822bfa4baea23a3d9273df266777f3ab796John McCall CGF.Builder.restoreIP(SavedIP); 343864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson} 343964d5d6c5903157c521af496479d06dc26032d718Anders Carlsson 344064d5d6c5903157c521af496479d06dc26032d718Anders Carlssonvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 3441898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar const ObjCAtThrowStmt &S) { 34422b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson llvm::Value *ExceptionAsObject; 34436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 34442b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson if (const Expr *ThrowExpr = S.getThrowExpr()) { 34452b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 34466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ExceptionAsObject = 3447578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 34482b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson } else { 34496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 345018ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar "Unexpected rethrow outside @catch block."); 3451273558fbd891a0872e620e0d3d109b92c1160d72Anders Carlsson ExceptionAsObject = CGF.ObjCEHValueStack.back(); 34522b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson } 34536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3454f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject) 3455f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotReturn(); 345680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson CGF.Builder.CreateUnreachable(); 3457a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 3458a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 3459a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar CGF.Builder.ClearInsertionPoint(); 346064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson} 346164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson 34623e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak 34636dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// object: objc_read_weak (id *src) 34646dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// 34653e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 34661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *AddrWeakObj) { 34672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type* DestTy = 34686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 34696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, 34706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.PtrObjectPtrTy); 347172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 34723e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian AddrWeakObj, "weakread"); 34738339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 34746dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian return read_weak; 34756dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian} 34766dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian 34773e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 34783e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// objc_assign_weak (id src, id *dst) 34793e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// 34803e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 34811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 34822acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 34830a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 34849408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 34850a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 34860a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 34876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 34883b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 34893b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3490dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3491dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 349296508e1fea58347b6401ca9a4728c0b268174603Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 34933e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian src, dst, "weakassign"); 34943e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian return; 34953e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian} 34963e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian 349758626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 349858626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_global (id src, id *dst) 349958626500527695865683d1d65053743de8770b60Fariborz Jahanian/// 350058626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 3501021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dst, 3502021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal) { 35032acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 35040a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 35059408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 35060a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 35070a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 35086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 35093b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 35103b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3511dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3512dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3513021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian if (!threadlocal) 3514021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 3515021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "globalassign"); 3516021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian else 3517021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 3518021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "threadlocalassign"); 351958626500527695865683d1d65053743de8770b60Fariborz Jahanian return; 352058626500527695865683d1d65053743de8770b60Fariborz Jahanian} 352158626500527695865683d1d65053743de8770b60Fariborz Jahanian 35227eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 35236c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) 35247eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// 35257eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanianvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 35266c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *src, llvm::Value *dst, 35276c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset) { 35286c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); 35292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 35300a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 35319408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 35320a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 35330a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 35346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 35353b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 35363b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 35377eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 35387eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 35396c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 35406c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian src, dst, ivarOffset); 35417eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian return; 35427eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian} 35437eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian 354458626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 354558626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst) 354658626500527695865683d1d65053743de8770b60Fariborz Jahanian/// 354758626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 35481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 35492acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 35500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 35519408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 35520a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 35530a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 35546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 35553b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 35563b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 3557dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3558dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3559bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 356058626500527695865683d1d65053743de8770b60Fariborz Jahanian src, dst, "weakassign"); 356158626500527695865683d1d65053743de8770b60Fariborz Jahanian return; 356258626500527695865683d1d65053743de8770b60Fariborz Jahanian} 356358626500527695865683d1d65053743de8770b60Fariborz Jahanian 3564082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 35656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *DestPtr, 35666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *SrcPtr, 356755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *size) { 3568082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 3569082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 3570082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 357155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian DestPtr, SrcPtr, size); 3572082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return; 3573082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian} 3574082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian 35750bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// EmitObjCValueForIvar - Code Gen for ivar reference. 35760bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// 3577598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 3578598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian QualType ObjectTy, 3579598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian llvm::Value *BaseValue, 3580598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian const ObjCIvarDecl *Ivar, 3581598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian unsigned CVRQualifiers) { 3582c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall const ObjCInterfaceDecl *ID = 3583c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall ObjectTy->getAs<ObjCObjectType>()->getInterface(); 35849777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 35859777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar EmitIvarOffset(CGF, ID, Ivar)); 35860bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian} 35870bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian 3588f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 35892a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar const ObjCInterfaceDecl *Interface, 3590f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian const ObjCIvarDecl *Ivar) { 35919777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 35924a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson return llvm::ConstantInt::get( 35936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getTypes().ConvertType(CGM.getContext().LongTy), 35946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Offset); 3595f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian} 3596f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian 3597f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** Private Interface *** */ 3598f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 3599f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// EmitImageInfo - Emit the image info marker used to encode some module 3600f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// level information. 3601f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// 3602f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// See: <rdr://4810609&4810587&4810587> 3603f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// struct IMAGE_INFO { 3604f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// unsigned version; 3605f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// unsigned flags; 3606f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// }; 3607f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarenum ImageInfoFlags { 3608fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar eImageInfo_FixAndContinue = (1 << 0), 36096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar eImageInfo_GarbageCollected = (1 << 1), 36106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar eImageInfo_GCOnly = (1 << 2), 3611c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 3612c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar 3613fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar // A flag indicating that the module has no instances of a @synthesize of a 3614fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar // superclass variable. <rdar://problem/6803242> 36150982251be96409814c69d03193b558c7a927e1e8Bill Wendling eImageInfo_CorrectedSynthesize = (1 << 4), 36160982251be96409814c69d03193b558c7a927e1e8Bill Wendling eImageInfo_ImageIsSimulated = (1 << 5) 3617f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}; 3618f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 3619fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbarvoid CGObjCCommonMac::EmitImageInfo() { 3620f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar unsigned version = 0; // Version is unused? 36213973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling const char *Section = (ObjCABI == 1) ? 36223973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling "__OBJC, __image_info,regular" : 36233973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling "__DATA, __objc_imageinfo, regular, no_dead_strip"; 36243973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling 36253973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Generate module-level named metadata to convey this information to the 36263973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // linker and code-gen. 36273973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::Module &Mod = CGM.getModule(); 36283973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling 36293973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Add the ObjC ABI version to the module flags. 36303973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI); 36313973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version", 36323973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling version); 36333973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section", 36343973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::MDString::get(VMContext,Section)); 36353973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling 36364e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 36373973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Non-GC overrides those files which specify GC. 36383973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Override, 36393973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling "Objective-C Garbage Collection", (uint32_t)0); 36403973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling } else { 36413973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Add the ObjC garbage collection value. 36423973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Error, 36433973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling "Objective-C Garbage Collection", 36443973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling eImageInfo_GarbageCollected); 36453973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling 36464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 36473973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Add the ObjC GC Only value. 36483973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only", 36493973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling eImageInfo_GCOnly); 36503973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling 36513973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling // Require that GC be specified and set to eImageInfo_GarbageCollected. 36523973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::Value *Ops[2] = { 36533973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::MDString::get(VMContext, "Objective-C Garbage Collection"), 36543973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 36553973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling eImageInfo_GarbageCollected) 36563973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling }; 36573973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only", 36583973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling llvm::MDNode::get(VMContext, Ops)); 36593973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling } 36603973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling } 36610982251be96409814c69d03193b558c7a927e1e8Bill Wendling 36620982251be96409814c69d03193b558c7a927e1e8Bill Wendling // Indicate whether we're compiling this to run on a simulator. 36630982251be96409814c69d03193b558c7a927e1e8Bill Wendling const llvm::Triple &Triple = CGM.getTarget().getTriple(); 36640982251be96409814c69d03193b558c7a927e1e8Bill Wendling if (Triple.getOS() == llvm::Triple::IOS && 36650982251be96409814c69d03193b558c7a927e1e8Bill Wendling (Triple.getArch() == llvm::Triple::x86 || 36660982251be96409814c69d03193b558c7a927e1e8Bill Wendling Triple.getArch() == llvm::Triple::x86_64)) 36670982251be96409814c69d03193b558c7a927e1e8Bill Wendling Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated", 36680982251be96409814c69d03193b558c7a927e1e8Bill Wendling eImageInfo_ImageIsSimulated); 3669f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar} 3670f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 36714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// struct objc_module { 36724e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// unsigned long version; 36734e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// unsigned long size; 36744e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// const char *name; 36754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// Symtab symtab; 36764e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// }; 36774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 36784e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// FIXME: Get from somewhere 36794e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarstatic const int ModuleVersion = 7; 36804e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 36814e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarvoid CGObjCMac::EmitModuleInfo() { 36829408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 36836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 36841d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 36851d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion), 36861d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantInt::get(ObjCTypes.LongTy, Size), 36871d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer // This used to be the filename, now it is unused. <rdr://4327263> 36881d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(&CGM.getContext().Idents.get("")), 36891d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer EmitModuleSymbols() 36901d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 36916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CreateMetadataVar("\01L_OBJC_MODULES", 369208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 369363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__module_info,regular,no_dead_strip", 369458a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar 4, true); 36954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 36964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 36974e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarllvm::Constant *CGObjCMac::EmitModuleSymbols() { 369827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned NumClasses = DefinedClasses.size(); 369927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar unsigned NumCategories = DefinedCategories.size(); 370027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3701242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Return null if no symbols were defined. 3702242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar if (!NumClasses && !NumCategories) 3703c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 3704242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar 3705c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[5]; 37064a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 3707c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 37084a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 37094a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 371027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 371186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // The runtime expects exactly the list of defined classes followed 371286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar // by the list of defined categories, in a single array. 37130b2397132efe74ee11c1b371dd9033820c54240fChris Lattner SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories); 371486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar for (unsigned i=0; i<NumClasses; i++) 37153c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 371686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar ObjCTypes.Int8PtrTy); 371786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar for (unsigned i=0; i<NumCategories; i++) 37186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Symbols[NumClasses + i] = 37193c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(DefinedCategories[i], 372086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar ObjCTypes.Int8PtrTy); 372186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 37226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = 372396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 37240b2397132efe74ee11c1b371dd9033820c54240fChris Lattner Symbols.size()), 372527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar Symbols); 372627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3727c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 372827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 37294e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar llvm::GlobalVariable *GV = 373063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 373163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__symbols,regular,no_dead_strip", 37320bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 37333c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 373427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 373527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 3736f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder, 3737f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II) { 3738f85e193739c953358c865005855253af4f68a497John McCall LazySymbols.insert(II); 3739f85e193739c953358c865005855253af4f68a497John McCall 3740f85e193739c953358c865005855253af4f68a497John McCall llvm::GlobalVariable *&Entry = ClassReferences[II]; 3741f85e193739c953358c865005855253af4f68a497John McCall 374227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar if (!Entry) { 37436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 3744f85e193739c953358c865005855253af4f68a497John McCall llvm::ConstantExpr::getBitCast(GetClassName(II), 3745f85e193739c953358c865005855253af4f68a497John McCall ObjCTypes.ClassPtrTy); 37466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 3747f85e193739c953358c865005855253af4f68a497John McCall CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 3748f85e193739c953358c865005855253af4f68a497John McCall "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 3749f85e193739c953358c865005855253af4f68a497John McCall 4, true); 375027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar } 3751f85e193739c953358c865005855253af4f68a497John McCall 3752578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 37534e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 37544e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 3755f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 3756f85e193739c953358c865005855253af4f68a497John McCall const ObjCInterfaceDecl *ID) { 3757f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, ID->getIdentifier()); 3758f85e193739c953358c865005855253af4f68a497John McCall} 3759f85e193739c953358c865005855253af4f68a497John McCall 3760f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) { 3761f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 3762f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, II); 3763f85e193739c953358c865005855253af4f68a497John McCall} 3764f85e193739c953358c865005855253af4f68a497John McCall 376503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel, 376603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian bool lvalue) { 3767259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 37686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3769259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar if (!Entry) { 37706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 37713c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 3772259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar ObjCTypes.SelectorPtrTy); 37736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 377463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 377563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__OBJC,__message_refs,literal_pointers,no_dead_strip", 37760bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar 4, true); 3777259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar } 3778259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 377903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian if (lvalue) 378003b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return Entry; 3781578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 3782259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar} 3783259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 3784058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 37856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar llvm::GlobalVariable *&Entry = ClassNames[Ident]; 37864e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 378763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 37886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 378994010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, 379094010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner Ident->getNameStart()), 3791af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 3792af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_classname,cstring_literals" : 3793af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 3794b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 37954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 3796a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 37974e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar} 37984e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 37999d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidisllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 38009d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 38019d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis I = MethodDefinitions.find(MD); 38029d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis if (I != MethodDefinitions.end()) 38039d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis return I->second; 38049d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 38059d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis return NULL; 38069d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis} 38079d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis 3808d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// GetIvarLayoutName - Returns a unique constant for the given 3809d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// ivar layout bitmap. 3810d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 38116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCommonTypesHelper &ObjCTypes) { 3812c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3813d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian} 3814d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian 3815d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 38166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, 3817d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar bool ForStrongLayout, 3818d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar bool &HasUnion) { 3819d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar const RecordDecl *RD = RT->getDecl(); 3820d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar // FIXME - Use iterator. 3821262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie SmallVector<const FieldDecl*, 16> Fields; 3822262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie for (RecordDecl::field_iterator i = RD->field_begin(), 3823262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie e = RD->field_end(); i != e; ++i) 3824581deb3da481053c4993c7600f97acf7768caac5David Blaikie Fields.push_back(*i); 38252acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 38266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const llvm::StructLayout *RecLayout = 3827d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 38286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3829d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 3830d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 3831d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar} 3832d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar 38335a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 38346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const llvm::StructLayout *Layout, 38356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const RecordDecl *RD, 3836795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling ArrayRef<const FieldDecl*> RecFields, 38376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int BytePos, bool ForStrongLayout, 38386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool &HasUnion) { 3839820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian bool IsUnion = (RD && RD->isUnion()); 3840820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t MaxUnionIvarSize = 0; 3841820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t MaxSkippedUnionIvarSize = 0; 3842db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *MaxField = 0; 3843db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *MaxSkippedField = 0; 3844db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *LastFieldBitfieldOrUnnamed = 0; 3845900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar uint64_t MaxFieldOffset = 0; 3846900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar uint64_t MaxSkippedFieldOffset = 0; 38470dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis uint64_t LastBitfieldOrUnnamedOffset = 0; 3848f85e193739c953358c865005855253af4f68a497John McCall uint64_t FirstFieldDelta = 0; 38496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3850a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian if (RecFields.empty()) 3851a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian return; 3852bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); 3853bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); 38544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!RD && CGM.getLangOpts().ObjCAutoRefCount) { 3855db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *FirstField = RecFields[0]; 3856f85e193739c953358c865005855253af4f68a497John McCall FirstFieldDelta = 3857f85e193739c953358c865005855253af4f68a497John McCall ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField)); 3858f85e193739c953358c865005855253af4f68a497John McCall } 3859f85e193739c953358c865005855253af4f68a497John McCall 3860f1690858344968358131f8d5690d9ee458883000Chris Lattner for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 3861db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl *Field = RecFields[i]; 3862e05cc98e97ec910829beccd0d890a002ce5ab909Daniel Dunbar uint64_t FieldOffset; 3863fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson if (RD) { 3864f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar // Note that 'i' here is actually the field index inside RD of Field, 3865f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar // although this dependency is hidden. 3866f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); 3867f85e193739c953358c865005855253af4f68a497John McCall FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta; 3868fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson } else 3869f85e193739c953358c865005855253af4f68a497John McCall FieldOffset = 3870f85e193739c953358c865005855253af4f68a497John McCall ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta; 387125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar 3872a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian // Skip over unnamed or bitfields 38737fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian if (!Field->getIdentifier() || Field->isBitField()) { 38740dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastFieldBitfieldOrUnnamed = Field; 38750dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastBitfieldOrUnnamedOffset = FieldOffset; 3876a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian continue; 38777fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian } 387825d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar 38790dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis LastFieldBitfieldOrUnnamed = 0; 3880a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian QualType FQT = Field->getType(); 3881667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian if (FQT->isRecordType() || FQT->isUnionType()) { 3882a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian if (FQT->isUnionType()) 3883a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian HasUnion = true; 3884820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian 38856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), 388625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar BytePos + FieldOffset, 3887d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 3888a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian continue; 3889a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian } 38906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3891f1690858344968358131f8d5690d9ee458883000Chris Lattner if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 38926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ConstantArrayType *CArray = 38935e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar dyn_cast_or_null<ConstantArrayType>(Array); 38947fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian uint64_t ElCount = CArray->getSize().getZExtValue(); 38955e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar assert(CArray && "only array with known element size is supported"); 3896820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian FQT = CArray->getElementType(); 3897667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3898667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian const ConstantArrayType *CArray = 38995e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar dyn_cast_or_null<ConstantArrayType>(Array); 39007fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian ElCount *= CArray->getSize().getZExtValue(); 3901667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian FQT = CArray->getElementType(); 3902667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian } 39036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 39046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert(!FQT->isUnionType() && 3905820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian "layout for array of unions not supported"); 3906f96bdf409fc9e5570e35aaf8a9167265e63d58d8Fariborz Jahanian if (FQT->isRecordType() && ElCount) { 390781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int OldIndex = IvarsInfo.size() - 1; 390881adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int OldSkIndex = SkipIvars.size() -1; 39096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 39106217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = FQT->getAs<RecordType>(); 391125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 3912d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar ForStrongLayout, HasUnion); 39136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 3914820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // Replicate layout information for each array element. Note that 3915820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // one element is already done. 3916820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian uint64_t ElIx = 1; 39176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (int FirstIndex = IvarsInfo.size() - 1, 39186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 3919c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 39208b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar for (int i = OldIndex+1; i <= FirstIndex; ++i) 39218b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 39228b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar IvarsInfo[i].ivar_size)); 39238b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 39248b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 39258b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar SkipIvars[i].ivar_size)); 3926820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3927820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian continue; 3928820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3929a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian } 3930820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // At this point, we are done with Record/Union and array there of. 3931820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian // For other arrays we are down to its element type. 39320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 39335e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar 39348b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 39350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 39360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 3937487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (IsUnion) { 39388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 3939487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (UnionIvarSize > MaxUnionIvarSize) { 3940820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxUnionIvarSize = UnionIvarSize; 3941820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxField = Field; 3942900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar MaxFieldOffset = FieldOffset; 3943820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3944487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar } else { 394525d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 39468b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar FieldSize / WordSizeInBits)); 3947820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 39486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } else if ((ForStrongLayout && 39490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) 39500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { 3951487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (IsUnion) { 3952f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: Why the asymmetry? We divide by word size in bits on other 3953f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // side. 39548b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar uint64_t UnionIvarSize = FieldSize; 3955487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar if (UnionIvarSize > MaxSkippedUnionIvarSize) { 3956820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxSkippedUnionIvarSize = UnionIvarSize; 3957820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian MaxSkippedField = Field; 3958900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar MaxSkippedFieldOffset = FieldOffset; 3959820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3960487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar } else { 39618b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar // FIXME: Why the asymmetry, we divide by byte size in bits here? 396225d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 39638b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar FieldSize / ByteSizeInBits)); 3964820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3965820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3966820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian } 3967d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar 39680dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis if (LastFieldBitfieldOrUnnamed) { 39690dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis if (LastFieldBitfieldOrUnnamed->isBitField()) { 39700dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis // Last field was a bitfield. Must update skip info. 3971a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith uint64_t BitFieldSize 3972a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); 39730dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis GC_IVAR skivar; 39740dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; 39750dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 39760dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis + ((BitFieldSize % ByteSizeInBits) != 0); 39770dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis SkipIvars.push_back(skivar); 39780dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis } else { 39790dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); 39800dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis // Last field was unnamed. Must update skip info. 39810dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis unsigned FieldSize 39820dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); 39830dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, 39840dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis FieldSize / ByteSizeInBits)); 39850dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis } 39867fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian } 39876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 39888b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar if (MaxField) 39896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 39908b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar MaxUnionIvarSize)); 39918b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar if (MaxSkippedField) 3992900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 39938b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar MaxSkippedUnionIvarSize)); 3994d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian} 3995d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian 3996b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// BuildIvarLayoutBitmap - This routine is the horsework for doing all 3997b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the computations and returning the layout bitmap (for ivar or blocks) in 3998b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the given argument BitMap string container. Routine reads 3999b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// two containers, IvarsInfo and SkipIvars which are assumed to be 4000b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// filled already by the caller. 400194010695f7fce626e41ef045b60def9c912e9ce8Chris Lattnerllvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { 40029397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int WordsToScan, WordsToSkip; 40038b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *PtrTy = CGM.Int8PtrTy; 400493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 40059397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Build the string of skip/scan nibbles 40065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<SKIP_SCAN, 32> SkipScanIvars; 40076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int WordSize = 400893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 40099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if (IvarsInfo[0].ivar_bytepos == 0) { 40109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = 0; 40119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[0].ivar_size; 401231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else { 40139397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 40149397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[0].ivar_size; 40159397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 401631682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 40176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned int TailPrevGCObjC = 401893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 401931682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 40209397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // consecutive 'scanned' object pointers. 40219397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan += IvarsInfo[i].ivar_size; 402231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else { 40239397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Skip over 'gc'able object pointer which lay over each other. 40249397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 40259397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian continue; 40269397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Must skip over 1 or more words. We save current skip/scan values 40279397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // and start a new pair. 4028c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 4029c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = WordsToSkip; 4030c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = WordsToScan; 403181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 403293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 40339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Skip the hole. 4034c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 4035c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = 0; 403681adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 40379397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToSkip = 0; 40389397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian WordsToScan = IvarsInfo[i].ivar_size; 40399397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 40409397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 404131682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (WordsToScan > 0) { 4042c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 4043c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = WordsToSkip; 4044c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = WordsToScan; 404581adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 40469397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 404793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 404831682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (!SkipIvars.empty()) { 404981adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian unsigned int LastIndex = SkipIvars.size()-1; 40506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int LastByteSkipped = 405193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 405281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian LastIndex = IvarsInfo.size()-1; 40536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar int LastByteScanned = 405493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[LastIndex].ivar_bytepos + 405593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo[LastIndex].ivar_size * WordSize; 40569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Compute number of bytes to skip at the tail end of the last ivar scanned. 405754d76db0aa7107597cac0b80d8e138a37e6d1de9Benjamin Kramer if (LastByteSkipped > LastByteScanned) { 40589397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 4059c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SKIP_SCAN SkScan; 4060c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.skip = TotalWords - (LastByteScanned/WordSize); 4061c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian SkScan.scan = 0; 406281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian SkipScanIvars.push_back(SkScan); 40639397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 40649397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 40659397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 40669397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // as 0xMN. 406781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian int SkipScan = SkipScanIvars.size()-1; 406831682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (int i = 0; i <= SkipScan; i++) { 40699397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 40709397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 40719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // 0xM0 followed by 0x0N detected. 40729397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 40739397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (int j = i+1; j < SkipScan; j++) 40749397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian SkipScanIvars[j] = SkipScanIvars[j+1]; 40759397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian --SkipScan; 40769397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 40779397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 407893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 40799397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // Generate the string. 408031682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar for (int i = 0; i <= SkipScan; i++) { 40819397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned char byte; 40829397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 40839397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 40849397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 40859397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 408693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 40879397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // first skip big. 40889397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (unsigned int ix = 0; ix < skip_big; ix++) 40899397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += (unsigned char)(0xf0); 409093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 40919397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // next (skip small, scan) 409231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (skip_small) { 40939397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte = skip_small << 4; 409431682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (scan_big > 0) { 40959397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte |= 0xf; 40969397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian --scan_big; 409731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar } else if (scan_small) { 40989397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte |= scan_small; 40999397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian scan_small = 0; 41009397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 41019397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += byte; 41029397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 41039397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // next scan big 41049397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian for (unsigned int ix = 0; ix < scan_big; ix++) 41059397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += (unsigned char)(0x0f); 41069397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // last scan small 410731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar if (scan_small) { 41089397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian byte = scan_small; 41099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian BitMap += byte; 41109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 41119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian } 41129397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian // null terminate string. 4113667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian unsigned char zero = 0; 4114667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian BitMap += zero; 411593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 411693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian llvm::GlobalVariable * Entry = 411793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 411894010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, BitMap,false), 4119af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 4120af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_classname,cstring_literals" : 4121af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 412293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 1, true); 412393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return getConstantGEP(VMContext, Entry, 0, 0); 412493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian} 41256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 412693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// BuildIvarLayout - Builds ivar layout bitmap for the class 412793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// implementation for the __strong or __weak case. 412893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// The layout map displays which words in ivar list must be skipped 412993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// and which must be scanned by GC (see below). String is built of bytes. 413093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 413193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// of words to skip and right nibble is count of words to scan. So, each 413293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// nibble represents up to 15 workds to skip or scan. Skipping the rest is 413393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// represented by a 0x00 byte which also ends the string. 413493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 1. when ForStrongLayout is true, following ivars are scanned: 413593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - id, Class 413693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - object * 413793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __strong anything 413893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 413993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 2. When ForStrongLayout is false, following ivars are scanned: 414093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __weak anything 414193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 414293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayout( 414393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian const ObjCImplementationDecl *OMD, 414493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian bool ForStrongLayout) { 414593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian bool hasUnion = false; 414693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 41478b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *PtrTy = CGM.Int8PtrTy; 41484e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::NonGC && 41494e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie !CGM.getLangOpts().ObjCAutoRefCount) 415093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 415193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 4152db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 4153db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const FieldDecl*, 32> RecFields; 41544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCAutoRefCount) { 4155db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); 4156bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) 4157bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian RecFields.push_back(cast<FieldDecl>(IVD)); 4158bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian } 4159bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian else { 4160db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const ObjCIvarDecl*, 32> Ivars; 4161f85e193739c953358c865005855253af4f68a497John McCall CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars); 416293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 4163db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose // FIXME: This is not ideal; we shouldn't have to do this copy. 4164db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose RecFields.append(Ivars.begin(), Ivars.end()); 4165bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian } 416693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 416793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (RecFields.empty()) 416893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 416993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 417093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian SkipIvars.clear(); 417193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian IvarsInfo.clear(); 417293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 417393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); 417493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian if (IvarsInfo.empty()) 417593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return llvm::Constant::getNullValue(PtrTy); 4176b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian // Sort on byte position in case we encounterred a union nested in 4177b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian // the ivar list. 4178b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian if (hasUnion && !IvarsInfo.empty()) 4179b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian std::sort(IvarsInfo.begin(), IvarsInfo.end()); 4180b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian if (hasUnion && !SkipIvars.empty()) 4181b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian std::sort(SkipIvars.begin(), SkipIvars.end()); 4182b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian 418393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian std::string BitMap; 4184b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 418593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian 41864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCGCBitmapPrint) { 41876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar printf("\n%s ivar layout for class '%s': ", 41883d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian ForStrongLayout ? "strong" : "weak", 41894087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar OMD->getClassInterface()->getName().data()); 419031ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky const unsigned char *s = (const unsigned char*)BitMap.c_str(); 419113562a1f30df391607604fb6bf345af42b0d831dBill Wendling for (unsigned i = 0, e = BitMap.size(); i < e; i++) 41923d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian if (!(s[i] & 0xf0)) 41933d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 41943d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian else 41953d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 41963d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian printf("\n"); 41973d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian } 419893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian return C; 4199d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian} 4200d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian 420156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 4202259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 4203259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 42040b2397132efe74ee11c1b371dd9033820c54240fChris Lattner // FIXME: Avoid std::string in "Sel.getAsString()" 420563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 42066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_", 420794010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()), 4208af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 4209af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methname,cstring_literals" : 4210af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 4211b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 4212259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 4213a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 42146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar} 42156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 421627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Merge into a single cstring creation function. 421756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 421827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 421927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 422027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 42213e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbarllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 42227794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel std::string TypeStr; 42237794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 42247794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 42257794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 42266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 422763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 422863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 422994010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, TypeStr), 4230af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 4231af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methtype,cstring_literals" : 4232af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 4233b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 42346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4235a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 4236259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar} 4237259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar 4238dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilsonllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 4239dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson bool Extended) { 424027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar std::string TypeStr; 4241a4dc693368e7af4001fe88076bdf4efd440022faBill Wendling if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended)) 4242f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 42437794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 42447794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 42457794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 4246b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar if (!Entry) 4247b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 424894010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, TypeStr), 4249af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar ((ObjCABI == 2) ? 4250af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__objc_methtype,cstring_literals" : 4251af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar "__TEXT,__cstring,cstring_literals"), 4252b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 42537794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel 4254a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 425527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar} 425627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4257c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function. 425856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 4259c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 42606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 426163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar if (!Entry) 42626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", 426394010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner llvm::ConstantDataArray::getString(VMContext, 426494010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner Ident->getNameStart()), 426563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar "__TEXT,__cstring,cstring_literals", 4266b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar 1, true); 4267c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 4268a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson return getConstantGEP(VMContext, Entry, 0, 0); 4269c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 4270c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 4271c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function. 4272c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar// FIXME: This Decl should be more precise. 427363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbarllvm::Constant * 42746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 42756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const Decl *Container) { 4276c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar std::string TypeStr; 4277c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 4278c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 4279c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar} 4280c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar 42816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 428256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian const ObjCContainerDecl *CD, 42835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> &Name) { 4284c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar llvm::raw_svector_ostream OS(Name); 4285679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian assert (CD && "Missing container decl in GetNameForMethod"); 4286c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 4287c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar << '[' << CD->getName(); 42886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (const ObjCCategoryImplDecl *CID = 4289c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 4290f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer OS << '(' << *CID << ')'; 4291c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar OS << ' ' << D->getSelector().getAsString() << ']'; 4292b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar} 4293b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 4294f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarvoid CGObjCMac::FinishModule() { 42954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar EmitModuleInfo(); 42964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 42970c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Emit the dummy bodies for any protocols which were referenced but 42980c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // never defined. 42996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 4300ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner I = Protocols.begin(), e = Protocols.end(); I != e; ++I) { 4301ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner if (I->second->hasInitializer()) 43020c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar continue; 43034e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 43041d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[5]; 4305c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 4306ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner Values[1] = GetClassName(I->first); 4307c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 43080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Values[3] = Values[4] = 4309c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 4310ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner I->second->setLinkage(llvm::GlobalValue::InternalLinkage); 431108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 43120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar Values)); 4313ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(I->second); 43140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar } 43150c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar 4316242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // Add assembler directives to add lazy undefined symbol references 4317242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // for classes which are referenced but not defined. This is 4318242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar // important for correct linker interaction. 4319330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar // 4320330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar // FIXME: It would be nice if we had an LLVM construct for this. 4321330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar if (!LazySymbols.empty() || !DefinedSymbols.empty()) { 4322f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Asm; 4323330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar Asm += CGM.getModule().getModuleInlineAsm(); 4324330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar if (!Asm.empty() && Asm.back() != '\n') 4325330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar Asm += '\n'; 4326330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar 4327330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar llvm::raw_svector_ostream OS(Asm); 4328330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(), 4329330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar e = DefinedSymbols.end(); I != e; ++I) 433001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n" 433101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "\t.globl .objc_class_name_" << (*I)->getName() << "\n"; 4332afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(), 4333b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian e = LazySymbols.end(); I != e; ++I) { 4334afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n"; 4335b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian } 4336b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian 433713562a1f30df391607604fb6bf345af42b0d831dBill Wendling for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) { 4338b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n" 4339b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n"; 4340b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian } 4341afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner 4342330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar CGM.getModule().setModuleInlineAsm(OS.str()); 4343242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar } 4344f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar} 4345f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 43466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 4347ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian : CGObjCCommonMac(cgm), 43481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCTypes(cgm) { 4349aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 4350ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian ObjCABI = 2; 4351ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian} 4352ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian 4353f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** */ 4354f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar 4355ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 435665a1e6707de0d6641e70d0a6edd7593fae85df3cDouglas Gregor : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0) 435765a1e6707de0d6641e70d0a6edd7593fae85df3cDouglas Gregor{ 43584e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar CodeGen::CodeGenTypes &Types = CGM.getTypes(); 43594e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar ASTContext &Ctx = CGM.getContext(); 43606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 436127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar ShortTy = Types.ConvertType(Ctx.ShortTy); 43626efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar IntTy = Types.ConvertType(Ctx.IntTy); 43634e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar LongTy = Types.ConvertType(Ctx.LongTy); 43640a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian LongLongTy = Types.ConvertType(Ctx.LongLongTy); 43658b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Int8PtrTy = CGM.Int8PtrTy; 43668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Int8PtrPtrTy = CGM.Int8PtrPtrTy; 43676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 43684e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 436996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 43704e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 43716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4372ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // I'm not sure I like this. The implicit coordination is a bit 4373ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // gross. We should solve this in a reasonable fashion because this 4374ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // is a pretty common task (match some runtime data structure with 4375ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // an LLVM data structure). 43766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4377ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME: This is leaked. 4378ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // FIXME: Merge with rewriter code? 43796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4380ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // struct _objc_super { 4381ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // id self; 4382ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // Class cls; 4383ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian // } 4384465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4385daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar Ctx.getTranslationUnitDecl(), 4386ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara SourceLocation(), SourceLocation(), 43876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar &Ctx.Idents.get("_objc_super")); 4388ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4389ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit)); 4390ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4391ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith Ctx.getObjCClassType(), 0, 0, false, 4392ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith ICIS_NoInit)); 4393838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor RD->completeDefinition(); 43946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4395ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperCTy = Ctx.getTagDeclType(RD); 4396ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperPtrCTy = Ctx.getPointerType(SuperCTy); 43976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4398ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 43996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 44006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 440130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_t { 440230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *name; 44036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar // char *attributes; 440430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 4405c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner PropertyTy = llvm::StructType::create("struct._prop_t", 4406c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, NULL); 44076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 440830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_list_t { 4409d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // uint32_t entsize; // sizeof(struct _prop_t) 441030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t count_of_properties; 4411d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _prop_t prop_list[count_of_properties]; 441230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 44139cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner PropertyListTy = 4414c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._prop_list_t", IntTy, IntTy, 4415c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(PropertyTy, 0), NULL); 441630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _prop_list_t * 441796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 44186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 441930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _objc_method { 442030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // SEL _cmd; 442130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *method_type; 442230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *_imp; 442330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 4424c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodTy = llvm::StructType::create("struct._objc_method", 4425c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner SelectorPtrTy, Int8PtrTy, Int8PtrTy, 4426c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner NULL); 44276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4428d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _objc_cache * 4429c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); 443096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 44319d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 4432ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian} 44334e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar 44346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 44351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : ObjCCommonTypesHelper(cgm) { 443610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description { 443710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // SEL name; 443810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *types; 443910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 44406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionTy = 4441c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_method_description", 4442c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner SelectorPtrTy, Int8PtrTy, NULL); 44436efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 444410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list { 444510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // int count; 444610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description[1]; 444710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 44486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionListTy = 4449c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_method_description_list", 4450c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, 4451c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(MethodDescriptionTy, 0),NULL); 44526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 445310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list * 44546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodDescriptionListPtrTy = 445596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::PointerType::getUnqual(MethodDescriptionListTy); 44566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 44576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar // Protocol description structures 44586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 445910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension { 446010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // uint32_t size; // sizeof(struct _objc_protocol_extension) 446110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *optional_instance_methods; 446210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *optional_class_methods; 446310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_property_list *instance_properties; 4464dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson // const char ** extendedMethodTypes; 446510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 44666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolExtensionTy = 4467c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_protocol_extension", 4468c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, MethodDescriptionListPtrTy, 4469c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodDescriptionListPtrTy, PropertyListPtrTy, 4470dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson Int8PtrPtrTy, NULL); 44716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 447210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension * 447396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 44746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 44750c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar // Handle recursive construction of Protocol and ProtocolList types 44766efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 44779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolTy = 4478c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol"); 44796efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 44809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListTy = 4481c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 44829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), 4483ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian LongTy, 44849cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::ArrayType::get(ProtocolTy, 0), 4485ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian NULL); 44866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 448710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol { 448810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_extension *isa; 448910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *protocol_name; 449010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol **_objc_protocol_list; 449110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *instance_methods; 449210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_description_list *class_methods; 449310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 44949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 44959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ProtocolListTy), 44969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodDescriptionListPtrTy, 44979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodDescriptionListPtrTy, 44989cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 44999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 450010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_list * 450196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 45026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar 450396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 450427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 450527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Class description structures 450627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 450710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar { 450810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_name; 450910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_type; 451010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // int ivar_offset; 451110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 4512c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IvarTy = llvm::StructType::create("struct._objc_ivar", 4513c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, IntTy, NULL); 451427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 451510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar_list * 45169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListTy = 4517c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_ivar_list"); 451896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 451927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 452010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list * 45219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListTy = 4522c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_method_list"); 452396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 452427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 452510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class_extension * 45266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ClassExtensionTy = 4527c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_class_extension", 4528c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, Int8PtrTy, PropertyListPtrTy, NULL); 452996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 453027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4531c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassTy = llvm::StructType::create(VMContext, "struct._objc_class"); 453227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 453310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class { 453410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // Class isa; 453510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // Class super_class; 453610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *name; 453710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long version; 453810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long info; 453910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long instance_size; 454010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_ivar_list *ivars; 454110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *methods; 454210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_cache *cache; 454310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_protocol_list *protocols; 454410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *ivar_layout; 454510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_class_ext *ext; 454610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // }; 45479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 45489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassTy), 45499cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner Int8PtrTy, 45509cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 45519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 45529cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner LongTy, 45539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListPtrTy, 45549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListPtrTy, 45559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CachePtrTy, 45569cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListPtrTy, 45579cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner Int8PtrTy, 45589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassExtensionPtrTy, 45599cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 45609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 456196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 456227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 456310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_category { 456410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *category_name; 456510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *class_name; 456610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *instance_method; 456710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_method_list *class_method; 456810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // uint32_t size; // sizeof(struct _objc_category) 456910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_property_list *instance_properties;// category's @property 457010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 45719cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CategoryTy = 4572c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_category", 4573c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, MethodListPtrTy, 4574c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListPtrTy, ProtocolListPtrTy, 4575c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, PropertyListPtrTy, NULL); 457686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar 457727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar // Global metadata structures 457827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 457910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // struct _objc_symtab { 458010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // long sel_ref_cnt; 458110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // SEL *refs; 458210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // short cls_def_cnt; 458310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // short cat_def_cnt; 458410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // char *defs[cls_def_cnt + cat_def_cnt]; 458510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian // } 45869cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner SymtabTy = 4587c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_symtab", 4588c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner LongTy, SelectorPtrTy, ShortTy, ShortTy, 4589c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(Int8PtrTy, 0), NULL); 459096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 459127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar 4592db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // struct _objc_module { 4593db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // long version; 4594db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // long size; // sizeof(struct _objc_module) 4595db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // char *name; 4596db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // struct _objc_symtab* symtab; 4597db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian // } 45986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ModuleTy = 4599c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_module", 4600c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL); 460114c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar 46026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4603f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This is the size of the setjmp buffer and should be target 4604f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // specific. 18 is what's used on 32-bit X86. 4605124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson uint64_t SetJmpBufferSize = 18; 46066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4607124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson // Exceptions 46088b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 46096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 46106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ExceptionDataTy = 4611c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_exception_data", 46128b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize), 46138b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner StackPtrTy, NULL); 4614124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson 4615bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 4616bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 46176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 46181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : ObjCCommonTypesHelper(cgm) { 461930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _method_list_t { 462030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t entsize; // sizeof(struct _objc_method) 462130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t method_count; 462230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _objc_method method_list[method_count]; 462330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 46249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner MethodListnfABITy = 4625c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__method_list_t", IntTy, IntTy, 4626c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(MethodTy, 0), NULL); 4627d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct method_list_t * 462896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 46296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 463030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _protocol_t { 463130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // id isa; // NULL 463230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const char * const protocol_name; 4633d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _protocol_list_t * protocol_list; // super protocols 463430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t * const instance_methods; 463530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t * const class_methods; 463630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t *optionalInstanceMethods; 463730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct method_list_t *optionalClassMethods; 4638d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _prop_list_t * properties; 463930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint32_t size; // sizeof(struct _protocol_t) 464030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint32_t flags; // = 0 4641dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson // const char ** extendedMethodTypes; 464230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 46436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4644d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // Holder for struct _protocol_list_t * 46459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListnfABITy = 4646c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 46479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner 46489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolnfABITy = 4649c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy, 4650c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(ProtocolListnfABITy), 4651c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4652c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4653dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, 4654dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson NULL); 4655948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 4656948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // struct _protocol_t* 465796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 46586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4659da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // struct _protocol_list_t { 4660d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // long protocol_count; // Note, this is 32/64 bit 4661948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // struct _protocol_t *[protocol_count]; 466230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 46639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ProtocolListnfABITy->setBody(LongTy, 46649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::ArrayType::get(ProtocolnfABIPtrTy, 0), 46659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 46666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4667d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _objc_protocol_list* 466896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 46696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 467030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _ivar_t { 467130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // unsigned long int *offset; // pointer to ivar offset location 467230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *name; 467330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // char *type; 467430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t alignment; 467530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t size; 467630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 46779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarnfABITy = 4678c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._ivar_t", 4679c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(LongTy), 4680c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); 46816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 468230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _ivar_list_t { 468330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32 entsize; // sizeof(struct _ivar_t) 468430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32 count; 468530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // struct _iver_t list[count]; 468630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 46879cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner IvarListnfABITy = 4688c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy, 4689c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::ArrayType::get(IvarnfABITy, 0), NULL); 46906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 469196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 46926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4693d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_ro_t { 469430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const flags; 469530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const instanceStart; 469630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const instanceSize; 469730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // uint32_t const reserved; // only when building for 64bit targets 469830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint8_t * const ivarLayout; 469930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const char *const name; 470030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _method_list_t * const baseMethods; 470130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _objc_protocol_list *const baseProtocols; 470230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _ivar_list_t *const ivars; 470330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const uint8_t * const weakIvarLayout; 470430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // const struct _prop_list_t * const properties; 470530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian // } 47066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4707d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // FIXME. Add 'reserved' field in 64bit abi mode! 4708c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassRonfABITy = llvm::StructType::create("struct._class_ro_t", 4709c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IntTy, IntTy, IntTy, Int8PtrTy, 4710c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, MethodListnfABIPtrTy, 4711c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ProtocolListnfABIPtrTy, 4712c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner IvarListnfABIPtrTy, 4713c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, PropertyListPtrTy, NULL); 47146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4715d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 47169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 47170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 47180774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall ->getPointerTo(); 47196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4720d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t { 4721d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t *isa; 4722d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t * const superclass; 4723d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // void *cache; 4724d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // IMP *vtable; 4725d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct class_ro_t *ro; 4726d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // } 47276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4728c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t"); 47299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 47309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassnfABITy), 47319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner CachePtrTy, 47329cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ImpnfABITy), 47339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType::getUnqual(ClassRonfABITy), 47349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner NULL); 47356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4736aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // LLVM for struct _class_t * 473796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 47386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4739d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _category_t { 4740d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const char * const name; 4741d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // struct _class_t *const cls; 4742d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _method_list_t * const instance_methods; 4743d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _method_list_t * const class_methods; 4744d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _protocol_list_t * const protocols; 4745d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian // const struct _prop_list_t * const properties; 474645c2ba0c13f353a8bab6cc01b30b3a13f3404c1eFariborz Jahanian // } 4747c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner CategorynfABITy = llvm::StructType::create("struct._category_t", 4748c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, ClassnfABIPtrTy, 4749c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, 4750c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner MethodListnfABIPtrTy, 4751c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ProtocolListnfABIPtrTy, 4752c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner PropertyListPtrTy, 4753c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner NULL); 47546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 47552e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // New types for nonfragile abi messaging. 475683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian CodeGen::CodeGenTypes &Types = CGM.getTypes(); 475783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian ASTContext &Ctx = CGM.getContext(); 47586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 47592e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefTy - LLVM for: 47602e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _message_ref_t { 47612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // IMP messenger; 47622e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 47632e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 47646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 476583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian // First the clang type for struct _message_ref_t 4766465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4767daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar Ctx.getTranslationUnitDecl(), 4768ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara SourceLocation(), SourceLocation(), 476983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian &Ctx.Idents.get("_message_ref_t")); 4770ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4771ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit)); 4772ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4773ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith Ctx.getObjCSelType(), 0, 0, false, 4774ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith ICIS_NoInit)); 4775838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor RD->completeDefinition(); 47766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 477783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefCTy = Ctx.getTagDeclType(RD); 477883a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 477983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 47806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 47812e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // MessageRefPtrTy - LLVM for struct _message_ref_t* 478296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 47836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 47842e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefTy - LLVM for: 47852e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // struct _super_message_ref_t { 47862e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SUPER_IMP messenger; 47872e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SEL name; 47882e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // }; 47899cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner SuperMessageRefTy = 4790c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._super_message_ref_t", 4791c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner ImpnfABITy, SelectorPtrTy, NULL); 47926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 47932e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 47946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 47959d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian 4796e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 4797e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // struct objc_typeinfo { 4798e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // const void** vtable; // objc_ehtype_vtable + 2 4799e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // const char* name; // c++ typeinfo string 4800e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // Class cls; 4801e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar // }; 48029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner EHTypeTy = 4803c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct._objc_typeinfo", 4804c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::PointerType::getUnqual(Int8PtrTy), 4805c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner Int8PtrTy, ClassnfABIPtrTy, NULL); 480696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 4807bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar} 4808bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 48096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 4810aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian FinishNonFragileABIModule(); 48116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4812aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian return NULL; 4813aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 4814aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 4815bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingvoid CGObjCNonFragileABIMac:: 4816bb02855f46423d2034918b75b157f886bb04bcccBill WendlingAddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, 4817bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const char *SymbolName, 4818bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const char *SectionName) { 4819463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar unsigned NumClasses = Container.size(); 48206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4821463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar if (!NumClasses) 4822463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar return; 48236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 48240b2397132efe74ee11c1b371dd9033820c54240fChris Lattner SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 4825463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar for (unsigned i=0; i<NumClasses; i++) 48263c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 4827463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar ObjCTypes.Int8PtrTy); 48280b2397132efe74ee11c1b371dd9033820c54240fChris Lattner llvm::Constant *Init = 482996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 48300b2397132efe74ee11c1b371dd9033820c54240fChris Lattner Symbols.size()), 4831463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar Symbols); 48326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4833463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar llvm::GlobalVariable *GV = 48341c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4835463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar llvm::GlobalValue::InternalLinkage, 4836463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar Init, 48371c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson SymbolName); 48384b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 4839463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar GV->setSection(SectionName); 4840ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 4841463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar} 48426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4843aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 4844aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian // nonfragile abi has no module definition. 48456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4846463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar // Build list of all implemented class addresses in array 4847f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // L_OBJC_LABEL_CLASS_$. 48486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedClasses, 4849463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "\01L_OBJC_LABEL_CLASS_$", 4850463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "__DATA, __objc_classlist, regular, no_dead_strip"); 4851a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 485213562a1f30df391607604fb6bf345af42b0d831dBill Wendling for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) { 4853a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian llvm::GlobalValue *IMPLGV = DefinedClasses[i]; 4854a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4855a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian continue; 4856a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4857a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian } 4858a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 485913562a1f30df391607604fb6bf345af42b0d831dBill Wendling for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) { 48600e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; 48610e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 48620e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian continue; 48630e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 48640e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian } 4865a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian 48666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedNonLazyClasses, 486774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 486874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "__DATA, __objc_nlclslist, regular, no_dead_strip"); 48696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4870f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // Build list of all implemented category addresses in array 4871f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian // L_OBJC_LABEL_CATEGORY_$. 48726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedCategories, 4873463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "\01L_OBJC_LABEL_CATEGORY_$", 4874463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar "__DATA, __objc_catlist, regular, no_dead_strip"); 48756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddModuleClassList(DefinedNonLazyCategories, 487674d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 487774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 48786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 4879fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar EmitImageInfo(); 4880aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 4881aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 4882944c84313da15477eb18d90babb0890d10d98082John McCall/// isVTableDispatchedSelector - Returns true if SEL is not in the list of 4883944c84313da15477eb18d90babb0890d10d98082John McCall/// VTableDispatchMethods; false otherwise. What this means is that 48846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// except for the 19 selectors in the list, we generate 32bit-style 4885d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// message dispatch call for all the rest. 4886944c84313da15477eb18d90babb0890d10d98082John McCallbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) { 4887944c84313da15477eb18d90babb0890d10d98082John McCall // At various points we've experimented with using vtable-based 4888944c84313da15477eb18d90babb0890d10d98082John McCall // dispatch for all methods. 4889f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { 4890f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar case CodeGenOptions::Legacy: 4891776dbf9704353515b422ee13e481194c937ba01dFariborz Jahanian return false; 4892944c84313da15477eb18d90babb0890d10d98082John McCall case CodeGenOptions::NonLegacy: 4893944c84313da15477eb18d90babb0890d10d98082John McCall return true; 4894f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar case CodeGenOptions::Mixed: 4895f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar break; 4896f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar } 4897f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar 4898f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar // If so, see whether this selector is in the white-list of things which must 4899f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar // use the new dispatch convention. We lazily build a dense set for this. 4900944c84313da15477eb18d90babb0890d10d98082John McCall if (VTableDispatchMethods.empty()) { 4901944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("alloc")); 4902944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("class")); 4903944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("self")); 4904944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("isFlipped")); 4905944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("length")); 4906944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("count")); 4907944c84313da15477eb18d90babb0890d10d98082John McCall 4908944c84313da15477eb18d90babb0890d10d98082John McCall // These are vtable-based if GC is disabled. 4909944c84313da15477eb18d90babb0890d10d98082John McCall // Optimistically use vtable dispatch for hybrid compiles. 49104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 4911944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("retain")); 4912944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("release")); 4913944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("autorelease")); 4914944c84313da15477eb18d90babb0890d10d98082John McCall } 4915944c84313da15477eb18d90babb0890d10d98082John McCall 4916944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("allocWithZone")); 4917944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 4918944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 4919944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("objectForKey")); 4920944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 4921944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isEqualToString")); 4922944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("isEqual")); 4923944c84313da15477eb18d90babb0890d10d98082John McCall 4924944c84313da15477eb18d90babb0890d10d98082John McCall // These are vtable-based if GC is enabled. 4925944c84313da15477eb18d90babb0890d10d98082John McCall // Optimistically use vtable dispatch for hybrid compiles. 49264e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 4927944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetNullarySelector("hash")); 4928944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert(GetUnarySelector("addObject")); 4929944c84313da15477eb18d90babb0890d10d98082John McCall 4930944c84313da15477eb18d90babb0890d10d98082John McCall // "countByEnumeratingWithState:objects:count" 4931944c84313da15477eb18d90babb0890d10d98082John McCall IdentifierInfo *KeyIdents[] = { 4932944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("countByEnumeratingWithState"), 4933944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("objects"), 4934944c84313da15477eb18d90babb0890d10d98082John McCall &CGM.getContext().Idents.get("count") 4935944c84313da15477eb18d90babb0890d10d98082John McCall }; 4936944c84313da15477eb18d90babb0890d10d98082John McCall VTableDispatchMethods.insert( 4937944c84313da15477eb18d90babb0890d10d98082John McCall CGM.getContext().Selectors.getSelector(3, KeyIdents)); 4938944c84313da15477eb18d90babb0890d10d98082John McCall } 4939d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian } 4940f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar 4941944c84313da15477eb18d90babb0890d10d98082John McCall return VTableDispatchMethods.count(Sel); 4942d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian} 4943d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian 4944058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian// Metadata flags 4945058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianenum MetaDataDlags { 4946058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS = 0x0, 4947058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS_META = 0x1, 4948058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian CLS_ROOT = 0x2, 4949493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian OBJC2_CLS_HIDDEN = 0x10, 4950f85e193739c953358c865005855253af4f68a497John McCall CLS_EXCEPTION = 0x20, 4951f85e193739c953358c865005855253af4f68a497John McCall 4952f85e193739c953358c865005855253af4f68a497John McCall /// (Obsolete) ARC-specific: this class has a .release_ivars method 4953f85e193739c953358c865005855253af4f68a497John McCall CLS_HAS_IVAR_RELEASER = 0x40, 4954f85e193739c953358c865005855253af4f68a497John McCall /// class was compiled with -fobjc-arr 4955f85e193739c953358c865005855253af4f68a497John McCall CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 4956058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}; 4957058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassRoTInitializer - generate meta-data for: 4958058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_ro_t { 4959058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const flags; 4960058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const instanceStart; 4961058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const instanceSize; 4962058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// uint32_t const reserved; // only when building for 64bit targets 4963058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const uint8_t * const ivarLayout; 4964058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const char *const name; 4965058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _method_list_t * const baseMethods; 4966da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _protocol_list_t *const baseProtocols; 4967058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _ivar_list_t *const ivars; 4968058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const uint8_t * const weakIvarLayout; 4969058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// const struct _prop_list_t * const properties; 4970058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// } 4971058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// 4972058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 49736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned flags, 49746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceStart, 49756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar unsigned InstanceSize, 49766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID) { 4977058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian std::string ClassName = ID->getNameAsString(); 49781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[10]; // 11 for 64bit targets! 4979f85e193739c953358c865005855253af4f68a497John McCall 49804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCAutoRefCount) 4981f85e193739c953358c865005855253af4f68a497John McCall flags |= CLS_COMPILED_BY_ARC; 4982f85e193739c953358c865005855253af4f68a497John McCall 49834a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 49844a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 49854a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 4986058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian // FIXME. For 64bit targets add 0 here. 49876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 49886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : BuildIvarLayout(ID, true); 4989058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values[ 4] = GetClassName(ID->getIdentifier()); 4990493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // const struct _method_list_t * const baseMethods; 4991493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian std::vector<llvm::Constant*> Methods; 4992493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian std::string MethodListName("\01l_OBJC_$_"); 4993493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (flags & CLS_META) { 4994493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 49956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::classmeth_iterator 499617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 4997493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Class methods should always be defined. 4998493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 4999493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 5000493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } else { 5001493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 50026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::instmeth_iterator 500317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 5004493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Instance methods should always be defined. 5005493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 5006493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 50076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCImplementationDecl::propimpl_iterator 500817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 5009581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCPropertyImplDecl *PID = *i; 50106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5011939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 5012939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian ObjCPropertyDecl *PD = PID->getPropertyDecl(); 50136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5014939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 5015939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (llvm::Constant *C = GetMethodConstant(MD)) 5016939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian Methods.push_back(C); 5017939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 5018939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian if (llvm::Constant *C = GetMethodConstant(MD)) 5019939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian Methods.push_back(C); 5020939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian } 5021939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian } 5022493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian } 50236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 5] = EmitMethodList(MethodListName, 50246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", Methods); 50256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5026da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian const ObjCInterfaceDecl *OID = ID->getClassInterface(); 5027da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 50286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 50299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + OID->getName(), 503053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek OID->all_referenced_protocol_begin(), 503153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek OID->all_referenced_protocol_end()); 50326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 503398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian if (flags & CLS_META) 5034c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 503598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian else 503698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Values[ 7] = EmitIvarList(ID); 50376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 50386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : BuildIvarLayout(ID, false); 50395de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian if (flags & CLS_META) 5040c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 50415de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian else 50429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 50439c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ID, ID->getClassInterface(), ObjCTypes); 504408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 5045058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values); 5046058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *CLASS_RO_GV = 50476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false, 50486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::InternalLinkage, 50496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 50506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar (flags & CLS_META) ? 50516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 50526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string("\01l_OBJC_CLASS_RO_$_")+ClassName); 505309796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian CLASS_RO_GV->setAlignment( 50544b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy)); 50551bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian CLASS_RO_GV->setSection("__DATA, __objc_const"); 5056058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian return CLASS_RO_GV; 5057f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian 5058058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian} 5059058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian 5060058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassMetaData - This routine defines that to-level meta-data 5061058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// for the given ClassName for: 5062058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t { 5063058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t *isa; 5064058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t * const superclass; 5065058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// void *cache; 5066058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// IMP *vtable; 5067058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct class_ro_t *ro; 5068058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// } 5069058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// 507084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 50716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string &ClassName, 50726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *IsAGV, 50736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *SuperClassGV, 50746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *ClassRoGV, 50756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool HiddenVisibility) { 50761d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 50771d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer IsAGV, 50781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer SuperClassGV, 50791d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCEmptyCacheVar, // &ObjCEmptyCacheVar 50801d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCEmptyVtableVar, // &ObjCEmptyVtableVar 50811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ClassRoGV // &CLASS_RO_GV 50821d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 50836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (!Values[1]) 50846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 50856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 5086058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian Values); 50875a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 50885a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar GV->setInitializer(Init); 5089dd0db2a60b65e7eaa852b77c8b9f607640eb50b9Fariborz Jahanian GV->setSection("__DATA, __objc_data"); 509009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 50914b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 5092cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (HiddenVisibility) 5093cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 509484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian return GV; 5095058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian} 5096058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian 50976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarbool 5098ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz JahanianCGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 509917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis return OD->getClassMethod(GetNullarySelector("load")) != 0; 510074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar} 510174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 51029f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbarvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 5103b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceStart, 5104b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar uint32_t &InstanceSize) { 51056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ASTRecordLayout &RL = 5106b4c79e027fdcc752b5a377611fd4cfbb21611a05Daniel Dunbar CGM.getContext().getASTObjCImplementationLayout(OID); 51076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 51086e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar // InstanceSize is really instance end. 5109ec2990351335f163601b98e39b52425e2e9f931eKen Dyck InstanceSize = RL.getDataSize().getQuantity(); 51106e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar 51116e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar // If there are no fields, the start is the same as the end. 51126e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar if (!RL.getFieldCount()) 51136e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar InstanceStart = InstanceSize; 51146e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar else 5115fb67ccd9da412d652d62e2ac9675b0f1b14fdc73Ken Dyck InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 5116b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar} 5117b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar 5118aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 5119aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian std::string ClassName = ID->getNameAsString(); 5120aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian if (!ObjCEmptyCacheVar) { 5121aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyCacheVar = new llvm::GlobalVariable( 51226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 51236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.CacheTy, 51246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 51256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 51266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 51276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_objc_empty_cache"); 51286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5129aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian ObjCEmptyVtableVar = new llvm::GlobalVariable( 51306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 51316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ImpnfABITy, 51326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 51336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 51346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 51356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_objc_empty_vtable"); 51366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 51376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar assert(ID->getClassInterface() && 5138493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 51396c1aac8883ef2732a2d8543d7ac2a5ca9a199f86Daniel Dunbar // FIXME: Is this correct (that meta class size is never computed)? 51406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t InstanceStart = 51419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 5142058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian uint32_t InstanceSize = InstanceStart; 5143058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian uint32_t flags = CLS_META; 51446ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 51456ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ObjCClassName(getClassSymbolPrefix()); 51466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5147058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *SuperClassGV, *IsAGV; 51486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 51496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool classIsHidden = 51501fb0caaa7bef765b85972274e3b434af2572c141John McCall ID->getClassInterface()->getVisibility() == HiddenVisibility; 5151cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (classIsHidden) 5152493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian flags |= OBJC2_CLS_HIDDEN; 5153f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 5154109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian flags |= eClassFlags_ABI2_HasCXXStructors; 5155493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!ID->getClassInterface()->getSuperClass()) { 5156058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian // class is root 5157058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian flags |= CLS_ROOT; 51585a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 51590f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 5160058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian } else { 516184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Has a root. Current class is not a root. 5162fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian const ObjCInterfaceDecl *Root = ID->getClassInterface(); 5163fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 5164fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian Root = Super; 51650f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 51660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Root->isWeakImported()) 51670e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5168fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian // work on super class metadata symbol. 51696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string SuperClassName = 51700e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian ObjCMetaClassName + 51710e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian ID->getClassInterface()->getSuperClass()->getNameAsString(); 51720f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian SuperClassGV = GetClassGlobal(SuperClassName); 51730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 5174a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5175058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian } 5176058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 5177058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian InstanceStart, 5178058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian InstanceSize,ID); 517984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian std::string TClassName = ObjCMetaClassName + ClassName; 51806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *MetaTClass = 5181cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 5182cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian classIsHidden); 5183a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian DefinedMetaClasses.push_back(MetaTClass); 51846ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar 518584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Metadata for the class 518684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian flags = CLS; 5187cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian if (classIsHidden) 5188493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian flags |= OBJC2_CLS_HIDDEN; 5189f85e193739c953358c865005855253af4f68a497John McCall if (ID->hasCXXStructors()) 5190109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian flags |= eClassFlags_ABI2_HasCXXStructors; 51918158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 519268584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) 51938158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar flags |= CLS_EXCEPTION; 51948158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 5195493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!ID->getClassInterface()->getSuperClass()) { 519684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian flags |= CLS_ROOT; 519784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian SuperClassGV = 0; 5198b7b58b1fcd3007730fd46471583543c9b57c7693Chris Lattner } else { 519984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian // Has a root. Current class is not a root. 5200fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian std::string RootClassName = 520184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian ID->getClassInterface()->getSuperClass()->getNameAsString(); 52025a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 52030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 5204a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 520584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian } 52069f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar GetClassSizeInfo(ID, InstanceStart, InstanceSize); 520784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian CLASS_RO_GV = BuildClassRoTInitializer(flags, 5208f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian InstanceStart, 52096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar InstanceSize, 5210f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian ID); 52116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 521284394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian TClassName = ObjCClassName + ClassName; 52136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *ClassMD = 5214cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 5215cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian classIsHidden); 5216f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian DefinedClasses.push_back(ClassMD); 52178158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 521874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar // Determine if this class is also "non-lazy". 521974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar if (ImplementationIsNonLazy(ID)) 522074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar DefinedNonLazyClasses.push_back(ClassMD); 522174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 52228158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // Force the definition of the EHType if necessary. 52238158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (flags & CLS_EXCEPTION) 52248158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar GetInterfaceEHType(ID->getClassInterface(), true); 522564089cece350472c04b420c497ae391443353325Fariborz Jahanian // Make sure method definition entries are all clear for next implementation. 522664089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 5227aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian} 5228aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian 52298cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// GenerateProtocolRef - This routine is called to generate code for 52308cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// a protocol reference expression; as in: 52318cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @code 52328cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @protocol(Proto1); 52338cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @endcode 52348cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 52358cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// which will hold address of the protocol meta-data. 52368cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// 52378cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 52386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 52396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5240960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // This routine is called for @protocol only. So, we must build definition 5241960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // of protocol's meta-data (not a reference to it!) 5242960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian // 52436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 52446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 52454c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor ObjCTypes.getExternalProtocolPtrTy()); 52466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52478cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 52484087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar ProtocolName += PD->getName(); 52496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52508cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 52518cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian if (PTGV) 5252578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(PTGV); 52538cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV = new llvm::GlobalVariable( 52546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CGM.getModule(), 52556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init->getType(), false, 52566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::WeakAnyLinkage, 52576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 52586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ProtocolName); 52598cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 52608cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5261ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(PTGV); 5262578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(PTGV); 52638cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian} 52648cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian 5265eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// GenerateCategory - Build metadata for a category implementation. 5266eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _category_t { 5267eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const char * const name; 5268eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _class_t *const cls; 5269eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _method_list_t * const instance_methods; 5270eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _method_list_t * const class_methods; 5271eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _protocol_list_t * const protocols; 5272eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// const struct _prop_list_t * const properties; 5273eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// } 5274eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// 527574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbarvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 5276eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 5277f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 52786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string ExtCatName(Prefix + Interface->getNameAsString()+ 52796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "_$_" + OCD->getNameAsString()); 52806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar std::string ExtClassName(getClassSymbolPrefix() + 52816ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar Interface->getNameAsString()); 52826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52831d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[6]; 5284eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values[0] = GetClassName(OCD->getIdentifier()); 5285eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian // meta-class entry symbol 52865a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 52870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Interface->isWeakImported()) 52882cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 52892cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian 5290eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values[1] = ClassGV; 5291f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian std::vector<llvm::Constant*> Methods; 5292f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian std::string MethodListName(Prefix); 52936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 5294f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian "_$_" + OCD->getNameAsString(); 52956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 52966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::instmeth_iterator 529717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 5298f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian // Instance methods should always be defined. 5299f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 5300f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian } 53016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[2] = EmitMethodList(MethodListName, 53036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", 5304f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods); 5305f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian 5306f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian MethodListName = Prefix; 5307f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 5308f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian OCD->getNameAsString(); 5309f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.clear(); 53106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCCategoryImplDecl::classmeth_iterator 531117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 5312f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian // Class methods should always be defined. 5313f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods.push_back(GetMethodConstant(*i)); 5314f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian } 53156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[3] = EmitMethodList(MethodListName, 53176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar "__DATA, __objc_const", 5318f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian Methods); 53196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCCategoryDecl *Category = 53205de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian Interface->FindCategoryDeclaration(OCD->getIdentifier()); 5321943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian if (Category) { 5322f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> ExtName; 53239c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" 53249c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar << OCD->getName(); 5325943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 53269c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + Interface->getName() + "_$_" 53279c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + Category->getName(), 5328943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Category->protocol_begin(), 5329943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian Category->protocol_end()); 53309c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 53319c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar OCD, Category, ObjCTypes); 5332b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 5333c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 5334c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 5335943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian } 53366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Init = 53386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 5339eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Values); 5340eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian llvm::GlobalVariable *GCATV 53416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy, 5342eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian false, 5343eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 5344eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian Init, 53451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson ExtCatName); 534609796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GCATV->setAlignment( 53474b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy)); 53481bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian GCATV->setSection("__DATA, __objc_const"); 5349ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GCATV); 5350eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian DefinedCategories.push_back(GCATV); 535174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar 535274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar // Determine if this category is also "non-lazy". 535374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar if (ImplementationIsNonLazy(OCD)) 535474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar DefinedNonLazyCategories.push_back(GCATV); 535564089cece350472c04b420c497ae391443353325Fariborz Jahanian // method definition entries must be clear for next implementation. 535664089cece350472c04b420c497ae391443353325Fariborz Jahanian MethodDefinitions.clear(); 5357eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian} 5358493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian 5359493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// GetMethodConstant - Return a struct objc_method constant for the 5360493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// given method if it has been defined. The result is null if the 5361493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// method has not been defined. The return value has type MethodPtrTy. 5362493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 53636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCMethodDecl *MD) { 53649d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis llvm::Function *Fn = GetMethodDefinition(MD); 5365493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (!Fn) 5366493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian return 0; 53676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 53681d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Method[] = { 53693c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 53701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer ObjCTypes.SelectorPtrTy), 53711d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetMethodVarType(MD), 53721d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 53731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 537408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 5375493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian} 5376493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian 5377493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// EmitMethodList - Build meta-data for method declarations 5378493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _method_list_t { 5379493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// uint32_t entsize; // sizeof(struct _objc_method) 5380493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// uint32_t method_count; 5381493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _objc_method method_list[method_count]; 5382493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// } 5383493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// 5384bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant * 5385bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCNonFragileABIMac::EmitMethodList(Twine Name, 5386bb02855f46423d2034918b75b157f886bb04bcccBill Wendling const char *Section, 5387bb02855f46423d2034918b75b157f886bb04bcccBill Wendling ArrayRef<llvm::Constant*> Methods) { 5388493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // Return null for empty list. 5389493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian if (Methods.empty()) 5390c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 53916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5392c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 5393493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // sizeof(struct _objc_method) 53949408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 53954a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5396493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian // method_count 53974a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 539896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 5399493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian Methods.size()); 54007db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Methods); 5401c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 54026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5403493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian llvm::GlobalVariable *GV = 54041c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5405c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::GlobalValue::InternalLinkage, Init, Name); 5406c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 5407493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian GV->setSection(Section); 5408ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 5409c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); 5410493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian} 541198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian 5412ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// ObjCIvarOffsetVariable - Returns the ivar offset variable for 5413ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// the given ivar. 5414e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::GlobalVariable * 5415e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 5416e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCIvarDecl *Ivar) { 5417e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); 5418a81419d0b53a40399a589a2fcc13f1ed2ec28f75Daniel Dunbar std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 54196ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor '.' + Ivar->getNameAsString(); 54206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *IvarOffsetGV = 5421ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian CGM.getModule().getGlobalVariable(Name); 5422ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian if (!IvarOffsetGV) 54236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarOffsetGV = 54241c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, 5425ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian false, 5426ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian llvm::GlobalValue::ExternalLinkage, 5427ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian 0, 54281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Name); 5429ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian return IvarOffsetGV; 5430ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian} 5431ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian 5432e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::Constant * 5433e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 5434e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar const ObjCIvarDecl *Ivar, 5435e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar unsigned long int Offset) { 5436737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 54376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 5438737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar Offset)); 543909796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian IvarOffsetGV->setAlignment( 54404b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy)); 5441737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar 5442f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 5443f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // well (i.e., in ObjCIvarOffsetVariable). 5444737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 5445737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar Ivar->getAccessControl() == ObjCIvarDecl::Package || 54461fb0caaa7bef765b85972274e3b434af2572c141John McCall ID->getVisibility() == HiddenVisibility) 54472fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 544804d4078425614bf9fd58d606335c1f5f74ee7fa4Daniel Dunbar else 544977c9fd2eee4cdac3c5a38a353788f308990598afFariborz Jahanian IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 54501f382510495b581e3028d670a23c7dcf5440be62Bill Wendling IvarOffsetGV->setSection("__DATA, __objc_ivar"); 545145012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian return IvarOffsetGV; 54521bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian} 54531bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian 545498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// EmitIvarList - Emit the ivar list for the given 54551139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar/// implementation. The return value has type 545698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// IvarListnfABIPtrTy. 545798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_t { 545898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// unsigned long int *offset; // pointer to ivar offset location 545998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// char *name; 546098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// char *type; 546198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32_t alignment; 546298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32_t size; 546398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// } 546498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_list_t { 546598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32 entsize; // sizeof(struct _ivar_t) 546698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// uint32 count; 546798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _iver_t list[count]; 546898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// } 546998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// 54703e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar 547198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 54726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCImplementationDecl *ID) { 54736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 54741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer std::vector<llvm::Constant*> Ivars; 54756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5476db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const ObjCInterfaceDecl *OID = ID->getClassInterface(); 547798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 54786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 54791bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian // FIXME. Consolidate this with similar code in GenerateClass. 54806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5481db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 5482bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian IVD; IVD = IVD->getNextIvar()) { 54838e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian // Ignore unnamed bit-fields. 54848e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian if (!IVD->getDeclName()) 54858e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian continue; 54861d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Ivar[5]; 54876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 54889f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar ComputeIvarBaseOffset(CGM, ID, IVD)); 54893fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 54903fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar Ivar[2] = GetMethodVarType(IVD); 54912acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *FieldTy = 54923fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar CGM.getTypes().ConvertTypeForMem(IVD->getType()); 54939408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 549498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian unsigned Align = CGM.getContext().getPreferredTypeAlign( 54956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar IVD->getType().getTypePtr()) >> 3; 549698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Align = llvm::Log2_32(Align); 54974a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 549891636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // NOTE. Size of a bitfield does not match gcc's, because of the 549991636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // way bitfields are treated special in each. But I am told that 550091636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // 'size' for bitfield ivars is ignored by the runtime so it does 550191636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // not matter. If it matters, there is enough info to get the 550291636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar // bitfield right! 55034a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 550408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 550598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian } 550698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian // Return null for empty list. 550798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian if (Ivars.empty()) 5508c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 5509c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner 5510c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[3]; 55119408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 55124a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 55134a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 551496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 551598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Ivars.size()); 55167db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson Values[2] = llvm::ConstantArray::get(AT, Ivars); 5517c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 551898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 551998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::GlobalVariable *GV = 55201c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 552198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 552298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian Init, 55239c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Prefix + OID->getName()); 552409796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 55254b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(Init->getType())); 55261bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian GV->setSection("__DATA, __objc_const"); 55276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5528ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 55293c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); 5530da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5531da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5532da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 55336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 5534da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 55356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5536da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (!Entry) { 5537da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // We use the initializer as a marker of whether this is a forward 5538da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // reference or not. At module finalization we add the empty 5539da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // contents for protocols which were referenced but never defined. 55406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 55416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, 55426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 55436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 55449c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 5545da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5546da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 55476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5548da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5549da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5550da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5551da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// GetOrEmitProtocol - Generate the protocol meta-data: 5552da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code 5553da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t { 5554da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// id isa; // NULL 5555da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const char * const protocol_name; 5556da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _protocol_list_t * protocol_list; // super protocols 5557da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t * const instance_methods; 5558da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t * const class_methods; 5559da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t *optionalInstanceMethods; 5560da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct method_list_t *optionalClassMethods; 5561da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const struct _prop_list_t * properties; 5562da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const uint32_t size; // sizeof(struct _protocol_t) 5563da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// const uint32_t flags; // = 0 5564dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson/// const char ** extendedMethodTypes; 5565da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// } 5566da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode 5567da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// 5568da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5569da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 55706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCProtocolDecl *PD) { 557150651b951c216573175e2145f32df2c4658ba3f9John McCall llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()]; 55726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5573da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Early exit if a defining object has already been generated. 5574da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (Entry && Entry->hasInitializer()) 5575da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5576da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 55771d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor // Use the protocol definition, if there is one. 55781d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor if (const ObjCProtocolDecl *Def = PD->getDefinition()) 55791d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor PD = Def; 55801d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor 5581da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Construct method lists. 5582da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 5583da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 5584dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt; 55856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::instmeth_iterator 558617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 5587da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCMethodDecl *MD = *i; 55883819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *C = GetMethodDescriptionConstant(MD); 5589f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 5590f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 5591f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 5592da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5593da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptInstanceMethods.push_back(C); 5594dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 5595da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 5596da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian InstanceMethods.push_back(C); 5597dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.push_back(GetMethodVarType(MD, true)); 55986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 5599da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 56006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 56016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar for (ObjCProtocolDecl::classmeth_iterator 560217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 5603da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ObjCMethodDecl *MD = *i; 56043819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian llvm::Constant *C = GetMethodDescriptionConstant(MD); 5605f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!C) 5606f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return GetOrEmitProtocolRef(PD); 5607f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 5608da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5609da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptClassMethods.push_back(C); 5610dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 5611da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 5612da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ClassMethods.push_back(C); 5613dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.push_back(GetMethodVarType(MD, true)); 56146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar } 5615da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 56166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5617dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt.insert(MethodTypesExt.end(), 5618dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson OptMethodTypesExt.begin(), OptMethodTypesExt.end()); 5619dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson 5620dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson llvm::Constant *Values[11]; 5621da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // isa is NULL 5622c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 5623da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Values[1] = GetClassName(PD->getIdentifier()); 56249c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), 56259c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar PD->protocol_begin(), 56269c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar PD->protocol_end()); 56276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 56283819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 56299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5630da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5631da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian InstanceMethods); 56326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 56339c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5634da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5635da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian ClassMethods); 56363819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 56379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5638da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5639da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptInstanceMethods); 56406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 56419c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar + PD->getName(), 5642da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian "__DATA, __objc_const", 5643da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian OptClassMethods); 56449c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(), 5645da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 0, PD, ObjCTypes); 56466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar uint32_t Size = 56479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 56484a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5649c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 5650dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 5651dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson + PD->getName(), 5652dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson MethodTypesExt, ObjCTypes); 565308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 5654da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Values); 56556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5656da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (Entry) { 5657da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Already created, fix the linkage and update the initializer. 5658286acbdbe0c82e9a6bcad5fca3c4fa582f3f1a2cMike Stump Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 5659da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setInitializer(Init); 5660da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } else { 56616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 56629c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 56639c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar false, llvm::GlobalValue::WeakAnyLinkage, Init, 56649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 566509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian Entry->setAlignment( 56664b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy)); 5667da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian Entry->setSection("__DATA,__datacoal_nt,coalesced"); 566850651b951c216573175e2145f32df2c4658ba3f9John McCall 566950651b951c216573175e2145f32df2c4658ba3f9John McCall Protocols[PD->getIdentifier()] = Entry; 5670da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian } 56718448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 5672ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 5673ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner 56748448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian // Use this protocol meta-data to build protocol list table in section 56758448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian // __DATA, __objc_protolist 56769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::GlobalVariable *PTGV = 56779c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 56789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar false, llvm::GlobalValue::WeakAnyLinkage, Entry, 56799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName()); 568009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian PTGV->setAlignment( 56814b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 56820bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 56838448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5684ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(PTGV); 5685da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian return Entry; 5686da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5687da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 5688da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// EmitProtocolList - Generate protocol list meta-data: 5689da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code 5690da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_list_t { 5691da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// long protocol_count; // Note, this is 32/64 bit 5692da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t[protocol_count]; 5693da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// } 5694da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode 5695da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// 5696da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant * 56975f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCNonFragileABIMac::EmitProtocolList(Twine Name, 56989c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ObjCProtocolDecl::protocol_iterator begin, 56999c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ObjCProtocolDecl::protocol_iterator end) { 57003964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs; 57016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5702da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // Just return null for empty protocol lists 57036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar if (begin == end) 5704c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 57056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5706948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar // FIXME: We shouldn't need to do this lookup here, should we? 5707f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> TmpName; 57089c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar Name.toVector(TmpName); 57099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar llvm::GlobalVariable *GV = 57109c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar CGM.getModule().getGlobalVariable(TmpName.str(), true); 5711da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian if (GV) 57129c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); 57136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5714948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar for (; begin != end; ++begin) 5715948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 5716948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar 5717da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian // This list is null terminated. 5718c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson ProtocolRefs.push_back(llvm::Constant::getNullValue( 57196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ProtocolnfABIPtrTy)); 57206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5721c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Values[2]; 5722a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson Values[0] = 57234a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 57246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Values[1] = 57253964e62786b0912fecc82d776daac236e05fc792Bill Wendling llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 57263964e62786b0912fecc82d776daac236e05fc792Bill Wendling ProtocolRefs.size()), 57273964e62786b0912fecc82d776daac236e05fc792Bill Wendling ProtocolRefs); 57286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5729c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 57301c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5731da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 5732c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner Init, Name); 5733da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian GV->setSection("__DATA, __objc_const"); 573409796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian GV->setAlignment( 57354b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment(Init->getType())); 5736ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(GV); 57376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return llvm::ConstantExpr::getBitCast(GV, 5738948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar ObjCTypes.ProtocolListnfABIPtrTy); 5739da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian} 5740da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian 57413819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// GetMethodDescriptionConstant - This routine build following meta-data: 57423819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// struct _objc_method { 57433819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// SEL _cmd; 57443819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// char *method_type; 57453819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// char *_imp; 57463819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// } 57473819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian 57483819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanianllvm::Constant * 57493819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz JahanianCGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 57501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Desc[3]; 5751a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson Desc[0] = 57526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 57536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.SelectorPtrTy); 57543819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian Desc[1] = GetMethodVarType(MD); 5755f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor if (!Desc[1]) 5756f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor return 0; 5757f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor 57588cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian // Protocol methods have no implementation. So, this entry is always NULL. 5759c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 576008e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 57613819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian} 576245012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian 576345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 576445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// This code gen. amounts to generating code for: 576545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @code 576645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 576745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @encode 57686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// 5769598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 5770506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall CodeGen::CodeGenFunction &CGF, 5771506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall QualType ObjectTy, 5772506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall llvm::Value *BaseValue, 5773506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall const ObjCIvarDecl *Ivar, 5774506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall unsigned CVRQualifiers) { 5775506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface(); 5776cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar); 5777cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset)) 5778cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 5779cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian llvm::MDNode::get(VMContext, 5780cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian ArrayRef<llvm::Value*>())); 57819777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 5782cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian Offset); 578345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian} 578445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian 5785f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 57866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 57876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *Interface, 57886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCIvarDecl *Ivar) { 57892da84ff228a231adbd3f6f236b857f752d02959aDaniel Dunbar return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); 5790f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian} 5791f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian 5792b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCallstatic void appendSelectorForMessageRefTable(std::string &buffer, 5793b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall Selector selector) { 5794b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (selector.isUnarySelector()) { 5795b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += selector.getNameForSlot(0); 5796b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall return; 5797b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } 57986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5799b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) { 5800b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += selector.getNameForSlot(i); 5801b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall buffer += '_'; 5802b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } 5803b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall} 5804b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5805944c84313da15477eb18d90babb0890d10d98082John McCall/// Emit a "v-table" message send. We emit a weak hidden-visibility 5806944c84313da15477eb18d90babb0890d10d98082John McCall/// struct, initially containing the selector pointer and a pointer to 5807944c84313da15477eb18d90babb0890d10d98082John McCall/// a "fixup" variant of the appropriate objc_msgSend. To call, we 5808944c84313da15477eb18d90babb0890d10d98082John McCall/// load and call the function pointer, passing the address of the 5809944c84313da15477eb18d90babb0890d10d98082John McCall/// struct as the second parameter. The runtime determines whether 5810944c84313da15477eb18d90babb0890d10d98082John McCall/// the selector is currently emitted using vtable dispatch; if so, it 5811944c84313da15477eb18d90babb0890d10d98082John McCall/// substitutes a stub function which simply tail-calls through the 5812944c84313da15477eb18d90babb0890d10d98082John McCall/// appropriate vtable slot, and if not, it substitues a stub function 5813944c84313da15477eb18d90babb0890d10d98082John McCall/// which tail-calls objc_msgSend. Both stubs adjust the selector 5814944c84313da15477eb18d90babb0890d10d98082John McCall/// argument to correctly point to the selector. 5815944c84313da15477eb18d90babb0890d10d98082John McCallRValue 5816944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, 5817944c84313da15477eb18d90babb0890d10d98082John McCall ReturnValueSlot returnSlot, 5818944c84313da15477eb18d90babb0890d10d98082John McCall QualType resultType, 5819944c84313da15477eb18d90babb0890d10d98082John McCall Selector selector, 5820944c84313da15477eb18d90babb0890d10d98082John McCall llvm::Value *arg0, 5821944c84313da15477eb18d90babb0890d10d98082John McCall QualType arg0Type, 5822944c84313da15477eb18d90babb0890d10d98082John McCall bool isSuper, 5823944c84313da15477eb18d90babb0890d10d98082John McCall const CallArgList &formalArgs, 5824944c84313da15477eb18d90babb0890d10d98082John McCall const ObjCMethodDecl *method) { 5825b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Compute the actual arguments. 5826b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CallArgList args; 5827b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5828944c84313da15477eb18d90babb0890d10d98082John McCall // First argument: the receiver / super-call structure. 5829b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (!isSuper) 5830944c84313da15477eb18d90babb0890d10d98082John McCall arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy); 5831944c84313da15477eb18d90babb0890d10d98082John McCall args.add(RValue::get(arg0), arg0Type); 5832b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5833944c84313da15477eb18d90babb0890d10d98082John McCall // Second argument: a pointer to the message ref structure. Leave 5834944c84313da15477eb18d90babb0890d10d98082John McCall // the actual argument value blank for now. 5835b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy); 5836b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5837b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args.insert(args.end(), formalArgs.begin(), formalArgs.end()); 5838b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5839de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall MessageSendInfo MSI = getMessageSendInfo(method, resultType, args); 5840b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5841cba681af356e24ec4335bcf2b6bb6515072ace99John McCall NullReturnState nullReturn; 5842cba681af356e24ec4335bcf2b6bb6515072ace99John McCall 5843944c84313da15477eb18d90babb0890d10d98082John McCall // Find the function to call and the mangled name for the message 5844944c84313da15477eb18d90babb0890d10d98082John McCall // ref structure. Using a different mangled name wouldn't actually 5845944c84313da15477eb18d90babb0890d10d98082John McCall // be a problem; it would just be a waste. 5846944c84313da15477eb18d90babb0890d10d98082John McCall // 5847944c84313da15477eb18d90babb0890d10d98082John McCall // The runtime currently never uses vtable dispatch for anything 5848944c84313da15477eb18d90babb0890d10d98082John McCall // except normal, non-super message-sends. 5849944c84313da15477eb18d90babb0890d10d98082John McCall // FIXME: don't use this for that. 5850b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Constant *fn = 0; 5851b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall std::string messageRefName("\01l_"); 5852de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { 5853b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (isSuper) { 5854b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 5855b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSendSuper2_stret_fixup"; 58569b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } else { 5857cba681af356e24ec4335bcf2b6bb6515072ace99John McCall nullReturn.init(CGF, arg0); 5858b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendStretFixupFn(); 5859b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_stret_fixup"; 58609b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } 5861b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) { 5862b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendFpretFixupFn(); 5863b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_fpret_fixup"; 5864b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 5865b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (isSuper) { 5866b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendSuper2FixupFn(); 5867b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSendSuper2_fixup"; 58689b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } else { 5869b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall fn = ObjCTypes.getMessageSendFixupFn(); 5870b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += "objc_msgSend_fixup"; 58719b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner } 587283a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian } 5873b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 5874b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName += '_'; 5875b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5876b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Append the selector name, except use underscores anywhere we 5877b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // would have used colons. 5878b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall appendSelectorForMessageRefTable(messageRefName, selector); 5879b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5880b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::GlobalVariable *messageRef 5881b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall = CGM.getModule().getGlobalVariable(messageRefName); 5882b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall if (!messageRef) { 5883944c84313da15477eb18d90babb0890d10d98082John McCall // Build the message ref structure. 5884b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Constant *values[] = { fn, GetMethodVarName(selector) }; 5885c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(values); 5886b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef = new llvm::GlobalVariable(CGM.getModule(), 5887b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall init->getType(), 5888b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall /*constant*/ false, 5889b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::GlobalValue::WeakAnyLinkage, 5890b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall init, 5891b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRefName); 5892b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); 5893b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setAlignment(16); 5894b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall messageRef->setSection("__DATA, __objc_msgrefs, coalesced"); 589583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian } 58963c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian 58973c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian bool requiresnullCheck = false; 58984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().ObjCAutoRefCount && method) 58993c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian for (ObjCMethodDecl::param_const_iterator i = method->param_begin(), 59003c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian e = method->param_end(); i != e; ++i) { 59013c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian const ParmVarDecl *ParamDecl = (*i); 59023c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian if (ParamDecl->hasAttr<NSConsumedAttr>()) { 59033c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian if (!nullReturn.NullBB) 59043c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian nullReturn.init(CGF, arg0); 59053c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian requiresnullCheck = true; 59063c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian break; 59073c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian } 59083c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian } 59093c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian 5910b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Value *mref = 5911b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); 59126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 5913944c84313da15477eb18d90babb0890d10d98082John McCall // Update the message ref argument. 5914b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall args[1].RV = RValue::get(mref); 5915b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5916b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall // Load the function to call from the message ref table. 5917b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0); 5918b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall callee = CGF.Builder.CreateLoad(callee, "msgSend_fn"); 5919b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5920de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType); 5921b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall 5922de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args); 59233c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian return nullReturn.complete(CGF, result, resultType, formalArgs, 59243c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian requiresnullCheck ? method : 0); 59254655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian} 59264655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian 59274655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian/// Generate code for a message send expression in the nonfragile abi. 5928d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue 5929d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 5930ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 5931d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar QualType ResultType, 5932d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar Selector Sel, 5933d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar llvm::Value *Receiver, 5934d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CallArgList &CallArgs, 5935c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall const ObjCInterfaceDecl *Class, 5936d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 5937944c84313da15477eb18d90babb0890d10d98082John McCall return isVTableDispatchedSelector(Sel) 5938944c84313da15477eb18d90babb0890d10d98082John McCall ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 59396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Receiver, CGF.getContext().getObjCIdType(), 5940944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method) 5941944c84313da15477eb18d90babb0890d10d98082John McCall : EmitMessageSend(CGF, Return, ResultType, 5942944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 59436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Receiver, CGF.getContext().getObjCIdType(), 5944944c84313da15477eb18d90babb0890d10d98082John McCall false, CallArgs, Method, ObjCTypes); 59454655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian} 59464655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian 59475a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbarllvm::GlobalVariable * 59480f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz JahanianCGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 59495a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 59505a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 5951dfff23060b4a3add79a3bb68ccec606ade4f39bfDaniel Dunbar if (!GV) { 59526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, 59531c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson false, llvm::GlobalValue::ExternalLinkage, 59541c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson 0, Name); 59555a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar } 59565a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 59575a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar return GV; 59585a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar} 59595a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar 5960f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder, 5961f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II) { 5962f85e193739c953358c865005855253af4f68a497John McCall llvm::GlobalVariable *&Entry = ClassReferences[II]; 5963f85e193739c953358c865005855253af4f68a497John McCall 59640e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian if (!Entry) { 5965f85e193739c953358c865005855253af4f68a497John McCall std::string ClassName(getClassSymbolPrefix() + II->getName().str()); 59665a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 59676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 5968f85e193739c953358c865005855253af4f68a497John McCall new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5969f85e193739c953358c865005855253af4f68a497John McCall false, llvm::GlobalValue::InternalLinkage, 5970f85e193739c953358c865005855253af4f68a497John McCall ClassGV, 5971f85e193739c953358c865005855253af4f68a497John McCall "\01L_OBJC_CLASSLIST_REFERENCES_$_"); 59720e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian Entry->setAlignment( 5973f85e193739c953358c865005855253af4f68a497John McCall CGM.getTargetData().getABITypeAlignment( 5974f85e193739c953358c865005855253af4f68a497John McCall ObjCTypes.ClassnfABIPtrTy)); 59751139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 5976ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 59771139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar } 5978f85e193739c953358c865005855253af4f68a497John McCall 5979578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 59801139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar} 59810e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 5982f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 5983f85e193739c953358c865005855253af4f68a497John McCall const ObjCInterfaceDecl *ID) { 5984f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, ID->getIdentifier()); 5985f85e193739c953358c865005855253af4f68a497John McCall} 5986f85e193739c953358c865005855253af4f68a497John McCall 5987f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef( 5988f85e193739c953358c865005855253af4f68a497John McCall CGBuilderTy &Builder) { 5989f85e193739c953358c865005855253af4f68a497John McCall IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 5990f85e193739c953358c865005855253af4f68a497John McCall return EmitClassRefFromId(Builder, II); 5991f85e193739c953358c865005855253af4f68a497John McCall} 5992f85e193739c953358c865005855253af4f68a497John McCall 59931139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbarllvm::Value * 59946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 59951139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar const ObjCInterfaceDecl *ID) { 59961139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 59976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 59981139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar if (!Entry) { 59991139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 60001139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 60016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 60026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 60031c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson false, llvm::GlobalValue::InternalLinkage, 60046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ClassGV, 60051c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 60061139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setAlignment( 60074b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment( 60086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ClassnfABIPtrTy)); 60091139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 6010ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 60110e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian } 60126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6013578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 60140e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian} 60150e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 60167a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// EmitMetaClassRef - Return a Value * of the address of _class_t 60177a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// meta-data 60187a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// 60196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 60206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *ID) { 60217a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 60227a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian if (Entry) 6023578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 60246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 60256ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 60260f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 60276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 60281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, 60297a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::GlobalValue::InternalLinkage, 60306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar MetaClassGV, 60311c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 60327a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian Entry->setAlignment( 60334b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar CGM.getTargetData().getABITypeAlignment( 60346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.ClassnfABIPtrTy)); 60356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 603633af70f0f003d9765b92621f4fdd801e2b6c0ae7Daniel Dunbar Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 6037ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 60386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6039578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return Builder.CreateLoad(Entry); 60407a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian} 60417a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian 60420e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// GetClass - Return a reference to the class for the given interface 60430e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// decl. 60440e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 60450e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian const ObjCInterfaceDecl *ID) { 60460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ID->isWeakImported()) { 6047269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 6048269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 6049269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 6050269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian } 6051269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian 60520e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian return EmitClassRef(Builder, ID); 60530e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian} 60540e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian 60557a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// Generates a message send where the super is the receiver. This is 60567a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// a message send to self with special delivery semantics indicating 60577a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// which class's method should be called. 60587a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCodeGen::RValue 60597a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 6060ef072fd2f3347cfd857d6eb787b245b950771430John McCall ReturnValueSlot Return, 60616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar QualType ResultType, 60626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Selector Sel, 60636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar const ObjCInterfaceDecl *Class, 60646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool isCategoryImpl, 60656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *Receiver, 60666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar bool IsClassMessage, 6067d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const CodeGen::CallArgList &CallArgs, 6068d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar const ObjCMethodDecl *Method) { 60697a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // ... 60707a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // Create and init a super structure; this is a (receiver, class) 60717a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // pair we will pass to objc_msgSendSuper. 60727a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::Value *ObjCSuper = 6073604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 60746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 60757a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian llvm::Value *ReceiverAsObject = 60767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 60777a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStore(ReceiverAsObject, 60787a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 60796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 60807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian // If this is a class message the metaclass is passed as the target. 60817ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian llvm::Value *Target; 60827ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (IsClassMessage) { 60837ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian if (isCategoryImpl) { 60847ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // Message sent to "super' in a class method defined in 60857ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian // a category implementation. 60861139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Target = EmitClassRef(CGF.Builder, Class); 60877ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateStructGEP(Target, 0); 60887ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = CGF.Builder.CreateLoad(Target); 6089b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else 60907ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian Target = EmitMetaClassRef(CGF.Builder, Class); 6091b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else 60921139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar Target = EmitSuperClassRef(CGF.Builder, Class); 60936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6094f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 6095f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ObjCTypes types. 60962acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ClassTy = 60977a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 60987a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian Target = CGF.Builder.CreateBitCast(Target, ClassTy); 60997a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStore(Target, 61007a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 61016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6102944c84313da15477eb18d90babb0890d10d98082John McCall return (isVTableDispatchedSelector(Sel)) 6103944c84313da15477eb18d90babb0890d10d98082John McCall ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 61046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCSuper, ObjCTypes.SuperPtrCTy, 6105944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method) 6106944c84313da15477eb18d90babb0890d10d98082John McCall : EmitMessageSend(CGF, Return, ResultType, 6107944c84313da15477eb18d90babb0890d10d98082John McCall EmitSelector(CGF.Builder, Sel), 61086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCSuper, ObjCTypes.SuperPtrCTy, 6109944c84313da15477eb18d90babb0890d10d98082John McCall true, CallArgs, Method, ObjCTypes); 61107a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian} 611126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian 61126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 611303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian Selector Sel, bool lval) { 611426cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 61156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 611626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian if (!Entry) { 61176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Constant *Casted = 61186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 61196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar ObjCTypes.SelectorPtrTy); 61206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Entry = 61216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 61226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalValue::InternalLinkage, 61236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); 6124d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 6125ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner CGM.AddUsedGlobal(Entry); 612626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian } 61276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 612803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian if (lval) 612903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian return Entry; 6130b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper llvm::LoadInst* LI = Builder.CreateLoad(Entry); 6131b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper 6132b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 6133b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper llvm::MDNode::get(VMContext, 6134b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper ArrayRef<llvm::Value*>())); 6135b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper return LI; 613626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian} 61376948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 61386c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t) 61396948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 61406948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 61411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, 61426c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *dst, 61436c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian llvm::Value *ivarOffset) { 61442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 61450a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 61469408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 61470a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 61480a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 61490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 61503b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 61513b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 61526948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 61536948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 61546c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 61556c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian src, dst, ivarOffset); 61566948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 61576948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 61586948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 61596948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 61606948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst) 61616948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 61626948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 61636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 61641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 61652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 61660a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 61679408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 61680a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 61690a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 61706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 61713b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 61723b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 61736948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 61746948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6175bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 61766948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src, dst, "weakassign"); 61776948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 61786948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 61796948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 6180082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 61816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 61826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *DestPtr, 61836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::Value *SrcPtr, 618455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian llvm::Value *Size) { 6185082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 6186082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 6187082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 618855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian DestPtr, SrcPtr, Size); 6189082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian return; 6190082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian} 6191082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian 61926948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak 61936948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// object: objc_read_weak (id *src) 61946948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 61956948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 61966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar CodeGen::CodeGenFunction &CGF, 61971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *AddrWeakObj) { 61982acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type* DestTy = 61996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 62006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 620172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 62026948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian AddrWeakObj, "weakread"); 62038339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 62046948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return read_weak; 62056948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 62066948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 62076948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 62086948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_weak (id src, id *dst) 62096948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 62106948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 62111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *src, llvm::Value *dst) { 62122acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 62130a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 62149408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 62150a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 62160a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 62170a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 62183b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 62193b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 62206948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 62216948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 622296508e1fea58347b6401ca9a4728c0b268174603Chris Lattner CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 62236948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src, dst, "weakassign"); 62246948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 62256948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 62266948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian 62276948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 62286948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_global (id src, id *dst) 62296948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// 62306948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 6231021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian llvm::Value *src, llvm::Value *dst, 6232021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian bool threadlocal) { 62332acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type * SrcTy = src->getType(); 62340a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian if (!isa<llvm::PointerType>(SrcTy)) { 62359408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 62360a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian assert(Size <= 8 && "does not support size > 8"); 62370a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 62380a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 62393b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 62403b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian } 62416948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 62426948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6243021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian if (!threadlocal) 6244021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 6245021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "globalassign"); 6246021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian else 6247021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 6248021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian src, dst, "threadlocalassign"); 62496948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian return; 62506948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian} 625126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian 62526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid 6253f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 6254f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtSynchronizedStmt &S) { 625505dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall EmitAtSynchronizedStmt(CGF, S, 625605dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 625705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 6258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 62594ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar 62605a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant * 6261cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz JahanianCGObjCNonFragileABIMac::GetEHType(QualType T) { 62625a180397870944548aaadeaebf58e415885b9489John McCall // There's a particular fixed type info for 'id'. 62635a180397870944548aaadeaebf58e415885b9489John McCall if (T->isObjCIdType() || 62645a180397870944548aaadeaebf58e415885b9489John McCall T->isObjCQualifiedIdType()) { 62655a180397870944548aaadeaebf58e415885b9489John McCall llvm::Constant *IDEHType = 62665a180397870944548aaadeaebf58e415885b9489John McCall CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 62675a180397870944548aaadeaebf58e415885b9489John McCall if (!IDEHType) 62685a180397870944548aaadeaebf58e415885b9489John McCall IDEHType = 62695a180397870944548aaadeaebf58e415885b9489John McCall new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 62705a180397870944548aaadeaebf58e415885b9489John McCall false, 62715a180397870944548aaadeaebf58e415885b9489John McCall llvm::GlobalValue::ExternalLinkage, 62725a180397870944548aaadeaebf58e415885b9489John McCall 0, "OBJC_EHTYPE_id"); 62735a180397870944548aaadeaebf58e415885b9489John McCall return IDEHType; 62745a180397870944548aaadeaebf58e415885b9489John McCall } 62755a180397870944548aaadeaebf58e415885b9489John McCall 62765a180397870944548aaadeaebf58e415885b9489John McCall // All other types should be Objective-C interface pointer types. 62775a180397870944548aaadeaebf58e415885b9489John McCall const ObjCObjectPointerType *PT = 62785a180397870944548aaadeaebf58e415885b9489John McCall T->getAs<ObjCObjectPointerType>(); 62795a180397870944548aaadeaebf58e415885b9489John McCall assert(PT && "Invalid @catch type."); 62805a180397870944548aaadeaebf58e415885b9489John McCall const ObjCInterfaceType *IT = PT->getInterfaceType(); 62815a180397870944548aaadeaebf58e415885b9489John McCall assert(IT && "Invalid @catch type."); 62825a180397870944548aaadeaebf58e415885b9489John McCall return GetInterfaceEHType(IT->getDecl(), false); 62835a180397870944548aaadeaebf58e415885b9489John McCall} 62845a180397870944548aaadeaebf58e415885b9489John McCall 6285f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 6286f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const ObjCAtTryStmt &S) { 628705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall EmitTryCatchStmt(CGF, S, 628805dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 628905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 629005dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 62918ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar} 62928ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar 6293f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson/// EmitThrowStmt - Generate code for a throw statement. 6294f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlssonvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 6295f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson const ObjCAtThrowStmt &S) { 6296f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson if (const Expr *ThrowExpr = S.getThrowExpr()) { 62972b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 6298578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 62994c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception) 63007ec404c40e42ce274d956a289ffa91e8f4befc43John McCall .setDoesNotReturn(); 6301f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 63024c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn()) 63037ec404c40e42ce274d956a289ffa91e8f4befc43John McCall .setDoesNotReturn(); 6304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 63054ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar 63067ec404c40e42ce274d956a289ffa91e8f4befc43John McCall CGF.Builder.CreateUnreachable(); 6307f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson CGF.Builder.ClearInsertionPoint(); 6308f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson} 6309e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 63105a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant * 63116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 63128158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar bool ForDefinition) { 6313e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 63147e075cb62c06e0b0023fd12875c95da9c5ddefb7Daniel Dunbar 63158158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // If we don't need a definition, return the entry if found or check 63168158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // if we use an external reference. 63178158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (!ForDefinition) { 63188158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (Entry) 63198158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar return Entry; 63208158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 63218158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // If this type (or a super class) has the __objc_exception__ 63228158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // attribute, emit an external reference. 632368584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 63246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar return Entry = 63251c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 63268158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar llvm::GlobalValue::ExternalLinkage, 63276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 0, 63289c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ("OBJC_EHTYPE_$_" + 632901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar ID->getIdentifier()->getName())); 63308158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 63316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 63328158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // Otherwise we need to either make a new entry or fill in the 63338158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar // initializer. 63348158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 63356ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 6336e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar std::string VTableName = "objc_ehtype_vtable"; 63376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar llvm::GlobalVariable *VTableGV = 6338e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar CGM.getModule().getGlobalVariable(VTableName); 6339e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar if (!VTableGV) 63406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, 63416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar false, 6342e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar llvm::GlobalValue::ExternalLinkage, 63431c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson 0, VTableName); 6344e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 63458b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 6346e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 63471d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::Constant *Values[] = { 63481d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx), 63491d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassName(ID->getIdentifier()), 63501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer GetClassGlobal(ClassName) 63511d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer }; 6352a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::Constant *Init = 635308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 6354e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 63558158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (Entry) { 63568158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setInitializer(Init); 63578158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } else { 63581c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 63598158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar llvm::GlobalValue::WeakAnyLinkage, 63606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar Init, 63619c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar ("OBJC_EHTYPE_$_" + 636201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar ID->getIdentifier()->getName())); 63638158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 63648158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 63654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility) 63666ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 63674b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar Entry->setAlignment(CGM.getTargetData().getABITypeAlignment( 63684b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar ObjCTypes.EHTypeTy)); 63698158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar 63708158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar if (ForDefinition) { 63718158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setSection("__DATA,__objc_const"); 63728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 63738158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } else { 63748158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar Entry->setSection("__DATA,__datacoal_nt,coalesced"); 63758158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar } 6376e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar 6377e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar return Entry; 6378e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar} 63796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar 6380bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** */ 6381bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar 63826efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CGObjCRuntime * 63836efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 6384260611a32535c851237926bfcf78869b13c07d5bJohn McCall switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 6385260611a32535c851237926bfcf78869b13c07d5bJohn McCall case ObjCRuntime::FragileMacOSX: 6386c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar return new CGObjCMac(CGM); 6387260611a32535c851237926bfcf78869b13c07d5bJohn McCall 6388260611a32535c851237926bfcf78869b13c07d5bJohn McCall case ObjCRuntime::MacOSX: 6389260611a32535c851237926bfcf78869b13c07d5bJohn McCall case ObjCRuntime::iOS: 6390260611a32535c851237926bfcf78869b13c07d5bJohn McCall return new CGObjCNonFragileABIMac(CGM); 6391260611a32535c851237926bfcf78869b13c07d5bJohn McCall 639211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall case ObjCRuntime::GNUstep: 639311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall case ObjCRuntime::GCC: 6394f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall case ObjCRuntime::ObjFW: 6395260611a32535c851237926bfcf78869b13c07d5bJohn McCall llvm_unreachable("these runtimes are not Mac runtimes"); 6396260611a32535c851237926bfcf78869b13c07d5bJohn McCall } 6397260611a32535c851237926bfcf78869b13c07d5bJohn McCall llvm_unreachable("bad runtime"); 6398c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} 6399