CGObjCGNU.cpp revision 26c8294dacc2efc83d8d560593ff863e7a32a48f
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 "clang/AST/ASTContext.h" 21#include "clang/AST/Decl.h" 22#include "clang/AST/DeclObjC.h" 23#include "llvm/Module.h" 24#include "llvm/ADT/SmallVector.h" 25#include "llvm/ADT/StringMap.h" 26#include "llvm/Support/Compiler.h" 27#include "llvm/Target/TargetData.h" 28#include <map> 29 30 31using namespace clang; 32using namespace CodeGen; 33using llvm::dyn_cast; 34 35// The version of the runtime that this class targets. Must match the version 36// in the runtime. 37static const int RuntimeVersion = 8; 38static const int ProtocolVersion = 2; 39 40namespace { 41class CGObjCGNU : public CodeGen::CGObjCRuntime { 42private: 43 CodeGen::CodeGenModule &CGM; 44 llvm::Module &TheModule; 45 const llvm::PointerType *SelectorTy; 46 const llvm::PointerType *PtrToInt8Ty; 47 const llvm::FunctionType *IMPTy; 48 const llvm::PointerType *IdTy; 49 const llvm::IntegerType *IntTy; 50 const llvm::PointerType *PtrTy; 51 const llvm::IntegerType *LongTy; 52 const llvm::PointerType *PtrToIntTy; 53 std::vector<llvm::Constant*> Classes; 54 std::vector<llvm::Constant*> Categories; 55 std::vector<llvm::Constant*> ConstantStrings; 56 llvm::Function *LoadFunction; 57 llvm::StringMap<llvm::Constant*> ExistingProtocols; 58 typedef std::pair<std::string, std::string> TypedSelector; 59 std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors; 60 llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors; 61 // Some zeros used for GEPs in lots of places. 62 llvm::Constant *Zeros[2]; 63 llvm::Constant *NULLPtr; 64private: 65 llvm::Constant *GenerateIvarList( 66 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 67 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 68 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets); 69 llvm::Constant *GenerateMethodList(const std::string &ClassName, 70 const std::string &CategoryName, 71 const llvm::SmallVectorImpl<Selector> &MethodSels, 72 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 73 bool isClassMethodList); 74 llvm::Constant *GenerateProtocolList( 75 const llvm::SmallVectorImpl<std::string> &Protocols); 76 llvm::Constant *GenerateClassStructure( 77 llvm::Constant *MetaClass, 78 llvm::Constant *SuperClass, 79 unsigned info, 80 const char *Name, 81 llvm::Constant *Version, 82 llvm::Constant *InstanceSize, 83 llvm::Constant *IVars, 84 llvm::Constant *Methods, 85 llvm::Constant *Protocols); 86 llvm::Constant *GenerateProtocolMethodList( 87 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 88 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes); 89 llvm::Constant *MakeConstantString(const std::string &Str, const std::string 90 &Name=""); 91 llvm::Constant *MakeGlobal(const llvm::StructType *Ty, 92 std::vector<llvm::Constant*> &V, const std::string &Name=""); 93 llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty, 94 std::vector<llvm::Constant*> &V, const std::string &Name=""); 95public: 96 CGObjCGNU(CodeGen::CodeGenModule &cgm); 97 virtual llvm::Constant *GenerateConstantString(const std::string &String); 98 virtual CodeGen::RValue 99 GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 100 QualType ResultType, 101 Selector Sel, 102 llvm::Value *Receiver, 103 bool IsClassMessage, 104 const CallArgList &CallArgs); 105 virtual CodeGen::RValue 106 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 107 QualType ResultType, 108 Selector Sel, 109 const ObjCInterfaceDecl *Class, 110 bool isCategoryImpl, 111 llvm::Value *Receiver, 112 bool IsClassMessage, 113 const CallArgList &CallArgs); 114 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 115 const ObjCInterfaceDecl *OID); 116 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 117 118 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 119 const ObjCContainerDecl *CD); 120 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 121 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 122 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 123 const ObjCProtocolDecl *PD); 124 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 125 virtual llvm::Function *ModuleInitFunction(); 126 virtual llvm::Function *GetPropertyGetFunction(); 127 virtual llvm::Function *GetPropertySetFunction(); 128 virtual llvm::Function *EnumerationMutationFunction(); 129 130 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 131 const Stmt &S); 132 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 133 const ObjCAtThrowStmt &S); 134 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 135 llvm::Value *AddrWeakObj); 136 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 137 llvm::Value *src, llvm::Value *dst); 138 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 139 llvm::Value *src, llvm::Value *dest); 140 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 141 llvm::Value *src, llvm::Value *dest); 142 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 143 llvm::Value *src, llvm::Value *dest); 144 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 145 QualType ObjectTy, 146 llvm::Value *BaseValue, 147 const ObjCIvarDecl *Ivar, 148 const FieldDecl *Field, 149 unsigned CVRQualifiers); 150 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 151 ObjCInterfaceDecl *Interface, 152 const ObjCIvarDecl *Ivar); 153}; 154} // end anonymous namespace 155 156 157 158static std::string SymbolNameForClass(const std::string &ClassName) { 159 return ".objc_class_" + ClassName; 160} 161 162static std::string SymbolNameForMethod(const std::string &ClassName, const 163 std::string &CategoryName, const std::string &MethodName, bool isClassMethod) 164{ 165 return "._objc_method_" + ClassName +"("+CategoryName+")"+ 166 (isClassMethod ? "+" : "-") + MethodName; 167} 168 169CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) 170 : CGM(cgm), TheModule(CGM.getModule()) { 171 IntTy = cast<llvm::IntegerType>( 172 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 173 LongTy = cast<llvm::IntegerType>( 174 CGM.getTypes().ConvertType(CGM.getContext().LongTy)); 175 176 Zeros[0] = llvm::ConstantInt::get(LongTy, 0); 177 Zeros[1] = Zeros[0]; 178 NULLPtr = llvm::ConstantPointerNull::get( 179 llvm::PointerType::getUnqual(llvm::Type::Int8Ty)); 180 // C string type. Used in lots of places. 181 PtrToInt8Ty = 182 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 183 // Get the selector Type. 184 SelectorTy = cast<llvm::PointerType>( 185 CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType())); 186 187 PtrToIntTy = llvm::PointerType::getUnqual(IntTy); 188 PtrTy = PtrToInt8Ty; 189 190 // Object type 191 IdTy = cast<llvm::PointerType>( 192 CGM.getTypes().ConvertType(CGM.getContext().getObjCIdType())); 193 194 // IMP type 195 std::vector<const llvm::Type*> IMPArgs; 196 IMPArgs.push_back(IdTy); 197 IMPArgs.push_back(SelectorTy); 198 IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true); 199} 200// This has to perform the lookup every time, since posing and related 201// techniques can modify the name -> class mapping. 202llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, 203 const ObjCInterfaceDecl *OID) { 204 llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString()); 205 ClassName = Builder.CreateStructGEP(ClassName, 0); 206 207 std::vector<const llvm::Type*> Params(1, PtrToInt8Ty); 208 llvm::Constant *ClassLookupFn = 209 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, 210 Params, 211 true), 212 "objc_lookup_class"); 213 return Builder.CreateCall(ClassLookupFn, ClassName); 214} 215 216/// GetSelector - Return the pointer to the unique'd string for this selector. 217llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { 218 // FIXME: uniquing on the string is wasteful, unique on Sel instead! 219 llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; 220 if (US == 0) 221 US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), 222 llvm::GlobalValue::InternalLinkage, 223 ".objc_untyped_selector_alias", 224 NULL, &TheModule); 225 226 return Builder.CreateLoad(US); 227 228} 229 230llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, 231 const std::string &Name) { 232 llvm::Constant * ConstStr = llvm::ConstantArray::get(Str); 233 ConstStr = new llvm::GlobalVariable(ConstStr->getType(), true, 234 llvm::GlobalValue::InternalLinkage, 235 ConstStr, Name, &TheModule); 236 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); 237} 238llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty, 239 std::vector<llvm::Constant*> &V, const std::string &Name) { 240 llvm::Constant *C = llvm::ConstantStruct::get(Ty, V); 241 return new llvm::GlobalVariable(Ty, false, 242 llvm::GlobalValue::InternalLinkage, C, Name, &TheModule); 243} 244llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty, 245 std::vector<llvm::Constant*> &V, const std::string &Name) { 246 llvm::Constant *C = llvm::ConstantArray::get(Ty, V); 247 return new llvm::GlobalVariable(Ty, false, 248 llvm::GlobalValue::InternalLinkage, C, Name, &TheModule); 249} 250 251/// Generate an NSConstantString object. 252//TODO: In case there are any crazy people still using the GNU runtime without 253//an OpenStep implementation, this should let them select their own class for 254//constant strings. 255llvm::Constant *CGObjCGNU::GenerateConstantString(const std::string &Str) { 256 std::vector<llvm::Constant*> Ivars; 257 Ivars.push_back(NULLPtr); 258 Ivars.push_back(MakeConstantString(Str)); 259 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size())); 260 llvm::Constant *ObjCStr = MakeGlobal( 261 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL), 262 Ivars, ".objc_str"); 263 ConstantStrings.push_back( 264 llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty)); 265 return ObjCStr; 266} 267 268///Generates a message send where the super is the receiver. This is a message 269///send to self with special delivery semantics indicating which class's method 270///should be called. 271CodeGen::RValue 272CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 273 QualType ResultType, 274 Selector Sel, 275 const ObjCInterfaceDecl *Class, 276 bool isCategoryImpl, 277 llvm::Value *Receiver, 278 bool IsClassMessage, 279 const CallArgList &CallArgs) { 280 llvm::Value *cmd = GetSelector(CGF.Builder, Sel); 281 282 CallArgList ActualArgs; 283 284 ActualArgs.push_back( 285 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 286 CGF.getContext().getObjCIdType())); 287 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 288 CGF.getContext().getObjCSelType())); 289 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 290 291 CodeGenTypes &Types = CGM.getTypes(); 292 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 293 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false); 294 295 296 const ObjCInterfaceDecl *SuperClass = Class->getSuperClass(); 297 // TODO: This should be cached, not looked up every time. 298 llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass); 299 300 301 // Construct the structure used to look up the IMP 302 llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(), 303 IdTy, NULL); 304 llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy); 305 306 CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 307 CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 308 309 // Get the IMP 310 std::vector<const llvm::Type*> Params; 311 Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy)); 312 Params.push_back(SelectorTy); 313 llvm::Constant *lookupFunction = 314 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 315 llvm::PointerType::getUnqual(impType), Params, true), 316 "objc_msg_lookup_super"); 317 318 llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; 319 llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, 320 lookupArgs+2); 321 322 return CGF.EmitCall(FnInfo, imp, ActualArgs); 323} 324 325/// Generate code for a message send expression. 326CodeGen::RValue 327CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 328 QualType ResultType, 329 Selector Sel, 330 llvm::Value *Receiver, 331 bool IsClassMessage, 332 const CallArgList &CallArgs) { 333 llvm::Value *cmd = GetSelector(CGF.Builder, Sel); 334 CallArgList ActualArgs; 335 336 ActualArgs.push_back( 337 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), 338 CGF.getContext().getObjCIdType())); 339 ActualArgs.push_back(std::make_pair(RValue::get(cmd), 340 CGF.getContext().getObjCSelType())); 341 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 342 343 CodeGenTypes &Types = CGM.getTypes(); 344 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 345 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false); 346 347 std::vector<const llvm::Type*> Params; 348 Params.push_back(Receiver->getType()); 349 Params.push_back(SelectorTy); 350 llvm::Constant *lookupFunction = 351 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 352 llvm::PointerType::getUnqual(impType), Params, true), 353 "objc_msg_lookup"); 354 355 llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd); 356 357 return CGF.EmitCall(FnInfo, imp, ActualArgs); 358} 359 360/// Generates a MethodList. Used in construction of a objc_class and 361/// objc_category structures. 362llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName, 363 const std::string &CategoryName, 364 const llvm::SmallVectorImpl<Selector> &MethodSels, 365 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes, 366 bool isClassMethodList) { 367 // Get the method structure type. 368 llvm::StructType *ObjCMethodTy = llvm::StructType::get( 369 PtrToInt8Ty, // Really a selector, but the runtime creates it us. 370 PtrToInt8Ty, // Method types 371 llvm::PointerType::getUnqual(IMPTy), //Method pointer 372 NULL); 373 std::vector<llvm::Constant*> Methods; 374 std::vector<llvm::Constant*> Elements; 375 for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) { 376 Elements.clear(); 377 llvm::Constant *C = 378 CGM.GetAddrOfConstantCString(MethodSels[i].getAsString()); 379 Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2)); 380 Elements.push_back( 381 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2)); 382 llvm::Constant *Method = 383 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName, 384 MethodSels[i].getAsString(), 385 isClassMethodList)); 386 Method = llvm::ConstantExpr::getBitCast(Method, 387 llvm::PointerType::getUnqual(IMPTy)); 388 Elements.push_back(Method); 389 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements)); 390 } 391 392 // Array of method structures 393 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy, 394 MethodSels.size()); 395 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy, 396 Methods); 397 398 // Structure containing list pointer, array and array count 399 llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields; 400 llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(); 401 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy); 402 llvm::StructType *ObjCMethodListTy = llvm::StructType::get(NextPtrTy, 403 IntTy, 404 ObjCMethodArrayTy, 405 NULL); 406 // Refine next pointer type to concrete type 407 llvm::cast<llvm::OpaqueType>( 408 OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy); 409 ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get()); 410 411 Methods.clear(); 412 Methods.push_back(llvm::ConstantPointerNull::get( 413 llvm::PointerType::getUnqual(ObjCMethodListTy))); 414 Methods.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 415 MethodTypes.size())); 416 Methods.push_back(MethodArray); 417 418 // Create an instance of the structure 419 return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list"); 420} 421 422/// Generates an IvarList. Used in construction of a objc_class. 423llvm::Constant *CGObjCGNU::GenerateIvarList( 424 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 425 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 426 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) { 427 // Get the method structure type. 428 llvm::StructType *ObjCIvarTy = llvm::StructType::get( 429 PtrToInt8Ty, 430 PtrToInt8Ty, 431 IntTy, 432 NULL); 433 std::vector<llvm::Constant*> Ivars; 434 std::vector<llvm::Constant*> Elements; 435 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) { 436 Elements.clear(); 437 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarNames[i], 438 Zeros, 2)); 439 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarTypes[i], 440 Zeros, 2)); 441 Elements.push_back(IvarOffsets[i]); 442 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements)); 443 } 444 445 // Array of method structures 446 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy, 447 IvarNames.size()); 448 449 450 Elements.clear(); 451 Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size())); 452 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)); 453 // Structure containing array and array count 454 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy, 455 ObjCIvarArrayTy, 456 NULL); 457 458 // Create an instance of the structure 459 return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list"); 460} 461 462/// Generate a class structure 463llvm::Constant *CGObjCGNU::GenerateClassStructure( 464 llvm::Constant *MetaClass, 465 llvm::Constant *SuperClass, 466 unsigned info, 467 const char *Name, 468 llvm::Constant *Version, 469 llvm::Constant *InstanceSize, 470 llvm::Constant *IVars, 471 llvm::Constant *Methods, 472 llvm::Constant *Protocols) { 473 // Set up the class structure 474 // Note: Several of these are char*s when they should be ids. This is 475 // because the runtime performs this translation on load. 476 llvm::StructType *ClassTy = llvm::StructType::get( 477 PtrToInt8Ty, // class_pointer 478 PtrToInt8Ty, // super_class 479 PtrToInt8Ty, // name 480 LongTy, // version 481 LongTy, // info 482 LongTy, // instance_size 483 IVars->getType(), // ivars 484 Methods->getType(), // methods 485 // These are all filled in by the runtime, so we pretend 486 PtrTy, // dtable 487 PtrTy, // subclass_list 488 PtrTy, // sibling_class 489 PtrTy, // protocols 490 PtrTy, // gc_object_type 491 NULL); 492 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); 493 llvm::Constant *NullP = 494 llvm::ConstantPointerNull::get(PtrTy); 495 // Fill in the structure 496 std::vector<llvm::Constant*> Elements; 497 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty)); 498 Elements.push_back(SuperClass); 499 Elements.push_back(MakeConstantString(Name, ".class_name")); 500 Elements.push_back(Zero); 501 Elements.push_back(llvm::ConstantInt::get(LongTy, info)); 502 Elements.push_back(InstanceSize); 503 Elements.push_back(IVars); 504 Elements.push_back(Methods); 505 Elements.push_back(NullP); 506 Elements.push_back(NullP); 507 Elements.push_back(NullP); 508 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy)); 509 Elements.push_back(NullP); 510 // Create an instance of the structure 511 return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name)); 512} 513 514llvm::Constant *CGObjCGNU::GenerateProtocolMethodList( 515 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames, 516 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) { 517 // Get the method structure type. 518 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get( 519 PtrToInt8Ty, // Really a selector, but the runtime does the casting for us. 520 PtrToInt8Ty, 521 NULL); 522 std::vector<llvm::Constant*> Methods; 523 std::vector<llvm::Constant*> Elements; 524 for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) { 525 Elements.clear(); 526 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(MethodNames[i], 527 Zeros, 2)); 528 Elements.push_back( 529 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2)); 530 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements)); 531 } 532 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy, 533 MethodNames.size()); 534 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, Methods); 535 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get( 536 IntTy, ObjCMethodArrayTy, NULL); 537 Methods.clear(); 538 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size())); 539 Methods.push_back(Array); 540 return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list"); 541} 542// Create the protocol list structure used in classes, categories and so on 543llvm::Constant *CGObjCGNU::GenerateProtocolList( 544 const llvm::SmallVectorImpl<std::string> &Protocols) { 545 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 546 Protocols.size()); 547 llvm::StructType *ProtocolListTy = llvm::StructType::get( 548 PtrTy, //Should be a recurisve pointer, but it's always NULL here. 549 LongTy,//FIXME: Should be size_t 550 ProtocolArrayTy, 551 NULL); 552 std::vector<llvm::Constant*> Elements; 553 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); 554 iter != endIter ; iter++) { 555 llvm::Constant *Ptr = 556 llvm::ConstantExpr::getBitCast(ExistingProtocols[*iter], PtrToInt8Ty); 557 Elements.push_back(Ptr); 558 } 559 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy, 560 Elements); 561 Elements.clear(); 562 Elements.push_back(NULLPtr); 563 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size())); 564 Elements.push_back(ProtocolArray); 565 return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); 566} 567 568llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder, 569 const ObjCProtocolDecl *PD) { 570 return ExistingProtocols[PD->getNameAsString()]; 571} 572 573void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { 574 ASTContext &Context = CGM.getContext(); 575 std::string ProtocolName = PD->getNameAsString(); 576 llvm::SmallVector<std::string, 16> Protocols; 577 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(), 578 E = PD->protocol_end(); PI != E; ++PI) 579 Protocols.push_back((*PI)->getNameAsString()); 580 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames; 581 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 582 for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(), 583 E = PD->instmeth_end(); iter != E; iter++) { 584 std::string TypeStr; 585 Context.getObjCEncodingForMethodDecl(*iter, TypeStr); 586 InstanceMethodNames.push_back( 587 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString())); 588 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 589 } 590 // Collect information about class methods: 591 llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames; 592 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 593 for (ObjCProtocolDecl::classmeth_iterator iter = PD->classmeth_begin(), 594 endIter = PD->classmeth_end() ; iter != endIter ; iter++) { 595 std::string TypeStr; 596 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 597 ClassMethodNames.push_back( 598 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString())); 599 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 600 } 601 602 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols); 603 llvm::Constant *InstanceMethodList = 604 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes); 605 llvm::Constant *ClassMethodList = 606 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes); 607 // Protocols are objects containing lists of the methods implemented and 608 // protocols adopted. 609 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy, 610 PtrToInt8Ty, 611 ProtocolList->getType(), 612 InstanceMethodList->getType(), 613 ClassMethodList->getType(), 614 NULL); 615 std::vector<llvm::Constant*> Elements; 616 // The isa pointer must be set to a magic number so the runtime knows it's 617 // the correct layout. 618 Elements.push_back(llvm::ConstantExpr::getIntToPtr( 619 llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy)); 620 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name")); 621 Elements.push_back(ProtocolList); 622 Elements.push_back(InstanceMethodList); 623 Elements.push_back(ClassMethodList); 624 ExistingProtocols[ProtocolName] = 625 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements, 626 ".objc_protocol"), IdTy); 627} 628 629void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 630 std::string ClassName = OCD->getClassInterface()->getNameAsString(); 631 std::string CategoryName = OCD->getNameAsString(); 632 // Collect information about instance methods 633 llvm::SmallVector<Selector, 16> InstanceMethodSels; 634 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 635 for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(), 636 endIter = OCD->instmeth_end() ; iter != endIter ; iter++) { 637 InstanceMethodSels.push_back((*iter)->getSelector()); 638 std::string TypeStr; 639 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 640 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 641 } 642 643 // Collect information about class methods 644 llvm::SmallVector<Selector, 16> ClassMethodSels; 645 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 646 for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(), 647 endIter = OCD->classmeth_end() ; iter != endIter ; iter++) { 648 ClassMethodSels.push_back((*iter)->getSelector()); 649 std::string TypeStr; 650 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr); 651 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 652 } 653 654 // Collect the names of referenced protocols 655 llvm::SmallVector<std::string, 16> Protocols; 656 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface(); 657 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 658 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 659 E = Protos.end(); I != E; ++I) 660 Protocols.push_back((*I)->getNameAsString()); 661 662 std::vector<llvm::Constant*> Elements; 663 Elements.push_back(MakeConstantString(CategoryName)); 664 Elements.push_back(MakeConstantString(ClassName)); 665 // Instance method list 666 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 667 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes, 668 false), PtrTy)); 669 // Class method list 670 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList( 671 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true), 672 PtrTy)); 673 // Protocol list 674 Elements.push_back(llvm::ConstantExpr::getBitCast( 675 GenerateProtocolList(Protocols), PtrTy)); 676 Categories.push_back(llvm::ConstantExpr::getBitCast( 677 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy, 678 PtrTy, PtrTy, NULL), Elements), PtrTy)); 679} 680 681void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { 682 ASTContext &Context = CGM.getContext(); 683 684 // Get the superclass name. 685 const ObjCInterfaceDecl * SuperClassDecl = 686 OID->getClassInterface()->getSuperClass(); 687 std::string SuperClassName; 688 if (SuperClassDecl) 689 SuperClassName = SuperClassDecl->getNameAsString(); 690 691 // Get the class name 692 ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface(); 693 std::string ClassName = ClassDecl->getNameAsString(); 694 695 // Get the size of instances. For runtimes that support late-bound instances 696 // this should probably be something different (size just of instance 697 // varaibles in this class, not superclasses?). 698 int instanceSize = 0; 699 const llvm::Type *ObjTy = 0; 700 if (!LateBoundIVars()) { 701 ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl)); 702 instanceSize = CGM.getTargetData().getTypePaddedSize(ObjTy); 703 } else { 704 // This is required by newer ObjC runtimes. 705 assert(0 && "Late-bound instance variables not yet supported"); 706 } 707 708 // Collect information about instance variables. 709 llvm::SmallVector<llvm::Constant*, 16> IvarNames; 710 llvm::SmallVector<llvm::Constant*, 16> IvarTypes; 711 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets; 712 const llvm::StructLayout *Layout = 713 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(ObjTy)); 714 ObjTy = llvm::PointerType::getUnqual(ObjTy); 715 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), 716 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { 717 // Store the name 718 IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter) 719 ->getNameAsString())); 720 // Get the type encoding for this ivar 721 std::string TypeStr; 722 Context.getObjCEncodingForType((*iter)->getType(), TypeStr); 723 IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 724 // Get the offset 725 FieldDecl *Field = ClassDecl->lookupFieldDeclForIvar(Context, (*iter)); 726 int offset = 727 (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); 728 IvarOffsets.push_back( 729 llvm::ConstantInt::get(llvm::Type::Int32Ty, offset)); 730 } 731 732 // Collect information about instance methods 733 llvm::SmallVector<Selector, 16> InstanceMethodSels; 734 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; 735 for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(), 736 endIter = OID->instmeth_end() ; iter != endIter ; iter++) { 737 InstanceMethodSels.push_back((*iter)->getSelector()); 738 std::string TypeStr; 739 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 740 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 741 } 742 743 // Collect information about class methods 744 llvm::SmallVector<Selector, 16> ClassMethodSels; 745 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; 746 for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(), 747 endIter = OID->classmeth_end() ; iter != endIter ; iter++) { 748 ClassMethodSels.push_back((*iter)->getSelector()); 749 std::string TypeStr; 750 Context.getObjCEncodingForMethodDecl((*iter),TypeStr); 751 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); 752 } 753 // Collect the names of referenced protocols 754 llvm::SmallVector<std::string, 16> Protocols; 755 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols(); 756 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(), 757 E = Protos.end(); I != E; ++I) 758 Protocols.push_back((*I)->getNameAsString()); 759 760 761 762 // Get the superclass pointer. 763 llvm::Constant *SuperClass; 764 if (!SuperClassName.empty()) { 765 SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); 766 } else { 767 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); 768 } 769 // Empty vector used to construct empty method lists 770 llvm::SmallVector<llvm::Constant*, 1> empty; 771 // Generate the method and instance variable lists 772 llvm::Constant *MethodList = GenerateMethodList(ClassName, "", 773 InstanceMethodSels, InstanceMethodTypes, false); 774 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "", 775 ClassMethodSels, ClassMethodTypes, true); 776 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes, 777 IvarOffsets); 778 //Generate metaclass for class methods 779 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, 780 NULLPtr, 0x2L, /*name*/"", 0, Zeros[0], GenerateIvarList( 781 empty, empty, empty), ClassMethodList, NULLPtr); 782 // Generate the class structure 783 llvm::Constant *ClassStruct = 784 GenerateClassStructure(MetaClassStruct, SuperClass, 0x1L, 785 ClassName.c_str(), 0, 786 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, 787 MethodList, GenerateProtocolList(Protocols)); 788 // Add class structure to list to be added to the symtab later 789 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty); 790 Classes.push_back(ClassStruct); 791} 792 793llvm::Function *CGObjCGNU::ModuleInitFunction() { 794 // Only emit an ObjC load function if no Objective-C stuff has been called 795 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && 796 ExistingProtocols.empty() && TypedSelectors.empty() && 797 UntypedSelectors.empty()) 798 return NULL; 799 800 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>( 801 SelectorTy->getElementType()); 802 const llvm::Type *SelStructPtrTy = SelectorTy; 803 bool isSelOpaque = false; 804 if (SelStructTy == 0) { 805 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL); 806 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); 807 isSelOpaque = true; 808 } 809 810 // Name the ObjC types to make the IR a bit easier to read 811 TheModule.addTypeName(".objc_selector", SelStructPtrTy); 812 TheModule.addTypeName(".objc_id", IdTy); 813 TheModule.addTypeName(".objc_imp", IMPTy); 814 815 std::vector<llvm::Constant*> Elements; 816 // Generate statics list: 817 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty, 818 ConstantStrings.size() + 1); 819 ConstantStrings.push_back(NULLPtr); 820 Elements.push_back(MakeConstantString("NSConstantString", 821 ".objc_static_class_name")); 822 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, ConstantStrings)); 823 llvm::StructType *StaticsListTy = 824 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL); 825 llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy); 826 llvm::Constant *Statics = 827 MakeGlobal(StaticsListTy, Elements, ".objc_statics"); 828 llvm::ArrayType *StaticsListArrayTy = 829 llvm::ArrayType::get(StaticsListPtrTy, 2); 830 Elements.clear(); 831 Elements.push_back(Statics); 832 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy)); 833 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr"); 834 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy); 835 // Array of classes, categories, and constant objects 836 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, 837 Classes.size() + Categories.size() + 2); 838 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy, 839 llvm::Type::Int16Ty, 840 llvm::Type::Int16Ty, 841 ClassListTy, NULL); 842 843 Elements.clear(); 844 // Pointer to an array of selectors used in this module. 845 std::vector<llvm::Constant*> Selectors; 846 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 847 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end(); 848 iter != iterEnd ; ++iter) { 849 Elements.push_back(MakeConstantString(iter->first.first, ".objc_sel_name")); 850 Elements.push_back(MakeConstantString(iter->first.second, 851 ".objc_sel_types")); 852 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 853 Elements.clear(); 854 } 855 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 856 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 857 iter != iterEnd; ++iter) { 858 Elements.push_back( 859 MakeConstantString(iter->getKeyData(), ".objc_sel_name")); 860 Elements.push_back(NULLPtr); 861 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 862 Elements.clear(); 863 } 864 Elements.push_back(NULLPtr); 865 Elements.push_back(NULLPtr); 866 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements)); 867 Elements.clear(); 868 // Number of static selectors 869 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() )); 870 llvm::Constant *SelectorList = MakeGlobal( 871 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, 872 ".objc_selector_list"); 873 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, 874 SelStructPtrTy)); 875 876 // Now that all of the static selectors exist, create pointers to them. 877 int index = 0; 878 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator 879 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); 880 iter != iterEnd; ++iter) { 881 llvm::Constant *Idxs[] = {Zeros[0], 882 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 883 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, 884 true, llvm::GlobalValue::InternalLinkage, 885 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 886 ".objc_sel_ptr", &TheModule); 887 // If selectors are defined as an opaque type, cast the pointer to this 888 // type. 889 if (isSelOpaque) { 890 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 891 llvm::PointerType::getUnqual(SelectorTy)); 892 } 893 (*iter).second->setAliasee(SelPtr); 894 } 895 for (llvm::StringMap<llvm::GlobalAlias*>::iterator 896 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); 897 iter != iterEnd; iter++) { 898 llvm::Constant *Idxs[] = {Zeros[0], 899 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; 900 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, true, 901 llvm::GlobalValue::InternalLinkage, 902 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), 903 ".objc_sel_ptr", &TheModule); 904 // If selectors are defined as an opaque type, cast the pointer to this 905 // type. 906 if (isSelOpaque) { 907 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, 908 llvm::PointerType::getUnqual(SelectorTy)); 909 } 910 (*iter).second->setAliasee(SelPtr); 911 } 912 // Number of classes defined. 913 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 914 Classes.size())); 915 // Number of categories defined 916 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty, 917 Categories.size())); 918 // Create an array of classes, then categories, then static object instances 919 Classes.insert(Classes.end(), Categories.begin(), Categories.end()); 920 // NULL-terminated list of static object instances (mainly constant strings) 921 Classes.push_back(Statics); 922 Classes.push_back(NULLPtr); 923 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes); 924 Elements.push_back(ClassList); 925 // Construct the symbol table 926 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements); 927 928 // The symbol table is contained in a module which has some version-checking 929 // constants 930 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy, 931 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL); 932 Elements.clear(); 933 // Runtime version used for compatibility checking. 934 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion)); 935 //FIXME: Should be sizeof(ModuleTy) 936 Elements.push_back(llvm::ConstantInt::get(LongTy, 16)); 937 //FIXME: Should be the path to the file where this module was declared 938 Elements.push_back(NULLPtr); 939 Elements.push_back(SymTab); 940 llvm::Value *Module = MakeGlobal(ModuleTy, Elements); 941 942 // Create the load function calling the runtime entry point with the module 943 // structure 944 std::vector<const llvm::Type*> VoidArgs; 945 llvm::Function * LoadFunction = llvm::Function::Create( 946 llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false), 947 llvm::GlobalValue::InternalLinkage, ".objc_load_function", 948 &TheModule); 949 llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction); 950 CGBuilderTy Builder; 951 Builder.SetInsertPoint(EntryBB); 952 953 std::vector<const llvm::Type*> Params(1, 954 llvm::PointerType::getUnqual(ModuleTy)); 955 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get( 956 llvm::Type::VoidTy, Params, true), "__objc_exec_class"); 957 Builder.CreateCall(Register, Module); 958 Builder.CreateRetVoid(); 959 return LoadFunction; 960} 961 962llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, 963 const ObjCContainerDecl *CD) { 964 const ObjCCategoryImplDecl *OCD = 965 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext()); 966 std::string CategoryName = OCD ? OCD->getNameAsString() : ""; 967 std::string ClassName = OMD->getClassInterface()->getNameAsString(); 968 std::string MethodName = OMD->getSelector().getAsString(); 969 bool isClassMethod = !OMD->isInstanceMethod(); 970 971 CodeGenTypes &Types = CGM.getTypes(); 972 const llvm::FunctionType *MethodTy = 973 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 974 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, 975 MethodName, isClassMethod); 976 977 llvm::Function *Method = llvm::Function::Create(MethodTy, 978 llvm::GlobalValue::InternalLinkage, 979 FunctionName, 980 &TheModule); 981 return Method; 982} 983 984llvm::Function *CGObjCGNU::GetPropertyGetFunction() { 985 return 0; 986} 987 988llvm::Function *CGObjCGNU::GetPropertySetFunction() { 989 return 0; 990} 991 992llvm::Function *CGObjCGNU::EnumerationMutationFunction() { 993 std::vector<const llvm::Type*> Params(1, IdTy); 994 return cast<llvm::Function>(CGM.CreateRuntimeFunction( 995 llvm::FunctionType::get(llvm::Type::VoidTy, Params, true), 996 "objc_enumerationMutation")); 997} 998 999void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1000 const Stmt &S) { 1001 CGF.ErrorUnsupported(&S, "@try/@synchronized statement"); 1002} 1003 1004void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1005 const ObjCAtThrowStmt &S) { 1006 CGF.ErrorUnsupported(&S, "@throw statement"); 1007} 1008 1009llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1010 llvm::Value *AddrWeakObj) 1011{ 1012 return 0; 1013} 1014 1015void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1016 llvm::Value *src, llvm::Value *dst) 1017{ 1018 return; 1019} 1020 1021void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1022 llvm::Value *src, llvm::Value *dst) 1023{ 1024 return; 1025} 1026 1027void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1028 llvm::Value *src, llvm::Value *dst) 1029{ 1030 return; 1031} 1032 1033void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1034 llvm::Value *src, llvm::Value *dst) 1035{ 1036 return; 1037} 1038 1039LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1040 QualType ObjectTy, 1041 llvm::Value *BaseValue, 1042 const ObjCIvarDecl *Ivar, 1043 const FieldDecl *Field, 1044 unsigned CVRQualifiers) { 1045 if (Ivar->isBitField()) 1046 return CGF.EmitLValueForBitfield(BaseValue, const_cast<FieldDecl *>(Field), 1047 CVRQualifiers); 1048 // TODO: Add a special case for isa (index 0) 1049 unsigned Index = CGM.getTypes().getLLVMFieldNo(Field); 1050 llvm::Value *V = CGF.Builder.CreateStructGEP(BaseValue, Index, "tmp"); 1051 LValue LV = LValue::MakeAddr(V, 1052 Ivar->getType().getCVRQualifiers()|CVRQualifiers); 1053 LValue::SetObjCIvar(LV, true); 1054 return LV; 1055} 1056 1057llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1058 ObjCInterfaceDecl *Interface, 1059 const ObjCIvarDecl *Ivar) { 1060 const llvm::Type *InterfaceLTy = 1061 CGM.getTypes().ConvertType( 1062 CGM.getContext().getObjCInterfaceType(Interface)); 1063 const llvm::StructLayout *Layout = 1064 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceLTy)); 1065 FieldDecl *Field = Interface->lookupFieldDeclForIvar(CGM.getContext(), Ivar); 1066 uint64_t Offset = 1067 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); 1068 1069 return llvm::ConstantInt::get( 1070 CGM.getTypes().ConvertType(CGM.getContext().LongTy), 1071 Offset); 1072} 1073 1074CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ 1075 return new CGObjCGNU(CGM); 1076} 1077