CGObjCGNU.cpp revision c38e9affd4519ea199af22419c8c794973cc4b23
1//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This provides Objective-C code generation targetting the GNU runtime. The 11// class in this file generates structures used by the GNU Objective-C runtime 12// library. These structures are defined in objc/objc.h and objc/objc-api.h in 13// the GNU runtime distribution. 14// 15//===----------------------------------------------------------------------===// 16 17#include "CGObjCRuntime.h" 18#include "CodeGenModule.h" 19#include "CodeGenFunction.h" 20 21#include "clang/AST/ASTContext.h" 22#include "clang/AST/Decl.h" 23#include "clang/AST/DeclObjC.h" 24#include "clang/AST/RecordLayout.h" 25#include "clang/AST/StmtObjC.h" 26 27#include "llvm/Intrinsics.h" 28#include "llvm/Module.h" 29#include "llvm/ADT/SmallVector.h" 30#include "llvm/ADT/StringMap.h" 31#include "llvm/Support/Compiler.h" 32#include "llvm/Target/TargetData.h" 33 34#include <map> 35 36 37using namespace clang; 38using namespace CodeGen; 39using llvm::dyn_cast; 40 41// The version of the runtime that this class targets. Must match the version 42// in the runtime. 43static const int RuntimeVersion = 8; 44static const int NonFragileRuntimeVersion = 9; 45static const int ProtocolVersion = 2; 46 47namespace { 48class CGObjCGNU : public CodeGen::CGObjCRuntime { 49private: 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; 73private: 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); 108public: 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. 176void 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 190static std::string SymbolNameForClass(const std::string &ClassName) { 191 return "_OBJC_CLASS_" + ClassName; 192} 193 194static 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 201CGObjCGNU::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. 235llvm::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 250llvm::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 261llvm::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 287llvm::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} 295llvm::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} 301llvm::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. 312llvm::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. 330CodeGen::RValue 331CGObjCGNU::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. 423CodeGen::RValue 424CGObjCGNU::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. 485llvm::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. 547llvm::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 587llvm::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 638llvm::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 667llvm::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 695llvm::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 703llvm::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 733void 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(Context), 743 E = PD->instmeth_end(Context); 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(Context), 755 endIter = PD->classmeth_end(Context) ; 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 790void 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(CGM.getContext()), 798 endIter = OCD->instmeth_end(CGM.getContext()); 799 iter != endIter ; iter++) { 800 InstanceMethodSels.push_back((*iter)->getSelector()); 801 std::string TypeStr; 802 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 803 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 804 } 805 806 // Collect information about class methods 807 llvm::SmallVector<Selector, 16> ClassMethodSels; 808 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 809 for (ObjCCategoryImplDecl::classmeth_iterator 810 iter = OCD->classmeth_begin(CGM.getContext()), 811 endIter = OCD->classmeth_end(CGM.getContext()); 812 iter != endIter ; iter++) { 813 ClassMethodSels.push_back((*iter)->getSelector()); 814 std::string TypeStr; 815 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 816 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 817 } 818 819 // Collect the names of referenced protocols 820 llvm::SmallVector<std::string, 16> Protocols; 821 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface(); 822 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 823 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 824 E = Protos.end(); I != E; ++I) 825 Protocols.push_back((*I)->getNameAsString()); 826 827 std::vector<llvm::Constant*> Elements; 828 Elements.push_back(MakeConstantString(CategoryName)); 829 Elements.push_back(MakeConstantString(ClassName)); 830 // Instance method list 831 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 832 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes, 833 false), PtrTy)); 834 // Class method list 835 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 836 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true), 837 PtrTy)); 838 // Protocol list 839 Elements.push_back(llvm::ConstantExpr::getBitCast( 840 GenerateProtocolList(Protocols), PtrTy)); 841 Categories.push_back(llvm::ConstantExpr::getBitCast( 842 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy, 843 PtrTy, PtrTy, NULL), Elements), PtrTy)); 844} 845 846void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 847 ASTContext &Context = CGM.getContext(); 848 849 // Get the superclass name. 850 const ObjCInterfaceDecl * SuperClassDecl = 851 OID->getClassInterface()->getSuperClass(); 852 std::string SuperClassName; 853 if (SuperClassDecl) { 854 SuperClassName = SuperClassDecl->getNameAsString(); 855 EmitClassRef(SuperClassName); 856 } 857 858 // Get the class name 859 ObjCInterfaceDecl *ClassDecl = 860 const_cast<ObjCInterfaceDecl *>(OID->getClassInterface()); 861 std::string ClassName = ClassDecl->getNameAsString(); 862 // Emit the symbol that is used to generate linker errors if this class is 863 // referenced in other modules but not declared. 864 new llvm::GlobalVariable(LongTy, false, llvm::GlobalValue::ExternalLinkage, 865 llvm::ConstantInt::get(LongTy, 0), "__objc_class_name_" + ClassName, 866 &TheModule); 867 868 // Get the size of instances. 869 int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8; 870 871 // Collect information about instance variables. 872 llvm::SmallVector<llvm::Constant*, 16> IvarNames; 873 llvm::SmallVector<llvm::Constant*, 16> IvarTypes; 874 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets; 875 876 int superInstanceSize = !SuperClassDecl ? 0 : 877 Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8; 878 // For non-fragile ivars, set the instance size to 0 - {the size of just this 879 // class}. The runtime will then set this to the correct value on load. 880 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 881 instanceSize = 0 - (instanceSize - superInstanceSize); 882 } 883 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 884 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 885 // Store the name 886 IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter) 887 ->getNameAsString())); 888 // Get the type encoding for this ivar 889 std::string TypeStr; 890 Context.getObjCEncodingForType((*iter)->getType(), TypeStr); 891 IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 892 // Get the offset 893 uint64_t Offset; 894 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 895 Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter) - 896 superInstanceSize; 897 ObjCIvarOffsetVariable(ClassDecl, *iter); 898 } else { 899 Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter); 900 } 901 IvarOffsets.push_back( 902 llvm::ConstantInt::get(llvm::Type::Int32Ty, Offset)); 903 } 904 905 // Collect information about instance methods 906 llvm::SmallVector<Selector, 16> InstanceMethodSels; 907 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 908 for (ObjCImplementationDecl::instmeth_iterator 909 iter = OID->instmeth_begin(CGM.getContext()), 910 endIter = OID->instmeth_end(CGM.getContext()); 911 iter != endIter ; iter++) { 912 InstanceMethodSels.push_back((*iter)->getSelector()); 913 std::string TypeStr; 914 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 915 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 916 } 917 for (ObjCImplDecl::propimpl_iterator 918 iter = OID->propimpl_begin(CGM.getContext()), 919 endIter = OID->propimpl_end(CGM.getContext()); 920 iter != endIter ; iter++) { 921 ObjCPropertyDecl *property = (*iter)->getPropertyDecl(); 922 if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) { 923 InstanceMethodSels.push_back(getter->getSelector()); 924 std::string TypeStr; 925 Context.getObjCEncodingForMethodDecl(getter,TypeStr); 926 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 927 } 928 if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) { 929 InstanceMethodSels.push_back(setter->getSelector()); 930 std::string TypeStr; 931 Context.getObjCEncodingForMethodDecl(setter,TypeStr); 932 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 933 } 934 } 935 936 // Collect information about class methods 937 llvm::SmallVector<Selector, 16> ClassMethodSels; 938 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 939 for (ObjCImplementationDecl::classmeth_iterator 940 iter = OID->classmeth_begin(CGM.getContext()), 941 endIter = OID->classmeth_end(CGM.getContext()); 942 iter != endIter ; iter++) { 943 ClassMethodSels.push_back((*iter)->getSelector()); 944 std::string TypeStr; 945 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 946 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 947 } 948 // Collect the names of referenced protocols 949 llvm::SmallVector<std::string, 16> Protocols; 950 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 951 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 952 E = Protos.end(); I != E; ++I) 953 Protocols.push_back((*I)->getNameAsString()); 954 955 956 957 // Get the superclass pointer. 958 llvm::Constant *SuperClass; 959 if (!SuperClassName.empty()) { 960 SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 961 } else { 962 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 963 } 964 // Empty vector used to construct empty method lists 965 llvm::SmallVector<llvm::Constant*, 1> empty; 966 // Generate the method and instance variable lists 967 llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 968 InstanceMethodSels, InstanceMethodTypes, false); 969 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 970 ClassMethodSels, ClassMethodTypes, true); 971 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 972 IvarOffsets); 973 //Generate metaclass for class methods 974 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, 975 NULLPtr, 0x2L, /*name*/"", 0, Zeros[0], GenerateIvarList( 976 empty, empty, empty), ClassMethodList, NULLPtr); 977 978 // Generate the class structure 979 llvm::Constant *ClassStruct = 980 GenerateClassStructure(MetaClassStruct, SuperClass, 0x1L, 981 ClassName.c_str(), 0, 982 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, 983 MethodList, GenerateProtocolList(Protocols)); 984 985 // Resolve the class aliases, if they exist. 986 if (ClassPtrAlias) { 987 ClassPtrAlias->setAliasee( 988 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy)); 989 ClassPtrAlias = 0; 990 } 991 if (MetaClassPtrAlias) { 992 MetaClassPtrAlias->setAliasee( 993 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy)); 994 MetaClassPtrAlias = 0; 995 } 996 997 // Add class structure to list to be added to the symtab later 998 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 999 Classes.push_back(ClassStruct); 1000} 1001 1002void CGObjCGNU::MergeMetadataGlobals( 1003 std::vector<llvm::Constant*> &UsedArray) { 1004} 1005 1006llvm::Function *CGObjCGNU::ModuleInitFunction() { 1007 // Only emit an ObjC load function if no Objective-C stuff has been called 1008 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 1009 ExistingProtocols.empty() && TypedSelectors.empty() && 1010 UntypedSelectors.empty()) 1011 return NULL; 1012 1013 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>( 1014 SelectorTy->getElementType()); 1015 const llvm::Type *SelStructPtrTy = SelectorTy; 1016 bool isSelOpaque = false; 1017 if (SelStructTy == 0) { 1018 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL); 1019 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); 1020 isSelOpaque = true; 1021 } 1022 1023 // Name the ObjC types to make the IR a bit easier to read 1024 TheModule.addTypeName(".objc_selector", SelStructPtrTy); 1025 TheModule.addTypeName(".objc_id", IdTy); 1026 TheModule.addTypeName(".objc_imp", IMPTy); 1027 1028 std::vector<llvm::Constant*> Elements; 1029 llvm::Constant *Statics = NULLPtr; 1030 // Generate statics list: 1031 if (ConstantStrings.size()) { 1032 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 1033 ConstantStrings.size() + 1); 1034 ConstantStrings.push_back(NULLPtr); 1035 Elements.push_back(MakeConstantString("NSConstantString", 1036 ".objc_static_class_name")); 1037 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, 1038 ConstantStrings)); 1039 llvm::StructType *StaticsListTy = 1040 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL); 1041 llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy); 1042 Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics"); 1043 llvm::ArrayType *StaticsListArrayTy = 1044 llvm::ArrayType::get(StaticsListPtrTy, 2); 1045 Elements.clear(); 1046 Elements.push_back(Statics); 1047 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy)); 1048 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr"); 1049 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy); 1050 } 1051 // Array of classes, categories, and constant objects 1052 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, 1053 Classes.size() + Categories.size() + 2); 1054 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy, 1055 llvm::Type::Int16Ty, 1056 llvm::Type::Int16Ty, 1057 ClassListTy, NULL); 1058 1059 Elements.clear(); 1060 // Pointer to an array of selectors used in this module. 1061 std::vector<llvm::Constant*> Selectors; 1062 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1063 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end(); 1064 iter != iterEnd ; ++iter) { 1065 Elements.push_back(MakeConstantString(iter->first.first, ".objc_sel_name")); 1066 Elements.push_back(MakeConstantString(iter->first.second, 1067 ".objc_sel_types")); 1068 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1069 Elements.clear(); 1070 } 1071 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1072 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1073 iter != iterEnd; ++iter) { 1074 Elements.push_back( 1075 MakeConstantString(iter->getKeyData(), ".objc_sel_name")); 1076 Elements.push_back(NULLPtr); 1077 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1078 Elements.clear(); 1079 } 1080 Elements.push_back(NULLPtr); 1081 Elements.push_back(NULLPtr); 1082 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 1083 Elements.clear(); 1084 // Number of static selectors 1085 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() )); 1086 llvm::Constant *SelectorList = MakeGlobal( 1087 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, 1088 ".objc_selector_list"); 1089 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, 1090 SelStructPtrTy)); 1091 1092 // Now that all of the static selectors exist, create pointers to them. 1093 int index = 0; 1094 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 1095 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); 1096 iter != iterEnd; ++iter) { 1097 llvm::Constant *Idxs[] = {Zeros[0], 1098 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 1099 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, 1100 true, llvm::GlobalValue::InternalLinkage, 1101 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1102 ".objc_sel_ptr", &TheModule); 1103 // If selectors are defined as an opaque type, cast the pointer to this 1104 // type. 1105 if (isSelOpaque) { 1106 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1107 llvm::PointerType::getUnqual(SelectorTy)); 1108 } 1109 (*iter).second->setAliasee(SelPtr); 1110 } 1111 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 1112 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 1113 iter != iterEnd; iter++) { 1114 llvm::Constant *Idxs[] = {Zeros[0], 1115 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 1116 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, true, 1117 llvm::GlobalValue::InternalLinkage, 1118 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 1119 ".objc_sel_ptr", &TheModule); 1120 // If selectors are defined as an opaque type, cast the pointer to this 1121 // type. 1122 if (isSelOpaque) { 1123 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 1124 llvm::PointerType::getUnqual(SelectorTy)); 1125 } 1126 (*iter).second->setAliasee(SelPtr); 1127 } 1128 // Number of classes defined. 1129 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 1130 Classes.size())); 1131 // Number of categories defined 1132 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 1133 Categories.size())); 1134 // Create an array of classes, then categories, then static object instances 1135 Classes.insert(Classes.end(), Categories.begin(), Categories.end()); 1136 // NULL-terminated list of static object instances (mainly constant strings) 1137 Classes.push_back(Statics); 1138 Classes.push_back(NULLPtr); 1139 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes); 1140 Elements.push_back(ClassList); 1141 // Construct the symbol table 1142 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements); 1143 1144 // The symbol table is contained in a module which has some version-checking 1145 // constants 1146 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy, 1147 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL); 1148 Elements.clear(); 1149 // Runtime version used for compatibility checking. 1150 if (CGM.getContext().getLangOptions().ObjCNonFragileABI) { 1151 Elements.push_back(llvm::ConstantInt::get(LongTy, 1152 NonFragileRuntimeVersion)); 1153 } else { 1154 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion)); 1155 } 1156 // sizeof(ModuleTy) 1157 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1158 Elements.push_back(llvm::ConstantInt::get(LongTy, td.getTypeSizeInBits(ModuleTy)/8)); 1159 //FIXME: Should be the path to the file where this module was declared 1160 Elements.push_back(NULLPtr); 1161 Elements.push_back(SymTab); 1162 llvm::Value *Module = MakeGlobal(ModuleTy, Elements); 1163 1164 // Create the load function calling the runtime entry point with the module 1165 // structure 1166 std::vector<const llvm::Type*> VoidArgs; 1167 llvm::Function * LoadFunction = llvm::Function::Create( 1168 llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false), 1169 llvm::GlobalValue::InternalLinkage, ".objc_load_function", 1170 &TheModule); 1171 llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction); 1172 CGBuilderTy Builder; 1173 Builder.SetInsertPoint(EntryBB); 1174 1175 std::vector<const llvm::Type*> Params(1, 1176 llvm::PointerType::getUnqual(ModuleTy)); 1177 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 1178 llvm::Type::VoidTy, Params, true), "__objc_exec_class"); 1179 Builder.CreateCall(Register, Module); 1180 Builder.CreateRetVoid(); 1181 1182 return LoadFunction; 1183} 1184 1185llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 1186 const ObjCContainerDecl *CD) { 1187 const ObjCCategoryImplDecl *OCD = 1188 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); 1189 std::string CategoryName = OCD ? OCD->getNameAsString() : ""; 1190 std::string ClassName = OMD->getClassInterface()->getNameAsString(); 1191 std::string MethodName = OMD->getSelector().getAsString(); 1192 bool isClassMethod = !OMD->isInstanceMethod(); 1193 1194 CodeGenTypes &Types = CGM.getTypes(); 1195 const llvm::FunctionType *MethodTy = 1196 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 1197 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, 1198 MethodName, isClassMethod); 1199 1200 llvm::Function *Method = llvm::Function::Create(MethodTy, 1201 llvm::GlobalValue::InternalLinkage, 1202 FunctionName, 1203 &TheModule); 1204 return Method; 1205} 1206 1207llvm::Function *CGObjCGNU::GetPropertyGetFunction() { 1208 std::vector<const llvm::Type*> Params; 1209 const llvm::Type *BoolTy = 1210 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1211 Params.push_back(IdTy); 1212 Params.push_back(SelectorTy); 1213 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1214 Params.push_back(LongTy); 1215 Params.push_back(BoolTy); 1216 // void objc_getProperty (id, SEL, ptrdiff_t, bool) 1217 const llvm::FunctionType *FTy = 1218 llvm::FunctionType::get(IdTy, Params, false); 1219 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1220 "objc_getProperty")); 1221} 1222 1223llvm::Function *CGObjCGNU::GetPropertySetFunction() { 1224 std::vector<const llvm::Type*> Params; 1225 const llvm::Type *BoolTy = 1226 CGM.getTypes().ConvertType(CGM.getContext().BoolTy); 1227 Params.push_back(IdTy); 1228 Params.push_back(SelectorTy); 1229 // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64 1230 Params.push_back(LongTy); 1231 Params.push_back(IdTy); 1232 Params.push_back(BoolTy); 1233 Params.push_back(BoolTy); 1234 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 1235 const llvm::FunctionType *FTy = 1236 llvm::FunctionType::get(llvm::Type::VoidTy, Params, false); 1237 return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy, 1238 "objc_setProperty")); 1239} 1240 1241llvm::Function *CGObjCGNU::EnumerationMutationFunction() { 1242 std::vector<const llvm::Type*> Params(1, IdTy); 1243 return cast<llvm::Function>(CGM.CreateRuntimeFunction( 1244 llvm::FunctionType::get(llvm::Type::VoidTy, Params, true), 1245 "objc_enumerationMutation")); 1246} 1247 1248void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1249 const Stmt &S) { 1250 // Pointer to the personality function 1251 llvm::Constant *Personality = 1252 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 1253 std::vector<const llvm::Type*>(), true), 1254 "__gnu_objc_personality_v0"); 1255 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy); 1256 std::vector<const llvm::Type*> Params; 1257 Params.push_back(PtrTy); 1258 llvm::Value *RethrowFn = 1259 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 1260 Params, false), "_Unwind_Resume_or_Rethrow"); 1261 1262 bool isTry = isa<ObjCAtTryStmt>(S); 1263 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 1264 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 1265 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 1266 llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow"); 1267 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 1268 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 1269 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 1270 1271 // GNU runtime does not currently support @synchronized() 1272 if (!isTry) { 1273 std::vector<const llvm::Type*> Args(1, IdTy); 1274 llvm::FunctionType *FTy = 1275 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1276 llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 1277 llvm::Value *SyncArg = 1278 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1279 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1280 CGF.Builder.CreateCall(SyncEnter, SyncArg); 1281 } 1282 1283 1284 // Push an EH context entry, used for handling rethrows and jumps 1285 // through finally. 1286 CGF.PushCleanupBlock(FinallyBlock); 1287 1288 // Emit the statements in the @try {} block 1289 CGF.setInvokeDest(TryHandler); 1290 1291 CGF.EmitBlock(TryBlock); 1292 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 1293 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 1294 1295 // Jump to @finally if there is no exception 1296 CGF.EmitBranchThroughCleanup(FinallyEnd); 1297 1298 // Emit the handlers 1299 CGF.EmitBlock(TryHandler); 1300 1301 // Get the correct versions of the exception handling intrinsics 1302 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule); 1303 int PointerWidth = td.getTypeSizeInBits(PtrTy); 1304 assert((PointerWidth == 32 || PointerWidth == 64) && 1305 "Can't yet handle exceptions if pointers are not 32 or 64 bits"); 1306 llvm::Value *llvm_eh_exception = 1307 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 1308 llvm::Value *llvm_eh_selector = PointerWidth == 32 ? 1309 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i32) : 1310 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i64); 1311 llvm::Value *llvm_eh_typeid_for = PointerWidth == 32 ? 1312 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i32) : 1313 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i64); 1314 1315 // Exception object 1316 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1317 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 1318 1319 llvm::SmallVector<llvm::Value*, 8> ESelArgs; 1320 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 1321 1322 ESelArgs.push_back(Exc); 1323 ESelArgs.push_back(Personality); 1324 1325 bool HasCatchAll = false; 1326 // Only @try blocks are allowed @catch blocks, but both can have @finally 1327 if (isTry) { 1328 if (const ObjCAtCatchStmt* CatchStmt = 1329 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 1330 CGF.setInvokeDest(CatchInCatch); 1331 1332 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1333 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 1334 Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody())); 1335 1336 // @catch() and @catch(id) both catch any ObjC exception 1337 if (!CatchDecl || CGF.getContext().isObjCIdType(CatchDecl->getType()) 1338 || CatchDecl->getType()->isObjCQualifiedIdType()) { 1339 // Use i8* null here to signal this is a catch all, not a cleanup. 1340 ESelArgs.push_back(NULLPtr); 1341 HasCatchAll = true; 1342 // No further catches after this one will ever by reached 1343 break; 1344 } 1345 1346 // All other types should be Objective-C interface pointer types. 1347 const PointerType *PT = CatchDecl->getType()->getAsPointerType(); 1348 assert(PT && "Invalid @catch type."); 1349 const ObjCInterfaceType *IT = 1350 PT->getPointeeType()->getAsObjCInterfaceType(); 1351 assert(IT && "Invalid @catch type."); 1352 llvm::Value *EHType = 1353 MakeConstantString(IT->getDecl()->getNameAsString()); 1354 ESelArgs.push_back(EHType); 1355 } 1356 } 1357 } 1358 1359 // We use a cleanup unless there was already a catch all. 1360 if (!HasCatchAll) { 1361 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); 1362 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 1363 } 1364 1365 // Find which handler was matched. 1366 llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector, 1367 ESelArgs.begin(), ESelArgs.end(), "selector"); 1368 1369 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 1370 const ParmVarDecl *CatchParam = Handlers[i].first; 1371 const Stmt *CatchBody = Handlers[i].second; 1372 1373 llvm::BasicBlock *Next = 0; 1374 1375 // The last handler always matches. 1376 if (i + 1 != e) { 1377 assert(CatchParam && "Only last handler can be a catch all."); 1378 1379 // Test whether this block matches the type for the selector and branch 1380 // to Match if it does, or to the next BB if it doesn't. 1381 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 1382 Next = CGF.createBasicBlock("catch.next"); 1383 llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for, 1384 CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy)); 1385 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match, 1386 Next); 1387 1388 CGF.EmitBlock(Match); 1389 } 1390 1391 if (CatchBody) { 1392 llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc, 1393 CGF.ConvertType(CatchParam->getType())); 1394 1395 // Bind the catch parameter if it exists. 1396 if (CatchParam) { 1397 // CatchParam is a ParmVarDecl because of the grammar 1398 // construction used to handle this, but for codegen purposes 1399 // we treat this as a local decl. 1400 CGF.EmitLocalBlockVarDecl(*CatchParam); 1401 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 1402 } 1403 1404 CGF.ObjCEHValueStack.push_back(ExcObject); 1405 CGF.EmitStmt(CatchBody); 1406 CGF.ObjCEHValueStack.pop_back(); 1407 1408 CGF.EmitBranchThroughCleanup(FinallyEnd); 1409 1410 if (Next) 1411 CGF.EmitBlock(Next); 1412 } else { 1413 assert(!Next && "catchup should be last handler."); 1414 1415 CGF.Builder.CreateStore(Exc, RethrowPtr); 1416 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1417 } 1418 } 1419 // The @finally block is a secondary landing pad for any exceptions thrown in 1420 // @catch() blocks 1421 CGF.EmitBlock(CatchInCatch); 1422 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 1423 ESelArgs.clear(); 1424 ESelArgs.push_back(Exc); 1425 ESelArgs.push_back(Personality); 1426 ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); 1427 CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(), 1428 "selector"); 1429 CGF.Builder.CreateCall(llvm_eh_typeid_for, 1430 CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy)); 1431 CGF.Builder.CreateStore(Exc, RethrowPtr); 1432 CGF.EmitBranchThroughCleanup(FinallyRethrow); 1433 1434 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 1435 1436 CGF.setInvokeDest(PrevLandingPad); 1437 1438 CGF.EmitBlock(FinallyBlock); 1439 1440 1441 if (isTry) { 1442 if (const ObjCAtFinallyStmt* FinallyStmt = 1443 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 1444 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1445 } else { 1446 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 1447 // @synchronized. 1448 std::vector<const llvm::Type*> Args(1, IdTy); 1449 llvm::FunctionType *FTy = 1450 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1451 llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 1452 llvm::Value *SyncArg = 1453 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1454 SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy); 1455 CGF.Builder.CreateCall(SyncExit, SyncArg); 1456 } 1457 1458 if (Info.SwitchBlock) 1459 CGF.EmitBlock(Info.SwitchBlock); 1460 if (Info.EndBlock) 1461 CGF.EmitBlock(Info.EndBlock); 1462 1463 // Branch around the rethrow code. 1464 CGF.EmitBranch(FinallyEnd); 1465 1466 CGF.EmitBlock(FinallyRethrow); 1467 CGF.Builder.CreateCall(RethrowFn, CGF.Builder.CreateLoad(RethrowPtr)); 1468 CGF.Builder.CreateUnreachable(); 1469 1470 CGF.EmitBlock(FinallyEnd); 1471 1472} 1473 1474void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1475 const ObjCAtThrowStmt &S) { 1476 llvm::Value *ExceptionAsObject; 1477 1478 std::vector<const llvm::Type*> Args(1, IdTy); 1479 llvm::FunctionType *FTy = 1480 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 1481 llvm::Value *ThrowFn = 1482 CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 1483 1484 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1485 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1486 ExceptionAsObject = Exception; 1487 } else { 1488 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 1489 "Unexpected rethrow outside @catch block."); 1490 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 1491 } 1492 ExceptionAsObject = 1493 CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp"); 1494 1495 // Note: This may have to be an invoke, if we want to support constructs like: 1496 // @try { 1497 // @throw(obj); 1498 // } 1499 // @catch(id) ... 1500 // 1501 // This is effectively turning @throw into an incredibly-expensive goto, but 1502 // it may happen as a result of inlining followed by missed optimizations, or 1503 // as a result of stupidity. 1504 llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); 1505 if (!UnwindBB) { 1506 CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject); 1507 CGF.Builder.CreateUnreachable(); 1508 } else { 1509 CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject, 1510 &ExceptionAsObject+1); 1511 } 1512 // Clear the insertion point to indicate we are in unreachable code. 1513 CGF.Builder.ClearInsertionPoint(); 1514} 1515 1516llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1517 llvm::Value *AddrWeakObj) 1518{ 1519 return 0; 1520} 1521 1522void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1523 llvm::Value *src, llvm::Value *dst) 1524{ 1525 return; 1526} 1527 1528void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1529 llvm::Value *src, llvm::Value *dst) 1530{ 1531 return; 1532} 1533 1534void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1535 llvm::Value *src, llvm::Value *dst) 1536{ 1537 return; 1538} 1539 1540void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1541 llvm::Value *src, llvm::Value *dst) 1542{ 1543 return; 1544} 1545 1546llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( 1547 const ObjCInterfaceDecl *ID, 1548 const ObjCIvarDecl *Ivar) { 1549 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString() 1550 + '.' + Ivar->getNameAsString(); 1551 // Emit the variable and initialize it with what we think the correct value 1552 // is. This allows code compiled with non-fragile ivars to work correctly 1553 // when linked against code which isn't (most of the time). 1554 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); 1555 if (!IvarOffsetGV) { 1556 uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); 1557 llvm::ConstantInt *OffsetGuess = 1558 llvm::ConstantInt::get(LongTy, Offset, "ivar"); 1559 IvarOffsetGV = new llvm::GlobalVariable(LongTy, false, 1560 llvm::GlobalValue::CommonLinkage, OffsetGuess, Name, &TheModule); 1561 } 1562 return IvarOffsetGV; 1563} 1564 1565LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1566 QualType ObjectTy, 1567 llvm::Value *BaseValue, 1568 const ObjCIvarDecl *Ivar, 1569 unsigned CVRQualifiers) { 1570 const ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); 1571 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 1572 EmitIvarOffset(CGF, ID, Ivar)); 1573} 1574static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 1575 const ObjCInterfaceDecl *OID, 1576 const ObjCIvarDecl *OIVD) { 1577 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 1578 Context.ShallowCollectObjCIvars(OID, Ivars); 1579 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 1580 if (OIVD == Ivars[k]) 1581 return OID; 1582 } 1583 1584 // Otherwise check in the super class. 1585 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1586 return FindIvarInterface(Context, Super, OIVD); 1587 1588 return 0; 1589} 1590 1591llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1592 const ObjCInterfaceDecl *Interface, 1593 const ObjCIvarDecl *Ivar) { 1594 if (CGF.getContext().getLangOptions().ObjCNonFragileABI) 1595 { 1596 Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar); 1597 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar), 1598 false, "ivar"); 1599 } 1600 uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); 1601 return llvm::ConstantInt::get(LongTy, Offset, "ivar"); 1602} 1603 1604CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ 1605 return new CGObjCGNU(CGM); 1606} 1607