CGObjC.cpp revision 46f45b9bec4a265ad8400a538e5ec3a5683617f1
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) 8646f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar Args.push_back(std::make_pair(EmitAnyExprToTemp(*i), (*i)->getType())); 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); 109f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar 110f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar CGM.SetMethodAttributes(OMD, CurFn); 111f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar 1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); 1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Create a marker to make it easy to insert allocas into the entryblock 1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // later. Don't create this with the builder, because we don't want it 1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // folded. 1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty); 1184111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt", 1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EntryBB); 1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner FnRetTy = OMD->getResultType(); 1224111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner CurFuncDecl = OMD; 1234111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1244111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner Builder.SetInsertPoint(EntryBB); 1254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Emit allocs for param decls. Give the LLVM Argument nodes names. 1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner llvm::Function::arg_iterator AI = CurFn->arg_begin(); 1284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 129b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar // Name the struct return argument. 1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner if (hasAggregateLLVMType(OMD->getResultType())) { 131b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar AI->setName("agg.result"); 1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 134b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 1354111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner // Add implicit parameters to the decl map. 136b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getSelfDecl(), AI); 137b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar ++AI; 138b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 139b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar EmitParmDecl(*OMD->getCmdDecl(), AI); 1404111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner ++AI; 1414111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 1424111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) { 1434111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner assert(AI != CurFn->arg_end() && "Argument mismatch!"); 1444111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner EmitParmDecl(*OMD->getParamDecl(i), AI); 1454111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner } 146b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar assert(AI == CurFn->arg_end() && "Argument mismatch"); 147af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method. An Objective-C method is a C function with 150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// its pointer, name, and types registered in the class struture. 151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { 152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(OMD->getBody()); 154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody()); 156af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar if (S) { 157af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(S->getRBracLoc()); 158af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } else { 159af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 160af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 161af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 162af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 163af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: I wasn't sure about the synthesis approach. If we end up 164af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// generating an AST for the whole body we can just fall back to 165af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// having a GenerateFunction which takes the body Stmt. 166af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 167af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter 168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) { 171af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 172af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); 173af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate getter (empty method)"); 174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 186af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ReturnStmt Return(Loc, &IvarRef); 187af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Return); 188af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 189af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 190af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar} 191af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 192af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter 193af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl 194af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl. 195af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) { 196af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 197af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCMethodDecl *OMD = PD->getSetterMethodDecl(); 198af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar assert(OMD && "Invalid call to generate setter (empty method)"); 199af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: This is rather murky, we create this here since they will 200af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // not have been created by Sema for us. 201af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar OMD->createImplicitParams(getContext()); 202af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar StartObjCMethod(OMD); 203af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 204af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar switch (PD->getSetterKind()) { 205af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Assign: break; 206af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Copy: 207af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'"); 208af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 209af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar case ObjCPropertyDecl::Retain: 210af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'"); 211af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar break; 212af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar } 213b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar 214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar // FIXME: What about nonatomic? 215af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar SourceLocation Loc = PD->getLocation(); 216af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ValueDecl *Self = OMD->getSelfDecl(); 217af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 218af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Base(Self, Self->getType(), Loc); 219af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ParmVarDecl *ArgDecl = OMD->getParamDecl(0); 220af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); 221af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, 222af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar true, true); 223af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, 224af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar Ivar->getType(), Loc); 225af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar EmitStmt(&Assign); 226af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar 227af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar FinishFunction(); 2284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 230b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf(void) { 231b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 232b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); 2334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner} 2344111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner 2359c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel DunbarRValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) { 2369c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar // Determine getter selector. 2379c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar Selector S; 238e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (E->getKind() == ObjCPropertyRefExpr::MethodRef) { 239e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getGetterMethod()->getSelector(); 2409c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } else { 241e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getProperty()->getGetterName(); 2429c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar } 2439c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 2447f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar return CGM.getObjCRuntime(). 2457f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar GenerateMessageSend(*this, E->getType(), S, 2467f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar EmitScalarExpr(E->getBase()), 2477f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar false, CallArgList()); 2489c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar} 2499c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar 25085c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbarvoid CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, 25185c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar RValue Src) { 2527f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar Selector S; 253e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (E->getKind() == ObjCPropertyRefExpr::MethodRef) { 254e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar ObjCMethodDecl *Setter = E->getSetterMethod(); 255e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar 256e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar if (Setter) { 257e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = Setter->getSelector(); 258e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar } else { 259e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar // FIXME: This should be diagnosed by sema. 260e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar SourceRange Range = E->getSourceRange(); 261e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()), 262e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar diag::err_typecheck_assign_const, 0, 0, 263e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar &Range, 1); 264e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar return; 265e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar } 2667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar } else { 267e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar S = E->getProperty()->getSetterName(); 2687f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar } 2697f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar 2707f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar CallArgList Args; 27146f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar Args.push_back(std::make_pair(Src, E->getType())); 2727f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, 2737f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar EmitScalarExpr(E->getBase()), 2747f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar false, Args); 27585c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar} 27685c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar 2773d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlssonvoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) 2783d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson{ 279f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *DeclAddress; 280f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType ElementTy; 281f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 282f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) { 283f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitStmt(SD); 284f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 285f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ElementTy = cast<ValueDecl>(SD->getDecl())->getType(); 286f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson DeclAddress = LocalDeclMap[SD->getDecl()]; 287f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } else { 288f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ElementTy = cast<Expr>(S.getElement())->getType(); 289f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson DeclAddress = 0; 290f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } 291f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 292f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Fast enumeration state. 293f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType StateTy = getContext().getObjCFastEnumerationStateType(); 294f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy), 295f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson "state.ptr"); 296f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3); 2972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitMemSetToZero(StatePtr, StateTy); 298f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 299f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Number of elements in the items array. 3002abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson static const unsigned NumItems = 16; 301f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 302f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Get selector 303f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::SmallVector<IdentifierInfo*, 3> II; 304f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState")); 305f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("objects")); 306f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson II.push_back(&CGM.getContext().Idents.get("count")); 307f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(), 308f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson &II[0]); 309f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 310f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson QualType ItemsTy = 311f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getConstantArrayType(getContext().getObjCIdType(), 312f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::APInt(32, NumItems), 313f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ArrayType::Normal, 0); 314f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr"); 315f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Collection = EmitScalarExpr(S.getCollection()); 317f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 318f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CallArgList Args; 31946f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar Args.push_back(std::make_pair(RValue::get(StatePtr), 320f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getPointerType(StateTy))); 321f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 32246f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar Args.push_back(std::make_pair(RValue::get(ItemsPtr), 323f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().getPointerType(ItemsTy))); 324f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 325f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy); 326f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems); 32746f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar Args.push_back(std::make_pair(RValue::get(Count), 32846f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar getContext().UnsignedLongTy)); 329f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 330f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson RValue CountRV = 331f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CGM.getObjCRuntime().GenerateMessageSend(*this, 332f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().UnsignedLongTy, 333f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson FastEnumSel, 334f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Collection, false, Args); 335f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 336f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr"); 337f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 338f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 339f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements"); 3402abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *SetStartMutations = 3412abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock::Create("setstartmutations"); 342f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 343f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Limit = Builder.CreateLoad(LimitPtr); 344f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy); 345f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 346f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 3472abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCondBr(IsZero, NoElements, SetStartMutations); 348f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3492abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(SetStartMutations); 3502abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3512abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StartMutationsPtr = 3522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson CreateTempAlloca(UnsignedLongLTy); 3532abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutationsPtrPtr = 3552abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); 3562abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, 3572abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutationsptr"); 3582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr, 3602abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutations"); 3612abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3622abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateStore(StateMutations, StartMutationsPtr); 3632abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3642abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart"); 365f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopStart); 366f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 367f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr"); 368f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(Zero, CounterPtr); 369f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3702abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody"); 371f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopBody); 372f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 3732abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); 3742abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations"); 3752abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3762abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr, 3772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "mutations"); 3782abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations, 3792abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson StartMutations, 3802abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "tobool"); 3812abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3822abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3832abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated"); 3842abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated"); 3852abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3862abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated); 3872abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3882abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(WasMutated); 3892abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson llvm::Value *V = 3902abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateBitCast(Collection, 3912abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson ConvertType(getContext().getObjCIdType()), 3922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson "tmp"); 3932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson Builder.CreateCall(CGM.getObjCRuntime().EnumerationMutationFunction(), 3942abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson V); 3952abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 3962abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson EmitBlock(WasNotMutated); 3972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson 398f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *StateItemsPtr = 399f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); 400f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 401f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter"); 402f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 403f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr, 404f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson "stateitems"); 405f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 406f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CurrentItemPtr = 407f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr"); 408f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 409f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem"); 410f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 411f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Cast the item to the right type. 412f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CurrentItem = Builder.CreateBitCast(CurrentItem, 413f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson ConvertType(ElementTy), "tmp"); 414f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 415f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (!DeclAddress) { 416f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LValue LV = EmitLValue(cast<Expr>(S.getElement())); 417f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 418f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Set the value to null. 419f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CurrentItem, LV.getAddress()); 420f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } else 421f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CurrentItem, DeclAddress); 422f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 423f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Increment the counter. 424f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Counter = Builder.CreateAdd(Counter, 425f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::ConstantInt::get(UnsignedLongLTy, 1)); 426f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(Counter, CounterPtr); 427f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 428f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *LoopEnd = llvm::BasicBlock::Create("loopend"); 429f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *AfterBody = llvm::BasicBlock::Create("afterbody"); 430f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 431f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); 432f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 433f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitStmt(S.getBody()); 434f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 435f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson BreakContinueStack.pop_back(); 436f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 437f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(AfterBody); 438f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 439f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore"); 440f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 441f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless"); 442fe2b2c08984f861f82339138302689480c658ecdDaniel Dunbar Builder.CreateCondBr(IsLess, LoopBody, FetchMore); 443f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 444f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Fetch more elements. 445f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(FetchMore); 446f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 447f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CountRV = 448f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson CGM.getObjCRuntime().GenerateMessageSend(*this, 449f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson getContext().UnsignedLongTy, 450f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson FastEnumSel, 451f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Collection, false, Args); 452f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 453f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Limit = Builder.CreateLoad(LimitPtr); 454f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 455f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 456f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateCondBr(IsZero, NoElements, LoopStart); 457f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 458f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // No more elements. 459f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(NoElements); 460f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 461f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson if (!DeclAddress) { 462f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // If the element was not a declaration, set it to be null. 463f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 464f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LValue LV = EmitLValue(cast<Expr>(S.getElement())); 465f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 466f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson // Set the value to null. 467f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)), 468f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson LV.getAddress()); 469f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson } 470f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson 471f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson EmitBlock(LoopEnd); 4723d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson} 4733d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson 4742979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {} 475