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)