CGObjCGNU.cpp revision 202879
1229109Sed//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// 2229109Sed// 3229109Sed// The LLVM Compiler Infrastructure 4229109Sed// 5229109Sed// This file is distributed under the University of Illinois Open Source 6229109Sed// License. See LICENSE.TXT for details. 7229109Sed// 8229109Sed//===----------------------------------------------------------------------===// 9229109Sed// 10229109Sed// This provides Objective-C code generation targetting the GNU runtime. The 11229109Sed// class in this file generates structures used by the GNU Objective-C runtime 12229109Sed// library. These structures are defined in objc/objc.h and objc/objc-api.h in 13229109Sed// the GNU runtime distribution. 14229109Sed// 15229109Sed//===----------------------------------------------------------------------===// 16229109Sed 17229109Sed#include "CGObjCRuntime.h" 18229109Sed#include "CodeGenModule.h" 19229109Sed#include "CodeGenFunction.h" 20296417Sdim 21251034Sed#include "clang/AST/ASTContext.h" 22251034Sed#include "clang/AST/Decl.h" 23251034Sed#include "clang/AST/DeclObjC.h" 24251034Sed#include "clang/AST/RecordLayout.h" 25251034Sed#include "clang/AST/StmtObjC.h" 26251034Sed 27251034Sed#include "llvm/Intrinsics.h" 28251034Sed#include "llvm/Module.h" 29251034Sed#include "llvm/ADT/SmallVector.h" 30251034Sed#include "llvm/ADT/StringMap.h" 31251034Sed#include "llvm/Support/Compiler.h" 32251034Sed#include "llvm/Target/TargetData.h" 33251034Sed 34251034Sed#include <map> 35251034Sed 36251034Sed 37251034Sedusing namespace clang; 38251034Sedusing namespace CodeGen; 39251034Sedusing llvm::dyn_cast; 40251034Sed 41251034Sed// The version of the runtime that this class targets. Must match the version 42251034Sed// in the runtime. 43251034Sedstatic const int RuntimeVersion = 8; 44251034Sedstatic const int NonFragileRuntimeVersion = 9; 45251034Sedstatic const int ProtocolVersion = 2; 46276789Sdimstatic const int NonFragileProtocolVersion = 3; 47251034Sed 48251034Sednamespace { 49251034Sedclass CGObjCGNU : public CodeGen::CGObjCRuntime { 50251034Sedprivate: 51251034Sed CodeGen::CodeGenModule &CGM; 52274201Sdim llvm::Module &TheModule; 53276789Sdim const llvm::PointerType *SelectorTy; 54276789Sdim const llvm::IntegerType *Int8Ty; 55276789Sdim const llvm::PointerType *PtrToInt8Ty; 56276789Sdim const llvm::FunctionType *IMPTy; 57276789Sdim const llvm::PointerType *IdTy; 58276789Sdim QualType ASTIdTy; 59276789Sdim const llvm::IntegerType *IntTy; 60276789Sdim const llvm::PointerType *PtrTy; 61276789Sdim const llvm::IntegerType *LongTy; 62280031Sdim const llvm::PointerType *PtrToIntTy; 63276789Sdim llvm::GlobalAlias *ClassPtrAlias; 64276789Sdim llvm::GlobalAlias *MetaClassPtrAlias; 65276789Sdim std::vector<llvm::Constant*> Classes; 66276789Sdim std::vector<llvm::Constant*> Categories; 67276789Sdim std::vector<llvm::Constant*> ConstantStrings; 68276789Sdim llvm::Function *LoadFunction; 69280031Sdim llvm::StringMap<llvm::Constant*> ExistingProtocols; 70280031Sdim typedef std::pair<std::string, std::string> TypedSelector; 71280031Sdim std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors; 72280031Sdim llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors; 73280031Sdim // Some zeros used for GEPs in lots of places. 74280031Sdim llvm::Constant *Zeros[2]; 75280031Sdim llvm::Constant *NULLPtr; 76296417Sdim llvm::LLVMContext &VMContext; 77296417Sdimprivate: 78296417Sdim llvm::Constant *GenerateIvarList( 79296417Sdim const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 80296417Sdim const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 81296417Sdim const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets); 82296417Sdim llvm::Constant *GenerateMethodList(const std::string &ClassName, 83296417Sdim const std::string &CategoryName, 84296417Sdim const llvm::SmallVectorImpl<Selector> &MethodSels, 85296417Sdim const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 86296417Sdim bool isClassMethodList); 87296417Sdim llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName); 88296417Sdim llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID, 89296417Sdim llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 90276789Sdim llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes); 91276789Sdim llvm::Constant *GenerateProtocolList( 92276789Sdim const llvm::SmallVectorImpl<std::string> &Protocols); 93276789Sdim // To ensure that all protocols are seen by the runtime, we add a category on 94276789Sdim // a class defined in the runtime, declaring no methods, but adopting the 95276789Sdim // protocols. 96276789Sdim void GenerateProtocolHolderCategory(void); 97276789Sdim llvm::Constant *GenerateClassStructure( 98276789Sdim llvm::Constant *MetaClass, 99276789Sdim llvm::Constant *SuperClass, 100276789Sdim unsigned info, 101276789Sdim const char *Name, 102276789Sdim llvm::Constant *Version, 103280031Sdim llvm::Constant *InstanceSize, 104280031Sdim llvm::Constant *IVars, 105280031Sdim llvm::Constant *Methods, 106280031Sdim llvm::Constant *Protocols, 107280031Sdim llvm::Constant *IvarOffsets, 108280031Sdim llvm::Constant *Properties); 109280031Sdim llvm::Constant *GenerateProtocolMethodList( 110280031Sdim const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 111280031Sdim const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes); 112229109Sed llvm::Constant *MakeConstantString(const std::string &Str, const std::string 113274201Sdim &Name=""); 114276789Sdim llvm::Constant *ExportUniqueString(const std::string &Str, const std::string 115274201Sdim prefix); 116274201Sdim llvm::Constant *MakeGlobal(const llvm::StructType *Ty, 117288943Sdim std::vector<llvm::Constant*> &V, const std::string &Name="", 118288943Sdim llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage); 119288943Sdim llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty, 120288943Sdim std::vector<llvm::Constant*> &V, const std::string &Name="", 121276789Sdim llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage); 122276789Sdim llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 123280031Sdim const ObjCIvarDecl *Ivar); 124274201Sdim void EmitClassRef(const std::string &className); 125276789Sdimpublic: 126276789Sdim CGObjCGNU(CodeGen::CodeGenModule &cgm); 127280031Sdim virtual llvm::Constant *GenerateConstantString(const StringLiteral *); 128274201Sdim virtual CodeGen::RValue 129276789Sdim GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 130296417Sdim QualType ResultType, 131296417Sdim Selector Sel, 132296417Sdim llvm::Value *Receiver, 133296417Sdim bool IsClassMessage, 134296417Sdim const CallArgList &CallArgs, 135296417Sdim const ObjCMethodDecl *Method); 136276789Sdim virtual CodeGen::RValue 137276789Sdim GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 138276789Sdim QualType ResultType, 139288943Sdim Selector Sel, 140288943Sdim const ObjCInterfaceDecl *Class, 141288943Sdim bool isCategoryImpl, 142288943Sdim llvm::Value *Receiver, 143280031Sdim bool IsClassMessage, 144280031Sdim const CallArgList &CallArgs, 145276789Sdim const ObjCMethodDecl *Method); 146280031Sdim virtual llvm::Value *GetClass(CGBuilderTy &Builder, 147276789Sdim const ObjCInterfaceDecl *OID); 148296417Sdim virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 149276789Sdim virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 150276789Sdim *Method); 151276789Sdim 152276789Sdim virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 153276789Sdim const ObjCContainerDecl *CD); 154276789Sdim virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 155276789Sdim virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 156276789Sdim virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 157276789Sdim const ObjCProtocolDecl *PD); 158276789Sdim virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 159288943Sdim virtual llvm::Function *ModuleInitFunction(); 160288943Sdim virtual llvm::Function *GetPropertyGetFunction(); 161288943Sdim virtual llvm::Function *GetPropertySetFunction(); 162288943Sdim virtual llvm::Constant *EnumerationMutationFunction(); 163238901Sandrew 164276789Sdim virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 165238901Sandrew const Stmt &S); 166276789Sdim virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 167229109Sed const ObjCAtThrowStmt &S); 168229109Sed virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 169251034Sed llvm::Value *AddrWeakObj); 170238901Sandrew virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 171229109Sed llvm::Value *src, llvm::Value *dst); 172229109Sed virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 173229109Sed llvm::Value *src, llvm::Value *dest); 174229109Sed virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 175229109Sed llvm::Value *src, llvm::Value *dest, 176229109Sed llvm::Value *ivarOffset); 177229109Sed virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 178229109Sed llvm::Value *src, llvm::Value *dest); 179229109Sed virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 180229109Sed llvm::Value *DestPtr, 181229109Sed llvm::Value *SrcPtr, 182229109Sed QualType Ty); 183251034Sed virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 184251034Sed QualType ObjectTy, 185251034Sed llvm::Value *BaseValue, 186245614Sandrew const ObjCIvarDecl *Ivar, 187245614Sandrew unsigned CVRQualifiers); 188296417Sdim virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 189296417Sdim const ObjCInterfaceDecl *Interface, 190245614Sandrew const ObjCIvarDecl *Ivar); 191245614Sandrew}; 192245614Sandrew} // end anonymous namespace 193251034Sed 194229109Sed 195251034Sed/// Emits a reference to a dummy variable which is emitted with each class. 196251034Sed/// This ensures that a linker error will be generated when trying to link 197229109Sed/// together modules where a referenced class is not defined. 198251034Sedvoid CGObjCGNU::EmitClassRef(const std::string &className) { 199251034Sed std::string symbolRef = "__objc_class_ref_" + className; 200251034Sed // Don't emit two copies of the same symbol 201251034Sed if (TheModule.getGlobalVariable(symbolRef)) 202251034Sed return; 203251034Sed std::string symbolName = "__objc_class_name_" + className; 204251034Sed llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName); 205251034Sed if (!ClassSymbol) { 206251034Sed ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, 207251034Sed llvm::GlobalValue::ExternalLinkage, 0, symbolName); 208251034Sed } 209251034Sed new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true, 210251034Sed llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef); 211251034Sed} 212251034Sed 213229109Sedstatic std::string SymbolNameForClass(const std::string &ClassName) { 214229109Sed return "_OBJC_CLASS_" + ClassName; 215251034Sed} 216251034Sed 217251034Sedstatic std::string SymbolNameForMethod(const std::string &ClassName, const 218251034Sed std::string &CategoryName, const std::string &MethodName, bool isClassMethod) 219251034Sed{ 220251034Sed std::string MethodNameColonStripped = MethodName; 221251034Sed std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(), 222251034Sed ':', '_'); 223251034Sed return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" + 224251034Sed CategoryName + "_" + MethodNameColonStripped; 225251034Sed} 226251034Sed 227251034SedCGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) 228238901Sandrew : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0), 229251034Sed MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) { 230229109Sed IntTy = cast<llvm::IntegerType>( 231229109Sed CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 232229109Sed LongTy = cast<llvm::IntegerType>( 233238901Sandrew CGM.getTypes().ConvertType(CGM.getContext().LongTy)); 234251034Sed 235229109Sed Int8Ty = llvm::Type::getInt8Ty(VMContext); 236229109Sed // C string type. Used in lots of places. 237229109Sed PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 238238901Sandrew 239251034Sed Zeros[0] = llvm::ConstantInt::get(LongTy, 0); 240229109Sed Zeros[1] = Zeros[0]; 241229109Sed NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty); 242229109Sed // Get the selector Type. 243251034Sed QualType selTy = CGM.getContext().getObjCSelType(); 244251034Sed if (QualType() == selTy) { 245251034Sed SelectorTy = PtrToInt8Ty; 246251034Sed } else { 247251034Sed SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy)); 248238901Sandrew } 249251034Sed 250251034Sed PtrToIntTy = llvm::PointerType::getUnqual(IntTy); 251229109Sed PtrTy = PtrToInt8Ty; 252229109Sed 253238901Sandrew // Object type 254251034Sed ASTIdTy = CGM.getContext().getObjCIdType(); 255229109Sed if (QualType() == ASTIdTy) { 256229109Sed IdTy = PtrToInt8Ty; 257229109Sed } else { 258229109Sed IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 259238901Sandrew } 260251034Sed 261251034Sed // IMP type 262229109Sed std::vector<const llvm::Type*> IMPArgs; 263229109Sed IMPArgs.push_back(IdTy); 264251034Sed IMPArgs.push_back(SelectorTy); 265251034Sed IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true); 266251034Sed} 267251034Sed 268251034Sed// This has to perform the lookup every time, since posing and related 269238901Sandrew// techniques can modify the name -> class mapping. 270251034Sedllvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, 271251034Sed const ObjCInterfaceDecl *OID) { 272229109Sed llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString()); 273229109Sed // With the incompatible ABI, this will need to be replaced with a direct 274238901Sandrew // reference to the class symbol. For the compatible nonfragile ABI we are 275251034Sed // still performing this lookup at run time but emitting the symbol for the 276251034Sed // class externally so that we can make the switch later. 277251034Sed EmitClassRef(OID->getNameAsString()); 278251034Sed ClassName = Builder.CreateStructGEP(ClassName, 0); 279251034Sed 280251034Sed std::vector<const llvm::Type*> Params(1, PtrToInt8Ty); 281251034Sed llvm::Constant *ClassLookupFn = 282251034Sed CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, 283251034Sed Params, 284251034Sed true), 285251034Sed "objc_lookup_class"); 286238901Sandrew return Builder.CreateCall(ClassLookupFn, ClassName); 287238901Sandrew} 288238901Sandrew 289238901Sandrewllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { 290251034Sed llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; 291229109Sed if (US == 0) 292229109Sed US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), 293229109Sed llvm::GlobalValue::PrivateLinkage, 294238901Sandrew ".objc_untyped_selector_alias"+Sel.getAsString(), 295251034Sed NULL, &TheModule); 296238901Sandrew 297251034Sed return Builder.CreateLoad(US); 298238901Sandrew} 299238901Sandrew 300238901Sandrewllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 301238901Sandrew *Method) { 302238901Sandrew 303238901Sandrew std::string SelName = Method->getSelector().getAsString(); 304238901Sandrew std::string SelTypes; 305238901Sandrew CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes); 306238901Sandrew // Typed selectors 307251034Sed TypedSelector Selector = TypedSelector(SelName, 308251034Sed SelTypes); 309251034Sed 310229109Sed // If it's already cached, return it. 311229109Sed if (TypedSelectors[Selector]) { 312229109Sed return Builder.CreateLoad(TypedSelectors[Selector]); 313 } 314 315 // If it isn't, cache it. 316 llvm::GlobalAlias *Sel = new llvm::GlobalAlias( 317 llvm::PointerType::getUnqual(SelectorTy), 318 llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName, 319 NULL, &TheModule); 320 TypedSelectors[Selector] = Sel; 321 322 return Builder.CreateLoad(Sel); 323} 324 325llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, 326 const std::string &Name) { 327 llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str()); 328 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 329} 330llvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str, 331 const std::string prefix) { 332 std::string name = prefix + Str; 333 llvm::Constant *ConstStr = TheModule.getGlobalVariable(name); 334 if (!ConstStr) { 335 llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true); 336 ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true, 337 llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str); 338 } 339 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 340} 341 342llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty, 343 std::vector<llvm::Constant*> &V, const std::string &Name, 344 llvm::GlobalValue::LinkageTypes linkage) { 345 llvm::Constant *C = llvm::ConstantStruct::get(Ty, V); 346 return new llvm::GlobalVariable(TheModule, Ty, false, 347 llvm::GlobalValue::InternalLinkage, C, Name); 348} 349 350llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty, 351 std::vector<llvm::Constant*> &V, const std::string &Name, 352 llvm::GlobalValue::LinkageTypes linkage) { 353 llvm::Constant *C = llvm::ConstantArray::get(Ty, V); 354 return new llvm::GlobalVariable(TheModule, Ty, false, 355 llvm::GlobalValue::InternalLinkage, C, Name); 356} 357 358/// Generate an NSConstantString object. 359llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { 360 std::string Str(SL->getStrData(), SL->getByteLength()); 361 362 std::vector<llvm::Constant*> Ivars; 363 Ivars.push_back(NULLPtr); 364 Ivars.push_back(MakeConstantString(Str)); 365 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size())); 366 llvm::Constant *ObjCStr = MakeGlobal( 367 llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL), 368 Ivars, ".objc_str"); 369 ConstantStrings.push_back( 370 llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty)); 371 return ObjCStr; 372} 373 374///Generates a message send where the super is the receiver. This is a message 375///send to self with special delivery semantics indicating which class's method 376///should be called. 377CodeGen::RValue 378CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 379 QualType ResultType, 380 Selector Sel, 381 const ObjCInterfaceDecl *Class, 382 bool isCategoryImpl, 383 llvm::Value *Receiver, 384 bool IsClassMessage, 385 const CallArgList &CallArgs, 386 const ObjCMethodDecl *Method) { 387 llvm::Value *cmd = GetSelector(CGF.Builder, Sel); 388 389 CallArgList ActualArgs; 390 391 ActualArgs.push_back( 392 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 393 ASTIdTy)); 394 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 395 CGF.getContext().getObjCSelType())); 396 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 397 398 CodeGenTypes &Types = CGM.getTypes(); 399 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 400 const llvm::FunctionType *impType = 401 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 402 403 llvm::Value *ReceiverClass = 0; 404 if (isCategoryImpl) { 405 llvm::Constant *classLookupFunction = 0; 406 std::vector<const llvm::Type*> Params; 407 Params.push_back(PtrTy); 408 if (IsClassMessage) { 409 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 410 IdTy, Params, true), "objc_get_meta_class"); 411 } else { 412 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 413 IdTy, Params, true), "objc_get_class"); 414 } 415 ReceiverClass = CGF.Builder.CreateCall(classLookupFunction, 416 MakeConstantString(Class->getNameAsString())); 417 } else { 418 // Set up global aliases for the metaclass or class pointer if they do not 419 // already exist. These will are forward-references which will be set to 420 // pointers to the class and metaclass structure created for the runtime 421 // load function. To send a message to super, we look up the value of the 422 // super_class pointer from either the class or metaclass structure. 423 if (IsClassMessage) { 424 if (!MetaClassPtrAlias) { 425 MetaClassPtrAlias = new llvm::GlobalAlias(IdTy, 426 llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" + 427 Class->getNameAsString(), NULL, &TheModule); 428 } 429 ReceiverClass = MetaClassPtrAlias; 430 } else { 431 if (!ClassPtrAlias) { 432 ClassPtrAlias = new llvm::GlobalAlias(IdTy, 433 llvm::GlobalValue::InternalLinkage, ".objc_class_ref" + 434 Class->getNameAsString(), NULL, &TheModule); 435 } 436 ReceiverClass = ClassPtrAlias; 437 } 438 } 439 // Cast the pointer to a simplified version of the class structure 440 ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass, 441 llvm::PointerType::getUnqual( 442 llvm::StructType::get(VMContext, IdTy, IdTy, NULL))); 443 // Get the superclass pointer 444 ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1); 445 // Load the superclass pointer 446 ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass); 447 // Construct the structure used to look up the IMP 448 llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext, 449 Receiver->getType(), IdTy, NULL); 450 llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy); 451 452 CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 453 CGF.Builder.CreateStore(ReceiverClass, 454 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 455 456 // Get the IMP 457 std::vector<const llvm::Type*> Params; 458 Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy)); 459 Params.push_back(SelectorTy); 460 llvm::Constant *lookupFunction = 461 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 462 llvm::PointerType::getUnqual(impType), Params, true), 463 "objc_msg_lookup_super"); 464 465 llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; 466 llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, 467 lookupArgs+2); 468 469 return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); 470} 471 472/// Generate code for a message send expression. 473CodeGen::RValue 474CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 475 QualType ResultType, 476 Selector Sel, 477 llvm::Value *Receiver, 478 bool IsClassMessage, 479 const CallArgList &CallArgs, 480 const ObjCMethodDecl *Method) { 481 CGBuilderTy &Builder = CGF.Builder; 482 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 483 llvm::Value *cmd; 484 if (Method) 485 cmd = GetSelector(Builder, Method); 486 else 487 cmd = GetSelector(Builder, Sel); 488 CallArgList ActualArgs; 489 490 Receiver = Builder.CreateBitCast(Receiver, IdTy); 491 ActualArgs.push_back( 492 std::make_pair(RValue::get(Receiver), ASTIdTy)); 493 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 494 CGF.getContext().getObjCSelType())); 495 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 496 497 CodeGenTypes &Types = CGM.getTypes(); 498 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 499 const llvm::FunctionType *impType = 500 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 501 502 llvm::Value *imp; 503 // For sender-aware dispatch, we pass the sender as the third argument to a 504 // lookup function. When sending messages from C code, the sender is nil. 505 // objc_msg_lookup_sender(id *receiver, SEL selector, id sender); 506 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 507 508 std::vector<const llvm::Type*> Params; 509 llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType()); 510 Builder.CreateStore(Receiver, ReceiverPtr); 511 Params.push_back(ReceiverPtr->getType()); 512 Params.push_back(SelectorTy); 513 llvm::Value *self; 514 515 if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) { 516 self = CGF.LoadObjCSelf(); 517 } else { 518 self = llvm::ConstantPointerNull::get(IdTy); 519 } 520 521 Params.push_back(self->getType()); 522 523 // The lookup function returns a slot, which can be safely cached. 524 llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy, 525 IntTy, llvm::PointerType::getUnqual(impType), NULL); 526 llvm::Constant *lookupFunction = 527 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 528 llvm::PointerType::getUnqual(SlotTy), Params, true), 529 "objc_msg_lookup_sender"); 530 531 // The lookup function is guaranteed not to capture the receiver pointer. 532 if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) { 533 LookupFn->setDoesNotCapture(1); 534 } 535 536 llvm::Value *slot = 537 Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self); 538 imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4)); 539 // The lookup function may have changed the receiver, so make sure we use 540 // the new one. 541 ActualArgs[0] = 542 std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy); 543 } else { 544 std::vector<const llvm::Type*> Params; 545 Params.push_back(Receiver->getType()); 546 Params.push_back(SelectorTy); 547 llvm::Constant *lookupFunction = 548 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 549 llvm::PointerType::getUnqual(impType), Params, true), 550 "objc_msg_lookup"); 551 552 imp = Builder.CreateCall2(lookupFunction, Receiver, cmd); 553 } 554 555 return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); 556} 557 558/// Generates a MethodList. Used in construction of a objc_class and 559/// objc_category structures. 560llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName, 561 const std::string &CategoryName, 562 const llvm::SmallVectorImpl<Selector> &MethodSels, 563 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 564 bool isClassMethodList) { 565 if (MethodSels.empty()) 566 return NULLPtr; 567 // Get the method structure type. 568 llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext, 569 PtrToInt8Ty, // Really a selector, but the runtime creates it us. 570 PtrToInt8Ty, // Method types 571 llvm::PointerType::getUnqual(IMPTy), //Method pointer 572 NULL); 573 std::vector<llvm::Constant*> Methods; 574 std::vector<llvm::Constant*> Elements; 575 for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) { 576 Elements.clear(); 577 if (llvm::Constant *Method = 578 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName, 579 MethodSels[i].getAsString(), 580 isClassMethodList))) { 581 llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString()); 582 Elements.push_back(C); 583 Elements.push_back(MethodTypes[i]); 584 Method = llvm::ConstantExpr::getBitCast(Method, 585 llvm::PointerType::getUnqual(IMPTy)); 586 Elements.push_back(Method); 587 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements)); 588 } 589 } 590 591 // Array of method structures 592 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy, 593 Methods.size()); 594 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy, 595 Methods); 596 597 // Structure containing list pointer, array and array count 598 llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields; 599 llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext); 600 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy); 601 llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext, 602 NextPtrTy, 603 IntTy, 604 ObjCMethodArrayTy, 605 NULL); 606 // Refine next pointer type to concrete type 607 llvm::cast<llvm::OpaqueType>( 608 OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy); 609 ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get()); 610 611 Methods.clear(); 612 Methods.push_back(llvm::ConstantPointerNull::get( 613 llvm::PointerType::getUnqual(ObjCMethodListTy))); 614 Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 615 MethodTypes.size())); 616 Methods.push_back(MethodArray); 617 618 // Create an instance of the structure 619 return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list"); 620} 621 622/// Generates an IvarList. Used in construction of a objc_class. 623llvm::Constant *CGObjCGNU::GenerateIvarList( 624 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 625 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 626 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) { 627 if (IvarNames.size() == 0) 628 return NULLPtr; 629 // Get the method structure type. 630 llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext, 631 PtrToInt8Ty, 632 PtrToInt8Ty, 633 IntTy, 634 NULL); 635 std::vector<llvm::Constant*> Ivars; 636 std::vector<llvm::Constant*> Elements; 637 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { 638 Elements.clear(); 639 Elements.push_back(IvarNames[i]); 640 Elements.push_back(IvarTypes[i]); 641 Elements.push_back(IvarOffsets[i]); 642 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements)); 643 } 644 645 // Array of method structures 646 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy, 647 IvarNames.size()); 648 649 650 Elements.clear(); 651 Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size())); 652 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)); 653 // Structure containing array and array count 654 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy, 655 ObjCIvarArrayTy, 656 NULL); 657 658 // Create an instance of the structure 659 return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list"); 660} 661 662/// Generate a class structure 663llvm::Constant *CGObjCGNU::GenerateClassStructure( 664 llvm::Constant *MetaClass, 665 llvm::Constant *SuperClass, 666 unsigned info, 667 const char *Name, 668 llvm::Constant *Version, 669 llvm::Constant *InstanceSize, 670 llvm::Constant *IVars, 671 llvm::Constant *Methods, 672 llvm::Constant *Protocols, 673 llvm::Constant *IvarOffsets, 674 llvm::Constant *Properties) { 675 // Set up the class structure 676 // Note: Several of these are char*s when they should be ids. This is 677 // because the runtime performs this translation on load. 678 // 679 // Fields marked New ABI are part of the GNUstep runtime. We emit them 680 // anyway; the classes will still work with the GNU runtime, they will just 681 // be ignored. 682 llvm::StructType *ClassTy = llvm::StructType::get(VMContext, 683 PtrToInt8Ty, // class_pointer 684 PtrToInt8Ty, // super_class 685 PtrToInt8Ty, // name 686 LongTy, // version 687 LongTy, // info 688 LongTy, // instance_size 689 IVars->getType(), // ivars 690 Methods->getType(), // methods 691 // These are all filled in by the runtime, so we pretend 692 PtrTy, // dtable 693 PtrTy, // subclass_list 694 PtrTy, // sibling_class 695 PtrTy, // protocols 696 PtrTy, // gc_object_type 697 // New ABI: 698 LongTy, // abi_version 699 IvarOffsets->getType(), // ivar_offsets 700 Properties->getType(), // properties 701 NULL); 702 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); 703 // Fill in the structure 704 std::vector<llvm::Constant*> Elements; 705 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty)); 706 Elements.push_back(SuperClass); 707 Elements.push_back(MakeConstantString(Name, ".class_name")); 708 Elements.push_back(Zero); 709 Elements.push_back(llvm::ConstantInt::get(LongTy, info)); 710 Elements.push_back(InstanceSize); 711 Elements.push_back(IVars); 712 Elements.push_back(Methods); 713 Elements.push_back(NULLPtr); 714 Elements.push_back(NULLPtr); 715 Elements.push_back(NULLPtr); 716 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy)); 717 Elements.push_back(NULLPtr); 718 Elements.push_back(Zero); 719 Elements.push_back(IvarOffsets); 720 Elements.push_back(Properties); 721 // Create an instance of the structure 722 // This is now an externally visible symbol, so that we can speed up class 723 // messages in the next ABI. 724 return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name), 725 llvm::GlobalValue::ExternalLinkage); 726} 727 728llvm::Constant *CGObjCGNU::GenerateProtocolMethodList( 729 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 730 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) { 731 // Get the method structure type. 732 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext, 733 PtrToInt8Ty, // Really a selector, but the runtime does the casting for us. 734 PtrToInt8Ty, 735 NULL); 736 std::vector<llvm::Constant*> Methods; 737 std::vector<llvm::Constant*> Elements; 738 for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) { 739 Elements.clear(); 740 Elements.push_back(MethodNames[i]); 741 Elements.push_back(MethodTypes[i]); 742 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements)); 743 } 744 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy, 745 MethodNames.size()); 746 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, 747 Methods); 748 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext, 749 IntTy, ObjCMethodArrayTy, NULL); 750 Methods.clear(); 751 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size())); 752 Methods.push_back(Array); 753 return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list"); 754} 755 756// Create the protocol list structure used in classes, categories and so on 757llvm::Constant *CGObjCGNU::GenerateProtocolList( 758 const llvm::SmallVectorImpl<std::string> &Protocols) { 759 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 760 Protocols.size()); 761 llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext, 762 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 763 LongTy,//FIXME: Should be size_t 764 ProtocolArrayTy, 765 NULL); 766 std::vector<llvm::Constant*> Elements; 767 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); 768 iter != endIter ; iter++) { 769 llvm::Constant *protocol = 0; 770 llvm::StringMap<llvm::Constant*>::iterator value = 771 ExistingProtocols.find(*iter); 772 if (value == ExistingProtocols.end()) { 773 protocol = GenerateEmptyProtocol(*iter); 774 } else { 775 protocol = value->getValue(); 776 } 777 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol, 778 PtrToInt8Ty); 779 Elements.push_back(Ptr); 780 } 781 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 782 Elements); 783 Elements.clear(); 784 Elements.push_back(NULLPtr); 785 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size())); 786 Elements.push_back(ProtocolArray); 787 return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); 788} 789 790llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, 791 const ObjCProtocolDecl *PD) { 792 llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()]; 793 const llvm::Type *T = 794 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); 795 return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); 796} 797 798llvm::Constant *CGObjCGNU::GenerateEmptyProtocol( 799 const std::string &ProtocolName) { 800 llvm::SmallVector<std::string, 0> EmptyStringVector; 801 llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector; 802 803 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector); 804 llvm::Constant *MethodList = 805 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector); 806 // Protocols are objects containing lists of the methods implemented and 807 // protocols adopted. 808 llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy, 809 PtrToInt8Ty, 810 ProtocolList->getType(), 811 MethodList->getType(), 812 MethodList->getType(), 813 MethodList->getType(), 814 MethodList->getType(), 815 NULL); 816 std::vector<llvm::Constant*> Elements; 817 // The isa pointer must be set to a magic number so the runtime knows it's 818 // the correct layout. 819 int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ? 820 NonFragileProtocolVersion : ProtocolVersion; 821 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 822 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy)); 823 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 824 Elements.push_back(ProtocolList); 825 Elements.push_back(MethodList); 826 Elements.push_back(MethodList); 827 Elements.push_back(MethodList); 828 Elements.push_back(MethodList); 829 return MakeGlobal(ProtocolTy, Elements, ".objc_protocol"); 830} 831 832void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { 833 ASTContext &Context = CGM.getContext(); 834 std::string ProtocolName = PD->getNameAsString(); 835 llvm::SmallVector<std::string, 16> Protocols; 836 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(), 837 E = PD->protocol_end(); PI != E; ++PI) 838 Protocols.push_back((*PI)->getNameAsString()); 839 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames; 840 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 841 llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames; 842 llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes; 843 for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(), 844 E = PD->instmeth_end(); iter != E; iter++) { 845 std::string TypeStr; 846 Context.getObjCEncodingForMethodDecl(*iter, TypeStr); 847 if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) { 848 InstanceMethodNames.push_back( 849 MakeConstantString((*iter)->getSelector().getAsString())); 850 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 851 } else { 852 OptionalInstanceMethodNames.push_back( 853 MakeConstantString((*iter)->getSelector().getAsString())); 854 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 855 } 856 } 857 // Collect information about class methods: 858 llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames; 859 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 860 llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames; 861 llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes; 862 for (ObjCProtocolDecl::classmeth_iterator 863 iter = PD->classmeth_begin(), endIter = PD->classmeth_end(); 864 iter != endIter ; iter++) { 865 std::string TypeStr; 866 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 867 if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) { 868 ClassMethodNames.push_back( 869 MakeConstantString((*iter)->getSelector().getAsString())); 870 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 871 } else { 872 OptionalClassMethodNames.push_back( 873 MakeConstantString((*iter)->getSelector().getAsString())); 874 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr)); 875 } 876 } 877 878 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 879 llvm::Constant *InstanceMethodList = 880 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes); 881 llvm::Constant *ClassMethodList = 882 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes); 883 llvm::Constant *OptionalInstanceMethodList = 884 GenerateProtocolMethodList(OptionalInstanceMethodNames, 885 OptionalInstanceMethodTypes); 886 llvm::Constant *OptionalClassMethodList = 887 GenerateProtocolMethodList(OptionalClassMethodNames, 888 OptionalClassMethodTypes); 889 890 // Property metadata: name, attributes, isSynthesized, setter name, setter 891 // types, getter name, getter types. 892 // The isSynthesized value is always set to 0 in a protocol. It exists to 893 // simplify the runtime library by allowing it to use the same data 894 // structures for protocol metadata everywhere. 895 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext, 896 PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, 897 PtrToInt8Ty, NULL); 898 std::vector<llvm::Constant*> Properties; 899 std::vector<llvm::Constant*> OptionalProperties; 900 901 // Add all of the property methods need adding to the method list and to the 902 // property metadata list. 903 for (ObjCContainerDecl::prop_iterator 904 iter = PD->prop_begin(), endIter = PD->prop_end(); 905 iter != endIter ; iter++) { 906 std::vector<llvm::Constant*> Fields; 907 ObjCPropertyDecl *property = (*iter); 908 909 Fields.push_back(MakeConstantString(property->getNameAsString())); 910 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 911 property->getPropertyAttributes())); 912 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0)); 913 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 914 std::string TypeStr; 915 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 916 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 917 InstanceMethodTypes.push_back(TypeEncoding); 918 Fields.push_back(MakeConstantString(getter->getSelector().getAsString())); 919 Fields.push_back(TypeEncoding); 920 } else { 921 Fields.push_back(NULLPtr); 922 Fields.push_back(NULLPtr); 923 } 924 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 925 std::string TypeStr; 926 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 927 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 928 InstanceMethodTypes.push_back(TypeEncoding); 929 Fields.push_back(MakeConstantString(setter->getSelector().getAsString())); 930 Fields.push_back(TypeEncoding); 931 } else { 932 Fields.push_back(NULLPtr); 933 Fields.push_back(NULLPtr); 934 } 935 if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) { 936 OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 937 } else { 938 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 939 } 940 } 941 llvm::Constant *PropertyArray = llvm::ConstantArray::get( 942 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties); 943 llvm::Constant* PropertyListInitFields[] = 944 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray}; 945 946 llvm::Constant *PropertyListInit = 947 llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false); 948 llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule, 949 PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage, 950 PropertyListInit, ".objc_property_list"); 951 952 llvm::Constant *OptionalPropertyArray = 953 llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy, 954 OptionalProperties.size()) , OptionalProperties); 955 llvm::Constant* OptionalPropertyListInitFields[] = { 956 llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr, 957 OptionalPropertyArray }; 958 959 llvm::Constant *OptionalPropertyListInit = 960 llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false); 961 llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule, 962 OptionalPropertyListInit->getType(), false, 963 llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit, 964 ".objc_property_list"); 965 966 // Protocols are objects containing lists of the methods implemented and 967 // protocols adopted. 968 llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy, 969 PtrToInt8Ty, 970 ProtocolList->getType(), 971 InstanceMethodList->getType(), 972 ClassMethodList->getType(), 973 OptionalInstanceMethodList->getType(), 974 OptionalClassMethodList->getType(), 975 PropertyList->getType(), 976 OptionalPropertyList->getType(), 977 NULL); 978 std::vector<llvm::Constant*> Elements; 979 // The isa pointer must be set to a magic number so the runtime knows it's 980 // the correct layout. 981 int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ? 982 NonFragileProtocolVersion : ProtocolVersion; 983 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 984 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy)); 985 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 986 Elements.push_back(ProtocolList); 987 Elements.push_back(InstanceMethodList); 988 Elements.push_back(ClassMethodList); 989 Elements.push_back(OptionalInstanceMethodList); 990 Elements.push_back(OptionalClassMethodList); 991 Elements.push_back(PropertyList); 992 Elements.push_back(OptionalPropertyList); 993 ExistingProtocols[ProtocolName] = 994 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements, 995 ".objc_protocol"), IdTy); 996} 997void CGObjCGNU::GenerateProtocolHolderCategory(void) { 998 // Collect information about instance methods 999 llvm::SmallVector<Selector, 1> MethodSels; 1000 llvm::SmallVector<llvm::Constant*, 1> MethodTypes; 1001 1002 std::vector<llvm::Constant*> Elements; 1003 const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack"; 1004 const std::string CategoryName = "AnotherHack"; 1005 Elements.push_back(MakeConstantString(CategoryName)); 1006 Elements.push_back(MakeConstantString(ClassName)); 1007 // Instance method list 1008 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1009 ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy)); 1010 // Class method list 1011 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1012 ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy)); 1013 // Protocol list 1014 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy, 1015 ExistingProtocols.size()); 1016 llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext, 1017 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 1018 LongTy,//FIXME: Should be size_t 1019 ProtocolArrayTy, 1020 NULL); 1021 std::vector<llvm::Constant*> ProtocolElements; 1022 for (llvm::StringMapIterator<llvm::Constant*> iter = 1023 ExistingProtocols.begin(), endIter = ExistingProtocols.end(); 1024 iter != endIter ; iter++) { 1025 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(), 1026 PtrTy); 1027 ProtocolElements.push_back(Ptr); 1028 } 1029 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 1030 ProtocolElements); 1031 ProtocolElements.clear(); 1032 ProtocolElements.push_back(NULLPtr); 1033 ProtocolElements.push_back(llvm::ConstantInt::get(LongTy, 1034 ExistingProtocols.size())); 1035 ProtocolElements.push_back(ProtocolArray); 1036 Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy, 1037 ProtocolElements, ".objc_protocol_list"), PtrTy)); 1038 Categories.push_back(llvm::ConstantExpr::getBitCast( 1039 MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, 1040 PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy)); 1041} 1042 1043void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 1044 std::string ClassName = OCD->getClassInterface()->getNameAsString(); 1045 std::string CategoryName = OCD->getNameAsString(); 1046 // Collect information about instance methods 1047 llvm::SmallVector<Selector, 16> InstanceMethodSels; 1048 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 1049 for (ObjCCategoryImplDecl::instmeth_iterator 1050 iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end(); 1051 iter != endIter ; iter++) { 1052 InstanceMethodSels.push_back((*iter)->getSelector()); 1053 std::string TypeStr; 1054 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 1055 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 1056 } 1057 1058 // Collect information about class methods 1059 llvm::SmallVector<Selector, 16> ClassMethodSels; 1060 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 1061 for (ObjCCategoryImplDecl::classmeth_iterator 1062 iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end(); 1063 iter != endIter ; iter++) { 1064 ClassMethodSels.push_back((*iter)->getSelector()); 1065 std::string TypeStr; 1066 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 1067 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 1068 } 1069 1070 // Collect the names of referenced protocols 1071 llvm::SmallVector<std::string, 16> Protocols; 1072 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface(); 1073 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 1074 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 1075 E = Protos.end(); I != E; ++I) 1076 Protocols.push_back((*I)->getNameAsString()); 1077 1078 std::vector<llvm::Constant*> Elements; 1079 Elements.push_back(MakeConstantString(CategoryName)); 1080 Elements.push_back(MakeConstantString(ClassName)); 1081 // Instance method list 1082 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1083 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes, 1084 false), PtrTy)); 1085 // Class method list 1086 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1087 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true), 1088 PtrTy)); 1089 // Protocol list 1090 Elements.push_back(llvm::ConstantExpr::getBitCast( 1091 GenerateProtocolList(Protocols), PtrTy)); 1092 Categories.push_back(llvm::ConstantExpr::getBitCast( 1093 MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, 1094 PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy)); 1095} 1096 1097llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID, 1098 llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 1099 llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) { 1100 ASTContext &Context = CGM.getContext(); 1101 // 1102 // Property metadata: name, attributes, isSynthesized, setter name, setter 1103 // types, getter name, getter types. 1104 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext, 1105 PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, 1106 PtrToInt8Ty, NULL); 1107 std::vector<llvm::Constant*> Properties; 1108 1109 1110 // Add all of the property methods need adding to the method list and to the 1111 // property metadata list. 1112 for (ObjCImplDecl::propimpl_iterator 1113 iter = OID->propimpl_begin(), endIter = OID->propimpl_end(); 1114 iter != endIter ; iter++) { 1115 std::vector<llvm::Constant*> Fields; 1116 ObjCPropertyDecl *property = (*iter)->getPropertyDecl(); 1117 1118 Fields.push_back(MakeConstantString(property->getNameAsString())); 1119 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 1120 property->getPropertyAttributes())); 1121 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 1122 (*iter)->getPropertyImplementation() == 1123 ObjCPropertyImplDecl::Synthesize)); 1124 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 1125 InstanceMethodSels.push_back(getter->getSelector()); 1126 std::string TypeStr; 1127 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 1128 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 1129 InstanceMethodTypes.push_back(TypeEncoding); 1130 Fields.push_back(MakeConstantString(getter->getSelector().getAsString())); 1131 Fields.push_back(TypeEncoding); 1132 } else { 1133 Fields.push_back(NULLPtr); 1134 Fields.push_back(NULLPtr); 1135 } 1136 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 1137 InstanceMethodSels.push_back(setter->getSelector()); 1138 std::string TypeStr; 1139 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 1140 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 1141 InstanceMethodTypes.push_back(TypeEncoding); 1142 Fields.push_back(MakeConstantString(setter->getSelector().getAsString())); 1143 Fields.push_back(TypeEncoding); 1144 } else { 1145 Fields.push_back(NULLPtr); 1146 Fields.push_back(NULLPtr); 1147 } 1148 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 1149 } 1150 llvm::ArrayType *PropertyArrayTy = 1151 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()); 1152 llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy, 1153 Properties); 1154 llvm::Constant* PropertyListInitFields[] = 1155 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray}; 1156 1157 llvm::Constant *PropertyListInit = 1158 llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false); 1159 return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false, 1160 llvm::GlobalValue::InternalLinkage, PropertyListInit, 1161 ".objc_property_list"); 1162} 1163 1164void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 1165 ASTContext &Context = CGM.getContext(); 1166 1167 // Get the superclass name. 1168 const ObjCInterfaceDecl * SuperClassDecl = 1169 OID->getClassInterface()->getSuperClass(); 1170 std::string SuperClassName; 1171 if (SuperClassDecl) { 1172 SuperClassName = SuperClassDecl->getNameAsString(); 1173 EmitClassRef(SuperClassName); 1174 } 1175 1176 // Get the class name 1177 ObjCInterfaceDecl *ClassDecl = 1178 const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 1179 std::string ClassName = ClassDecl->getNameAsString(); 1180 // Emit the symbol that is used to generate linker errors if this class is 1181 // referenced in other modules but not declared. 1182 std::string classSymbolName = "__objc_class_name_" + ClassName; 1183 if (llvm::GlobalVariable *symbol = 1184 TheModule.getGlobalVariable(classSymbolName)) { 1185 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0)); 1186 } else { 1187 new llvm::GlobalVariable(TheModule, LongTy, false, 1188 llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0), 1189 classSymbolName); 1190 } 1191 1192 // Get the size of instances. 1193 int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8; 1194 1195 // Collect information about instance variables. 1196 llvm::SmallVector<llvm::Constant*, 16> IvarNames; 1197 llvm::SmallVector<llvm::Constant*, 16> IvarTypes; 1198 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets; 1199 1200 std::vector<llvm::Constant*> IvarOffsetValues; 1201 1202 int superInstanceSize = !SuperClassDecl ? 0 : 1203 Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8; 1204 // For non-fragile ivars, set the instance size to 0 - {the size of just this 1205 // class}. The runtime will then set this to the correct value on load. 1206 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1207 instanceSize = 0 - (instanceSize - superInstanceSize); 1208 } 1209 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 1210 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 1211 // Store the name 1212 IvarNames.push_back(MakeConstantString((*iter)->getNameAsString())); 1213 // Get the type encoding for this ivar 1214 std::string TypeStr; 1215 Context.getObjCEncodingForType((*iter)->getType(), TypeStr); 1216 IvarTypes.push_back(MakeConstantString(TypeStr)); 1217 // Get the offset 1218 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter); 1219 uint64_t Offset = BaseOffset; 1220 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1221 Offset = BaseOffset - superInstanceSize; 1222 } 1223 IvarOffsets.push_back( 1224 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset)); 1225 IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy, 1226 false, llvm::GlobalValue::ExternalLinkage, 1227 llvm::ConstantInt::get(IntTy, BaseOffset), 1228 "__objc_ivar_offset_value_" + ClassName +"." + 1229 (*iter)->getNameAsString())); 1230 } 1231 llvm::Constant *IvarOffsetArrayInit = 1232 llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy, 1233 IvarOffsetValues.size()), IvarOffsetValues); 1234 llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule, 1235 IvarOffsetArrayInit->getType(), false, 1236 llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit, 1237 ".ivar.offsets"); 1238 1239 // Collect information about instance methods 1240 llvm::SmallVector<Selector, 16> InstanceMethodSels; 1241 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 1242 for (ObjCImplementationDecl::instmeth_iterator 1243 iter = OID->instmeth_begin(), endIter = OID->instmeth_end(); 1244 iter != endIter ; iter++) { 1245 InstanceMethodSels.push_back((*iter)->getSelector()); 1246 std::string TypeStr; 1247 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 1248 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 1249 } 1250 1251 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels, 1252 InstanceMethodTypes); 1253 1254 1255 // Collect information about class methods 1256 llvm::SmallVector<Selector, 16> ClassMethodSels; 1257 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 1258 for (ObjCImplementationDecl::classmeth_iterator 1259 iter = OID->classmeth_begin(), endIter = OID->classmeth_end(); 1260 iter != endIter ; iter++) { 1261 ClassMethodSels.push_back((*iter)->getSelector()); 1262 std::string TypeStr; 1263 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 1264 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 1265 } 1266 // Collect the names of referenced protocols 1267 llvm::SmallVector<std::string, 16> Protocols; 1268 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 1269 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 1270 E = Protos.end(); I != E; ++I) 1271 Protocols.push_back((*I)->getNameAsString()); 1272 1273 1274 1275 // Get the superclass pointer. 1276 llvm::Constant *SuperClass; 1277 if (!SuperClassName.empty()) { 1278 SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 1279 } else { 1280 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 1281 } 1282 // Empty vector used to construct empty method lists 1283 llvm::SmallVector<llvm::Constant*, 1> empty; 1284 // Generate the method and instance variable lists 1285 llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 1286 InstanceMethodSels, InstanceMethodTypes, false); 1287 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 1288 ClassMethodSels, ClassMethodTypes, true); 1289 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 1290 IvarOffsets); 1291 // Irrespective of whether we are compiling for a fragile or non-fragile ABI, 1292 // we emit a symbol containing the offset for each ivar in the class. This 1293 // allows code compiled for the non-Fragile ABI to inherit from code compiled 1294 // for the legacy ABI, without causing problems. The converse is also 1295 // possible, but causes all ivar accesses to be fragile. 1296 int i = 0; 1297 // Offset pointer for getting at the correct field in the ivar list when 1298 // setting up the alias. These are: The base address for the global, the 1299 // ivar array (second field), the ivar in this list (set for each ivar), and 1300 // the offset (third field in ivar structure) 1301 const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext); 1302 llvm::Constant *offsetPointerIndexes[] = {Zeros[0], 1303 llvm::ConstantInt::get(IndexTy, 1), 0, 1304 llvm::ConstantInt::get(IndexTy, 2) }; 1305 1306 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 1307 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 1308 const std::string Name = "__objc_ivar_offset_" + ClassName + '.' 1309 +(*iter)->getNameAsString(); 1310 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++); 1311 // Get the correct ivar field 1312 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr( 1313 IvarList, offsetPointerIndexes, 4); 1314 // Get the existing alias, if one exists. 1315 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name); 1316 if (offset) { 1317 offset->setInitializer(offsetValue); 1318 // If this is the real definition, change its linkage type so that 1319 // different modules will use this one, rather than their private 1320 // copy. 1321 offset->setLinkage(llvm::GlobalValue::ExternalLinkage); 1322 } else { 1323 // Add a new alias if there isn't one already. 1324 offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(), 1325 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name); 1326 } 1327 } 1328 //Generate metaclass for class methods 1329 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, 1330 NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList( 1331 empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr); 1332 1333 // Generate the class structure 1334 llvm::Constant *ClassStruct = 1335 GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L, 1336 ClassName.c_str(), 0, 1337 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, 1338 MethodList, GenerateProtocolList(Protocols), IvarOffsetArray, 1339 Properties); 1340 1341 // Resolve the class aliases, if they exist. 1342 if (ClassPtrAlias) { 1343 ClassPtrAlias->setAliasee( 1344 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); 1345 ClassPtrAlias = 0; 1346 } 1347 if (MetaClassPtrAlias) { 1348 MetaClassPtrAlias->setAliasee( 1349 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); 1350 MetaClassPtrAlias = 0; 1351 } 1352 1353 // Add class structure to list to be added to the symtab later 1354 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 1355 Classes.push_back(ClassStruct); 1356} 1357 1358 1359llvm::Function *CGObjCGNU::ModuleInitFunction() { 1360 // Only emit an ObjC load function if no Objective-C stuff has been called 1361 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 1362 ExistingProtocols.empty() && TypedSelectors.empty() && 1363 UntypedSelectors.empty()) 1364 return NULL; 1365 1366 // Add all referenced protocols to a category. 1367 GenerateProtocolHolderCategory(); 1368 1369 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>( 1370 SelectorTy->getElementType()); 1371 const llvm::Type *SelStructPtrTy = SelectorTy; 1372 bool isSelOpaque = false; 1373 if (SelStructTy == 0) { 1374 SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty, 1375 PtrToInt8Ty, NULL); 1376 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); 1377 isSelOpaque = true; 1378 } 1379 1380 // Name the ObjC types to make the IR a bit easier to read 1381 TheModule.addTypeName(".objc_selector", SelStructPtrTy); 1382 TheModule.addTypeName(".objc_id", IdTy); 1383 TheModule.addTypeName(".objc_imp", IMPTy); 1384 1385 std::vector<llvm::Constant*> Elements; 1386 llvm::Constant *Statics = NULLPtr; 1387 // Generate statics list: 1388 if (ConstantStrings.size()) { 1389 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 1390 ConstantStrings.size() + 1); 1391 ConstantStrings.push_back(NULLPtr); 1392 1393 llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass; 1394 if (StringClass.empty()) StringClass = "NXConstantString"; 1395 Elements.push_back(MakeConstantString(StringClass, 1396 ".objc_static_class_name")); 1397 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, 1398 ConstantStrings)); 1399 llvm::StructType *StaticsListTy = 1400 llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL); 1401 llvm::Type *StaticsListPtrTy = 1402 llvm::PointerType::getUnqual(StaticsListTy); 1403 Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics"); 1404 llvm::ArrayType *StaticsListArrayTy = 1405 llvm::ArrayType::get(StaticsListPtrTy, 2); 1406 Elements.clear(); 1407 Elements.push_back(Statics); 1408 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy)); 1409 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr"); 1410 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy); 1411 } 1412 // Array of classes, categories, and constant objects 1413 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, 1414 Classes.size() + Categories.size() + 2); 1415 llvm::StructType *SymTabTy = llvm::StructType::get(VMContext, 1416 LongTy, SelStructPtrTy, 1417 llvm::Type::getInt16Ty(VMContext), 1418 llvm::Type::getInt16Ty(VMContext), 1419 ClassListTy, NULL); 1420 1421 Elements.clear(); 1422 // Pointer to an array of selectors used in this module. 1423 std::vector<llvm::Constant*> Selectors; 1424 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1425 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end(); 1426 iter != iterEnd ; ++iter) { 1427 Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name")); 1428 Elements.push_back(MakeConstantString(iter->first.second, 1429 ".objc_sel_types")); 1430 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1431 Elements.clear(); 1432 } 1433 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1434 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1435 iter != iterEnd; ++iter) { 1436 Elements.push_back( 1437 ExportUniqueString(iter->getKeyData(), ".objc_sel_name")); 1438 Elements.push_back(NULLPtr); 1439 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1440 Elements.clear(); 1441 } 1442 Elements.push_back(NULLPtr); 1443 Elements.push_back(NULLPtr); 1444 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1445 Elements.clear(); 1446 // Number of static selectors 1447 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() )); 1448 llvm::Constant *SelectorList = MakeGlobal( 1449 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, 1450 ".objc_selector_list"); 1451 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, 1452 SelStructPtrTy)); 1453 1454 // Now that all of the static selectors exist, create pointers to them. 1455 int index = 0; 1456 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1457 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); 1458 iter != iterEnd; ++iter) { 1459 llvm::Constant *Idxs[] = {Zeros[0], 1460 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; 1461 llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy, 1462 true, llvm::GlobalValue::InternalLinkage, 1463 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1464 ".objc_sel_ptr"); 1465 // If selectors are defined as an opaque type, cast the pointer to this 1466 // type. 1467 if (isSelOpaque) { 1468 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1469 llvm::PointerType::getUnqual(SelectorTy)); 1470 } 1471 (*iter).second->setAliasee(SelPtr); 1472 } 1473 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1474 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1475 iter != iterEnd; iter++) { 1476 llvm::Constant *Idxs[] = {Zeros[0], 1477 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; 1478 llvm::Constant *SelPtr = new llvm::GlobalVariable 1479 (TheModule, SelStructPtrTy, 1480 true, llvm::GlobalValue::InternalLinkage, 1481 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1482 ".objc_sel_ptr"); 1483 // If selectors are defined as an opaque type, cast the pointer to this 1484 // type. 1485 if (isSelOpaque) { 1486 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1487 llvm::PointerType::getUnqual(SelectorTy)); 1488 } 1489 (*iter).second->setAliasee(SelPtr); 1490 } 1491 // Number of classes defined. 1492 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext), 1493 Classes.size())); 1494 // Number of categories defined 1495 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext), 1496 Categories.size())); 1497 // Create an array of classes, then categories, then static object instances 1498 Classes.insert(Classes.end(), Categories.begin(), Categories.end()); 1499 // NULL-terminated list of static object instances (mainly constant strings) 1500 Classes.push_back(Statics); 1501 Classes.push_back(NULLPtr); 1502 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes); 1503 Elements.push_back(ClassList); 1504 // Construct the symbol table 1505 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements); 1506 1507 // The symbol table is contained in a module which has some version-checking 1508 // constants 1509 llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy, 1510 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL); 1511 Elements.clear(); 1512 // Runtime version used for compatibility checking. 1513 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1514 Elements.push_back(llvm::ConstantInt::get(LongTy, 1515 NonFragileRuntimeVersion)); 1516 } else { 1517 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion)); 1518 } 1519 // sizeof(ModuleTy) 1520 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1521 Elements.push_back(llvm::ConstantInt::get(LongTy, 1522 td.getTypeSizeInBits(ModuleTy)/8)); 1523 //FIXME: Should be the path to the file where this module was declared 1524 Elements.push_back(NULLPtr); 1525 Elements.push_back(SymTab); 1526 llvm::Value *Module = MakeGlobal(ModuleTy, Elements); 1527 1528 // Create the load function calling the runtime entry point with the module 1529 // structure 1530 llvm::Function * LoadFunction = llvm::Function::Create( 1531 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), 1532 llvm::GlobalValue::InternalLinkage, ".objc_load_function", 1533 &TheModule); 1534 llvm::BasicBlock *EntryBB = 1535 llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); 1536 CGBuilderTy Builder(VMContext); 1537 Builder.SetInsertPoint(EntryBB); 1538 1539 std::vector<const llvm::Type*> Params(1, 1540 llvm::PointerType::getUnqual(ModuleTy)); 1541 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 1542 llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class"); 1543 Builder.CreateCall(Register, Module); 1544 Builder.CreateRetVoid(); 1545 1546 return LoadFunction; 1547} 1548 1549llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 1550 const ObjCContainerDecl *CD) { 1551 const ObjCCategoryImplDecl *OCD = 1552 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); 1553 std::string CategoryName = OCD ? OCD->getNameAsString() : ""; 1554 std::string ClassName = OMD->getClassInterface()->getNameAsString(); 1555 std::string MethodName = OMD->getSelector().getAsString(); 1556 bool isClassMethod = !OMD->isInstanceMethod(); 1557 1558 CodeGenTypes &Types = CGM.getTypes(); 1559 const llvm::FunctionType *MethodTy = 1560 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 1561 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, 1562 MethodName, isClassMethod); 1563 1564 llvm::Function *Method 1565 = llvm::Function::Create(MethodTy, 1566 llvm::GlobalValue::InternalLinkage, 1567 FunctionName, 1568 &TheModule); 1569 return Method; 1570} 1571 1572llvm::Function *CGObjCGNU::GetPropertyGetFunction() { 1573 std::vector<const llvm::Type*> Params; 1574 const llvm::Type *BoolTy = 1575 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1576 Params.push_back(IdTy); 1577 Params.push_back(SelectorTy); 1578 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1579 Params.push_back(LongTy); 1580 Params.push_back(BoolTy); 1581 // void objc_getProperty (id, SEL, ptrdiff_t, bool) 1582 const llvm::FunctionType *FTy = 1583 llvm::FunctionType::get(IdTy, Params, false); 1584 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1585 "objc_getProperty")); 1586} 1587 1588llvm::Function *CGObjCGNU::GetPropertySetFunction() { 1589 std::vector<const llvm::Type*> Params; 1590 const llvm::Type *BoolTy = 1591 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1592 Params.push_back(IdTy); 1593 Params.push_back(SelectorTy); 1594 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1595 Params.push_back(LongTy); 1596 Params.push_back(IdTy); 1597 Params.push_back(BoolTy); 1598 Params.push_back(BoolTy); 1599 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 1600 const llvm::FunctionType *FTy = 1601 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 1602 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1603 "objc_setProperty")); 1604} 1605 1606llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { 1607 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 1608 ASTContext &Ctx = CGM.getContext(); 1609 // void objc_enumerationMutation (id) 1610 llvm::SmallVector<QualType,16> Params; 1611 Params.push_back(ASTIdTy); 1612 const llvm::FunctionType *FTy = 1613 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false); 1614 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 1615} 1616 1617void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1618 const Stmt &S) { 1619 // Pointer to the personality function 1620 llvm::Constant *Personality = 1621 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 1622 true), 1623 "__gnu_objc_personality_v0"); 1624 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy); 1625 std::vector<const llvm::Type*> Params; 1626 Params.push_back(PtrTy); 1627 llvm::Value *RethrowFn = 1628 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1629 Params, false), "_Unwind_Resume"); 1630 1631 bool isTry = isa<ObjCAtTryStmt>(S); 1632 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 1633 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 1634 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 1635 llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow"); 1636 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 1637 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 1638 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 1639 1640 // @synchronized() 1641 if (!isTry) { 1642 std::vector<const llvm::Type*> Args(1, IdTy); 1643 llvm::FunctionType *FTy = 1644 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1645 llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 1646 llvm::Value *SyncArg = 1647 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1648 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1649 CGF.Builder.CreateCall(SyncEnter, SyncArg); 1650 } 1651 1652 1653 // Push an EH context entry, used for handling rethrows and jumps 1654 // through finally. 1655 CGF.PushCleanupBlock(FinallyBlock); 1656 1657 // Emit the statements in the @try {} block 1658 CGF.setInvokeDest(TryHandler); 1659 1660 CGF.EmitBlock(TryBlock); 1661 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 1662 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 1663 1664 // Jump to @finally if there is no exception 1665 CGF.EmitBranchThroughCleanup(FinallyEnd); 1666 1667 // Emit the handlers 1668 CGF.EmitBlock(TryHandler); 1669 1670 // Get the correct versions of the exception handling intrinsics 1671 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1672 llvm::Value *llvm_eh_exception = 1673 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 1674 llvm::Value *llvm_eh_selector = 1675 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 1676 llvm::Value *llvm_eh_typeid_for = 1677 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 1678 1679 // Exception object 1680 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1681 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 1682 1683 llvm::SmallVector<llvm::Value*, 8> ESelArgs; 1684 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 1685 1686 ESelArgs.push_back(Exc); 1687 ESelArgs.push_back(Personality); 1688 1689 bool HasCatchAll = false; 1690 // Only @try blocks are allowed @catch blocks, but both can have @finally 1691 if (isTry) { 1692 if (const ObjCAtCatchStmt* CatchStmt = 1693 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 1694 CGF.setInvokeDest(CatchInCatch); 1695 1696 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1697 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 1698 Handlers.push_back(std::make_pair(CatchDecl, 1699 CatchStmt->getCatchBody())); 1700 1701 // @catch() and @catch(id) both catch any ObjC exception 1702 if (!CatchDecl || CatchDecl->getType()->isObjCIdType() 1703 || CatchDecl->getType()->isObjCQualifiedIdType()) { 1704 // Use i8* null here to signal this is a catch all, not a cleanup. 1705 ESelArgs.push_back(NULLPtr); 1706 HasCatchAll = true; 1707 // No further catches after this one will ever by reached 1708 break; 1709 } 1710 1711 // All other types should be Objective-C interface pointer types. 1712 const ObjCObjectPointerType *OPT = 1713 CatchDecl->getType()->getAs<ObjCObjectPointerType>(); 1714 assert(OPT && "Invalid @catch type."); 1715 const ObjCInterfaceType *IT = 1716 OPT->getPointeeType()->getAs<ObjCInterfaceType>(); 1717 assert(IT && "Invalid @catch type."); 1718 llvm::Value *EHType = 1719 MakeConstantString(IT->getDecl()->getNameAsString()); 1720 ESelArgs.push_back(EHType); 1721 } 1722 } 1723 } 1724 1725 // We use a cleanup unless there was already a catch all. 1726 if (!HasCatchAll) { 1727 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); 1728 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 1729 } 1730 1731 // Find which handler was matched. 1732 llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector, 1733 ESelArgs.begin(), ESelArgs.end(), "selector"); 1734 1735 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 1736 const ParmVarDecl *CatchParam = Handlers[i].first; 1737 const Stmt *CatchBody = Handlers[i].second; 1738 1739 llvm::BasicBlock *Next = 0; 1740 1741 // The last handler always matches. 1742 if (i + 1 != e) { 1743 assert(CatchParam && "Only last handler can be a catch all."); 1744 1745 // Test whether this block matches the type for the selector and branch 1746 // to Match if it does, or to the next BB if it doesn't. 1747 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 1748 Next = CGF.createBasicBlock("catch.next"); 1749 llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for, 1750 CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy)); 1751 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match, 1752 Next); 1753 1754 CGF.EmitBlock(Match); 1755 } 1756 1757 if (CatchBody) { 1758 llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc, 1759 CGF.ConvertType(CatchParam->getType())); 1760 1761 // Bind the catch parameter if it exists. 1762 if (CatchParam) { 1763 // CatchParam is a ParmVarDecl because of the grammar 1764 // construction used to handle this, but for codegen purposes 1765 // we treat this as a local decl. 1766 CGF.EmitLocalBlockVarDecl(*CatchParam); 1767 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 1768 } 1769 1770 CGF.ObjCEHValueStack.push_back(ExcObject); 1771 CGF.EmitStmt(CatchBody); 1772 CGF.ObjCEHValueStack.pop_back(); 1773 1774 CGF.EmitBranchThroughCleanup(FinallyEnd); 1775 1776 if (Next) 1777 CGF.EmitBlock(Next); 1778 } else { 1779 assert(!Next && "catchup should be last handler."); 1780 1781 CGF.Builder.CreateStore(Exc, RethrowPtr); 1782 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1783 } 1784 } 1785 // The @finally block is a secondary landing pad for any exceptions thrown in 1786 // @catch() blocks 1787 CGF.EmitBlock(CatchInCatch); 1788 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1789 ESelArgs.clear(); 1790 ESelArgs.push_back(Exc); 1791 ESelArgs.push_back(Personality); 1792 // If there is a @catch or @finally clause in outside of this one then we 1793 // need to make sure that we catch and rethrow it. 1794 if (PrevLandingPad) { 1795 ESelArgs.push_back(NULLPtr); 1796 } else { 1797 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); 1798 } 1799 CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(), 1800 "selector"); 1801 CGF.Builder.CreateCall(llvm_eh_typeid_for, 1802 CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy)); 1803 CGF.Builder.CreateStore(Exc, RethrowPtr); 1804 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1805 1806 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 1807 1808 CGF.setInvokeDest(PrevLandingPad); 1809 1810 CGF.EmitBlock(FinallyBlock); 1811 1812 1813 if (isTry) { 1814 if (const ObjCAtFinallyStmt* FinallyStmt = 1815 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 1816 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1817 } else { 1818 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 1819 // @synchronized. 1820 std::vector<const llvm::Type*> Args(1, IdTy); 1821 llvm::FunctionType *FTy = 1822 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1823 llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 1824 llvm::Value *SyncArg = 1825 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1826 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1827 CGF.Builder.CreateCall(SyncExit, SyncArg); 1828 } 1829 1830 if (Info.SwitchBlock) 1831 CGF.EmitBlock(Info.SwitchBlock); 1832 if (Info.EndBlock) 1833 CGF.EmitBlock(Info.EndBlock); 1834 1835 // Branch around the rethrow code. 1836 CGF.EmitBranch(FinallyEnd); 1837 1838 CGF.EmitBlock(FinallyRethrow); 1839 1840 llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr); 1841 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1842 if (!UnwindBB) { 1843 CGF.Builder.CreateCall(RethrowFn, ExceptionObject); 1844 // Exception always thrown, next instruction is never reached. 1845 CGF.Builder.CreateUnreachable(); 1846 } else { 1847 // If there is a @catch block outside this scope, we invoke instead of 1848 // calling because we may return to this function. This is very slow, but 1849 // some people still do it. It would be nice to add an optimised path for 1850 // this. 1851 CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject, 1852 &ExceptionObject+1); 1853 } 1854 1855 CGF.EmitBlock(FinallyEnd); 1856} 1857 1858void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1859 const ObjCAtThrowStmt &S) { 1860 llvm::Value *ExceptionAsObject; 1861 1862 std::vector<const llvm::Type*> Args(1, IdTy); 1863 llvm::FunctionType *FTy = 1864 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1865 llvm::Value *ThrowFn = 1866 CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 1867 1868 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1869 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1870 ExceptionAsObject = Exception; 1871 } else { 1872 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 1873 "Unexpected rethrow outside @catch block."); 1874 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 1875 } 1876 ExceptionAsObject = 1877 CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp"); 1878 1879 // Note: This may have to be an invoke, if we want to support constructs like: 1880 // @try { 1881 // @throw(obj); 1882 // } 1883 // @catch(id) ... 1884 // 1885 // This is effectively turning @throw into an incredibly-expensive goto, but 1886 // it may happen as a result of inlining followed by missed optimizations, or 1887 // as a result of stupidity. 1888 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1889 if (!UnwindBB) { 1890 CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject); 1891 CGF.Builder.CreateUnreachable(); 1892 } else { 1893 CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject, 1894 &ExceptionAsObject+1); 1895 } 1896 // Clear the insertion point to indicate we are in unreachable code. 1897 CGF.Builder.ClearInsertionPoint(); 1898} 1899 1900llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1901 llvm::Value *AddrWeakObj) { 1902 return 0; 1903} 1904 1905void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1906 llvm::Value *src, llvm::Value *dst) { 1907 return; 1908} 1909 1910void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1911 llvm::Value *src, llvm::Value *dst) { 1912 return; 1913} 1914 1915void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1916 llvm::Value *src, llvm::Value *dst, 1917 llvm::Value *ivarOffset) { 1918 return; 1919} 1920 1921void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1922 llvm::Value *src, llvm::Value *dst) { 1923 return; 1924} 1925 1926void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1927 llvm::Value *DestPtr, 1928 llvm::Value *SrcPtr, 1929 QualType Ty) { 1930 return; 1931} 1932 1933llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( 1934 const ObjCInterfaceDecl *ID, 1935 const ObjCIvarDecl *Ivar) { 1936 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 1937 + '.' + Ivar->getNameAsString(); 1938 // Emit the variable and initialize it with what we think the correct value 1939 // is. This allows code compiled with non-fragile ivars to work correctly 1940 // when linked against code which isn't (most of the time). 1941 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); 1942 if (!IvarOffsetPointer) { 1943 uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); 1944 llvm::ConstantInt *OffsetGuess = 1945 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar"); 1946 // Don't emit the guess in non-PIC code because the linker will not be able 1947 // to replace it with the real version for a library. In non-PIC code you 1948 // must compile with the fragile ABI if you want to use ivars from a 1949 // GCC-compiled class. 1950 if (CGM.getLangOptions().PICLevel) { 1951 llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule, 1952 llvm::Type::getInt32Ty(VMContext), false, 1953 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess"); 1954 IvarOffsetPointer = new llvm::GlobalVariable(TheModule, 1955 IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage, 1956 IvarOffsetGV, Name); 1957 } else { 1958 IvarOffsetPointer = new llvm::GlobalVariable(TheModule, 1959 llvm::Type::getInt32PtrTy(VMContext), false, 1960 llvm::GlobalValue::ExternalLinkage, 0, Name); 1961 } 1962 } 1963 return IvarOffsetPointer; 1964} 1965 1966LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1967 QualType ObjectTy, 1968 llvm::Value *BaseValue, 1969 const ObjCIvarDecl *Ivar, 1970 unsigned CVRQualifiers) { 1971 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl(); 1972 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 1973 EmitIvarOffset(CGF, ID, Ivar)); 1974} 1975 1976static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 1977 const ObjCInterfaceDecl *OID, 1978 const ObjCIvarDecl *OIVD) { 1979 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 1980 Context.ShallowCollectObjCIvars(OID, Ivars); 1981 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 1982 if (OIVD == Ivars[k]) 1983 return OID; 1984 } 1985 1986 // Otherwise check in the super class. 1987 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1988 return FindIvarInterface(Context, Super, OIVD); 1989 1990 return 0; 1991} 1992 1993llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1994 const ObjCInterfaceDecl *Interface, 1995 const ObjCIvarDecl *Ivar) { 1996 if (CGM.getLangOptions().ObjCNonFragileABI) { 1997 Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); 1998 return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad( 1999 ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar")); 2000 } 2001 uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); 2002 return llvm::ConstantInt::get(LongTy, Offset, "ivar"); 2003} 2004 2005CodeGen::CGObjCRuntime * 2006CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) { 2007 return new CGObjCGNU(CGM); 2008} 2009