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 37 using namespace clang; 38 using namespace CodeGen; 39 using llvm::dyn_cast; 40 41 // The version of the runtime that this class targets. Must match the version 42 // in the runtime. 43 static const int RuntimeVersion = 8; 44 static const int NonFragileRuntimeVersion = 9; 45 static const int ProtocolVersion = 2; 46 47 namespace { 48 class CGObjCGNU : public CodeGen::CGObjCRuntime { 49 private: 50 CodeGen::CodeGenModule &CGM; 51 llvm::Module &TheModule; 52 const llvm::PointerType *SelectorTy; 53 const llvm::PointerType *PtrToInt8Ty; 54 const llvm::FunctionType *IMPTy; 55 const llvm::PointerType *IdTy; 56 const llvm::IntegerType *IntTy; 57 const llvm::PointerType *PtrTy; 58 const llvm::IntegerType *LongTy; 59 const llvm::PointerType *PtrToIntTy; 60 llvm::GlobalAlias *ClassPtrAlias; 61 llvm::GlobalAlias *MetaClassPtrAlias; 62 std::vector<llvm::Constant*> Classes; 63 std::vector<llvm::Constant*> Categories; 64 std::vector<llvm::Constant*> ConstantStrings; 65 llvm::Function *LoadFunction; 66 llvm::StringMap<llvm::Constant*> ExistingProtocols; 67 typedef std::pair<std::string, std::string> TypedSelector; 68 std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors; 69 llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors; 70 // Some zeros used for GEPs in lots of places. 71 llvm::Constant *Zeros[2]; 72 llvm::Constant *NULLPtr; 73 llvm::LLVMContext &VMContext; 74 private: 75 llvm::Constant *GenerateIvarList( 76 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 77 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 78 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets); 79 llvm::Constant *GenerateMethodList(const std::string &ClassName, 80 const std::string &CategoryName, 81 const llvm::SmallVectorImpl<Selector> &MethodSels, 82 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 83 bool isClassMethodList); 84 llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName); 85 llvm::Constant *GenerateProtocolList( 86 const llvm::SmallVectorImpl<std::string> &Protocols); 87 llvm::Constant *GenerateClassStructure( 88 llvm::Constant *MetaClass, 89 llvm::Constant *SuperClass, 90 unsigned info, 91 const char *Name, 92 llvm::Constant *Version, 93 llvm::Constant *InstanceSize, 94 llvm::Constant *IVars, 95 llvm::Constant *Methods, 96 llvm::Constant *Protocols); 97 llvm::Constant *GenerateProtocolMethodList( 98 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 99 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes); 100 llvm::Constant *MakeConstantString(const std::string &Str, const std::string 101 &Name=""); 102 llvm::Constant *MakeGlobal(const llvm::StructType *Ty, 103 std::vector<llvm::Constant*> &V, const std::string &Name=""); 104 llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty, 105 std::vector<llvm::Constant*> &V, const std::string &Name=""); 106 llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 107 const ObjCIvarDecl *Ivar); 108 void EmitClassRef(const std::string &className); 109 public: 110 CGObjCGNU(CodeGen::CodeGenModule &cgm); 111 virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *); 112 virtual CodeGen::RValue 113 GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 114 QualType ResultType, 115 Selector Sel, 116 llvm::Value *Receiver, 117 bool IsClassMessage, 118 const CallArgList &CallArgs, 119 const ObjCMethodDecl *Method); 120 virtual CodeGen::RValue 121 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 122 QualType ResultType, 123 Selector Sel, 124 const ObjCInterfaceDecl *Class, 125 bool isCategoryImpl, 126 llvm::Value *Receiver, 127 bool IsClassMessage, 128 const CallArgList &CallArgs); 129 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 130 const ObjCInterfaceDecl *OID); 131 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 132 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 133 *Method); 134 135 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 136 const ObjCContainerDecl *CD); 137 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 138 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 139 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 140 const ObjCProtocolDecl *PD); 141 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 142 virtual llvm::Function *ModuleInitFunction(); 143 virtual llvm::Function *GetPropertyGetFunction(); 144 virtual llvm::Function *GetPropertySetFunction(); 145 virtual llvm::Constant *EnumerationMutationFunction(); 146 147 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 148 const Stmt &S); 149 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 150 const ObjCAtThrowStmt &S); 151 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 152 llvm::Value *AddrWeakObj); 153 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 154 llvm::Value *src, llvm::Value *dst); 155 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 156 llvm::Value *src, llvm::Value *dest); 157 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 158 llvm::Value *src, llvm::Value *dest); 159 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 160 llvm::Value *src, llvm::Value *dest); 161 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 162 llvm::Value *DestPtr, 163 llvm::Value *SrcPtr, 164 unsigned long size); 165 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 166 QualType ObjectTy, 167 llvm::Value *BaseValue, 168 const ObjCIvarDecl *Ivar, 169 unsigned CVRQualifiers); 170 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 171 const ObjCInterfaceDecl *Interface, 172 const ObjCIvarDecl *Ivar); 173 }; 174 } // end anonymous namespace 175 176 177 /// Emits a reference to a dummy variable which is emitted with each class. 178 /// This ensures that a linker error will be generated when trying to link 179 /// together modules where a referenced class is not defined. 180 void CGObjCGNU::EmitClassRef(const std::string &className) { 181 std::string symbolRef = "__objc_class_ref_" + className; 182 // Don't emit two copies of the same symbol 183 if (TheModule.getGlobalVariable(symbolRef)) 184 return; 185 std::string symbolName = "__objc_class_name_" + className; 186 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName); 187 if (!ClassSymbol) { 188 ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false, 189 llvm::GlobalValue::ExternalLinkage, 0, symbolName); 190 } 191 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true, 192 llvm::GlobalValue::CommonLinkage, ClassSymbol, symbolRef); 193 } 194 195 static std::string SymbolNameForClass(const std::string &ClassName) { 196 return "_OBJC_CLASS_" + ClassName; 197 } 198 199 static std::string SymbolNameForMethod(const std::string &ClassName, const 200 std::string &CategoryName, const std::string &MethodName, bool isClassMethod) 201 { 202 return "_OBJC_METHOD_" + ClassName + "("+CategoryName+")"+ 203 (isClassMethod ? "+" : "-") + MethodName; 204 } 205 206 CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) 207 : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0), 208 MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) { 209 IntTy = cast<llvm::IntegerType>( 210 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 211 LongTy = cast<llvm::IntegerType>( 212 CGM.getTypes().ConvertType(CGM.getContext().LongTy)); 213 214 Zeros[0] = llvm::ConstantInt::get(LongTy, 0); 215 Zeros[1] = Zeros[0]; 216 NULLPtr = llvm::ConstantPointerNull::get( 217 llvm::PointerType::getUnqual(llvm::Type::Int8Ty)); 218 // C string type. Used in lots of places. 219 PtrToInt8Ty = 220 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 221 // Get the selector Type. 222 SelectorTy = cast<llvm::PointerType>( 223 CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType())); 224 225 PtrToIntTy = llvm::PointerType::getUnqual(IntTy); 226 PtrTy = PtrToInt8Ty; 227 228 // Object type 229 IdTy = cast<llvm::PointerType>( 230 CGM.getTypes().ConvertType(CGM.getContext().getObjCIdType())); 231 232 // IMP type 233 std::vector<const llvm::Type*> IMPArgs; 234 IMPArgs.push_back(IdTy); 235 IMPArgs.push_back(SelectorTy); 236 IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true); 237 } 238 239 // This has to perform the lookup every time, since posing and related 240 // techniques can modify the name -> class mapping. 241 llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, 242 const ObjCInterfaceDecl *OID) { 243 llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString()); 244 EmitClassRef(OID->getNameAsString()); 245 ClassName = Builder.CreateStructGEP(ClassName, 0); 246 247 std::vector<const llvm::Type*> Params(1, PtrToInt8Ty); 248 llvm::Constant *ClassLookupFn = 249 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, 250 Params, 251 true), 252 "objc_lookup_class"); 253 return Builder.CreateCall(ClassLookupFn, ClassName); 254 } 255 256 llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { 257 llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; 258 if (US == 0) 259 US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), 260 llvm::GlobalValue::InternalLinkage, 261 ".objc_untyped_selector_alias", 262 NULL, &TheModule); 263 264 return Builder.CreateLoad(US); 265 } 266 267 llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 268 *Method) { 269 270 std::string SelName = Method->getSelector().getAsString(); 271 std::string SelTypes; 272 CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes); 273 // Typed selectors 274 TypedSelector Selector = TypedSelector(SelName, 275 SelTypes); 276 277 // If it's already cached, return it. 278 if (TypedSelectors[Selector]) { 279 return Builder.CreateLoad(TypedSelectors[Selector]); 280 } 281 282 // If it isn't, cache it. 283 llvm::GlobalAlias *Sel = new llvm::GlobalAlias( 284 llvm::PointerType::getUnqual(SelectorTy), 285 llvm::GlobalValue::InternalLinkage, SelName, 286 NULL, &TheModule); 287 TypedSelectors[Selector] = Sel; 288 289 return Builder.CreateLoad(Sel); 290 } 291 292 llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, 293 const std::string &Name) { 294 llvm::Constant * ConstStr = llvm::ConstantArray::get(Str); 295 ConstStr = new llvm::GlobalVariable(TheModule, ConstStr->getType(), true, 296 llvm::GlobalValue::InternalLinkage, 297 ConstStr, Name); 298 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 299 } 300 301 llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty, 302 std::vector<llvm::Constant*> &V, const std::string &Name) { 303 llvm::Constant *C = llvm::ConstantStruct::get(Ty, V); 304 return new llvm::GlobalVariable(TheModule, Ty, false, 305 llvm::GlobalValue::InternalLinkage, C, Name); 306 } 307 308 llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty, 309 std::vector<llvm::Constant*> &V, const std::string &Name) { 310 llvm::Constant *C = llvm::ConstantArray::get(Ty, V); 311 return new llvm::GlobalVariable(TheModule, Ty, false, 312 llvm::GlobalValue::InternalLinkage, C, Name); 313 } 314 315 /// Generate an NSConstantString object. 316 //TODO: In case there are any crazy people still using the GNU runtime without 317 //an OpenStep implementation, this should let them select their own class for 318 //constant strings. 319 llvm::Constant *CGObjCGNU::GenerateConstantString(const ObjCStringLiteral *SL) { 320 std::string Str(SL->getString()->getStrData(), 321 SL->getString()->getByteLength()); 322 std::vector<llvm::Constant*> Ivars; 323 Ivars.push_back(NULLPtr); 324 Ivars.push_back(MakeConstantString(Str)); 325 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size())); 326 llvm::Constant *ObjCStr = MakeGlobal( 327 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL), 328 Ivars, ".objc_str"); 329 ConstantStrings.push_back( 330 llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty)); 331 return ObjCStr; 332 } 333 334 ///Generates a message send where the super is the receiver. This is a message 335 ///send to self with special delivery semantics indicating which class's method 336 ///should be called. 337 CodeGen::RValue 338 CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 339 QualType ResultType, 340 Selector Sel, 341 const ObjCInterfaceDecl *Class, 342 bool isCategoryImpl, 343 llvm::Value *Receiver, 344 bool IsClassMessage, 345 const CallArgList &CallArgs) { 346 llvm::Value *cmd = GetSelector(CGF.Builder, Sel); 347 348 CallArgList ActualArgs; 349 350 ActualArgs.push_back( 351 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 352 CGF.getContext().getObjCIdType())); 353 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 354 CGF.getContext().getObjCSelType())); 355 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 356 357 CodeGenTypes &Types = CGM.getTypes(); 358 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 359 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false); 360 361 llvm::Value *ReceiverClass = 0; 362 if (isCategoryImpl) { 363 llvm::Constant *classLookupFunction = 0; 364 std::vector<const llvm::Type*> Params; 365 Params.push_back(PtrTy); 366 if (IsClassMessage) { 367 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 368 IdTy, Params, true), "objc_get_meta_class"); 369 } else { 370 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 371 IdTy, Params, true), "objc_get_class"); 372 } 373 ReceiverClass = CGF.Builder.CreateCall(classLookupFunction, 374 MakeConstantString(Class->getNameAsString())); 375 } else { 376 // Set up global aliases for the metaclass or class pointer if they do not 377 // already exist. These will are forward-references which will be set to 378 // pointers to the class and metaclass structure created for the runtime 379 // load function. To send a message to super, we look up the value of the 380 // super_class pointer from either the class or metaclass structure. 381 if (IsClassMessage) { 382 if (!MetaClassPtrAlias) { 383 MetaClassPtrAlias = new llvm::GlobalAlias(IdTy, 384 llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" + 385 Class->getNameAsString(), NULL, &TheModule); 386 } 387 ReceiverClass = MetaClassPtrAlias; 388 } else { 389 if (!ClassPtrAlias) { 390 ClassPtrAlias = new llvm::GlobalAlias(IdTy, 391 llvm::GlobalValue::InternalLinkage, ".objc_class_ref" + 392 Class->getNameAsString(), NULL, &TheModule); 393 } 394 ReceiverClass = ClassPtrAlias; 395 } 396 } 397 // Cast the pointer to a simplified version of the class structure 398 ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass, 399 llvm::PointerType::getUnqual( 400 llvm::StructType::get(IdTy, IdTy, NULL))); 401 // Get the superclass pointer 402 ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1); 403 // Load the superclass pointer 404 ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass); 405 // Construct the structure used to look up the IMP 406 llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(), 407 IdTy, NULL); 408 llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy); 409 410 CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 411 CGF.Builder.CreateStore(ReceiverClass, 412 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 413 414 // Get the IMP 415 std::vector<const llvm::Type*> Params; 416 Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy)); 417 Params.push_back(SelectorTy); 418 llvm::Constant *lookupFunction = 419 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 420 llvm::PointerType::getUnqual(impType), Params, true), 421 "objc_msg_lookup_super"); 422 423 llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; 424 llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, 425 lookupArgs+2); 426 427 return CGF.EmitCall(FnInfo, imp, ActualArgs); 428 } 429 430 /// Generate code for a message send expression. 431 CodeGen::RValue 432 CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 433 QualType ResultType, 434 Selector Sel, 435 llvm::Value *Receiver, 436 bool IsClassMessage, 437 const CallArgList &CallArgs, 438 const ObjCMethodDecl *Method) { 439 llvm::Value *cmd; 440 if (Method) 441 cmd = GetSelector(CGF.Builder, Method); 442 else 443 cmd = GetSelector(CGF.Builder, Sel); 444 CallArgList ActualArgs; 445 446 ActualArgs.push_back( 447 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 448 CGF.getContext().getObjCIdType())); 449 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 450 CGF.getContext().getObjCSelType())); 451 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 452 453 CodeGenTypes &Types = CGM.getTypes(); 454 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 455 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false); 456 457 llvm::Value *imp; 458 std::vector<const llvm::Type*> Params; 459 Params.push_back(Receiver->getType()); 460 Params.push_back(SelectorTy); 461 // For sender-aware dispatch, we pass the sender as the third argument to a 462 // lookup function. When sending messages from C code, the sender is nil. 463 // objc_msg_lookup_sender(id receiver, SEL selector, id sender); 464 if (CGM.getContext().getLangOptions().ObjCSenderDispatch) { 465 llvm::Value *self; 466 467 if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) { 468 self = CGF.LoadObjCSelf(); 469 } else { 470 self = llvm::ConstantPointerNull::get(IdTy); 471 } 472 Params.push_back(self->getType()); 473 llvm::Constant *lookupFunction = 474 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 475 llvm::PointerType::getUnqual(impType), Params, true), 476 "objc_msg_lookup_sender"); 477 478 imp = CGF.Builder.CreateCall3(lookupFunction, Receiver, cmd, self); 479 } else { 480 llvm::Constant *lookupFunction = 481 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 482 llvm::PointerType::getUnqual(impType), Params, true), 483 "objc_msg_lookup"); 484 485 imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd); 486 } 487 488 return CGF.EmitCall(FnInfo, imp, ActualArgs); 489 } 490 491 /// Generates a MethodList. Used in construction of a objc_class and 492 /// objc_category structures. 493 llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName, 494 const std::string &CategoryName, 495 const llvm::SmallVectorImpl<Selector> &MethodSels, 496 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 497 bool isClassMethodList) { 498 // Get the method structure type. 499 llvm::StructType *ObjCMethodTy = llvm::StructType::get( 500 PtrToInt8Ty, // Really a selector, but the runtime creates it us. 501 PtrToInt8Ty, // Method types 502 llvm::PointerType::getUnqual(IMPTy), //Method pointer 503 NULL); 504 std::vector<llvm::Constant*> Methods; 505 std::vector<llvm::Constant*> Elements; 506 for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) { 507 Elements.clear(); 508 if (llvm::Constant *Method = 509 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName, 510 MethodSels[i].getAsString(), 511 isClassMethodList))) { 512 llvm::Constant *C = 513 CGM.GetAddrOfConstantCString(MethodSels[i].getAsString()); 514 Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2)); 515 Elements.push_back( 516 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2)); 517 Method = llvm::ConstantExpr::getBitCast(Method, 518 llvm::PointerType::getUnqual(IMPTy)); 519 Elements.push_back(Method); 520 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements)); 521 } 522 } 523 524 // Array of method structures 525 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy, 526 Methods.size()); 527 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy, 528 Methods); 529 530 // Structure containing list pointer, array and array count 531 llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields; 532 llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(); 533 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy); 534 llvm::StructType *ObjCMethodListTy = llvm::StructType::get(NextPtrTy, 535 IntTy, 536 ObjCMethodArrayTy, 537 NULL); 538 // Refine next pointer type to concrete type 539 llvm::cast<llvm::OpaqueType>( 540 OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy); 541 ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get()); 542 543 Methods.clear(); 544 Methods.push_back(llvm::ConstantPointerNull::get( 545 llvm::PointerType::getUnqual(ObjCMethodListTy))); 546 Methods.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 547 MethodTypes.size())); 548 Methods.push_back(MethodArray); 549 550 // Create an instance of the structure 551 return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list"); 552 } 553 554 /// Generates an IvarList. Used in construction of a objc_class. 555 llvm::Constant *CGObjCGNU::GenerateIvarList( 556 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 557 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 558 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) { 559 // Get the method structure type. 560 llvm::StructType *ObjCIvarTy = llvm::StructType::get( 561 PtrToInt8Ty, 562 PtrToInt8Ty, 563 IntTy, 564 NULL); 565 std::vector<llvm::Constant*> Ivars; 566 std::vector<llvm::Constant*> Elements; 567 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { 568 Elements.clear(); 569 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarNames[i], 570 Zeros, 2)); 571 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarTypes[i], 572 Zeros, 2)); 573 Elements.push_back(IvarOffsets[i]); 574 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements)); 575 } 576 577 // Array of method structures 578 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy, 579 IvarNames.size()); 580 581 582 Elements.clear(); 583 Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size())); 584 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)); 585 // Structure containing array and array count 586 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy, 587 ObjCIvarArrayTy, 588 NULL); 589 590 // Create an instance of the structure 591 return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list"); 592 } 593 594 /// Generate a class structure 595 llvm::Constant *CGObjCGNU::GenerateClassStructure( 596 llvm::Constant *MetaClass, 597 llvm::Constant *SuperClass, 598 unsigned info, 599 const char *Name, 600 llvm::Constant *Version, 601 llvm::Constant *InstanceSize, 602 llvm::Constant *IVars, 603 llvm::Constant *Methods, 604 llvm::Constant *Protocols) { 605 // Set up the class structure 606 // Note: Several of these are char*s when they should be ids. This is 607 // because the runtime performs this translation on load. 608 llvm::StructType *ClassTy = llvm::StructType::get( 609 PtrToInt8Ty, // class_pointer 610 PtrToInt8Ty, // super_class 611 PtrToInt8Ty, // name 612 LongTy, // version 613 LongTy, // info 614 LongTy, // instance_size 615 IVars->getType(), // ivars 616 Methods->getType(), // methods 617 // These are all filled in by the runtime, so we pretend 618 PtrTy, // dtable 619 PtrTy, // subclass_list 620 PtrTy, // sibling_class 621 PtrTy, // protocols 622 PtrTy, // gc_object_type 623 NULL); 624 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); 625 llvm::Constant *NullP = 626 llvm::ConstantPointerNull::get(PtrTy); 627 // Fill in the structure 628 std::vector<llvm::Constant*> Elements; 629 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty)); 630 Elements.push_back(SuperClass); 631 Elements.push_back(MakeConstantString(Name, ".class_name")); 632 Elements.push_back(Zero); 633 Elements.push_back(llvm::ConstantInt::get(LongTy, info)); 634 Elements.push_back(InstanceSize); 635 Elements.push_back(IVars); 636 Elements.push_back(Methods); 637 Elements.push_back(NullP); 638 Elements.push_back(NullP); 639 Elements.push_back(NullP); 640 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy)); 641 Elements.push_back(NullP); 642 // Create an instance of the structure 643 return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name)); 644 } 645 646 llvm::Constant *CGObjCGNU::GenerateProtocolMethodList( 647 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 648 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) { 649 // Get the method structure type. 650 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get( 651 PtrToInt8Ty, // Really a selector, but the runtime does the casting for us. 652 PtrToInt8Ty, 653 NULL); 654 std::vector<llvm::Constant*> Methods; 655 std::vector<llvm::Constant*> Elements; 656 for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) { 657 Elements.clear(); 658 Elements.push_back(llvm::ConstantExpr::getGetElementPtr(MethodNames[i], 659 Zeros, 2)); 660 Elements.push_back( 661 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2)); 662 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements)); 663 } 664 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy, 665 MethodNames.size()); 666 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, 667 Methods); 668 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get( 669 IntTy, ObjCMethodArrayTy, NULL); 670 Methods.clear(); 671 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size())); 672 Methods.push_back(Array); 673 return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list"); 674 } 675 676 // Create the protocol list structure used in classes, categories and so on 677 llvm::Constant *CGObjCGNU::GenerateProtocolList( 678 const llvm::SmallVectorImpl<std::string> &Protocols) { 679 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 680 Protocols.size()); 681 llvm::StructType *ProtocolListTy = llvm::StructType::get( 682 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 683 LongTy,//FIXME: Should be size_t 684 ProtocolArrayTy, 685 NULL); 686 std::vector<llvm::Constant*> Elements; 687 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); 688 iter != endIter ; iter++) { 689 llvm::Constant *protocol = ExistingProtocols[*iter]; 690 if (!protocol) 691 protocol = GenerateEmptyProtocol(*iter); 692 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol, 693 PtrToInt8Ty); 694 Elements.push_back(Ptr); 695 } 696 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 697 Elements); 698 Elements.clear(); 699 Elements.push_back(NULLPtr); 700 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size())); 701 Elements.push_back(ProtocolArray); 702 return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); 703 } 704 705 llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, 706 const ObjCProtocolDecl *PD) { 707 llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()]; 708 const llvm::Type *T = 709 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); 710 return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); 711 } 712 713 llvm::Constant *CGObjCGNU::GenerateEmptyProtocol( 714 const std::string &ProtocolName) { 715 llvm::SmallVector<std::string, 0> EmptyStringVector; 716 llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector; 717 718 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector); 719 llvm::Constant *InstanceMethodList = 720 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector); 721 llvm::Constant *ClassMethodList = 722 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector); 723 // Protocols are objects containing lists of the methods implemented and 724 // protocols adopted. 725 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy, 726 PtrToInt8Ty, 727 ProtocolList->getType(), 728 InstanceMethodList->getType(), 729 ClassMethodList->getType(), 730 NULL); 731 std::vector<llvm::Constant*> Elements; 732 // The isa pointer must be set to a magic number so the runtime knows it's 733 // the correct layout. 734 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 735 llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy)); 736 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 737 Elements.push_back(ProtocolList); 738 Elements.push_back(InstanceMethodList); 739 Elements.push_back(ClassMethodList); 740 return MakeGlobal(ProtocolTy, Elements, ".objc_protocol"); 741 } 742 743 void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { 744 ASTContext &Context = CGM.getContext(); 745 std::string ProtocolName = PD->getNameAsString(); 746 llvm::SmallVector<std::string, 16> Protocols; 747 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(), 748 E = PD->protocol_end(); PI != E; ++PI) 749 Protocols.push_back((*PI)->getNameAsString()); 750 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames; 751 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 752 for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(), 753 E = PD->instmeth_end(); iter != E; iter++) { 754 std::string TypeStr; 755 Context.getObjCEncodingForMethodDecl(*iter, TypeStr); 756 InstanceMethodNames.push_back( 757 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString())); 758 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 759 } 760 // Collect information about class methods: 761 llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames; 762 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 763 for (ObjCProtocolDecl::classmeth_iterator 764 iter = PD->classmeth_begin(), endIter = PD->classmeth_end(); 765 iter != endIter ; iter++) { 766 std::string TypeStr; 767 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 768 ClassMethodNames.push_back( 769 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString())); 770 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 771 } 772 773 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 774 llvm::Constant *InstanceMethodList = 775 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes); 776 llvm::Constant *ClassMethodList = 777 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes); 778 // Protocols are objects containing lists of the methods implemented and 779 // protocols adopted. 780 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy, 781 PtrToInt8Ty, 782 ProtocolList->getType(), 783 InstanceMethodList->getType(), 784 ClassMethodList->getType(), 785 NULL); 786 std::vector<llvm::Constant*> Elements; 787 // The isa pointer must be set to a magic number so the runtime knows it's 788 // the correct layout. 789 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 790 llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy)); 791 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 792 Elements.push_back(ProtocolList); 793 Elements.push_back(InstanceMethodList); 794 Elements.push_back(ClassMethodList); 795 ExistingProtocols[ProtocolName] = 796 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements, 797 ".objc_protocol"), IdTy); 798 } 799 800 void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 801 std::string ClassName = OCD->getClassInterface()->getNameAsString(); 802 std::string CategoryName = OCD->getNameAsString(); 803 // Collect information about instance methods 804 llvm::SmallVector<Selector, 16> InstanceMethodSels; 805 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 806 for (ObjCCategoryImplDecl::instmeth_iterator 807 iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end(); 808 iter != endIter ; iter++) { 809 InstanceMethodSels.push_back((*iter)->getSelector()); 810 std::string TypeStr; 811 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 812 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 813 } 814 815 // Collect information about class methods 816 llvm::SmallVector<Selector, 16> ClassMethodSels; 817 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 818 for (ObjCCategoryImplDecl::classmeth_iterator 819 iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end(); 820 iter != endIter ; iter++) { 821 ClassMethodSels.push_back((*iter)->getSelector()); 822 std::string TypeStr; 823 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 824 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 825 } 826 827 // Collect the names of referenced protocols 828 llvm::SmallVector<std::string, 16> Protocols; 829 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface(); 830 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 831 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 832 E = Protos.end(); I != E; ++I) 833 Protocols.push_back((*I)->getNameAsString()); 834 835 std::vector<llvm::Constant*> Elements; 836 Elements.push_back(MakeConstantString(CategoryName)); 837 Elements.push_back(MakeConstantString(ClassName)); 838 // Instance method list 839 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 840 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes, 841 false), PtrTy)); 842 // Class method list 843 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 844 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true), 845 PtrTy)); 846 // Protocol list 847 Elements.push_back(llvm::ConstantExpr::getBitCast( 848 GenerateProtocolList(Protocols), PtrTy)); 849 Categories.push_back(llvm::ConstantExpr::getBitCast( 850 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy, 851 PtrTy, PtrTy, NULL), Elements), PtrTy)); 852 } 853 854 void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 855 ASTContext &Context = CGM.getContext(); 856 857 // Get the superclass name. 858 const ObjCInterfaceDecl * SuperClassDecl = 859 OID->getClassInterface()->getSuperClass(); 860 std::string SuperClassName; 861 if (SuperClassDecl) { 862 SuperClassName = SuperClassDecl->getNameAsString(); 863 EmitClassRef(SuperClassName); 864 } 865 866 // Get the class name 867 ObjCInterfaceDecl *ClassDecl = 868 const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 869 std::string ClassName = ClassDecl->getNameAsString(); 870 // Emit the symbol that is used to generate linker errors if this class is 871 // referenced in other modules but not declared. 872 std::string classSymbolName = "__objc_class_name_" + ClassName; 873 if (llvm::GlobalVariable *symbol = 874 TheModule.getGlobalVariable(classSymbolName)) { 875 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0)); 876 } else { 877 new llvm::GlobalVariable(TheModule, LongTy, false, 878 llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0), 879 classSymbolName); 880 } 881 882 // Get the size of instances. 883 int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8; 884 885 // Collect information about instance variables. 886 llvm::SmallVector<llvm::Constant*, 16> IvarNames; 887 llvm::SmallVector<llvm::Constant*, 16> IvarTypes; 888 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets; 889 890 int superInstanceSize = !SuperClassDecl ? 0 : 891 Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8; 892 // For non-fragile ivars, set the instance size to 0 - {the size of just this 893 // class}. The runtime will then set this to the correct value on load. 894 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 895 instanceSize = 0 - (instanceSize - superInstanceSize); 896 } 897 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 898 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 899 // Store the name 900 IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter) 901 ->getNameAsString())); 902 // Get the type encoding for this ivar 903 std::string TypeStr; 904 Context.getObjCEncodingForType((*iter)->getType(), TypeStr); 905 IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 906 // Get the offset 907 uint64_t Offset; 908 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 909 Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter) - 910 superInstanceSize; 911 ObjCIvarOffsetVariable(ClassDecl, *iter); 912 } else { 913 Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter); 914 } 915 IvarOffsets.push_back( 916 llvm::ConstantInt::get(llvm::Type::Int32Ty, Offset)); 917 } 918 919 // Collect information about instance methods 920 llvm::SmallVector<Selector, 16> InstanceMethodSels; 921 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 922 for (ObjCImplementationDecl::instmeth_iterator 923 iter = OID->instmeth_begin(), endIter = OID->instmeth_end(); 924 iter != endIter ; iter++) { 925 InstanceMethodSels.push_back((*iter)->getSelector()); 926 std::string TypeStr; 927 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 928 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 929 } 930 for (ObjCImplDecl::propimpl_iterator 931 iter = OID->propimpl_begin(), endIter = OID->propimpl_end(); 932 iter != endIter ; iter++) { 933 ObjCPropertyDecl *property = (*iter)->getPropertyDecl(); 934 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 935 InstanceMethodSels.push_back(getter->getSelector()); 936 std::string TypeStr; 937 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 938 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 939 } 940 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 941 InstanceMethodSels.push_back(setter->getSelector()); 942 std::string TypeStr; 943 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 944 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 945 } 946 } 947 948 // Collect information about class methods 949 llvm::SmallVector<Selector, 16> ClassMethodSels; 950 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 951 for (ObjCImplementationDecl::classmeth_iterator 952 iter = OID->classmeth_begin(), endIter = OID->classmeth_end(); 953 iter != endIter ; iter++) { 954 ClassMethodSels.push_back((*iter)->getSelector()); 955 std::string TypeStr; 956 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 957 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 958 } 959 // Collect the names of referenced protocols 960 llvm::SmallVector<std::string, 16> Protocols; 961 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 962 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 963 E = Protos.end(); I != E; ++I) 964 Protocols.push_back((*I)->getNameAsString()); 965 966 967 968 // Get the superclass pointer. 969 llvm::Constant *SuperClass; 970 if (!SuperClassName.empty()) { 971 SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 972 } else { 973 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 974 } 975 // Empty vector used to construct empty method lists 976 llvm::SmallVector<llvm::Constant*, 1> empty; 977 // Generate the method and instance variable lists 978 llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 979 InstanceMethodSels, InstanceMethodTypes, false); 980 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 981 ClassMethodSels, ClassMethodTypes, true); 982 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 983 IvarOffsets); 984 //Generate metaclass for class methods 985 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, 986 NULLPtr, 0x2L, /*name*/"", 0, Zeros[0], GenerateIvarList( 987 empty, empty, empty), ClassMethodList, NULLPtr); 988 989 // Generate the class structure 990 llvm::Constant *ClassStruct = 991 GenerateClassStructure(MetaClassStruct, SuperClass, 0x1L, 992 ClassName.c_str(), 0, 993 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, 994 MethodList, GenerateProtocolList(Protocols)); 995 996 // Resolve the class aliases, if they exist. 997 if (ClassPtrAlias) { 998 ClassPtrAlias->setAliasee( 999 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); 1000 ClassPtrAlias = 0; 1001 } 1002 if (MetaClassPtrAlias) { 1003 MetaClassPtrAlias->setAliasee( 1004 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); 1005 MetaClassPtrAlias = 0; 1006 } 1007 1008 // Add class structure to list to be added to the symtab later 1009 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 1010 Classes.push_back(ClassStruct); 1011 } 1012 1013 1014 llvm::Function *CGObjCGNU::ModuleInitFunction() { 1015 // Only emit an ObjC load function if no Objective-C stuff has been called 1016 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 1017 ExistingProtocols.empty() && TypedSelectors.empty() && 1018 UntypedSelectors.empty()) 1019 return NULL; 1020 1021 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>( 1022 SelectorTy->getElementType()); 1023 const llvm::Type *SelStructPtrTy = SelectorTy; 1024 bool isSelOpaque = false; 1025 if (SelStructTy == 0) { 1026 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL); 1027 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); 1028 isSelOpaque = true; 1029 } 1030 1031 // Name the ObjC types to make the IR a bit easier to read 1032 TheModule.addTypeName(".objc_selector", SelStructPtrTy); 1033 TheModule.addTypeName(".objc_id", IdTy); 1034 TheModule.addTypeName(".objc_imp", IMPTy); 1035 1036 std::vector<llvm::Constant*> Elements; 1037 llvm::Constant *Statics = NULLPtr; 1038 // Generate statics list: 1039 if (ConstantStrings.size()) { 1040 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 1041 ConstantStrings.size() + 1); 1042 ConstantStrings.push_back(NULLPtr); 1043 Elements.push_back(MakeConstantString("NSConstantString", 1044 ".objc_static_class_name")); 1045 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, 1046 ConstantStrings)); 1047 llvm::StructType *StaticsListTy = 1048 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL); 1049 llvm::Type *StaticsListPtrTy = 1050 llvm::PointerType::getUnqual(StaticsListTy); 1051 Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics"); 1052 llvm::ArrayType *StaticsListArrayTy = 1053 llvm::ArrayType::get(StaticsListPtrTy, 2); 1054 Elements.clear(); 1055 Elements.push_back(Statics); 1056 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy)); 1057 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr"); 1058 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy); 1059 } 1060 // Array of classes, categories, and constant objects 1061 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, 1062 Classes.size() + Categories.size() + 2); 1063 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy, 1064 llvm::Type::Int16Ty, 1065 llvm::Type::Int16Ty, 1066 ClassListTy, NULL); 1067 1068 Elements.clear(); 1069 // Pointer to an array of selectors used in this module. 1070 std::vector<llvm::Constant*> Selectors; 1071 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1072 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end(); 1073 iter != iterEnd ; ++iter) { 1074 Elements.push_back(MakeConstantString(iter->first.first, ".objc_sel_name")); 1075 Elements.push_back(MakeConstantString(iter->first.second, 1076 ".objc_sel_types")); 1077 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1078 Elements.clear(); 1079 } 1080 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1081 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1082 iter != iterEnd; ++iter) { 1083 Elements.push_back( 1084 MakeConstantString(iter->getKeyData(), ".objc_sel_name")); 1085 Elements.push_back(NULLPtr); 1086 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1087 Elements.clear(); 1088 } 1089 Elements.push_back(NULLPtr); 1090 Elements.push_back(NULLPtr); 1091 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1092 Elements.clear(); 1093 // Number of static selectors 1094 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() )); 1095 llvm::Constant *SelectorList = MakeGlobal( 1096 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, 1097 ".objc_selector_list"); 1098 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, 1099 SelStructPtrTy)); 1100 1101 // Now that all of the static selectors exist, create pointers to them. 1102 int index = 0; 1103 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1104 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); 1105 iter != iterEnd; ++iter) { 1106 llvm::Constant *Idxs[] = {Zeros[0], 1107 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 1108 llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy, 1109 true, llvm::GlobalValue::InternalLinkage, 1110 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1111 ".objc_sel_ptr"); 1112 // If selectors are defined as an opaque type, cast the pointer to this 1113 // type. 1114 if (isSelOpaque) { 1115 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1116 llvm::PointerType::getUnqual(SelectorTy)); 1117 } 1118 (*iter).second->setAliasee(SelPtr); 1119 } 1120 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1121 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1122 iter != iterEnd; iter++) { 1123 llvm::Constant *Idxs[] = {Zeros[0], 1124 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 1125 llvm::Constant *SelPtr = new llvm::GlobalVariable 1126 (TheModule, SelStructPtrTy, 1127 true, llvm::GlobalValue::InternalLinkage, 1128 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1129 ".objc_sel_ptr"); 1130 // If selectors are defined as an opaque type, cast the pointer to this 1131 // type. 1132 if (isSelOpaque) { 1133 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1134 llvm::PointerType::getUnqual(SelectorTy)); 1135 } 1136 (*iter).second->setAliasee(SelPtr); 1137 } 1138 // Number of classes defined. 1139 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 1140 Classes.size())); 1141 // Number of categories defined 1142 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 1143 Categories.size())); 1144 // Create an array of classes, then categories, then static object instances 1145 Classes.insert(Classes.end(), Categories.begin(), Categories.end()); 1146 // NULL-terminated list of static object instances (mainly constant strings) 1147 Classes.push_back(Statics); 1148 Classes.push_back(NULLPtr); 1149 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes); 1150 Elements.push_back(ClassList); 1151 // Construct the symbol table 1152 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements); 1153 1154 // The symbol table is contained in a module which has some version-checking 1155 // constants 1156 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy, 1157 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL); 1158 Elements.clear(); 1159 // Runtime version used for compatibility checking. 1160 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1161 Elements.push_back(llvm::ConstantInt::get(LongTy, 1162 NonFragileRuntimeVersion)); 1163 } else { 1164 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion)); 1165 } 1166 // sizeof(ModuleTy) 1167 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1168 Elements.push_back(llvm::ConstantInt::get(LongTy, 1169 td.getTypeSizeInBits(ModuleTy)/8)); 1170 //FIXME: Should be the path to the file where this module was declared 1171 Elements.push_back(NULLPtr); 1172 Elements.push_back(SymTab); 1173 llvm::Value *Module = MakeGlobal(ModuleTy, Elements); 1174 1175 // Create the load function calling the runtime entry point with the module 1176 // structure 1177 llvm::Function * LoadFunction = llvm::Function::Create( 1178 llvm::FunctionType::get(llvm::Type::VoidTy, false), 1179 llvm::GlobalValue::InternalLinkage, ".objc_load_function", 1180 &TheModule); 1181 llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction); 1182 CGBuilderTy Builder(VMContext); 1183 Builder.SetInsertPoint(EntryBB); 1184 1185 std::vector<const llvm::Type*> Params(1, 1186 llvm::PointerType::getUnqual(ModuleTy)); 1187 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 1188 llvm::Type::VoidTy, Params, true), "__objc_exec_class"); 1189 Builder.CreateCall(Register, Module); 1190 Builder.CreateRetVoid(); 1191 1192 return LoadFunction; 1193 } 1194 1195 llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 1196 const ObjCContainerDecl *CD) { 1197 const ObjCCategoryImplDecl *OCD = 1198 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); 1199 std::string CategoryName = OCD ? OCD->getNameAsString() : ""; 1200 std::string ClassName = OMD->getClassInterface()->getNameAsString(); 1201 std::string MethodName = OMD->getSelector().getAsString(); 1202 bool isClassMethod = !OMD->isInstanceMethod(); 1203 1204 CodeGenTypes &Types = CGM.getTypes(); 1205 const llvm::FunctionType *MethodTy = 1206 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 1207 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, 1208 MethodName, isClassMethod); 1209 1210 llvm::Function *Method = llvm::Function::Create(MethodTy, 1211 llvm::GlobalValue::InternalLinkage, 1212 FunctionName, 1213 &TheModule); 1214 return Method; 1215 } 1216 1217 llvm::Function *CGObjCGNU::GetPropertyGetFunction() { 1218 std::vector<const llvm::Type*> Params; 1219 const llvm::Type *BoolTy = 1220 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1221 Params.push_back(IdTy); 1222 Params.push_back(SelectorTy); 1223 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1224 Params.push_back(LongTy); 1225 Params.push_back(BoolTy); 1226 // void objc_getProperty (id, SEL, ptrdiff_t, bool) 1227 const llvm::FunctionType *FTy = 1228 llvm::FunctionType::get(IdTy, Params, false); 1229 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1230 "objc_getProperty")); 1231 } 1232 1233 llvm::Function *CGObjCGNU::GetPropertySetFunction() { 1234 std::vector<const llvm::Type*> Params; 1235 const llvm::Type *BoolTy = 1236 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1237 Params.push_back(IdTy); 1238 Params.push_back(SelectorTy); 1239 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1240 Params.push_back(LongTy); 1241 Params.push_back(IdTy); 1242 Params.push_back(BoolTy); 1243 Params.push_back(BoolTy); 1244 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 1245 const llvm::FunctionType *FTy = 1246 llvm::FunctionType::get(llvm::Type::VoidTy, Params, false); 1247 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1248 "objc_setProperty")); 1249 } 1250 1251 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { 1252 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 1253 ASTContext &Ctx = CGM.getContext(); 1254 // void objc_enumerationMutation (id) 1255 llvm::SmallVector<QualType,16> Params; 1256 Params.push_back(Ctx.getObjCIdType()); 1257 const llvm::FunctionType *FTy = 1258 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false); 1259 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 1260 } 1261 1262 void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1263 const Stmt &S) { 1264 // Pointer to the personality function 1265 llvm::Constant *Personality = 1266 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 1267 true), 1268 "__gnu_objc_personality_v0"); 1269 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy); 1270 std::vector<const llvm::Type*> Params; 1271 Params.push_back(PtrTy); 1272 llvm::Value *RethrowFn = 1273 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 1274 Params, false), "_Unwind_Resume_or_Rethrow"); 1275 1276 bool isTry = isa<ObjCAtTryStmt>(S); 1277 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 1278 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 1279 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 1280 llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow"); 1281 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 1282 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 1283 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 1284 1285 // GNU runtime does not currently support @synchronized() 1286 if (!isTry) { 1287 std::vector<const llvm::Type*> Args(1, IdTy); 1288 llvm::FunctionType *FTy = 1289 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1290 llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 1291 llvm::Value *SyncArg = 1292 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1293 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1294 CGF.Builder.CreateCall(SyncEnter, SyncArg); 1295 } 1296 1297 1298 // Push an EH context entry, used for handling rethrows and jumps 1299 // through finally. 1300 CGF.PushCleanupBlock(FinallyBlock); 1301 1302 // Emit the statements in the @try {} block 1303 CGF.setInvokeDest(TryHandler); 1304 1305 CGF.EmitBlock(TryBlock); 1306 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 1307 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 1308 1309 // Jump to @finally if there is no exception 1310 CGF.EmitBranchThroughCleanup(FinallyEnd); 1311 1312 // Emit the handlers 1313 CGF.EmitBlock(TryHandler); 1314 1315 // Get the correct versions of the exception handling intrinsics 1316 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1317 int PointerWidth = td.getTypeSizeInBits(PtrTy); 1318 assert((PointerWidth == 32 || PointerWidth == 64) && 1319 "Can't yet handle exceptions if pointers are not 32 or 64 bits"); 1320 llvm::Value *llvm_eh_exception = 1321 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 1322 llvm::Value *llvm_eh_selector = PointerWidth == 32 ? 1323 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i32) : 1324 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i64); 1325 llvm::Value *llvm_eh_typeid_for = PointerWidth == 32 ? 1326 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i32) : 1327 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i64); 1328 1329 // Exception object 1330 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1331 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 1332 1333 llvm::SmallVector<llvm::Value*, 8> ESelArgs; 1334 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 1335 1336 ESelArgs.push_back(Exc); 1337 ESelArgs.push_back(Personality); 1338 1339 bool HasCatchAll = false; 1340 // Only @try blocks are allowed @catch blocks, but both can have @finally 1341 if (isTry) { 1342 if (const ObjCAtCatchStmt* CatchStmt = 1343 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 1344 CGF.setInvokeDest(CatchInCatch); 1345 1346 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1347 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 1348 Handlers.push_back(std::make_pair(CatchDecl, 1349 CatchStmt->getCatchBody())); 1350 1351 // @catch() and @catch(id) both catch any ObjC exception 1352 if (!CatchDecl || CatchDecl->getType()->isObjCIdType() 1353 || CatchDecl->getType()->isObjCQualifiedIdType()) { 1354 // Use i8* null here to signal this is a catch all, not a cleanup. 1355 ESelArgs.push_back(NULLPtr); 1356 HasCatchAll = true; 1357 // No further catches after this one will ever by reached 1358 break; 1359 } 1360 1361 // All other types should be Objective-C interface pointer types. 1362 const ObjCObjectPointerType *OPT = 1363 CatchDecl->getType()->getAsObjCObjectPointerType(); 1364 assert(OPT && "Invalid @catch type."); 1365 const ObjCInterfaceType *IT = 1366 OPT->getPointeeType()->getAsObjCInterfaceType(); 1367 assert(IT && "Invalid @catch type."); 1368 llvm::Value *EHType = 1369 MakeConstantString(IT->getDecl()->getNameAsString()); 1370 ESelArgs.push_back(EHType); 1371 } 1372 } 1373 } 1374 1375 // We use a cleanup unless there was already a catch all. 1376 if (!HasCatchAll) { 1377 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); 1378 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 1379 } 1380 1381 // Find which handler was matched. 1382 llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector, 1383 ESelArgs.begin(), ESelArgs.end(), "selector"); 1384 1385 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 1386 const ParmVarDecl *CatchParam = Handlers[i].first; 1387 const Stmt *CatchBody = Handlers[i].second; 1388 1389 llvm::BasicBlock *Next = 0; 1390 1391 // The last handler always matches. 1392 if (i + 1 != e) { 1393 assert(CatchParam && "Only last handler can be a catch all."); 1394 1395 // Test whether this block matches the type for the selector and branch 1396 // to Match if it does, or to the next BB if it doesn't. 1397 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 1398 Next = CGF.createBasicBlock("catch.next"); 1399 llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for, 1400 CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy)); 1401 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match, 1402 Next); 1403 1404 CGF.EmitBlock(Match); 1405 } 1406 1407 if (CatchBody) { 1408 llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc, 1409 CGF.ConvertType(CatchParam->getType())); 1410 1411 // Bind the catch parameter if it exists. 1412 if (CatchParam) { 1413 // CatchParam is a ParmVarDecl because of the grammar 1414 // construction used to handle this, but for codegen purposes 1415 // we treat this as a local decl. 1416 CGF.EmitLocalBlockVarDecl(*CatchParam); 1417 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 1418 } 1419 1420 CGF.ObjCEHValueStack.push_back(ExcObject); 1421 CGF.EmitStmt(CatchBody); 1422 CGF.ObjCEHValueStack.pop_back(); 1423 1424 CGF.EmitBranchThroughCleanup(FinallyEnd); 1425 1426 if (Next) 1427 CGF.EmitBlock(Next); 1428 } else { 1429 assert(!Next && "catchup should be last handler."); 1430 1431 CGF.Builder.CreateStore(Exc, RethrowPtr); 1432 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1433 } 1434 } 1435 // The @finally block is a secondary landing pad for any exceptions thrown in 1436 // @catch() blocks 1437 CGF.EmitBlock(CatchInCatch); 1438 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1439 ESelArgs.clear(); 1440 ESelArgs.push_back(Exc); 1441 ESelArgs.push_back(Personality); 1442 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); 1443 CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(), 1444 "selector"); 1445 CGF.Builder.CreateCall(llvm_eh_typeid_for, 1446 CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy)); 1447 CGF.Builder.CreateStore(Exc, RethrowPtr); 1448 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1449 1450 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 1451 1452 CGF.setInvokeDest(PrevLandingPad); 1453 1454 CGF.EmitBlock(FinallyBlock); 1455 1456 1457 if (isTry) { 1458 if (const ObjCAtFinallyStmt* FinallyStmt = 1459 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 1460 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1461 } else { 1462 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 1463 // @synchronized. 1464 std::vector<const llvm::Type*> Args(1, IdTy); 1465 llvm::FunctionType *FTy = 1466 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1467 llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 1468 llvm::Value *SyncArg = 1469 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1470 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1471 CGF.Builder.CreateCall(SyncExit, SyncArg); 1472 } 1473 1474 if (Info.SwitchBlock) 1475 CGF.EmitBlock(Info.SwitchBlock); 1476 if (Info.EndBlock) 1477 CGF.EmitBlock(Info.EndBlock); 1478 1479 // Branch around the rethrow code. 1480 CGF.EmitBranch(FinallyEnd); 1481 1482 CGF.EmitBlock(FinallyRethrow); 1483 CGF.Builder.CreateCall(RethrowFn, CGF.Builder.CreateLoad(RethrowPtr)); 1484 CGF.Builder.CreateUnreachable(); 1485 1486 CGF.EmitBlock(FinallyEnd); 1487 1488 } 1489 1490 void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1491 const ObjCAtThrowStmt &S) { 1492 llvm::Value *ExceptionAsObject; 1493 1494 std::vector<const llvm::Type*> Args(1, IdTy); 1495 llvm::FunctionType *FTy = 1496 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1497 llvm::Value *ThrowFn = 1498 CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 1499 1500 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1501 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1502 ExceptionAsObject = Exception; 1503 } else { 1504 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 1505 "Unexpected rethrow outside @catch block."); 1506 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 1507 } 1508 ExceptionAsObject = 1509 CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp"); 1510 1511 // Note: This may have to be an invoke, if we want to support constructs like: 1512 // @try { 1513 // @throw(obj); 1514 // } 1515 // @catch(id) ... 1516 // 1517 // This is effectively turning @throw into an incredibly-expensive goto, but 1518 // it may happen as a result of inlining followed by missed optimizations, or 1519 // as a result of stupidity. 1520 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1521 if (!UnwindBB) { 1522 CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject); 1523 CGF.Builder.CreateUnreachable(); 1524 } else { 1525 CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject, 1526 &ExceptionAsObject+1); 1527 } 1528 // Clear the insertion point to indicate we are in unreachable code. 1529 CGF.Builder.ClearInsertionPoint(); 1530 } 1531 1532 llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1533 llvm::Value *AddrWeakObj) 1534 { 1535 return 0; 1536 } 1537 1538 void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1539 llvm::Value *src, llvm::Value *dst) 1540 { 1541 return; 1542 } 1543 1544 void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1545 llvm::Value *src, llvm::Value *dst) 1546 { 1547 return; 1548 } 1549 1550 void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1551 llvm::Value *src, llvm::Value *dst) 1552 { 1553 return; 1554 } 1555 1556 void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1557 llvm::Value *src, llvm::Value *dst) 1558 { 1559 return; 1560 } 1561 1562 void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1563 llvm::Value *DestPtr, 1564 llvm::Value *SrcPtr, 1565 unsigned long size) { 1566 return; 1567 } 1568 1569 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( 1570 const ObjCInterfaceDecl *ID, 1571 const ObjCIvarDecl *Ivar) { 1572 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 1573 + '.' + Ivar->getNameAsString(); 1574 // Emit the variable and initialize it with what we think the correct value 1575 // is. This allows code compiled with non-fragile ivars to work correctly 1576 // when linked against code which isn't (most of the time). 1577 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); 1578 if (!IvarOffsetGV) { 1579 uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); 1580 llvm::ConstantInt *OffsetGuess = 1581 llvm::ConstantInt::get(LongTy, Offset, "ivar"); 1582 IvarOffsetGV = new llvm::GlobalVariable(TheModule, LongTy, false, 1583 llvm::GlobalValue::CommonLinkage, OffsetGuess, Name); 1584 } 1585 return IvarOffsetGV; 1586 } 1587 1588 LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1589 QualType ObjectTy, 1590 llvm::Value *BaseValue, 1591 const ObjCIvarDecl *Ivar, 1592 unsigned CVRQualifiers) { 1593 const ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); 1594 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 1595 EmitIvarOffset(CGF, ID, Ivar)); 1596 } 1597 1598 static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 1599 const ObjCInterfaceDecl *OID, 1600 const ObjCIvarDecl *OIVD) { 1601 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 1602 Context.ShallowCollectObjCIvars(OID, Ivars); 1603 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 1604 if (OIVD == Ivars[k]) 1605 return OID; 1606 } 1607 1608 // Otherwise check in the super class. 1609 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1610 return FindIvarInterface(Context, Super, OIVD); 1611 1612 return 0; 1613 } 1614 1615 llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1616 const ObjCInterfaceDecl *Interface, 1617 const ObjCIvarDecl *Ivar) { 1618 if (CGF.getContext().getLangOptions().ObjCNonFragileABI) { 1619 Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); 1620 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar), 1621 false, "ivar"); 1622 } 1623 uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); 1624 return llvm::ConstantInt::get(LongTy, Offset, "ivar"); 1625 } 1626 1627 CodeGen::CGObjCRuntime * 1628 CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) { 1629 return new CGObjCGNU(CGM); 1630 } 1631