comparison gen/toir.cpp @ 585:fbb1a366cfbc

Complex number should now follow the D ABI on x86. They're also treated as first class values now. Big change.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 09 Sep 2008 16:49:47 -0700
parents f0c20d50d4b3
children 23538d0f0d5b
comparison
equal deleted inserted replaced
584:c7d7e2282ba3 585:fbb1a366cfbc
62 // _arguments 62 // _arguments
63 if (vd->ident == Id::_arguments && p->func()->_arguments) 63 if (vd->ident == Id::_arguments && p->func()->_arguments)
64 { 64 {
65 Logger::println("Id::_arguments"); 65 Logger::println("Id::_arguments");
66 LLValue* v = p->func()->_arguments; 66 LLValue* v = p->func()->_arguments;
67 return new DVarValue(type, vd, v, true); 67 return new DVarValue(type, vd, v);
68 } 68 }
69 // _argptr 69 // _argptr
70 else if (vd->ident == Id::_argptr && p->func()->_argptr) 70 else if (vd->ident == Id::_argptr && p->func()->_argptr)
71 { 71 {
72 Logger::println("Id::_argptr"); 72 Logger::println("Id::_argptr");
73 LLValue* v = p->func()->_argptr; 73 LLValue* v = p->func()->_argptr;
74 return new DVarValue(type, vd, v, true); 74 return new DVarValue(type, vd, v);
75 } 75 }
76 // _dollar 76 // _dollar
77 else if (vd->ident == Id::dollar) 77 else if (vd->ident == Id::dollar)
78 { 78 {
79 Logger::println("Id::dollar"); 79 Logger::println("Id::dollar");
80 assert(!p->arrays.empty()); 80 assert(!p->arrays.empty());
81 LLValue* tmp = DtoArrayLen(p->arrays.back()); 81 LLValue* tmp = DtoArrayLen(p->arrays.back());
82 return new DVarValue(type, vd, tmp, false); 82 return new DImValue(type, tmp);
83 } 83 }
84 // typeinfo 84 // typeinfo
85 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) 85 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
86 { 86 {
87 Logger::println("TypeInfoDeclaration"); 87 Logger::println("TypeInfoDeclaration");
88 DtoForceDeclareDsymbol(tid); 88 DtoForceDeclareDsymbol(tid);
89 assert(tid->ir.getIrValue()); 89 assert(tid->ir.getIrValue());
90 const LLType* vartype = DtoType(type); 90 const LLType* vartype = DtoType(type);
91 LLValue* m; 91 LLValue* m = tid->ir.getIrValue();
92 if (tid->ir.getIrValue()->getType() != getPtrToType(vartype)) 92 if (m->getType() != getPtrToType(vartype))
93 m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp"); 93 m = p->ir->CreateBitCast(m, vartype, "tmp");
94 else 94 return new DImValue(type, m);
95 m = tid->ir.getIrValue();
96 return new DVarValue(type, vd, m, true);
97 } 95 }
98 // classinfo 96 // classinfo
99 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) 97 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
100 { 98 {
101 Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); 99 Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
102 DtoForceDeclareDsymbol(cid->cd); 100 DtoForceDeclareDsymbol(cid->cd);
103 assert(cid->cd->ir.irStruct->classInfo); 101 assert(cid->cd->ir.irStruct->classInfo);
104 return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true); 102 return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo);
105 } 103 }
106 // nested variable 104 // nested variable
107 else if (vd->nestedref) { 105 else if (vd->nestedref) {
108 Logger::println("nested variable"); 106 Logger::println("nested variable");
109 return DtoNestedVariable(loc, type, vd); 107 return DtoNestedVariable(loc, type, vd);
115 if (fd && fd != p->func()->decl) { 113 if (fd && fd != p->func()->decl) {
116 Logger::println("nested parameter"); 114 Logger::println("nested parameter");
117 return DtoNestedVariable(loc, type, vd); 115 return DtoNestedVariable(loc, type, vd);
118 } 116 }
119 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) { 117 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
120 return new DVarValue(type, vd, vd->ir.getIrValue(), true); 118 return new DVarValue(type, vd, vd->ir.getIrValue());
121 } 119 }
122 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) { 120 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) {
123 return new DImValue(type, vd->ir.getIrValue()); 121 return new DImValue(type, vd->ir.getIrValue());
124 } 122 }
125 else assert(0); 123 else assert(0);
126 } 124 }
127 else { 125 else {
126 Logger::println("a normal variable");
128 // take care of forward references of global variables 127 // take care of forward references of global variables
129 if (vd->isDataseg() || (vd->storage_class & STCextern)) { 128 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
130 vd->toObjFile(0); // TODO: multiobj 129 vd->toObjFile(0); // TODO: multiobj
131 DtoConstInitGlobal(vd); 130 DtoConstInitGlobal(vd);
132 } 131 }
133 if (!vd->ir.isSet() || !vd->ir.getIrValue() || DtoType(vd->type)->isAbstract()) { 132 if (!vd->ir.isSet() || !vd->ir.getIrValue() || DtoType(vd->type)->isAbstract()) {
134 error("global variable %s not resolved", vd->toChars()); 133 error("global variable %s not resolved", vd->toChars());
135 Logger::cout() << "unresolved global had type: " << *DtoType(vd->type) << '\n'; 134 Logger::cout() << "unresolved global had type: " << *DtoType(vd->type) << '\n';
136 fatal(); 135 fatal();
137 } 136 }
138 return new DVarValue(type, vd, vd->ir.getIrValue(), true); 137 return new DVarValue(type, vd, vd->ir.getIrValue());
139 } 138 }
140 } 139 }
141 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) 140 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
142 { 141 {
143 Logger::println("FuncDeclaration"); 142 Logger::println("FuncDeclaration");
156 assert(sdecltype->ty == Tstruct); 155 assert(sdecltype->ty == Tstruct);
157 TypeStruct* ts = (TypeStruct*)sdecltype; 156 TypeStruct* ts = (TypeStruct*)sdecltype;
158 assert(ts->sym); 157 assert(ts->sym);
159 DtoForceConstInitDsymbol(ts->sym); 158 DtoForceConstInitDsymbol(ts->sym);
160 assert(ts->sym->ir.irStruct->init); 159 assert(ts->sym->ir.irStruct->init);
161 return new DVarValue(type, ts->sym->ir.irStruct->init, true); 160 return new DVarValue(type, ts->sym->ir.irStruct->init);
162 } 161 }
163 else 162 else
164 { 163 {
165 assert(0 && "Unimplemented VarExp type"); 164 assert(0 && "Unimplemented VarExp type");
166 } 165 }
279 DValue* ComplexExp::toElem(IRState* p) 278 DValue* ComplexExp::toElem(IRState* p)
280 { 279 {
281 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); 280 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars());
282 LOG_SCOPE; 281 LOG_SCOPE;
283 LLConstant* c = toConstElem(p); 282 LLConstant* c = toConstElem(p);
283 LLValue* res;
284 284
285 if (c->isNullValue()) { 285 if (c->isNullValue()) {
286 Type* t = type->toBasetype(); 286 Type* t = type->toBasetype();
287 if (t->ty == Tcomplex32) 287 if (t->ty == Tcomplex32)
288 c = DtoConstFP(Type::tfloat32, 0); 288 c = DtoConstFP(Type::tfloat32, 0);
290 c = DtoConstFP(Type::tfloat64, 0); 290 c = DtoConstFP(Type::tfloat64, 0);
291 else if (t->ty == Tcomplex80) 291 else if (t->ty == Tcomplex80)
292 c = DtoConstFP(Type::tfloat80, 0); 292 c = DtoConstFP(Type::tfloat80, 0);
293 else 293 else
294 assert(0); 294 assert(0);
295 return new DComplexValue(type, c, c); 295 res = DtoAggrPair(DtoType(type), c, c);
296 } 296 }
297 297 else {
298 return new DComplexValue(type, c->getOperand(0), c->getOperand(1)); 298 res = DtoAggrPair(DtoType(type), c->getOperand(0), c->getOperand(1));
299 }
300
301 return new DImValue(type, res);
299 } 302 }
300 303
301 ////////////////////////////////////////////////////////////////////////////////////////// 304 //////////////////////////////////////////////////////////////////////////////////////////
302 305
303 LLConstant* ComplexExp::toConstElem(IRState* p) 306 LLConstant* ComplexExp::toConstElem(IRState* p)
358 361
359 if (dtype->ty == Tarray) { 362 if (dtype->ty == Tarray) {
360 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); 363 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false);
361 LLValue* tmpmem = DtoAlloca(DtoType(dtype),"tempstring"); 364 LLValue* tmpmem = DtoAlloca(DtoType(dtype),"tempstring");
362 DtoSetArray(tmpmem, clen, arrptr); 365 DtoSetArray(tmpmem, clen, arrptr);
363 return new DVarValue(type, tmpmem, true); 366 return new DVarValue(type, tmpmem);
364 } 367 }
365 else if (dtype->ty == Tsarray) { 368 else if (dtype->ty == Tsarray) {
366 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); 369 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
367 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); 370 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
368 return new DVarValue(type, emem, true); 371 return new DVarValue(type, emem);
369 } 372 }
370 else if (dtype->ty == Tpointer) { 373 else if (dtype->ty == Tpointer) {
371 return new DImValue(type, arrptr); 374 return new DImValue(type, arrptr);
372 } 375 }
373 376
454 if (e1->op == TOKarraylength) 457 if (e1->op == TOKarraylength)
455 { 458 {
456 Logger::println("performing array.length assignment"); 459 Logger::println("performing array.length assignment");
457 ArrayLengthExp *ale = (ArrayLengthExp *)e1; 460 ArrayLengthExp *ale = (ArrayLengthExp *)e1;
458 DValue* arr = ale->e1->toElem(p); 461 DValue* arr = ale->e1->toElem(p);
459 DVarValue arrval(ale->e1->type, arr->getLVal(), true); 462 DVarValue arrval(ale->e1->type, arr->getLVal());
460 DValue* newlen = e2->toElem(p); 463 DValue* newlen = e2->toElem(p);
461 DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen); 464 DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen);
462 DtoAssign(loc, &arrval, slice); 465 DtoAssign(loc, &arrval, slice);
463 return newlen; 466 return newlen;
464 } 467 }
467 470
468 DValue* l = e1->toElem(p); 471 DValue* l = e1->toElem(p);
469 DValue* r = e2->toElem(p); 472 DValue* r = e2->toElem(p);
470 DtoAssign(loc, l, r); 473 DtoAssign(loc, l, r);
471 474
472 if (l->isSlice() || l->isComplex()) 475 if (l->isSlice())
473 return l; 476 return l;
474 477
475 #if 0 478 #if 0
476 if (type->toBasetype()->ty == Tstruct && e2->type->isintegral()) 479 if (type->toBasetype()->ty == Tstruct && e2->type->isintegral())
477 { 480 {
501 Type* e1type = e1->type->toBasetype(); 504 Type* e1type = e1->type->toBasetype();
502 Type* e1next = e1type->next ? e1type->next->toBasetype() : NULL; 505 Type* e1next = e1type->next ? e1type->next->toBasetype() : NULL;
503 Type* e2type = e2->type->toBasetype(); 506 Type* e2type = e2->type->toBasetype();
504 507
505 if (e1type != e2type) { 508 if (e1type != e2type) {
506 if (llvmFieldIndex) { 509 /*if (llvmFieldIndex) {
507 assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct); 510 assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct);
508 Logger::println("add to AddrExp of struct"); 511 Logger::println("add to AddrExp of struct");
509 assert(r->isConst()); 512 assert(r->isConst());
510 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c); 513 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
511 514
512 TypeStruct* ts = (TypeStruct*)e1next; 515 TypeStruct* ts = (TypeStruct*)e1next;
513 DStructIndexVector offsets; 516 DStructIndexVector offsets;
514 LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); 517 LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets);
515 return new DFieldValue(type, v, true); 518 return new DFieldValue(type, v);
516 } 519 }
517 else if (e1type->ty == Tpointer) { 520 else*/ if (e1type->ty == Tpointer) {
518 Logger::println("add to pointer"); 521 Logger::println("add to pointer");
519 if (r->isConst()) { 522 if (r->isConst()) {
520 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c); 523 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
521 if (cofs->isZero()) { 524 if (cofs->isZero()) {
522 Logger::println("is zero"); 525 Logger::println("is zero");
846 else if (DImValue* im = v->isIm()) { 849 else if (DImValue* im = v->isIm()) {
847 Logger::println("is immediate"); 850 Logger::println("is immediate");
848 return v; 851 return v;
849 } 852 }
850 Logger::println("is nothing special"); 853 Logger::println("is nothing special");
851 return new DFieldValue(type, v->getLVal(), false); 854 LLValue* lval = v->getLVal();
855 Logger::cout() << "lval: " << *lval << '\n';
856 return new DImValue(type, v->getLVal());
852 } 857 }
853 858
854 LLConstant* AddrExp::toConstElem(IRState* p) 859 LLConstant* AddrExp::toConstElem(IRState* p)
855 { 860 {
856 assert(e1->op == TOKvar); 861 assert(e1->op == TOKvar);
891 Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars()); 896 Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars());
892 LOG_SCOPE; 897 LOG_SCOPE;
893 898
894 DValue* a = e1->toElem(p); 899 DValue* a = e1->toElem(p);
895 900
896 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! 901 // this is *so* ugly.. I'd really like to figure out some way to avoid this badness...
897 LLValue* lv = a->getRVal(); 902 LLValue* lv = a->getRVal();
898 LLValue* v = lv; 903 LLValue* v = lv;
899 if (DtoCanLoad(v)) 904
905 Type* bt = type->toBasetype();
906
907 // we can't load function pointers, but they aren't passed by reference either
908 // FIXME: maybe a MayLoad function isn't a bad idea after all ...
909 if (!DtoIsPassedByRef(bt) && bt->ty != Tfunction)
900 v = DtoLoad(v); 910 v = DtoLoad(v);
901 return new DLRValue(new DVarValue(type, lv, true), new DImValue(type, v)); 911
912 return new DLRValue(new DVarValue(type, lv), new DImValue(type, v));
902 } 913 }
903 914
904 ////////////////////////////////////////////////////////////////////////////////////////// 915 //////////////////////////////////////////////////////////////////////////////////////////
905 916
906 DValue* DotVarExp::toElem(IRState* p) 917 DValue* DotVarExp::toElem(IRState* p)
949 } 960 }
950 else 961 else
951 assert(0); 962 assert(0);
952 963
953 //Logger::cout() << "mem: " << *arrptr << '\n'; 964 //Logger::cout() << "mem: " << *arrptr << '\n';
954 return new DVarValue(type, vd, arrptr, true); 965 return new DVarValue(type, vd, arrptr);
955 } 966 }
956 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) 967 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
957 { 968 {
958 DtoResolveDsymbol(fdecl); 969 DtoResolveDsymbol(fdecl);
959 970
1019 // FIXME: check for TOKthis in AssertExp instead 1030 // FIXME: check for TOKthis in AssertExp instead
1020 if (!var) 1031 if (!var)
1021 { 1032 {
1022 LLValue* v = p->func()->thisArg; 1033 LLValue* v = p->func()->thisArg;
1023 assert(v); 1034 assert(v);
1024 return new DVarValue(type, v, true); 1035 return new DVarValue(type, v);
1025 } 1036 }
1026 // regular this expr 1037 // regular this expr
1027 else if (VarDeclaration* vd = var->isVarDeclaration()) { 1038 else if (VarDeclaration* vd = var->isVarDeclaration()) {
1028 LLValue* v; 1039 LLValue* v;
1029 if (vd->toParent2() != p->func()->decl) { 1040 if (vd->toParent2() != p->func()->decl) {
1032 } 1043 }
1033 else { 1044 else {
1034 Logger::println("normal this exp"); 1045 Logger::println("normal this exp");
1035 v = p->func()->thisArg; 1046 v = p->func()->thisArg;
1036 } 1047 }
1037 return new DVarValue(type, vd, v, true); 1048 return new DVarValue(type, vd, v);
1038 } 1049 }
1039 1050
1040 // anything we're not yet handling ? 1051 // anything we're not yet handling ?
1041 assert(0); 1052 assert(0);
1042 return 0; 1053 return 0;
1080 } 1091 }
1081 else { 1092 else {
1082 Logger::println("invalid index exp! e1type: %s", e1type->toChars()); 1093 Logger::println("invalid index exp! e1type: %s", e1type->toChars());
1083 assert(0); 1094 assert(0);
1084 } 1095 }
1085 return new DVarValue(type, arrptr, true); 1096 return new DVarValue(type, arrptr);
1086 } 1097 }
1087 1098
1088 ////////////////////////////////////////////////////////////////////////////////////////// 1099 //////////////////////////////////////////////////////////////////////////////////////////
1089 1100
1090 DValue* SliceExp::toElem(IRState* p) 1101 DValue* SliceExp::toElem(IRState* p)
1477 // new basic type 1488 // new basic type
1478 else 1489 else
1479 { 1490 {
1480 // allocate 1491 // allocate
1481 LLValue* mem = DtoNew(newtype); 1492 LLValue* mem = DtoNew(newtype);
1482 DVarValue tmpvar(newtype, mem, true); 1493 DVarValue tmpvar(newtype, mem);
1483 1494
1484 // default initialize 1495 // default initialize
1485 Expression* exp = newtype->defaultInit(loc); 1496 Expression* exp = newtype->defaultInit(loc);
1486 DValue* iv = exp->toElem(gIR); 1497 DValue* iv = exp->toElem(gIR);
1487 DtoAssign(loc, &tmpvar, iv); 1498 DtoAssign(loc, &tmpvar, iv);
1506 // simple pointer 1517 // simple pointer
1507 if (et->ty == Tpointer) 1518 if (et->ty == Tpointer)
1508 { 1519 {
1509 LLValue* rval = dval->getRVal(); 1520 LLValue* rval = dval->getRVal();
1510 DtoDeleteMemory(rval); 1521 DtoDeleteMemory(rval);
1511 if (dval->isVar() && dval->isVar()->lval) 1522 if (dval->isVar())
1512 DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal()); 1523 DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal());
1513 } 1524 }
1514 // class 1525 // class
1515 else if (et->ty == Tclass) 1526 else if (et->ty == Tclass)
1516 { 1527 {
1529 } 1540 }
1530 if (!onstack) { 1541 if (!onstack) {
1531 LLValue* rval = dval->getRVal(); 1542 LLValue* rval = dval->getRVal();
1532 DtoDeleteClass(rval); 1543 DtoDeleteClass(rval);
1533 } 1544 }
1534 if (dval->isVar() && dval->isVar()->lval) { 1545 if (dval->isVar()) {
1535 LLValue* lval = dval->getLVal(); 1546 LLValue* lval = dval->getLVal();
1536 DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval); 1547 DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval);
1537 } 1548 }
1538 } 1549 }
1539 // dyn array 1550 // dyn array
1955 const LLType* resty = DtoType(dtype); 1966 const LLType* resty = DtoType(dtype);
1956 1967
1957 // allocate a temporary for the final result. failed to come up with a better way :/ 1968 // allocate a temporary for the final result. failed to come up with a better way :/
1958 llvm::BasicBlock* entryblock = &p->topfunc()->front(); 1969 llvm::BasicBlock* entryblock = &p->topfunc()->front();
1959 LLValue* resval = DtoAlloca(resty,"condtmp"); 1970 LLValue* resval = DtoAlloca(resty,"condtmp");
1960 DVarValue* dvv = new DVarValue(type, resval, true); 1971 DVarValue* dvv = new DVarValue(type, resval);
1961 1972
1962 llvm::BasicBlock* oldend = p->scopeend(); 1973 llvm::BasicBlock* oldend = p->scopeend();
1963 llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend); 1974 llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend);
1964 llvm::BasicBlock* condfalse = llvm::BasicBlock::Create("condfalse", gIR->topfunc(), oldend); 1975 llvm::BasicBlock* condfalse = llvm::BasicBlock::Create("condfalse", gIR->topfunc(), oldend);
1965 llvm::BasicBlock* condend = llvm::BasicBlock::Create("condend", gIR->topfunc(), oldend); 1976 llvm::BasicBlock* condend = llvm::BasicBlock::Create("condend", gIR->topfunc(), oldend);
2113 fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); 2124 fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
2114 2125
2115 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); 2126 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
2116 DtoStore(castfptr, fptr); 2127 DtoStore(castfptr, fptr);
2117 2128
2118 return new DVarValue(type, lval, true); 2129 return new DVarValue(type, lval);
2119 2130
2120 } else if(fd->tok == TOKfunction) { 2131 } else if(fd->tok == TOKfunction) {
2121 return new DVarValue(type, fd->ir.irFunc->func, false); 2132 return new DImValue(type, fd->ir.irFunc->func);
2122 } 2133 }
2123 2134
2124 assert(0 && "fd->tok must be TOKfunction or TOKdelegate"); 2135 assert(0 && "fd->tok must be TOKfunction or TOKdelegate");
2125 } 2136 }
2126 2137
2157 { 2168 {
2158 Expression* expr = (Expression*)elements->data[i]; 2169 Expression* expr = (Expression*)elements->data[i];
2159 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); 2170 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb());
2160 2171
2161 // emulate assignment 2172 // emulate assignment
2162 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); 2173 DVarValue* vv = new DVarValue(expr->type, elemAddr);
2163 DValue* e = expr->toElem(p); 2174 DValue* e = expr->toElem(p);
2164 DtoAssign(loc, vv, e); 2175 DtoAssign(loc, vv, e);
2165 } 2176 }
2166 2177
2167 // return storage directly ? 2178 // return storage directly ?
2246 Expression* vx = (Expression*)elements->data[i]; 2257 Expression* vx = (Expression*)elements->data[i];
2247 if (!vx) continue; 2258 if (!vx) continue;
2248 2259
2249 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; 2260 Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
2250 LLValue* arrptr = DtoGEPi(sptr,0,j); 2261 LLValue* arrptr = DtoGEPi(sptr,0,j);
2251 DValue* darrptr = new DVarValue(vx->type, arrptr, true); 2262 DValue* darrptr = new DVarValue(vx->type, arrptr);
2252 2263
2253 DValue* ve = vx->toElem(p); 2264 DValue* ve = vx->toElem(p);
2254 DtoAssign(loc, darrptr, ve); 2265 DtoAssign(loc, darrptr, ve);
2255 2266
2256 j++; 2267 j++;
2322 Type* vtype = aatype->next; 2333 Type* vtype = aatype->next;
2323 const LLType* aalltype = DtoType(type); 2334 const LLType* aalltype = DtoType(type);
2324 2335
2325 // it should be possible to avoid the temporary in some cases 2336 // it should be possible to avoid the temporary in some cases
2326 LLValue* tmp = DtoAlloca(aalltype,"aaliteral"); 2337 LLValue* tmp = DtoAlloca(aalltype,"aaliteral");
2327 DValue* aa = new DVarValue(type, tmp, true); 2338 DValue* aa = new DVarValue(type, tmp);
2328 DtoStore(LLConstant::getNullValue(aalltype), tmp); 2339 DtoStore(LLConstant::getNullValue(aalltype), tmp);
2329 2340
2330 const size_t n = keys->dim; 2341 const size_t n = keys->dim;
2331 for (size_t i=0; i<n; ++i) 2342 for (size_t i=0; i<n; ++i)
2332 { 2343 {