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.