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