blob: b4eaff838594b053e99a74bf8a444f061d69352c [file] [log] [blame]
Daniel Dunbar0dbe2272008-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 Dunbarb7688072008-09-10 00:41:16 +000017#include "CodeGenModule.h"
Daniel Dunbar0dbe2272008-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 Dunbar0dbe2272008-09-08 21:33:45 +000027// FIXME: Use iterator and sidestep silly type array creation.
28
Daniel Dunbar45c25ba2008-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 Dunbar0dbe2272008-09-08 21:33:45 +000044CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
Daniel Dunbar0dbe2272008-09-08 21:33:45 +000045{
46 const FunctionType *FTy = FD->getType()->getAsFunctionType();
47 const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
Daniel Dunbar45c25ba2008-09-10 04:01:49 +000048
Daniel Dunbar0dbe2272008-09-08 21:33:45 +000049 ArgTypes.push_back(FTy->getResultType());
Daniel Dunbar45c25ba2008-09-10 04:01:49 +000050 if (FTP) {
51 IsVariadic = FTP->isVariadic();
Daniel Dunbar0dbe2272008-09-08 21:33:45 +000052 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
53 ArgTypes.push_back(FTP->getArgType(i));
Daniel Dunbar45c25ba2008-09-10 04:01:49 +000054 } else {
55 IsVariadic = true;
56 }
Daniel Dunbar0dbe2272008-09-08 21:33:45 +000057}
58
59CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
60 const ASTContext &Context)
Daniel Dunbar45c25ba2008-09-10 04:01:49 +000061 : IsVariadic(MD->isVariadic())
Daniel Dunbar0dbe2272008-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 Dunbar5323a4b2008-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 Dunbar0dbe2272008-09-08 21:33:45 +000077}
78
79/***/
80
Daniel Dunbar5323a4b2008-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 Dunbar0dbe2272008-09-08 21:33:45 +000084 ArgTypes.push_back(i->second);
85}
86
Daniel Dunbar5323a4b2008-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 Dunbar0dbe2272008-09-08 21:33:45 +000093}
Daniel Dunbar17b708d2008-09-09 23:27:19 +000094
95/***/
96
Daniel Dunbar2c8e0f32008-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;
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000107 const llvm::Type *TypeData;
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000108
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000109 ABIArgInfo(Kind K, const llvm::Type *TD) : TheKind(K),
110 TypeData(TD) {}
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000111public:
112 static ABIArgInfo getDefault() {
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000113 return ABIArgInfo(Default, 0);
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000114 }
115 static ABIArgInfo getStructRet() {
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000116 return ABIArgInfo(StructRet, 0);
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000117 }
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000118 static ABIArgInfo getCoerce(const llvm::Type *T) {
119 assert(T->isSingleValueType() && "Can only coerce to simple types");
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000120 return ABIArgInfo(Coerce, T);
121 }
122
123 Kind getKind() const { return TheKind; }
124 bool isDefault() const { return TheKind == Default; }
125 bool isStructRet() const { return TheKind == StructRet; }
126 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000127
128 // Coerce accessors
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000129 const llvm::Type *getCoerceToType() const {
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000130 assert(TheKind == Coerce && "Invalid kind!");
131 return TypeData;
132 }
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000133};
134
135/***/
136
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000137static ABIArgInfo classifyReturnType(QualType RetTy,
138 ASTContext &Context) {
Daniel Dunbar6660c8a2008-09-11 00:04:36 +0000139 assert(!RetTy->isArrayType() &&
140 "Array types cannot be passed directly.");
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000141 if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000142 uint64_t Size = Context.getTypeSize(RetTy);
143 if (Size == 8) {
144 return ABIArgInfo::getCoerce(llvm::Type::Int8Ty);
145 } else if (Size == 16) {
146 return ABIArgInfo::getCoerce(llvm::Type::Int16Ty);
147 } else if (Size == 32) {
148 return ABIArgInfo::getCoerce(llvm::Type::Int32Ty);
149 } else if (Size == 64) {
150 return ABIArgInfo::getCoerce(llvm::Type::Int64Ty);
151 } else {
152 return ABIArgInfo::getStructRet();
153 }
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000154 } else {
155 return ABIArgInfo::getDefault();
156 }
157}
158
159/***/
160
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000161const llvm::FunctionType *
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000162CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) {
163 return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic);
164}
165
166const llvm::FunctionType *
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000167CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000168 return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic());
169}
170
171const llvm::FunctionType *
172CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
173 bool IsVariadic) {
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000174 std::vector<const llvm::Type*> ArgTys;
175
176 const llvm::Type *ResultType = 0;
177
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000178 QualType RetTy = *begin;
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000179 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000180 switch (RetAI.getKind()) {
181 case ABIArgInfo::Default:
182 if (RetTy->isVoidType()) {
183 ResultType = llvm::Type::VoidTy;
184 } else {
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000185 ResultType = ConvertType(RetTy);
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000186 }
187 break;
188
189 case ABIArgInfo::StructRet: {
190 ResultType = llvm::Type::VoidTy;
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000191 const llvm::Type *STy = ConvertType(RetTy);
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000192 ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
193 break;
194 }
195
196 case ABIArgInfo::Coerce:
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000197 ResultType = RetAI.getCoerceToType();
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000198 break;
199 }
200
201 for (++begin; begin != end; ++begin) {
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000202 const llvm::Type *Ty = ConvertType(*begin);
Daniel Dunbar6660c8a2008-09-11 00:04:36 +0000203 assert(!(*begin)->isArrayType() &&
204 "Array types cannot be passed directly.");
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000205 if (Ty->isSingleValueType())
206 ArgTys.push_back(Ty);
207 else
208 // byval arguments are always on the stack, which is addr space #0.
209 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
210 }
211
Daniel Dunbar62d5c1b2008-09-10 07:00:50 +0000212 return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000213}
214
Daniel Dunbarb7688072008-09-10 00:41:16 +0000215bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000216 return classifyReturnType(RetTy, getContext()).isStructRet();
Daniel Dunbar3913f182008-09-09 23:48:28 +0000217}
218
Daniel Dunbarb7688072008-09-10 00:41:16 +0000219void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000220 ArgTypeIterator begin,
221 ArgTypeIterator end,
222 ParamAttrListType &PAL) {
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000223 unsigned FuncAttrs = 0;
224
225 if (TargetDecl) {
226 if (TargetDecl->getAttr<NoThrowAttr>())
227 FuncAttrs |= llvm::ParamAttr::NoUnwind;
228 if (TargetDecl->getAttr<NoReturnAttr>())
229 FuncAttrs |= llvm::ParamAttr::NoReturn;
230 }
231
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000232 QualType RetTy = *begin;
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000233 unsigned Index = 1;
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000234 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar45c25ba2008-09-10 04:01:49 +0000235 switch (RetAI.getKind()) {
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000236 case ABIArgInfo::Default:
237 if (RetTy->isPromotableIntegerType()) {
238 if (RetTy->isSignedIntegerType()) {
239 FuncAttrs |= llvm::ParamAttr::SExt;
240 } else if (RetTy->isUnsignedIntegerType()) {
241 FuncAttrs |= llvm::ParamAttr::ZExt;
242 }
243 }
244 break;
245
246 case ABIArgInfo::StructRet:
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000247 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index,
248 llvm::ParamAttr::StructRet));
249 ++Index;
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000250 break;
251
252 case ABIArgInfo::Coerce:
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000253 break;
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000254 }
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000255
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000256 if (FuncAttrs)
257 PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
258 for (++begin; begin != end; ++begin, ++Index) {
259 QualType ParamType = *begin;
260 unsigned ParamAttrs = 0;
Daniel Dunbar6660c8a2008-09-11 00:04:36 +0000261 assert(!ParamType->isArrayType() &&
262 "Array types cannot be passed directly.");
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000263 if (ParamType->isRecordType())
264 ParamAttrs |= llvm::ParamAttr::ByVal;
265 if (ParamType->isPromotableIntegerType()) {
266 if (ParamType->isSignedIntegerType()) {
267 ParamAttrs |= llvm::ParamAttr::SExt;
268 } else if (ParamType->isUnsignedIntegerType()) {
269 ParamAttrs |= llvm::ParamAttr::ZExt;
270 }
271 }
272 if (ParamAttrs)
273 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, ParamAttrs));
274 }
275}
276
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000277void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
278 QualType RetTy,
279 const FunctionArgList &Args) {
280 // Emit allocs for param decls. Give the LLVM Argument nodes names.
281 llvm::Function::arg_iterator AI = Fn->arg_begin();
282
283 // Name the struct return argument.
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000284 if (CGM.ReturnTypeUsesSret(RetTy)) {
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000285 AI->setName("agg.result");
286 ++AI;
287 }
288
289 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
290 i != e; ++i, ++AI) {
291 const VarDecl *Arg = i->first;
292 QualType T = i->second;
293 assert(AI != Fn->arg_end() && "Argument mismatch!");
294 llvm::Value* V = AI;
295 if (!getContext().typesAreCompatible(T, Arg->getType())) {
296 // This must be a promotion, for something like
297 // "void a(x) short x; {..."
298 V = EmitScalarConversion(V, T, Arg->getType());
299 }
300 EmitParmDecl(*Arg, V);
301 }
302 assert(AI == Fn->arg_end() && "Argument mismatch!");
303}
304
305void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
306 llvm::Value *ReturnValue) {
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000307 llvm::Value *RV = 0;
308
309 // Functions with no result always return void.
310 if (ReturnValue) {
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000311 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000312
313 switch (RetAI.getKind()) {
314 case ABIArgInfo::StructRet:
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000315 EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000316 break;
317
318 case ABIArgInfo::Default:
319 RV = Builder.CreateLoad(ReturnValue);
320 break;
321
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000322 case ABIArgInfo::Coerce: {
323 const llvm::Type *CoerceToPTy =
324 llvm::PointerType::getUnqual(RetAI.getCoerceToType());
325 RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy));
326 }
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000327 }
328 }
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000329
330 if (RV) {
331 Builder.CreateRet(RV);
332 } else {
333 Builder.CreateRetVoid();
334 }
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000335}
336
337RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000338 QualType RetTy,
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000339 const CallArgList &CallArgs) {
340 // FIXME: Factor out code to load from args into locals into target.
341 llvm::SmallVector<llvm::Value*, 16> Args;
342 llvm::Value *TempArg0 = 0;
343
344 // Handle struct-return functions by passing a pointer to the
345 // location that we would like to return into.
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000346 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000347 switch (RetAI.getKind()) {
348 case ABIArgInfo::StructRet:
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000349 // Create a temporary alloca to hold the result of the call. :(
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000350 TempArg0 = CreateTempAlloca(ConvertType(RetTy));
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000351 Args.push_back(TempArg0);
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000352 break;
353
354 case ABIArgInfo::Default:
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000355 case ABIArgInfo::Coerce:
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000356 break;
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000357 }
358
359 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
360 I != E; ++I) {
361 RValue RV = I->first;
362 if (RV.isScalar()) {
363 Args.push_back(RV.getScalarVal());
364 } else if (RV.isComplex()) {
365 // Make a temporary alloca to pass the argument.
366 Args.push_back(CreateTempAlloca(ConvertType(I->second)));
367 StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
368 } else {
369 Args.push_back(RV.getAggregateAddr());
370 }
371 }
372
373 llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000374 CGCallInfo CallInfo(RetTy, CallArgs);
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000375
Daniel Dunbar5323a4b2008-09-10 00:32:18 +0000376 // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000377 CodeGen::ParamAttrListType ParamAttrList;
Daniel Dunbarb7688072008-09-10 00:41:16 +0000378 CGM.ConstructParamAttrList(0,
379 CallInfo.argtypes_begin(), CallInfo.argtypes_end(),
380 ParamAttrList);
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000381 CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
382 ParamAttrList.size()));
383
384 if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
385 CI->setCallingConv(F->getCallingConv());
386 if (CI->getType() != llvm::Type::VoidTy)
387 CI->setName("call");
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000388
389 switch (RetAI.getKind()) {
390 case ABIArgInfo::StructRet:
391 if (RetTy->isAnyComplexType())
392 return RValue::getComplex(LoadComplexFromAddr(TempArg0, false));
393 else
394 // Struct return.
395 return RValue::getAggregate(TempArg0);
396
397 case ABIArgInfo::Default:
398 return RValue::get(RetTy->isVoidType() ? 0 : CI);
399
Daniel Dunbar639ffe42008-09-10 07:04:09 +0000400 case ABIArgInfo::Coerce: {
401 const llvm::Type *CoerceToPTy =
402 llvm::PointerType::getUnqual(RetAI.getCoerceToType());
403 llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp");
404 Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
405 return RValue::getAggregate(V);
406 }
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000407 }
Daniel Dunbar2c8e0f32008-09-10 02:41:04 +0000408
409 assert(0 && "Unhandled ABIArgInfo::Kind");
410 return RValue::get(0);
Daniel Dunbar17b708d2008-09-09 23:27:19 +0000411}