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