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