CGObjC.cpp revision e66f4e3e3ae9d7d11b0c302211066fad69228aba
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" 19e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar#include "clang/Basic/Diagnostic.h" 203d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson#include "llvm/ADT/STLExtras.h" 214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 225508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace clang; 235508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace CodeGen; 245508518a2702b00be3b15a26d772bde968972f54Anders Carlsson 258fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emits an instance of NSConstantString representing the object. 26bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) { 27bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar std::string String(E->getString()->getStrData(), E->getString()->getByteLength()); 28bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(String); 29ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar // FIXME: This bitcast should just be made an invariant on the Runtime. 30bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); 318fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner} 328fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 338fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emit a selector. 348fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { 358fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Untyped selector. 368fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Note that this implementation allows for non-constant strings to be passed 378fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // as arguments to @selector(). Currently, the only thing preventing this 388fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // behaviour is the type checking in the front end. 39208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); 408fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner} 418fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 42ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { 43ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar // FIXME: This should pass the Decl not the name. 44ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol()); 45ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar} 468fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 478fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 488f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { 498fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Only the lookup mechanism and first two arguments of the method 508fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // implementation vary between runtimes. We can get the receiver and 518fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // arguments in generic code. 528fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 53208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar CGObjCRuntime &Runtime = CGM.getObjCRuntime(); 548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner const Expr *ReceiverExpr = E->getReceiver(); 558fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner bool isSuperMessage = false; 56f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar bool isClassMessage = false; 578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner // Find the receiver 588fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner llvm::Value *Receiver; 598fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner if (!ReceiverExpr) { 60ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar const ObjCInterfaceDecl *OID = E->getClassInfo().first; 61ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar 62ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar // Very special case, super send in class method. The receiver is 63ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar // self (the class object) and the send uses super semantics. 64ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar if (!OID) { 65ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar assert(!strcmp(E->getClassName()->getName(), "super") && 66ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar "Unexpected missing class interface in message send."); 67ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar isSuperMessage = true; 68f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver = LoadObjCSelf(); 69f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar } else { 70f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver = Runtime.GetClass(Builder, OID); 718fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 72f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar 73f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar isClassMessage = true; 74d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner } else if (const PredefinedExpr *PDE = 75d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner dyn_cast<PredefinedExpr>(E->getReceiver())) { 76d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper); 778fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner isSuperMessage = true; 788fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner Receiver = LoadObjCSelf(); 798fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } else { 802bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar Receiver = EmitScalarExpr(E->getReceiver()); 818fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 828fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner 8319cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar CallArgList Args; 8419cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end(); 8519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar i != e; ++i) 8619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar EmitCallArg(*i, Args); 8719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar 888fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner if (isSuperMessage) { 899384c768e93f270118a30ce96546083a666da284Chris Lattner // super is only valid in an Objective-C method 909384c768e93f270118a30ce96546083a666da284Chris Lattner const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 917f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar return Runtime.GenerateMessageSendSuper(*this, E->getType(), 927f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar E->getSelector(), 93f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar OMD->getClassInterface(), 94f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar Receiver, 9519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar isClassMessage, 9619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar Args); 978fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner } 987f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(), 997f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Receiver, isClassMessage, Args); 1005508518a2702b00be3b15a26d772bde968972f54Anders Carlsson} 1015508518a2702b00be3b15a26d772bde968972f54Anders Carlsson 102af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// StartObjCMethod - Begin emission of an ObjCMethod. This generates 103af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// the LLVM function and sets the other context used by 104af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// CodeGenFunction. 105af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 106af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: This should really be merged with GenerateCode. 107af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { 1087ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar CurFn = CGM.getObjCRuntime().GenerateMethod(OMD); 1094111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); 1104111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1114111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Create a marker to make it easy to insert allocas into the entryblock 1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // later. Don't create this with the builder, because we don't want it 1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // folded. 1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty); 1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt", 1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EntryBB); 1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1184111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner FnRetTy = OMD->getResultType(); 1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner CurFuncDecl = OMD; 1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner Builder.SetInsertPoint(EntryBB); 1224111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1234111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Emit allocs for param decls. Give the LLVM Argument nodes names. 1244111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Function::arg_iterator AI = CurFn->arg_begin(); 1254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 126b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar // Name the struct return argument. 1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner if (hasAggregateLLVMType(OMD->getResultType())) { 128b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar AI->setName("agg.result"); 1294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 131b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Add implicit parameters to the decl map. 133b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getSelfDecl(), AI); 134b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar ++AI; 135b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 136b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getCmdDecl(), AI); 1374111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1384111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1394111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) { 1404111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner assert(AI != CurFn->arg_end() && "Argument mismatch!"); 1414111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EmitParmDecl(*OMD->getParamDecl(i), AI); 1424111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 143b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar assert(AI == CurFn->arg_end() && "Argument mismatch"); 144af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 145af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 146af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method. An Objective-C method is a C function with 147af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// its pointer, name, and types registered in the class struture. 148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { 149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(OMD->getBody()); 151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody()); 153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar if (S) { 154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(S->getRBracLoc()); 155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } else { 156af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 157af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 158af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 159af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 160af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: I wasn't sure about the synthesis approach. If we end up 161af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// generating an AST for the whole body we can just fall back to 162af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// having a GenerateFunction which takes the body Stmt. 163af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 164af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter 165af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 166af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 167af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) { 168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); 170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate getter (empty method)"); 171af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 172af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 173af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ReturnStmt Return(Loc, &IvarRef); 184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Return); 185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 186af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 187af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 188af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 189af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter 190af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 191af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 192af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) { 193af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 194af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getSetterMethodDecl(); 195af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate setter (empty method)"); 196af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 197af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 198af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 199af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 200af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 201af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar switch (PD->getSetterKind()) { 202af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Assign: break; 203af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Copy: 204af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'"); 205af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 206af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Retain: 207af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'"); 208af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 209af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 210b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 211af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 212af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 213af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 215af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 216af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ParmVarDecl *ArgDecl = OMD->getParamDecl(0); 217af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); 218af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 219af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 220af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, 221af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar Ivar->getType(), Loc); 222af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Assign); 223af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 224af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 2254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 227b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf(void) { 228b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 229b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); 2304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2314111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 2329c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel DunbarRValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) { 2339c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // Determine getter selector. 2349c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar Selector S; 235e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (E->getKind() == ObjCPropertyRefExpr::MethodRef) { 236e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getGetterMethod()->getSelector(); 2379c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } else { 238e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getProperty()->getGetterName(); 2399c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } 2409c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 2417f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar return CGM.getObjCRuntime(). 2427f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar GenerateMessageSend(*this, E->getType(), S, 2437f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar EmitScalarExpr(E->getBase()), 2447f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar false, CallArgList()); 2459c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar} 2469c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 24785c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbarvoid CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, 24885c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar RValue Src) { 2497f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector S; 250e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (E->getKind() == ObjCPropertyRefExpr::MethodRef) { 251e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar ObjCMethodDecl *Setter = E->getSetterMethod(); 252e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar 253e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (Setter) { 254e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = Setter->getSelector(); 255e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar } else { 256e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar // FIXME: This should be diagnosed by sema. 257e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar SourceRange Range = E->getSourceRange(); 258e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()), 259e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar diag::err_typecheck_assign_const, 0, 0, 260e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar &Range, 1); 261e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar return; 262e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar } 2637f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar } else { 264e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getProperty()->getSetterName(); 2657f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar } 2667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar 2677f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar CallArgList Args; 2687f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar EmitCallArg(Src, E->getType(), Args); 2697f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, 2707f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar EmitScalarExpr(E->getBase()), 2717f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar false, Args); 27285c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar} 27385c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar 2743d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlssonvoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) 2753d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson{ 276f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *DeclAddress; 277f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType ElementTy; 278f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 279f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) { 280f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitStmt(SD); 281f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 282f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ElementTy = cast<ValueDecl>(SD->getDecl())->getType(); 283f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson DeclAddress = LocalDeclMap[SD->getDecl()]; 284f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } else { 285f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ElementTy = cast<Expr>(S.getElement())->getType(); 286f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson DeclAddress = 0; 287f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } 288f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 289f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Fast enumeration state. 290f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType StateTy = getContext().getObjCFastEnumerationStateType(); 291f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy), 292f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson "state.ptr"); 293f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3); 2942abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitMemSetToZero(StatePtr, StateTy); 295f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 296f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Number of elements in the items array. 2972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson static const unsigned NumItems = 16; 298f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 299f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Get selector 300f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::SmallVector<IdentifierInfo*, 3> II; 301f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState")); 302f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("objects")); 303f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("count")); 304f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(), 305f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson &II[0]); 306f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 307f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType ItemsTy = 308f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getConstantArrayType(getContext().getObjCIdType(), 309f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::APInt(32, NumItems), 310f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ArrayType::Normal, 0); 311f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr"); 312f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 313f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Collection = EmitScalarExpr(S.getCollection()); 314f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 315f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CallArgList Args; 316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Args.push_back(std::make_pair(StatePtr, 317f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getPointerType(StateTy))); 318f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 319f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Args.push_back(std::make_pair(ItemsPtr, 320f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getPointerType(ItemsTy))); 321f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 322f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy); 323f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems); 324f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Args.push_back(std::make_pair(Count, getContext().UnsignedLongTy)); 325f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 326f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson RValue CountRV = 327f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CGM.getObjCRuntime().GenerateMessageSend(*this, 328f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().UnsignedLongTy, 329f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson FastEnumSel, 330f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Collection, false, Args); 331f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 332f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr"); 333f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 334f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 335f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements"); 3362abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *SetStartMutations = 3372abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock::Create("setstartmutations"); 338f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 339f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Limit = Builder.CreateLoad(LimitPtr); 340f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy); 341f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 342f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 3432abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCondBr(IsZero, NoElements, SetStartMutations); 344f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3452abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(SetStartMutations); 3462abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3472abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StartMutationsPtr = 3482abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson CreateTempAlloca(UnsignedLongLTy); 3492abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3502abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutationsPtrPtr = 3512abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); 3522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, 3532abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutationsptr"); 3542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3552abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr, 3562abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutations"); 3572abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateStore(StateMutations, StartMutationsPtr); 3592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3602abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart"); 361f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopStart); 362f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 363f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr"); 364f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(Zero, CounterPtr); 365f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3662abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody"); 367f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopBody); 368f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3692abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); 3702abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations"); 3712abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3722abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr, 3732abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutations"); 3742abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations, 3752abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StartMutations, 3762abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "tobool"); 3772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3782abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3792abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated"); 3802abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated"); 3812abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3822abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated); 3832abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3842abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(WasMutated); 3852abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *V = 3862abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateBitCast(Collection, 3872abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson ConvertType(getContext().getObjCIdType()), 3882abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "tmp"); 3892abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCall(CGM.getObjCRuntime().EnumerationMutationFunction(), 3902abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson V); 3912abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(WasNotMutated); 3932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 394f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *StateItemsPtr = 395f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); 396f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 397f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter"); 398f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 399f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr, 400f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson "stateitems"); 401f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 402f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CurrentItemPtr = 403f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr"); 404f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 405f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem"); 406f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 407f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Cast the item to the right type. 408f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CurrentItem = Builder.CreateBitCast(CurrentItem, 409f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ConvertType(ElementTy), "tmp"); 410f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 411f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (!DeclAddress) { 412f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LValue LV = EmitLValue(cast<Expr>(S.getElement())); 413f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 414f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Set the value to null. 415f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CurrentItem, LV.getAddress()); 416f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } else 417f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CurrentItem, DeclAddress); 418f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 419f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Increment the counter. 420f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Counter = Builder.CreateAdd(Counter, 421f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::ConstantInt::get(UnsignedLongLTy, 1)); 422f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(Counter, CounterPtr); 423f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 424f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *LoopEnd = llvm::BasicBlock::Create("loopend"); 425f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *AfterBody = llvm::BasicBlock::Create("afterbody"); 426f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 427f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); 428f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 429f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitStmt(S.getBody()); 430f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 431f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson BreakContinueStack.pop_back(); 432f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 433f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(AfterBody); 434f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 435f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore"); 436f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 437f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless"); 4382abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCondBr(IsLess, LoopStart, FetchMore); 439f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 440f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Fetch more elements. 441f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(FetchMore); 442f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 443f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CountRV = 444f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CGM.getObjCRuntime().GenerateMessageSend(*this, 445f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().UnsignedLongTy, 446f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson FastEnumSel, 447f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Collection, false, Args); 448f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 449f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Limit = Builder.CreateLoad(LimitPtr); 450f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 451f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 452f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateCondBr(IsZero, NoElements, LoopStart); 453f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 454f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // No more elements. 455f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(NoElements); 456f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 457f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (!DeclAddress) { 458f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // If the element was not a declaration, set it to be null. 459f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 460f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LValue LV = EmitLValue(cast<Expr>(S.getElement())); 461f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 462f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Set the value to null. 463f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)), 464f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LV.getAddress()); 465f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } 466f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 467f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopEnd); 4683d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson} 4693d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson 4702979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {} 471