Mercurial > projects > ldc
comparison gen/toir.cpp @ 175:c44e6a711885 trunk
[svn r191] Fixed: array literals did not support all type/storage combinations.
Fixed: with expression had broke somewhere along the way.
author | lindquist |
---|---|
date | Wed, 07 May 2008 00:01:13 +0200 |
parents | db9890b3fb64 |
children | a074a5ff709c |
comparison
equal
deleted
inserted
replaced
174:16e676ae5ab4 | 175:c44e6a711885 |
---|---|
2548 DValue* ArrayLiteralExp::toElem(IRState* p) | 2548 DValue* ArrayLiteralExp::toElem(IRState* p) |
2549 { | 2549 { |
2550 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2550 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2551 LOG_SCOPE; | 2551 LOG_SCOPE; |
2552 | 2552 |
2553 Type* ty = DtoDType(type); | 2553 // D types |
2554 const llvm::Type* t = DtoType(ty); | 2554 Type* arrayType = type->toBasetype(); |
2555 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | 2555 Type* elemType = arrayType->nextOf()->toBasetype(); |
2556 | 2556 |
2557 llvm::Value* mem = 0; | 2557 // is dynamic ? |
2558 bool inplace_slice = false; | 2558 bool dyn = (arrayType->ty == Tarray); |
2559 | 2559 // length |
2560 if (!p->topexp() || p->topexp()->e2 != this) { | 2560 size_t len = elements->dim; |
2561 assert(DtoDType(type)->ty == Tsarray); | 2561 // store into slice? |
2562 mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint()); | 2562 bool sliceInPlace = false; |
2563 } | 2563 |
2564 else if (p->topexp()->e2 == this) { | 2564 // llvm target type |
2565 DValue* tlv = p->topexp()->v; | 2565 const llvm::Type* llType = DtoType(arrayType); |
2566 if (DSliceValue* sv = tlv->isSlice()) { | 2566 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; |
2567 assert(sv->len == 0); | 2567 |
2568 mem = sv->ptr; | 2568 // llvm storage type |
2569 inplace_slice = true; | 2569 const llvm::Type* llStoType = llvm::ArrayType::get(DtoType(elemType), len); |
2570 } | 2570 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; |
2571 else { | 2571 |
2572 mem = p->topexp()->v->getLVal(); | 2572 // dst pointer |
2573 } | 2573 llvm::Value* dstMem = 0; |
2574 assert(mem); | 2574 |
2575 if (!isaPointer(mem->getType()) || | 2575 // rvalue of assignment |
2576 !isaArray(mem->getType()->getContainedType(0))) | 2576 if (p->topexp() && p->topexp()->e2 == this) |
2577 { | |
2578 DValue* topval = p->topexp()->v; | |
2579 // slice assignment (copy) | |
2580 if (DSliceValue* s = topval->isSlice()) | |
2577 { | 2581 { |
2578 assert(!inplace_slice); | 2582 dstMem = s->ptr; |
2579 assert(ty->ty == Tarray); | 2583 sliceInPlace = true; |
2580 // we need to give this array literal storage | 2584 assert(s->len == NULL); |
2581 const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim); | 2585 } |
2582 mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint()); | 2586 // static array assignment |
2583 } | 2587 else if (topval->getType()->toBasetype()->ty == Tsarray) |
2584 } | 2588 { |
2585 else | 2589 dstMem = topval->getLVal(); |
2586 assert(0); | 2590 } |
2587 | 2591 // otherwise we still need to alloca storage |
2588 Logger::cout() << "array literal mem: " << *mem << '\n'; | 2592 } |
2589 | 2593 |
2590 for (unsigned i=0; i<elements->dim; ++i) | 2594 // alloca storage if not found already |
2595 if (!dstMem) | |
2596 { | |
2597 dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint()); | |
2598 } | |
2599 Logger::cout() << "using dest mem: " << *dstMem << '\n'; | |
2600 | |
2601 // store elements | |
2602 for (size_t i=0; i<len; ++i) | |
2591 { | 2603 { |
2592 Expression* expr = (Expression*)elements->data[i]; | 2604 Expression* expr = (Expression*)elements->data[i]; |
2593 llvm::Value* elemAddr = DtoGEPi(mem,0,i,"tmp",p->scopebb()); | 2605 llvm::Value* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); |
2606 | |
2607 // emulate assignment | |
2594 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); | 2608 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); |
2595 p->exps.push_back(IRExp(NULL, expr, vv)); | 2609 p->exps.push_back(IRExp(NULL, expr, vv)); |
2596 DValue* e = expr->toElem(p); | 2610 DValue* e = expr->toElem(p); |
2597 p->exps.pop_back(); | 2611 p->exps.pop_back(); |
2598 | |
2599 DImValue* im = e->isIm(); | 2612 DImValue* im = e->isIm(); |
2600 if (!im || !im->inPlace()) { | 2613 if (!im || !im->inPlace()) { |
2601 DtoAssign(vv, e); | 2614 DtoAssign(vv, e); |
2602 } | 2615 } |
2603 } | 2616 } |
2604 | 2617 |
2605 if (ty->ty == Tsarray || (ty->ty == Tarray && inplace_slice)) | 2618 // return storage directly ? |
2606 return new DImValue(type, mem, true); | 2619 if (!dyn || (dyn && sliceInPlace)) |
2607 else if (ty->ty == Tarray) | 2620 return new DImValue(type, dstMem, true); |
2608 return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp")); | 2621 // wrap in a slice |
2609 else { | 2622 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); |
2610 assert(0); | |
2611 return 0; | |
2612 } | |
2613 } | 2623 } |
2614 | 2624 |
2615 ////////////////////////////////////////////////////////////////////////////////////////// | 2625 ////////////////////////////////////////////////////////////////////////////////////////// |
2616 | 2626 |
2617 llvm::Constant* ArrayLiteralExp::toConstElem(IRState* p) | 2627 llvm::Constant* ArrayLiteralExp::toConstElem(IRState* p) |