[svn r191] Fixed: array literals did not support all type/storage combinations.

Fixed: with expression had broke somewhere along the way.
This commit is contained in:
Tomas Lindquist Olsen
2008-05-07 00:01:13 +02:00
parent e07b99bc26
commit c31af3dc2d
10 changed files with 73 additions and 46 deletions

View File

@@ -1053,8 +1053,9 @@ void WithStatement::toIR(IRState* p)
assert(body); assert(body);
DValue* e = exp->toElem(p); DValue* e = exp->toElem(p);
assert(!wthis->ir.isSet());
wthis->ir.irLocal = new IrLocal(wthis);
wthis->ir.irLocal->value = e->getRVal(); wthis->ir.irLocal->value = e->getRVal();
delete e;
body->toIR(p); body->toIR(p);
} }

View File

@@ -2550,66 +2550,76 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE; LOG_SCOPE;
Type* ty = DtoDType(type); // D types
const llvm::Type* t = DtoType(ty); Type* arrayType = type->toBasetype();
Logger::cout() << "array literal has llvm type: " << *t << '\n'; Type* elemType = arrayType->nextOf()->toBasetype();
llvm::Value* mem = 0; // is dynamic ?
bool inplace_slice = false; bool dyn = (arrayType->ty == Tarray);
// length
size_t len = elements->dim;
// store into slice?
bool sliceInPlace = false;
if (!p->topexp() || p->topexp()->e2 != this) { // llvm target type
assert(DtoDType(type)->ty == Tsarray); const llvm::Type* llType = DtoType(arrayType);
mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint()); Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
}
else if (p->topexp()->e2 == this) { // llvm storage type
DValue* tlv = p->topexp()->v; const llvm::Type* llStoType = llvm::ArrayType::get(DtoType(elemType), len);
if (DSliceValue* sv = tlv->isSlice()) { Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
assert(sv->len == 0);
mem = sv->ptr; // dst pointer
inplace_slice = true; llvm::Value* dstMem = 0;
}
else { // rvalue of assignment
mem = p->topexp()->v->getLVal(); if (p->topexp() && p->topexp()->e2 == this)
} {
assert(mem); DValue* topval = p->topexp()->v;
if (!isaPointer(mem->getType()) || // slice assignment (copy)
!isaArray(mem->getType()->getContainedType(0))) if (DSliceValue* s = topval->isSlice())
{ {
assert(!inplace_slice); dstMem = s->ptr;
assert(ty->ty == Tarray); sliceInPlace = true;
// we need to give this array literal storage assert(s->len == NULL);
const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim);
mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint());
} }
// static array assignment
else if (topval->getType()->toBasetype()->ty == Tsarray)
{
dstMem = topval->getLVal();
}
// otherwise we still need to alloca storage
} }
else
assert(0);
Logger::cout() << "array literal mem: " << *mem << '\n'; // alloca storage if not found already
if (!dstMem)
{
dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint());
}
Logger::cout() << "using dest mem: " << *dstMem << '\n';
for (unsigned i=0; i<elements->dim; ++i) // store elements
for (size_t i=0; i<len; ++i)
{ {
Expression* expr = (Expression*)elements->data[i]; Expression* expr = (Expression*)elements->data[i];
llvm::Value* elemAddr = DtoGEPi(mem,0,i,"tmp",p->scopebb()); llvm::Value* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb());
// emulate assignment
DVarValue* vv = new DVarValue(expr->type, elemAddr, true); DVarValue* vv = new DVarValue(expr->type, elemAddr, true);
p->exps.push_back(IRExp(NULL, expr, vv)); p->exps.push_back(IRExp(NULL, expr, vv));
DValue* e = expr->toElem(p); DValue* e = expr->toElem(p);
p->exps.pop_back(); p->exps.pop_back();
DImValue* im = e->isIm(); DImValue* im = e->isIm();
if (!im || !im->inPlace()) { if (!im || !im->inPlace()) {
DtoAssign(vv, e); DtoAssign(vv, e);
} }
} }
if (ty->ty == Tsarray || (ty->ty == Tarray && inplace_slice)) // return storage directly ?
return new DImValue(type, mem, true); if (!dyn || (dyn && sliceInPlace))
else if (ty->ty == Tarray) return new DImValue(type, dstMem, true);
return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp")); // wrap in a slice
else { return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp"));
assert(0);
return 0;
}
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -51,6 +51,11 @@ void IrDsymbol::reset()
irField = NULL; irField = NULL;
} }
bool IrDsymbol::isSet()
{
return (irStruct || irFunc || irGlobal || irLocal || irField);
}
IrVar* IrDsymbol::getIrVar() IrVar* IrDsymbol::getIrVar()
{ {
assert(irGlobal || irLocal || irField); assert(irGlobal || irLocal || irField);

View File

@@ -47,6 +47,8 @@ struct IrDsymbol
IrField* irField; IrField* irField;
IrVar* getIrVar(); IrVar* getIrVar();
llvm::Value*& getIrValue(); llvm::Value*& getIrValue();
bool isSet();
}; };
#endif #endif

View File

@@ -1,3 +1,5 @@
extern(C) int printf(char*, ...);
void integer() void integer()
{ {
auto arr = new int[16]; auto arr = new int[16];

View File

@@ -1,8 +1,10 @@
module arrays13; module arrays13;
extern(C) int printf(char*, ...);
void main() void main()
{ {
string a = "hello"; char[] a = "hello";
assert(a > "hel"); assert(a > "hel");
assert(a >= "hel"); assert(a >= "hel");

View File

@@ -1,5 +1,5 @@
module arrays4; module arrays4;
import std.stdio;
void main() void main()
{ {
int[] arr; int[] arr;
@@ -10,5 +10,4 @@ void main()
assert(arr.length == 2); assert(arr.length == 2);
assert(arr[0] == 3); assert(arr[0] == 3);
assert(arr[1] == 5); assert(arr[1] == 5);
writefln(arr);
} }

View File

@@ -1,5 +1,7 @@
module arrays7; module arrays7;
extern(C) int printf(char*, ...);
pragma(LLVM_internal, "notypeinfo") pragma(LLVM_internal, "notypeinfo")
struct S struct S
{ {

View File

@@ -1,5 +1,7 @@
module arrays8; module arrays8;
extern(C) int printf(char*, ...);
void main() void main()
{ {
char[] a = "hello "; char[] a = "hello ";

View File

@@ -10,6 +10,8 @@ void main()
with(s) with(s)
{ {
i = 0; i = 0;
f = 3.4; f = 3.5;
} }
assert(s.i == 0);
assert(s.f == 3.5);
} }