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