blob: 473abd5d8be816202371b40501619d89e7716d24 [file] [log] [blame]
Daniel Dunbara8f02052008-09-08 21:33:45 +00001//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
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// These classes wrap the information about a call or function
11// definition used to handle ABI compliancy.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CGCall.h"
16#include "CodeGenFunction.h"
Daniel Dunbar3ef2e852008-09-10 00:41:16 +000017#include "CodeGenModule.h"
Daniel Dunbara8f02052008-09-08 21:33:45 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclObjC.h"
21#include "llvm/ParameterAttributes.h"
22using namespace clang;
23using namespace CodeGen;
24
25/***/
26
Daniel Dunbara8f02052008-09-08 21:33:45 +000027// FIXME: Use iterator and sidestep silly type array creation.
28
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000029CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP)
30 : IsVariadic(true)
31{
32 ArgTypes.push_back(FTNP->getResultType());
33}
34
35CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP)
36 : IsVariadic(FTP->isVariadic())
37{
38 ArgTypes.push_back(FTP->getResultType());
39 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
40 ArgTypes.push_back(FTP->getArgType(i));
41}
42
43// FIXME: Is there really any reason to have this still?
Daniel Dunbara8f02052008-09-08 21:33:45 +000044CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
Daniel Dunbara8f02052008-09-08 21:33:45 +000045{
46 const FunctionType *FTy = FD->getType()->getAsFunctionType();
47 const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000048
Daniel Dunbara8f02052008-09-08 21:33:45 +000049 ArgTypes.push_back(FTy->getResultType());
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000050 if (FTP) {
51 IsVariadic = FTP->isVariadic();
Daniel Dunbara8f02052008-09-08 21:33:45 +000052 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
53 ArgTypes.push_back(FTP->getArgType(i));
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000054 } else {
55 IsVariadic = true;
56 }
Daniel Dunbara8f02052008-09-08 21:33:45 +000057}
58
59CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
60 const ASTContext &Context)
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000061 : IsVariadic(MD->isVariadic())
Daniel Dunbara8f02052008-09-08 21:33:45 +000062{
63 ArgTypes.push_back(MD->getResultType());
64 ArgTypes.push_back(MD->getSelfDecl()->getType());
65 ArgTypes.push_back(Context.getObjCSelType());
66 for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
67 e = MD->param_end(); i != e; ++i)
68 ArgTypes.push_back((*i)->getType());
69}
70
Daniel Dunbarbccb0682008-09-10 00:32:18 +000071ArgTypeIterator CGFunctionInfo::argtypes_begin() const {
72 return ArgTypes.begin();
73}
74
75ArgTypeIterator CGFunctionInfo::argtypes_end() const {
76 return ArgTypes.end();
Daniel Dunbara8f02052008-09-08 21:33:45 +000077}
78
79/***/
80
Daniel Dunbarbccb0682008-09-10 00:32:18 +000081CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) {
82 ArgTypes.push_back(_ResultType);
83 for (CallArgList::const_iterator i = _Args.begin(), e = _Args.end(); i!=e; ++i)
Daniel Dunbara8f02052008-09-08 21:33:45 +000084 ArgTypes.push_back(i->second);
85}
86
Daniel Dunbarbccb0682008-09-10 00:32:18 +000087ArgTypeIterator CGCallInfo::argtypes_begin() const {
88 return ArgTypes.begin();
89}
90
91ArgTypeIterator CGCallInfo::argtypes_end() const {
92 return ArgTypes.end();
Daniel Dunbara8f02052008-09-08 21:33:45 +000093}
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +000094
95/***/
96
Daniel Dunbare126ab12008-09-10 02:41:04 +000097class ABIArgInfo {
98public:
99 enum Kind {
100 Default,
101 StructRet, // Only valid for struct return types
102 Coerce // Only valid for return types
103 };
104
105private:
106 Kind TheKind;
107 QualType TypeData;
108
109 ABIArgInfo(Kind K, QualType TD) : TheKind(K),
110 TypeData(TD) {}
111public:
112 static ABIArgInfo getDefault() {
113 return ABIArgInfo(Default, QualType());
114 }
115 static ABIArgInfo getStructRet() {
116 return ABIArgInfo(StructRet, QualType());
117 }
118 static ABIArgInfo getCoerce(QualType T) {
119 return ABIArgInfo(Coerce, T);
120 }
121
122 Kind getKind() const { return TheKind; }
123 bool isDefault() const { return TheKind == Default; }
124 bool isStructRet() const { return TheKind == StructRet; }
125 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000126
127 // Coerce accessors
128 QualType getCoerceToType() const {
129 assert(TheKind == Coerce && "Invalid kind!");
130 return TypeData;
131 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000132};
133
134/***/
135
136static ABIArgInfo classifyReturnType(QualType RetTy) {
137 if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
138 return ABIArgInfo::getStructRet();
139 } else {
140 return ABIArgInfo::getDefault();
141 }
142}
143
144/***/
145
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000146const llvm::FunctionType *
Daniel Dunbara9976a22008-09-10 07:00:50 +0000147CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) {
148 return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic);
149}
150
151const llvm::FunctionType *
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000152CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
Daniel Dunbara9976a22008-09-10 07:00:50 +0000153 return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic());
154}
155
156const llvm::FunctionType *
157CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
158 bool IsVariadic) {
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000159 std::vector<const llvm::Type*> ArgTys;
160
161 const llvm::Type *ResultType = 0;
162
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000163 QualType RetTy = *begin;
164 ABIArgInfo RetAI = classifyReturnType(RetTy);
165 switch (RetAI.getKind()) {
166 case ABIArgInfo::Default:
167 if (RetTy->isVoidType()) {
168 ResultType = llvm::Type::VoidTy;
169 } else {
Daniel Dunbara9976a22008-09-10 07:00:50 +0000170 ResultType = ConvertType(RetTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000171 }
172 break;
173
174 case ABIArgInfo::StructRet: {
175 ResultType = llvm::Type::VoidTy;
Daniel Dunbara9976a22008-09-10 07:00:50 +0000176 const llvm::Type *STy = ConvertType(RetTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000177 ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
178 break;
179 }
180
181 case ABIArgInfo::Coerce:
182 ResultType = llvm::Type::VoidTy;
Daniel Dunbara9976a22008-09-10 07:00:50 +0000183 ArgTys.push_back(ConvertType(RetAI.getCoerceToType()));
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000184 break;
185 }
186
187 for (++begin; begin != end; ++begin) {
Daniel Dunbara9976a22008-09-10 07:00:50 +0000188 const llvm::Type *Ty = ConvertType(*begin);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000189 if (Ty->isSingleValueType())
190 ArgTys.push_back(Ty);
191 else
192 // byval arguments are always on the stack, which is addr space #0.
193 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
194 }
195
Daniel Dunbara9976a22008-09-10 07:00:50 +0000196 return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000197}
198
Daniel Dunbara9976a22008-09-10 07:00:50 +0000199// FIXME: This can die now?
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000200bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
Daniel Dunbare126ab12008-09-10 02:41:04 +0000201 return classifyReturnType(RetTy).isStructRet();
Daniel Dunbar49f5a0d2008-09-09 23:48:28 +0000202}
203
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000204void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
Daniel Dunbare126ab12008-09-10 02:41:04 +0000205 ArgTypeIterator begin,
206 ArgTypeIterator end,
207 ParamAttrListType &PAL) {
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000208 unsigned FuncAttrs = 0;
209
210 if (TargetDecl) {
211 if (TargetDecl->getAttr<NoThrowAttr>())
212 FuncAttrs |= llvm::ParamAttr::NoUnwind;
213 if (TargetDecl->getAttr<NoReturnAttr>())
214 FuncAttrs |= llvm::ParamAttr::NoReturn;
215 }
216
Daniel Dunbare126ab12008-09-10 02:41:04 +0000217 QualType RetTy = *begin;
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000218 unsigned Index = 1;
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000219 ABIArgInfo RetAI = classifyReturnType(RetTy);
220 switch (RetAI.getKind()) {
Daniel Dunbare126ab12008-09-10 02:41:04 +0000221 case ABIArgInfo::Default:
222 if (RetTy->isPromotableIntegerType()) {
223 if (RetTy->isSignedIntegerType()) {
224 FuncAttrs |= llvm::ParamAttr::SExt;
225 } else if (RetTy->isUnsignedIntegerType()) {
226 FuncAttrs |= llvm::ParamAttr::ZExt;
227 }
228 }
229 break;
230
231 case ABIArgInfo::StructRet:
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000232 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index,
233 llvm::ParamAttr::StructRet));
234 ++Index;
Daniel Dunbare126ab12008-09-10 02:41:04 +0000235 break;
236
237 case ABIArgInfo::Coerce:
238 assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
239 break;
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000240 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000241
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000242 if (FuncAttrs)
243 PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
244 for (++begin; begin != end; ++begin, ++Index) {
245 QualType ParamType = *begin;
246 unsigned ParamAttrs = 0;
247 if (ParamType->isRecordType())
248 ParamAttrs |= llvm::ParamAttr::ByVal;
249 if (ParamType->isPromotableIntegerType()) {
250 if (ParamType->isSignedIntegerType()) {
251 ParamAttrs |= llvm::ParamAttr::SExt;
252 } else if (ParamType->isUnsignedIntegerType()) {
253 ParamAttrs |= llvm::ParamAttr::ZExt;
254 }
255 }
256 if (ParamAttrs)
257 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, ParamAttrs));
258 }
259}
260
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000261void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
262 QualType RetTy,
263 const FunctionArgList &Args) {
264 // Emit allocs for param decls. Give the LLVM Argument nodes names.
265 llvm::Function::arg_iterator AI = Fn->arg_begin();
266
267 // Name the struct return argument.
Daniel Dunbare126ab12008-09-10 02:41:04 +0000268 if (CGM.ReturnTypeUsesSret(RetTy)) {
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000269 AI->setName("agg.result");
270 ++AI;
271 }
272
273 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
274 i != e; ++i, ++AI) {
275 const VarDecl *Arg = i->first;
276 QualType T = i->second;
277 assert(AI != Fn->arg_end() && "Argument mismatch!");
278 llvm::Value* V = AI;
279 if (!getContext().typesAreCompatible(T, Arg->getType())) {
280 // This must be a promotion, for something like
281 // "void a(x) short x; {..."
282 V = EmitScalarConversion(V, T, Arg->getType());
283 }
284 EmitParmDecl(*Arg, V);
285 }
286 assert(AI == Fn->arg_end() && "Argument mismatch!");
287}
288
289void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
290 llvm::Value *ReturnValue) {
Daniel Dunbare126ab12008-09-10 02:41:04 +0000291 llvm::Value *RV = 0;
292
293 // Functions with no result always return void.
294 if (ReturnValue) {
295 ABIArgInfo RetAI = classifyReturnType(RetTy);
296
297 switch (RetAI.getKind()) {
298 case ABIArgInfo::StructRet:
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000299 EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
Daniel Dunbare126ab12008-09-10 02:41:04 +0000300 break;
301
302 case ABIArgInfo::Default:
303 RV = Builder.CreateLoad(ReturnValue);
304 break;
305
306 case ABIArgInfo::Coerce:
307 assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
308 break;
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000309 }
310 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000311
312 if (RV) {
313 Builder.CreateRet(RV);
314 } else {
315 Builder.CreateRetVoid();
316 }
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000317}
318
319RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
Daniel Dunbare126ab12008-09-10 02:41:04 +0000320 QualType RetTy,
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000321 const CallArgList &CallArgs) {
322 // FIXME: Factor out code to load from args into locals into target.
323 llvm::SmallVector<llvm::Value*, 16> Args;
324 llvm::Value *TempArg0 = 0;
325
326 // Handle struct-return functions by passing a pointer to the
327 // location that we would like to return into.
Daniel Dunbare126ab12008-09-10 02:41:04 +0000328 ABIArgInfo RetAI = classifyReturnType(RetTy);
329 switch (RetAI.getKind()) {
330 case ABIArgInfo::StructRet:
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000331 // Create a temporary alloca to hold the result of the call. :(
Daniel Dunbare126ab12008-09-10 02:41:04 +0000332 TempArg0 = CreateTempAlloca(ConvertType(RetTy));
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000333 Args.push_back(TempArg0);
Daniel Dunbare126ab12008-09-10 02:41:04 +0000334 break;
335
336 case ABIArgInfo::Default:
337 break;
338
339 case ABIArgInfo::Coerce:
340 assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
341 break;
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000342 }
343
344 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
345 I != E; ++I) {
346 RValue RV = I->first;
347 if (RV.isScalar()) {
348 Args.push_back(RV.getScalarVal());
349 } else if (RV.isComplex()) {
350 // Make a temporary alloca to pass the argument.
351 Args.push_back(CreateTempAlloca(ConvertType(I->second)));
352 StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
353 } else {
354 Args.push_back(RV.getAggregateAddr());
355 }
356 }
357
358 llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
Daniel Dunbare126ab12008-09-10 02:41:04 +0000359 CGCallInfo CallInfo(RetTy, CallArgs);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000360
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000361 // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000362 CodeGen::ParamAttrListType ParamAttrList;
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000363 CGM.ConstructParamAttrList(0,
364 CallInfo.argtypes_begin(), CallInfo.argtypes_end(),
365 ParamAttrList);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000366 CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
367 ParamAttrList.size()));
368
369 if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
370 CI->setCallingConv(F->getCallingConv());
371 if (CI->getType() != llvm::Type::VoidTy)
372 CI->setName("call");
Daniel Dunbare126ab12008-09-10 02:41:04 +0000373
374 switch (RetAI.getKind()) {
375 case ABIArgInfo::StructRet:
376 if (RetTy->isAnyComplexType())
377 return RValue::getComplex(LoadComplexFromAddr(TempArg0, false));
378 else
379 // Struct return.
380 return RValue::getAggregate(TempArg0);
381
382 case ABIArgInfo::Default:
383 return RValue::get(RetTy->isVoidType() ? 0 : CI);
384
385 case ABIArgInfo::Coerce:
386 assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
387 return RValue::get(0);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000388 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000389
390 assert(0 && "Unhandled ABIArgInfo::Kind");
391 return RValue::get(0);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000392}