Mercurial > projects > ldc
comparison gen/toir.cpp @ 486:a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Reimplemented support for nested functions/class using a new approach.
Added error on taking address of intrinsic.
Fixed problems with the ->syntaxCopy of TypeFunction delegate exp.
Removed DtoDType and replaced all uses with ->toBasetype() instead.
Removed unused inplace stuff.
Fixed a bunch of issues in the runtime unittests, not complete yet.
Added mini tests.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 10 Aug 2008 08:37:38 +0200 |
parents | 50f6e2337a6b |
children | d7b2e8777e2b |
comparison
equal
deleted
inserted
replaced
485:50f6e2337a6b | 486:a34078905d01 |
---|---|
104 return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true); | 104 return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true); |
105 } | 105 } |
106 // nested variable | 106 // nested variable |
107 else if (vd->nestedref) { | 107 else if (vd->nestedref) { |
108 Logger::println("nested variable"); | 108 Logger::println("nested variable"); |
109 return DtoNestedVariable(type, vd); | 109 return DtoNestedVariable(loc, type, vd); |
110 } | 110 } |
111 // function parameter | 111 // function parameter |
112 else if (vd->isParameter()) { | 112 else if (vd->isParameter()) { |
113 Logger::println("function param"); | 113 Logger::println("function param"); |
114 FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration(); | 114 FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration(); |
115 if (fd && fd != p->func()->decl) { | 115 if (fd && fd != p->func()->decl) { |
116 Logger::println("nested parameter"); | 116 Logger::println("nested parameter"); |
117 return DtoNestedVariable(type, vd); | 117 return DtoNestedVariable(loc, type, vd); |
118 } | 118 } |
119 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) { | 119 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); | 120 return new DVarValue(type, vd, vd->ir.getIrValue(), true); |
121 } | 121 } |
122 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) { | 122 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) { |
149 return new DFuncValue(fdecl, func); | 149 return new DFuncValue(fdecl, func); |
150 } | 150 } |
151 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 151 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
152 { | 152 { |
153 // this seems to be the static initialiser for structs | 153 // this seems to be the static initialiser for structs |
154 Type* sdecltype = DtoDType(sdecl->type); | 154 Type* sdecltype = sdecl->type->toBasetype(); |
155 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | 155 Logger::print("Sym: type=%s\n", sdecltype->toChars()); |
156 assert(sdecltype->ty == Tstruct); | 156 assert(sdecltype->ty == Tstruct); |
157 TypeStruct* ts = (TypeStruct*)sdecltype; | 157 TypeStruct* ts = (TypeStruct*)sdecltype; |
158 assert(ts->sym); | 158 assert(ts->sym); |
159 DtoForceConstInitDsymbol(ts->sym); | 159 DtoForceConstInitDsymbol(ts->sym); |
175 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 175 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
176 LOG_SCOPE; | 176 LOG_SCOPE; |
177 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 177 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
178 { | 178 { |
179 // this seems to be the static initialiser for structs | 179 // this seems to be the static initialiser for structs |
180 Type* sdecltype = DtoDType(sdecl->type); | 180 Type* sdecltype = sdecl->type->toBasetype(); |
181 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | 181 Logger::print("Sym: type=%s\n", sdecltype->toChars()); |
182 assert(sdecltype->ty == Tstruct); | 182 assert(sdecltype->ty == Tstruct); |
183 TypeStruct* ts = (TypeStruct*)sdecltype; | 183 TypeStruct* ts = (TypeStruct*)sdecltype; |
184 DtoForceConstInitDsymbol(ts->sym); | 184 DtoForceConstInitDsymbol(ts->sym); |
185 assert(ts->sym->ir.irStruct->constInit); | 185 assert(ts->sym->ir.irStruct->constInit); |
240 | 240 |
241 LLConstant* RealExp::toConstElem(IRState* p) | 241 LLConstant* RealExp::toConstElem(IRState* p) |
242 { | 242 { |
243 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 243 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
244 LOG_SCOPE; | 244 LOG_SCOPE; |
245 Type* t = DtoDType(type); | 245 Type* t = type->toBasetype(); |
246 return DtoConstFP(t, value); | 246 return DtoConstFP(t, value); |
247 } | 247 } |
248 | 248 |
249 ////////////////////////////////////////////////////////////////////////////////////////// | 249 ////////////////////////////////////////////////////////////////////////////////////////// |
250 | 250 |
281 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); | 281 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); |
282 LOG_SCOPE; | 282 LOG_SCOPE; |
283 LLConstant* c = toConstElem(p); | 283 LLConstant* c = toConstElem(p); |
284 | 284 |
285 if (c->isNullValue()) { | 285 if (c->isNullValue()) { |
286 Type* t = DtoDType(type); | 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); |
289 else if (t->ty == Tcomplex64) | 289 else if (t->ty == Tcomplex64) |
290 c = DtoConstFP(Type::tfloat64, 0); | 290 c = DtoConstFP(Type::tfloat64, 0); |
291 else if (t->ty == Tcomplex80) | 291 else if (t->ty == Tcomplex80) |
312 DValue* StringExp::toElem(IRState* p) | 312 DValue* StringExp::toElem(IRState* p) |
313 { | 313 { |
314 Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars()); | 314 Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars()); |
315 LOG_SCOPE; | 315 LOG_SCOPE; |
316 | 316 |
317 Type* dtype = DtoDType(type); | 317 Type* dtype = type->toBasetype(); |
318 Type* cty = DtoDType(dtype->next); | 318 Type* cty = dtype->next->toBasetype(); |
319 | 319 |
320 const LLType* ct = DtoTypeNotVoid(cty); | 320 const LLType* ct = DtoTypeNotVoid(cty); |
321 //printf("ct = %s\n", type->next->toChars()); | 321 //printf("ct = %s\n", type->next->toChars()); |
322 const LLArrayType* at = LLArrayType::get(ct,len+1); | 322 const LLArrayType* at = LLArrayType::get(ct,len+1); |
323 | 323 |
380 LLConstant* StringExp::toConstElem(IRState* p) | 380 LLConstant* StringExp::toConstElem(IRState* p) |
381 { | 381 { |
382 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 382 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
383 LOG_SCOPE; | 383 LOG_SCOPE; |
384 | 384 |
385 Type* t = DtoDType(type); | 385 Type* t = type->toBasetype(); |
386 Type* cty = DtoDType(t->next); | 386 Type* cty = t->next->toBasetype(); |
387 | 387 |
388 bool nullterm = (t->ty != Tsarray); | 388 bool nullterm = (t->ty != Tsarray); |
389 size_t endlen = nullterm ? len+1 : len; | 389 size_t endlen = nullterm ? len+1 : len; |
390 | 390 |
391 const LLType* ct = DtoType(cty); | 391 const LLType* ct = DtoType(cty); |
470 DtoAssign(loc, l, r); | 470 DtoAssign(loc, l, r); |
471 | 471 |
472 if (l->isSlice() || l->isComplex()) | 472 if (l->isSlice() || l->isComplex()) |
473 return l; | 473 return l; |
474 | 474 |
475 #if 0 | |
476 if (type->toBasetype()->ty == Tstruct && e2->type->isintegral()) | |
477 { | |
478 // handle struct = 0; | |
479 return l; | |
480 } | |
481 else | |
482 { | |
483 return r; | |
484 } | |
485 #else | |
475 return r; | 486 return r; |
487 #endif | |
476 } | 488 } |
477 | 489 |
478 ////////////////////////////////////////////////////////////////////////////////////////// | 490 ////////////////////////////////////////////////////////////////////////////////////////// |
479 | 491 |
480 DValue* AddExp::toElem(IRState* p) | 492 DValue* AddExp::toElem(IRState* p) |
483 LOG_SCOPE; | 495 LOG_SCOPE; |
484 | 496 |
485 DValue* l = e1->toElem(p); | 497 DValue* l = e1->toElem(p); |
486 DValue* r = e2->toElem(p); | 498 DValue* r = e2->toElem(p); |
487 | 499 |
488 Type* t = DtoDType(type); | 500 Type* t = type->toBasetype(); |
489 Type* e1type = DtoDType(e1->type); | 501 Type* e1type = e1->type->toBasetype(); |
490 Type* e1next = e1type->next ? DtoDType(e1type->next) : NULL; | 502 Type* e1next = e1type->next ? e1type->next->toBasetype() : NULL; |
491 Type* e2type = DtoDType(e2->type); | 503 Type* e2type = e2->type->toBasetype(); |
492 | 504 |
493 if (e1type != e2type) { | 505 if (e1type != e2type) { |
494 if (llvmFieldIndex) { | 506 if (llvmFieldIndex) { |
495 assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct); | 507 assert(e1type->ty == Tpointer && e1next && e1next->ty == Tstruct); |
496 Logger::println("add to AddrExp of struct"); | 508 Logger::println("add to AddrExp of struct"); |
535 LOG_SCOPE; | 547 LOG_SCOPE; |
536 | 548 |
537 DValue* l = e1->toElem(p); | 549 DValue* l = e1->toElem(p); |
538 DValue* r = e2->toElem(p); | 550 DValue* r = e2->toElem(p); |
539 | 551 |
540 Type* t = DtoDType(type); | 552 Type* t = type->toBasetype(); |
541 | 553 |
542 DValue* res; | 554 DValue* res; |
543 if (DtoDType(e1->type)->ty == Tpointer) { | 555 if (e1->type->toBasetype()->ty == Tpointer) { |
544 LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); | 556 LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); |
545 res = new DImValue(type, gep); | 557 res = new DImValue(type, gep); |
546 } | 558 } |
547 else if (t->iscomplex()) { | 559 else if (t->iscomplex()) { |
548 res = DtoComplexAdd(loc, e1->type, l, r); | 560 res = DtoComplexAdd(loc, e1->type, l, r); |
563 LOG_SCOPE; | 575 LOG_SCOPE; |
564 | 576 |
565 DValue* l = e1->toElem(p); | 577 DValue* l = e1->toElem(p); |
566 DValue* r = e2->toElem(p); | 578 DValue* r = e2->toElem(p); |
567 | 579 |
568 Type* t = DtoDType(type); | 580 Type* t = type->toBasetype(); |
569 Type* t1 = DtoDType(e1->type); | 581 Type* t1 = e1->type->toBasetype(); |
570 Type* t2 = DtoDType(e2->type); | 582 Type* t2 = e2->type->toBasetype(); |
571 | 583 |
572 if (t1->ty == Tpointer && t2->ty == Tpointer) { | 584 if (t1->ty == Tpointer && t2->ty == Tpointer) { |
573 LLValue* lv = l->getRVal(); | 585 LLValue* lv = l->getRVal(); |
574 LLValue* rv = r->getRVal(); | 586 LLValue* rv = r->getRVal(); |
575 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n'; | 587 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n'; |
601 LOG_SCOPE; | 613 LOG_SCOPE; |
602 | 614 |
603 DValue* l = e1->toElem(p); | 615 DValue* l = e1->toElem(p); |
604 DValue* r = e2->toElem(p); | 616 DValue* r = e2->toElem(p); |
605 | 617 |
606 Type* t = DtoDType(type); | 618 Type* t = type->toBasetype(); |
607 | 619 |
608 DValue* res; | 620 DValue* res; |
609 if (DtoDType(e1->type)->ty == Tpointer) { | 621 if (e1->type->toBasetype()->ty == Tpointer) { |
610 Logger::println("ptr"); | 622 Logger::println("ptr"); |
611 LLValue* tmp = r->getRVal(); | 623 LLValue* tmp = r->getRVal(); |
612 LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false); | 624 LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false); |
613 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); | 625 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); |
614 tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb()); | 626 tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb()); |
768 else if (fndecl->llvmInternal == LLVMalloca) { | 780 else if (fndecl->llvmInternal == LLVMalloca) { |
769 Expression* exp = (Expression*)arguments->data[0]; | 781 Expression* exp = (Expression*)arguments->data[0]; |
770 DValue* expv = exp->toElem(p); | 782 DValue* expv = exp->toElem(p); |
771 if (expv->getType()->toBasetype()->ty != Tint32) | 783 if (expv->getType()->toBasetype()->ty != Tint32) |
772 expv = DtoCast(loc, expv, Type::tint32); | 784 expv = DtoCast(loc, expv, Type::tint32); |
773 return new DImValue(type, DtoAlloca(LLType::Int8Ty, expv->getRVal(), ".alloca")); | 785 return new DImValue(type, p->ir->CreateAlloca(LLType::Int8Ty, expv->getRVal(), ".alloca")); |
774 } | 786 } |
775 } | 787 } |
776 | 788 |
777 return DtoCallFunction(loc, type, fnval, arguments); | 789 return DtoCallFunction(loc, type, fnval, arguments); |
778 } | 790 } |
842 LLConstant* AddrExp::toConstElem(IRState* p) | 854 LLConstant* AddrExp::toConstElem(IRState* p) |
843 { | 855 { |
844 assert(e1->op == TOKvar); | 856 assert(e1->op == TOKvar); |
845 VarExp* vexp = (VarExp*)e1; | 857 VarExp* vexp = (VarExp*)e1; |
846 | 858 |
859 if (vexp->var->needThis()) | |
860 { | |
861 error("need 'this' to access %s", vexp->var->toChars()); | |
862 fatal(); | |
863 } | |
864 | |
847 // global variable | 865 // global variable |
848 if (VarDeclaration* vd = vexp->var->isVarDeclaration()) | 866 if (VarDeclaration* vd = vexp->var->isVarDeclaration()) |
849 { | 867 { |
850 LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); | 868 LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); |
851 assert(llc); | 869 assert(llc); |
890 Logger::print("DotVarExp::toElem: %s | %s\n", toChars(), type->toChars()); | 908 Logger::print("DotVarExp::toElem: %s | %s\n", toChars(), type->toChars()); |
891 LOG_SCOPE; | 909 LOG_SCOPE; |
892 | 910 |
893 DValue* l = e1->toElem(p); | 911 DValue* l = e1->toElem(p); |
894 | 912 |
895 Type* t = DtoDType(type); | 913 Type* t = type->toBasetype(); |
896 Type* e1type = DtoDType(e1->type); | 914 Type* e1type = e1->type->toBasetype(); |
897 | 915 |
898 //Logger::println("e1type=%s", e1type->toChars()); | 916 //Logger::println("e1type=%s", e1type->toChars()); |
899 //Logger::cout() << *DtoType(e1type) << '\n'; | 917 //Logger::cout() << *DtoType(e1type) << '\n'; |
900 | 918 |
901 if (VarDeclaration* vd = var->isVarDeclaration()) { | 919 if (VarDeclaration* vd = var->isVarDeclaration()) { |
902 LLValue* arrptr; | 920 LLValue* arrptr; |
903 if (e1type->ty == Tpointer) { | 921 if (e1type->ty == Tpointer) { |
904 assert(e1type->next->ty == Tstruct); | 922 assert(e1type->next->ty == Tstruct); |
905 TypeStruct* ts = (TypeStruct*)e1type->next; | 923 TypeStruct* ts = (TypeStruct*)e1type->next; |
924 Logger::println("Struct member offset:%d", vd->offset); | |
925 | |
926 LLValue* src = l->getRVal(); | |
927 | |
928 DStructIndexVector vdoffsets; | |
929 arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); | |
930 } | |
931 // happens for tuples | |
932 else if (e1type->ty == Tstruct) { | |
933 TypeStruct* ts = (TypeStruct*)e1type; | |
906 Logger::println("Struct member offset:%d", vd->offset); | 934 Logger::println("Struct member offset:%d", vd->offset); |
907 | 935 |
908 LLValue* src = l->getRVal(); | 936 LLValue* src = l->getRVal(); |
909 | 937 |
910 DStructIndexVector vdoffsets; | 938 DStructIndexVector vdoffsets; |
951 assert(fdecl->vtblIndex > 0); | 979 assert(fdecl->vtblIndex > 0); |
952 assert(e1type->ty == Tclass); | 980 assert(e1type->ty == Tclass); |
953 | 981 |
954 LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); | 982 LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); |
955 LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); | 983 LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); |
956 //Logger::cout() << "vthis: " << *vthis << '\n'; | 984 Logger::cout() << "vthis: " << *vthis << '\n'; |
957 funcval = DtoGEP(vthis, zero, zero); | 985 funcval = DtoGEP(vthis, zero, zero); |
958 funcval = DtoLoad(funcval); | 986 funcval = DtoLoad(funcval); |
959 funcval = DtoGEP(funcval, zero, vtblidx, toChars()); | 987 funcval = DtoGEP(funcval, zero, vtblidx, toChars()); |
960 funcval = DtoLoad(funcval); | 988 funcval = DtoLoad(funcval); |
961 #if OPAQUE_VTBLS | 989 #if OPAQUE_VTBLS |
989 // this seems to happen for dmd generated assert statements like: | 1017 // this seems to happen for dmd generated assert statements like: |
990 // assert(this, "null this"); | 1018 // assert(this, "null this"); |
991 // FIXME: check for TOKthis in AssertExp instead | 1019 // FIXME: check for TOKthis in AssertExp instead |
992 if (!var) | 1020 if (!var) |
993 { | 1021 { |
994 LLValue* v = p->func()->thisVar; | 1022 LLValue* v = p->func()->thisArg; |
995 assert(v); | 1023 assert(v); |
996 return new DVarValue(type, v, true); | 1024 return new DVarValue(type, v, true); |
997 } | 1025 } |
998 // regular this expr | 1026 // regular this expr |
999 else if (VarDeclaration* vd = var->isVarDeclaration()) { | 1027 else if (VarDeclaration* vd = var->isVarDeclaration()) { |
1000 LLValue* v; | 1028 LLValue* v; |
1001 if (vd->toParent2() != p->func()->decl) { | 1029 if (vd->toParent2() != p->func()->decl) { |
1002 Logger::println("nested this exp"); | 1030 Logger::println("nested this exp"); |
1003 return DtoNestedVariable(type, vd); | 1031 return DtoNestedVariable(loc, type, vd); |
1004 } | 1032 } |
1005 else { | 1033 else { |
1006 Logger::println("normal this exp"); | 1034 Logger::println("normal this exp"); |
1007 v = p->func()->decl->ir.irFunc->thisVar; | 1035 v = p->func()->thisArg; |
1008 } | 1036 } |
1009 return new DVarValue(type, vd, v, true); | 1037 return new DVarValue(type, vd, v, true); |
1010 } | 1038 } |
1011 | 1039 |
1012 // anything we're not yet handling ? | 1040 // anything we're not yet handling ? |
1021 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1049 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1022 LOG_SCOPE; | 1050 LOG_SCOPE; |
1023 | 1051 |
1024 DValue* l = e1->toElem(p); | 1052 DValue* l = e1->toElem(p); |
1025 | 1053 |
1026 Type* e1type = DtoDType(e1->type); | 1054 Type* e1type = e1->type->toBasetype(); |
1027 | 1055 |
1028 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. | 1056 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. |
1029 DValue* r = e2->toElem(p); | 1057 DValue* r = e2->toElem(p); |
1030 p->arrays.pop_back(); | 1058 p->arrays.pop_back(); |
1031 | 1059 |
1139 LOG_SCOPE; | 1167 LOG_SCOPE; |
1140 | 1168 |
1141 DValue* l = e1->toElem(p); | 1169 DValue* l = e1->toElem(p); |
1142 DValue* r = e2->toElem(p); | 1170 DValue* r = e2->toElem(p); |
1143 | 1171 |
1144 Type* t = DtoDType(e1->type); | 1172 Type* t = e1->type->toBasetype(); |
1145 Type* e2t = DtoDType(e2->type); | 1173 Type* e2t = e2->type->toBasetype(); |
1146 assert(DtoType(t) == DtoType(e2t)); | 1174 assert(DtoType(t) == DtoType(e2t)); |
1147 | 1175 |
1148 LLValue* eval = 0; | 1176 LLValue* eval = 0; |
1149 | 1177 |
1150 if (t->isintegral() || t->ty == Tpointer) | 1178 if (t->isintegral() || t->ty == Tpointer) |
1252 LOG_SCOPE; | 1280 LOG_SCOPE; |
1253 | 1281 |
1254 DValue* l = e1->toElem(p); | 1282 DValue* l = e1->toElem(p); |
1255 DValue* r = e2->toElem(p); | 1283 DValue* r = e2->toElem(p); |
1256 | 1284 |
1257 Type* t = DtoDType(e1->type); | 1285 Type* t = e1->type->toBasetype(); |
1258 Type* e2t = DtoDType(e2->type); | 1286 Type* e2t = e2->type->toBasetype(); |
1259 //assert(t == e2t); | 1287 //assert(t == e2t); |
1260 | 1288 |
1261 LLValue* eval = 0; | 1289 LLValue* eval = 0; |
1262 | 1290 |
1263 if (t->isintegral() || t->ty == Tpointer) | 1291 if (t->isintegral() || t->ty == Tpointer) |
1339 DValue* r = e2->toElem(p); | 1367 DValue* r = e2->toElem(p); |
1340 | 1368 |
1341 LLValue* val = l->getRVal(); | 1369 LLValue* val = l->getRVal(); |
1342 LLValue* post = 0; | 1370 LLValue* post = 0; |
1343 | 1371 |
1344 Type* e1type = DtoDType(e1->type); | 1372 Type* e1type = e1->type->toBasetype(); |
1345 Type* e2type = DtoDType(e2->type); | 1373 Type* e2type = e2->type->toBasetype(); |
1346 | 1374 |
1347 if (e1type->isintegral()) | 1375 if (e1type->isintegral()) |
1348 { | 1376 { |
1349 assert(e2type->isintegral()); | 1377 assert(e2type->isintegral()); |
1350 LLValue* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); | 1378 LLValue* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); |
1377 else | 1405 else |
1378 assert(post); | 1406 assert(post); |
1379 | 1407 |
1380 DtoStore(post,l->getLVal()); | 1408 DtoStore(post,l->getLVal()); |
1381 | 1409 |
1382 return new DImValue(type,val,true); | 1410 return new DImValue(type,val); |
1383 } | 1411 } |
1384 | 1412 |
1385 ////////////////////////////////////////////////////////////////////////////////////////// | 1413 ////////////////////////////////////////////////////////////////////////////////////////// |
1386 | 1414 |
1387 DValue* NewExp::toElem(IRState* p) | 1415 DValue* NewExp::toElem(IRState* p) |
1388 { | 1416 { |
1389 Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1417 Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1390 LOG_SCOPE; | 1418 LOG_SCOPE; |
1391 | 1419 |
1392 assert(newtype); | 1420 assert(newtype); |
1393 Type* ntype = DtoDType(newtype); | 1421 Type* ntype = newtype->toBasetype(); |
1394 | 1422 |
1395 // new class | 1423 // new class |
1396 if (ntype->ty == Tclass) { | 1424 if (ntype->ty == Tclass) { |
1397 Logger::println("new class"); | 1425 Logger::println("new class"); |
1398 return DtoNewClass((TypeClass*)ntype, this); | 1426 return DtoNewClass(loc, (TypeClass*)ntype, this); |
1399 } | 1427 } |
1400 // new dynamic array | 1428 // new dynamic array |
1401 else if (ntype->ty == Tarray) | 1429 else if (ntype->ty == Tarray) |
1402 { | 1430 { |
1403 Logger::println("new dynamic array: %s", newtype->toChars()); | 1431 Logger::println("new dynamic array: %s", newtype->toChars()); |
1437 } | 1465 } |
1438 else { | 1466 else { |
1439 assert(ts->sym); | 1467 assert(ts->sym); |
1440 DtoAggrCopy(mem,ts->sym->ir.irStruct->init); | 1468 DtoAggrCopy(mem,ts->sym->ir.irStruct->init); |
1441 } | 1469 } |
1442 return new DImValue(type, mem, false); | 1470 return new DImValue(type, mem); |
1443 } | 1471 } |
1444 // new basic type | 1472 // new basic type |
1445 else | 1473 else |
1446 { | 1474 { |
1447 // allocate | 1475 // allocate |
1452 Expression* exp = newtype->defaultInit(loc); | 1480 Expression* exp = newtype->defaultInit(loc); |
1453 DValue* iv = exp->toElem(gIR); | 1481 DValue* iv = exp->toElem(gIR); |
1454 DtoAssign(loc, &tmpvar, iv); | 1482 DtoAssign(loc, &tmpvar, iv); |
1455 | 1483 |
1456 // return as pointer-to | 1484 // return as pointer-to |
1457 return new DImValue(type, mem, false); | 1485 return new DImValue(type, mem); |
1458 } | 1486 } |
1459 | 1487 |
1460 assert(0); | 1488 assert(0); |
1461 } | 1489 } |
1462 | 1490 |
1466 { | 1494 { |
1467 Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1495 Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1468 LOG_SCOPE; | 1496 LOG_SCOPE; |
1469 | 1497 |
1470 DValue* dval = e1->toElem(p); | 1498 DValue* dval = e1->toElem(p); |
1471 Type* et = DtoDType(e1->type); | 1499 Type* et = e1->type->toBasetype(); |
1472 | 1500 |
1473 // simple pointer | 1501 // simple pointer |
1474 if (et->ty == Tpointer) | 1502 if (et->ty == Tpointer) |
1475 { | 1503 { |
1476 LLValue* rval = dval->getRVal(); | 1504 LLValue* rval = dval->getRVal(); |
1761 LLValue* lval = DtoAlloca(DtoType(type), "tmpdelegate"); | 1789 LLValue* lval = DtoAlloca(DtoType(type), "tmpdelegate"); |
1762 | 1790 |
1763 DValue* u = e1->toElem(p); | 1791 DValue* u = e1->toElem(p); |
1764 LLValue* uval; | 1792 LLValue* uval; |
1765 if (DFuncValue* f = u->isFunc()) { | 1793 if (DFuncValue* f = u->isFunc()) { |
1766 assert(f->func); | 1794 assert(f->func); |
1767 LLValue* contextptr = DtoNestedContext(f->func->toParent2()->isFuncDeclaration()); | 1795 LLValue* contextptr; |
1768 if (!contextptr) | 1796 if (p->func()->decl == f->func) |
1769 uval = LLConstant::getNullValue(getVoidPtrType()); | 1797 contextptr = p->func()->thisArg; |
1770 else | 1798 else |
1771 uval = DtoBitCast(contextptr, getVoidPtrType()); | 1799 contextptr = DtoNestedContext(loc, f->func); |
1800 uval = DtoBitCast(contextptr, getVoidPtrType()); | |
1772 } | 1801 } |
1773 else { | 1802 else { |
1774 DValue* src = u; | 1803 DValue* src = u; |
1775 if (ClassDeclaration* cd = u->getType()->isClassHandle()) | 1804 if (ClassDeclaration* cd = u->getType()->isClassHandle()) |
1776 { | 1805 { |
1890 DValue* CondExp::toElem(IRState* p) | 1919 DValue* CondExp::toElem(IRState* p) |
1891 { | 1920 { |
1892 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1921 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1893 LOG_SCOPE; | 1922 LOG_SCOPE; |
1894 | 1923 |
1895 Type* dtype = DtoDType(type); | 1924 Type* dtype = type->toBasetype(); |
1896 const LLType* resty = DtoType(dtype); | 1925 const LLType* resty = DtoType(dtype); |
1897 | 1926 |
1898 // allocate a temporary for the final result. failed to come up with a better way :/ | 1927 // allocate a temporary for the final result. failed to come up with a better way :/ |
1899 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 1928 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
1900 LLValue* resval = DtoAlloca(resty,"condtmp"); | 1929 LLValue* resval = DtoAlloca(resty,"condtmp"); |
1951 if (type->iscomplex()) { | 1980 if (type->iscomplex()) { |
1952 return DtoComplexNeg(loc, type, l); | 1981 return DtoComplexNeg(loc, type, l); |
1953 } | 1982 } |
1954 | 1983 |
1955 LLValue* val = l->getRVal(); | 1984 LLValue* val = l->getRVal(); |
1956 Type* t = DtoDType(type); | 1985 Type* t = type->toBasetype(); |
1957 | 1986 |
1958 LLValue* zero = 0; | 1987 LLValue* zero = 0; |
1959 if (t->isintegral()) | 1988 if (t->isintegral()) |
1960 zero = llvm::ConstantInt::get(val->getType(), 0, true); | 1989 zero = llvm::ConstantInt::get(val->getType(), 0, true); |
1961 else if (t->isfloating()) { | 1990 else if (t->isfloating()) { |
1973 DValue* CatExp::toElem(IRState* p) | 2002 DValue* CatExp::toElem(IRState* p) |
1974 { | 2003 { |
1975 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2004 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1976 LOG_SCOPE; | 2005 LOG_SCOPE; |
1977 | 2006 |
1978 Type* t = DtoDType(type); | 2007 Type* t = type->toBasetype(); |
1979 | 2008 |
1980 bool arrNarr = DtoDType(e1->type) == DtoDType(e2->type); | 2009 bool arrNarr = e1->type->toBasetype() == e2->type->toBasetype(); |
1981 | 2010 |
1982 // array ~ array | 2011 // array ~ array |
1983 if (arrNarr) | 2012 if (arrNarr) |
1984 { | 2013 { |
1985 return DtoCatArrays(type, e1, e2); | 2014 return DtoCatArrays(type, e1, e2); |
1999 Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2028 Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2000 LOG_SCOPE; | 2029 LOG_SCOPE; |
2001 | 2030 |
2002 DValue* l = e1->toElem(p); | 2031 DValue* l = e1->toElem(p); |
2003 | 2032 |
2004 Type* e1type = DtoDType(e1->type); | 2033 Type* e1type = e1->type->toBasetype(); |
2005 Type* elemtype = DtoDType(e1type->next); | 2034 Type* elemtype = e1type->next->toBasetype(); |
2006 Type* e2type = DtoDType(e2->type); | 2035 Type* e2type = e2->type->toBasetype(); |
2007 | 2036 |
2008 if (e2type == elemtype) { | 2037 if (e2type == elemtype) { |
2009 DSliceValue* slice = DtoCatAssignElement(l,e2); | 2038 DSliceValue* slice = DtoCatAssignElement(l,e2); |
2010 DtoAssign(loc, l, slice); | 2039 DtoAssign(loc, l, slice); |
2011 } | 2040 } |
2035 | 2064 |
2036 const LLType* dgty = DtoType(type); | 2065 const LLType* dgty = DtoType(type); |
2037 LLValue* lval = DtoAlloca(dgty,"dgstorage"); | 2066 LLValue* lval = DtoAlloca(dgty,"dgstorage"); |
2038 | 2067 |
2039 LLValue* context = DtoGEPi(lval,0,0); | 2068 LLValue* context = DtoGEPi(lval,0,0); |
2040 const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); | 2069 LLValue* cval; |
2041 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; | 2070 IrFunction* irfn = p->func(); |
2042 if (llvmNested == NULL) { | 2071 if (irfn->nestedVar) |
2043 LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); | 2072 cval = irfn->nestedVar; |
2044 DtoStore(nullcontext, context); | 2073 else if (irfn->nestArg) |
2045 } | 2074 cval = irfn->nestArg; |
2046 else { | 2075 else |
2047 LLValue* nestedcontext = DtoBitCast(llvmNested, pty); | 2076 cval = getNullPtr(getVoidPtrType()); |
2048 DtoStore(nestedcontext, context); | 2077 cval = DtoBitCast(cval, context->getType()->getContainedType(0)); |
2049 } | 2078 DtoStore(cval, context); |
2050 | 2079 |
2051 LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); | 2080 LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); |
2052 | 2081 |
2053 assert(fd->ir.irFunc->func); | 2082 assert(fd->ir.irFunc->func); |
2054 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); | 2083 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); |
2055 DtoStore(castfptr, fptr); | 2084 DtoStore(castfptr, fptr); |
2070 | 2099 |
2071 // is dynamic ? | 2100 // is dynamic ? |
2072 bool dyn = (arrayType->ty == Tarray); | 2101 bool dyn = (arrayType->ty == Tarray); |
2073 // length | 2102 // length |
2074 size_t len = elements->dim; | 2103 size_t len = elements->dim; |
2075 // store into slice? | |
2076 bool sliceInPlace = false; | |
2077 | 2104 |
2078 // llvm target type | 2105 // llvm target type |
2079 const LLType* llType = DtoType(arrayType); | 2106 const LLType* llType = DtoType(arrayType); |
2080 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; | 2107 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; |
2081 | 2108 |
2094 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); | 2121 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); |
2095 | 2122 |
2096 // emulate assignment | 2123 // emulate assignment |
2097 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); | 2124 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); |
2098 DValue* e = expr->toElem(p); | 2125 DValue* e = expr->toElem(p); |
2099 DImValue* im = e->isIm(); | 2126 DtoAssign(loc, vv, e); |
2100 if (!im || !im->inPlace()) { | |
2101 DtoAssign(loc, vv, e); | |
2102 } | |
2103 } | 2127 } |
2104 | 2128 |
2105 // return storage directly ? | 2129 // return storage directly ? |
2106 if (!dyn || (dyn && sliceInPlace)) | 2130 if (!dyn) |
2107 return new DImValue(type, dstMem, false); | 2131 return new DImValue(type, dstMem); |
2132 | |
2108 // wrap in a slice | 2133 // wrap in a slice |
2109 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); | 2134 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); |
2110 } | 2135 } |
2111 | 2136 |
2112 ////////////////////////////////////////////////////////////////////////////////////////// | 2137 ////////////////////////////////////////////////////////////////////////////////////////// |
2186 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; | 2211 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; |
2187 LLValue* arrptr = DtoGEPi(sptr,0,j); | 2212 LLValue* arrptr = DtoGEPi(sptr,0,j); |
2188 DValue* darrptr = new DVarValue(vx->type, arrptr, true); | 2213 DValue* darrptr = new DVarValue(vx->type, arrptr, true); |
2189 | 2214 |
2190 DValue* ve = vx->toElem(p); | 2215 DValue* ve = vx->toElem(p); |
2191 | 2216 DtoAssign(loc, darrptr, ve); |
2192 if (!ve->inPlace()) | |
2193 DtoAssign(loc, darrptr, ve); | |
2194 | 2217 |
2195 j++; | 2218 j++; |
2196 } | 2219 } |
2197 | 2220 |
2198 return new DImValue(type, sptr); | 2221 return new DImValue(type, sptr); |
2212 { | 2235 { |
2213 Expression* vx = (Expression*)elements->data[i]; | 2236 Expression* vx = (Expression*)elements->data[i]; |
2214 vals[i] = vx->toConstElem(p); | 2237 vals[i] = vx->toConstElem(p); |
2215 } | 2238 } |
2216 | 2239 |
2217 assert(DtoDType(type)->ty == Tstruct); | 2240 assert(type->toBasetype()->ty == Tstruct); |
2218 const LLType* t = DtoType(type); | 2241 const LLType* t = DtoType(type); |
2219 const LLStructType* st = isaStruct(t); | 2242 const LLStructType* st = isaStruct(t); |
2220 return llvm::ConstantStruct::get(st,vals); | 2243 return llvm::ConstantStruct::get(st,vals); |
2221 } | 2244 } |
2222 | 2245 |
2255 | 2278 |
2256 assert(keys); | 2279 assert(keys); |
2257 assert(values); | 2280 assert(values); |
2258 assert(keys->dim == values->dim); | 2281 assert(keys->dim == values->dim); |
2259 | 2282 |
2260 Type* aatype = DtoDType(type); | 2283 Type* aatype = type->toBasetype(); |
2261 Type* vtype = aatype->next; | 2284 Type* vtype = aatype->next; |
2262 const LLType* aalltype = DtoType(type); | 2285 const LLType* aalltype = DtoType(type); |
2263 | 2286 |
2264 // it should be possible to avoid the temporary in some cases | 2287 // it should be possible to avoid the temporary in some cases |
2265 LLValue* tmp = DtoAlloca(aalltype,"aaliteral"); | 2288 LLValue* tmp = DtoAlloca(aalltype,"aaliteral"); |