CGObjCGNU.cpp revision 42ba04a072c69d84a6660e4498215086662910ac
1//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This provides Objective-C code generation targetting the GNU runtime. The 11// class in this file generates structures used by the GNU Objective-C runtime 12// library. These structures are defined in objc/objc.h and objc/objc-api.h in 13// the GNU runtime distribution. 14// 15//===----------------------------------------------------------------------===// 16 17#include "CGObjCRuntime.h" 18#include "CodeGenModule.h" 19#include "CodeGenFunction.h" 20 21#include "clang/AST/ASTContext.h" 22#include "clang/AST/Decl.h" 23#include "clang/AST/DeclObjC.h" 24#include "clang/AST/RecordLayout.h" 25#include "clang/AST/StmtObjC.h" 26 27#include "llvm/Intrinsics.h" 28#include "llvm/Module.h" 29#include "llvm/ADT/SmallVector.h" 30#include "llvm/ADT/StringMap.h" 31#include "llvm/Support/Compiler.h" 32#include "llvm/Target/TargetData.h" 33 34#include <map> 35 36 37using namespace clang; 38using namespace CodeGen; 39using llvm::dyn_cast; 40 41// The version of the runtime that this class targets. Must match the version 42// in the runtime. 43static const int RuntimeVersion = 8; 44static const int NonFragileRuntimeVersion = 9; 45static const int ProtocolVersion = 2; 46static const int NonFragileProtocolVersion = 3; 47 48namespace { 49class CGObjCGNU : public CodeGen::CGObjCRuntime { 50private: 51 CodeGen::CodeGenModule &CGM; 52 llvm::Module &TheModule; 53 const llvm::PointerType *SelectorTy; 54 const llvm::IntegerType *Int8Ty; 55 const llvm::PointerType *PtrToInt8Ty; 56 const llvm::FunctionType *IMPTy; 57 const llvm::PointerType *IdTy; 58 const llvm::PointerType *PtrToIdTy; 59 CanQualType ASTIdTy; 60 const llvm::IntegerType *IntTy; 61 const llvm::PointerType *PtrTy; 62 const llvm::IntegerType *LongTy; 63 const llvm::PointerType *PtrToIntTy; 64 llvm::GlobalAlias *ClassPtrAlias; 65 llvm::GlobalAlias *MetaClassPtrAlias; 66 std::vector<llvm::Constant*> Classes; 67 std::vector<llvm::Constant*> Categories; 68 std::vector<llvm::Constant*> ConstantStrings; 69 llvm::StringMap<llvm::Constant*> ObjCStrings; 70 llvm::Function *LoadFunction; 71 llvm::StringMap<llvm::Constant*> ExistingProtocols; 72 typedef std::pair<std::string, std::string> TypedSelector; 73 std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors; 74 llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors; 75 // Selectors that we don't emit in GC mode 76 Selector RetainSel, ReleaseSel, AutoreleaseSel; 77 // Functions used for GC. 78 llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn, 79 *WeakAssignFn, *GlobalAssignFn; 80 // Some zeros used for GEPs in lots of places. 81 llvm::Constant *Zeros[2]; 82 llvm::Constant *NULLPtr; 83 llvm::LLVMContext &VMContext; 84private: 85 llvm::Constant *GenerateIvarList( 86 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 87 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 88 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets); 89 llvm::Constant *GenerateMethodList(const std::string &ClassName, 90 const std::string &CategoryName, 91 const llvm::SmallVectorImpl<Selector> &MethodSels, 92 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 93 bool isClassMethodList); 94 llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName); 95 llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID, 96 llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 97 llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes); 98 llvm::Constant *GenerateProtocolList( 99 const llvm::SmallVectorImpl<std::string> &Protocols); 100 // To ensure that all protocols are seen by the runtime, we add a category on 101 // a class defined in the runtime, declaring no methods, but adopting the 102 // protocols. 103 void GenerateProtocolHolderCategory(void); 104 llvm::Constant *GenerateClassStructure( 105 llvm::Constant *MetaClass, 106 llvm::Constant *SuperClass, 107 unsigned info, 108 const char *Name, 109 llvm::Constant *Version, 110 llvm::Constant *InstanceSize, 111 llvm::Constant *IVars, 112 llvm::Constant *Methods, 113 llvm::Constant *Protocols, 114 llvm::Constant *IvarOffsets, 115 llvm::Constant *Properties); 116 llvm::Constant *GenerateProtocolMethodList( 117 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 118 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes); 119 llvm::Constant *MakeConstantString(const std::string &Str, const std::string 120 &Name=""); 121 llvm::Constant *ExportUniqueString(const std::string &Str, const std::string 122 prefix); 123 llvm::Constant *MakeGlobal(const llvm::StructType *Ty, 124 std::vector<llvm::Constant*> &V, llvm::StringRef Name="", 125 llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage); 126 llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty, 127 std::vector<llvm::Constant*> &V, llvm::StringRef Name="", 128 llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage); 129 llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 130 const ObjCIvarDecl *Ivar); 131 void EmitClassRef(const std::string &className); 132 llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){ 133 if (V->getType() == Ty) return V; 134 return B.CreateBitCast(V, Ty); 135 } 136public: 137 CGObjCGNU(CodeGen::CodeGenModule &cgm); 138 virtual llvm::Constant *GenerateConstantString(const StringLiteral *); 139 virtual CodeGen::RValue 140 GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 141 QualType ResultType, 142 Selector Sel, 143 llvm::Value *Receiver, 144 bool IsClassMessage, 145 const CallArgList &CallArgs, 146 const ObjCMethodDecl *Method); 147 virtual CodeGen::RValue 148 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 149 QualType ResultType, 150 Selector Sel, 151 const ObjCInterfaceDecl *Class, 152 bool isCategoryImpl, 153 llvm::Value *Receiver, 154 bool IsClassMessage, 155 const CallArgList &CallArgs, 156 const ObjCMethodDecl *Method); 157 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 158 const ObjCInterfaceDecl *OID); 159 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 160 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 161 *Method); 162 163 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 164 const ObjCContainerDecl *CD); 165 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 166 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 167 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 168 const ObjCProtocolDecl *PD); 169 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 170 virtual llvm::Function *ModuleInitFunction(); 171 virtual llvm::Function *GetPropertyGetFunction(); 172 virtual llvm::Function *GetPropertySetFunction(); 173 virtual llvm::Constant *EnumerationMutationFunction(); 174 175 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 176 const Stmt &S); 177 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 178 const ObjCAtThrowStmt &S); 179 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 180 llvm::Value *AddrWeakObj); 181 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 182 llvm::Value *src, llvm::Value *dst); 183 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 184 llvm::Value *src, llvm::Value *dest); 185 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 186 llvm::Value *src, llvm::Value *dest, 187 llvm::Value *ivarOffset); 188 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 189 llvm::Value *src, llvm::Value *dest); 190 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 191 llvm::Value *DestPtr, 192 llvm::Value *SrcPtr, 193 QualType Ty); 194 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 195 QualType ObjectTy, 196 llvm::Value *BaseValue, 197 const ObjCIvarDecl *Ivar, 198 unsigned CVRQualifiers); 199 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 200 const ObjCInterfaceDecl *Interface, 201 const ObjCIvarDecl *Ivar); 202}; 203} // end anonymous namespace 204 205 206/// Emits a reference to a dummy variable which is emitted with each class. 207/// This ensures that a linker error will be generated when trying to link 208/// together modules where a referenced class is not defined. 209void CGObjCGNU::EmitClassRef(const std::string &className) { 210 std::string symbolRef = "__objc_class_ref_" + className; 211 // Don't emit two copies of the same symbol 212 if (TheModule.getGlobalVariable(symbolRef)) 213 return; 214 std::string symbolName = "__objc_class_name_" + className; 215 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName); 216 if (!ClassSymbol) { 217 ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, 218 llvm::GlobalValue::ExternalLinkage, 0, symbolName); 219 } 220 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true, 221 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef); 222} 223 224static std::string SymbolNameForClass(const std::string &ClassName) { 225 return "_OBJC_CLASS_" + ClassName; 226} 227 228static std::string SymbolNameForMethod(const std::string &ClassName, const 229 std::string &CategoryName, const std::string &MethodName, bool isClassMethod) 230{ 231 std::string MethodNameColonStripped = MethodName; 232 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(), 233 ':', '_'); 234 return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" + 235 CategoryName + "_" + MethodNameColonStripped; 236} 237 238CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) 239 : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0), 240 MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) { 241 IntTy = cast<llvm::IntegerType>( 242 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 243 LongTy = cast<llvm::IntegerType>( 244 CGM.getTypes().ConvertType(CGM.getContext().LongTy)); 245 246 Int8Ty = llvm::Type::getInt8Ty(VMContext); 247 // C string type. Used in lots of places. 248 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 249 250 Zeros[0] = llvm::ConstantInt::get(LongTy, 0); 251 Zeros[1] = Zeros[0]; 252 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty); 253 // Get the selector Type. 254 QualType selTy = CGM.getContext().getObjCSelType(); 255 if (QualType() == selTy) { 256 SelectorTy = PtrToInt8Ty; 257 } else { 258 SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy)); 259 } 260 261 PtrToIntTy = llvm::PointerType::getUnqual(IntTy); 262 PtrTy = PtrToInt8Ty; 263 264 // Object type 265 ASTIdTy = CGM.getContext().getCanonicalType(CGM.getContext().getObjCIdType()); 266 if (QualType() == ASTIdTy) { 267 IdTy = PtrToInt8Ty; 268 } else { 269 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 270 } 271 PtrToIdTy = llvm::PointerType::getUnqual(IdTy); 272 273 // IMP type 274 std::vector<const llvm::Type*> IMPArgs; 275 IMPArgs.push_back(IdTy); 276 IMPArgs.push_back(SelectorTy); 277 IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true); 278 279 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { 280 // Get selectors needed in GC mode 281 RetainSel = GetNullarySelector("retain", CGM.getContext()); 282 ReleaseSel = GetNullarySelector("release", CGM.getContext()); 283 AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext()); 284 285 // Get functions needed in GC mode 286 287 // id objc_assign_ivar(id, id, ptrdiff_t); 288 std::vector<const llvm::Type*> Args(1, IdTy); 289 Args.push_back(PtrToIdTy); 290 // FIXME: ptrdiff_t 291 Args.push_back(LongTy); 292 llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false); 293 IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 294 // id objc_assign_strongCast (id, id*) 295 Args.pop_back(); 296 FTy = llvm::FunctionType::get(IdTy, Args, false); 297 StrongCastAssignFn = 298 CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 299 // id objc_assign_global(id, id*); 300 FTy = llvm::FunctionType::get(IdTy, Args, false); 301 GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 302 // id objc_assign_weak(id, id*); 303 FTy = llvm::FunctionType::get(IdTy, Args, false); 304 WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 305 // id objc_read_weak(id*); 306 Args.clear(); 307 Args.push_back(PtrToIdTy); 308 FTy = llvm::FunctionType::get(IdTy, Args, false); 309 WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 310 // void *objc_memmove_collectable(void*, void *, size_t); 311 Args.clear(); 312 Args.push_back(PtrToInt8Ty); 313 Args.push_back(PtrToInt8Ty); 314 // FIXME: size_t 315 Args.push_back(LongTy); 316 FTy = llvm::FunctionType::get(IdTy, Args, false); 317 MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 318 } 319} 320 321// This has to perform the lookup every time, since posing and related 322// techniques can modify the name -> class mapping. 323llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, 324 const ObjCInterfaceDecl *OID) { 325 llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString()); 326 // With the incompatible ABI, this will need to be replaced with a direct 327 // reference to the class symbol. For the compatible nonfragile ABI we are 328 // still performing this lookup at run time but emitting the symbol for the 329 // class externally so that we can make the switch later. 330 EmitClassRef(OID->getNameAsString()); 331 ClassName = Builder.CreateStructGEP(ClassName, 0); 332 333 std::vector<const llvm::Type*> Params(1, PtrToInt8Ty); 334 llvm::Constant *ClassLookupFn = 335 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, 336 Params, 337 true), 338 "objc_lookup_class"); 339 return Builder.CreateCall(ClassLookupFn, ClassName); 340} 341 342llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { 343 llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; 344 if (US == 0) 345 US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), 346 llvm::GlobalValue::PrivateLinkage, 347 ".objc_untyped_selector_alias"+Sel.getAsString(), 348 NULL, &TheModule); 349 350 return Builder.CreateLoad(US); 351} 352 353llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 354 *Method) { 355 356 std::string SelName = Method->getSelector().getAsString(); 357 std::string SelTypes; 358 CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes); 359 // Typed selectors 360 TypedSelector Selector = TypedSelector(SelName, 361 SelTypes); 362 363 // If it's already cached, return it. 364 if (TypedSelectors[Selector]) { 365 return Builder.CreateLoad(TypedSelectors[Selector]); 366 } 367 368 // If it isn't, cache it. 369 llvm::GlobalAlias *Sel = new llvm::GlobalAlias( 370 llvm::PointerType::getUnqual(SelectorTy), 371 llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName, 372 NULL, &TheModule); 373 TypedSelectors[Selector] = Sel; 374 375 return Builder.CreateLoad(Sel); 376} 377 378llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, 379 const std::string &Name) { 380 llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str()); 381 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 382} 383llvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str, 384 const std::string prefix) { 385 std::string name = prefix + Str; 386 llvm::Constant *ConstStr = TheModule.getGlobalVariable(name); 387 if (!ConstStr) { 388 llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true); 389 ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true, 390 llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str); 391 } 392 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 393} 394 395llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty, 396 std::vector<llvm::Constant*> &V, llvm::StringRef Name, 397 llvm::GlobalValue::LinkageTypes linkage) { 398 llvm::Constant *C = llvm::ConstantStruct::get(Ty, V); 399 return new llvm::GlobalVariable(TheModule, Ty, false, 400 llvm::GlobalValue::InternalLinkage, C, Name); 401} 402 403llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty, 404 std::vector<llvm::Constant*> &V, llvm::StringRef Name, 405 llvm::GlobalValue::LinkageTypes linkage) { 406 llvm::Constant *C = llvm::ConstantArray::get(Ty, V); 407 return new llvm::GlobalVariable(TheModule, Ty, false, 408 llvm::GlobalValue::InternalLinkage, C, Name); 409} 410 411/// Generate an NSConstantString object. 412llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { 413 414 std::string Str(SL->getStrData(), SL->getByteLength()); 415 416 // Look for an existing one 417 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str); 418 if (old != ObjCStrings.end()) 419 return old->getValue(); 420 421 std::vector<llvm::Constant*> Ivars; 422 Ivars.push_back(NULLPtr); 423 Ivars.push_back(MakeConstantString(Str)); 424 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size())); 425 llvm::Constant *ObjCStr = MakeGlobal( 426 llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL), 427 Ivars, ".objc_str"); 428 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty); 429 ObjCStrings[Str] = ObjCStr; 430 ConstantStrings.push_back(ObjCStr); 431 return ObjCStr; 432} 433 434///Generates a message send where the super is the receiver. This is a message 435///send to self with special delivery semantics indicating which class's method 436///should be called. 437CodeGen::RValue 438CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 439 QualType ResultType, 440 Selector Sel, 441 const ObjCInterfaceDecl *Class, 442 bool isCategoryImpl, 443 llvm::Value *Receiver, 444 bool IsClassMessage, 445 const CallArgList &CallArgs, 446 const ObjCMethodDecl *Method) { 447 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { 448 if (Sel == RetainSel || Sel == AutoreleaseSel) { 449 return RValue::get(Receiver); 450 } 451 if (Sel == ReleaseSel) { 452 return RValue::get(0); 453 } 454 } 455 llvm::Value *cmd = GetSelector(CGF.Builder, Sel); 456 457 CallArgList ActualArgs; 458 459 ActualArgs.push_back( 460 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 461 ASTIdTy)); 462 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 463 CGF.getContext().getObjCSelType())); 464 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 465 466 CodeGenTypes &Types = CGM.getTypes(); 467 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, 468 CC_Default, false); 469 const llvm::FunctionType *impType = 470 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 471 472 llvm::Value *ReceiverClass = 0; 473 if (isCategoryImpl) { 474 llvm::Constant *classLookupFunction = 0; 475 std::vector<const llvm::Type*> Params; 476 Params.push_back(PtrTy); 477 if (IsClassMessage) { 478 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 479 IdTy, Params, true), "objc_get_meta_class"); 480 } else { 481 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 482 IdTy, Params, true), "objc_get_class"); 483 } 484 ReceiverClass = CGF.Builder.CreateCall(classLookupFunction, 485 MakeConstantString(Class->getNameAsString())); 486 } else { 487 // Set up global aliases for the metaclass or class pointer if they do not 488 // already exist. These will are forward-references which will be set to 489 // pointers to the class and metaclass structure created for the runtime 490 // load function. To send a message to super, we look up the value of the 491 // super_class pointer from either the class or metaclass structure. 492 if (IsClassMessage) { 493 if (!MetaClassPtrAlias) { 494 MetaClassPtrAlias = new llvm::GlobalAlias(IdTy, 495 llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" + 496 Class->getNameAsString(), NULL, &TheModule); 497 } 498 ReceiverClass = MetaClassPtrAlias; 499 } else { 500 if (!ClassPtrAlias) { 501 ClassPtrAlias = new llvm::GlobalAlias(IdTy, 502 llvm::GlobalValue::InternalLinkage, ".objc_class_ref" + 503 Class->getNameAsString(), NULL, &TheModule); 504 } 505 ReceiverClass = ClassPtrAlias; 506 } 507 } 508 // Cast the pointer to a simplified version of the class structure 509 ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass, 510 llvm::PointerType::getUnqual( 511 llvm::StructType::get(VMContext, IdTy, IdTy, NULL))); 512 // Get the superclass pointer 513 ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1); 514 // Load the superclass pointer 515 ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass); 516 // Construct the structure used to look up the IMP 517 llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext, 518 Receiver->getType(), IdTy, NULL); 519 llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy); 520 521 CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 522 CGF.Builder.CreateStore(ReceiverClass, 523 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 524 525 // Get the IMP 526 std::vector<const llvm::Type*> Params; 527 Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy)); 528 Params.push_back(SelectorTy); 529 llvm::Constant *lookupFunction = 530 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 531 llvm::PointerType::getUnqual(impType), Params, true), 532 "objc_msg_lookup_super"); 533 534 llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; 535 llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, 536 lookupArgs+2); 537 538 return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); 539} 540 541/// Generate code for a message send expression. 542CodeGen::RValue 543CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 544 QualType ResultType, 545 Selector Sel, 546 llvm::Value *Receiver, 547 bool IsClassMessage, 548 const CallArgList &CallArgs, 549 const ObjCMethodDecl *Method) { 550 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { 551 if (Sel == RetainSel || Sel == AutoreleaseSel) { 552 return RValue::get(Receiver); 553 } 554 if (Sel == ReleaseSel) { 555 return RValue::get(0); 556 } 557 } 558 CGBuilderTy &Builder = CGF.Builder; 559 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy)); 560 llvm::Value *cmd; 561 if (Method) 562 cmd = GetSelector(Builder, Method); 563 else 564 cmd = GetSelector(Builder, Sel); 565 CallArgList ActualArgs; 566 567 Receiver = Builder.CreateBitCast(Receiver, IdTy); 568 ActualArgs.push_back( 569 std::make_pair(RValue::get(Receiver), ASTIdTy)); 570 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 571 CGF.getContext().getObjCSelType())); 572 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 573 574 CodeGenTypes &Types = CGM.getTypes(); 575 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, 576 CC_Default, false); 577 const llvm::FunctionType *impType = 578 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 579 580 llvm::Value *imp; 581 // For sender-aware dispatch, we pass the sender as the third argument to a 582 // lookup function. When sending messages from C code, the sender is nil. 583 // objc_msg_lookup_sender(id *receiver, SEL selector, id sender); 584 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 585 586 std::vector<const llvm::Type*> Params; 587 llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType()); 588 Builder.CreateStore(Receiver, ReceiverPtr); 589 Params.push_back(ReceiverPtr->getType()); 590 Params.push_back(SelectorTy); 591 llvm::Value *self; 592 593 if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) { 594 self = CGF.LoadObjCSelf(); 595 } else { 596 self = llvm::ConstantPointerNull::get(IdTy); 597 } 598 599 Params.push_back(self->getType()); 600 601 // The lookup function returns a slot, which can be safely cached. 602 llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy, 603 IntTy, llvm::PointerType::getUnqual(impType), NULL); 604 llvm::Constant *lookupFunction = 605 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 606 llvm::PointerType::getUnqual(SlotTy), Params, true), 607 "objc_msg_lookup_sender"); 608 609 // The lookup function is guaranteed not to capture the receiver pointer. 610 if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) { 611 LookupFn->setDoesNotCapture(1); 612 } 613 614 llvm::Value *slot = 615 Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self); 616 imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4)); 617 // The lookup function may have changed the receiver, so make sure we use 618 // the new one. 619 ActualArgs[0] = 620 std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy); 621 } else { 622 std::vector<const llvm::Type*> Params; 623 Params.push_back(Receiver->getType()); 624 Params.push_back(SelectorTy); 625 llvm::Constant *lookupFunction = 626 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 627 llvm::PointerType::getUnqual(impType), Params, true), 628 "objc_msg_lookup"); 629 630 imp = Builder.CreateCall2(lookupFunction, Receiver, cmd); 631 } 632 633 return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); 634} 635 636/// Generates a MethodList. Used in construction of a objc_class and 637/// objc_category structures. 638llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName, 639 const std::string &CategoryName, 640 const llvm::SmallVectorImpl<Selector> &MethodSels, 641 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 642 bool isClassMethodList) { 643 if (MethodSels.empty()) 644 return NULLPtr; 645 // Get the method structure type. 646 llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext, 647 PtrToInt8Ty, // Really a selector, but the runtime creates it us. 648 PtrToInt8Ty, // Method types 649 llvm::PointerType::getUnqual(IMPTy), //Method pointer 650 NULL); 651 std::vector<llvm::Constant*> Methods; 652 std::vector<llvm::Constant*> Elements; 653 for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) { 654 Elements.clear(); 655 if (llvm::Constant *Method = 656 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName, 657 MethodSels[i].getAsString(), 658 isClassMethodList))) { 659 llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString()); 660 Elements.push_back(C); 661 Elements.push_back(MethodTypes[i]); 662 Method = llvm::ConstantExpr::getBitCast(Method, 663 llvm::PointerType::getUnqual(IMPTy)); 664 Elements.push_back(Method); 665 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements)); 666 } 667 } 668 669 // Array of method structures 670 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy, 671 Methods.size()); 672 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy, 673 Methods); 674 675 // Structure containing list pointer, array and array count 676 llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields; 677 llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext); 678 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy); 679 llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext, 680 NextPtrTy, 681 IntTy, 682 ObjCMethodArrayTy, 683 NULL); 684 // Refine next pointer type to concrete type 685 llvm::cast<llvm::OpaqueType>( 686 OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy); 687 ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get()); 688 689 Methods.clear(); 690 Methods.push_back(llvm::ConstantPointerNull::get( 691 llvm::PointerType::getUnqual(ObjCMethodListTy))); 692 Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 693 MethodTypes.size())); 694 Methods.push_back(MethodArray); 695 696 // Create an instance of the structure 697 return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list"); 698} 699 700/// Generates an IvarList. Used in construction of a objc_class. 701llvm::Constant *CGObjCGNU::GenerateIvarList( 702 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 703 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 704 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) { 705 if (IvarNames.size() == 0) 706 return NULLPtr; 707 // Get the method structure type. 708 llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext, 709 PtrToInt8Ty, 710 PtrToInt8Ty, 711 IntTy, 712 NULL); 713 std::vector<llvm::Constant*> Ivars; 714 std::vector<llvm::Constant*> Elements; 715 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { 716 Elements.clear(); 717 Elements.push_back(IvarNames[i]); 718 Elements.push_back(IvarTypes[i]); 719 Elements.push_back(IvarOffsets[i]); 720 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements)); 721 } 722 723 // Array of method structures 724 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy, 725 IvarNames.size()); 726 727 728 Elements.clear(); 729 Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size())); 730 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)); 731 // Structure containing array and array count 732 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy, 733 ObjCIvarArrayTy, 734 NULL); 735 736 // Create an instance of the structure 737 return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list"); 738} 739 740/// Generate a class structure 741llvm::Constant *CGObjCGNU::GenerateClassStructure( 742 llvm::Constant *MetaClass, 743 llvm::Constant *SuperClass, 744 unsigned info, 745 const char *Name, 746 llvm::Constant *Version, 747 llvm::Constant *InstanceSize, 748 llvm::Constant *IVars, 749 llvm::Constant *Methods, 750 llvm::Constant *Protocols, 751 llvm::Constant *IvarOffsets, 752 llvm::Constant *Properties) { 753 // Set up the class structure 754 // Note: Several of these are char*s when they should be ids. This is 755 // because the runtime performs this translation on load. 756 // 757 // Fields marked New ABI are part of the GNUstep runtime. We emit them 758 // anyway; the classes will still work with the GNU runtime, they will just 759 // be ignored. 760 llvm::StructType *ClassTy = llvm::StructType::get(VMContext, 761 PtrToInt8Ty, // class_pointer 762 PtrToInt8Ty, // super_class 763 PtrToInt8Ty, // name 764 LongTy, // version 765 LongTy, // info 766 LongTy, // instance_size 767 IVars->getType(), // ivars 768 Methods->getType(), // methods 769 // These are all filled in by the runtime, so we pretend 770 PtrTy, // dtable 771 PtrTy, // subclass_list 772 PtrTy, // sibling_class 773 PtrTy, // protocols 774 PtrTy, // gc_object_type 775 // New ABI: 776 LongTy, // abi_version 777 IvarOffsets->getType(), // ivar_offsets 778 Properties->getType(), // properties 779 NULL); 780 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); 781 // Fill in the structure 782 std::vector<llvm::Constant*> Elements; 783 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty)); 784 Elements.push_back(SuperClass); 785 Elements.push_back(MakeConstantString(Name, ".class_name")); 786 Elements.push_back(Zero); 787 Elements.push_back(llvm::ConstantInt::get(LongTy, info)); 788 Elements.push_back(InstanceSize); 789 Elements.push_back(IVars); 790 Elements.push_back(Methods); 791 Elements.push_back(NULLPtr); 792 Elements.push_back(NULLPtr); 793 Elements.push_back(NULLPtr); 794 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy)); 795 Elements.push_back(NULLPtr); 796 Elements.push_back(Zero); 797 Elements.push_back(IvarOffsets); 798 Elements.push_back(Properties); 799 // Create an instance of the structure 800 // This is now an externally visible symbol, so that we can speed up class 801 // messages in the next ABI. 802 return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name), 803 llvm::GlobalValue::ExternalLinkage); 804} 805 806llvm::Constant *CGObjCGNU::GenerateProtocolMethodList( 807 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 808 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) { 809 // Get the method structure type. 810 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext, 811 PtrToInt8Ty, // Really a selector, but the runtime does the casting for us. 812 PtrToInt8Ty, 813 NULL); 814 std::vector<llvm::Constant*> Methods; 815 std::vector<llvm::Constant*> Elements; 816 for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) { 817 Elements.clear(); 818 Elements.push_back(MethodNames[i]); 819 Elements.push_back(MethodTypes[i]); 820 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements)); 821 } 822 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy, 823 MethodNames.size()); 824 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, 825 Methods); 826 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext, 827 IntTy, ObjCMethodArrayTy, NULL); 828 Methods.clear(); 829 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size())); 830 Methods.push_back(Array); 831 return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list"); 832} 833 834// Create the protocol list structure used in classes, categories and so on 835llvm::Constant *CGObjCGNU::GenerateProtocolList( 836 const llvm::SmallVectorImpl<std::string> &Protocols) { 837 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 838 Protocols.size()); 839 llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext, 840 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 841 LongTy,//FIXME: Should be size_t 842 ProtocolArrayTy, 843 NULL); 844 std::vector<llvm::Constant*> Elements; 845 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); 846 iter != endIter ; iter++) { 847 llvm::Constant *protocol = 0; 848 llvm::StringMap<llvm::Constant*>::iterator value = 849 ExistingProtocols.find(*iter); 850 if (value == ExistingProtocols.end()) { 851 protocol = GenerateEmptyProtocol(*iter); 852 } else { 853 protocol = value->getValue(); 854 } 855 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol, 856 PtrToInt8Ty); 857 Elements.push_back(Ptr); 858 } 859 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 860 Elements); 861 Elements.clear(); 862 Elements.push_back(NULLPtr); 863 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size())); 864 Elements.push_back(ProtocolArray); 865 return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); 866} 867 868llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, 869 const ObjCProtocolDecl *PD) { 870 llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()]; 871 const llvm::Type *T = 872 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); 873 return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); 874} 875 876llvm::Constant *CGObjCGNU::GenerateEmptyProtocol( 877 const std::string &ProtocolName) { 878 llvm::SmallVector<std::string, 0> EmptyStringVector; 879 llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector; 880 881 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector); 882 llvm::Constant *MethodList = 883 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector); 884 // Protocols are objects containing lists of the methods implemented and 885 // protocols adopted. 886 llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy, 887 PtrToInt8Ty, 888 ProtocolList->getType(), 889 MethodList->getType(), 890 MethodList->getType(), 891 MethodList->getType(), 892 MethodList->getType(), 893 NULL); 894 std::vector<llvm::Constant*> Elements; 895 // The isa pointer must be set to a magic number so the runtime knows it's 896 // the correct layout. 897 int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ? 898 NonFragileProtocolVersion : ProtocolVersion; 899 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 900 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy)); 901 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 902 Elements.push_back(ProtocolList); 903 Elements.push_back(MethodList); 904 Elements.push_back(MethodList); 905 Elements.push_back(MethodList); 906 Elements.push_back(MethodList); 907 return MakeGlobal(ProtocolTy, Elements, ".objc_protocol"); 908} 909 910void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { 911 ASTContext &Context = CGM.getContext(); 912 std::string ProtocolName = PD->getNameAsString(); 913 llvm::SmallVector<std::string, 16> Protocols; 914 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(), 915 E = PD->protocol_end(); PI != E; ++PI) 916 Protocols.push_back((*PI)->getNameAsString()); 917 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames; 918 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 919 llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames; 920 llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes; 921 for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(), 922 E = PD->instmeth_end(); iter != E; iter++) { 923 std::string TypeStr; 924 Context.getObjCEncodingForMethodDecl(*iter, TypeStr); 925 if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) { 926 InstanceMethodNames.push_back( 927 MakeConstantString((*iter)->getSelector().getAsString())); 928 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 929 } else { 930 OptionalInstanceMethodNames.push_back( 931 MakeConstantString((*iter)->getSelector().getAsString())); 932 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 933 } 934 } 935 // Collect information about class methods: 936 llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames; 937 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 938 llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames; 939 llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes; 940 for (ObjCProtocolDecl::classmeth_iterator 941 iter = PD->classmeth_begin(), endIter = PD->classmeth_end(); 942 iter != endIter ; iter++) { 943 std::string TypeStr; 944 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 945 if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) { 946 ClassMethodNames.push_back( 947 MakeConstantString((*iter)->getSelector().getAsString())); 948 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 949 } else { 950 OptionalClassMethodNames.push_back( 951 MakeConstantString((*iter)->getSelector().getAsString())); 952 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr)); 953 } 954 } 955 956 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 957 llvm::Constant *InstanceMethodList = 958 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes); 959 llvm::Constant *ClassMethodList = 960 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes); 961 llvm::Constant *OptionalInstanceMethodList = 962 GenerateProtocolMethodList(OptionalInstanceMethodNames, 963 OptionalInstanceMethodTypes); 964 llvm::Constant *OptionalClassMethodList = 965 GenerateProtocolMethodList(OptionalClassMethodNames, 966 OptionalClassMethodTypes); 967 968 // Property metadata: name, attributes, isSynthesized, setter name, setter 969 // types, getter name, getter types. 970 // The isSynthesized value is always set to 0 in a protocol. It exists to 971 // simplify the runtime library by allowing it to use the same data 972 // structures for protocol metadata everywhere. 973 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext, 974 PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, 975 PtrToInt8Ty, NULL); 976 std::vector<llvm::Constant*> Properties; 977 std::vector<llvm::Constant*> OptionalProperties; 978 979 // Add all of the property methods need adding to the method list and to the 980 // property metadata list. 981 for (ObjCContainerDecl::prop_iterator 982 iter = PD->prop_begin(), endIter = PD->prop_end(); 983 iter != endIter ; iter++) { 984 std::vector<llvm::Constant*> Fields; 985 ObjCPropertyDecl *property = (*iter); 986 987 Fields.push_back(MakeConstantString(property->getNameAsString())); 988 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 989 property->getPropertyAttributes())); 990 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0)); 991 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 992 std::string TypeStr; 993 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 994 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 995 InstanceMethodTypes.push_back(TypeEncoding); 996 Fields.push_back(MakeConstantString(getter->getSelector().getAsString())); 997 Fields.push_back(TypeEncoding); 998 } else { 999 Fields.push_back(NULLPtr); 1000 Fields.push_back(NULLPtr); 1001 } 1002 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 1003 std::string TypeStr; 1004 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 1005 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 1006 InstanceMethodTypes.push_back(TypeEncoding); 1007 Fields.push_back(MakeConstantString(setter->getSelector().getAsString())); 1008 Fields.push_back(TypeEncoding); 1009 } else { 1010 Fields.push_back(NULLPtr); 1011 Fields.push_back(NULLPtr); 1012 } 1013 if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) { 1014 OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 1015 } else { 1016 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 1017 } 1018 } 1019 llvm::Constant *PropertyArray = llvm::ConstantArray::get( 1020 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties); 1021 llvm::Constant* PropertyListInitFields[] = 1022 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray}; 1023 1024 llvm::Constant *PropertyListInit = 1025 llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false); 1026 llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule, 1027 PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage, 1028 PropertyListInit, ".objc_property_list"); 1029 1030 llvm::Constant *OptionalPropertyArray = 1031 llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy, 1032 OptionalProperties.size()) , OptionalProperties); 1033 llvm::Constant* OptionalPropertyListInitFields[] = { 1034 llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr, 1035 OptionalPropertyArray }; 1036 1037 llvm::Constant *OptionalPropertyListInit = 1038 llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false); 1039 llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule, 1040 OptionalPropertyListInit->getType(), false, 1041 llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit, 1042 ".objc_property_list"); 1043 1044 // Protocols are objects containing lists of the methods implemented and 1045 // protocols adopted. 1046 llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy, 1047 PtrToInt8Ty, 1048 ProtocolList->getType(), 1049 InstanceMethodList->getType(), 1050 ClassMethodList->getType(), 1051 OptionalInstanceMethodList->getType(), 1052 OptionalClassMethodList->getType(), 1053 PropertyList->getType(), 1054 OptionalPropertyList->getType(), 1055 NULL); 1056 std::vector<llvm::Constant*> Elements; 1057 // The isa pointer must be set to a magic number so the runtime knows it's 1058 // the correct layout. 1059 int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ? 1060 NonFragileProtocolVersion : ProtocolVersion; 1061 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 1062 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy)); 1063 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 1064 Elements.push_back(ProtocolList); 1065 Elements.push_back(InstanceMethodList); 1066 Elements.push_back(ClassMethodList); 1067 Elements.push_back(OptionalInstanceMethodList); 1068 Elements.push_back(OptionalClassMethodList); 1069 Elements.push_back(PropertyList); 1070 Elements.push_back(OptionalPropertyList); 1071 ExistingProtocols[ProtocolName] = 1072 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements, 1073 ".objc_protocol"), IdTy); 1074} 1075void CGObjCGNU::GenerateProtocolHolderCategory(void) { 1076 // Collect information about instance methods 1077 llvm::SmallVector<Selector, 1> MethodSels; 1078 llvm::SmallVector<llvm::Constant*, 1> MethodTypes; 1079 1080 std::vector<llvm::Constant*> Elements; 1081 const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack"; 1082 const std::string CategoryName = "AnotherHack"; 1083 Elements.push_back(MakeConstantString(CategoryName)); 1084 Elements.push_back(MakeConstantString(ClassName)); 1085 // Instance method list 1086 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1087 ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy)); 1088 // Class method list 1089 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1090 ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy)); 1091 // Protocol list 1092 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy, 1093 ExistingProtocols.size()); 1094 llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext, 1095 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 1096 LongTy,//FIXME: Should be size_t 1097 ProtocolArrayTy, 1098 NULL); 1099 std::vector<llvm::Constant*> ProtocolElements; 1100 for (llvm::StringMapIterator<llvm::Constant*> iter = 1101 ExistingProtocols.begin(), endIter = ExistingProtocols.end(); 1102 iter != endIter ; iter++) { 1103 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(), 1104 PtrTy); 1105 ProtocolElements.push_back(Ptr); 1106 } 1107 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 1108 ProtocolElements); 1109 ProtocolElements.clear(); 1110 ProtocolElements.push_back(NULLPtr); 1111 ProtocolElements.push_back(llvm::ConstantInt::get(LongTy, 1112 ExistingProtocols.size())); 1113 ProtocolElements.push_back(ProtocolArray); 1114 Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy, 1115 ProtocolElements, ".objc_protocol_list"), PtrTy)); 1116 Categories.push_back(llvm::ConstantExpr::getBitCast( 1117 MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, 1118 PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy)); 1119} 1120 1121void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 1122 std::string ClassName = OCD->getClassInterface()->getNameAsString(); 1123 std::string CategoryName = OCD->getNameAsString(); 1124 // Collect information about instance methods 1125 llvm::SmallVector<Selector, 16> InstanceMethodSels; 1126 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 1127 for (ObjCCategoryImplDecl::instmeth_iterator 1128 iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end(); 1129 iter != endIter ; iter++) { 1130 InstanceMethodSels.push_back((*iter)->getSelector()); 1131 std::string TypeStr; 1132 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 1133 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 1134 } 1135 1136 // Collect information about class methods 1137 llvm::SmallVector<Selector, 16> ClassMethodSels; 1138 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 1139 for (ObjCCategoryImplDecl::classmeth_iterator 1140 iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end(); 1141 iter != endIter ; iter++) { 1142 ClassMethodSels.push_back((*iter)->getSelector()); 1143 std::string TypeStr; 1144 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 1145 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 1146 } 1147 1148 // Collect the names of referenced protocols 1149 llvm::SmallVector<std::string, 16> Protocols; 1150 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface(); 1151 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 1152 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 1153 E = Protos.end(); I != E; ++I) 1154 Protocols.push_back((*I)->getNameAsString()); 1155 1156 std::vector<llvm::Constant*> Elements; 1157 Elements.push_back(MakeConstantString(CategoryName)); 1158 Elements.push_back(MakeConstantString(ClassName)); 1159 // Instance method list 1160 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1161 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes, 1162 false), PtrTy)); 1163 // Class method list 1164 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 1165 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true), 1166 PtrTy)); 1167 // Protocol list 1168 Elements.push_back(llvm::ConstantExpr::getBitCast( 1169 GenerateProtocolList(Protocols), PtrTy)); 1170 Categories.push_back(llvm::ConstantExpr::getBitCast( 1171 MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, 1172 PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy)); 1173} 1174 1175llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID, 1176 llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 1177 llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) { 1178 ASTContext &Context = CGM.getContext(); 1179 // 1180 // Property metadata: name, attributes, isSynthesized, setter name, setter 1181 // types, getter name, getter types. 1182 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext, 1183 PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, 1184 PtrToInt8Ty, NULL); 1185 std::vector<llvm::Constant*> Properties; 1186 1187 1188 // Add all of the property methods need adding to the method list and to the 1189 // property metadata list. 1190 for (ObjCImplDecl::propimpl_iterator 1191 iter = OID->propimpl_begin(), endIter = OID->propimpl_end(); 1192 iter != endIter ; iter++) { 1193 std::vector<llvm::Constant*> Fields; 1194 ObjCPropertyDecl *property = (*iter)->getPropertyDecl(); 1195 ObjCPropertyImplDecl *propertyImpl = *iter; 1196 bool isSynthesized = (propertyImpl->getPropertyImplementation() == 1197 ObjCPropertyImplDecl::Synthesize); 1198 1199 Fields.push_back(MakeConstantString(property->getNameAsString())); 1200 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 1201 property->getPropertyAttributes())); 1202 Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized)); 1203 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 1204 std::string TypeStr; 1205 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 1206 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 1207 if (isSynthesized) { 1208 InstanceMethodTypes.push_back(TypeEncoding); 1209 InstanceMethodSels.push_back(getter->getSelector()); 1210 } 1211 Fields.push_back(MakeConstantString(getter->getSelector().getAsString())); 1212 Fields.push_back(TypeEncoding); 1213 } else { 1214 Fields.push_back(NULLPtr); 1215 Fields.push_back(NULLPtr); 1216 } 1217 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 1218 std::string TypeStr; 1219 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 1220 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr); 1221 if (isSynthesized) { 1222 InstanceMethodTypes.push_back(TypeEncoding); 1223 InstanceMethodSels.push_back(setter->getSelector()); 1224 } 1225 Fields.push_back(MakeConstantString(setter->getSelector().getAsString())); 1226 Fields.push_back(TypeEncoding); 1227 } else { 1228 Fields.push_back(NULLPtr); 1229 Fields.push_back(NULLPtr); 1230 } 1231 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields)); 1232 } 1233 llvm::ArrayType *PropertyArrayTy = 1234 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()); 1235 llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy, 1236 Properties); 1237 llvm::Constant* PropertyListInitFields[] = 1238 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray}; 1239 1240 llvm::Constant *PropertyListInit = 1241 llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false); 1242 return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false, 1243 llvm::GlobalValue::InternalLinkage, PropertyListInit, 1244 ".objc_property_list"); 1245} 1246 1247void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 1248 ASTContext &Context = CGM.getContext(); 1249 1250 // Get the superclass name. 1251 const ObjCInterfaceDecl * SuperClassDecl = 1252 OID->getClassInterface()->getSuperClass(); 1253 std::string SuperClassName; 1254 if (SuperClassDecl) { 1255 SuperClassName = SuperClassDecl->getNameAsString(); 1256 EmitClassRef(SuperClassName); 1257 } 1258 1259 // Get the class name 1260 ObjCInterfaceDecl *ClassDecl = 1261 const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 1262 std::string ClassName = ClassDecl->getNameAsString(); 1263 // Emit the symbol that is used to generate linker errors if this class is 1264 // referenced in other modules but not declared. 1265 std::string classSymbolName = "__objc_class_name_" + ClassName; 1266 if (llvm::GlobalVariable *symbol = 1267 TheModule.getGlobalVariable(classSymbolName)) { 1268 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0)); 1269 } else { 1270 new llvm::GlobalVariable(TheModule, LongTy, false, 1271 llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0), 1272 classSymbolName); 1273 } 1274 1275 // Get the size of instances. 1276 int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8; 1277 1278 // Collect information about instance variables. 1279 llvm::SmallVector<llvm::Constant*, 16> IvarNames; 1280 llvm::SmallVector<llvm::Constant*, 16> IvarTypes; 1281 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets; 1282 1283 std::vector<llvm::Constant*> IvarOffsetValues; 1284 1285 int superInstanceSize = !SuperClassDecl ? 0 : 1286 Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8; 1287 // For non-fragile ivars, set the instance size to 0 - {the size of just this 1288 // class}. The runtime will then set this to the correct value on load. 1289 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1290 instanceSize = 0 - (instanceSize - superInstanceSize); 1291 } 1292 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 1293 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 1294 // Store the name 1295 IvarNames.push_back(MakeConstantString((*iter)->getNameAsString())); 1296 // Get the type encoding for this ivar 1297 std::string TypeStr; 1298 Context.getObjCEncodingForType((*iter)->getType(), TypeStr); 1299 IvarTypes.push_back(MakeConstantString(TypeStr)); 1300 // Get the offset 1301 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter); 1302 uint64_t Offset = BaseOffset; 1303 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1304 Offset = BaseOffset - superInstanceSize; 1305 } 1306 IvarOffsets.push_back( 1307 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset)); 1308 IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy, 1309 false, llvm::GlobalValue::ExternalLinkage, 1310 llvm::ConstantInt::get(IntTy, BaseOffset), 1311 "__objc_ivar_offset_value_" + ClassName +"." + 1312 (*iter)->getNameAsString())); 1313 } 1314 llvm::Constant *IvarOffsetArrayInit = 1315 llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy, 1316 IvarOffsetValues.size()), IvarOffsetValues); 1317 llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule, 1318 IvarOffsetArrayInit->getType(), false, 1319 llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit, 1320 ".ivar.offsets"); 1321 1322 // Collect information about instance methods 1323 llvm::SmallVector<Selector, 16> InstanceMethodSels; 1324 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 1325 for (ObjCImplementationDecl::instmeth_iterator 1326 iter = OID->instmeth_begin(), endIter = OID->instmeth_end(); 1327 iter != endIter ; iter++) { 1328 InstanceMethodSels.push_back((*iter)->getSelector()); 1329 std::string TypeStr; 1330 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 1331 InstanceMethodTypes.push_back(MakeConstantString(TypeStr)); 1332 } 1333 1334 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels, 1335 InstanceMethodTypes); 1336 1337 1338 // Collect information about class methods 1339 llvm::SmallVector<Selector, 16> ClassMethodSels; 1340 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 1341 for (ObjCImplementationDecl::classmeth_iterator 1342 iter = OID->classmeth_begin(), endIter = OID->classmeth_end(); 1343 iter != endIter ; iter++) { 1344 ClassMethodSels.push_back((*iter)->getSelector()); 1345 std::string TypeStr; 1346 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 1347 ClassMethodTypes.push_back(MakeConstantString(TypeStr)); 1348 } 1349 // Collect the names of referenced protocols 1350 llvm::SmallVector<std::string, 16> Protocols; 1351 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 1352 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 1353 E = Protos.end(); I != E; ++I) 1354 Protocols.push_back((*I)->getNameAsString()); 1355 1356 1357 1358 // Get the superclass pointer. 1359 llvm::Constant *SuperClass; 1360 if (!SuperClassName.empty()) { 1361 SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 1362 } else { 1363 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 1364 } 1365 // Empty vector used to construct empty method lists 1366 llvm::SmallVector<llvm::Constant*, 1> empty; 1367 // Generate the method and instance variable lists 1368 llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 1369 InstanceMethodSels, InstanceMethodTypes, false); 1370 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 1371 ClassMethodSels, ClassMethodTypes, true); 1372 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 1373 IvarOffsets); 1374 // Irrespective of whether we are compiling for a fragile or non-fragile ABI, 1375 // we emit a symbol containing the offset for each ivar in the class. This 1376 // allows code compiled for the non-Fragile ABI to inherit from code compiled 1377 // for the legacy ABI, without causing problems. The converse is also 1378 // possible, but causes all ivar accesses to be fragile. 1379 int i = 0; 1380 // Offset pointer for getting at the correct field in the ivar list when 1381 // setting up the alias. These are: The base address for the global, the 1382 // ivar array (second field), the ivar in this list (set for each ivar), and 1383 // the offset (third field in ivar structure) 1384 const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext); 1385 llvm::Constant *offsetPointerIndexes[] = {Zeros[0], 1386 llvm::ConstantInt::get(IndexTy, 1), 0, 1387 llvm::ConstantInt::get(IndexTy, 2) }; 1388 1389 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 1390 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 1391 const std::string Name = "__objc_ivar_offset_" + ClassName + '.' 1392 +(*iter)->getNameAsString(); 1393 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++); 1394 // Get the correct ivar field 1395 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr( 1396 IvarList, offsetPointerIndexes, 4); 1397 // Get the existing alias, if one exists. 1398 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name); 1399 if (offset) { 1400 offset->setInitializer(offsetValue); 1401 // If this is the real definition, change its linkage type so that 1402 // different modules will use this one, rather than their private 1403 // copy. 1404 offset->setLinkage(llvm::GlobalValue::ExternalLinkage); 1405 } else { 1406 // Add a new alias if there isn't one already. 1407 offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(), 1408 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name); 1409 } 1410 } 1411 //Generate metaclass for class methods 1412 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, 1413 NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList( 1414 empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr); 1415 1416 // Generate the class structure 1417 llvm::Constant *ClassStruct = 1418 GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L, 1419 ClassName.c_str(), 0, 1420 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, 1421 MethodList, GenerateProtocolList(Protocols), IvarOffsetArray, 1422 Properties); 1423 1424 // Resolve the class aliases, if they exist. 1425 if (ClassPtrAlias) { 1426 ClassPtrAlias->setAliasee( 1427 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); 1428 ClassPtrAlias = 0; 1429 } 1430 if (MetaClassPtrAlias) { 1431 MetaClassPtrAlias->setAliasee( 1432 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); 1433 MetaClassPtrAlias = 0; 1434 } 1435 1436 // Add class structure to list to be added to the symtab later 1437 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 1438 Classes.push_back(ClassStruct); 1439} 1440 1441 1442llvm::Function *CGObjCGNU::ModuleInitFunction() { 1443 // Only emit an ObjC load function if no Objective-C stuff has been called 1444 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 1445 ExistingProtocols.empty() && TypedSelectors.empty() && 1446 UntypedSelectors.empty()) 1447 return NULL; 1448 1449 // Add all referenced protocols to a category. 1450 GenerateProtocolHolderCategory(); 1451 1452 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>( 1453 SelectorTy->getElementType()); 1454 const llvm::Type *SelStructPtrTy = SelectorTy; 1455 bool isSelOpaque = false; 1456 if (SelStructTy == 0) { 1457 SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty, 1458 PtrToInt8Ty, NULL); 1459 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); 1460 isSelOpaque = true; 1461 } 1462 1463 // Name the ObjC types to make the IR a bit easier to read 1464 TheModule.addTypeName(".objc_selector", SelStructPtrTy); 1465 TheModule.addTypeName(".objc_id", IdTy); 1466 TheModule.addTypeName(".objc_imp", IMPTy); 1467 1468 std::vector<llvm::Constant*> Elements; 1469 llvm::Constant *Statics = NULLPtr; 1470 // Generate statics list: 1471 if (ConstantStrings.size()) { 1472 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 1473 ConstantStrings.size() + 1); 1474 ConstantStrings.push_back(NULLPtr); 1475 1476 llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass; 1477 if (StringClass.empty()) StringClass = "NXConstantString"; 1478 Elements.push_back(MakeConstantString(StringClass, 1479 ".objc_static_class_name")); 1480 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, 1481 ConstantStrings)); 1482 llvm::StructType *StaticsListTy = 1483 llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL); 1484 llvm::Type *StaticsListPtrTy = 1485 llvm::PointerType::getUnqual(StaticsListTy); 1486 Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics"); 1487 llvm::ArrayType *StaticsListArrayTy = 1488 llvm::ArrayType::get(StaticsListPtrTy, 2); 1489 Elements.clear(); 1490 Elements.push_back(Statics); 1491 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy)); 1492 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr"); 1493 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy); 1494 } 1495 // Array of classes, categories, and constant objects 1496 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, 1497 Classes.size() + Categories.size() + 2); 1498 llvm::StructType *SymTabTy = llvm::StructType::get(VMContext, 1499 LongTy, SelStructPtrTy, 1500 llvm::Type::getInt16Ty(VMContext), 1501 llvm::Type::getInt16Ty(VMContext), 1502 ClassListTy, NULL); 1503 1504 Elements.clear(); 1505 // Pointer to an array of selectors used in this module. 1506 std::vector<llvm::Constant*> Selectors; 1507 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1508 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end(); 1509 iter != iterEnd ; ++iter) { 1510 Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name")); 1511 Elements.push_back(MakeConstantString(iter->first.second, 1512 ".objc_sel_types")); 1513 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1514 Elements.clear(); 1515 } 1516 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1517 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1518 iter != iterEnd; ++iter) { 1519 Elements.push_back( 1520 ExportUniqueString(iter->getKeyData(), ".objc_sel_name")); 1521 Elements.push_back(NULLPtr); 1522 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1523 Elements.clear(); 1524 } 1525 Elements.push_back(NULLPtr); 1526 Elements.push_back(NULLPtr); 1527 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1528 Elements.clear(); 1529 // Number of static selectors 1530 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() )); 1531 llvm::Constant *SelectorList = MakeGlobal( 1532 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, 1533 ".objc_selector_list"); 1534 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, 1535 SelStructPtrTy)); 1536 1537 // Now that all of the static selectors exist, create pointers to them. 1538 int index = 0; 1539 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1540 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); 1541 iter != iterEnd; ++iter) { 1542 llvm::Constant *Idxs[] = {Zeros[0], 1543 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; 1544 llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy, 1545 true, llvm::GlobalValue::InternalLinkage, 1546 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1547 ".objc_sel_ptr"); 1548 // If selectors are defined as an opaque type, cast the pointer to this 1549 // type. 1550 if (isSelOpaque) { 1551 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1552 llvm::PointerType::getUnqual(SelectorTy)); 1553 } 1554 (*iter).second->setAliasee(SelPtr); 1555 } 1556 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1557 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1558 iter != iterEnd; iter++) { 1559 llvm::Constant *Idxs[] = {Zeros[0], 1560 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; 1561 llvm::Constant *SelPtr = new llvm::GlobalVariable 1562 (TheModule, SelStructPtrTy, 1563 true, llvm::GlobalValue::InternalLinkage, 1564 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1565 ".objc_sel_ptr"); 1566 // If selectors are defined as an opaque type, cast the pointer to this 1567 // type. 1568 if (isSelOpaque) { 1569 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1570 llvm::PointerType::getUnqual(SelectorTy)); 1571 } 1572 (*iter).second->setAliasee(SelPtr); 1573 } 1574 // Number of classes defined. 1575 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext), 1576 Classes.size())); 1577 // Number of categories defined 1578 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext), 1579 Categories.size())); 1580 // Create an array of classes, then categories, then static object instances 1581 Classes.insert(Classes.end(), Categories.begin(), Categories.end()); 1582 // NULL-terminated list of static object instances (mainly constant strings) 1583 Classes.push_back(Statics); 1584 Classes.push_back(NULLPtr); 1585 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes); 1586 Elements.push_back(ClassList); 1587 // Construct the symbol table 1588 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements); 1589 1590 // The symbol table is contained in a module which has some version-checking 1591 // constants 1592 llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy, 1593 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL); 1594 Elements.clear(); 1595 // Runtime version used for compatibility checking. 1596 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1597 Elements.push_back(llvm::ConstantInt::get(LongTy, 1598 NonFragileRuntimeVersion)); 1599 } else { 1600 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion)); 1601 } 1602 // sizeof(ModuleTy) 1603 llvm::TargetData td(&TheModule); 1604 Elements.push_back(llvm::ConstantInt::get(LongTy, 1605 td.getTypeSizeInBits(ModuleTy)/8)); 1606 //FIXME: Should be the path to the file where this module was declared 1607 Elements.push_back(NULLPtr); 1608 Elements.push_back(SymTab); 1609 llvm::Value *Module = MakeGlobal(ModuleTy, Elements); 1610 1611 // Create the load function calling the runtime entry point with the module 1612 // structure 1613 llvm::Function * LoadFunction = llvm::Function::Create( 1614 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false), 1615 llvm::GlobalValue::InternalLinkage, ".objc_load_function", 1616 &TheModule); 1617 llvm::BasicBlock *EntryBB = 1618 llvm::BasicBlock::Create(VMContext, "entry", LoadFunction); 1619 CGBuilderTy Builder(VMContext); 1620 Builder.SetInsertPoint(EntryBB); 1621 1622 std::vector<const llvm::Type*> Params(1, 1623 llvm::PointerType::getUnqual(ModuleTy)); 1624 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 1625 llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class"); 1626 Builder.CreateCall(Register, Module); 1627 Builder.CreateRetVoid(); 1628 1629 return LoadFunction; 1630} 1631 1632llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 1633 const ObjCContainerDecl *CD) { 1634 const ObjCCategoryImplDecl *OCD = 1635 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); 1636 std::string CategoryName = OCD ? OCD->getNameAsString() : ""; 1637 std::string ClassName = OMD->getClassInterface()->getNameAsString(); 1638 std::string MethodName = OMD->getSelector().getAsString(); 1639 bool isClassMethod = !OMD->isInstanceMethod(); 1640 1641 CodeGenTypes &Types = CGM.getTypes(); 1642 const llvm::FunctionType *MethodTy = 1643 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 1644 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, 1645 MethodName, isClassMethod); 1646 1647 llvm::Function *Method 1648 = llvm::Function::Create(MethodTy, 1649 llvm::GlobalValue::InternalLinkage, 1650 FunctionName, 1651 &TheModule); 1652 return Method; 1653} 1654 1655llvm::Function *CGObjCGNU::GetPropertyGetFunction() { 1656 std::vector<const llvm::Type*> Params; 1657 const llvm::Type *BoolTy = 1658 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1659 Params.push_back(IdTy); 1660 Params.push_back(SelectorTy); 1661 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1662 Params.push_back(LongTy); 1663 Params.push_back(BoolTy); 1664 // void objc_getProperty (id, SEL, ptrdiff_t, bool) 1665 const llvm::FunctionType *FTy = 1666 llvm::FunctionType::get(IdTy, Params, false); 1667 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1668 "objc_getProperty")); 1669} 1670 1671llvm::Function *CGObjCGNU::GetPropertySetFunction() { 1672 std::vector<const llvm::Type*> Params; 1673 const llvm::Type *BoolTy = 1674 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1675 Params.push_back(IdTy); 1676 Params.push_back(SelectorTy); 1677 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1678 Params.push_back(LongTy); 1679 Params.push_back(IdTy); 1680 Params.push_back(BoolTy); 1681 Params.push_back(BoolTy); 1682 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 1683 const llvm::FunctionType *FTy = 1684 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 1685 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1686 "objc_setProperty")); 1687} 1688 1689llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { 1690 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 1691 ASTContext &Ctx = CGM.getContext(); 1692 // void objc_enumerationMutation (id) 1693 llvm::SmallVector<CanQualType,1> Params; 1694 Params.push_back(ASTIdTy); 1695 const llvm::FunctionType *FTy = 1696 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 1697 CC_Default, false), false); 1698 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 1699} 1700 1701void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1702 const Stmt &S) { 1703 // Pointer to the personality function 1704 llvm::Constant *Personality = 1705 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 1706 true), 1707 "__gnu_objc_personality_v0"); 1708 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy); 1709 std::vector<const llvm::Type*> Params; 1710 Params.push_back(PtrTy); 1711 llvm::Value *RethrowFn = 1712 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1713 Params, false), "_Unwind_Resume"); 1714 1715 bool isTry = isa<ObjCAtTryStmt>(S); 1716 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 1717 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 1718 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 1719 llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow"); 1720 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 1721 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 1722 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 1723 1724 // @synchronized() 1725 if (!isTry) { 1726 std::vector<const llvm::Type*> Args(1, IdTy); 1727 llvm::FunctionType *FTy = 1728 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1729 llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 1730 llvm::Value *SyncArg = 1731 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1732 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1733 CGF.Builder.CreateCall(SyncEnter, SyncArg); 1734 } 1735 1736 1737 // Push an EH context entry, used for handling rethrows and jumps 1738 // through finally. 1739 CGF.PushCleanupBlock(FinallyBlock); 1740 1741 // Emit the statements in the @try {} block 1742 CGF.setInvokeDest(TryHandler); 1743 1744 CGF.EmitBlock(TryBlock); 1745 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 1746 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 1747 1748 // Jump to @finally if there is no exception 1749 CGF.EmitBranchThroughCleanup(FinallyEnd); 1750 1751 // Emit the handlers 1752 CGF.EmitBlock(TryHandler); 1753 1754 // Get the correct versions of the exception handling intrinsics 1755 llvm::Value *llvm_eh_exception = 1756 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 1757 llvm::Value *llvm_eh_selector = 1758 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 1759 llvm::Value *llvm_eh_typeid_for = 1760 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 1761 1762 // Exception object 1763 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1764 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 1765 1766 llvm::SmallVector<llvm::Value*, 8> ESelArgs; 1767 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 1768 1769 ESelArgs.push_back(Exc); 1770 ESelArgs.push_back(Personality); 1771 1772 bool HasCatchAll = false; 1773 // Only @try blocks are allowed @catch blocks, but both can have @finally 1774 if (isTry) { 1775 if (const ObjCAtCatchStmt* CatchStmt = 1776 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 1777 CGF.setInvokeDest(CatchInCatch); 1778 1779 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1780 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 1781 Handlers.push_back(std::make_pair(CatchDecl, 1782 CatchStmt->getCatchBody())); 1783 1784 // @catch() and @catch(id) both catch any ObjC exception 1785 if (!CatchDecl || CatchDecl->getType()->isObjCIdType() 1786 || CatchDecl->getType()->isObjCQualifiedIdType()) { 1787 // Use i8* null here to signal this is a catch all, not a cleanup. 1788 ESelArgs.push_back(NULLPtr); 1789 HasCatchAll = true; 1790 // No further catches after this one will ever by reached 1791 break; 1792 } 1793 1794 // All other types should be Objective-C interface pointer types. 1795 const ObjCObjectPointerType *OPT = 1796 CatchDecl->getType()->getAs<ObjCObjectPointerType>(); 1797 assert(OPT && "Invalid @catch type."); 1798 const ObjCInterfaceType *IT = 1799 OPT->getPointeeType()->getAs<ObjCInterfaceType>(); 1800 assert(IT && "Invalid @catch type."); 1801 llvm::Value *EHType = 1802 MakeConstantString(IT->getDecl()->getNameAsString()); 1803 ESelArgs.push_back(EHType); 1804 } 1805 } 1806 } 1807 1808 // We use a cleanup unless there was already a catch all. 1809 if (!HasCatchAll) { 1810 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); 1811 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 1812 } 1813 1814 // Find which handler was matched. 1815 llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector, 1816 ESelArgs.begin(), ESelArgs.end(), "selector"); 1817 1818 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 1819 const ParmVarDecl *CatchParam = Handlers[i].first; 1820 const Stmt *CatchBody = Handlers[i].second; 1821 1822 llvm::BasicBlock *Next = 0; 1823 1824 // The last handler always matches. 1825 if (i + 1 != e) { 1826 assert(CatchParam && "Only last handler can be a catch all."); 1827 1828 // Test whether this block matches the type for the selector and branch 1829 // to Match if it does, or to the next BB if it doesn't. 1830 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 1831 Next = CGF.createBasicBlock("catch.next"); 1832 llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for, 1833 CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy)); 1834 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match, 1835 Next); 1836 1837 CGF.EmitBlock(Match); 1838 } 1839 1840 if (CatchBody) { 1841 llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc, 1842 CGF.ConvertType(CatchParam->getType())); 1843 1844 // Bind the catch parameter if it exists. 1845 if (CatchParam) { 1846 // CatchParam is a ParmVarDecl because of the grammar 1847 // construction used to handle this, but for codegen purposes 1848 // we treat this as a local decl. 1849 CGF.EmitLocalBlockVarDecl(*CatchParam); 1850 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 1851 } 1852 1853 CGF.ObjCEHValueStack.push_back(ExcObject); 1854 CGF.EmitStmt(CatchBody); 1855 CGF.ObjCEHValueStack.pop_back(); 1856 1857 CGF.EmitBranchThroughCleanup(FinallyEnd); 1858 1859 if (Next) 1860 CGF.EmitBlock(Next); 1861 } else { 1862 assert(!Next && "catchup should be last handler."); 1863 1864 CGF.Builder.CreateStore(Exc, RethrowPtr); 1865 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1866 } 1867 } 1868 // The @finally block is a secondary landing pad for any exceptions thrown in 1869 // @catch() blocks 1870 CGF.EmitBlock(CatchInCatch); 1871 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1872 ESelArgs.clear(); 1873 ESelArgs.push_back(Exc); 1874 ESelArgs.push_back(Personality); 1875 // If there is a @catch or @finally clause in outside of this one then we 1876 // need to make sure that we catch and rethrow it. 1877 if (PrevLandingPad) { 1878 ESelArgs.push_back(NULLPtr); 1879 } else { 1880 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); 1881 } 1882 CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(), 1883 "selector"); 1884 CGF.Builder.CreateCall(llvm_eh_typeid_for, 1885 CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy)); 1886 CGF.Builder.CreateStore(Exc, RethrowPtr); 1887 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1888 1889 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 1890 1891 CGF.setInvokeDest(PrevLandingPad); 1892 1893 CGF.EmitBlock(FinallyBlock); 1894 1895 1896 if (isTry) { 1897 if (const ObjCAtFinallyStmt* FinallyStmt = 1898 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 1899 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1900 } else { 1901 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 1902 // @synchronized. 1903 std::vector<const llvm::Type*> Args(1, IdTy); 1904 llvm::FunctionType *FTy = 1905 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1906 llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 1907 llvm::Value *SyncArg = 1908 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1909 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1910 CGF.Builder.CreateCall(SyncExit, SyncArg); 1911 } 1912 1913 if (Info.SwitchBlock) 1914 CGF.EmitBlock(Info.SwitchBlock); 1915 if (Info.EndBlock) 1916 CGF.EmitBlock(Info.EndBlock); 1917 1918 // Branch around the rethrow code. 1919 CGF.EmitBranch(FinallyEnd); 1920 1921 CGF.EmitBlock(FinallyRethrow); 1922 1923 llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr); 1924 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1925 if (!UnwindBB) { 1926 CGF.Builder.CreateCall(RethrowFn, ExceptionObject); 1927 // Exception always thrown, next instruction is never reached. 1928 CGF.Builder.CreateUnreachable(); 1929 } else { 1930 // If there is a @catch block outside this scope, we invoke instead of 1931 // calling because we may return to this function. This is very slow, but 1932 // some people still do it. It would be nice to add an optimised path for 1933 // this. 1934 CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject, 1935 &ExceptionObject+1); 1936 } 1937 1938 CGF.EmitBlock(FinallyEnd); 1939} 1940 1941void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1942 const ObjCAtThrowStmt &S) { 1943 llvm::Value *ExceptionAsObject; 1944 1945 std::vector<const llvm::Type*> Args(1, IdTy); 1946 llvm::FunctionType *FTy = 1947 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 1948 llvm::Value *ThrowFn = 1949 CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 1950 1951 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1952 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1953 ExceptionAsObject = Exception; 1954 } else { 1955 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 1956 "Unexpected rethrow outside @catch block."); 1957 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 1958 } 1959 ExceptionAsObject = 1960 CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp"); 1961 1962 // Note: This may have to be an invoke, if we want to support constructs like: 1963 // @try { 1964 // @throw(obj); 1965 // } 1966 // @catch(id) ... 1967 // 1968 // This is effectively turning @throw into an incredibly-expensive goto, but 1969 // it may happen as a result of inlining followed by missed optimizations, or 1970 // as a result of stupidity. 1971 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1972 if (!UnwindBB) { 1973 CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject); 1974 CGF.Builder.CreateUnreachable(); 1975 } else { 1976 CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject, 1977 &ExceptionAsObject+1); 1978 } 1979 // Clear the insertion point to indicate we are in unreachable code. 1980 CGF.Builder.ClearInsertionPoint(); 1981} 1982 1983llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1984 llvm::Value *AddrWeakObj) { 1985 CGBuilderTy B = CGF.Builder; 1986 AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy); 1987 return B.CreateCall(WeakReadFn, AddrWeakObj); 1988} 1989 1990void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1991 llvm::Value *src, llvm::Value *dst) { 1992 CGBuilderTy B = CGF.Builder; 1993 src = EnforceType(B, src, IdTy); 1994 dst = EnforceType(B, dst, PtrToIdTy); 1995 B.CreateCall2(WeakAssignFn, src, dst); 1996} 1997 1998void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1999 llvm::Value *src, llvm::Value *dst) { 2000 CGBuilderTy B = CGF.Builder; 2001 src = EnforceType(B, src, IdTy); 2002 dst = EnforceType(B, dst, PtrToIdTy); 2003 B.CreateCall2(GlobalAssignFn, src, dst); 2004} 2005 2006void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 2007 llvm::Value *src, llvm::Value *dst, 2008 llvm::Value *ivarOffset) { 2009 CGBuilderTy B = CGF.Builder; 2010 src = EnforceType(B, src, IdTy); 2011 dst = EnforceType(B, dst, PtrToIdTy); 2012 B.CreateCall3(IvarAssignFn, src, dst, ivarOffset); 2013} 2014 2015void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 2016 llvm::Value *src, llvm::Value *dst) { 2017 CGBuilderTy B = CGF.Builder; 2018 src = EnforceType(B, src, IdTy); 2019 dst = EnforceType(B, dst, PtrToIdTy); 2020 B.CreateCall2(StrongCastAssignFn, src, dst); 2021} 2022 2023void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 2024 llvm::Value *DestPtr, 2025 llvm::Value *SrcPtr, 2026 QualType Ty) { 2027 CGBuilderTy B = CGF.Builder; 2028 DestPtr = EnforceType(B, DestPtr, IdTy); 2029 SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy); 2030 2031 std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty); 2032 unsigned long size = TypeInfo.first/8; 2033 // FIXME: size_t 2034 llvm::Value *N = llvm::ConstantInt::get(LongTy, size); 2035 2036 B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N); 2037} 2038 2039llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( 2040 const ObjCInterfaceDecl *ID, 2041 const ObjCIvarDecl *Ivar) { 2042 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 2043 + '.' + Ivar->getNameAsString(); 2044 // Emit the variable and initialize it with what we think the correct value 2045 // is. This allows code compiled with non-fragile ivars to work correctly 2046 // when linked against code which isn't (most of the time). 2047 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); 2048 if (!IvarOffsetPointer) { 2049 uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); 2050 llvm::ConstantInt *OffsetGuess = 2051 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar"); 2052 // Don't emit the guess in non-PIC code because the linker will not be able 2053 // to replace it with the real version for a library. In non-PIC code you 2054 // must compile with the fragile ABI if you want to use ivars from a 2055 // GCC-compiled class. 2056 if (CGM.getLangOptions().PICLevel) { 2057 llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule, 2058 llvm::Type::getInt32Ty(VMContext), false, 2059 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess"); 2060 IvarOffsetPointer = new llvm::GlobalVariable(TheModule, 2061 IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage, 2062 IvarOffsetGV, Name); 2063 } else { 2064 IvarOffsetPointer = new llvm::GlobalVariable(TheModule, 2065 llvm::Type::getInt32PtrTy(VMContext), false, 2066 llvm::GlobalValue::ExternalLinkage, 0, Name); 2067 } 2068 } 2069 return IvarOffsetPointer; 2070} 2071 2072LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 2073 QualType ObjectTy, 2074 llvm::Value *BaseValue, 2075 const ObjCIvarDecl *Ivar, 2076 unsigned CVRQualifiers) { 2077 const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl(); 2078 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 2079 EmitIvarOffset(CGF, ID, Ivar)); 2080} 2081 2082static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 2083 const ObjCInterfaceDecl *OID, 2084 const ObjCIvarDecl *OIVD) { 2085 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 2086 Context.ShallowCollectObjCIvars(OID, Ivars); 2087 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 2088 if (OIVD == Ivars[k]) 2089 return OID; 2090 } 2091 2092 // Otherwise check in the super class. 2093 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 2094 return FindIvarInterface(Context, Super, OIVD); 2095 2096 return 0; 2097} 2098 2099llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 2100 const ObjCInterfaceDecl *Interface, 2101 const ObjCIvarDecl *Ivar) { 2102 if (CGM.getLangOptions().ObjCNonFragileABI) { 2103 Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); 2104 return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad( 2105 ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar")); 2106 } 2107 uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); 2108 return llvm::ConstantInt::get(LongTy, Offset, "ivar"); 2109} 2110 2111CodeGen::CGObjCRuntime * 2112CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) { 2113 return new CGObjCGNU(CGM); 2114} 2115