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