CGObjCMac.cpp revision f3c47c9525153aea2de0ec4bd615b9cf2d81c103
16780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===// 26780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// 36780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// The LLVM Compiler Infrastructure 46780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// 56780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// This file is distributed under the University of Illinois Open Source 66780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// License. See LICENSE.TXT for details. 76780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// 86780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George//===----------------------------------------------------------------------===// 96780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// 106780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// This provides Objective-C code generation targetting the Apple runtime. 116780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// 126780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George//===----------------------------------------------------------------------===// 136780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 146780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "CGObjCRuntime.h" 156780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 166780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "CodeGenModule.h" 176780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "CodeGenFunction.h" 186780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/AST/ASTContext.h" 196780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/AST/Decl.h" 206780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/AST/DeclObjC.h" 216780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/AST/RecordLayout.h" 226780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/AST/StmtObjC.h" 236780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "clang/Basic/LangOptions.h" 246780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 256780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/Intrinsics.h" 266780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/LLVMContext.h" 276780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/Module.h" 286780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/ADT/DenseSet.h" 296780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/ADT/SetVector.h" 306780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/ADT/SmallString.h" 316780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/ADT/SmallPtrSet.h" 326780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/Support/raw_ostream.h" 336780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include "llvm/Target/TargetData.h" 346780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George#include <cstdio> 356780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 366780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeusing namespace clang; 376780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeusing namespace CodeGen; 386780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 396780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// Common CGObjCRuntime functions, these don't belong here, but they 406780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// don't belong in CGObjCRuntime either so we will live with it for 416780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// now. 426780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 436780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George/// FindIvarInterface - Find the interface containing the ivar. 446780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George/// 456780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George/// FIXME: We shouldn't need to do this, the containing context should 466780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George/// be fixed. 476780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgestatic const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 486780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCInterfaceDecl *OID, 496780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCIvarDecl *OIVD, 506780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George unsigned &Index) { 516780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // FIXME: The index here is closely tied to how 526780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // ASTContext::getObjCLayout is implemented. This should be fixed to 536780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // get the information from the layout directly. 546780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Index = 0; 556780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 566780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Context.ShallowCollectObjCIvars(OID, Ivars); 576780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 586780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George if (OIVD == Ivars[k]) 596780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return OID; 606780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George ++Index; 616780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 626780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 636780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // Otherwise check in the super class. 646780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 656780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return FindIvarInterface(Context, Super, OIVD, Index); 666780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 676780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return 0; 686780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George} 696780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 706780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgestatic uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, 716780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCInterfaceDecl *OID, 726780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCImplementationDecl *ID, 736780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCIvarDecl *Ivar) { 746780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George unsigned Index; 756780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCInterfaceDecl *Container = 766780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George FindIvarInterface(CGM.getContext(), OID, Ivar, Index); 776780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George assert(Container && "Unable to find ivar container"); 786780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 796780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // If we know have an implementation (and the ivar is in it) then 806780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // look up in the implementation layout. 816780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ASTRecordLayout *RL; 826780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George if (ID && ID->getClassInterface() == Container) 836780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George RL = &CGM.getContext().getASTObjCImplementationLayout(ID); 846780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George else 856780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George RL = &CGM.getContext().getASTObjCInterfaceLayout(Container); 866780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return RL->getFieldOffset(Index); 876780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George} 886780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 896780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeuint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 906780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCInterfaceDecl *OID, 916780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCIvarDecl *Ivar) { 926780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8; 936780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George} 946780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 956780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeuint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 966780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCImplementationDecl *OID, 976780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCIvarDecl *Ivar) { 986780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8; 996780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George} 1006780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1016780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew GeorgeLValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, 1026780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCInterfaceDecl *OID, 1036780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Value *BaseValue, 1046780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const ObjCIvarDecl *Ivar, 1056780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George unsigned CVRQualifiers, 1066780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Value *Offset) { 1076780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // Compute (type*) ( (char *) BaseValue + Offset) 1086780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 1096780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George QualType IvarTy = Ivar->getType(); 1106780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy); 1116780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr); 1126780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George V = CGF.Builder.CreateGEP(V, Offset, "add.ptr"); 1136780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy)); 1146780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1156780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Qualifiers Quals = CGF.MakeQualifiers(IvarTy); 1166780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Quals.addCVRQualifiers(CVRQualifiers); 1176780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1186780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George if (Ivar->isBitField()) { 1196780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // We need to compute the bit offset for the bit-field, the offset 1206780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // is to the byte. Note, there is a subtle invariant here: we can 1216780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // only call this routine on non-sythesized ivars but we may be 1226780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // called for synthesized ivars. However, a synthesized ivar can 1236780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // never be a bit-field so this is safe. 1246780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8; 1256780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1266780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George uint64_t BitFieldSize = 1276780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); 1286780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return LValue::MakeBitfield(V, BitOffset, BitFieldSize, 1296780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George IvarTy->isSignedIntegerType(), 1306780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Quals.getCVRQualifiers()); 1316780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 1326780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1336780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1346780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George LValue LV = LValue::MakeAddr(V, Quals); 1356780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return LV; 1366780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George} 1376780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1386780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George/// 1396780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1406780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgenamespace { 1416780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1426780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgetypedef std::vector<llvm::Constant*> ConstantVector; 1436780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1446780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// FIXME: We should find a nicer way to make the labels for metadata, string 1456780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George// concatenation is lame. 1466780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1476780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeclass ObjCCommonTypesHelper { 1486780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeprotected: 1496780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::LLVMContext &VMContext; 1506780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1516780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeprivate: 1526780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendFn() const { 1536780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // id objc_msgSend (id, SEL, ...) 1546780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 1556780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(ObjectPtrTy); 1566780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 1576780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return 1586780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1596780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 1606780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George "objc_msgSend"); 1616780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 1626780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1636780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendStretFn() const { 1646780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // id objc_msgSend_stret (id, SEL, ...) 1656780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 1666780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(ObjectPtrTy); 1676780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 1686780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return 1696780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1706780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 1716780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George "objc_msgSend_stret"); 1726780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1736780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 1746780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1756780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendFpretFn() const { 1766780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // FIXME: This should be long double on x86_64? 1776780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 1786780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 1796780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(ObjectPtrTy); 1806780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 1816780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return 1826780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George CGM.CreateRuntimeFunction(llvm::FunctionType::get( 1836780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Type::getDoubleTy(VMContext), 1846780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, 1856780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George true), 1866780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George "objc_msgSend_fpret"); 1876780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1886780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 1896780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 1906780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperFn() const { 1916780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 1926780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const char *SuperName = "objc_msgSendSuper"; 1936780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 1946780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SuperPtrTy); 1956780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 1966780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 1976780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 1986780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George SuperName); 1996780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2006780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2016780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperFn2() const { 2026780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 2036780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const char *SuperName = "objc_msgSendSuper2"; 2046780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 2056780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SuperPtrTy); 2066780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 2076780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2086780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 2096780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George SuperName); 2106780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2116780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2126780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperStretFn() const { 2136780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super, 2146780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // SEL op, ...) 2156780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 2166780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(Int8PtrTy); 2176780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SuperPtrTy); 2186780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 2196780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return CGM.CreateRuntimeFunction( 2206780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 2216780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 2226780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George "objc_msgSendSuper_stret"); 2236780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2246780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2256780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperStretFn2() const { 2266780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 2276780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // SEL op, ...) 2286780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George std::vector<const llvm::Type*> Params; 2296780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(Int8PtrTy); 2306780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SuperPtrTy); 2316780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params.push_back(SelectorPtrTy); 2326780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return CGM.CreateRuntimeFunction( 2336780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 2346780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George Params, true), 2356780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George "objc_msgSendSuper2_stret"); 2366780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2376780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2386780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperFpretFn() const { 2396780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // There is no objc_msgSendSuper_fpret? How can that work? 2406780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return getMessageSendSuperFn(); 2416780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2426780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2436780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George llvm::Constant *getMessageSendSuperFpretFn2() const { 2446780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // There is no objc_msgSendSuper_fpret? How can that work? 2456780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George return getMessageSendSuperFn2(); 2466780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George } 2476780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2486780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgeprotected: 2496780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George CodeGen::CodeGenModule &CGM; 2506780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2516780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew Georgepublic: 2526780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 2536780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *Int8PtrTy; 2546780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2556780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 2566780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *ObjectPtrTy; 2576780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2586780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// PtrObjectPtrTy - LLVM type for id * 2596780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *PtrObjectPtrTy; 2606780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2616780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 2626780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *SelectorPtrTy; 2636780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// ProtocolPtrTy - LLVM type for external protocol handles 2646780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// (typeof(Protocol)) 2656780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *ExternalProtocolPtrTy; 2666780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2676780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // SuperCTy - clang type for struct objc_super. 2686780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George QualType SuperCTy; 2696780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // SuperPtrCTy - clang type for struct objc_super *. 2706780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George QualType SuperPtrCTy; 2716780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2726780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// SuperTy - LLVM type for struct objc_super. 2736780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::StructType *SuperTy; 2746780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// SuperPtrTy - LLVM type for struct objc_super *. 2756780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *SuperPtrTy; 2766780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2776780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 2786780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// in GCC parlance). 2796780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::StructType *PropertyTy; 2806780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2816780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// PropertyListTy - LLVM type for struct objc_property_list 2826780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// (_prop_list_t in GCC parlance). 2836780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::StructType *PropertyListTy; 2846780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 2856780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *PropertyListPtrTy; 2866780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2876780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George // MethodTy - LLVM type for struct objc_method. 2886780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::StructType *MethodTy; 2896780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 2906780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// CacheTy - LLVM type for struct objc_cache. 2916780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *CacheTy; 2926780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George /// CachePtrTy - LLVM type for struct objc_cache *. 2936780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George const llvm::Type *CachePtrTy; 2946780bd3d0ca0ddbf60778417fb09d3746a96b802Haynes Mathew George 295 llvm::Constant *getGetPropertyFn() { 296 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 297 ASTContext &Ctx = CGM.getContext(); 298 // id objc_getProperty (id, SEL, ptrdiff_t, bool) 299 llvm::SmallVector<QualType,16> Params; 300 QualType IdType = Ctx.getObjCIdType(); 301 QualType SelType = Ctx.getObjCSelType(); 302 Params.push_back(IdType); 303 Params.push_back(SelType); 304 Params.push_back(Ctx.LongTy); 305 Params.push_back(Ctx.BoolTy); 306 const llvm::FunctionType *FTy = 307 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params), false); 308 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 309 } 310 311 llvm::Constant *getSetPropertyFn() { 312 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 313 ASTContext &Ctx = CGM.getContext(); 314 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 315 llvm::SmallVector<QualType,16> Params; 316 QualType IdType = Ctx.getObjCIdType(); 317 QualType SelType = Ctx.getObjCSelType(); 318 Params.push_back(IdType); 319 Params.push_back(SelType); 320 Params.push_back(Ctx.LongTy); 321 Params.push_back(IdType); 322 Params.push_back(Ctx.BoolTy); 323 Params.push_back(Ctx.BoolTy); 324 const llvm::FunctionType *FTy = 325 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false); 326 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 327 } 328 329 llvm::Constant *getEnumerationMutationFn() { 330 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 331 ASTContext &Ctx = CGM.getContext(); 332 // void objc_enumerationMutation (id) 333 llvm::SmallVector<QualType,16> Params; 334 Params.push_back(Ctx.getObjCIdType()); 335 const llvm::FunctionType *FTy = 336 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false); 337 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 338 } 339 340 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 341 llvm::Constant *getGcReadWeakFn() { 342 // id objc_read_weak (id *) 343 std::vector<const llvm::Type*> Args; 344 Args.push_back(ObjectPtrTy->getPointerTo()); 345 llvm::FunctionType *FTy = 346 llvm::FunctionType::get(ObjectPtrTy, Args, false); 347 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 348 } 349 350 /// GcAssignWeakFn -- LLVM objc_assign_weak function. 351 llvm::Constant *getGcAssignWeakFn() { 352 // id objc_assign_weak (id, id *) 353 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 354 Args.push_back(ObjectPtrTy->getPointerTo()); 355 llvm::FunctionType *FTy = 356 llvm::FunctionType::get(ObjectPtrTy, Args, false); 357 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 358 } 359 360 /// GcAssignGlobalFn -- LLVM objc_assign_global function. 361 llvm::Constant *getGcAssignGlobalFn() { 362 // id objc_assign_global(id, id *) 363 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 364 Args.push_back(ObjectPtrTy->getPointerTo()); 365 llvm::FunctionType *FTy = 366 llvm::FunctionType::get(ObjectPtrTy, Args, false); 367 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 368 } 369 370 /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 371 llvm::Constant *getGcAssignIvarFn() { 372 // id objc_assign_ivar(id, id *, ptrdiff_t) 373 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 374 Args.push_back(ObjectPtrTy->getPointerTo()); 375 Args.push_back(LongTy); 376 llvm::FunctionType *FTy = 377 llvm::FunctionType::get(ObjectPtrTy, Args, false); 378 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 379 } 380 381 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function. 382 llvm::Constant *GcMemmoveCollectableFn() { 383 // void *objc_memmove_collectable(void *dst, const void *src, size_t size) 384 std::vector<const llvm::Type*> Args(1, Int8PtrTy); 385 Args.push_back(Int8PtrTy); 386 Args.push_back(LongTy); 387 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); 388 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 389 } 390 391 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 392 llvm::Constant *getGcAssignStrongCastFn() { 393 // id objc_assign_global(id, id *) 394 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 395 Args.push_back(ObjectPtrTy->getPointerTo()); 396 llvm::FunctionType *FTy = 397 llvm::FunctionType::get(ObjectPtrTy, Args, false); 398 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 399 } 400 401 /// ExceptionThrowFn - LLVM objc_exception_throw function. 402 llvm::Constant *getExceptionThrowFn() { 403 // void objc_exception_throw(id) 404 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 405 llvm::FunctionType *FTy = 406 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 407 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 408 } 409 410 /// SyncEnterFn - LLVM object_sync_enter function. 411 llvm::Constant *getSyncEnterFn() { 412 // void objc_sync_enter (id) 413 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 414 llvm::FunctionType *FTy = 415 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 416 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 417 } 418 419 /// SyncExitFn - LLVM object_sync_exit function. 420 llvm::Constant *getSyncExitFn() { 421 // void objc_sync_exit (id) 422 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 423 llvm::FunctionType *FTy = 424 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 425 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 426 } 427 428 llvm::Constant *getSendFn(bool IsSuper) const { 429 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 430 } 431 432 llvm::Constant *getSendFn2(bool IsSuper) const { 433 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 434 } 435 436 llvm::Constant *getSendStretFn(bool IsSuper) const { 437 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 438 } 439 440 llvm::Constant *getSendStretFn2(bool IsSuper) const { 441 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 442 } 443 444 llvm::Constant *getSendFpretFn(bool IsSuper) const { 445 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 446 } 447 448 llvm::Constant *getSendFpretFn2(bool IsSuper) const { 449 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 450 } 451 452 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 453 ~ObjCCommonTypesHelper(){} 454}; 455 456/// ObjCTypesHelper - Helper class that encapsulates lazy 457/// construction of varies types used during ObjC generation. 458class ObjCTypesHelper : public ObjCCommonTypesHelper { 459public: 460 /// SymtabTy - LLVM type for struct objc_symtab. 461 const llvm::StructType *SymtabTy; 462 /// SymtabPtrTy - LLVM type for struct objc_symtab *. 463 const llvm::Type *SymtabPtrTy; 464 /// ModuleTy - LLVM type for struct objc_module. 465 const llvm::StructType *ModuleTy; 466 467 /// ProtocolTy - LLVM type for struct objc_protocol. 468 const llvm::StructType *ProtocolTy; 469 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 470 const llvm::Type *ProtocolPtrTy; 471 /// ProtocolExtensionTy - LLVM type for struct 472 /// objc_protocol_extension. 473 const llvm::StructType *ProtocolExtensionTy; 474 /// ProtocolExtensionTy - LLVM type for struct 475 /// objc_protocol_extension *. 476 const llvm::Type *ProtocolExtensionPtrTy; 477 /// MethodDescriptionTy - LLVM type for struct 478 /// objc_method_description. 479 const llvm::StructType *MethodDescriptionTy; 480 /// MethodDescriptionListTy - LLVM type for struct 481 /// objc_method_description_list. 482 const llvm::StructType *MethodDescriptionListTy; 483 /// MethodDescriptionListPtrTy - LLVM type for struct 484 /// objc_method_description_list *. 485 const llvm::Type *MethodDescriptionListPtrTy; 486 /// ProtocolListTy - LLVM type for struct objc_property_list. 487 const llvm::Type *ProtocolListTy; 488 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 489 const llvm::Type *ProtocolListPtrTy; 490 /// CategoryTy - LLVM type for struct objc_category. 491 const llvm::StructType *CategoryTy; 492 /// ClassTy - LLVM type for struct objc_class. 493 const llvm::StructType *ClassTy; 494 /// ClassPtrTy - LLVM type for struct objc_class *. 495 const llvm::Type *ClassPtrTy; 496 /// ClassExtensionTy - LLVM type for struct objc_class_ext. 497 const llvm::StructType *ClassExtensionTy; 498 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 499 const llvm::Type *ClassExtensionPtrTy; 500 // IvarTy - LLVM type for struct objc_ivar. 501 const llvm::StructType *IvarTy; 502 /// IvarListTy - LLVM type for struct objc_ivar_list. 503 const llvm::Type *IvarListTy; 504 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 505 const llvm::Type *IvarListPtrTy; 506 /// MethodListTy - LLVM type for struct objc_method_list. 507 const llvm::Type *MethodListTy; 508 /// MethodListPtrTy - LLVM type for struct objc_method_list *. 509 const llvm::Type *MethodListPtrTy; 510 511 /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 512 const llvm::Type *ExceptionDataTy; 513 514 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 515 llvm::Constant *getExceptionTryEnterFn() { 516 std::vector<const llvm::Type*> Params; 517 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 518 return CGM.CreateRuntimeFunction( 519 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 520 Params, false), 521 "objc_exception_try_enter"); 522 } 523 524 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 525 llvm::Constant *getExceptionTryExitFn() { 526 std::vector<const llvm::Type*> Params; 527 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 528 return CGM.CreateRuntimeFunction( 529 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 530 Params, false), 531 "objc_exception_try_exit"); 532 } 533 534 /// ExceptionExtractFn - LLVM objc_exception_extract function. 535 llvm::Constant *getExceptionExtractFn() { 536 std::vector<const llvm::Type*> Params; 537 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 538 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 539 Params, false), 540 "objc_exception_extract"); 541 542 } 543 544 /// ExceptionMatchFn - LLVM objc_exception_match function. 545 llvm::Constant *getExceptionMatchFn() { 546 std::vector<const llvm::Type*> Params; 547 Params.push_back(ClassPtrTy); 548 Params.push_back(ObjectPtrTy); 549 return CGM.CreateRuntimeFunction( 550 llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 551 Params, false), 552 "objc_exception_match"); 553 554 } 555 556 /// SetJmpFn - LLVM _setjmp function. 557 llvm::Constant *getSetJmpFn() { 558 std::vector<const llvm::Type*> Params; 559 Params.push_back(llvm::Type::getInt32PtrTy(VMContext)); 560 return 561 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 562 Params, false), 563 "_setjmp"); 564 565 } 566 567public: 568 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 569 ~ObjCTypesHelper() {} 570}; 571 572/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 573/// modern abi 574class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 575public: 576 577 // MethodListnfABITy - LLVM for struct _method_list_t 578 const llvm::StructType *MethodListnfABITy; 579 580 // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 581 const llvm::Type *MethodListnfABIPtrTy; 582 583 // ProtocolnfABITy = LLVM for struct _protocol_t 584 const llvm::StructType *ProtocolnfABITy; 585 586 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 587 const llvm::Type *ProtocolnfABIPtrTy; 588 589 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 590 const llvm::StructType *ProtocolListnfABITy; 591 592 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 593 const llvm::Type *ProtocolListnfABIPtrTy; 594 595 // ClassnfABITy - LLVM for struct _class_t 596 const llvm::StructType *ClassnfABITy; 597 598 // ClassnfABIPtrTy - LLVM for struct _class_t* 599 const llvm::Type *ClassnfABIPtrTy; 600 601 // IvarnfABITy - LLVM for struct _ivar_t 602 const llvm::StructType *IvarnfABITy; 603 604 // IvarListnfABITy - LLVM for struct _ivar_list_t 605 const llvm::StructType *IvarListnfABITy; 606 607 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 608 const llvm::Type *IvarListnfABIPtrTy; 609 610 // ClassRonfABITy - LLVM for struct _class_ro_t 611 const llvm::StructType *ClassRonfABITy; 612 613 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 614 const llvm::Type *ImpnfABITy; 615 616 // CategorynfABITy - LLVM for struct _category_t 617 const llvm::StructType *CategorynfABITy; 618 619 // New types for nonfragile abi messaging. 620 621 // MessageRefTy - LLVM for: 622 // struct _message_ref_t { 623 // IMP messenger; 624 // SEL name; 625 // }; 626 const llvm::StructType *MessageRefTy; 627 // MessageRefCTy - clang type for struct _message_ref_t 628 QualType MessageRefCTy; 629 630 // MessageRefPtrTy - LLVM for struct _message_ref_t* 631 const llvm::Type *MessageRefPtrTy; 632 // MessageRefCPtrTy - clang type for struct _message_ref_t* 633 QualType MessageRefCPtrTy; 634 635 // MessengerTy - Type of the messenger (shown as IMP above) 636 const llvm::FunctionType *MessengerTy; 637 638 // SuperMessageRefTy - LLVM for: 639 // struct _super_message_ref_t { 640 // SUPER_IMP messenger; 641 // SEL name; 642 // }; 643 const llvm::StructType *SuperMessageRefTy; 644 645 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 646 const llvm::Type *SuperMessageRefPtrTy; 647 648 llvm::Constant *getMessageSendFixupFn() { 649 // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 650 std::vector<const llvm::Type*> Params; 651 Params.push_back(ObjectPtrTy); 652 Params.push_back(MessageRefPtrTy); 653 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 654 Params, true), 655 "objc_msgSend_fixup"); 656 } 657 658 llvm::Constant *getMessageSendFpretFixupFn() { 659 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 660 std::vector<const llvm::Type*> Params; 661 Params.push_back(ObjectPtrTy); 662 Params.push_back(MessageRefPtrTy); 663 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 664 Params, true), 665 "objc_msgSend_fpret_fixup"); 666 } 667 668 llvm::Constant *getMessageSendStretFixupFn() { 669 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 670 std::vector<const llvm::Type*> Params; 671 Params.push_back(ObjectPtrTy); 672 Params.push_back(MessageRefPtrTy); 673 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 674 Params, true), 675 "objc_msgSend_stret_fixup"); 676 } 677 678 llvm::Constant *getMessageSendIdFixupFn() { 679 // id objc_msgSendId_fixup(id, struct message_ref_t*, ...) 680 std::vector<const llvm::Type*> Params; 681 Params.push_back(ObjectPtrTy); 682 Params.push_back(MessageRefPtrTy); 683 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 684 Params, true), 685 "objc_msgSendId_fixup"); 686 } 687 688 llvm::Constant *getMessageSendIdStretFixupFn() { 689 // id objc_msgSendId_stret_fixup(id, struct message_ref_t*, ...) 690 std::vector<const llvm::Type*> Params; 691 Params.push_back(ObjectPtrTy); 692 Params.push_back(MessageRefPtrTy); 693 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 694 Params, true), 695 "objc_msgSendId_stret_fixup"); 696 } 697 llvm::Constant *getMessageSendSuper2FixupFn() { 698 // id objc_msgSendSuper2_fixup (struct objc_super *, 699 // struct _super_message_ref_t*, ...) 700 std::vector<const llvm::Type*> Params; 701 Params.push_back(SuperPtrTy); 702 Params.push_back(SuperMessageRefPtrTy); 703 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 704 Params, true), 705 "objc_msgSendSuper2_fixup"); 706 } 707 708 llvm::Constant *getMessageSendSuper2StretFixupFn() { 709 // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 710 // struct _super_message_ref_t*, ...) 711 std::vector<const llvm::Type*> Params; 712 Params.push_back(SuperPtrTy); 713 Params.push_back(SuperMessageRefPtrTy); 714 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 715 Params, true), 716 "objc_msgSendSuper2_stret_fixup"); 717 } 718 719 720 721 /// EHPersonalityPtr - LLVM value for an i8* to the Objective-C 722 /// exception personality function. 723 llvm::Value *getEHPersonalityPtr() { 724 llvm::Constant *Personality = 725 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 726 true), 727 "__objc_personality_v0"); 728 return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy); 729 } 730 731 llvm::Constant *getUnwindResumeOrRethrowFn() { 732 std::vector<const llvm::Type*> Params; 733 Params.push_back(Int8PtrTy); 734 return CGM.CreateRuntimeFunction( 735 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 736 Params, false), 737 "_Unwind_Resume_or_Rethrow"); 738 } 739 740 llvm::Constant *getObjCEndCatchFn() { 741 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 742 false), 743 "objc_end_catch"); 744 745 } 746 747 llvm::Constant *getObjCBeginCatchFn() { 748 std::vector<const llvm::Type*> Params; 749 Params.push_back(Int8PtrTy); 750 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 751 Params, false), 752 "objc_begin_catch"); 753 } 754 755 const llvm::StructType *EHTypeTy; 756 const llvm::Type *EHTypePtrTy; 757 758 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 759 ~ObjCNonFragileABITypesHelper(){} 760}; 761 762class CGObjCCommonMac : public CodeGen::CGObjCRuntime { 763public: 764 // FIXME - accessibility 765 class GC_IVAR { 766 public: 767 unsigned ivar_bytepos; 768 unsigned ivar_size; 769 GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 770 : ivar_bytepos(bytepos), ivar_size(size) {} 771 772 // Allow sorting based on byte pos. 773 bool operator<(const GC_IVAR &b) const { 774 return ivar_bytepos < b.ivar_bytepos; 775 } 776 }; 777 778 class SKIP_SCAN { 779 public: 780 unsigned skip; 781 unsigned scan; 782 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 783 : skip(_skip), scan(_scan) {} 784 }; 785 786protected: 787 CodeGen::CodeGenModule &CGM; 788 llvm::LLVMContext &VMContext; 789 // FIXME! May not be needing this after all. 790 unsigned ObjCABI; 791 792 // gc ivar layout bitmap calculation helper caches. 793 llvm::SmallVector<GC_IVAR, 16> SkipIvars; 794 llvm::SmallVector<GC_IVAR, 16> IvarsInfo; 795 796 /// LazySymbols - Symbols to generate a lazy reference for. See 797 /// DefinedSymbols and FinishModule(). 798 llvm::SetVector<IdentifierInfo*> LazySymbols; 799 800 /// DefinedSymbols - External symbols which are defined by this 801 /// module. The symbols in this list and LazySymbols are used to add 802 /// special linker symbols which ensure that Objective-C modules are 803 /// linked properly. 804 llvm::SetVector<IdentifierInfo*> DefinedSymbols; 805 806 /// ClassNames - uniqued class names. 807 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 808 809 /// MethodVarNames - uniqued method variable names. 810 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 811 812 /// MethodVarTypes - uniqued method type signatures. We have to use 813 /// a StringMap here because have no other unique reference. 814 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 815 816 /// MethodDefinitions - map of methods which have been defined in 817 /// this translation unit. 818 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 819 820 /// PropertyNames - uniqued method variable names. 821 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 822 823 /// ClassReferences - uniqued class references. 824 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 825 826 /// SelectorReferences - uniqued selector references. 827 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 828 829 /// Protocols - Protocols for which an objc_protocol structure has 830 /// been emitted. Forward declarations are handled by creating an 831 /// empty structure whose initializer is filled in when/if defined. 832 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 833 834 /// DefinedProtocols - Protocols which have actually been 835 /// defined. We should not need this, see FIXME in GenerateProtocol. 836 llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 837 838 /// DefinedClasses - List of defined classes. 839 std::vector<llvm::GlobalValue*> DefinedClasses; 840 841 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 842 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses; 843 844 /// DefinedCategories - List of defined categories. 845 std::vector<llvm::GlobalValue*> DefinedCategories; 846 847 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 848 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories; 849 850 /// GetNameForMethod - Return a name for the given method. 851 /// \param[out] NameOut - The return value. 852 void GetNameForMethod(const ObjCMethodDecl *OMD, 853 const ObjCContainerDecl *CD, 854 llvm::SmallVectorImpl<char> &NameOut); 855 856 /// GetMethodVarName - Return a unique constant for the given 857 /// selector's name. The return value has type char *. 858 llvm::Constant *GetMethodVarName(Selector Sel); 859 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 860 llvm::Constant *GetMethodVarName(const std::string &Name); 861 862 /// GetMethodVarType - Return a unique constant for the given 863 /// selector's name. The return value has type char *. 864 865 // FIXME: This is a horrible name. 866 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 867 llvm::Constant *GetMethodVarType(const FieldDecl *D); 868 869 /// GetPropertyName - Return a unique constant for the given 870 /// name. The return value has type char *. 871 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 872 873 // FIXME: This can be dropped once string functions are unified. 874 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 875 const Decl *Container); 876 877 /// GetClassName - Return a unique constant for the given selector's 878 /// name. The return value has type char *. 879 llvm::Constant *GetClassName(IdentifierInfo *Ident); 880 881 /// BuildIvarLayout - Builds ivar layout bitmap for the class 882 /// implementation for the __strong or __weak case. 883 /// 884 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 885 bool ForStrongLayout); 886 887 void BuildAggrIvarRecordLayout(const RecordType *RT, 888 unsigned int BytePos, bool ForStrongLayout, 889 bool &HasUnion); 890 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 891 const llvm::StructLayout *Layout, 892 const RecordDecl *RD, 893 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 894 unsigned int BytePos, bool ForStrongLayout, 895 bool &HasUnion); 896 897 /// GetIvarLayoutName - Returns a unique constant for the given 898 /// ivar layout bitmap. 899 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 900 const ObjCCommonTypesHelper &ObjCTypes); 901 902 /// EmitPropertyList - Emit the given property list. The return 903 /// value has type PropertyListPtrTy. 904 llvm::Constant *EmitPropertyList(llvm::Twine Name, 905 const Decl *Container, 906 const ObjCContainerDecl *OCD, 907 const ObjCCommonTypesHelper &ObjCTypes); 908 909 /// PushProtocolProperties - Push protocol's property on the input stack. 910 void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 911 std::vector<llvm::Constant*> &Properties, 912 const Decl *Container, 913 const ObjCProtocolDecl *PROTO, 914 const ObjCCommonTypesHelper &ObjCTypes); 915 916 /// GetProtocolRef - Return a reference to the internal protocol 917 /// description, creating an empty one if it has not been 918 /// defined. The return value has type ProtocolPtrTy. 919 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 920 921 /// CreateMetadataVar - Create a global variable with internal 922 /// linkage for use by the Objective-C runtime. 923 /// 924 /// This is a convenience wrapper which not only creates the 925 /// variable, but also sets the section and alignment and adds the 926 /// global to the "llvm.used" list. 927 /// 928 /// \param Name - The variable name. 929 /// \param Init - The variable initializer; this is also used to 930 /// define the type of the variable. 931 /// \param Section - The section the variable should go into, or 0. 932 /// \param Align - The alignment for the variable, or 0. 933 /// \param AddToUsed - Whether the variable should be added to 934 /// "llvm.used". 935 llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name, 936 llvm::Constant *Init, 937 const char *Section, 938 unsigned Align, 939 bool AddToUsed); 940 941 CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, 942 QualType ResultType, 943 llvm::Value *Sel, 944 llvm::Value *Arg0, 945 QualType Arg0Ty, 946 bool IsSuper, 947 const CallArgList &CallArgs, 948 const ObjCMethodDecl *OMD, 949 const ObjCCommonTypesHelper &ObjCTypes); 950 951public: 952 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : 953 CGM(cgm), VMContext(cgm.getLLVMContext()) { } 954 955 virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *SL); 956 957 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 958 const ObjCContainerDecl *CD=0); 959 960 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 961 962 /// GetOrEmitProtocol - Get the protocol object for the given 963 /// declaration, emitting it if necessary. The return value has type 964 /// ProtocolPtrTy. 965 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 966 967 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 968 /// object for the given declaration, emitting it if needed. These 969 /// forward references will be filled in with empty bodies if no 970 /// definition is seen. The return value has type ProtocolPtrTy. 971 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 972}; 973 974class CGObjCMac : public CGObjCCommonMac { 975private: 976 ObjCTypesHelper ObjCTypes; 977 /// EmitImageInfo - Emit the image info marker used to encode some module 978 /// level information. 979 void EmitImageInfo(); 980 981 /// EmitModuleInfo - Another marker encoding module level 982 /// information. 983 void EmitModuleInfo(); 984 985 /// EmitModuleSymols - Emit module symbols, the list of defined 986 /// classes and categories. The result has type SymtabPtrTy. 987 llvm::Constant *EmitModuleSymbols(); 988 989 /// FinishModule - Write out global data structures at the end of 990 /// processing a translation unit. 991 void FinishModule(); 992 993 /// EmitClassExtension - Generate the class extension structure used 994 /// to store the weak ivar layout and properties. The return value 995 /// has type ClassExtensionPtrTy. 996 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 997 998 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 999 /// for the given class. 1000 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 1001 const ObjCInterfaceDecl *ID); 1002 1003 /// EmitSuperClassRef - Emits reference to class's main metadata class. 1004 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID); 1005 1006 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1007 QualType ResultType, 1008 Selector Sel, 1009 llvm::Value *Arg0, 1010 QualType Arg0Ty, 1011 bool IsSuper, 1012 const CallArgList &CallArgs); 1013 1014 /// EmitIvarList - Emit the ivar list for the given 1015 /// implementation. If ForClass is true the list of class ivars 1016 /// (i.e. metaclass ivars) is emitted, otherwise the list of 1017 /// interface ivars will be emitted. The return value has type 1018 /// IvarListPtrTy. 1019 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 1020 bool ForClass); 1021 1022 /// EmitMetaClass - Emit a forward reference to the class structure 1023 /// for the metaclass of the given interface. The return value has 1024 /// type ClassPtrTy. 1025 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 1026 1027 /// EmitMetaClass - Emit a class structure for the metaclass of the 1028 /// given implementation. The return value has type ClassPtrTy. 1029 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 1030 llvm::Constant *Protocols, 1031 const ConstantVector &Methods); 1032 1033 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 1034 1035 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 1036 1037 /// EmitMethodList - Emit the method list for the given 1038 /// implementation. The return value has type MethodListPtrTy. 1039 llvm::Constant *EmitMethodList(llvm::Twine Name, 1040 const char *Section, 1041 const ConstantVector &Methods); 1042 1043 /// EmitMethodDescList - Emit a method description list for a list of 1044 /// method declarations. 1045 /// - TypeName: The name for the type containing the methods. 1046 /// - IsProtocol: True iff these methods are for a protocol. 1047 /// - ClassMethds: True iff these are class methods. 1048 /// - Required: When true, only "required" methods are 1049 /// listed. Similarly, when false only "optional" methods are 1050 /// listed. For classes this should always be true. 1051 /// - begin, end: The method list to output. 1052 /// 1053 /// The return value has type MethodDescriptionListPtrTy. 1054 llvm::Constant *EmitMethodDescList(llvm::Twine Name, 1055 const char *Section, 1056 const ConstantVector &Methods); 1057 1058 /// GetOrEmitProtocol - Get the protocol object for the given 1059 /// declaration, emitting it if necessary. The return value has type 1060 /// ProtocolPtrTy. 1061 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1062 1063 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1064 /// object for the given declaration, emitting it if needed. These 1065 /// forward references will be filled in with empty bodies if no 1066 /// definition is seen. The return value has type ProtocolPtrTy. 1067 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1068 1069 /// EmitProtocolExtension - Generate the protocol extension 1070 /// structure used to store optional instance and class methods, and 1071 /// protocol properties. The return value has type 1072 /// ProtocolExtensionPtrTy. 1073 llvm::Constant * 1074 EmitProtocolExtension(const ObjCProtocolDecl *PD, 1075 const ConstantVector &OptInstanceMethods, 1076 const ConstantVector &OptClassMethods); 1077 1078 /// EmitProtocolList - Generate the list of referenced 1079 /// protocols. The return value has type ProtocolListPtrTy. 1080 llvm::Constant *EmitProtocolList(llvm::Twine Name, 1081 ObjCProtocolDecl::protocol_iterator begin, 1082 ObjCProtocolDecl::protocol_iterator end); 1083 1084 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1085 /// for the given selector. 1086 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); 1087 1088public: 1089 CGObjCMac(CodeGen::CodeGenModule &cgm); 1090 1091 virtual llvm::Function *ModuleInitFunction(); 1092 1093 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1094 QualType ResultType, 1095 Selector Sel, 1096 llvm::Value *Receiver, 1097 bool IsClassMessage, 1098 const CallArgList &CallArgs, 1099 const ObjCMethodDecl *Method); 1100 1101 virtual CodeGen::RValue 1102 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1103 QualType ResultType, 1104 Selector Sel, 1105 const ObjCInterfaceDecl *Class, 1106 bool isCategoryImpl, 1107 llvm::Value *Receiver, 1108 bool IsClassMessage, 1109 const CallArgList &CallArgs, 1110 const ObjCMethodDecl *Method); 1111 1112 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1113 const ObjCInterfaceDecl *ID); 1114 1115 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 1116 1117 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1118 /// untyped one. 1119 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1120 const ObjCMethodDecl *Method); 1121 1122 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1123 1124 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1125 1126 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1127 const ObjCProtocolDecl *PD); 1128 1129 virtual llvm::Constant *GetPropertyGetFunction(); 1130 virtual llvm::Constant *GetPropertySetFunction(); 1131 virtual llvm::Constant *EnumerationMutationFunction(); 1132 1133 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1134 const Stmt &S); 1135 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1136 const ObjCAtThrowStmt &S); 1137 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1138 llvm::Value *AddrWeakObj); 1139 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1140 llvm::Value *src, llvm::Value *dst); 1141 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1142 llvm::Value *src, llvm::Value *dest); 1143 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1144 llvm::Value *src, llvm::Value *dest, 1145 llvm::Value *ivarOffset); 1146 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1147 llvm::Value *src, llvm::Value *dest); 1148 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1149 llvm::Value *dest, llvm::Value *src, 1150 QualType Ty); 1151 1152 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1153 QualType ObjectTy, 1154 llvm::Value *BaseValue, 1155 const ObjCIvarDecl *Ivar, 1156 unsigned CVRQualifiers); 1157 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1158 const ObjCInterfaceDecl *Interface, 1159 const ObjCIvarDecl *Ivar); 1160}; 1161 1162class CGObjCNonFragileABIMac : public CGObjCCommonMac { 1163private: 1164 ObjCNonFragileABITypesHelper ObjCTypes; 1165 llvm::GlobalVariable* ObjCEmptyCacheVar; 1166 llvm::GlobalVariable* ObjCEmptyVtableVar; 1167 1168 /// SuperClassReferences - uniqued super class references. 1169 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 1170 1171 /// MetaClassReferences - uniqued meta class references. 1172 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 1173 1174 /// EHTypeReferences - uniqued class ehtype references. 1175 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 1176 1177 /// NonLegacyDispatchMethods - List of methods for which we do *not* generate 1178 /// legacy messaging dispatch. 1179 llvm::DenseSet<Selector> NonLegacyDispatchMethods; 1180 1181 /// DefinedMetaClasses - List of defined meta-classes. 1182 std::vector<llvm::GlobalValue*> DefinedMetaClasses; 1183 1184 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of 1185 /// NonLegacyDispatchMethods; false otherwise. 1186 bool LegacyDispatchedSelector(Selector Sel); 1187 1188 /// FinishNonFragileABIModule - Write out global data structures at the end of 1189 /// processing a translation unit. 1190 void FinishNonFragileABIModule(); 1191 1192 /// AddModuleClassList - Add the given list of class pointers to the 1193 /// module with the provided symbol and section names. 1194 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container, 1195 const char *SymbolName, 1196 const char *SectionName); 1197 1198 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 1199 unsigned InstanceStart, 1200 unsigned InstanceSize, 1201 const ObjCImplementationDecl *ID); 1202 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 1203 llvm::Constant *IsAGV, 1204 llvm::Constant *SuperClassGV, 1205 llvm::Constant *ClassRoGV, 1206 bool HiddenVisibility); 1207 1208 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 1209 1210 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 1211 1212 /// EmitMethodList - Emit the method list for the given 1213 /// implementation. The return value has type MethodListnfABITy. 1214 llvm::Constant *EmitMethodList(llvm::Twine Name, 1215 const char *Section, 1216 const ConstantVector &Methods); 1217 /// EmitIvarList - Emit the ivar list for the given 1218 /// implementation. If ForClass is true the list of class ivars 1219 /// (i.e. metaclass ivars) is emitted, otherwise the list of 1220 /// interface ivars will be emitted. The return value has type 1221 /// IvarListnfABIPtrTy. 1222 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 1223 1224 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 1225 const ObjCIvarDecl *Ivar, 1226 unsigned long int offset); 1227 1228 /// GetOrEmitProtocol - Get the protocol object for the given 1229 /// declaration, emitting it if necessary. The return value has type 1230 /// ProtocolPtrTy. 1231 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1232 1233 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1234 /// object for the given declaration, emitting it if needed. These 1235 /// forward references will be filled in with empty bodies if no 1236 /// definition is seen. The return value has type ProtocolPtrTy. 1237 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1238 1239 /// EmitProtocolList - Generate the list of referenced 1240 /// protocols. The return value has type ProtocolListPtrTy. 1241 llvm::Constant *EmitProtocolList(llvm::Twine Name, 1242 ObjCProtocolDecl::protocol_iterator begin, 1243 ObjCProtocolDecl::protocol_iterator end); 1244 1245 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1246 QualType ResultType, 1247 Selector Sel, 1248 llvm::Value *Receiver, 1249 QualType Arg0Ty, 1250 bool IsSuper, 1251 const CallArgList &CallArgs); 1252 1253 /// GetClassGlobal - Return the global variable for the Objective-C 1254 /// class of the given name. 1255 llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 1256 1257 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1258 /// for the given class reference. 1259 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 1260 const ObjCInterfaceDecl *ID); 1261 1262 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1263 /// for the given super class reference. 1264 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 1265 const ObjCInterfaceDecl *ID); 1266 1267 /// EmitMetaClassRef - Return a Value * of the address of _class_t 1268 /// meta-data 1269 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 1270 const ObjCInterfaceDecl *ID); 1271 1272 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 1273 /// the given ivar. 1274 /// 1275 llvm::GlobalVariable * ObjCIvarOffsetVariable( 1276 const ObjCInterfaceDecl *ID, 1277 const ObjCIvarDecl *Ivar); 1278 1279 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1280 /// for the given selector. 1281 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); 1282 1283 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 1284 /// interface. The return value has type EHTypePtrTy. 1285 llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 1286 bool ForDefinition); 1287 1288 const char *getMetaclassSymbolPrefix() const { 1289 return "OBJC_METACLASS_$_"; 1290 } 1291 1292 const char *getClassSymbolPrefix() const { 1293 return "OBJC_CLASS_$_"; 1294 } 1295 1296 void GetClassSizeInfo(const ObjCImplementationDecl *OID, 1297 uint32_t &InstanceStart, 1298 uint32_t &InstanceSize); 1299 1300 // Shamelessly stolen from Analysis/CFRefCount.cpp 1301 Selector GetNullarySelector(const char* name) const { 1302 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1303 return CGM.getContext().Selectors.getSelector(0, &II); 1304 } 1305 1306 Selector GetUnarySelector(const char* name) const { 1307 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1308 return CGM.getContext().Selectors.getSelector(1, &II); 1309 } 1310 1311 /// ImplementationIsNonLazy - Check whether the given category or 1312 /// class implementation is "non-lazy". 1313 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 1314 1315public: 1316 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 1317 // FIXME. All stubs for now! 1318 virtual llvm::Function *ModuleInitFunction(); 1319 1320 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1321 QualType ResultType, 1322 Selector Sel, 1323 llvm::Value *Receiver, 1324 bool IsClassMessage, 1325 const CallArgList &CallArgs, 1326 const ObjCMethodDecl *Method); 1327 1328 virtual CodeGen::RValue 1329 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1330 QualType ResultType, 1331 Selector Sel, 1332 const ObjCInterfaceDecl *Class, 1333 bool isCategoryImpl, 1334 llvm::Value *Receiver, 1335 bool IsClassMessage, 1336 const CallArgList &CallArgs, 1337 const ObjCMethodDecl *Method); 1338 1339 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1340 const ObjCInterfaceDecl *ID); 1341 1342 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) 1343 { return EmitSelector(Builder, Sel); } 1344 1345 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1346 /// untyped one. 1347 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1348 const ObjCMethodDecl *Method) 1349 { return EmitSelector(Builder, Method->getSelector()); } 1350 1351 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1352 1353 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1354 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1355 const ObjCProtocolDecl *PD); 1356 1357 virtual llvm::Constant *GetPropertyGetFunction() { 1358 return ObjCTypes.getGetPropertyFn(); 1359 } 1360 virtual llvm::Constant *GetPropertySetFunction() { 1361 return ObjCTypes.getSetPropertyFn(); 1362 } 1363 virtual llvm::Constant *EnumerationMutationFunction() { 1364 return ObjCTypes.getEnumerationMutationFn(); 1365 } 1366 1367 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1368 const Stmt &S); 1369 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1370 const ObjCAtThrowStmt &S); 1371 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1372 llvm::Value *AddrWeakObj); 1373 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1374 llvm::Value *src, llvm::Value *dst); 1375 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1376 llvm::Value *src, llvm::Value *dest); 1377 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1378 llvm::Value *src, llvm::Value *dest, 1379 llvm::Value *ivarOffset); 1380 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1381 llvm::Value *src, llvm::Value *dest); 1382 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1383 llvm::Value *dest, llvm::Value *src, 1384 QualType Ty); 1385 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1386 QualType ObjectTy, 1387 llvm::Value *BaseValue, 1388 const ObjCIvarDecl *Ivar, 1389 unsigned CVRQualifiers); 1390 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1391 const ObjCInterfaceDecl *Interface, 1392 const ObjCIvarDecl *Ivar); 1393}; 1394 1395} // end anonymous namespace 1396 1397/* *** Helper Functions *** */ 1398 1399/// getConstantGEP() - Help routine to construct simple GEPs. 1400static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext, 1401 llvm::Constant *C, 1402 unsigned idx0, 1403 unsigned idx1) { 1404 llvm::Value *Idxs[] = { 1405 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0), 1406 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1) 1407 }; 1408 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 1409} 1410 1411/// hasObjCExceptionAttribute - Return true if this class or any super 1412/// class has the __objc_exception__ attribute. 1413static bool hasObjCExceptionAttribute(ASTContext &Context, 1414 const ObjCInterfaceDecl *OID) { 1415 if (OID->hasAttr<ObjCExceptionAttr>()) 1416 return true; 1417 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1418 return hasObjCExceptionAttribute(Context, Super); 1419 return false; 1420} 1421 1422/* *** CGObjCMac Public Interface *** */ 1423 1424CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 1425 ObjCTypes(cgm) { 1426 ObjCABI = 1; 1427 EmitImageInfo(); 1428} 1429 1430/// GetClass - Return a reference to the class for the given interface 1431/// decl. 1432llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 1433 const ObjCInterfaceDecl *ID) { 1434 return EmitClassRef(Builder, ID); 1435} 1436 1437/// GetSelector - Return the pointer to the unique'd string for this selector. 1438llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) { 1439 return EmitSelector(Builder, Sel); 1440} 1441llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 1442 *Method) { 1443 return EmitSelector(Builder, Method->getSelector()); 1444} 1445 1446/// Generate a constant CFString object. 1447/* 1448 struct __builtin_CFString { 1449 const int *isa; // point to __CFConstantStringClassReference 1450 int flags; 1451 const char *str; 1452 long length; 1453 }; 1454*/ 1455 1456llvm::Constant *CGObjCCommonMac::GenerateConstantString( 1457 const ObjCStringLiteral *SL) { 1458 return CGM.GetAddrOfConstantCFString(SL->getString()); 1459} 1460 1461/// Generates a message send where the super is the receiver. This is 1462/// a message send to self with special delivery semantics indicating 1463/// which class's method should be called. 1464CodeGen::RValue 1465CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1466 QualType ResultType, 1467 Selector Sel, 1468 const ObjCInterfaceDecl *Class, 1469 bool isCategoryImpl, 1470 llvm::Value *Receiver, 1471 bool IsClassMessage, 1472 const CodeGen::CallArgList &CallArgs, 1473 const ObjCMethodDecl *Method) { 1474 // Create and init a super structure; this is a (receiver, class) 1475 // pair we will pass to objc_msgSendSuper. 1476 llvm::Value *ObjCSuper = 1477 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 1478 llvm::Value *ReceiverAsObject = 1479 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 1480 CGF.Builder.CreateStore(ReceiverAsObject, 1481 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 1482 1483 // If this is a class message the metaclass is passed as the target. 1484 llvm::Value *Target; 1485 if (IsClassMessage) { 1486 if (isCategoryImpl) { 1487 // Message sent to 'super' in a class method defined in a category 1488 // implementation requires an odd treatment. 1489 // If we are in a class method, we must retrieve the 1490 // _metaclass_ for the current class, pointed at by 1491 // the class's "isa" pointer. The following assumes that 1492 // isa" is the first ivar in a class (which it must be). 1493 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1494 Target = CGF.Builder.CreateStructGEP(Target, 0); 1495 Target = CGF.Builder.CreateLoad(Target); 1496 } else { 1497 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 1498 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 1499 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 1500 Target = Super; 1501 } 1502 } 1503 else if (isCategoryImpl) 1504 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1505 else { 1506 llvm::Value *ClassPtr = EmitSuperClassRef(Class); 1507 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1); 1508 Target = CGF.Builder.CreateLoad(ClassPtr); 1509 } 1510 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 1511 // ObjCTypes types. 1512 const llvm::Type *ClassTy = 1513 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 1514 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 1515 CGF.Builder.CreateStore(Target, 1516 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 1517 return EmitLegacyMessageSend(CGF, ResultType, 1518 EmitSelector(CGF.Builder, Sel), 1519 ObjCSuper, ObjCTypes.SuperPtrCTy, 1520 true, CallArgs, Method, ObjCTypes); 1521} 1522 1523/// Generate code for a message send expression. 1524CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1525 QualType ResultType, 1526 Selector Sel, 1527 llvm::Value *Receiver, 1528 bool IsClassMessage, 1529 const CallArgList &CallArgs, 1530 const ObjCMethodDecl *Method) { 1531 return EmitLegacyMessageSend(CGF, ResultType, 1532 EmitSelector(CGF.Builder, Sel), 1533 Receiver, CGF.getContext().getObjCIdType(), 1534 false, CallArgs, Method, ObjCTypes); 1535} 1536 1537CodeGen::RValue 1538CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, 1539 QualType ResultType, 1540 llvm::Value *Sel, 1541 llvm::Value *Arg0, 1542 QualType Arg0Ty, 1543 bool IsSuper, 1544 const CallArgList &CallArgs, 1545 const ObjCMethodDecl *Method, 1546 const ObjCCommonTypesHelper &ObjCTypes) { 1547 CallArgList ActualArgs; 1548 if (!IsSuper) 1549 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp"); 1550 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 1551 ActualArgs.push_back(std::make_pair(RValue::get(Sel), 1552 CGF.getContext().getObjCSelType())); 1553 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 1554 1555 CodeGenTypes &Types = CGM.getTypes(); 1556 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 1557 const llvm::FunctionType *FTy = 1558 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 1559 1560 llvm::Constant *Fn = NULL; 1561 if (CGM.ReturnTypeUsesSret(FnInfo)) { 1562 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 1563 : ObjCTypes.getSendStretFn(IsSuper); 1564 } else if (ResultType->isFloatingType()) { 1565 if (ObjCABI == 2) { 1566 if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) { 1567 BuiltinType::Kind k = BT->getKind(); 1568 Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper) 1569 : ObjCTypes.getSendFn2(IsSuper); 1570 } else { 1571 Fn = ObjCTypes.getSendFn2(IsSuper); 1572 } 1573 } else 1574 // FIXME. This currently matches gcc's API for x86-32. May need to change 1575 // for others if we have their API. 1576 Fn = ObjCTypes.getSendFpretFn(IsSuper); 1577 } else { 1578 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 1579 : ObjCTypes.getSendFn(IsSuper); 1580 } 1581 assert(Fn && "EmitLegacyMessageSend - unknown API"); 1582 Fn = llvm::ConstantExpr::getBitCast(Fn, 1583 llvm::PointerType::getUnqual(FTy)); 1584 return CGF.EmitCall(FnInfo, Fn, ReturnValueSlot(), ActualArgs); 1585} 1586 1587llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 1588 const ObjCProtocolDecl *PD) { 1589 // FIXME: I don't understand why gcc generates this, or where it is 1590 // resolved. Investigate. Its also wasteful to look this up over and over. 1591 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1592 1593 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 1594 ObjCTypes.ExternalProtocolPtrTy); 1595} 1596 1597void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 1598 // FIXME: We shouldn't need this, the protocol decl should contain enough 1599 // information to tell us whether this was a declaration or a definition. 1600 DefinedProtocols.insert(PD->getIdentifier()); 1601 1602 // If we have generated a forward reference to this protocol, emit 1603 // it now. Otherwise do nothing, the protocol objects are lazily 1604 // emitted. 1605 if (Protocols.count(PD->getIdentifier())) 1606 GetOrEmitProtocol(PD); 1607} 1608 1609llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 1610 if (DefinedProtocols.count(PD->getIdentifier())) 1611 return GetOrEmitProtocol(PD); 1612 return GetOrEmitProtocolRef(PD); 1613} 1614 1615/* 1616// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 1617struct _objc_protocol { 1618struct _objc_protocol_extension *isa; 1619char *protocol_name; 1620struct _objc_protocol_list *protocol_list; 1621struct _objc__method_prototype_list *instance_methods; 1622struct _objc__method_prototype_list *class_methods 1623}; 1624 1625See EmitProtocolExtension(). 1626*/ 1627llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 1628 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1629 1630 // Early exit if a defining object has already been generated. 1631 if (Entry && Entry->hasInitializer()) 1632 return Entry; 1633 1634 // FIXME: I don't understand why gcc generates this, or where it is 1635 // resolved. Investigate. Its also wasteful to look this up over and over. 1636 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1637 1638 // Construct method lists. 1639 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1640 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 1641 for (ObjCProtocolDecl::instmeth_iterator 1642 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 1643 ObjCMethodDecl *MD = *i; 1644 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1645 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1646 OptInstanceMethods.push_back(C); 1647 } else { 1648 InstanceMethods.push_back(C); 1649 } 1650 } 1651 1652 for (ObjCProtocolDecl::classmeth_iterator 1653 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 1654 ObjCMethodDecl *MD = *i; 1655 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1656 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1657 OptClassMethods.push_back(C); 1658 } else { 1659 ClassMethods.push_back(C); 1660 } 1661 } 1662 1663 std::vector<llvm::Constant*> Values(5); 1664 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods); 1665 Values[1] = GetClassName(PD->getIdentifier()); 1666 Values[2] = 1667 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(), 1668 PD->protocol_begin(), 1669 PD->protocol_end()); 1670 Values[3] = 1671 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(), 1672 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1673 InstanceMethods); 1674 Values[4] = 1675 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(), 1676 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1677 ClassMethods); 1678 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 1679 Values); 1680 1681 if (Entry) { 1682 // Already created, fix the linkage and update the initializer. 1683 Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 1684 Entry->setInitializer(Init); 1685 } else { 1686 Entry = 1687 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 1688 llvm::GlobalValue::InternalLinkage, 1689 Init, 1690 "\01L_OBJC_PROTOCOL_" + PD->getName()); 1691 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1692 Entry->setAlignment(4); 1693 // FIXME: Is this necessary? Why only for protocol? 1694 Entry->setAlignment(4); 1695 } 1696 CGM.AddUsedGlobal(Entry); 1697 1698 return Entry; 1699} 1700 1701llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 1702 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1703 1704 if (!Entry) { 1705 // We use the initializer as a marker of whether this is a forward 1706 // reference or not. At module finalization we add the empty 1707 // contents for protocols which were referenced but never defined. 1708 Entry = 1709 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 1710 llvm::GlobalValue::ExternalLinkage, 1711 0, 1712 "\01L_OBJC_PROTOCOL_" + PD->getName()); 1713 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1714 Entry->setAlignment(4); 1715 // FIXME: Is this necessary? Why only for protocol? 1716 Entry->setAlignment(4); 1717 } 1718 1719 return Entry; 1720} 1721 1722/* 1723 struct _objc_protocol_extension { 1724 uint32_t size; 1725 struct objc_method_description_list *optional_instance_methods; 1726 struct objc_method_description_list *optional_class_methods; 1727 struct objc_property_list *instance_properties; 1728 }; 1729*/ 1730llvm::Constant * 1731CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 1732 const ConstantVector &OptInstanceMethods, 1733 const ConstantVector &OptClassMethods) { 1734 uint64_t Size = 1735 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 1736 std::vector<llvm::Constant*> Values(4); 1737 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1738 Values[1] = 1739 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 1740 + PD->getName(), 1741 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1742 OptInstanceMethods); 1743 Values[2] = 1744 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(), 1745 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1746 OptClassMethods); 1747 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 1748 0, PD, ObjCTypes); 1749 1750 // Return null if no extension bits are used. 1751 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 1752 Values[3]->isNullValue()) 1753 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 1754 1755 llvm::Constant *Init = 1756 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 1757 1758 // No special section, but goes in llvm.used 1759 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(), 1760 Init, 1761 0, 0, true); 1762} 1763 1764/* 1765 struct objc_protocol_list { 1766 struct objc_protocol_list *next; 1767 long count; 1768 Protocol *list[]; 1769 }; 1770*/ 1771llvm::Constant * 1772CGObjCMac::EmitProtocolList(llvm::Twine Name, 1773 ObjCProtocolDecl::protocol_iterator begin, 1774 ObjCProtocolDecl::protocol_iterator end) { 1775 std::vector<llvm::Constant*> ProtocolRefs; 1776 1777 for (; begin != end; ++begin) 1778 ProtocolRefs.push_back(GetProtocolRef(*begin)); 1779 1780 // Just return null for empty protocol lists 1781 if (ProtocolRefs.empty()) 1782 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1783 1784 // This list is null terminated. 1785 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 1786 1787 std::vector<llvm::Constant*> Values(3); 1788 // This field is only used by the runtime. 1789 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1790 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, 1791 ProtocolRefs.size() - 1); 1792 Values[2] = 1793 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 1794 ProtocolRefs.size()), 1795 ProtocolRefs); 1796 1797 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 1798 llvm::GlobalVariable *GV = 1799 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1800 4, false); 1801 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 1802} 1803 1804void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 1805 std::vector<llvm::Constant*> &Properties, 1806 const Decl *Container, 1807 const ObjCProtocolDecl *PROTO, 1808 const ObjCCommonTypesHelper &ObjCTypes) { 1809 std::vector<llvm::Constant*> Prop(2); 1810 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), 1811 E = PROTO->protocol_end(); P != E; ++P) 1812 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 1813 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), 1814 E = PROTO->prop_end(); I != E; ++I) { 1815 const ObjCPropertyDecl *PD = *I; 1816 if (!PropertySet.insert(PD->getIdentifier())) 1817 continue; 1818 Prop[0] = GetPropertyName(PD->getIdentifier()); 1819 Prop[1] = GetPropertyTypeString(PD, Container); 1820 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); 1821 } 1822} 1823 1824/* 1825 struct _objc_property { 1826 const char * const name; 1827 const char * const attributes; 1828 }; 1829 1830 struct _objc_property_list { 1831 uint32_t entsize; // sizeof (struct _objc_property) 1832 uint32_t prop_count; 1833 struct _objc_property[prop_count]; 1834 }; 1835*/ 1836llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name, 1837 const Decl *Container, 1838 const ObjCContainerDecl *OCD, 1839 const ObjCCommonTypesHelper &ObjCTypes) { 1840 std::vector<llvm::Constant*> Properties, Prop(2); 1841 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 1842 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 1843 E = OCD->prop_end(); I != E; ++I) { 1844 const ObjCPropertyDecl *PD = *I; 1845 PropertySet.insert(PD->getIdentifier()); 1846 Prop[0] = GetPropertyName(PD->getIdentifier()); 1847 Prop[1] = GetPropertyTypeString(PD, Container); 1848 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 1849 Prop)); 1850 } 1851 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) 1852 for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(), 1853 E = OID->protocol_end(); P != E; ++P) 1854 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 1855 1856 // Return null for empty list. 1857 if (Properties.empty()) 1858 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1859 1860 unsigned PropertySize = 1861 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 1862 std::vector<llvm::Constant*> Values(3); 1863 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 1864 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 1865 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 1866 Properties.size()); 1867 Values[2] = llvm::ConstantArray::get(AT, Properties); 1868 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 1869 1870 llvm::GlobalVariable *GV = 1871 CreateMetadataVar(Name, Init, 1872 (ObjCABI == 2) ? "__DATA, __objc_const" : 1873 "__OBJC,__property,regular,no_dead_strip", 1874 (ObjCABI == 2) ? 8 : 4, 1875 true); 1876 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 1877} 1878 1879/* 1880 struct objc_method_description_list { 1881 int count; 1882 struct objc_method_description list[]; 1883 }; 1884*/ 1885llvm::Constant * 1886CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 1887 std::vector<llvm::Constant*> Desc(2); 1888 Desc[0] = 1889 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 1890 ObjCTypes.SelectorPtrTy); 1891 Desc[1] = GetMethodVarType(MD); 1892 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 1893 Desc); 1894} 1895 1896llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name, 1897 const char *Section, 1898 const ConstantVector &Methods) { 1899 // Return null for empty list. 1900 if (Methods.empty()) 1901 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 1902 1903 std::vector<llvm::Constant*> Values(2); 1904 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 1905 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 1906 Methods.size()); 1907 Values[1] = llvm::ConstantArray::get(AT, Methods); 1908 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 1909 1910 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 1911 return llvm::ConstantExpr::getBitCast(GV, 1912 ObjCTypes.MethodDescriptionListPtrTy); 1913} 1914 1915/* 1916 struct _objc_category { 1917 char *category_name; 1918 char *class_name; 1919 struct _objc_method_list *instance_methods; 1920 struct _objc_method_list *class_methods; 1921 struct _objc_protocol_list *protocols; 1922 uint32_t size; // <rdar://4585769> 1923 struct _objc_property_list *instance_properties; 1924 }; 1925*/ 1926void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 1927 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 1928 1929 // FIXME: This is poor design, the OCD should have a pointer to the category 1930 // decl. Additionally, note that Category can be null for the @implementation 1931 // w/o an @interface case. Sema should just create one for us as it does for 1932 // @implementation so everyone else can live life under a clear blue sky. 1933 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 1934 const ObjCCategoryDecl *Category = 1935 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 1936 1937 llvm::SmallString<256> ExtName; 1938 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' 1939 << OCD->getName(); 1940 1941 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1942 for (ObjCCategoryImplDecl::instmeth_iterator 1943 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 1944 // Instance methods should always be defined. 1945 InstanceMethods.push_back(GetMethodConstant(*i)); 1946 } 1947 for (ObjCCategoryImplDecl::classmeth_iterator 1948 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 1949 // Class methods should always be defined. 1950 ClassMethods.push_back(GetMethodConstant(*i)); 1951 } 1952 1953 std::vector<llvm::Constant*> Values(7); 1954 Values[0] = GetClassName(OCD->getIdentifier()); 1955 Values[1] = GetClassName(Interface->getIdentifier()); 1956 LazySymbols.insert(Interface->getIdentifier()); 1957 Values[2] = 1958 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(), 1959 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1960 InstanceMethods); 1961 Values[3] = 1962 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(), 1963 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1964 ClassMethods); 1965 if (Category) { 1966 Values[4] = 1967 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(), 1968 Category->protocol_begin(), 1969 Category->protocol_end()); 1970 } else { 1971 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1972 } 1973 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1974 1975 // If there is no category @interface then there can be no properties. 1976 if (Category) { 1977 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 1978 OCD, Category, ObjCTypes); 1979 } else { 1980 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1981 } 1982 1983 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 1984 Values); 1985 1986 llvm::GlobalVariable *GV = 1987 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init, 1988 "__OBJC,__category,regular,no_dead_strip", 1989 4, true); 1990 DefinedCategories.push_back(GV); 1991} 1992 1993// FIXME: Get from somewhere? 1994enum ClassFlags { 1995 eClassFlags_Factory = 0x00001, 1996 eClassFlags_Meta = 0x00002, 1997 // <rdr://5142207> 1998 eClassFlags_HasCXXStructors = 0x02000, 1999 eClassFlags_Hidden = 0x20000, 2000 eClassFlags_ABI2_Hidden = 0x00010, 2001 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 2002}; 2003 2004/* 2005 struct _objc_class { 2006 Class isa; 2007 Class super_class; 2008 const char *name; 2009 long version; 2010 long info; 2011 long instance_size; 2012 struct _objc_ivar_list *ivars; 2013 struct _objc_method_list *methods; 2014 struct _objc_cache *cache; 2015 struct _objc_protocol_list *protocols; 2016 // Objective-C 1.0 extensions (<rdr://4585769>) 2017 const char *ivar_layout; 2018 struct _objc_class_ext *ext; 2019 }; 2020 2021 See EmitClassExtension(); 2022*/ 2023void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 2024 DefinedSymbols.insert(ID->getIdentifier()); 2025 2026 std::string ClassName = ID->getNameAsString(); 2027 // FIXME: Gross 2028 ObjCInterfaceDecl *Interface = 2029 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 2030 llvm::Constant *Protocols = 2031 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(), 2032 Interface->protocol_begin(), 2033 Interface->protocol_end()); 2034 unsigned Flags = eClassFlags_Factory; 2035 unsigned Size = 2036 CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8; 2037 2038 // FIXME: Set CXX-structors flag. 2039 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 2040 Flags |= eClassFlags_Hidden; 2041 2042 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 2043 for (ObjCImplementationDecl::instmeth_iterator 2044 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 2045 // Instance methods should always be defined. 2046 InstanceMethods.push_back(GetMethodConstant(*i)); 2047 } 2048 for (ObjCImplementationDecl::classmeth_iterator 2049 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 2050 // Class methods should always be defined. 2051 ClassMethods.push_back(GetMethodConstant(*i)); 2052 } 2053 2054 for (ObjCImplementationDecl::propimpl_iterator 2055 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 2056 ObjCPropertyImplDecl *PID = *i; 2057 2058 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 2059 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 2060 2061 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 2062 if (llvm::Constant *C = GetMethodConstant(MD)) 2063 InstanceMethods.push_back(C); 2064 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 2065 if (llvm::Constant *C = GetMethodConstant(MD)) 2066 InstanceMethods.push_back(C); 2067 } 2068 } 2069 2070 std::vector<llvm::Constant*> Values(12); 2071 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 2072 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 2073 // Record a reference to the super class. 2074 LazySymbols.insert(Super->getIdentifier()); 2075 2076 Values[ 1] = 2077 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2078 ObjCTypes.ClassPtrTy); 2079 } else { 2080 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2081 } 2082 Values[ 2] = GetClassName(ID->getIdentifier()); 2083 // Version is always 0. 2084 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2085 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2086 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2087 Values[ 6] = EmitIvarList(ID, false); 2088 Values[ 7] = 2089 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(), 2090 "__OBJC,__inst_meth,regular,no_dead_strip", 2091 InstanceMethods); 2092 // cache is always NULL. 2093 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2094 Values[ 9] = Protocols; 2095 Values[10] = BuildIvarLayout(ID, true); 2096 Values[11] = EmitClassExtension(ID); 2097 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2098 Values); 2099 std::string Name("\01L_OBJC_CLASS_"); 2100 Name += ClassName; 2101 const char *Section = "__OBJC,__class,regular,no_dead_strip"; 2102 // Check for a forward reference. 2103 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2104 if (GV) { 2105 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2106 "Forward metaclass reference has incorrect type."); 2107 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2108 GV->setInitializer(Init); 2109 GV->setSection(Section); 2110 GV->setAlignment(4); 2111 CGM.AddUsedGlobal(GV); 2112 } 2113 else 2114 GV = CreateMetadataVar(Name, Init, Section, 4, true); 2115 DefinedClasses.push_back(GV); 2116} 2117 2118llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 2119 llvm::Constant *Protocols, 2120 const ConstantVector &Methods) { 2121 unsigned Flags = eClassFlags_Meta; 2122 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 2123 2124 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 2125 Flags |= eClassFlags_Hidden; 2126 2127 std::vector<llvm::Constant*> Values(12); 2128 // The isa for the metaclass is the root of the hierarchy. 2129 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 2130 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 2131 Root = Super; 2132 Values[ 0] = 2133 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 2134 ObjCTypes.ClassPtrTy); 2135 // The super class for the metaclass is emitted as the name of the 2136 // super class. The runtime fixes this up to point to the 2137 // *metaclass* for the super class. 2138 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 2139 Values[ 1] = 2140 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2141 ObjCTypes.ClassPtrTy); 2142 } else { 2143 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2144 } 2145 Values[ 2] = GetClassName(ID->getIdentifier()); 2146 // Version is always 0. 2147 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2148 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2149 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2150 Values[ 6] = EmitIvarList(ID, true); 2151 Values[ 7] = 2152 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 2153 "__OBJC,__cls_meth,regular,no_dead_strip", 2154 Methods); 2155 // cache is always NULL. 2156 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2157 Values[ 9] = Protocols; 2158 // ivar_layout for metaclass is always NULL. 2159 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2160 // The class extension is always unused for metaclasses. 2161 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2162 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2163 Values); 2164 2165 std::string Name("\01L_OBJC_METACLASS_"); 2166 Name += ID->getNameAsCString(); 2167 2168 // Check for a forward reference. 2169 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2170 if (GV) { 2171 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2172 "Forward metaclass reference has incorrect type."); 2173 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2174 GV->setInitializer(Init); 2175 } else { 2176 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2177 llvm::GlobalValue::InternalLinkage, 2178 Init, Name); 2179 } 2180 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 2181 GV->setAlignment(4); 2182 CGM.AddUsedGlobal(GV); 2183 2184 return GV; 2185} 2186 2187llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 2188 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 2189 2190 // FIXME: Should we look these up somewhere other than the module. Its a bit 2191 // silly since we only generate these while processing an implementation, so 2192 // exactly one pointer would work if know when we entered/exitted an 2193 // implementation block. 2194 2195 // Check for an existing forward reference. 2196 // Previously, metaclass with internal linkage may have been defined. 2197 // pass 'true' as 2nd argument so it is returned. 2198 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2199 true)) { 2200 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2201 "Forward metaclass reference has incorrect type."); 2202 return GV; 2203 } else { 2204 // Generate as an external reference to keep a consistent 2205 // module. This will be patched up when we emit the metaclass. 2206 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2207 llvm::GlobalValue::ExternalLinkage, 2208 0, 2209 Name); 2210 } 2211} 2212 2213llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { 2214 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString(); 2215 2216 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2217 true)) { 2218 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2219 "Forward class metadata reference has incorrect type."); 2220 return GV; 2221 } else { 2222 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2223 llvm::GlobalValue::ExternalLinkage, 2224 0, 2225 Name); 2226 } 2227} 2228 2229/* 2230 struct objc_class_ext { 2231 uint32_t size; 2232 const char *weak_ivar_layout; 2233 struct _objc_property_list *properties; 2234 }; 2235*/ 2236llvm::Constant * 2237CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 2238 uint64_t Size = 2239 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 2240 2241 std::vector<llvm::Constant*> Values(3); 2242 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2243 Values[1] = BuildIvarLayout(ID, false); 2244 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 2245 ID, ID->getClassInterface(), ObjCTypes); 2246 2247 // Return null if no extension bits are used. 2248 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 2249 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2250 2251 llvm::Constant *Init = 2252 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 2253 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(), 2254 Init, "__OBJC,__class_ext,regular,no_dead_strip", 2255 4, true); 2256} 2257 2258/* 2259 struct objc_ivar { 2260 char *ivar_name; 2261 char *ivar_type; 2262 int ivar_offset; 2263 }; 2264 2265 struct objc_ivar_list { 2266 int ivar_count; 2267 struct objc_ivar list[count]; 2268 }; 2269*/ 2270llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 2271 bool ForClass) { 2272 std::vector<llvm::Constant*> Ivars, Ivar(3); 2273 2274 // When emitting the root class GCC emits ivar entries for the 2275 // actual class structure. It is not clear if we need to follow this 2276 // behavior; for now lets try and get away with not doing it. If so, 2277 // the cleanest solution would be to make up an ObjCInterfaceDecl 2278 // for the class. 2279 if (ForClass) 2280 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2281 2282 ObjCInterfaceDecl *OID = 2283 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 2284 2285 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars; 2286 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars); 2287 2288 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { 2289 ObjCIvarDecl *IVD = OIvars[i]; 2290 // Ignore unnamed bit-fields. 2291 if (!IVD->getDeclName()) 2292 continue; 2293 Ivar[0] = GetMethodVarName(IVD->getIdentifier()); 2294 Ivar[1] = GetMethodVarType(IVD); 2295 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, 2296 ComputeIvarBaseOffset(CGM, OID, IVD)); 2297 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 2298 } 2299 2300 // Return null for empty list. 2301 if (Ivars.empty()) 2302 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2303 2304 std::vector<llvm::Constant*> Values(2); 2305 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 2306 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 2307 Ivars.size()); 2308 Values[1] = llvm::ConstantArray::get(AT, Ivars); 2309 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2310 2311 llvm::GlobalVariable *GV; 2312 if (ForClass) 2313 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(), 2314 Init, "__OBJC,__class_vars,regular,no_dead_strip", 2315 4, true); 2316 else 2317 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(), 2318 Init, "__OBJC,__instance_vars,regular,no_dead_strip", 2319 4, true); 2320 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 2321} 2322 2323/* 2324 struct objc_method { 2325 SEL method_name; 2326 char *method_types; 2327 void *method; 2328 }; 2329 2330 struct objc_method_list { 2331 struct objc_method_list *obsolete; 2332 int count; 2333 struct objc_method methods_list[count]; 2334 }; 2335*/ 2336 2337/// GetMethodConstant - Return a struct objc_method constant for the 2338/// given method if it has been defined. The result is null if the 2339/// method has not been defined. The return value has type MethodPtrTy. 2340llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 2341 // FIXME: Use DenseMap::lookup 2342 llvm::Function *Fn = MethodDefinitions[MD]; 2343 if (!Fn) 2344 return 0; 2345 2346 std::vector<llvm::Constant*> Method(3); 2347 Method[0] = 2348 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 2349 ObjCTypes.SelectorPtrTy); 2350 Method[1] = GetMethodVarType(MD); 2351 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 2352 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 2353} 2354 2355llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name, 2356 const char *Section, 2357 const ConstantVector &Methods) { 2358 // Return null for empty list. 2359 if (Methods.empty()) 2360 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 2361 2362 std::vector<llvm::Constant*> Values(3); 2363 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2364 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 2365 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 2366 Methods.size()); 2367 Values[2] = llvm::ConstantArray::get(AT, Methods); 2368 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2369 2370 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2371 return llvm::ConstantExpr::getBitCast(GV, 2372 ObjCTypes.MethodListPtrTy); 2373} 2374 2375llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 2376 const ObjCContainerDecl *CD) { 2377 llvm::SmallString<256> Name; 2378 GetNameForMethod(OMD, CD, Name); 2379 2380 CodeGenTypes &Types = CGM.getTypes(); 2381 const llvm::FunctionType *MethodTy = 2382 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 2383 llvm::Function *Method = 2384 llvm::Function::Create(MethodTy, 2385 llvm::GlobalValue::InternalLinkage, 2386 Name.str(), 2387 &CGM.getModule()); 2388 MethodDefinitions.insert(std::make_pair(OMD, Method)); 2389 2390 return Method; 2391} 2392 2393llvm::GlobalVariable * 2394CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name, 2395 llvm::Constant *Init, 2396 const char *Section, 2397 unsigned Align, 2398 bool AddToUsed) { 2399 const llvm::Type *Ty = Init->getType(); 2400 llvm::GlobalVariable *GV = 2401 new llvm::GlobalVariable(CGM.getModule(), Ty, false, 2402 llvm::GlobalValue::InternalLinkage, Init, Name); 2403 if (Section) 2404 GV->setSection(Section); 2405 if (Align) 2406 GV->setAlignment(Align); 2407 if (AddToUsed) 2408 CGM.AddUsedGlobal(GV); 2409 return GV; 2410} 2411 2412llvm::Function *CGObjCMac::ModuleInitFunction() { 2413 // Abuse this interface function as a place to finalize. 2414 FinishModule(); 2415 return NULL; 2416} 2417 2418llvm::Constant *CGObjCMac::GetPropertyGetFunction() { 2419 return ObjCTypes.getGetPropertyFn(); 2420} 2421 2422llvm::Constant *CGObjCMac::GetPropertySetFunction() { 2423 return ObjCTypes.getSetPropertyFn(); 2424} 2425 2426llvm::Constant *CGObjCMac::EnumerationMutationFunction() { 2427 return ObjCTypes.getEnumerationMutationFn(); 2428} 2429 2430/* 2431 2432 Objective-C setjmp-longjmp (sjlj) Exception Handling 2433 -- 2434 2435 The basic framework for a @try-catch-finally is as follows: 2436 { 2437 objc_exception_data d; 2438 id _rethrow = null; 2439 bool _call_try_exit = true; 2440 2441 objc_exception_try_enter(&d); 2442 if (!setjmp(d.jmp_buf)) { 2443 ... try body ... 2444 } else { 2445 // exception path 2446 id _caught = objc_exception_extract(&d); 2447 2448 // enter new try scope for handlers 2449 if (!setjmp(d.jmp_buf)) { 2450 ... match exception and execute catch blocks ... 2451 2452 // fell off end, rethrow. 2453 _rethrow = _caught; 2454 ... jump-through-finally to finally_rethrow ... 2455 } else { 2456 // exception in catch block 2457 _rethrow = objc_exception_extract(&d); 2458 _call_try_exit = false; 2459 ... jump-through-finally to finally_rethrow ... 2460 } 2461 } 2462 ... jump-through-finally to finally_end ... 2463 2464 finally: 2465 if (_call_try_exit) 2466 objc_exception_try_exit(&d); 2467 2468 ... finally block .... 2469 ... dispatch to finally destination ... 2470 2471 finally_rethrow: 2472 objc_exception_throw(_rethrow); 2473 2474 finally_end: 2475 } 2476 2477 This framework differs slightly from the one gcc uses, in that gcc 2478 uses _rethrow to determine if objc_exception_try_exit should be called 2479 and if the object should be rethrown. This breaks in the face of 2480 throwing nil and introduces unnecessary branches. 2481 2482 We specialize this framework for a few particular circumstances: 2483 2484 - If there are no catch blocks, then we avoid emitting the second 2485 exception handling context. 2486 2487 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 2488 e)) we avoid emitting the code to rethrow an uncaught exception. 2489 2490 - FIXME: If there is no @finally block we can do a few more 2491 simplifications. 2492 2493 Rethrows and Jumps-Through-Finally 2494 -- 2495 2496 Support for implicit rethrows and jumping through the finally block is 2497 handled by storing the current exception-handling context in 2498 ObjCEHStack. 2499 2500 In order to implement proper @finally semantics, we support one basic 2501 mechanism for jumping through the finally block to an arbitrary 2502 destination. Constructs which generate exits from a @try or @catch 2503 block use this mechanism to implement the proper semantics by chaining 2504 jumps, as necessary. 2505 2506 This mechanism works like the one used for indirect goto: we 2507 arbitrarily assign an ID to each destination and store the ID for the 2508 destination in a variable prior to entering the finally block. At the 2509 end of the finally block we simply create a switch to the proper 2510 destination. 2511 2512 Code gen for @synchronized(expr) stmt; 2513 Effectively generating code for: 2514 objc_sync_enter(expr); 2515 @try stmt @finally { objc_sync_exit(expr); } 2516*/ 2517 2518void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 2519 const Stmt &S) { 2520 bool isTry = isa<ObjCAtTryStmt>(S); 2521 // Create various blocks we refer to for handling @finally. 2522 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 2523 llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit"); 2524 llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit"); 2525 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 2526 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 2527 2528 // For @synchronized, call objc_sync_enter(sync.expr). The 2529 // evaluation of the expression must occur before we enter the 2530 // @synchronized. We can safely avoid a temp here because jumps into 2531 // @synchronized are illegal & this will dominate uses. 2532 llvm::Value *SyncArg = 0; 2533 if (!isTry) { 2534 SyncArg = 2535 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 2536 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 2537 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg); 2538 } 2539 2540 // Push an EH context entry, used for handling rethrows and jumps 2541 // through finally. 2542 CGF.PushCleanupBlock(FinallyBlock); 2543 2544 if (CGF.ObjCEHValueStack.empty()) 2545 CGF.ObjCEHValueStack.push_back(0); 2546 // If This is a nested @try, caught exception is that of enclosing @try. 2547 else 2548 CGF.ObjCEHValueStack.push_back(CGF.ObjCEHValueStack.back()); 2549 // Allocate memory for the exception data and rethrow pointer. 2550 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 2551 "exceptiondata.ptr"); 2552 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 2553 "_rethrow"); 2554 llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca( 2555 llvm::Type::getInt1Ty(VMContext), 2556 "_call_try_exit"); 2557 CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), 2558 CallTryExitPtr); 2559 2560 // Enter a new try block and call setjmp. 2561 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData); 2562 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0, 2563 "jmpbufarray"); 2564 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp"); 2565 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), 2566 JmpBufPtr, "result"); 2567 2568 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 2569 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 2570 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"), 2571 TryHandler, TryBlock); 2572 2573 // Emit the @try block. 2574 CGF.EmitBlock(TryBlock); 2575 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 2576 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 2577 CGF.EmitBranchThroughCleanup(FinallyEnd); 2578 2579 // Emit the "exception in @try" block. 2580 CGF.EmitBlock(TryHandler); 2581 2582 // Retrieve the exception object. We may emit multiple blocks but 2583 // nothing can cross this so the value is already in SSA form. 2584 llvm::Value *Caught = 2585 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 2586 ExceptionData, "caught"); 2587 CGF.ObjCEHValueStack.back() = Caught; 2588 if (!isTry) { 2589 CGF.Builder.CreateStore(Caught, RethrowPtr); 2590 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), 2591 CallTryExitPtr); 2592 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2593 } else if (const ObjCAtCatchStmt* CatchStmt = 2594 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 2595 // Enter a new exception try block (in case a @catch block throws 2596 // an exception). 2597 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData); 2598 2599 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), 2600 JmpBufPtr, "result"); 2601 llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"); 2602 2603 llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch"); 2604 llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler"); 2605 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 2606 2607 CGF.EmitBlock(CatchBlock); 2608 2609 // Handle catch list. As a special case we check if everything is 2610 // matched and avoid generating code for falling off the end if 2611 // so. 2612 bool AllMatched = false; 2613 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 2614 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch"); 2615 2616 const ParmVarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 2617 const ObjCObjectPointerType *OPT = 0; 2618 2619 // catch(...) always matches. 2620 if (!CatchParam) { 2621 AllMatched = true; 2622 } else { 2623 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>(); 2624 2625 // catch(id e) always matches. 2626 // FIXME: For the time being we also match id<X>; this should 2627 // be rejected by Sema instead. 2628 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())) 2629 AllMatched = true; 2630 } 2631 2632 if (AllMatched) { 2633 if (CatchParam) { 2634 CGF.EmitLocalBlockVarDecl(*CatchParam); 2635 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 2636 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 2637 } 2638 2639 CGF.EmitStmt(CatchStmt->getCatchBody()); 2640 CGF.EmitBranchThroughCleanup(FinallyEnd); 2641 break; 2642 } 2643 2644 assert(OPT && "Unexpected non-object pointer type in @catch"); 2645 QualType T = OPT->getPointeeType(); 2646 const ObjCInterfaceType *ObjCType = T->getAs<ObjCInterfaceType>(); 2647 assert(ObjCType && "Catch parameter must have Objective-C type!"); 2648 2649 // Check if the @catch block matches the exception object. 2650 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl()); 2651 2652 llvm::Value *Match = 2653 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 2654 Class, Caught, "match"); 2655 2656 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched"); 2657 2658 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 2659 MatchedBlock, NextCatchBlock); 2660 2661 // Emit the @catch block. 2662 CGF.EmitBlock(MatchedBlock); 2663 CGF.EmitLocalBlockVarDecl(*CatchParam); 2664 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 2665 2666 llvm::Value *Tmp = 2667 CGF.Builder.CreateBitCast(Caught, 2668 CGF.ConvertType(CatchParam->getType()), 2669 "tmp"); 2670 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 2671 2672 CGF.EmitStmt(CatchStmt->getCatchBody()); 2673 CGF.EmitBranchThroughCleanup(FinallyEnd); 2674 2675 CGF.EmitBlock(NextCatchBlock); 2676 } 2677 2678 if (!AllMatched) { 2679 // None of the handlers caught the exception, so store it to be 2680 // rethrown at the end of the @finally block. 2681 CGF.Builder.CreateStore(Caught, RethrowPtr); 2682 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2683 } 2684 2685 // Emit the exception handler for the @catch blocks. 2686 CGF.EmitBlock(CatchHandler); 2687 CGF.Builder.CreateStore( 2688 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 2689 ExceptionData), 2690 RethrowPtr); 2691 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), 2692 CallTryExitPtr); 2693 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2694 } else { 2695 CGF.Builder.CreateStore(Caught, RethrowPtr); 2696 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), 2697 CallTryExitPtr); 2698 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2699 } 2700 2701 // Pop the exception-handling stack entry. It is important to do 2702 // this now, because the code in the @finally block is not in this 2703 // context. 2704 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 2705 2706 CGF.ObjCEHValueStack.pop_back(); 2707 2708 // Emit the @finally block. 2709 CGF.EmitBlock(FinallyBlock); 2710 llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp"); 2711 2712 CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit); 2713 2714 CGF.EmitBlock(FinallyExit); 2715 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData); 2716 2717 CGF.EmitBlock(FinallyNoExit); 2718 if (isTry) { 2719 if (const ObjCAtFinallyStmt* FinallyStmt = 2720 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 2721 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 2722 } else { 2723 // Emit objc_sync_exit(expr); as finally's sole statement for 2724 // @synchronized. 2725 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg); 2726 } 2727 2728 // Emit the switch block 2729 if (Info.SwitchBlock) 2730 CGF.EmitBlock(Info.SwitchBlock); 2731 if (Info.EndBlock) 2732 CGF.EmitBlock(Info.EndBlock); 2733 2734 CGF.EmitBlock(FinallyRethrow); 2735 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), 2736 CGF.Builder.CreateLoad(RethrowPtr)); 2737 CGF.Builder.CreateUnreachable(); 2738 2739 CGF.EmitBlock(FinallyEnd); 2740} 2741 2742void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 2743 const ObjCAtThrowStmt &S) { 2744 llvm::Value *ExceptionAsObject; 2745 2746 if (const Expr *ThrowExpr = S.getThrowExpr()) { 2747 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 2748 ExceptionAsObject = 2749 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 2750 } else { 2751 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 2752 "Unexpected rethrow outside @catch block."); 2753 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 2754 } 2755 2756 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject); 2757 CGF.Builder.CreateUnreachable(); 2758 2759 // Clear the insertion point to indicate we are in unreachable code. 2760 CGF.Builder.ClearInsertionPoint(); 2761} 2762 2763/// EmitObjCWeakRead - Code gen for loading value of a __weak 2764/// object: objc_read_weak (id *src) 2765/// 2766llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 2767 llvm::Value *AddrWeakObj) { 2768 const llvm::Type* DestTy = 2769 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 2770 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, 2771 ObjCTypes.PtrObjectPtrTy); 2772 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 2773 AddrWeakObj, "weakread"); 2774 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 2775 return read_weak; 2776} 2777 2778/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 2779/// objc_assign_weak (id src, id *dst) 2780/// 2781void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 2782 llvm::Value *src, llvm::Value *dst) { 2783 const llvm::Type * SrcTy = src->getType(); 2784 if (!isa<llvm::PointerType>(SrcTy)) { 2785 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2786 assert(Size <= 8 && "does not support size > 8"); 2787 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2788 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2789 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2790 } 2791 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2792 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2793 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 2794 src, dst, "weakassign"); 2795 return; 2796} 2797 2798/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 2799/// objc_assign_global (id src, id *dst) 2800/// 2801void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 2802 llvm::Value *src, llvm::Value *dst) { 2803 const llvm::Type * SrcTy = src->getType(); 2804 if (!isa<llvm::PointerType>(SrcTy)) { 2805 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2806 assert(Size <= 8 && "does not support size > 8"); 2807 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2808 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2809 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2810 } 2811 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2812 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2813 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 2814 src, dst, "globalassign"); 2815 return; 2816} 2817 2818/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 2819/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) 2820/// 2821void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 2822 llvm::Value *src, llvm::Value *dst, 2823 llvm::Value *ivarOffset) { 2824 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); 2825 const llvm::Type * SrcTy = src->getType(); 2826 if (!isa<llvm::PointerType>(SrcTy)) { 2827 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2828 assert(Size <= 8 && "does not support size > 8"); 2829 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2830 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2831 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2832 } 2833 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2834 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2835 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 2836 src, dst, ivarOffset); 2837 return; 2838} 2839 2840/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 2841/// objc_assign_strongCast (id src, id *dst) 2842/// 2843void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 2844 llvm::Value *src, llvm::Value *dst) { 2845 const llvm::Type * SrcTy = src->getType(); 2846 if (!isa<llvm::PointerType>(SrcTy)) { 2847 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2848 assert(Size <= 8 && "does not support size > 8"); 2849 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2850 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2851 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2852 } 2853 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2854 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2855 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 2856 src, dst, "weakassign"); 2857 return; 2858} 2859 2860void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 2861 llvm::Value *DestPtr, 2862 llvm::Value *SrcPtr, 2863 QualType Ty) { 2864 // Get size info for this aggregate. 2865 std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty); 2866 unsigned long size = TypeInfo.first/8; 2867 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 2868 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 2869 llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size); 2870 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 2871 DestPtr, SrcPtr, N); 2872 return; 2873} 2874 2875/// EmitObjCValueForIvar - Code Gen for ivar reference. 2876/// 2877LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 2878 QualType ObjectTy, 2879 llvm::Value *BaseValue, 2880 const ObjCIvarDecl *Ivar, 2881 unsigned CVRQualifiers) { 2882 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl(); 2883 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 2884 EmitIvarOffset(CGF, ID, Ivar)); 2885} 2886 2887llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 2888 const ObjCInterfaceDecl *Interface, 2889 const ObjCIvarDecl *Ivar) { 2890 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 2891 return llvm::ConstantInt::get( 2892 CGM.getTypes().ConvertType(CGM.getContext().LongTy), 2893 Offset); 2894} 2895 2896/* *** Private Interface *** */ 2897 2898/// EmitImageInfo - Emit the image info marker used to encode some module 2899/// level information. 2900/// 2901/// See: <rdr://4810609&4810587&4810587> 2902/// struct IMAGE_INFO { 2903/// unsigned version; 2904/// unsigned flags; 2905/// }; 2906enum ImageInfoFlags { 2907 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what 2908 // this implies. 2909 eImageInfo_GarbageCollected = (1 << 1), 2910 eImageInfo_GCOnly = (1 << 2), 2911 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 2912 2913 // A flag indicating that the module has no instances of an 2914 // @synthesize of a superclass variable. <rdar://problem/6803242> 2915 eImageInfo_CorrectedSynthesize = (1 << 4) 2916}; 2917 2918void CGObjCMac::EmitImageInfo() { 2919 unsigned version = 0; // Version is unused? 2920 unsigned flags = 0; 2921 2922 // FIXME: Fix and continue? 2923 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 2924 flags |= eImageInfo_GarbageCollected; 2925 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 2926 flags |= eImageInfo_GCOnly; 2927 2928 // We never allow @synthesize of a superclass property. 2929 flags |= eImageInfo_CorrectedSynthesize; 2930 2931 // Emitted as int[2]; 2932 llvm::Constant *values[2] = { 2933 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), version), 2934 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags) 2935 }; 2936 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 2); 2937 2938 const char *Section; 2939 if (ObjCABI == 1) 2940 Section = "__OBJC, __image_info,regular"; 2941 else 2942 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip"; 2943 llvm::GlobalVariable *GV = 2944 CreateMetadataVar("\01L_OBJC_IMAGE_INFO", 2945 llvm::ConstantArray::get(AT, values, 2), 2946 Section, 2947 0, 2948 true); 2949 GV->setConstant(true); 2950} 2951 2952 2953// struct objc_module { 2954// unsigned long version; 2955// unsigned long size; 2956// const char *name; 2957// Symtab symtab; 2958// }; 2959 2960// FIXME: Get from somewhere 2961static const int ModuleVersion = 7; 2962 2963void CGObjCMac::EmitModuleInfo() { 2964 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 2965 2966 std::vector<llvm::Constant*> Values(4); 2967 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 2968 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2969 // This used to be the filename, now it is unused. <rdr://4327263> 2970 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 2971 Values[3] = EmitModuleSymbols(); 2972 CreateMetadataVar("\01L_OBJC_MODULES", 2973 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 2974 "__OBJC,__module_info,regular,no_dead_strip", 2975 4, true); 2976} 2977 2978llvm::Constant *CGObjCMac::EmitModuleSymbols() { 2979 unsigned NumClasses = DefinedClasses.size(); 2980 unsigned NumCategories = DefinedCategories.size(); 2981 2982 // Return null if no symbols were defined. 2983 if (!NumClasses && !NumCategories) 2984 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 2985 2986 std::vector<llvm::Constant*> Values(5); 2987 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2988 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 2989 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 2990 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 2991 2992 // The runtime expects exactly the list of defined classes followed 2993 // by the list of defined categories, in a single array. 2994 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 2995 for (unsigned i=0; i<NumClasses; i++) 2996 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 2997 ObjCTypes.Int8PtrTy); 2998 for (unsigned i=0; i<NumCategories; i++) 2999 Symbols[NumClasses + i] = 3000 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 3001 ObjCTypes.Int8PtrTy); 3002 3003 Values[4] = 3004 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 3005 NumClasses + NumCategories), 3006 Symbols); 3007 3008 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 3009 3010 llvm::GlobalVariable *GV = 3011 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 3012 "__OBJC,__symbols,regular,no_dead_strip", 3013 4, true); 3014 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 3015} 3016 3017llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 3018 const ObjCInterfaceDecl *ID) { 3019 LazySymbols.insert(ID->getIdentifier()); 3020 3021 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 3022 3023 if (!Entry) { 3024 llvm::Constant *Casted = 3025 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()), 3026 ObjCTypes.ClassPtrTy); 3027 Entry = 3028 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 3029 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 3030 4, true); 3031 } 3032 3033 return Builder.CreateLoad(Entry, "tmp"); 3034} 3035 3036llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) { 3037 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 3038 3039 if (!Entry) { 3040 llvm::Constant *Casted = 3041 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 3042 ObjCTypes.SelectorPtrTy); 3043 Entry = 3044 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 3045 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 3046 4, true); 3047 } 3048 3049 return Builder.CreateLoad(Entry, "tmp"); 3050} 3051 3052llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 3053 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 3054 3055 if (!Entry) 3056 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 3057 llvm::ConstantArray::get(VMContext, 3058 Ident->getNameStart()), 3059 "__TEXT,__cstring,cstring_literals", 3060 1, true); 3061 3062 return getConstantGEP(VMContext, Entry, 0, 0); 3063} 3064 3065/// GetIvarLayoutName - Returns a unique constant for the given 3066/// ivar layout bitmap. 3067llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 3068 const ObjCCommonTypesHelper &ObjCTypes) { 3069 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3070} 3071 3072static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { 3073 if (FQT.isObjCGCStrong()) 3074 return Qualifiers::Strong; 3075 3076 if (FQT.isObjCGCWeak()) 3077 return Qualifiers::Weak; 3078 3079 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) 3080 return Qualifiers::Strong; 3081 3082 if (const PointerType *PT = FQT->getAs<PointerType>()) 3083 return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 3084 3085 return Qualifiers::GCNone; 3086} 3087 3088void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 3089 unsigned int BytePos, 3090 bool ForStrongLayout, 3091 bool &HasUnion) { 3092 const RecordDecl *RD = RT->getDecl(); 3093 // FIXME - Use iterator. 3094 llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end()); 3095 const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 3096 const llvm::StructLayout *RecLayout = 3097 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 3098 3099 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 3100 ForStrongLayout, HasUnion); 3101} 3102 3103void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 3104 const llvm::StructLayout *Layout, 3105 const RecordDecl *RD, 3106 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 3107 unsigned int BytePos, bool ForStrongLayout, 3108 bool &HasUnion) { 3109 bool IsUnion = (RD && RD->isUnion()); 3110 uint64_t MaxUnionIvarSize = 0; 3111 uint64_t MaxSkippedUnionIvarSize = 0; 3112 FieldDecl *MaxField = 0; 3113 FieldDecl *MaxSkippedField = 0; 3114 FieldDecl *LastFieldBitfield = 0; 3115 uint64_t MaxFieldOffset = 0; 3116 uint64_t MaxSkippedFieldOffset = 0; 3117 uint64_t LastBitfieldOffset = 0; 3118 3119 if (RecFields.empty()) 3120 return; 3121 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0); 3122 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth(); 3123 3124 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 3125 FieldDecl *Field = RecFields[i]; 3126 uint64_t FieldOffset; 3127 if (RD) { 3128 if (Field->isBitField()) { 3129 CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); 3130 3131 const llvm::Type *Ty = 3132 CGM.getTypes().ConvertTypeForMemRecursive(Field->getType()); 3133 uint64_t TypeSize = 3134 CGM.getTypes().getTargetData().getTypeAllocSize(Ty); 3135 FieldOffset = Info.FieldNo * TypeSize; 3136 } else 3137 FieldOffset = 3138 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); 3139 } else 3140 FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)); 3141 3142 // Skip over unnamed or bitfields 3143 if (!Field->getIdentifier() || Field->isBitField()) { 3144 LastFieldBitfield = Field; 3145 LastBitfieldOffset = FieldOffset; 3146 continue; 3147 } 3148 3149 LastFieldBitfield = 0; 3150 QualType FQT = Field->getType(); 3151 if (FQT->isRecordType() || FQT->isUnionType()) { 3152 if (FQT->isUnionType()) 3153 HasUnion = true; 3154 3155 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), 3156 BytePos + FieldOffset, 3157 ForStrongLayout, HasUnion); 3158 continue; 3159 } 3160 3161 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3162 const ConstantArrayType *CArray = 3163 dyn_cast_or_null<ConstantArrayType>(Array); 3164 uint64_t ElCount = CArray->getSize().getZExtValue(); 3165 assert(CArray && "only array with known element size is supported"); 3166 FQT = CArray->getElementType(); 3167 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3168 const ConstantArrayType *CArray = 3169 dyn_cast_or_null<ConstantArrayType>(Array); 3170 ElCount *= CArray->getSize().getZExtValue(); 3171 FQT = CArray->getElementType(); 3172 } 3173 3174 assert(!FQT->isUnionType() && 3175 "layout for array of unions not supported"); 3176 if (FQT->isRecordType()) { 3177 int OldIndex = IvarsInfo.size() - 1; 3178 int OldSkIndex = SkipIvars.size() -1; 3179 3180 const RecordType *RT = FQT->getAs<RecordType>(); 3181 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 3182 ForStrongLayout, HasUnion); 3183 3184 // Replicate layout information for each array element. Note that 3185 // one element is already done. 3186 uint64_t ElIx = 1; 3187 for (int FirstIndex = IvarsInfo.size() - 1, 3188 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 3189 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 3190 for (int i = OldIndex+1; i <= FirstIndex; ++i) 3191 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 3192 IvarsInfo[i].ivar_size)); 3193 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 3194 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 3195 SkipIvars[i].ivar_size)); 3196 } 3197 continue; 3198 } 3199 } 3200 // At this point, we are done with Record/Union and array there of. 3201 // For other arrays we are down to its element type. 3202 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 3203 3204 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 3205 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 3206 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 3207 if (IsUnion) { 3208 uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 3209 if (UnionIvarSize > MaxUnionIvarSize) { 3210 MaxUnionIvarSize = UnionIvarSize; 3211 MaxField = Field; 3212 MaxFieldOffset = FieldOffset; 3213 } 3214 } else { 3215 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 3216 FieldSize / WordSizeInBits)); 3217 } 3218 } else if ((ForStrongLayout && 3219 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) 3220 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { 3221 if (IsUnion) { 3222 // FIXME: Why the asymmetry? We divide by word size in bits on other 3223 // side. 3224 uint64_t UnionIvarSize = FieldSize; 3225 if (UnionIvarSize > MaxSkippedUnionIvarSize) { 3226 MaxSkippedUnionIvarSize = UnionIvarSize; 3227 MaxSkippedField = Field; 3228 MaxSkippedFieldOffset = FieldOffset; 3229 } 3230 } else { 3231 // FIXME: Why the asymmetry, we divide by byte size in bits here? 3232 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 3233 FieldSize / ByteSizeInBits)); 3234 } 3235 } 3236 } 3237 3238 if (LastFieldBitfield) { 3239 // Last field was a bitfield. Must update skip info. 3240 Expr *BitWidth = LastFieldBitfield->getBitWidth(); 3241 uint64_t BitFieldSize = 3242 BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue(); 3243 GC_IVAR skivar; 3244 skivar.ivar_bytepos = BytePos + LastBitfieldOffset; 3245 skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 3246 + ((BitFieldSize % ByteSizeInBits) != 0); 3247 SkipIvars.push_back(skivar); 3248 } 3249 3250 if (MaxField) 3251 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 3252 MaxUnionIvarSize)); 3253 if (MaxSkippedField) 3254 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 3255 MaxSkippedUnionIvarSize)); 3256} 3257 3258/// BuildIvarLayout - Builds ivar layout bitmap for the class 3259/// implementation for the __strong or __weak case. 3260/// The layout map displays which words in ivar list must be skipped 3261/// and which must be scanned by GC (see below). String is built of bytes. 3262/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 3263/// of words to skip and right nibble is count of words to scan. So, each 3264/// nibble represents up to 15 workds to skip or scan. Skipping the rest is 3265/// represented by a 0x00 byte which also ends the string. 3266/// 1. when ForStrongLayout is true, following ivars are scanned: 3267/// - id, Class 3268/// - object * 3269/// - __strong anything 3270/// 3271/// 2. When ForStrongLayout is false, following ivars are scanned: 3272/// - __weak anything 3273/// 3274llvm::Constant *CGObjCCommonMac::BuildIvarLayout( 3275 const ObjCImplementationDecl *OMD, 3276 bool ForStrongLayout) { 3277 bool hasUnion = false; 3278 3279 unsigned int WordsToScan, WordsToSkip; 3280 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 3281 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) 3282 return llvm::Constant::getNullValue(PtrTy); 3283 3284 llvm::SmallVector<FieldDecl*, 32> RecFields; 3285 const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 3286 CGM.getContext().CollectObjCIvars(OI, RecFields); 3287 3288 // Add this implementations synthesized ivars. 3289 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 3290 CGM.getContext().CollectSynthesizedIvars(OI, Ivars); 3291 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) 3292 RecFields.push_back(cast<FieldDecl>(Ivars[k])); 3293 3294 if (RecFields.empty()) 3295 return llvm::Constant::getNullValue(PtrTy); 3296 3297 SkipIvars.clear(); 3298 IvarsInfo.clear(); 3299 3300 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); 3301 if (IvarsInfo.empty()) 3302 return llvm::Constant::getNullValue(PtrTy); 3303 3304 // Sort on byte position in case we encounterred a union nested in 3305 // the ivar list. 3306 if (hasUnion && !IvarsInfo.empty()) 3307 std::sort(IvarsInfo.begin(), IvarsInfo.end()); 3308 if (hasUnion && !SkipIvars.empty()) 3309 std::sort(SkipIvars.begin(), SkipIvars.end()); 3310 3311 // Build the string of skip/scan nibbles 3312 llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars; 3313 unsigned int WordSize = 3314 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 3315 if (IvarsInfo[0].ivar_bytepos == 0) { 3316 WordsToSkip = 0; 3317 WordsToScan = IvarsInfo[0].ivar_size; 3318 } else { 3319 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 3320 WordsToScan = IvarsInfo[0].ivar_size; 3321 } 3322 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 3323 unsigned int TailPrevGCObjC = 3324 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 3325 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 3326 // consecutive 'scanned' object pointers. 3327 WordsToScan += IvarsInfo[i].ivar_size; 3328 } else { 3329 // Skip over 'gc'able object pointer which lay over each other. 3330 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 3331 continue; 3332 // Must skip over 1 or more words. We save current skip/scan values 3333 // and start a new pair. 3334 SKIP_SCAN SkScan; 3335 SkScan.skip = WordsToSkip; 3336 SkScan.scan = WordsToScan; 3337 SkipScanIvars.push_back(SkScan); 3338 3339 // Skip the hole. 3340 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 3341 SkScan.scan = 0; 3342 SkipScanIvars.push_back(SkScan); 3343 WordsToSkip = 0; 3344 WordsToScan = IvarsInfo[i].ivar_size; 3345 } 3346 } 3347 if (WordsToScan > 0) { 3348 SKIP_SCAN SkScan; 3349 SkScan.skip = WordsToSkip; 3350 SkScan.scan = WordsToScan; 3351 SkipScanIvars.push_back(SkScan); 3352 } 3353 3354 bool BytesSkipped = false; 3355 if (!SkipIvars.empty()) { 3356 unsigned int LastIndex = SkipIvars.size()-1; 3357 int LastByteSkipped = 3358 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 3359 LastIndex = IvarsInfo.size()-1; 3360 int LastByteScanned = 3361 IvarsInfo[LastIndex].ivar_bytepos + 3362 IvarsInfo[LastIndex].ivar_size * WordSize; 3363 BytesSkipped = (LastByteSkipped > LastByteScanned); 3364 // Compute number of bytes to skip at the tail end of the last ivar scanned. 3365 if (BytesSkipped) { 3366 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 3367 SKIP_SCAN SkScan; 3368 SkScan.skip = TotalWords - (LastByteScanned/WordSize); 3369 SkScan.scan = 0; 3370 SkipScanIvars.push_back(SkScan); 3371 } 3372 } 3373 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 3374 // as 0xMN. 3375 int SkipScan = SkipScanIvars.size()-1; 3376 for (int i = 0; i <= SkipScan; i++) { 3377 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 3378 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 3379 // 0xM0 followed by 0x0N detected. 3380 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 3381 for (int j = i+1; j < SkipScan; j++) 3382 SkipScanIvars[j] = SkipScanIvars[j+1]; 3383 --SkipScan; 3384 } 3385 } 3386 3387 // Generate the string. 3388 std::string BitMap; 3389 for (int i = 0; i <= SkipScan; i++) { 3390 unsigned char byte; 3391 unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 3392 unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 3393 unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 3394 unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 3395 3396 if (skip_small > 0 || skip_big > 0) 3397 BytesSkipped = true; 3398 // first skip big. 3399 for (unsigned int ix = 0; ix < skip_big; ix++) 3400 BitMap += (unsigned char)(0xf0); 3401 3402 // next (skip small, scan) 3403 if (skip_small) { 3404 byte = skip_small << 4; 3405 if (scan_big > 0) { 3406 byte |= 0xf; 3407 --scan_big; 3408 } else if (scan_small) { 3409 byte |= scan_small; 3410 scan_small = 0; 3411 } 3412 BitMap += byte; 3413 } 3414 // next scan big 3415 for (unsigned int ix = 0; ix < scan_big; ix++) 3416 BitMap += (unsigned char)(0x0f); 3417 // last scan small 3418 if (scan_small) { 3419 byte = scan_small; 3420 BitMap += byte; 3421 } 3422 } 3423 // null terminate string. 3424 unsigned char zero = 0; 3425 BitMap += zero; 3426 3427 if (CGM.getLangOptions().ObjCGCBitmapPrint) { 3428 printf("\n%s ivar layout for class '%s': ", 3429 ForStrongLayout ? "strong" : "weak", 3430 OMD->getClassInterface()->getNameAsCString()); 3431 const unsigned char *s = (unsigned char*)BitMap.c_str(); 3432 for (unsigned i = 0; i < BitMap.size(); i++) 3433 if (!(s[i] & 0xf0)) 3434 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 3435 else 3436 printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 3437 printf("\n"); 3438 } 3439 llvm::GlobalVariable * Entry = 3440 CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 3441 llvm::ConstantArray::get(VMContext, BitMap.c_str()), 3442 "__TEXT,__cstring,cstring_literals", 3443 1, true); 3444 return getConstantGEP(VMContext, Entry, 0, 0); 3445} 3446 3447llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 3448 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 3449 3450 // FIXME: Avoid std::string copying. 3451 if (!Entry) 3452 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_", 3453 llvm::ConstantArray::get(VMContext, Sel.getAsString()), 3454 "__TEXT,__cstring,cstring_literals", 3455 1, true); 3456 3457 return getConstantGEP(VMContext, Entry, 0, 0); 3458} 3459 3460// FIXME: Merge into a single cstring creation function. 3461llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 3462 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 3463} 3464 3465// FIXME: Merge into a single cstring creation function. 3466llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) { 3467 return GetMethodVarName(&CGM.getContext().Idents.get(Name)); 3468} 3469 3470llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 3471 std::string TypeStr; 3472 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 3473 3474 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 3475 3476 if (!Entry) 3477 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 3478 llvm::ConstantArray::get(VMContext, TypeStr), 3479 "__TEXT,__cstring,cstring_literals", 3480 1, true); 3481 3482 return getConstantGEP(VMContext, Entry, 0, 0); 3483} 3484 3485llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) { 3486 std::string TypeStr; 3487 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D), 3488 TypeStr); 3489 3490 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 3491 3492 if (!Entry) 3493 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 3494 llvm::ConstantArray::get(VMContext, TypeStr), 3495 "__TEXT,__cstring,cstring_literals", 3496 1, true); 3497 3498 return getConstantGEP(VMContext, Entry, 0, 0); 3499} 3500 3501// FIXME: Merge into a single cstring creation function. 3502llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 3503 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 3504 3505 if (!Entry) 3506 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", 3507 llvm::ConstantArray::get(VMContext, 3508 Ident->getNameStart()), 3509 "__TEXT,__cstring,cstring_literals", 3510 1, true); 3511 3512 return getConstantGEP(VMContext, Entry, 0, 0); 3513} 3514 3515// FIXME: Merge into a single cstring creation function. 3516// FIXME: This Decl should be more precise. 3517llvm::Constant * 3518CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 3519 const Decl *Container) { 3520 std::string TypeStr; 3521 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 3522 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 3523} 3524 3525void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 3526 const ObjCContainerDecl *CD, 3527 llvm::SmallVectorImpl<char> &Name) { 3528 llvm::raw_svector_ostream OS(Name); 3529 assert (CD && "Missing container decl in GetNameForMethod"); 3530 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 3531 << '[' << CD->getName(); 3532 if (const ObjCCategoryImplDecl *CID = 3533 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 3534 OS << '(' << CID->getNameAsString() << ')'; 3535 OS << ' ' << D->getSelector().getAsString() << ']'; 3536} 3537 3538void CGObjCMac::FinishModule() { 3539 EmitModuleInfo(); 3540 3541 // Emit the dummy bodies for any protocols which were referenced but 3542 // never defined. 3543 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 3544 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) { 3545 if (I->second->hasInitializer()) 3546 continue; 3547 3548 std::vector<llvm::Constant*> Values(5); 3549 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 3550 Values[1] = GetClassName(I->first); 3551 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 3552 Values[3] = Values[4] = 3553 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 3554 I->second->setLinkage(llvm::GlobalValue::InternalLinkage); 3555 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 3556 Values)); 3557 CGM.AddUsedGlobal(I->second); 3558 } 3559 3560 // Add assembler directives to add lazy undefined symbol references 3561 // for classes which are referenced but not defined. This is 3562 // important for correct linker interaction. 3563 // 3564 // FIXME: It would be nice if we had an LLVM construct for this. 3565 if (!LazySymbols.empty() || !DefinedSymbols.empty()) { 3566 llvm::SmallString<256> Asm; 3567 Asm += CGM.getModule().getModuleInlineAsm(); 3568 if (!Asm.empty() && Asm.back() != '\n') 3569 Asm += '\n'; 3570 3571 llvm::raw_svector_ostream OS(Asm); 3572 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(), 3573 e = LazySymbols.end(); I != e; ++I) 3574 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n"; 3575 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(), 3576 e = DefinedSymbols.end(); I != e; ++I) 3577 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n" 3578 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n"; 3579 3580 CGM.getModule().setModuleInlineAsm(OS.str()); 3581 } 3582} 3583 3584CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 3585 : CGObjCCommonMac(cgm), 3586 ObjCTypes(cgm) { 3587 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 3588 ObjCABI = 2; 3589} 3590 3591/* *** */ 3592 3593ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 3594 : VMContext(cgm.getLLVMContext()), CGM(cgm) { 3595 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 3596 ASTContext &Ctx = CGM.getContext(); 3597 3598 ShortTy = Types.ConvertType(Ctx.ShortTy); 3599 IntTy = Types.ConvertType(Ctx.IntTy); 3600 LongTy = Types.ConvertType(Ctx.LongTy); 3601 LongLongTy = Types.ConvertType(Ctx.LongLongTy); 3602 Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 3603 3604 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 3605 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 3606 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 3607 3608 // FIXME: It would be nice to unify this with the opaque type, so that the IR 3609 // comes out a bit cleaner. 3610 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 3611 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 3612 3613 // I'm not sure I like this. The implicit coordination is a bit 3614 // gross. We should solve this in a reasonable fashion because this 3615 // is a pretty common task (match some runtime data structure with 3616 // an LLVM data structure). 3617 3618 // FIXME: This is leaked. 3619 // FIXME: Merge with rewriter code? 3620 3621 // struct _objc_super { 3622 // id self; 3623 // Class cls; 3624 // } 3625 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 3626 SourceLocation(), 3627 &Ctx.Idents.get("_objc_super")); 3628 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3629 Ctx.getObjCIdType(), 0, 0, false)); 3630 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3631 Ctx.getObjCClassType(), 0, 0, false)); 3632 RD->completeDefinition(Ctx); 3633 3634 SuperCTy = Ctx.getTagDeclType(RD); 3635 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 3636 3637 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 3638 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 3639 3640 // struct _prop_t { 3641 // char *name; 3642 // char *attributes; 3643 // } 3644 PropertyTy = llvm::StructType::get(VMContext, Int8PtrTy, Int8PtrTy, NULL); 3645 CGM.getModule().addTypeName("struct._prop_t", 3646 PropertyTy); 3647 3648 // struct _prop_list_t { 3649 // uint32_t entsize; // sizeof(struct _prop_t) 3650 // uint32_t count_of_properties; 3651 // struct _prop_t prop_list[count_of_properties]; 3652 // } 3653 PropertyListTy = llvm::StructType::get(VMContext, IntTy, 3654 IntTy, 3655 llvm::ArrayType::get(PropertyTy, 0), 3656 NULL); 3657 CGM.getModule().addTypeName("struct._prop_list_t", 3658 PropertyListTy); 3659 // struct _prop_list_t * 3660 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 3661 3662 // struct _objc_method { 3663 // SEL _cmd; 3664 // char *method_type; 3665 // char *_imp; 3666 // } 3667 MethodTy = llvm::StructType::get(VMContext, SelectorPtrTy, 3668 Int8PtrTy, 3669 Int8PtrTy, 3670 NULL); 3671 CGM.getModule().addTypeName("struct._objc_method", MethodTy); 3672 3673 // struct _objc_cache * 3674 CacheTy = llvm::OpaqueType::get(VMContext); 3675 CGM.getModule().addTypeName("struct._objc_cache", CacheTy); 3676 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 3677} 3678 3679ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 3680 : ObjCCommonTypesHelper(cgm) { 3681 // struct _objc_method_description { 3682 // SEL name; 3683 // char *types; 3684 // } 3685 MethodDescriptionTy = 3686 llvm::StructType::get(VMContext, SelectorPtrTy, 3687 Int8PtrTy, 3688 NULL); 3689 CGM.getModule().addTypeName("struct._objc_method_description", 3690 MethodDescriptionTy); 3691 3692 // struct _objc_method_description_list { 3693 // int count; 3694 // struct _objc_method_description[1]; 3695 // } 3696 MethodDescriptionListTy = 3697 llvm::StructType::get(VMContext, IntTy, 3698 llvm::ArrayType::get(MethodDescriptionTy, 0), 3699 NULL); 3700 CGM.getModule().addTypeName("struct._objc_method_description_list", 3701 MethodDescriptionListTy); 3702 3703 // struct _objc_method_description_list * 3704 MethodDescriptionListPtrTy = 3705 llvm::PointerType::getUnqual(MethodDescriptionListTy); 3706 3707 // Protocol description structures 3708 3709 // struct _objc_protocol_extension { 3710 // uint32_t size; // sizeof(struct _objc_protocol_extension) 3711 // struct _objc_method_description_list *optional_instance_methods; 3712 // struct _objc_method_description_list *optional_class_methods; 3713 // struct _objc_property_list *instance_properties; 3714 // } 3715 ProtocolExtensionTy = 3716 llvm::StructType::get(VMContext, IntTy, 3717 MethodDescriptionListPtrTy, 3718 MethodDescriptionListPtrTy, 3719 PropertyListPtrTy, 3720 NULL); 3721 CGM.getModule().addTypeName("struct._objc_protocol_extension", 3722 ProtocolExtensionTy); 3723 3724 // struct _objc_protocol_extension * 3725 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 3726 3727 // Handle recursive construction of Protocol and ProtocolList types 3728 3729 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(VMContext); 3730 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext); 3731 3732 const llvm::Type *T = 3733 llvm::StructType::get(VMContext, 3734 llvm::PointerType::getUnqual(ProtocolListTyHolder), 3735 LongTy, 3736 llvm::ArrayType::get(ProtocolTyHolder, 0), 3737 NULL); 3738 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); 3739 3740 // struct _objc_protocol { 3741 // struct _objc_protocol_extension *isa; 3742 // char *protocol_name; 3743 // struct _objc_protocol **_objc_protocol_list; 3744 // struct _objc_method_description_list *instance_methods; 3745 // struct _objc_method_description_list *class_methods; 3746 // } 3747 T = llvm::StructType::get(VMContext, ProtocolExtensionPtrTy, 3748 Int8PtrTy, 3749 llvm::PointerType::getUnqual(ProtocolListTyHolder), 3750 MethodDescriptionListPtrTy, 3751 MethodDescriptionListPtrTy, 3752 NULL); 3753 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T); 3754 3755 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get()); 3756 CGM.getModule().addTypeName("struct._objc_protocol_list", 3757 ProtocolListTy); 3758 // struct _objc_protocol_list * 3759 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 3760 3761 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get()); 3762 CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy); 3763 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 3764 3765 // Class description structures 3766 3767 // struct _objc_ivar { 3768 // char *ivar_name; 3769 // char *ivar_type; 3770 // int ivar_offset; 3771 // } 3772 IvarTy = llvm::StructType::get(VMContext, Int8PtrTy, 3773 Int8PtrTy, 3774 IntTy, 3775 NULL); 3776 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy); 3777 3778 // struct _objc_ivar_list * 3779 IvarListTy = llvm::OpaqueType::get(VMContext); 3780 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy); 3781 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 3782 3783 // struct _objc_method_list * 3784 MethodListTy = llvm::OpaqueType::get(VMContext); 3785 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); 3786 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 3787 3788 // struct _objc_class_extension * 3789 ClassExtensionTy = 3790 llvm::StructType::get(VMContext, IntTy, 3791 Int8PtrTy, 3792 PropertyListPtrTy, 3793 NULL); 3794 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy); 3795 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 3796 3797 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext); 3798 3799 // struct _objc_class { 3800 // Class isa; 3801 // Class super_class; 3802 // char *name; 3803 // long version; 3804 // long info; 3805 // long instance_size; 3806 // struct _objc_ivar_list *ivars; 3807 // struct _objc_method_list *methods; 3808 // struct _objc_cache *cache; 3809 // struct _objc_protocol_list *protocols; 3810 // char *ivar_layout; 3811 // struct _objc_class_ext *ext; 3812 // }; 3813 T = llvm::StructType::get(VMContext, 3814 llvm::PointerType::getUnqual(ClassTyHolder), 3815 llvm::PointerType::getUnqual(ClassTyHolder), 3816 Int8PtrTy, 3817 LongTy, 3818 LongTy, 3819 LongTy, 3820 IvarListPtrTy, 3821 MethodListPtrTy, 3822 CachePtrTy, 3823 ProtocolListPtrTy, 3824 Int8PtrTy, 3825 ClassExtensionPtrTy, 3826 NULL); 3827 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T); 3828 3829 ClassTy = cast<llvm::StructType>(ClassTyHolder.get()); 3830 CGM.getModule().addTypeName("struct._objc_class", ClassTy); 3831 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 3832 3833 // struct _objc_category { 3834 // char *category_name; 3835 // char *class_name; 3836 // struct _objc_method_list *instance_method; 3837 // struct _objc_method_list *class_method; 3838 // uint32_t size; // sizeof(struct _objc_category) 3839 // struct _objc_property_list *instance_properties;// category's @property 3840 // } 3841 CategoryTy = llvm::StructType::get(VMContext, Int8PtrTy, 3842 Int8PtrTy, 3843 MethodListPtrTy, 3844 MethodListPtrTy, 3845 ProtocolListPtrTy, 3846 IntTy, 3847 PropertyListPtrTy, 3848 NULL); 3849 CGM.getModule().addTypeName("struct._objc_category", CategoryTy); 3850 3851 // Global metadata structures 3852 3853 // struct _objc_symtab { 3854 // long sel_ref_cnt; 3855 // SEL *refs; 3856 // short cls_def_cnt; 3857 // short cat_def_cnt; 3858 // char *defs[cls_def_cnt + cat_def_cnt]; 3859 // } 3860 SymtabTy = llvm::StructType::get(VMContext, LongTy, 3861 SelectorPtrTy, 3862 ShortTy, 3863 ShortTy, 3864 llvm::ArrayType::get(Int8PtrTy, 0), 3865 NULL); 3866 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 3867 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 3868 3869 // struct _objc_module { 3870 // long version; 3871 // long size; // sizeof(struct _objc_module) 3872 // char *name; 3873 // struct _objc_symtab* symtab; 3874 // } 3875 ModuleTy = 3876 llvm::StructType::get(VMContext, LongTy, 3877 LongTy, 3878 Int8PtrTy, 3879 SymtabPtrTy, 3880 NULL); 3881 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 3882 3883 3884 // FIXME: This is the size of the setjmp buffer and should be target 3885 // specific. 18 is what's used on 32-bit X86. 3886 uint64_t SetJmpBufferSize = 18; 3887 3888 // Exceptions 3889 const llvm::Type *StackPtrTy = llvm::ArrayType::get( 3890 llvm::Type::getInt8PtrTy(VMContext), 4); 3891 3892 ExceptionDataTy = 3893 llvm::StructType::get(VMContext, llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 3894 SetJmpBufferSize), 3895 StackPtrTy, NULL); 3896 CGM.getModule().addTypeName("struct._objc_exception_data", 3897 ExceptionDataTy); 3898 3899} 3900 3901ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 3902 : ObjCCommonTypesHelper(cgm) { 3903 // struct _method_list_t { 3904 // uint32_t entsize; // sizeof(struct _objc_method) 3905 // uint32_t method_count; 3906 // struct _objc_method method_list[method_count]; 3907 // } 3908 MethodListnfABITy = llvm::StructType::get(VMContext, IntTy, 3909 IntTy, 3910 llvm::ArrayType::get(MethodTy, 0), 3911 NULL); 3912 CGM.getModule().addTypeName("struct.__method_list_t", 3913 MethodListnfABITy); 3914 // struct method_list_t * 3915 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 3916 3917 // struct _protocol_t { 3918 // id isa; // NULL 3919 // const char * const protocol_name; 3920 // const struct _protocol_list_t * protocol_list; // super protocols 3921 // const struct method_list_t * const instance_methods; 3922 // const struct method_list_t * const class_methods; 3923 // const struct method_list_t *optionalInstanceMethods; 3924 // const struct method_list_t *optionalClassMethods; 3925 // const struct _prop_list_t * properties; 3926 // const uint32_t size; // sizeof(struct _protocol_t) 3927 // const uint32_t flags; // = 0 3928 // } 3929 3930 // Holder for struct _protocol_list_t * 3931 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext); 3932 3933 ProtocolnfABITy = llvm::StructType::get(VMContext, ObjectPtrTy, 3934 Int8PtrTy, 3935 llvm::PointerType::getUnqual( 3936 ProtocolListTyHolder), 3937 MethodListnfABIPtrTy, 3938 MethodListnfABIPtrTy, 3939 MethodListnfABIPtrTy, 3940 MethodListnfABIPtrTy, 3941 PropertyListPtrTy, 3942 IntTy, 3943 IntTy, 3944 NULL); 3945 CGM.getModule().addTypeName("struct._protocol_t", 3946 ProtocolnfABITy); 3947 3948 // struct _protocol_t* 3949 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 3950 3951 // struct _protocol_list_t { 3952 // long protocol_count; // Note, this is 32/64 bit 3953 // struct _protocol_t *[protocol_count]; 3954 // } 3955 ProtocolListnfABITy = llvm::StructType::get(VMContext, LongTy, 3956 llvm::ArrayType::get( 3957 ProtocolnfABIPtrTy, 0), 3958 NULL); 3959 CGM.getModule().addTypeName("struct._objc_protocol_list", 3960 ProtocolListnfABITy); 3961 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo( 3962 ProtocolListnfABITy); 3963 3964 // struct _objc_protocol_list* 3965 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 3966 3967 // struct _ivar_t { 3968 // unsigned long int *offset; // pointer to ivar offset location 3969 // char *name; 3970 // char *type; 3971 // uint32_t alignment; 3972 // uint32_t size; 3973 // } 3974 IvarnfABITy = llvm::StructType::get(VMContext, 3975 llvm::PointerType::getUnqual(LongTy), 3976 Int8PtrTy, 3977 Int8PtrTy, 3978 IntTy, 3979 IntTy, 3980 NULL); 3981 CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy); 3982 3983 // struct _ivar_list_t { 3984 // uint32 entsize; // sizeof(struct _ivar_t) 3985 // uint32 count; 3986 // struct _iver_t list[count]; 3987 // } 3988 IvarListnfABITy = llvm::StructType::get(VMContext, IntTy, 3989 IntTy, 3990 llvm::ArrayType::get( 3991 IvarnfABITy, 0), 3992 NULL); 3993 CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy); 3994 3995 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 3996 3997 // struct _class_ro_t { 3998 // uint32_t const flags; 3999 // uint32_t const instanceStart; 4000 // uint32_t const instanceSize; 4001 // uint32_t const reserved; // only when building for 64bit targets 4002 // const uint8_t * const ivarLayout; 4003 // const char *const name; 4004 // const struct _method_list_t * const baseMethods; 4005 // const struct _objc_protocol_list *const baseProtocols; 4006 // const struct _ivar_list_t *const ivars; 4007 // const uint8_t * const weakIvarLayout; 4008 // const struct _prop_list_t * const properties; 4009 // } 4010 4011 // FIXME. Add 'reserved' field in 64bit abi mode! 4012 ClassRonfABITy = llvm::StructType::get(VMContext, IntTy, 4013 IntTy, 4014 IntTy, 4015 Int8PtrTy, 4016 Int8PtrTy, 4017 MethodListnfABIPtrTy, 4018 ProtocolListnfABIPtrTy, 4019 IvarListnfABIPtrTy, 4020 Int8PtrTy, 4021 PropertyListPtrTy, 4022 NULL); 4023 CGM.getModule().addTypeName("struct._class_ro_t", 4024 ClassRonfABITy); 4025 4026 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 4027 std::vector<const llvm::Type*> Params; 4028 Params.push_back(ObjectPtrTy); 4029 Params.push_back(SelectorPtrTy); 4030 ImpnfABITy = llvm::PointerType::getUnqual( 4031 llvm::FunctionType::get(ObjectPtrTy, Params, false)); 4032 4033 // struct _class_t { 4034 // struct _class_t *isa; 4035 // struct _class_t * const superclass; 4036 // void *cache; 4037 // IMP *vtable; 4038 // struct class_ro_t *ro; 4039 // } 4040 4041 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext); 4042 ClassnfABITy = 4043 llvm::StructType::get(VMContext, 4044 llvm::PointerType::getUnqual(ClassTyHolder), 4045 llvm::PointerType::getUnqual(ClassTyHolder), 4046 CachePtrTy, 4047 llvm::PointerType::getUnqual(ImpnfABITy), 4048 llvm::PointerType::getUnqual(ClassRonfABITy), 4049 NULL); 4050 CGM.getModule().addTypeName("struct._class_t", ClassnfABITy); 4051 4052 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo( 4053 ClassnfABITy); 4054 4055 // LLVM for struct _class_t * 4056 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 4057 4058 // struct _category_t { 4059 // const char * const name; 4060 // struct _class_t *const cls; 4061 // const struct _method_list_t * const instance_methods; 4062 // const struct _method_list_t * const class_methods; 4063 // const struct _protocol_list_t * const protocols; 4064 // const struct _prop_list_t * const properties; 4065 // } 4066 CategorynfABITy = llvm::StructType::get(VMContext, Int8PtrTy, 4067 ClassnfABIPtrTy, 4068 MethodListnfABIPtrTy, 4069 MethodListnfABIPtrTy, 4070 ProtocolListnfABIPtrTy, 4071 PropertyListPtrTy, 4072 NULL); 4073 CGM.getModule().addTypeName("struct._category_t", CategorynfABITy); 4074 4075 // New types for nonfragile abi messaging. 4076 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 4077 ASTContext &Ctx = CGM.getContext(); 4078 4079 // MessageRefTy - LLVM for: 4080 // struct _message_ref_t { 4081 // IMP messenger; 4082 // SEL name; 4083 // }; 4084 4085 // First the clang type for struct _message_ref_t 4086 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 4087 SourceLocation(), 4088 &Ctx.Idents.get("_message_ref_t")); 4089 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 4090 Ctx.VoidPtrTy, 0, 0, false)); 4091 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 4092 Ctx.getObjCSelType(), 0, 0, false)); 4093 RD->completeDefinition(Ctx); 4094 4095 MessageRefCTy = Ctx.getTagDeclType(RD); 4096 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 4097 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 4098 4099 // MessageRefPtrTy - LLVM for struct _message_ref_t* 4100 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 4101 4102 // SuperMessageRefTy - LLVM for: 4103 // struct _super_message_ref_t { 4104 // SUPER_IMP messenger; 4105 // SEL name; 4106 // }; 4107 SuperMessageRefTy = llvm::StructType::get(VMContext, ImpnfABITy, 4108 SelectorPtrTy, 4109 NULL); 4110 CGM.getModule().addTypeName("struct._super_message_ref_t", SuperMessageRefTy); 4111 4112 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 4113 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 4114 4115 4116 // struct objc_typeinfo { 4117 // const void** vtable; // objc_ehtype_vtable + 2 4118 // const char* name; // c++ typeinfo string 4119 // Class cls; 4120 // }; 4121 EHTypeTy = llvm::StructType::get(VMContext, 4122 llvm::PointerType::getUnqual(Int8PtrTy), 4123 Int8PtrTy, 4124 ClassnfABIPtrTy, 4125 NULL); 4126 CGM.getModule().addTypeName("struct._objc_typeinfo", EHTypeTy); 4127 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 4128} 4129 4130llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 4131 FinishNonFragileABIModule(); 4132 4133 return NULL; 4134} 4135 4136void CGObjCNonFragileABIMac::AddModuleClassList(const 4137 std::vector<llvm::GlobalValue*> 4138 &Container, 4139 const char *SymbolName, 4140 const char *SectionName) { 4141 unsigned NumClasses = Container.size(); 4142 4143 if (!NumClasses) 4144 return; 4145 4146 std::vector<llvm::Constant*> Symbols(NumClasses); 4147 for (unsigned i=0; i<NumClasses; i++) 4148 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 4149 ObjCTypes.Int8PtrTy); 4150 llvm::Constant* Init = 4151 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 4152 NumClasses), 4153 Symbols); 4154 4155 llvm::GlobalVariable *GV = 4156 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4157 llvm::GlobalValue::InternalLinkage, 4158 Init, 4159 SymbolName); 4160 GV->setAlignment(8); 4161 GV->setSection(SectionName); 4162 CGM.AddUsedGlobal(GV); 4163} 4164 4165void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 4166 // nonfragile abi has no module definition. 4167 4168 // Build list of all implemented class addresses in array 4169 // L_OBJC_LABEL_CLASS_$. 4170 AddModuleClassList(DefinedClasses, 4171 "\01L_OBJC_LABEL_CLASS_$", 4172 "__DATA, __objc_classlist, regular, no_dead_strip"); 4173 4174 for (unsigned i = 0; i < DefinedClasses.size(); i++) { 4175 llvm::GlobalValue *IMPLGV = DefinedClasses[i]; 4176 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4177 continue; 4178 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4179 } 4180 4181 for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) { 4182 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; 4183 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4184 continue; 4185 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4186 } 4187 4188 AddModuleClassList(DefinedNonLazyClasses, 4189 "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 4190 "__DATA, __objc_nlclslist, regular, no_dead_strip"); 4191 4192 // Build list of all implemented category addresses in array 4193 // L_OBJC_LABEL_CATEGORY_$. 4194 AddModuleClassList(DefinedCategories, 4195 "\01L_OBJC_LABEL_CATEGORY_$", 4196 "__DATA, __objc_catlist, regular, no_dead_strip"); 4197 AddModuleClassList(DefinedNonLazyCategories, 4198 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 4199 "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 4200 4201 // static int L_OBJC_IMAGE_INFO[2] = { 0, flags }; 4202 // FIXME. flags can be 0 | 1 | 2 | 6. For now just use 0 4203 std::vector<llvm::Constant*> Values(2); 4204 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); 4205 unsigned int flags = 0; 4206 // FIXME: Fix and continue? 4207 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 4208 flags |= eImageInfo_GarbageCollected; 4209 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 4210 flags |= eImageInfo_GCOnly; 4211 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 4212 llvm::Constant* Init = llvm::ConstantArray::get( 4213 llvm::ArrayType::get(ObjCTypes.IntTy, 2), 4214 Values); 4215 llvm::GlobalVariable *IMGV = 4216 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4217 llvm::GlobalValue::InternalLinkage, 4218 Init, 4219 "\01L_OBJC_IMAGE_INFO"); 4220 IMGV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 4221 IMGV->setConstant(true); 4222 CGM.AddUsedGlobal(IMGV); 4223} 4224 4225/// LegacyDispatchedSelector - Returns true if SEL is not in the list of 4226/// NonLegacyDispatchMethods; false otherwise. What this means is that 4227/// except for the 19 selectors in the list, we generate 32bit-style 4228/// message dispatch call for all the rest. 4229/// 4230bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) { 4231 if (NonLegacyDispatchMethods.empty()) { 4232 NonLegacyDispatchMethods.insert(GetNullarySelector("alloc")); 4233 NonLegacyDispatchMethods.insert(GetNullarySelector("class")); 4234 NonLegacyDispatchMethods.insert(GetNullarySelector("self")); 4235 NonLegacyDispatchMethods.insert(GetNullarySelector("isFlipped")); 4236 NonLegacyDispatchMethods.insert(GetNullarySelector("length")); 4237 NonLegacyDispatchMethods.insert(GetNullarySelector("count")); 4238 NonLegacyDispatchMethods.insert(GetNullarySelector("retain")); 4239 NonLegacyDispatchMethods.insert(GetNullarySelector("release")); 4240 NonLegacyDispatchMethods.insert(GetNullarySelector("autorelease")); 4241 NonLegacyDispatchMethods.insert(GetNullarySelector("hash")); 4242 4243 NonLegacyDispatchMethods.insert(GetUnarySelector("allocWithZone")); 4244 NonLegacyDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 4245 NonLegacyDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 4246 NonLegacyDispatchMethods.insert(GetUnarySelector("objectForKey")); 4247 NonLegacyDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 4248 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqualToString")); 4249 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqual")); 4250 NonLegacyDispatchMethods.insert(GetUnarySelector("addObject")); 4251 // "countByEnumeratingWithState:objects:count" 4252 IdentifierInfo *KeyIdents[] = { 4253 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 4254 &CGM.getContext().Idents.get("objects"), 4255 &CGM.getContext().Idents.get("count") 4256 }; 4257 NonLegacyDispatchMethods.insert( 4258 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 4259 } 4260 return (NonLegacyDispatchMethods.count(Sel) == 0); 4261} 4262 4263// Metadata flags 4264enum MetaDataDlags { 4265 CLS = 0x0, 4266 CLS_META = 0x1, 4267 CLS_ROOT = 0x2, 4268 OBJC2_CLS_HIDDEN = 0x10, 4269 CLS_EXCEPTION = 0x20 4270}; 4271/// BuildClassRoTInitializer - generate meta-data for: 4272/// struct _class_ro_t { 4273/// uint32_t const flags; 4274/// uint32_t const instanceStart; 4275/// uint32_t const instanceSize; 4276/// uint32_t const reserved; // only when building for 64bit targets 4277/// const uint8_t * const ivarLayout; 4278/// const char *const name; 4279/// const struct _method_list_t * const baseMethods; 4280/// const struct _protocol_list_t *const baseProtocols; 4281/// const struct _ivar_list_t *const ivars; 4282/// const uint8_t * const weakIvarLayout; 4283/// const struct _prop_list_t * const properties; 4284/// } 4285/// 4286llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 4287 unsigned flags, 4288 unsigned InstanceStart, 4289 unsigned InstanceSize, 4290 const ObjCImplementationDecl *ID) { 4291 std::string ClassName = ID->getNameAsString(); 4292 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets! 4293 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 4294 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 4295 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 4296 // FIXME. For 64bit targets add 0 here. 4297 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4298 : BuildIvarLayout(ID, true); 4299 Values[ 4] = GetClassName(ID->getIdentifier()); 4300 // const struct _method_list_t * const baseMethods; 4301 std::vector<llvm::Constant*> Methods; 4302 std::string MethodListName("\01l_OBJC_$_"); 4303 if (flags & CLS_META) { 4304 MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 4305 for (ObjCImplementationDecl::classmeth_iterator 4306 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 4307 // Class methods should always be defined. 4308 Methods.push_back(GetMethodConstant(*i)); 4309 } 4310 } else { 4311 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 4312 for (ObjCImplementationDecl::instmeth_iterator 4313 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 4314 // Instance methods should always be defined. 4315 Methods.push_back(GetMethodConstant(*i)); 4316 } 4317 for (ObjCImplementationDecl::propimpl_iterator 4318 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 4319 ObjCPropertyImplDecl *PID = *i; 4320 4321 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 4322 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 4323 4324 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 4325 if (llvm::Constant *C = GetMethodConstant(MD)) 4326 Methods.push_back(C); 4327 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 4328 if (llvm::Constant *C = GetMethodConstant(MD)) 4329 Methods.push_back(C); 4330 } 4331 } 4332 } 4333 Values[ 5] = EmitMethodList(MethodListName, 4334 "__DATA, __objc_const", Methods); 4335 4336 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4337 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 4338 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 4339 + OID->getName(), 4340 OID->protocol_begin(), 4341 OID->protocol_end()); 4342 4343 if (flags & CLS_META) 4344 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 4345 else 4346 Values[ 7] = EmitIvarList(ID); 4347 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4348 : BuildIvarLayout(ID, false); 4349 if (flags & CLS_META) 4350 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 4351 else 4352 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 4353 ID, ID->getClassInterface(), ObjCTypes); 4354 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 4355 Values); 4356 llvm::GlobalVariable *CLASS_RO_GV = 4357 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false, 4358 llvm::GlobalValue::InternalLinkage, 4359 Init, 4360 (flags & CLS_META) ? 4361 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 4362 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName); 4363 CLASS_RO_GV->setAlignment( 4364 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassRonfABITy)); 4365 CLASS_RO_GV->setSection("__DATA, __objc_const"); 4366 return CLASS_RO_GV; 4367 4368} 4369 4370/// BuildClassMetaData - This routine defines that to-level meta-data 4371/// for the given ClassName for: 4372/// struct _class_t { 4373/// struct _class_t *isa; 4374/// struct _class_t * const superclass; 4375/// void *cache; 4376/// IMP *vtable; 4377/// struct class_ro_t *ro; 4378/// } 4379/// 4380llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 4381 std::string &ClassName, 4382 llvm::Constant *IsAGV, 4383 llvm::Constant *SuperClassGV, 4384 llvm::Constant *ClassRoGV, 4385 bool HiddenVisibility) { 4386 std::vector<llvm::Constant*> Values(5); 4387 Values[0] = IsAGV; 4388 Values[1] = SuperClassGV; 4389 if (!Values[1]) 4390 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 4391 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar 4392 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar 4393 Values[4] = ClassRoGV; // &CLASS_RO_GV 4394 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 4395 Values); 4396 llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 4397 GV->setInitializer(Init); 4398 GV->setSection("__DATA, __objc_data"); 4399 GV->setAlignment( 4400 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassnfABITy)); 4401 if (HiddenVisibility) 4402 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4403 return GV; 4404} 4405 4406bool 4407CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 4408 return OD->getClassMethod(GetNullarySelector("load")) != 0; 4409} 4410 4411void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 4412 uint32_t &InstanceStart, 4413 uint32_t &InstanceSize) { 4414 const ASTRecordLayout &RL = 4415 CGM.getContext().getASTObjCImplementationLayout(OID); 4416 4417 // InstanceSize is really instance end. 4418 InstanceSize = llvm::RoundUpToAlignment(RL.getDataSize(), 8) / 8; 4419 4420 // If there are no fields, the start is the same as the end. 4421 if (!RL.getFieldCount()) 4422 InstanceStart = InstanceSize; 4423 else 4424 InstanceStart = RL.getFieldOffset(0) / 8; 4425} 4426 4427void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 4428 std::string ClassName = ID->getNameAsString(); 4429 if (!ObjCEmptyCacheVar) { 4430 ObjCEmptyCacheVar = new llvm::GlobalVariable( 4431 CGM.getModule(), 4432 ObjCTypes.CacheTy, 4433 false, 4434 llvm::GlobalValue::ExternalLinkage, 4435 0, 4436 "_objc_empty_cache"); 4437 4438 ObjCEmptyVtableVar = new llvm::GlobalVariable( 4439 CGM.getModule(), 4440 ObjCTypes.ImpnfABITy, 4441 false, 4442 llvm::GlobalValue::ExternalLinkage, 4443 0, 4444 "_objc_empty_vtable"); 4445 } 4446 assert(ID->getClassInterface() && 4447 "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 4448 // FIXME: Is this correct (that meta class size is never computed)? 4449 uint32_t InstanceStart = 4450 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 4451 uint32_t InstanceSize = InstanceStart; 4452 uint32_t flags = CLS_META; 4453 std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 4454 std::string ObjCClassName(getClassSymbolPrefix()); 4455 4456 llvm::GlobalVariable *SuperClassGV, *IsAGV; 4457 4458 bool classIsHidden = 4459 CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden; 4460 if (classIsHidden) 4461 flags |= OBJC2_CLS_HIDDEN; 4462 if (!ID->getClassInterface()->getSuperClass()) { 4463 // class is root 4464 flags |= CLS_ROOT; 4465 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 4466 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 4467 } else { 4468 // Has a root. Current class is not a root. 4469 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 4470 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 4471 Root = Super; 4472 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 4473 if (Root->hasAttr<WeakImportAttr>()) 4474 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4475 // work on super class metadata symbol. 4476 std::string SuperClassName = 4477 ObjCMetaClassName + 4478 ID->getClassInterface()->getSuperClass()->getNameAsString(); 4479 SuperClassGV = GetClassGlobal(SuperClassName); 4480 if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>()) 4481 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4482 } 4483 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 4484 InstanceStart, 4485 InstanceSize,ID); 4486 std::string TClassName = ObjCMetaClassName + ClassName; 4487 llvm::GlobalVariable *MetaTClass = 4488 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 4489 classIsHidden); 4490 DefinedMetaClasses.push_back(MetaTClass); 4491 4492 // Metadata for the class 4493 flags = CLS; 4494 if (classIsHidden) 4495 flags |= OBJC2_CLS_HIDDEN; 4496 4497 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) 4498 flags |= CLS_EXCEPTION; 4499 4500 if (!ID->getClassInterface()->getSuperClass()) { 4501 flags |= CLS_ROOT; 4502 SuperClassGV = 0; 4503 } else { 4504 // Has a root. Current class is not a root. 4505 std::string RootClassName = 4506 ID->getClassInterface()->getSuperClass()->getNameAsString(); 4507 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 4508 if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>()) 4509 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4510 } 4511 GetClassSizeInfo(ID, InstanceStart, InstanceSize); 4512 CLASS_RO_GV = BuildClassRoTInitializer(flags, 4513 InstanceStart, 4514 InstanceSize, 4515 ID); 4516 4517 TClassName = ObjCClassName + ClassName; 4518 llvm::GlobalVariable *ClassMD = 4519 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 4520 classIsHidden); 4521 DefinedClasses.push_back(ClassMD); 4522 4523 // Determine if this class is also "non-lazy". 4524 if (ImplementationIsNonLazy(ID)) 4525 DefinedNonLazyClasses.push_back(ClassMD); 4526 4527 // Force the definition of the EHType if necessary. 4528 if (flags & CLS_EXCEPTION) 4529 GetInterfaceEHType(ID->getClassInterface(), true); 4530} 4531 4532/// GenerateProtocolRef - This routine is called to generate code for 4533/// a protocol reference expression; as in: 4534/// @code 4535/// @protocol(Proto1); 4536/// @endcode 4537/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 4538/// which will hold address of the protocol meta-data. 4539/// 4540llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 4541 const ObjCProtocolDecl *PD) { 4542 4543 // This routine is called for @protocol only. So, we must build definition 4544 // of protocol's meta-data (not a reference to it!) 4545 // 4546 llvm::Constant *Init = 4547 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 4548 ObjCTypes.ExternalProtocolPtrTy); 4549 4550 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 4551 ProtocolName += PD->getNameAsCString(); 4552 4553 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 4554 if (PTGV) 4555 return Builder.CreateLoad(PTGV, "tmp"); 4556 PTGV = new llvm::GlobalVariable( 4557 CGM.getModule(), 4558 Init->getType(), false, 4559 llvm::GlobalValue::WeakAnyLinkage, 4560 Init, 4561 ProtocolName); 4562 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 4563 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4564 CGM.AddUsedGlobal(PTGV); 4565 return Builder.CreateLoad(PTGV, "tmp"); 4566} 4567 4568/// GenerateCategory - Build metadata for a category implementation. 4569/// struct _category_t { 4570/// const char * const name; 4571/// struct _class_t *const cls; 4572/// const struct _method_list_t * const instance_methods; 4573/// const struct _method_list_t * const class_methods; 4574/// const struct _protocol_list_t * const protocols; 4575/// const struct _prop_list_t * const properties; 4576/// } 4577/// 4578void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 4579 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 4580 const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 4581 std::string ExtCatName(Prefix + Interface->getNameAsString()+ 4582 "_$_" + OCD->getNameAsString()); 4583 std::string ExtClassName(getClassSymbolPrefix() + 4584 Interface->getNameAsString()); 4585 4586 std::vector<llvm::Constant*> Values(6); 4587 Values[0] = GetClassName(OCD->getIdentifier()); 4588 // meta-class entry symbol 4589 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 4590 if (Interface->hasAttr<WeakImportAttr>()) 4591 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 4592 4593 Values[1] = ClassGV; 4594 std::vector<llvm::Constant*> Methods; 4595 std::string MethodListName(Prefix); 4596 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 4597 "_$_" + OCD->getNameAsString(); 4598 4599 for (ObjCCategoryImplDecl::instmeth_iterator 4600 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 4601 // Instance methods should always be defined. 4602 Methods.push_back(GetMethodConstant(*i)); 4603 } 4604 4605 Values[2] = EmitMethodList(MethodListName, 4606 "__DATA, __objc_const", 4607 Methods); 4608 4609 MethodListName = Prefix; 4610 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 4611 OCD->getNameAsString(); 4612 Methods.clear(); 4613 for (ObjCCategoryImplDecl::classmeth_iterator 4614 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 4615 // Class methods should always be defined. 4616 Methods.push_back(GetMethodConstant(*i)); 4617 } 4618 4619 Values[3] = EmitMethodList(MethodListName, 4620 "__DATA, __objc_const", 4621 Methods); 4622 const ObjCCategoryDecl *Category = 4623 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 4624 if (Category) { 4625 llvm::SmallString<256> ExtName; 4626 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" 4627 << OCD->getName(); 4628 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 4629 + Interface->getName() + "_$_" 4630 + Category->getName(), 4631 Category->protocol_begin(), 4632 Category->protocol_end()); 4633 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 4634 OCD, Category, ObjCTypes); 4635 } else { 4636 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 4637 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 4638 } 4639 4640 llvm::Constant *Init = 4641 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 4642 Values); 4643 llvm::GlobalVariable *GCATV 4644 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy, 4645 false, 4646 llvm::GlobalValue::InternalLinkage, 4647 Init, 4648 ExtCatName); 4649 GCATV->setAlignment( 4650 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.CategorynfABITy)); 4651 GCATV->setSection("__DATA, __objc_const"); 4652 CGM.AddUsedGlobal(GCATV); 4653 DefinedCategories.push_back(GCATV); 4654 4655 // Determine if this category is also "non-lazy". 4656 if (ImplementationIsNonLazy(OCD)) 4657 DefinedNonLazyCategories.push_back(GCATV); 4658} 4659 4660/// GetMethodConstant - Return a struct objc_method constant for the 4661/// given method if it has been defined. The result is null if the 4662/// method has not been defined. The return value has type MethodPtrTy. 4663llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 4664 const ObjCMethodDecl *MD) { 4665 // FIXME: Use DenseMap::lookup 4666 llvm::Function *Fn = MethodDefinitions[MD]; 4667 if (!Fn) 4668 return 0; 4669 4670 std::vector<llvm::Constant*> Method(3); 4671 Method[0] = 4672 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 4673 ObjCTypes.SelectorPtrTy); 4674 Method[1] = GetMethodVarType(MD); 4675 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 4676 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 4677} 4678 4679/// EmitMethodList - Build meta-data for method declarations 4680/// struct _method_list_t { 4681/// uint32_t entsize; // sizeof(struct _objc_method) 4682/// uint32_t method_count; 4683/// struct _objc_method method_list[method_count]; 4684/// } 4685/// 4686llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name, 4687 const char *Section, 4688 const ConstantVector &Methods) { 4689 // Return null for empty list. 4690 if (Methods.empty()) 4691 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 4692 4693 std::vector<llvm::Constant*> Values(3); 4694 // sizeof(struct _objc_method) 4695 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 4696 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4697 // method_count 4698 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 4699 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 4700 Methods.size()); 4701 Values[2] = llvm::ConstantArray::get(AT, Methods); 4702 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 4703 4704 llvm::GlobalVariable *GV = 4705 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4706 llvm::GlobalValue::InternalLinkage, 4707 Init, 4708 Name); 4709 GV->setAlignment( 4710 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 4711 GV->setSection(Section); 4712 CGM.AddUsedGlobal(GV); 4713 return llvm::ConstantExpr::getBitCast(GV, 4714 ObjCTypes.MethodListnfABIPtrTy); 4715} 4716 4717/// ObjCIvarOffsetVariable - Returns the ivar offset variable for 4718/// the given ivar. 4719llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( 4720 const ObjCInterfaceDecl *ID, 4721 const ObjCIvarDecl *Ivar) { 4722 // FIXME: We shouldn't need to do this lookup. 4723 unsigned Index; 4724 const ObjCInterfaceDecl *Container = 4725 FindIvarInterface(CGM.getContext(), ID, Ivar, Index); 4726 assert(Container && "Unable to find ivar container!"); 4727 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 4728 '.' + Ivar->getNameAsString(); 4729 llvm::GlobalVariable *IvarOffsetGV = 4730 CGM.getModule().getGlobalVariable(Name); 4731 if (!IvarOffsetGV) 4732 IvarOffsetGV = 4733 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, 4734 false, 4735 llvm::GlobalValue::ExternalLinkage, 4736 0, 4737 Name); 4738 return IvarOffsetGV; 4739} 4740 4741llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( 4742 const ObjCInterfaceDecl *ID, 4743 const ObjCIvarDecl *Ivar, 4744 unsigned long int Offset) { 4745 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 4746 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 4747 Offset)); 4748 IvarOffsetGV->setAlignment( 4749 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy)); 4750 4751 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 4752 // well (i.e., in ObjCIvarOffsetVariable). 4753 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 4754 Ivar->getAccessControl() == ObjCIvarDecl::Package || 4755 CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden) 4756 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4757 else 4758 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 4759 IvarOffsetGV->setSection("__DATA, __objc_const"); 4760 return IvarOffsetGV; 4761} 4762 4763/// EmitIvarList - Emit the ivar list for the given 4764/// implementation. The return value has type 4765/// IvarListnfABIPtrTy. 4766/// struct _ivar_t { 4767/// unsigned long int *offset; // pointer to ivar offset location 4768/// char *name; 4769/// char *type; 4770/// uint32_t alignment; 4771/// uint32_t size; 4772/// } 4773/// struct _ivar_list_t { 4774/// uint32 entsize; // sizeof(struct _ivar_t) 4775/// uint32 count; 4776/// struct _iver_t list[count]; 4777/// } 4778/// 4779 4780llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 4781 const ObjCImplementationDecl *ID) { 4782 4783 std::vector<llvm::Constant*> Ivars, Ivar(5); 4784 4785 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4786 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 4787 4788 // FIXME. Consolidate this with similar code in GenerateClass. 4789 4790 // Collect declared and synthesized ivars in a small vector. 4791 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars; 4792 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars); 4793 4794 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { 4795 ObjCIvarDecl *IVD = OIvars[i]; 4796 // Ignore unnamed bit-fields. 4797 if (!IVD->getDeclName()) 4798 continue; 4799 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 4800 ComputeIvarBaseOffset(CGM, ID, IVD)); 4801 Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 4802 Ivar[2] = GetMethodVarType(IVD); 4803 const llvm::Type *FieldTy = 4804 CGM.getTypes().ConvertTypeForMem(IVD->getType()); 4805 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 4806 unsigned Align = CGM.getContext().getPreferredTypeAlign( 4807 IVD->getType().getTypePtr()) >> 3; 4808 Align = llvm::Log2_32(Align); 4809 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 4810 // NOTE. Size of a bitfield does not match gcc's, because of the 4811 // way bitfields are treated special in each. But I am told that 4812 // 'size' for bitfield ivars is ignored by the runtime so it does 4813 // not matter. If it matters, there is enough info to get the 4814 // bitfield right! 4815 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4816 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 4817 } 4818 // Return null for empty list. 4819 if (Ivars.empty()) 4820 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 4821 std::vector<llvm::Constant*> Values(3); 4822 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 4823 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4824 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 4825 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 4826 Ivars.size()); 4827 Values[2] = llvm::ConstantArray::get(AT, Ivars); 4828 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 4829 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 4830 llvm::GlobalVariable *GV = 4831 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4832 llvm::GlobalValue::InternalLinkage, 4833 Init, 4834 Prefix + OID->getName()); 4835 GV->setAlignment( 4836 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 4837 GV->setSection("__DATA, __objc_const"); 4838 4839 CGM.AddUsedGlobal(GV); 4840 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); 4841} 4842 4843llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 4844 const ObjCProtocolDecl *PD) { 4845 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 4846 4847 if (!Entry) { 4848 // We use the initializer as a marker of whether this is a forward 4849 // reference or not. At module finalization we add the empty 4850 // contents for protocols which were referenced but never defined. 4851 Entry = 4852 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, 4853 llvm::GlobalValue::ExternalLinkage, 4854 0, 4855 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 4856 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 4857 } 4858 4859 return Entry; 4860} 4861 4862/// GetOrEmitProtocol - Generate the protocol meta-data: 4863/// @code 4864/// struct _protocol_t { 4865/// id isa; // NULL 4866/// const char * const protocol_name; 4867/// const struct _protocol_list_t * protocol_list; // super protocols 4868/// const struct method_list_t * const instance_methods; 4869/// const struct method_list_t * const class_methods; 4870/// const struct method_list_t *optionalInstanceMethods; 4871/// const struct method_list_t *optionalClassMethods; 4872/// const struct _prop_list_t * properties; 4873/// const uint32_t size; // sizeof(struct _protocol_t) 4874/// const uint32_t flags; // = 0 4875/// } 4876/// @endcode 4877/// 4878 4879llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 4880 const ObjCProtocolDecl *PD) { 4881 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 4882 4883 // Early exit if a defining object has already been generated. 4884 if (Entry && Entry->hasInitializer()) 4885 return Entry; 4886 4887 // Construct method lists. 4888 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 4889 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 4890 for (ObjCProtocolDecl::instmeth_iterator 4891 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 4892 ObjCMethodDecl *MD = *i; 4893 llvm::Constant *C = GetMethodDescriptionConstant(MD); 4894 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 4895 OptInstanceMethods.push_back(C); 4896 } else { 4897 InstanceMethods.push_back(C); 4898 } 4899 } 4900 4901 for (ObjCProtocolDecl::classmeth_iterator 4902 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 4903 ObjCMethodDecl *MD = *i; 4904 llvm::Constant *C = GetMethodDescriptionConstant(MD); 4905 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 4906 OptClassMethods.push_back(C); 4907 } else { 4908 ClassMethods.push_back(C); 4909 } 4910 } 4911 4912 std::vector<llvm::Constant*> Values(10); 4913 // isa is NULL 4914 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 4915 Values[1] = GetClassName(PD->getIdentifier()); 4916 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), 4917 PD->protocol_begin(), 4918 PD->protocol_end()); 4919 4920 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 4921 + PD->getName(), 4922 "__DATA, __objc_const", 4923 InstanceMethods); 4924 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 4925 + PD->getName(), 4926 "__DATA, __objc_const", 4927 ClassMethods); 4928 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 4929 + PD->getName(), 4930 "__DATA, __objc_const", 4931 OptInstanceMethods); 4932 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 4933 + PD->getName(), 4934 "__DATA, __objc_const", 4935 OptClassMethods); 4936 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(), 4937 0, PD, ObjCTypes); 4938 uint32_t Size = 4939 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 4940 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4941 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 4942 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 4943 Values); 4944 4945 if (Entry) { 4946 // Already created, fix the linkage and update the initializer. 4947 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 4948 Entry->setInitializer(Init); 4949 } else { 4950 Entry = 4951 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 4952 false, llvm::GlobalValue::WeakAnyLinkage, Init, 4953 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 4954 Entry->setAlignment( 4955 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABITy)); 4956 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 4957 } 4958 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 4959 CGM.AddUsedGlobal(Entry); 4960 4961 // Use this protocol meta-data to build protocol list table in section 4962 // __DATA, __objc_protolist 4963 llvm::GlobalVariable *PTGV = 4964 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 4965 false, llvm::GlobalValue::WeakAnyLinkage, Entry, 4966 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName()); 4967 PTGV->setAlignment( 4968 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 4969 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 4970 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4971 CGM.AddUsedGlobal(PTGV); 4972 return Entry; 4973} 4974 4975/// EmitProtocolList - Generate protocol list meta-data: 4976/// @code 4977/// struct _protocol_list_t { 4978/// long protocol_count; // Note, this is 32/64 bit 4979/// struct _protocol_t[protocol_count]; 4980/// } 4981/// @endcode 4982/// 4983llvm::Constant * 4984CGObjCNonFragileABIMac::EmitProtocolList(llvm::Twine Name, 4985 ObjCProtocolDecl::protocol_iterator begin, 4986 ObjCProtocolDecl::protocol_iterator end) { 4987 std::vector<llvm::Constant*> ProtocolRefs; 4988 4989 // Just return null for empty protocol lists 4990 if (begin == end) 4991 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 4992 4993 // FIXME: We shouldn't need to do this lookup here, should we? 4994 llvm::SmallString<256> TmpName; 4995 Name.toVector(TmpName); 4996 llvm::GlobalVariable *GV = 4997 CGM.getModule().getGlobalVariable(TmpName.str(), true); 4998 if (GV) 4999 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); 5000 5001 for (; begin != end; ++begin) 5002 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 5003 5004 // This list is null terminated. 5005 ProtocolRefs.push_back(llvm::Constant::getNullValue( 5006 ObjCTypes.ProtocolnfABIPtrTy)); 5007 5008 std::vector<llvm::Constant*> Values(2); 5009 Values[0] = 5010 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 5011 Values[1] = 5012 llvm::ConstantArray::get( 5013 llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 5014 ProtocolRefs.size()), 5015 ProtocolRefs); 5016 5017 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 5018 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5019 llvm::GlobalValue::InternalLinkage, 5020 Init, 5021 Name); 5022 GV->setSection("__DATA, __objc_const"); 5023 GV->setAlignment( 5024 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 5025 CGM.AddUsedGlobal(GV); 5026 return llvm::ConstantExpr::getBitCast(GV, 5027 ObjCTypes.ProtocolListnfABIPtrTy); 5028} 5029 5030/// GetMethodDescriptionConstant - This routine build following meta-data: 5031/// struct _objc_method { 5032/// SEL _cmd; 5033/// char *method_type; 5034/// char *_imp; 5035/// } 5036 5037llvm::Constant * 5038CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 5039 std::vector<llvm::Constant*> Desc(3); 5040 Desc[0] = 5041 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 5042 ObjCTypes.SelectorPtrTy); 5043 Desc[1] = GetMethodVarType(MD); 5044 // Protocol methods have no implementation. So, this entry is always NULL. 5045 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 5046 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 5047} 5048 5049/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 5050/// This code gen. amounts to generating code for: 5051/// @code 5052/// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 5053/// @encode 5054/// 5055LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 5056 CodeGen::CodeGenFunction &CGF, 5057 QualType ObjectTy, 5058 llvm::Value *BaseValue, 5059 const ObjCIvarDecl *Ivar, 5060 unsigned CVRQualifiers) { 5061 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl(); 5062 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 5063 EmitIvarOffset(CGF, ID, Ivar)); 5064} 5065 5066llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 5067 CodeGen::CodeGenFunction &CGF, 5068 const ObjCInterfaceDecl *Interface, 5069 const ObjCIvarDecl *Ivar) { 5070 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); 5071} 5072 5073CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( 5074 CodeGen::CodeGenFunction &CGF, 5075 QualType ResultType, 5076 Selector Sel, 5077 llvm::Value *Receiver, 5078 QualType Arg0Ty, 5079 bool IsSuper, 5080 const CallArgList &CallArgs) { 5081 // FIXME. Even though IsSuper is passes. This function doese not handle calls 5082 // to 'super' receivers. 5083 CodeGenTypes &Types = CGM.getTypes(); 5084 llvm::Value *Arg0 = Receiver; 5085 if (!IsSuper) 5086 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp"); 5087 5088 // Find the message function name. 5089 // FIXME. This is too much work to get the ABI-specific result type needed to 5090 // find the message name. 5091 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, 5092 llvm::SmallVector<QualType, 16>()); 5093 llvm::Constant *Fn = 0; 5094 std::string Name("\01l_"); 5095 if (CGM.ReturnTypeUsesSret(FnInfo)) { 5096#if 0 5097 // unlike what is documented. gcc never generates this API!! 5098 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) { 5099 Fn = ObjCTypes.getMessageSendIdStretFixupFn(); 5100 // FIXME. Is there a better way of getting these names. 5101 // They are available in RuntimeFunctions vector pair. 5102 Name += "objc_msgSendId_stret_fixup"; 5103 } else 5104#endif 5105 if (IsSuper) { 5106 Fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 5107 Name += "objc_msgSendSuper2_stret_fixup"; 5108 } else { 5109 Fn = ObjCTypes.getMessageSendStretFixupFn(); 5110 Name += "objc_msgSend_stret_fixup"; 5111 } 5112 } else if (!IsSuper && ResultType->isFloatingType()) { 5113 if (ResultType->isSpecificBuiltinType(BuiltinType::LongDouble)) { 5114 Fn = ObjCTypes.getMessageSendFpretFixupFn(); 5115 Name += "objc_msgSend_fpret_fixup"; 5116 } else { 5117 Fn = ObjCTypes.getMessageSendFixupFn(); 5118 Name += "objc_msgSend_fixup"; 5119 } 5120 } else { 5121#if 0 5122// unlike what is documented. gcc never generates this API!! 5123 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) { 5124 Fn = ObjCTypes.getMessageSendIdFixupFn(); 5125 Name += "objc_msgSendId_fixup"; 5126 } else 5127#endif 5128 if (IsSuper) { 5129 Fn = ObjCTypes.getMessageSendSuper2FixupFn(); 5130 Name += "objc_msgSendSuper2_fixup"; 5131 } else { 5132 Fn = ObjCTypes.getMessageSendFixupFn(); 5133 Name += "objc_msgSend_fixup"; 5134 } 5135 } 5136 assert(Fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 5137 Name += '_'; 5138 std::string SelName(Sel.getAsString()); 5139 // Replace all ':' in selector name with '_' ouch! 5140 for (unsigned i = 0; i < SelName.size(); i++) 5141 if (SelName[i] == ':') 5142 SelName[i] = '_'; 5143 Name += SelName; 5144 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 5145 if (!GV) { 5146 // Build message ref table entry. 5147 std::vector<llvm::Constant*> Values(2); 5148 Values[0] = Fn; 5149 Values[1] = GetMethodVarName(Sel); 5150 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 5151 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5152 llvm::GlobalValue::WeakAnyLinkage, 5153 Init, 5154 Name); 5155 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5156 GV->setAlignment(16); 5157 GV->setSection("__DATA, __objc_msgrefs, coalesced"); 5158 } 5159 llvm::Value *Arg1 = CGF.Builder.CreateBitCast(GV, ObjCTypes.MessageRefPtrTy); 5160 5161 CallArgList ActualArgs; 5162 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 5163 ActualArgs.push_back(std::make_pair(RValue::get(Arg1), 5164 ObjCTypes.MessageRefCPtrTy)); 5165 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 5166 const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs); 5167 llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0); 5168 Callee = CGF.Builder.CreateLoad(Callee); 5169 const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true); 5170 Callee = CGF.Builder.CreateBitCast(Callee, 5171 llvm::PointerType::getUnqual(FTy)); 5172 return CGF.EmitCall(FnInfo1, Callee, ReturnValueSlot(), ActualArgs); 5173} 5174 5175/// Generate code for a message send expression in the nonfragile abi. 5176CodeGen::RValue 5177CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 5178 QualType ResultType, 5179 Selector Sel, 5180 llvm::Value *Receiver, 5181 bool IsClassMessage, 5182 const CallArgList &CallArgs, 5183 const ObjCMethodDecl *Method) { 5184 return LegacyDispatchedSelector(Sel) 5185 ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel), 5186 Receiver, CGF.getContext().getObjCIdType(), 5187 false, CallArgs, Method, ObjCTypes) 5188 : EmitMessageSend(CGF, ResultType, Sel, 5189 Receiver, CGF.getContext().getObjCIdType(), 5190 false, CallArgs); 5191} 5192 5193llvm::GlobalVariable * 5194CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 5195 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 5196 5197 if (!GV) { 5198 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, 5199 false, llvm::GlobalValue::ExternalLinkage, 5200 0, Name); 5201 } 5202 5203 return GV; 5204} 5205 5206llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 5207 const ObjCInterfaceDecl *ID) { 5208 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 5209 5210 if (!Entry) { 5211 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5212 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5213 Entry = 5214 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5215 false, llvm::GlobalValue::InternalLinkage, 5216 ClassGV, 5217 "\01L_OBJC_CLASSLIST_REFERENCES_$_"); 5218 Entry->setAlignment( 5219 CGM.getTargetData().getPrefTypeAlignment( 5220 ObjCTypes.ClassnfABIPtrTy)); 5221 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 5222 CGM.AddUsedGlobal(Entry); 5223 } 5224 5225 return Builder.CreateLoad(Entry, "tmp"); 5226} 5227 5228llvm::Value * 5229CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 5230 const ObjCInterfaceDecl *ID) { 5231 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 5232 5233 if (!Entry) { 5234 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5235 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5236 Entry = 5237 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5238 false, llvm::GlobalValue::InternalLinkage, 5239 ClassGV, 5240 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 5241 Entry->setAlignment( 5242 CGM.getTargetData().getPrefTypeAlignment( 5243 ObjCTypes.ClassnfABIPtrTy)); 5244 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5245 CGM.AddUsedGlobal(Entry); 5246 } 5247 5248 return Builder.CreateLoad(Entry, "tmp"); 5249} 5250 5251/// EmitMetaClassRef - Return a Value * of the address of _class_t 5252/// meta-data 5253/// 5254llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 5255 const ObjCInterfaceDecl *ID) { 5256 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 5257 if (Entry) 5258 return Builder.CreateLoad(Entry, "tmp"); 5259 5260 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 5261 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 5262 Entry = 5263 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, 5264 llvm::GlobalValue::InternalLinkage, 5265 MetaClassGV, 5266 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 5267 Entry->setAlignment( 5268 CGM.getTargetData().getPrefTypeAlignment( 5269 ObjCTypes.ClassnfABIPtrTy)); 5270 5271 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5272 CGM.AddUsedGlobal(Entry); 5273 5274 return Builder.CreateLoad(Entry, "tmp"); 5275} 5276 5277/// GetClass - Return a reference to the class for the given interface 5278/// decl. 5279llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 5280 const ObjCInterfaceDecl *ID) { 5281 if (ID->hasAttr<WeakImportAttr>()) { 5282 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5283 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5284 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5285 } 5286 5287 return EmitClassRef(Builder, ID); 5288} 5289 5290/// Generates a message send where the super is the receiver. This is 5291/// a message send to self with special delivery semantics indicating 5292/// which class's method should be called. 5293CodeGen::RValue 5294CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 5295 QualType ResultType, 5296 Selector Sel, 5297 const ObjCInterfaceDecl *Class, 5298 bool isCategoryImpl, 5299 llvm::Value *Receiver, 5300 bool IsClassMessage, 5301 const CodeGen::CallArgList &CallArgs, 5302 const ObjCMethodDecl *Method) { 5303 // ... 5304 // Create and init a super structure; this is a (receiver, class) 5305 // pair we will pass to objc_msgSendSuper. 5306 llvm::Value *ObjCSuper = 5307 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 5308 5309 llvm::Value *ReceiverAsObject = 5310 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 5311 CGF.Builder.CreateStore(ReceiverAsObject, 5312 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 5313 5314 // If this is a class message the metaclass is passed as the target. 5315 llvm::Value *Target; 5316 if (IsClassMessage) { 5317 if (isCategoryImpl) { 5318 // Message sent to "super' in a class method defined in 5319 // a category implementation. 5320 Target = EmitClassRef(CGF.Builder, Class); 5321 Target = CGF.Builder.CreateStructGEP(Target, 0); 5322 Target = CGF.Builder.CreateLoad(Target); 5323 } else 5324 Target = EmitMetaClassRef(CGF.Builder, Class); 5325 } else 5326 Target = EmitSuperClassRef(CGF.Builder, Class); 5327 5328 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 5329 // ObjCTypes types. 5330 const llvm::Type *ClassTy = 5331 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 5332 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 5333 CGF.Builder.CreateStore(Target, 5334 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 5335 5336 return (LegacyDispatchedSelector(Sel)) 5337 ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel), 5338 ObjCSuper, ObjCTypes.SuperPtrCTy, 5339 true, CallArgs, Method, ObjCTypes) 5340 : EmitMessageSend(CGF, ResultType, Sel, 5341 ObjCSuper, ObjCTypes.SuperPtrCTy, 5342 true, CallArgs); 5343} 5344 5345llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 5346 Selector Sel) { 5347 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5348 5349 if (!Entry) { 5350 llvm::Constant *Casted = 5351 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5352 ObjCTypes.SelectorPtrTy); 5353 Entry = 5354 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 5355 llvm::GlobalValue::InternalLinkage, 5356 Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); 5357 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 5358 CGM.AddUsedGlobal(Entry); 5359 } 5360 5361 return Builder.CreateLoad(Entry, "tmp"); 5362} 5363/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 5364/// objc_assign_ivar (id src, id *dst, ptrdiff_t) 5365/// 5366void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 5367 llvm::Value *src, 5368 llvm::Value *dst, 5369 llvm::Value *ivarOffset) { 5370 const llvm::Type * SrcTy = src->getType(); 5371 if (!isa<llvm::PointerType>(SrcTy)) { 5372 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5373 assert(Size <= 8 && "does not support size > 8"); 5374 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5375 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5376 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5377 } 5378 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5379 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5380 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 5381 src, dst, ivarOffset); 5382 return; 5383} 5384 5385/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 5386/// objc_assign_strongCast (id src, id *dst) 5387/// 5388void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 5389 CodeGen::CodeGenFunction &CGF, 5390 llvm::Value *src, llvm::Value *dst) { 5391 const llvm::Type * SrcTy = src->getType(); 5392 if (!isa<llvm::PointerType>(SrcTy)) { 5393 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5394 assert(Size <= 8 && "does not support size > 8"); 5395 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5396 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5397 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5398 } 5399 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5400 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5401 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 5402 src, dst, "weakassign"); 5403 return; 5404} 5405 5406void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 5407 CodeGen::CodeGenFunction &CGF, 5408 llvm::Value *DestPtr, 5409 llvm::Value *SrcPtr, 5410 QualType Ty) { 5411 // Get size info for this aggregate. 5412 std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty); 5413 unsigned long size = TypeInfo.first/8; 5414 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 5415 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 5416 llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size); 5417 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 5418 DestPtr, SrcPtr, N); 5419 return; 5420} 5421 5422/// EmitObjCWeakRead - Code gen for loading value of a __weak 5423/// object: objc_read_weak (id *src) 5424/// 5425llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 5426 CodeGen::CodeGenFunction &CGF, 5427 llvm::Value *AddrWeakObj) { 5428 const llvm::Type* DestTy = 5429 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 5430 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 5431 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 5432 AddrWeakObj, "weakread"); 5433 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 5434 return read_weak; 5435} 5436 5437/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 5438/// objc_assign_weak (id src, id *dst) 5439/// 5440void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 5441 llvm::Value *src, llvm::Value *dst) { 5442 const llvm::Type * SrcTy = src->getType(); 5443 if (!isa<llvm::PointerType>(SrcTy)) { 5444 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5445 assert(Size <= 8 && "does not support size > 8"); 5446 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5447 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5448 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5449 } 5450 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5451 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5452 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 5453 src, dst, "weakassign"); 5454 return; 5455} 5456 5457/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 5458/// objc_assign_global (id src, id *dst) 5459/// 5460void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 5461 llvm::Value *src, llvm::Value *dst) { 5462 const llvm::Type * SrcTy = src->getType(); 5463 if (!isa<llvm::PointerType>(SrcTy)) { 5464 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5465 assert(Size <= 8 && "does not support size > 8"); 5466 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5467 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5468 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5469 } 5470 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5471 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5472 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 5473 src, dst, "globalassign"); 5474 return; 5475} 5476 5477void 5478CGObjCNonFragileABIMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 5479 const Stmt &S) { 5480 bool isTry = isa<ObjCAtTryStmt>(S); 5481 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 5482 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 5483 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 5484 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 5485 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 5486 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 5487 5488 // For @synchronized, call objc_sync_enter(sync.expr). The 5489 // evaluation of the expression must occur before we enter the 5490 // @synchronized. We can safely avoid a temp here because jumps into 5491 // @synchronized are illegal & this will dominate uses. 5492 llvm::Value *SyncArg = 0; 5493 if (!isTry) { 5494 SyncArg = 5495 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 5496 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 5497 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg); 5498 } 5499 5500 // Push an EH context entry, used for handling rethrows and jumps 5501 // through finally. 5502 CGF.PushCleanupBlock(FinallyBlock); 5503 5504 CGF.setInvokeDest(TryHandler); 5505 5506 CGF.EmitBlock(TryBlock); 5507 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 5508 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 5509 CGF.EmitBranchThroughCleanup(FinallyEnd); 5510 5511 // Emit the exception handler. 5512 5513 CGF.EmitBlock(TryHandler); 5514 5515 llvm::Value *llvm_eh_exception = 5516 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 5517 llvm::Value *llvm_eh_selector = 5518 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 5519 llvm::Value *llvm_eh_typeid_for = 5520 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 5521 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5522 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 5523 5524 llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 5525 SelectorArgs.push_back(Exc); 5526 SelectorArgs.push_back(ObjCTypes.getEHPersonalityPtr()); 5527 5528 // Construct the lists of (type, catch body) to handle. 5529 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 5530 bool HasCatchAll = false; 5531 if (isTry) { 5532 if (const ObjCAtCatchStmt* CatchStmt = 5533 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 5534 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 5535 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 5536 Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody())); 5537 5538 // catch(...) always matches. 5539 if (!CatchDecl) { 5540 // Use i8* null here to signal this is a catch all, not a cleanup. 5541 llvm::Value *Null = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 5542 SelectorArgs.push_back(Null); 5543 HasCatchAll = true; 5544 break; 5545 } 5546 5547 if (CatchDecl->getType()->isObjCIdType() || 5548 CatchDecl->getType()->isObjCQualifiedIdType()) { 5549 llvm::Value *IDEHType = 5550 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 5551 if (!IDEHType) 5552 IDEHType = 5553 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 5554 false, 5555 llvm::GlobalValue::ExternalLinkage, 5556 0, "OBJC_EHTYPE_id"); 5557 SelectorArgs.push_back(IDEHType); 5558 } else { 5559 // All other types should be Objective-C interface pointer types. 5560 const ObjCObjectPointerType *PT = 5561 CatchDecl->getType()->getAs<ObjCObjectPointerType>(); 5562 assert(PT && "Invalid @catch type."); 5563 const ObjCInterfaceType *IT = PT->getInterfaceType(); 5564 assert(IT && "Invalid @catch type."); 5565 llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false); 5566 SelectorArgs.push_back(EHType); 5567 } 5568 } 5569 } 5570 } 5571 5572 // We use a cleanup unless there was already a catch all. 5573 if (!HasCatchAll) { 5574 // Even though this is a cleanup, treat it as a catch all to avoid the C++ 5575 // personality behavior of terminating the process if only cleanups are 5576 // found in the exception handling stack. 5577 SelectorArgs.push_back(llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy)); 5578 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 5579 } 5580 5581 llvm::Value *Selector = 5582 CGF.Builder.CreateCall(llvm_eh_selector, 5583 SelectorArgs.begin(), SelectorArgs.end(), 5584 "selector"); 5585 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 5586 const ParmVarDecl *CatchParam = Handlers[i].first; 5587 const Stmt *CatchBody = Handlers[i].second; 5588 5589 llvm::BasicBlock *Next = 0; 5590 5591 // The last handler always matches. 5592 if (i + 1 != e) { 5593 assert(CatchParam && "Only last handler can be a catch all."); 5594 5595 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 5596 Next = CGF.createBasicBlock("catch.next"); 5597 llvm::Value *Id = 5598 CGF.Builder.CreateCall(llvm_eh_typeid_for, 5599 CGF.Builder.CreateBitCast(SelectorArgs[i+2], 5600 ObjCTypes.Int8PtrTy)); 5601 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(Selector, Id), 5602 Match, Next); 5603 5604 CGF.EmitBlock(Match); 5605 } 5606 5607 if (CatchBody) { 5608 llvm::BasicBlock *MatchEnd = CGF.createBasicBlock("match.end"); 5609 llvm::BasicBlock *MatchHandler = CGF.createBasicBlock("match.handler"); 5610 5611 // Cleanups must call objc_end_catch. 5612 // 5613 // FIXME: It seems incorrect for objc_begin_catch to be inside this 5614 // context, but this matches gcc. 5615 CGF.PushCleanupBlock(MatchEnd); 5616 CGF.setInvokeDest(MatchHandler); 5617 5618 llvm::Value *ExcObject = 5619 CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), Exc); 5620 5621 // Bind the catch parameter if it exists. 5622 if (CatchParam) { 5623 ExcObject = 5624 CGF.Builder.CreateBitCast(ExcObject, 5625 CGF.ConvertType(CatchParam->getType())); 5626 // CatchParam is a ParmVarDecl because of the grammar 5627 // construction used to handle this, but for codegen purposes 5628 // we treat this as a local decl. 5629 CGF.EmitLocalBlockVarDecl(*CatchParam); 5630 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 5631 } 5632 5633 CGF.ObjCEHValueStack.push_back(ExcObject); 5634 CGF.EmitStmt(CatchBody); 5635 CGF.ObjCEHValueStack.pop_back(); 5636 5637 CGF.EmitBranchThroughCleanup(FinallyEnd); 5638 5639 CGF.EmitBlock(MatchHandler); 5640 5641 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5642 // We are required to emit this call to satisfy LLVM, even 5643 // though we don't use the result. 5644 llvm::SmallVector<llvm::Value*, 8> Args; 5645 Args.push_back(Exc); 5646 Args.push_back(ObjCTypes.getEHPersonalityPtr()); 5647 Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 5648 0)); 5649 CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 5650 CGF.Builder.CreateStore(Exc, RethrowPtr); 5651 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5652 5653 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 5654 5655 CGF.EmitBlock(MatchEnd); 5656 5657 // Unfortunately, we also have to generate another EH frame here 5658 // in case this throws. 5659 llvm::BasicBlock *MatchEndHandler = 5660 CGF.createBasicBlock("match.end.handler"); 5661 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); 5662 CGF.Builder.CreateInvoke(ObjCTypes.getObjCEndCatchFn(), 5663 Cont, MatchEndHandler, 5664 Args.begin(), Args.begin()); 5665 5666 CGF.EmitBlock(Cont); 5667 if (Info.SwitchBlock) 5668 CGF.EmitBlock(Info.SwitchBlock); 5669 if (Info.EndBlock) 5670 CGF.EmitBlock(Info.EndBlock); 5671 5672 CGF.EmitBlock(MatchEndHandler); 5673 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5674 // We are required to emit this call to satisfy LLVM, even 5675 // though we don't use the result. 5676 Args.clear(); 5677 Args.push_back(Exc); 5678 Args.push_back(ObjCTypes.getEHPersonalityPtr()); 5679 Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 5680 0)); 5681 CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 5682 CGF.Builder.CreateStore(Exc, RethrowPtr); 5683 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5684 5685 if (Next) 5686 CGF.EmitBlock(Next); 5687 } else { 5688 assert(!Next && "catchup should be last handler."); 5689 5690 CGF.Builder.CreateStore(Exc, RethrowPtr); 5691 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5692 } 5693 } 5694 5695 // Pop the cleanup entry, the @finally is outside this cleanup 5696 // scope. 5697 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 5698 CGF.setInvokeDest(PrevLandingPad); 5699 5700 CGF.EmitBlock(FinallyBlock); 5701 5702 if (isTry) { 5703 if (const ObjCAtFinallyStmt* FinallyStmt = 5704 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 5705 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 5706 } else { 5707 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 5708 // @synchronized. 5709 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg); 5710 } 5711 5712 if (Info.SwitchBlock) 5713 CGF.EmitBlock(Info.SwitchBlock); 5714 if (Info.EndBlock) 5715 CGF.EmitBlock(Info.EndBlock); 5716 5717 // Branch around the rethrow code. 5718 CGF.EmitBranch(FinallyEnd); 5719 5720 CGF.EmitBlock(FinallyRethrow); 5721 CGF.Builder.CreateCall(ObjCTypes.getUnwindResumeOrRethrowFn(), 5722 CGF.Builder.CreateLoad(RethrowPtr)); 5723 CGF.Builder.CreateUnreachable(); 5724 5725 CGF.EmitBlock(FinallyEnd); 5726} 5727 5728/// EmitThrowStmt - Generate code for a throw statement. 5729void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 5730 const ObjCAtThrowStmt &S) { 5731 llvm::Value *Exception; 5732 if (const Expr *ThrowExpr = S.getThrowExpr()) { 5733 Exception = CGF.EmitScalarExpr(ThrowExpr); 5734 } else { 5735 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 5736 "Unexpected rethrow outside @catch block."); 5737 Exception = CGF.ObjCEHValueStack.back(); 5738 } 5739 5740 llvm::Value *ExceptionAsObject = 5741 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 5742 llvm::BasicBlock *InvokeDest = CGF.getInvokeDest(); 5743 if (InvokeDest) { 5744 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); 5745 CGF.Builder.CreateInvoke(ObjCTypes.getExceptionThrowFn(), 5746 Cont, InvokeDest, 5747 &ExceptionAsObject, &ExceptionAsObject + 1); 5748 CGF.EmitBlock(Cont); 5749 } else 5750 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject); 5751 CGF.Builder.CreateUnreachable(); 5752 5753 // Clear the insertion point to indicate we are in unreachable code. 5754 CGF.Builder.ClearInsertionPoint(); 5755} 5756 5757llvm::Value * 5758CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 5759 bool ForDefinition) { 5760 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 5761 5762 // If we don't need a definition, return the entry if found or check 5763 // if we use an external reference. 5764 if (!ForDefinition) { 5765 if (Entry) 5766 return Entry; 5767 5768 // If this type (or a super class) has the __objc_exception__ 5769 // attribute, emit an external reference. 5770 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 5771 return Entry = 5772 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 5773 llvm::GlobalValue::ExternalLinkage, 5774 0, 5775 ("OBJC_EHTYPE_$_" + 5776 ID->getIdentifier()->getName())); 5777 } 5778 5779 // Otherwise we need to either make a new entry or fill in the 5780 // initializer. 5781 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 5782 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5783 std::string VTableName = "objc_ehtype_vtable"; 5784 llvm::GlobalVariable *VTableGV = 5785 CGM.getModule().getGlobalVariable(VTableName); 5786 if (!VTableGV) 5787 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, 5788 false, 5789 llvm::GlobalValue::ExternalLinkage, 5790 0, VTableName); 5791 5792 llvm::Value *VTableIdx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2); 5793 5794 std::vector<llvm::Constant*> Values(3); 5795 Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1); 5796 Values[1] = GetClassName(ID->getIdentifier()); 5797 Values[2] = GetClassGlobal(ClassName); 5798 llvm::Constant *Init = 5799 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 5800 5801 if (Entry) { 5802 Entry->setInitializer(Init); 5803 } else { 5804 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 5805 llvm::GlobalValue::WeakAnyLinkage, 5806 Init, 5807 ("OBJC_EHTYPE_$_" + 5808 ID->getIdentifier()->getName())); 5809 } 5810 5811 if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden) 5812 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 5813 Entry->setAlignment(8); 5814 5815 if (ForDefinition) { 5816 Entry->setSection("__DATA,__objc_const"); 5817 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 5818 } else { 5819 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5820 } 5821 5822 return Entry; 5823} 5824 5825/* *** */ 5826 5827CodeGen::CGObjCRuntime * 5828CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 5829 return new CGObjCMac(CGM); 5830} 5831 5832CodeGen::CGObjCRuntime * 5833CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { 5834 return new CGObjCNonFragileABIMac(CGM); 5835} 5836