Mercurial > projects > ldc
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 { |