CGObjC.cpp revision 4111024be81e7c0525e42dadcc126d27e5bf2425
1//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Objective-C code as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGObjCRuntime.h"
15#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
17#include "clang/AST/ExprObjC.h"
18#include "llvm/Constant.h"
19#include "llvm/Function.h"
20
21using namespace clang;
22using namespace CodeGen;
23
24llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
25  std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
26  return CGM.GetAddrOfConstantCFString(S);
27}
28
29/// Generate an Objective-C method.  An Objective-C method is a C function with
30/// its pointer, name, and types registered in the class struture.
31void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
32
33  llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
34  for (unsigned i=0 ; i<OMD->param_size() ; i++) {
35    const llvm::Type *Ty = ConvertType(OMD->getParamDecl(i)->getType());
36    if (Ty->isFirstClassType())
37      ParamTypes.push_back(Ty);
38    else
39      ParamTypes.push_back(llvm::PointerType::getUnqual(Ty));
40  }
41  std::string CategoryName = "";
42  if (ObjCCategoryImplDecl *OCD =
43      dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
44    CategoryName = OCD->getName();
45  }
46  const llvm::Type *ReturnTy = CGM.getTypes().ConvertReturnType(OMD->getResultType());
47  CurFn = CGM.getObjCRuntime()->MethodPreamble(
48                                              OMD->getClassInterface()->getName(),
49                                              CategoryName,
50                                              OMD->getSelector().getName(),
51                                              ReturnTy,
52                                              llvm::PointerType::getUnqual(
53                                              llvm::Type::Int32Ty),
54                                              ParamTypes.begin(),
55                                              OMD->param_size(),
56                                              !OMD->isInstance(),
57                                              OMD->isVariadic());
58  llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
59
60  // Create a marker to make it easy to insert allocas into the entryblock
61  // later.  Don't create this with the builder, because we don't want it
62  // folded.
63  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
64  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
65                                         EntryBB);
66
67  FnRetTy = OMD->getResultType();
68  CurFuncDecl = OMD;
69
70  Builder.SetInsertPoint(EntryBB);
71
72  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
73  llvm::Function::arg_iterator AI = CurFn->arg_begin();
74
75  if (hasAggregateLLVMType(OMD->getResultType())) {
76    ++AI;
77  }
78  // Add implicit parameters to the decl map.
79  // TODO: Add something to AST to let the runtime specify the names and types
80  // of these.
81
82  llvm::Value *&SelfEntry = LocalDeclMap[OMD->getSelfDecl()];
83  const llvm::Type *IPTy = AI->getType();
84  llvm::Value *DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
85      ".addr", AllocaInsertPt);
86  // Store the initial value into the alloca.
87  Builder.CreateStore(AI, DeclPtr);
88  SelfEntry = DeclPtr;
89  ++AI;
90  llvm::Value *&CmdEntry = LocalDeclMap[OMD->getCmdDecl()];
91  IPTy = AI->getType();
92  DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
93      ".addr", AllocaInsertPt);
94  // Store the initial value into the alloca.
95  Builder.CreateStore(AI, DeclPtr);
96  CmdEntry = DeclPtr;
97
98  for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
99    assert(AI != CurFn->arg_end() && "Argument mismatch!");
100    EmitParmDecl(*OMD->getParamDecl(i), AI);
101  }
102
103  GenerateFunction(OMD->getBody());
104}
105
106llvm::Value *CodeGenFunction::LoadObjCSelf(void)
107{
108  if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
109    ValueDecl *Decl = OMD->getSelfDecl();
110    llvm::Value *SelfPtr = LocalDeclMap[&(*(Decl))];
111    return Builder.CreateLoad(SelfPtr, "self");
112  }
113  return NULL;
114}
115
116CGObjCRuntime::~CGObjCRuntime() {}
117