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