CGObjC.cpp revision 85c59edda02df48fae8dc85049743319bc6e7e89
15508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 25508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// 35508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// The LLVM Compiler Infrastructure 45508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// 85508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===----------------------------------------------------------------------===// 95508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// 105508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// This contains code to emit Objective-C code as LLVM code. 115508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// 125508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===----------------------------------------------------------------------===// 135508518a2702b00be3b15a26d772bde968972f54Anders Carlsson 142979ec73b4f974d85f2ce84167712177a44c6f09Ted Kremenek#include "CGObjCRuntime.h" 155508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenFunction.h" 165508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenModule.h" 1785c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar#include "clang/AST/ASTContext.h" 18c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/DeclObjC.h" 194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 205508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace clang; 215508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace CodeGen; 225508518a2702b00be3b15a26d772bde968972f54Anders Carlsson 238fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emits an instance of NSConstantString representing the object. 24bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) { 25bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar std::string String(E->getString()->getStrData(), E->getString()->getByteLength()); 26bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(String); 27ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar // FIXME: This bitcast should just be made an invariant on the Runtime. 28bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); 298fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner} 308fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 318fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emit a selector. 328fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { 338fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Untyped selector. 348fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Note that this implementation allows for non-constant strings to be passed 358fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // as arguments to @selector(). Currently, the only thing preventing this 368fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // behaviour is the type checking in the front end. 37208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); 388fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner} 398fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 40ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { 41ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar // FIXME: This should pass the Decl not the name. 42ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol()); 43ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar} 448fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 458fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 468f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { 478fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Only the lookup mechanism and first two arguments of the method 488fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // implementation vary between runtimes. We can get the receiver and 498fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // arguments in generic code. 508fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 51208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar CGObjCRuntime &Runtime = CGM.getObjCRuntime(); 528fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner const Expr *ReceiverExpr = E->getReceiver(); 538fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner bool isSuperMessage = false; 54f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar bool isClassMessage = false; 558fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Find the receiver 568fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner llvm::Value *Receiver; 578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner if (!ReceiverExpr) { 58ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar const ObjCInterfaceDecl *OID = E->getClassInfo().first; 59ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar 60ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar // Very special case, super send in class method. The receiver is 61ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar // self (the class object) and the send uses super semantics. 62ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar if (!OID) { 63ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar assert(!strcmp(E->getClassName()->getName(), "super") && 64ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar "Unexpected missing class interface in message send."); 65ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar isSuperMessage = true; 66f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver = LoadObjCSelf(); 67f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 68f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver = Runtime.GetClass(Builder, OID); 698fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 70f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 71f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar isClassMessage = true; 72d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner } else if (const PredefinedExpr *PDE = 73d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner dyn_cast<PredefinedExpr>(E->getReceiver())) { 74d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper); 758fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner isSuperMessage = true; 768fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner Receiver = LoadObjCSelf(); 778fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } else { 782bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar Receiver = EmitScalarExpr(E->getReceiver()); 798fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 808fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 818fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner if (isSuperMessage) { 829384c768e93f270118a30ce96546083a666da284Chris Lattner // super is only valid in an Objective-C method 839384c768e93f270118a30ce96546083a666da284Chris Lattner const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 848f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar return Runtime.GenerateMessageSendSuper(*this, E, 85f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar OMD->getClassInterface(), 86f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver, 87f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar isClassMessage); 888fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 89f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar return Runtime.GenerateMessageSend(*this, E, Receiver, isClassMessage); 905508518a2702b00be3b15a26d772bde968972f54Anders Carlsson} 915508518a2702b00be3b15a26d772bde968972f54Anders Carlsson 92af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// StartObjCMethod - Begin emission of an ObjCMethod. This generates 93af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// the LLVM function and sets the other context used by 94af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// CodeGenFunction. 95af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 96af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: This should really be merged with GenerateCode. 97af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { 987ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar CurFn = CGM.getObjCRuntime().GenerateMethod(OMD); 994111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); 1004111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1014111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Create a marker to make it easy to insert allocas into the entryblock 1024111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // later. Don't create this with the builder, because we don't want it 1034111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // folded. 1044111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty); 1054111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt", 1064111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EntryBB); 1074111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1084111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner FnRetTy = OMD->getResultType(); 1094111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner CurFuncDecl = OMD; 1104111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1114111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner Builder.SetInsertPoint(EntryBB); 1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Emit allocs for param decls. Give the LLVM Argument nodes names. 1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Function::arg_iterator AI = CurFn->arg_begin(); 1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 116b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar // Name the struct return argument. 1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner if (hasAggregateLLVMType(OMD->getResultType())) { 118b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar AI->setName("agg.result"); 1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 121b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 1224111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Add implicit parameters to the decl map. 123b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getSelfDecl(), AI); 124b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar ++AI; 125b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 126b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getCmdDecl(), AI); 1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) { 1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner assert(AI != CurFn->arg_end() && "Argument mismatch!"); 1314111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EmitParmDecl(*OMD->getParamDecl(i), AI); 1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 133b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar assert(AI == CurFn->arg_end() && "Argument mismatch"); 134af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 135af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 136af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method. An Objective-C method is a C function with 137af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// its pointer, name, and types registered in the class struture. 138af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { 139af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 140af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(OMD->getBody()); 141af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 142af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody()); 143af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar if (S) { 144af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(S->getRBracLoc()); 145af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } else { 146af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 147af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: I wasn't sure about the synthesis approach. If we end up 151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// generating an AST for the whole body we can just fall back to 152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// having a GenerateFunction which takes the body Stmt. 153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter 155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 156af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 157af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) { 158af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 159af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); 160af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate getter (empty method)"); 161af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 162af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 163af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 164af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 165af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 166af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 167af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 171af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 172af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 173af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ReturnStmt Return(Loc, &IvarRef); 174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Return); 175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter 180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) { 183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getSetterMethodDecl(); 185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate setter (empty method)"); 186af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 187af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 188af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 189af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 190af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 191af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar switch (PD->getSetterKind()) { 192af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Assign: break; 193af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Copy: 194af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'"); 195af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 196af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Retain: 197af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'"); 198af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 199af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 200b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 201af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 202af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 203af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 204af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 205af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 206af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ParmVarDecl *ArgDecl = OMD->getParamDecl(0); 207af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); 208af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 209af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 210af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, 211af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar Ivar->getType(), Loc); 212af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Assign); 213af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 2154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 217b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf(void) { 218b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 219b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); 2204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 2229c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel DunbarRValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) { 2239c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // Determine getter selector. 2249c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar Selector S; 2259c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(E->getDecl())) { 2269c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar S = MD->getSelector(); 2279c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } else { 2289c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar S = cast<ObjCPropertyDecl>(E->getDecl())->getGetterName(); 2299c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } 2309c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 2319c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // FIXME: Improve location information. 2329c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar SourceLocation Loc = E->getLocation(); 2339c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // PropertyRefExprs are always instance messages. 2349c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // FIXME: Is there any reason to try and pass the method here? 2359c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar ObjCMessageExpr GetExpr(const_cast<Expr*>(E->getBase()), 2369c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar S, E->getType(), 0, Loc, Loc, 2379c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 0, 0); 2389c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 2399c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar return EmitObjCMessageExpr(&GetExpr); 2409c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar} 2419c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 24285c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbarvoid CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, 24385c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar RValue Src) { 24485c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar ErrorUnsupported(E, "Objective-C property setter call"); 24585c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar} 24685c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar 2472979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {} 248