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