blob: f69bad93d119fbea051dc0de63a53e0476ffc529 [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"
Daniel Dunbar04d35782008-09-17 00:51:38 +000021#include "llvm/ADT/StringExtras.h"
Daniel Dunbara8f02052008-09-08 21:33:45 +000022#include "llvm/ParameterAttributes.h"
23using namespace clang;
24using namespace CodeGen;
25
26/***/
27
Daniel Dunbara8f02052008-09-08 21:33:45 +000028// FIXME: Use iterator and sidestep silly type array creation.
29
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000030CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP)
31 : IsVariadic(true)
32{
33 ArgTypes.push_back(FTNP->getResultType());
34}
35
36CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP)
37 : IsVariadic(FTP->isVariadic())
38{
39 ArgTypes.push_back(FTP->getResultType());
40 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
41 ArgTypes.push_back(FTP->getArgType(i));
42}
43
44// FIXME: Is there really any reason to have this still?
Daniel Dunbara8f02052008-09-08 21:33:45 +000045CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
Daniel Dunbara8f02052008-09-08 21:33:45 +000046{
47 const FunctionType *FTy = FD->getType()->getAsFunctionType();
48 const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000049
Daniel Dunbara8f02052008-09-08 21:33:45 +000050 ArgTypes.push_back(FTy->getResultType());
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000051 if (FTP) {
52 IsVariadic = FTP->isVariadic();
Daniel Dunbara8f02052008-09-08 21:33:45 +000053 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
54 ArgTypes.push_back(FTP->getArgType(i));
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000055 } else {
56 IsVariadic = true;
57 }
Daniel Dunbara8f02052008-09-08 21:33:45 +000058}
59
60CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
61 const ASTContext &Context)
Daniel Dunbar3ad1f072008-09-10 04:01:49 +000062 : IsVariadic(MD->isVariadic())
Daniel Dunbara8f02052008-09-08 21:33:45 +000063{
64 ArgTypes.push_back(MD->getResultType());
65 ArgTypes.push_back(MD->getSelfDecl()->getType());
66 ArgTypes.push_back(Context.getObjCSelType());
67 for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
68 e = MD->param_end(); i != e; ++i)
69 ArgTypes.push_back((*i)->getType());
70}
71
Daniel Dunbarbccb0682008-09-10 00:32:18 +000072ArgTypeIterator CGFunctionInfo::argtypes_begin() const {
73 return ArgTypes.begin();
74}
75
76ArgTypeIterator CGFunctionInfo::argtypes_end() const {
77 return ArgTypes.end();
Daniel Dunbara8f02052008-09-08 21:33:45 +000078}
79
80/***/
81
Daniel Dunbarbccb0682008-09-10 00:32:18 +000082CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) {
83 ArgTypes.push_back(_ResultType);
84 for (CallArgList::const_iterator i = _Args.begin(), e = _Args.end(); i!=e; ++i)
Daniel Dunbara8f02052008-09-08 21:33:45 +000085 ArgTypes.push_back(i->second);
86}
87
Daniel Dunbarbccb0682008-09-10 00:32:18 +000088ArgTypeIterator CGCallInfo::argtypes_begin() const {
89 return ArgTypes.begin();
90}
91
92ArgTypeIterator CGCallInfo::argtypes_end() const {
93 return ArgTypes.end();
Daniel Dunbara8f02052008-09-08 21:33:45 +000094}
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +000095
96/***/
97
Daniel Dunbar22e30052008-09-11 01:48:57 +000098/// ABIArgInfo - Helper class to encapsulate information about how a
99/// specific C type should be passed to or returned from a function.
Daniel Dunbare126ab12008-09-10 02:41:04 +0000100class ABIArgInfo {
101public:
102 enum Kind {
103 Default,
Daniel Dunbar22e30052008-09-11 01:48:57 +0000104 StructRet, /// Only valid for aggregate return types.
105
Daniel Dunbar04d35782008-09-17 00:51:38 +0000106 Coerce, /// Only valid for aggregate return types, the argument
107 /// should be accessed by coercion to a provided type.
Daniel Dunbar22e30052008-09-11 01:48:57 +0000108
109 ByVal, /// Only valid for aggregate argument types. The
110 /// structure should be passed "byval" with the
111 /// specified alignment (0 indicates default
112 /// alignment).
113
114 Expand, /// Only valid for aggregate argument types. The
115 /// structure should be expanded into consecutive
Daniel Dunbar04d35782008-09-17 00:51:38 +0000116 /// arguments for its constituent fields. Currently
117 /// expand is only allowed on structures whose fields
118 /// are all scalar types or are themselves expandable
119 /// types.
Daniel Dunbar22e30052008-09-11 01:48:57 +0000120
121 KindFirst=Default, KindLast=Expand
Daniel Dunbare126ab12008-09-10 02:41:04 +0000122 };
123
124private:
125 Kind TheKind;
Daniel Dunbar73d66602008-09-10 07:04:09 +0000126 const llvm::Type *TypeData;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000127 unsigned UIntData;
Daniel Dunbare126ab12008-09-10 02:41:04 +0000128
Daniel Dunbar22e30052008-09-11 01:48:57 +0000129 ABIArgInfo(Kind K, const llvm::Type *TD=0,
130 unsigned UI=0) : TheKind(K),
131 TypeData(TD),
132 UIntData(0) {}
Daniel Dunbare126ab12008-09-10 02:41:04 +0000133public:
134 static ABIArgInfo getDefault() {
Daniel Dunbar22e30052008-09-11 01:48:57 +0000135 return ABIArgInfo(Default);
Daniel Dunbare126ab12008-09-10 02:41:04 +0000136 }
137 static ABIArgInfo getStructRet() {
Daniel Dunbar22e30052008-09-11 01:48:57 +0000138 return ABIArgInfo(StructRet);
Daniel Dunbare126ab12008-09-10 02:41:04 +0000139 }
Daniel Dunbar73d66602008-09-10 07:04:09 +0000140 static ABIArgInfo getCoerce(const llvm::Type *T) {
141 assert(T->isSingleValueType() && "Can only coerce to simple types");
Daniel Dunbare126ab12008-09-10 02:41:04 +0000142 return ABIArgInfo(Coerce, T);
143 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000144 static ABIArgInfo getByVal(unsigned Alignment) {
145 return ABIArgInfo(ByVal, 0, Alignment);
146 }
Daniel Dunbar04d35782008-09-17 00:51:38 +0000147 static ABIArgInfo getExpand() {
148 return ABIArgInfo(Expand);
149 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000150
151 Kind getKind() const { return TheKind; }
152 bool isDefault() const { return TheKind == Default; }
153 bool isStructRet() const { return TheKind == StructRet; }
154 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000155 bool isByVal() const { return TheKind == ByVal; }
Daniel Dunbar04d35782008-09-17 00:51:38 +0000156 bool isExpand() const { return TheKind == Expand; }
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000157
158 // Coerce accessors
Daniel Dunbar73d66602008-09-10 07:04:09 +0000159 const llvm::Type *getCoerceToType() const {
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000160 assert(TheKind == Coerce && "Invalid kind!");
161 return TypeData;
162 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000163
164 // ByVal accessors
165 unsigned getByValAlignment() const {
166 assert(TheKind == ByVal && "Invalid kind!");
167 return UIntData;
168 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000169};
170
171/***/
172
Daniel Dunbar73d66602008-09-10 07:04:09 +0000173static ABIArgInfo classifyReturnType(QualType RetTy,
174 ASTContext &Context) {
Daniel Dunbar753d1102008-09-11 00:04:36 +0000175 assert(!RetTy->isArrayType() &&
176 "Array types cannot be passed directly.");
Daniel Dunbare126ab12008-09-10 02:41:04 +0000177 if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
Daniel Dunbar73d66602008-09-10 07:04:09 +0000178 uint64_t Size = Context.getTypeSize(RetTy);
179 if (Size == 8) {
180 return ABIArgInfo::getCoerce(llvm::Type::Int8Ty);
181 } else if (Size == 16) {
182 return ABIArgInfo::getCoerce(llvm::Type::Int16Ty);
183 } else if (Size == 32) {
184 return ABIArgInfo::getCoerce(llvm::Type::Int32Ty);
185 } else if (Size == 64) {
186 return ABIArgInfo::getCoerce(llvm::Type::Int64Ty);
187 } else {
188 return ABIArgInfo::getStructRet();
189 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000190 } else {
191 return ABIArgInfo::getDefault();
192 }
193}
194
Daniel Dunbar22e30052008-09-11 01:48:57 +0000195static ABIArgInfo classifyArgumentType(QualType Ty,
196 ASTContext &Context,
197 CodeGenTypes &Types) {
198 assert(!Ty->isArrayType() && "Array types cannot be passed directly.");
199
200 if (!Types.ConvertType(Ty)->isSingleValueType()) {
201 return ABIArgInfo::getByVal(0);
202 } else {
203 return ABIArgInfo::getDefault();
204 }
205}
206
Daniel Dunbare126ab12008-09-10 02:41:04 +0000207/***/
208
Daniel Dunbar04d35782008-09-17 00:51:38 +0000209void CodeGenTypes::GetExpandedTypes(QualType Ty,
210 std::vector<const llvm::Type*> &ArgTys) {
211 const RecordType *RT = Ty->getAsStructureType();
212 assert(RT && "Can only expand structure types.");
213 const RecordDecl *RD = RT->getDecl();
214 assert(!RD->hasFlexibleArrayMember() &&
215 "Cannot expand structure with flexible array.");
216
217 for (RecordDecl::field_const_iterator i = RD->field_begin(),
218 e = RD->field_end(); i != e; ++i) {
219 const FieldDecl *FD = *i;
220 assert(!FD->isBitField() &&
221 "Cannot expand structure with bit-field members.");
222
223 QualType FT = FD->getType();
224 if (CodeGenFunction::hasAggregateLLVMType(FT)) {
225 GetExpandedTypes(FT, ArgTys);
226 } else {
227 ArgTys.push_back(ConvertType(FT));
228 }
229 }
230}
231
232llvm::Function::arg_iterator
233CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
234 llvm::Function::arg_iterator AI) {
235 const RecordType *RT = Ty->getAsStructureType();
236 assert(RT && "Can only expand structure types.");
237
238 RecordDecl *RD = RT->getDecl();
239 assert(LV.isSimple() &&
240 "Unexpected non-simple lvalue during struct expansion.");
241 llvm::Value *Addr = LV.getAddress();
242 for (RecordDecl::field_iterator i = RD->field_begin(),
243 e = RD->field_end(); i != e; ++i) {
244 FieldDecl *FD = *i;
245 QualType FT = FD->getType();
246
247 // FIXME: What are the right qualifiers here?
248 LValue LV = EmitLValueForField(Addr, FD, false, 0);
249 if (CodeGenFunction::hasAggregateLLVMType(FT)) {
250 AI = ExpandTypeFromArgs(FT, LV, AI);
251 } else {
252 EmitStoreThroughLValue(RValue::get(AI), LV, FT);
253 ++AI;
254 }
255 }
256
257 return AI;
258}
259
260void
261CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
262 llvm::SmallVector<llvm::Value*, 16> &Args) {
263 const RecordType *RT = Ty->getAsStructureType();
264 assert(RT && "Can only expand structure types.");
265
266 RecordDecl *RD = RT->getDecl();
267 assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
268 llvm::Value *Addr = RV.getAggregateAddr();
269 for (RecordDecl::field_iterator i = RD->field_begin(),
270 e = RD->field_end(); i != e; ++i) {
271 FieldDecl *FD = *i;
272 QualType FT = FD->getType();
273
274 // FIXME: What are the right qualifiers here?
275 LValue LV = EmitLValueForField(Addr, FD, false, 0);
276 if (CodeGenFunction::hasAggregateLLVMType(FT)) {
277 ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args);
278 } else {
279 RValue RV = EmitLoadOfLValue(LV, FT);
280 assert(RV.isScalar() &&
281 "Unexpected non-scalar rvalue during struct expansion.");
282 Args.push_back(RV.getScalarVal());
283 }
284 }
285}
286
287/***/
288
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000289const llvm::FunctionType *
Daniel Dunbara9976a22008-09-10 07:00:50 +0000290CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) {
291 return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic);
292}
293
294const llvm::FunctionType *
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000295CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
Daniel Dunbara9976a22008-09-10 07:00:50 +0000296 return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic());
297}
298
299const llvm::FunctionType *
300CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
301 bool IsVariadic) {
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000302 std::vector<const llvm::Type*> ArgTys;
303
304 const llvm::Type *ResultType = 0;
305
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000306 QualType RetTy = *begin;
Daniel Dunbar73d66602008-09-10 07:04:09 +0000307 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar22e30052008-09-11 01:48:57 +0000308 switch (RetAI.getKind()) {
309 case ABIArgInfo::ByVal:
310 case ABIArgInfo::Expand:
311 assert(0 && "Invalid ABI kind for return argument");
312
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000313 case ABIArgInfo::Default:
314 if (RetTy->isVoidType()) {
315 ResultType = llvm::Type::VoidTy;
316 } else {
Daniel Dunbara9976a22008-09-10 07:00:50 +0000317 ResultType = ConvertType(RetTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000318 }
319 break;
320
321 case ABIArgInfo::StructRet: {
322 ResultType = llvm::Type::VoidTy;
Daniel Dunbara9976a22008-09-10 07:00:50 +0000323 const llvm::Type *STy = ConvertType(RetTy);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000324 ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
325 break;
326 }
327
328 case ABIArgInfo::Coerce:
Daniel Dunbar73d66602008-09-10 07:04:09 +0000329 ResultType = RetAI.getCoerceToType();
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000330 break;
331 }
332
333 for (++begin; begin != end; ++begin) {
Daniel Dunbar22e30052008-09-11 01:48:57 +0000334 ABIArgInfo AI = classifyArgumentType(*begin, getContext(), *this);
Daniel Dunbara9976a22008-09-10 07:00:50 +0000335 const llvm::Type *Ty = ConvertType(*begin);
Daniel Dunbar22e30052008-09-11 01:48:57 +0000336
337 switch (AI.getKind()) {
Daniel Dunbar04d35782008-09-17 00:51:38 +0000338 case ABIArgInfo::Coerce:
Daniel Dunbar22e30052008-09-11 01:48:57 +0000339 case ABIArgInfo::StructRet:
340 assert(0 && "Invalid ABI kind for non-return argument");
341
342 case ABIArgInfo::ByVal:
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000343 // byval arguments are always on the stack, which is addr space #0.
344 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
Daniel Dunbar22e30052008-09-11 01:48:57 +0000345 assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
346 break;
347
348 case ABIArgInfo::Default:
349 ArgTys.push_back(Ty);
350 break;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000351
352 case ABIArgInfo::Expand:
Daniel Dunbar04d35782008-09-17 00:51:38 +0000353 GetExpandedTypes(*begin, ArgTys);
Daniel Dunbar22e30052008-09-11 01:48:57 +0000354 break;
355 }
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000356 }
357
Daniel Dunbara9976a22008-09-10 07:00:50 +0000358 return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000359}
360
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000361bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
Daniel Dunbar73d66602008-09-10 07:04:09 +0000362 return classifyReturnType(RetTy, getContext()).isStructRet();
Daniel Dunbar49f5a0d2008-09-09 23:48:28 +0000363}
364
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000365void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
Daniel Dunbare126ab12008-09-10 02:41:04 +0000366 ArgTypeIterator begin,
367 ArgTypeIterator end,
368 ParamAttrListType &PAL) {
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000369 unsigned FuncAttrs = 0;
370
371 if (TargetDecl) {
372 if (TargetDecl->getAttr<NoThrowAttr>())
373 FuncAttrs |= llvm::ParamAttr::NoUnwind;
374 if (TargetDecl->getAttr<NoReturnAttr>())
375 FuncAttrs |= llvm::ParamAttr::NoReturn;
376 }
377
Daniel Dunbare126ab12008-09-10 02:41:04 +0000378 QualType RetTy = *begin;
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000379 unsigned Index = 1;
Daniel Dunbar73d66602008-09-10 07:04:09 +0000380 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbar3ad1f072008-09-10 04:01:49 +0000381 switch (RetAI.getKind()) {
Daniel Dunbare126ab12008-09-10 02:41:04 +0000382 case ABIArgInfo::Default:
383 if (RetTy->isPromotableIntegerType()) {
384 if (RetTy->isSignedIntegerType()) {
385 FuncAttrs |= llvm::ParamAttr::SExt;
386 } else if (RetTy->isUnsignedIntegerType()) {
387 FuncAttrs |= llvm::ParamAttr::ZExt;
388 }
389 }
390 break;
391
392 case ABIArgInfo::StructRet:
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000393 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index,
394 llvm::ParamAttr::StructRet));
395 ++Index;
Daniel Dunbare126ab12008-09-10 02:41:04 +0000396 break;
397
398 case ABIArgInfo::Coerce:
Daniel Dunbare126ab12008-09-10 02:41:04 +0000399 break;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000400
401 case ABIArgInfo::ByVal:
402 case ABIArgInfo::Expand:
403 assert(0 && "Invalid ABI kind for return argument");
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000404 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000405
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000406 if (FuncAttrs)
407 PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
Daniel Dunbar04d35782008-09-17 00:51:38 +0000408 for (++begin; begin != end; ++begin) {
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000409 QualType ParamType = *begin;
410 unsigned ParamAttrs = 0;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000411 ABIArgInfo AI = classifyArgumentType(ParamType, getContext(), getTypes());
412
413 switch (AI.getKind()) {
414 case ABIArgInfo::StructRet:
Daniel Dunbar04d35782008-09-17 00:51:38 +0000415 case ABIArgInfo::Coerce:
Daniel Dunbar22e30052008-09-11 01:48:57 +0000416 assert(0 && "Invalid ABI kind for non-return argument");
417
418 case ABIArgInfo::ByVal:
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000419 ParamAttrs |= llvm::ParamAttr::ByVal;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000420 assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
421 break;
422
423 case ABIArgInfo::Default:
424 if (ParamType->isPromotableIntegerType()) {
425 if (ParamType->isSignedIntegerType()) {
426 ParamAttrs |= llvm::ParamAttr::SExt;
427 } else if (ParamType->isUnsignedIntegerType()) {
428 ParamAttrs |= llvm::ParamAttr::ZExt;
429 }
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000430 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000431 break;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000432
Daniel Dunbar04d35782008-09-17 00:51:38 +0000433 case ABIArgInfo::Expand: {
434 std::vector<const llvm::Type*> Tys;
435 // FIXME: This is rather inefficient. Do we ever actually need
436 // to do anything here? The result should be just reconstructed
437 // on the other side, so extension should be a non-issue.
438 getTypes().GetExpandedTypes(ParamType, Tys);
439 Index += Tys.size();
440 continue;
441 }
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000442 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000443
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000444 if (ParamAttrs)
445 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, ParamAttrs));
Daniel Dunbar04d35782008-09-17 00:51:38 +0000446 ++Index;
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000447 }
448}
449
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000450void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
451 QualType RetTy,
452 const FunctionArgList &Args) {
453 // Emit allocs for param decls. Give the LLVM Argument nodes names.
454 llvm::Function::arg_iterator AI = Fn->arg_begin();
455
456 // Name the struct return argument.
Daniel Dunbare126ab12008-09-10 02:41:04 +0000457 if (CGM.ReturnTypeUsesSret(RetTy)) {
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000458 AI->setName("agg.result");
459 ++AI;
460 }
461
462 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
Daniel Dunbar04d35782008-09-17 00:51:38 +0000463 i != e; ++i) {
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000464 const VarDecl *Arg = i->first;
Daniel Dunbar04d35782008-09-17 00:51:38 +0000465 QualType Ty = i->second;
466 ABIArgInfo ArgI = classifyArgumentType(Ty, getContext(), CGM.getTypes());
Daniel Dunbar22e30052008-09-11 01:48:57 +0000467
468 switch (ArgI.getKind()) {
469 case ABIArgInfo::ByVal:
470 case ABIArgInfo::Default: {
471 assert(AI != Fn->arg_end() && "Argument mismatch!");
472 llvm::Value* V = AI;
Daniel Dunbar04d35782008-09-17 00:51:38 +0000473 if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
Daniel Dunbar22e30052008-09-11 01:48:57 +0000474 // This must be a promotion, for something like
475 // "void a(x) short x; {..."
Daniel Dunbar04d35782008-09-17 00:51:38 +0000476 V = EmitScalarConversion(V, Ty, Arg->getType());
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000477 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000478 EmitParmDecl(*Arg, V);
479 break;
480 }
Daniel Dunbar04d35782008-09-17 00:51:38 +0000481
482 case ABIArgInfo::Expand: {
483 // If this was structure was expand into multiple arguments then
484 // we need to create a temporary and reconstruct it from the
485 // arguments.
486 std::string Name(Arg->getName());
487 llvm::Value *Temp = CreateTempAlloca(ConvertType(Ty),
488 (Name + ".addr").c_str());
489 // FIXME: What are the right qualifiers here?
490 llvm::Function::arg_iterator End =
491 ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp,0), AI);
492 EmitParmDecl(*Arg, Temp);
Daniel Dunbar22e30052008-09-11 01:48:57 +0000493
Daniel Dunbar04d35782008-09-17 00:51:38 +0000494 // Name the arguments used in expansion and increment AI.
495 unsigned Index = 0;
496 for (; AI != End; ++AI, ++Index)
497 AI->setName(Name + "." + llvm::utostr(Index));
498 continue;
499 }
500
Daniel Dunbar22e30052008-09-11 01:48:57 +0000501 case ABIArgInfo::Coerce:
Daniel Dunbar22e30052008-09-11 01:48:57 +0000502 case ABIArgInfo::StructRet:
503 assert(0 && "Invalid ABI kind for non-return argument");
504 }
Daniel Dunbar04d35782008-09-17 00:51:38 +0000505
506 ++AI;
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000507 }
508 assert(AI == Fn->arg_end() && "Argument mismatch!");
509}
510
511void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
512 llvm::Value *ReturnValue) {
Daniel Dunbare126ab12008-09-10 02:41:04 +0000513 llvm::Value *RV = 0;
514
515 // Functions with no result always return void.
516 if (ReturnValue) {
Daniel Dunbar73d66602008-09-10 07:04:09 +0000517 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbare126ab12008-09-10 02:41:04 +0000518
519 switch (RetAI.getKind()) {
520 case ABIArgInfo::StructRet:
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000521 EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
Daniel Dunbare126ab12008-09-10 02:41:04 +0000522 break;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000523
Daniel Dunbare126ab12008-09-10 02:41:04 +0000524 case ABIArgInfo::Default:
525 RV = Builder.CreateLoad(ReturnValue);
526 break;
527
Daniel Dunbar73d66602008-09-10 07:04:09 +0000528 case ABIArgInfo::Coerce: {
529 const llvm::Type *CoerceToPTy =
530 llvm::PointerType::getUnqual(RetAI.getCoerceToType());
531 RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy));
Daniel Dunbar22e30052008-09-11 01:48:57 +0000532 break;
Daniel Dunbar73d66602008-09-10 07:04:09 +0000533 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000534
535 case ABIArgInfo::ByVal:
536 case ABIArgInfo::Expand:
537 assert(0 && "Invalid ABI kind for return argument");
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000538 }
539 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000540
541 if (RV) {
542 Builder.CreateRet(RV);
543 } else {
544 Builder.CreateRetVoid();
545 }
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000546}
547
548RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
Daniel Dunbare126ab12008-09-10 02:41:04 +0000549 QualType RetTy,
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000550 const CallArgList &CallArgs) {
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000551 llvm::SmallVector<llvm::Value*, 16> Args;
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000552
553 // Handle struct-return functions by passing a pointer to the
554 // location that we would like to return into.
Daniel Dunbar73d66602008-09-10 07:04:09 +0000555 ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
Daniel Dunbare126ab12008-09-10 02:41:04 +0000556 switch (RetAI.getKind()) {
557 case ABIArgInfo::StructRet:
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000558 // Create a temporary alloca to hold the result of the call. :(
Daniel Dunbar04d35782008-09-17 00:51:38 +0000559 Args.push_back(CreateTempAlloca(ConvertType(RetTy)));
Daniel Dunbare126ab12008-09-10 02:41:04 +0000560 break;
561
562 case ABIArgInfo::Default:
Daniel Dunbare126ab12008-09-10 02:41:04 +0000563 case ABIArgInfo::Coerce:
Daniel Dunbare126ab12008-09-10 02:41:04 +0000564 break;
Daniel Dunbar22e30052008-09-11 01:48:57 +0000565
566 case ABIArgInfo::ByVal:
567 case ABIArgInfo::Expand:
568 assert(0 && "Invalid ABI kind for return argument");
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000569 }
570
571 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
572 I != E; ++I) {
Daniel Dunbar04d35782008-09-17 00:51:38 +0000573 ABIArgInfo ArgInfo = classifyArgumentType(I->second, getContext(),
574 CGM.getTypes());
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000575 RValue RV = I->first;
Daniel Dunbar04d35782008-09-17 00:51:38 +0000576
577 switch (ArgInfo.getKind()) {
578 case ABIArgInfo::ByVal: // Default is byval
579 case ABIArgInfo::Default:
580 if (RV.isScalar()) {
581 Args.push_back(RV.getScalarVal());
582 } else if (RV.isComplex()) {
583 // Make a temporary alloca to pass the argument.
584 Args.push_back(CreateTempAlloca(ConvertType(I->second)));
585 StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
586 } else {
587 Args.push_back(RV.getAggregateAddr());
588 }
589 break;
590
591 case ABIArgInfo::StructRet:
592 case ABIArgInfo::Coerce:
593 assert(0 && "Invalid ABI kind for non-return argument");
594 break;
595
596 case ABIArgInfo::Expand:
597 ExpandTypeToArgs(I->second, RV, Args);
598 break;
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000599 }
600 }
601
602 llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
Daniel Dunbare126ab12008-09-10 02:41:04 +0000603 CGCallInfo CallInfo(RetTy, CallArgs);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000604
Daniel Dunbarbccb0682008-09-10 00:32:18 +0000605 // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000606 CodeGen::ParamAttrListType ParamAttrList;
Daniel Dunbar3ef2e852008-09-10 00:41:16 +0000607 CGM.ConstructParamAttrList(0,
608 CallInfo.argtypes_begin(), CallInfo.argtypes_end(),
609 ParamAttrList);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000610 CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
611 ParamAttrList.size()));
612
613 if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
614 CI->setCallingConv(F->getCallingConv());
615 if (CI->getType() != llvm::Type::VoidTy)
616 CI->setName("call");
Daniel Dunbare126ab12008-09-10 02:41:04 +0000617
618 switch (RetAI.getKind()) {
619 case ABIArgInfo::StructRet:
620 if (RetTy->isAnyComplexType())
Daniel Dunbar04d35782008-09-17 00:51:38 +0000621 return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
Daniel Dunbare126ab12008-09-10 02:41:04 +0000622 else
623 // Struct return.
Daniel Dunbar04d35782008-09-17 00:51:38 +0000624 return RValue::getAggregate(Args[0]);
Daniel Dunbar22e30052008-09-11 01:48:57 +0000625
Daniel Dunbare126ab12008-09-10 02:41:04 +0000626 case ABIArgInfo::Default:
627 return RValue::get(RetTy->isVoidType() ? 0 : CI);
628
Daniel Dunbar73d66602008-09-10 07:04:09 +0000629 case ABIArgInfo::Coerce: {
630 const llvm::Type *CoerceToPTy =
631 llvm::PointerType::getUnqual(RetAI.getCoerceToType());
632 llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp");
633 Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
634 return RValue::getAggregate(V);
635 }
Daniel Dunbar22e30052008-09-11 01:48:57 +0000636
637 case ABIArgInfo::ByVal:
638 case ABIArgInfo::Expand:
639 assert(0 && "Invalid ABI kind for return argument");
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000640 }
Daniel Dunbare126ab12008-09-10 02:41:04 +0000641
642 assert(0 && "Unhandled ABIArgInfo::Kind");
643 return RValue::get(0);
Daniel Dunbarfc1a9c42008-09-09 23:27:19 +0000644}