CGObjC.cpp revision 9384c768e93f270118a30ce96546083a666da284
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"
17f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
185508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "llvm/Constant.h"
194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner#include "llvm/Function.h"
204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
215508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace clang;
225508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace CodeGen;
235508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
248fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emits an instance of NSConstantString representing the object.
257f02f721d48772e4eee4fccd8af4f800be1bbc1eChris Lattnerllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
268fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  return CGM.getObjCRuntime()->GenerateConstantString(
278fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      E->getString()->getStrData(), E->getString()->getByteLength());
288fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
298fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
308fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emit a selector.
318fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
328fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Untyped selector.
338fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Note that this implementation allows for non-constant strings to be passed
348fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // as arguments to @selector().  Currently, the only thing preventing this
358fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // behaviour is the type checking in the front end.
3642ba3e7ba1d4f3fad4871af77ab68ae3514b8c7eChris Lattner  return CGM.getObjCRuntime()->GetSelector(Builder, E->getSelector());
378fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
388fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
398fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
408fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
418fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
428fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Only the lookup mechanism and first two arguments of the method
438fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // implementation vary between runtimes.  We can get the receiver and
448fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // arguments in generic code.
458fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
468fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  CGObjCRuntime *Runtime = CGM.getObjCRuntime();
478fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  const Expr *ReceiverExpr = E->getReceiver();
488fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  bool isSuperMessage = false;
498fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Find the receiver
508fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  llvm::Value *Receiver;
518fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (!ReceiverExpr) {
528fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    const char * classname = E->getClassName()->getName();
538fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    if (!strcmp(classname, "super")) {
548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      classname = E->getMethodDecl()->getClassInterface()->getName();
558fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    }
568fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    llvm::Value *ClassName = CGM.GetAddrOfConstantString(classname);
578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    ClassName = Builder.CreateStructGEP(ClassName, 0);
588fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    Receiver = Runtime->LookupClass(Builder, ClassName);
59630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner  } else if (isa<PreDefinedExpr>(E->getReceiver())) {
60630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner    assert(cast<PreDefinedExpr>(E->getReceiver())->getIdentType() ==
61630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner           PreDefinedExpr::ObjCSuper);
628fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    isSuperMessage = true;
638fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    Receiver = LoadObjCSelf();
648fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  } else {
658fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner   Receiver = EmitScalarExpr(E->getReceiver());
668fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
678fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
688fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Process the arguments
698fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  unsigned ArgC = E->getNumArgs();
708fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  llvm::SmallVector<llvm::Value*, 16> Args;
718fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  for (unsigned i = 0; i != ArgC; ++i) {
728fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    const Expr *ArgExpr = E->getArg(i);
738fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    QualType ArgTy = ArgExpr->getType();
748fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    if (!hasAggregateLLVMType(ArgTy)) {
758fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      // Scalar argument is passed by-value.
768fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      Args.push_back(EmitScalarExpr(ArgExpr));
778fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    } else if (ArgTy->isAnyComplexType()) {
788fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      // Make a temporary alloca to pass the argument.
798fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
808fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
818fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      Args.push_back(DestMem);
828fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    } else {
838fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
848fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      EmitAggExpr(ArgExpr, DestMem, false);
858fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner      Args.push_back(DestMem);
868fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    }
878fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
888fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
898fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (isSuperMessage) {
909384c768e93f270118a30ce96546083a666da284Chris Lattner    // super is only valid in an Objective-C method
919384c768e93f270118a30ce96546083a666da284Chris Lattner    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
92630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner    const char *SuperClass =
93630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner      OMD->getClassInterface()->getSuperClass()->getName();
948fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    return Runtime->GenerateMessageSendSuper(Builder, ConvertType(E->getType()),
95630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner                                             Receiver, SuperClass,
968e67b63530b4f39a48bc12d97376f373a6901279Chris Lattner                                             Receiver, E->getSelector(),
97630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner                                             &Args[0], Args.size());
988fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
998fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  return Runtime->GenerateMessageSend(Builder, ConvertType(E->getType()),
1008fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner                                      LoadObjCSelf(),
1019384c768e93f270118a30ce96546083a666da284Chris Lattner                                      Receiver, E->getSelector(),
1028fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner                                      &Args[0], Args.size());
1035508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
1045508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
1054111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner/// Generate an Objective-C method.  An Objective-C method is a C function with
1064111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner/// its pointer, name, and types registered in the class struture.
1074111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattnervoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
1084111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1094111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
1104111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  for (unsigned i=0 ; i<OMD->param_size() ; i++) {
1114111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    const llvm::Type *Ty = ConvertType(OMD->getParamDecl(i)->getType());
1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    if (Ty->isFirstClassType())
1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner      ParamTypes.push_back(Ty);
1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    else
1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner      ParamTypes.push_back(llvm::PointerType::getUnqual(Ty));
1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  std::string CategoryName = "";
1184111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  if (ObjCCategoryImplDecl *OCD =
1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner      dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    CategoryName = OCD->getName();
1214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
122630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner  const llvm::Type *ReturnTy =
123630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner    CGM.getTypes().ConvertReturnType(OMD->getResultType());
1244111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  CurFn = CGM.getObjCRuntime()->MethodPreamble(
125630404b16e886238ed68a1abbfe2e548f43aa664Chris Lattner                                          OMD->getClassInterface()->getName(),
1264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              CategoryName,
1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              OMD->getSelector().getName(),
1284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              ReturnTy,
1294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              llvm::PointerType::getUnqual(
1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              llvm::Type::Int32Ty),
1314111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              ParamTypes.begin(),
1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              OMD->param_size(),
1334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              !OMD->isInstance(),
1344111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                              OMD->isVariadic());
1354111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
1364111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1374111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Create a marker to make it easy to insert allocas into the entryblock
1384111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // later.  Don't create this with the builder, because we don't want it
1394111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // folded.
1404111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
1414111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
1424111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                         EntryBB);
1434111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1444111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  FnRetTy = OMD->getResultType();
1454111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  CurFuncDecl = OMD;
1464111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1474111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  Builder.SetInsertPoint(EntryBB);
1484111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1494111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
1504111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Function::arg_iterator AI = CurFn->arg_begin();
1514111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1524111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  if (hasAggregateLLVMType(OMD->getResultType())) {
1534111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    ++AI;
1544111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
1554111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Add implicit parameters to the decl map.
1564111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // TODO: Add something to AST to let the runtime specify the names and types
1574111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // of these.
1584111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1594111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *&SelfEntry = LocalDeclMap[OMD->getSelfDecl()];
1604111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  const llvm::Type *IPTy = AI->getType();
1614111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
1624111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner      ".addr", AllocaInsertPt);
1634111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Store the initial value into the alloca.
1644111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  Builder.CreateStore(AI, DeclPtr);
1654111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  SelfEntry = DeclPtr;
1664111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ++AI;
1674111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *&CmdEntry = LocalDeclMap[OMD->getCmdDecl()];
1684111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  IPTy = AI->getType();
1694111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
1704111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner      ".addr", AllocaInsertPt);
1714111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Store the initial value into the alloca.
1724111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  Builder.CreateStore(AI, DeclPtr);
1734111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  CmdEntry = DeclPtr;
1744111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1754111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
1764111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    assert(AI != CurFn->arg_end() && "Argument mismatch!");
1774111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    EmitParmDecl(*OMD->getParamDecl(i), AI);
1784111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
1794111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1804111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  GenerateFunction(OMD->getBody());
1814111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
1824111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1834111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattnerllvm::Value *CodeGenFunction::LoadObjCSelf(void)
1844111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner{
1854111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
1864111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    ValueDecl *Decl = OMD->getSelfDecl();
1874111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    llvm::Value *SelfPtr = LocalDeclMap[&(*(Decl))];
1884111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    return Builder.CreateLoad(SelfPtr, "self");
1894111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
1904111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  return NULL;
1914111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
1924111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1932979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
194