mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 02:43:14 +01:00
[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:
@@ -1053,8 +1053,9 @@ void WithStatement::toIR(IRState* p)
|
||||
assert(body);
|
||||
|
||||
DValue* e = exp->toElem(p);
|
||||
assert(!wthis->ir.isSet());
|
||||
wthis->ir.irLocal = new IrLocal(wthis);
|
||||
wthis->ir.irLocal->value = e->getRVal();
|
||||
delete e;
|
||||
|
||||
body->toIR(p);
|
||||
}
|
||||
|
||||
92
gen/toir.cpp
92
gen/toir.cpp
@@ -2550,66 +2550,76 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||
Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* ty = DtoDType(type);
|
||||
const llvm::Type* t = DtoType(ty);
|
||||
Logger::cout() << "array literal has llvm type: " << *t << '\n';
|
||||
// D types
|
||||
Type* arrayType = type->toBasetype();
|
||||
Type* elemType = arrayType->nextOf()->toBasetype();
|
||||
|
||||
llvm::Value* mem = 0;
|
||||
bool inplace_slice = false;
|
||||
// is dynamic ?
|
||||
bool dyn = (arrayType->ty == Tarray);
|
||||
// length
|
||||
size_t len = elements->dim;
|
||||
// store into slice?
|
||||
bool sliceInPlace = false;
|
||||
|
||||
if (!p->topexp() || p->topexp()->e2 != this) {
|
||||
assert(DtoDType(type)->ty == Tsarray);
|
||||
mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint());
|
||||
}
|
||||
else if (p->topexp()->e2 == this) {
|
||||
DValue* tlv = p->topexp()->v;
|
||||
if (DSliceValue* sv = tlv->isSlice()) {
|
||||
assert(sv->len == 0);
|
||||
mem = sv->ptr;
|
||||
inplace_slice = true;
|
||||
}
|
||||
else {
|
||||
mem = p->topexp()->v->getLVal();
|
||||
}
|
||||
assert(mem);
|
||||
if (!isaPointer(mem->getType()) ||
|
||||
!isaArray(mem->getType()->getContainedType(0)))
|
||||
// llvm target type
|
||||
const llvm::Type* llType = DtoType(arrayType);
|
||||
Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
|
||||
|
||||
// llvm storage type
|
||||
const llvm::Type* llStoType = llvm::ArrayType::get(DtoType(elemType), len);
|
||||
Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
|
||||
|
||||
// dst pointer
|
||||
llvm::Value* dstMem = 0;
|
||||
|
||||
// rvalue of assignment
|
||||
if (p->topexp() && p->topexp()->e2 == this)
|
||||
{
|
||||
DValue* topval = p->topexp()->v;
|
||||
// slice assignment (copy)
|
||||
if (DSliceValue* s = topval->isSlice())
|
||||
{
|
||||
assert(!inplace_slice);
|
||||
assert(ty->ty == Tarray);
|
||||
// we need to give this array literal storage
|
||||
const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim);
|
||||
mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint());
|
||||
dstMem = s->ptr;
|
||||
sliceInPlace = true;
|
||||
assert(s->len == NULL);
|
||||
}
|
||||
// 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];
|
||||
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);
|
||||
p->exps.push_back(IRExp(NULL, expr, vv));
|
||||
DValue* e = expr->toElem(p);
|
||||
p->exps.pop_back();
|
||||
|
||||
DImValue* im = e->isIm();
|
||||
if (!im || !im->inPlace()) {
|
||||
DtoAssign(vv, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (ty->ty == Tsarray || (ty->ty == Tarray && inplace_slice))
|
||||
return new DImValue(type, mem, true);
|
||||
else if (ty->ty == Tarray)
|
||||
return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp"));
|
||||
else {
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
// return storage directly ?
|
||||
if (!dyn || (dyn && sliceInPlace))
|
||||
return new DImValue(type, dstMem, true);
|
||||
// wrap in a slice
|
||||
return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp"));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -51,6 +51,11 @@ void IrDsymbol::reset()
|
||||
irField = NULL;
|
||||
}
|
||||
|
||||
bool IrDsymbol::isSet()
|
||||
{
|
||||
return (irStruct || irFunc || irGlobal || irLocal || irField);
|
||||
}
|
||||
|
||||
IrVar* IrDsymbol::getIrVar()
|
||||
{
|
||||
assert(irGlobal || irLocal || irField);
|
||||
|
||||
@@ -47,6 +47,8 @@ struct IrDsymbol
|
||||
IrField* irField;
|
||||
IrVar* getIrVar();
|
||||
llvm::Value*& getIrValue();
|
||||
|
||||
bool isSet();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
void integer()
|
||||
{
|
||||
auto arr = new int[16];
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
module arrays13;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
void main()
|
||||
{
|
||||
string a = "hello";
|
||||
char[] a = "hello";
|
||||
|
||||
assert(a > "hel");
|
||||
assert(a >= "hel");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module arrays4;
|
||||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] arr;
|
||||
@@ -10,5 +10,4 @@ void main()
|
||||
assert(arr.length == 2);
|
||||
assert(arr[0] == 3);
|
||||
assert(arr[1] == 5);
|
||||
writefln(arr);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module arrays7;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
pragma(LLVM_internal, "notypeinfo")
|
||||
struct S
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module arrays8;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
void main()
|
||||
{
|
||||
char[] a = "hello ";
|
||||
|
||||
@@ -10,6 +10,8 @@ void main()
|
||||
with(s)
|
||||
{
|
||||
i = 0;
|
||||
f = 3.4;
|
||||
f = 3.5;
|
||||
}
|
||||
assert(s.i == 0);
|
||||
assert(s.f == 3.5);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user