Mercurial > projects > ldc
comparison gen/tocall.cpp @ 1051:dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
same LDC call.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 07 Mar 2009 14:25:30 +0100 |
parents | 32ead42679d1 |
children | 4c20fcc4252b |
comparison
equal
deleted
inserted
replaced
1050:32ead42679d1 | 1051:dc608dc33081 |
---|---|
199 { | 199 { |
200 Argument* fnarg = Argument::getNth(tf->parameters, i); | 200 Argument* fnarg = Argument::getNth(tf->parameters, i); |
201 DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); | 201 DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); |
202 args.push_back(argval->getRVal()); | 202 args.push_back(argval->getRVal()); |
203 | 203 |
204 if (tf->fty->args[i]->attrs) | 204 if (tf->fty.args[i]->attrs) |
205 { | 205 { |
206 llvm::AttributeWithIndex Attr; | 206 llvm::AttributeWithIndex Attr; |
207 Attr.Index = argidx; | 207 Attr.Index = argidx; |
208 Attr.Attrs = tf->fty->args[i]->attrs; | 208 Attr.Attrs = tf->fty.args[i]->attrs; |
209 attrs.push_back(Attr); | 209 attrs.push_back(Attr); |
210 } | 210 } |
211 | 211 |
212 ++argidx; | 212 ++argidx; |
213 } | 213 } |
237 | 237 |
238 // get function type info | 238 // get function type info |
239 TypeFunction* tf = DtoTypeFunction(fnval); | 239 TypeFunction* tf = DtoTypeFunction(fnval); |
240 | 240 |
241 // misc | 241 // misc |
242 bool retinptr = tf->fty->arg_sret; | 242 bool retinptr = tf->fty.arg_sret; |
243 bool thiscall = tf->fty->arg_this; | 243 bool thiscall = tf->fty.arg_this; |
244 bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); | 244 bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); |
245 bool nestedcall = tf->fty->arg_nest; | 245 bool nestedcall = tf->fty.arg_nest; |
246 bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); | 246 bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); |
247 | 247 |
248 unsigned callconv = DtoCallingConv(loc, tf->linkage); | 248 unsigned callconv = DtoCallingConv(loc, tf->linkage); |
249 | 249 |
250 // get callee llvm value | 250 // get callee llvm value |
265 // parameter attributes | 265 // parameter attributes |
266 std::vector<llvm::AttributeWithIndex> attrs; | 266 std::vector<llvm::AttributeWithIndex> attrs; |
267 llvm::AttributeWithIndex Attr; | 267 llvm::AttributeWithIndex Attr; |
268 | 268 |
269 // return attrs | 269 // return attrs |
270 if (tf->fty->ret->attrs) | 270 if (tf->fty.ret->attrs) |
271 { | 271 { |
272 Attr.Index = 0; | 272 Attr.Index = 0; |
273 Attr.Attrs = tf->fty->ret->attrs; | 273 Attr.Attrs = tf->fty.ret->attrs; |
274 attrs.push_back(Attr); | 274 attrs.push_back(Attr); |
275 } | 275 } |
276 | 276 |
277 // handle implicit arguments | 277 // handle implicit arguments |
278 std::vector<LLValue*> args; | 278 std::vector<LLValue*> args; |
279 args.reserve(tf->fty->args.size()); | 279 args.reserve(tf->fty.args.size()); |
280 | 280 |
281 // return in hidden ptr is first | 281 // return in hidden ptr is first |
282 if (retinptr) | 282 if (retinptr) |
283 { | 283 { |
284 LLValue* retvar = DtoAlloca(argiter->get()->getContainedType(0), ".rettmp"); | 284 LLValue* retvar = DtoAlloca(argiter->get()->getContainedType(0), ".rettmp"); |
330 error(loc, "Context argument required but none given"); | 330 error(loc, "Context argument required but none given"); |
331 fatal(); | 331 fatal(); |
332 } | 332 } |
333 | 333 |
334 // add attributes for context argument | 334 // add attributes for context argument |
335 if (tf->fty->arg_this && tf->fty->arg_this->attrs) | 335 if (tf->fty.arg_this && tf->fty.arg_this->attrs) |
336 { | 336 { |
337 Attr.Index = retinptr ? 2 : 1; | 337 Attr.Index = retinptr ? 2 : 1; |
338 Attr.Attrs = tf->fty->arg_this->attrs; | 338 Attr.Attrs = tf->fty.arg_this->attrs; |
339 attrs.push_back(Attr); | 339 attrs.push_back(Attr); |
340 } | 340 } |
341 else if (tf->fty->arg_nest && tf->fty->arg_nest->attrs) | 341 else if (tf->fty.arg_nest && tf->fty.arg_nest->attrs) |
342 { | 342 { |
343 Attr.Index = retinptr ? 2 : 1; | 343 Attr.Index = retinptr ? 2 : 1; |
344 Attr.Attrs = tf->fty->arg_nest->attrs; | 344 Attr.Attrs = tf->fty.arg_nest->attrs; |
345 attrs.push_back(Attr); | 345 attrs.push_back(Attr); |
346 } | 346 } |
347 } | 347 } |
348 | 348 |
349 // handle the rest of the arguments based on param passing style | 349 // handle the rest of the arguments based on param passing style |
400 Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n'; | 400 Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n'; |
401 Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n'; | 401 Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n'; |
402 } | 402 } |
403 | 403 |
404 // give the ABI a say | 404 // give the ABI a say |
405 LLValue* arg = tf->fty->putParam(argval->getType(), i, argval); | 405 LLValue* arg = tf->fty.putParam(argval->getType(), i, argval); |
406 | 406 |
407 if (Logger::enabled()) { | 407 if (Logger::enabled()) { |
408 Logger::cout() << "Argument after ABI: " << *arg << '\n'; | 408 Logger::cout() << "Argument after ABI: " << *arg << '\n'; |
409 Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n'; | 409 Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n'; |
410 } | 410 } |
411 | 411 |
412 int j = tf->fty->reverseParams ? beg + n - i - 1 : beg + i; | 412 int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i; |
413 | 413 |
414 // Hack around LDC assuming structs are in memory: | 414 // Hack around LDC assuming structs are in memory: |
415 // If the function wants a struct, and the argument value is a | 415 // If the function wants a struct, and the argument value is a |
416 // pointer to a struct, load from it before passing it in. | 416 // pointer to a struct, load from it before passing it in. |
417 if (argval->getType()->ty == Tstruct | 417 if (argval->getType()->ty == Tstruct |
432 #endif | 432 #endif |
433 arg = DtoBitCast(arg, callableTy->getParamType(j)); | 433 arg = DtoBitCast(arg, callableTy->getParamType(j)); |
434 } | 434 } |
435 | 435 |
436 // param attrs | 436 // param attrs |
437 attrptr[i] = tf->fty->args[i]->attrs; | 437 attrptr[i] = tf->fty.args[i]->attrs; |
438 | 438 |
439 ++argiter; | 439 ++argiter; |
440 args.push_back(arg); | 440 args.push_back(arg); |
441 } | 441 } |
442 | 442 |
443 // reverse the relevant params as well as the param attrs | 443 // reverse the relevant params as well as the param attrs |
444 if (tf->fty->reverseParams) | 444 if (tf->fty.reverseParams) |
445 { | 445 { |
446 std::reverse(args.begin() + beg, args.end()); | 446 std::reverse(args.begin() + beg, args.end()); |
447 std::reverse(attrptr.begin(), attrptr.end()); | 447 std::reverse(attrptr.begin(), attrptr.end()); |
448 } | 448 } |
449 | 449 |
505 // Ignore ABI for intrinsics | 505 // Ignore ABI for intrinsics |
506 if (tf->linkage != LINKintrinsic && !retinptr) | 506 if (tf->linkage != LINKintrinsic && !retinptr) |
507 { | 507 { |
508 // do abi specific return value fixups | 508 // do abi specific return value fixups |
509 DImValue dretval(tf->next, retllval); | 509 DImValue dretval(tf->next, retllval); |
510 retllval = tf->fty->getRet(tf->next, &dretval); | 510 retllval = tf->fty.getRet(tf->next, &dretval); |
511 } | 511 } |
512 | 512 |
513 // Hack around LDC assuming structs are in memory: | 513 // Hack around LDC assuming structs are in memory: |
514 // If the function returns a struct, and the return value is not a | 514 // If the function returns a struct, and the return value is not a |
515 // pointer to a struct, store it to a stack slot before continuing. | 515 // pointer to a struct, store it to a stack slot before continuing. |