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