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