blob: 91e7e63ca320abf4338f8ca19b98aa8ca64745da [file] [log] [blame]
Anders Carlsson55085182007-08-21 17:43:55 +00001//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Anders Carlsson55085182007-08-21 17:43:55 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Objective-C code as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
Ted Kremenek2979ec72008-04-09 15:51:31 +000014#include "CGObjCRuntime.h"
Anders Carlsson55085182007-08-21 17:43:55 +000015#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
Steve Narofff494b572008-05-29 21:12:08 +000017#include "clang/AST/ExprObjC.h"
Daniel Dunbarc4a1dea2008-08-11 05:35:13 +000018#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
Anders Carlsson55085182007-08-21 17:43:55 +000020#include "llvm/Constant.h"
Chris Lattner41110242008-06-17 18:05:57 +000021#include "llvm/Function.h"
22
Anders Carlsson55085182007-08-21 17:43:55 +000023using namespace clang;
24using namespace CodeGen;
25
Chris Lattner8fdf3282008-06-24 17:04:18 +000026/// Emits an instance of NSConstantString representing the object.
Chris Lattner7f02f722007-08-24 05:35:26 +000027llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
Chris Lattner8fdf3282008-06-24 17:04:18 +000028 return CGM.getObjCRuntime()->GenerateConstantString(
29 E->getString()->getStrData(), E->getString()->getByteLength());
30}
31
32/// Emit a selector.
33llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
34 // Untyped selector.
35 // Note that this implementation allows for non-constant strings to be passed
36 // as arguments to @selector(). Currently, the only thing preventing this
37 // behaviour is the type checking in the front end.
Chris Lattner42ba3e72008-06-26 04:38:58 +000038 return CGM.getObjCRuntime()->GetSelector(Builder, E->getSelector());
Chris Lattner8fdf3282008-06-24 17:04:18 +000039}
40
41
42
43llvm::Value *CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
44 // Only the lookup mechanism and first two arguments of the method
45 // implementation vary between runtimes. We can get the receiver and
46 // arguments in generic code.
47
48 CGObjCRuntime *Runtime = CGM.getObjCRuntime();
49 const Expr *ReceiverExpr = E->getReceiver();
50 bool isSuperMessage = false;
51 // Find the receiver
52 llvm::Value *Receiver;
53 if (!ReceiverExpr) {
54 const char * classname = E->getClassName()->getName();
55 if (!strcmp(classname, "super")) {
56 classname = E->getMethodDecl()->getClassInterface()->getName();
57 }
58 llvm::Value *ClassName = CGM.GetAddrOfConstantString(classname);
59 ClassName = Builder.CreateStructGEP(ClassName, 0);
60 Receiver = Runtime->LookupClass(Builder, ClassName);
Chris Lattnerd9f69102008-08-10 01:53:14 +000061 } else if (const PredefinedExpr *PDE =
62 dyn_cast<PredefinedExpr>(E->getReceiver())) {
63 assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper);
Chris Lattner8fdf3282008-06-24 17:04:18 +000064 isSuperMessage = true;
65 Receiver = LoadObjCSelf();
66 } else {
67 Receiver = EmitScalarExpr(E->getReceiver());
68 }
69
70 // Process the arguments
71 unsigned ArgC = E->getNumArgs();
72 llvm::SmallVector<llvm::Value*, 16> Args;
73 for (unsigned i = 0; i != ArgC; ++i) {
74 const Expr *ArgExpr = E->getArg(i);
75 QualType ArgTy = ArgExpr->getType();
76 if (!hasAggregateLLVMType(ArgTy)) {
77 // Scalar argument is passed by-value.
78 Args.push_back(EmitScalarExpr(ArgExpr));
79 } else if (ArgTy->isAnyComplexType()) {
80 // Make a temporary alloca to pass the argument.
81 llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
82 EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
83 Args.push_back(DestMem);
84 } else {
85 llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
86 EmitAggExpr(ArgExpr, DestMem, false);
87 Args.push_back(DestMem);
88 }
89 }
90
Chris Lattner8fdf3282008-06-24 17:04:18 +000091 if (isSuperMessage) {
Chris Lattner9384c762008-06-26 04:42:20 +000092 // super is only valid in an Objective-C method
93 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
Chris Lattner630404b2008-06-26 04:10:42 +000094 const char *SuperClass =
95 OMD->getClassInterface()->getSuperClass()->getName();
Chris Lattner8fdf3282008-06-24 17:04:18 +000096 return Runtime->GenerateMessageSendSuper(Builder, ConvertType(E->getType()),
Chris Lattner630404b2008-06-26 04:10:42 +000097 Receiver, SuperClass,
Chris Lattner8e67b632008-06-26 04:37:12 +000098 Receiver, E->getSelector(),
Chris Lattner630404b2008-06-26 04:10:42 +000099 &Args[0], Args.size());
Chris Lattner8fdf3282008-06-24 17:04:18 +0000100 }
101 return Runtime->GenerateMessageSend(Builder, ConvertType(E->getType()),
102 LoadObjCSelf(),
Chris Lattner9384c762008-06-26 04:42:20 +0000103 Receiver, E->getSelector(),
Chris Lattner8fdf3282008-06-24 17:04:18 +0000104 &Args[0], Args.size());
Anders Carlsson55085182007-08-21 17:43:55 +0000105}
106
Chris Lattner41110242008-06-17 18:05:57 +0000107/// Generate an Objective-C method. An Objective-C method is a C function with
108/// its pointer, name, and types registered in the class struture.
109void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
110
111 llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
112 for (unsigned i=0 ; i<OMD->param_size() ; i++) {
113 const llvm::Type *Ty = ConvertType(OMD->getParamDecl(i)->getType());
114 if (Ty->isFirstClassType())
115 ParamTypes.push_back(Ty);
116 else
117 ParamTypes.push_back(llvm::PointerType::getUnqual(Ty));
118 }
119 std::string CategoryName = "";
120 if (ObjCCategoryImplDecl *OCD =
121 dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
122 CategoryName = OCD->getName();
123 }
Chris Lattner630404b2008-06-26 04:10:42 +0000124 const llvm::Type *ReturnTy =
125 CGM.getTypes().ConvertReturnType(OMD->getResultType());
Chris Lattner41110242008-06-17 18:05:57 +0000126 CurFn = CGM.getObjCRuntime()->MethodPreamble(
Chris Lattner630404b2008-06-26 04:10:42 +0000127 OMD->getClassInterface()->getName(),
Chris Lattner41110242008-06-17 18:05:57 +0000128 CategoryName,
129 OMD->getSelector().getName(),
130 ReturnTy,
131 llvm::PointerType::getUnqual(
132 llvm::Type::Int32Ty),
133 ParamTypes.begin(),
134 OMD->param_size(),
135 !OMD->isInstance(),
136 OMD->isVariadic());
137 llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
138
139 // Create a marker to make it easy to insert allocas into the entryblock
140 // later. Don't create this with the builder, because we don't want it
141 // folded.
142 llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
143 AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
144 EntryBB);
145
146 FnRetTy = OMD->getResultType();
147 CurFuncDecl = OMD;
148
149 Builder.SetInsertPoint(EntryBB);
150
151 // Emit allocs for param decls. Give the LLVM Argument nodes names.
152 llvm::Function::arg_iterator AI = CurFn->arg_begin();
153
154 if (hasAggregateLLVMType(OMD->getResultType())) {
155 ++AI;
156 }
157 // Add implicit parameters to the decl map.
158 // TODO: Add something to AST to let the runtime specify the names and types
159 // of these.
160
161 llvm::Value *&SelfEntry = LocalDeclMap[OMD->getSelfDecl()];
162 const llvm::Type *IPTy = AI->getType();
163 llvm::Value *DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
164 ".addr", AllocaInsertPt);
165 // Store the initial value into the alloca.
166 Builder.CreateStore(AI, DeclPtr);
167 SelfEntry = DeclPtr;
168 ++AI;
169 llvm::Value *&CmdEntry = LocalDeclMap[OMD->getCmdDecl()];
170 IPTy = AI->getType();
171 DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
172 ".addr", AllocaInsertPt);
173 // Store the initial value into the alloca.
174 Builder.CreateStore(AI, DeclPtr);
175 CmdEntry = DeclPtr;
176
177 for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
178 assert(AI != CurFn->arg_end() && "Argument mismatch!");
179 EmitParmDecl(*OMD->getParamDecl(i), AI);
180 }
181
182 GenerateFunction(OMD->getBody());
183}
184
185llvm::Value *CodeGenFunction::LoadObjCSelf(void)
186{
187 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
188 ValueDecl *Decl = OMD->getSelfDecl();
189 llvm::Value *SelfPtr = LocalDeclMap[&(*(Decl))];
190 return Builder.CreateLoad(SelfPtr, "self");
191 }
192 return NULL;
193}
194
Ted Kremenek2979ec72008-04-09 15:51:31 +0000195CGObjCRuntime::~CGObjCRuntime() {}