[svn r316] Fixed array slice assignments like: int[] arr = ...; arr[] = 42;

There was problems with most non basic types...
Added an option to premake so we can do: premake --target gnu --no-boehm
to disable the Boehm GC.
This commit is contained in:
Tomas Lindquist Olsen
2008-06-23 14:48:42 +02:00
parent 0bddb2568f
commit 599f879149
11 changed files with 90 additions and 72 deletions

View File

@@ -111,32 +111,6 @@ void DtoArrayAssign(LLValue* dst, LLValue* src)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoArrayInit(LLValue* l, LLValue* r)
{
Logger::println("DtoArrayInit");
LOG_SCOPE;
const LLPointerType* ptrty = isaPointer(l->getType());
const LLType* t = ptrty->getContainedType(0);
const LLArrayType* arrty = isaArray(t);
if (arrty)
{
LLValue* ptr = DtoGEPi(l,0,0);
LLValue* dim = DtoConstSize_t(arrty->getNumElements());
DtoArrayInit(ptr, dim, r);
}
else if (isaStruct(t))
{
LLValue* dim = DtoLoad(DtoGEPi(l, 0,0));
LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1));
DtoArrayInit(ptr, dim, r);
}
else
assert(0);
}
//////////////////////////////////////////////////////////////////////////////////////////
typedef const LLType* constLLVMTypeP;
static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
@@ -151,40 +125,57 @@ static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
return 0;
}
void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val)
void DtoArrayInit(DValue* array, DValue* value)
{
Logger::println("DtoArrayInit");
LOG_SCOPE;
Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n';
LLValue* dim = DtoArrayLen(array);
LLValue* ptr = DtoArrayPtr(array);
LLValue* val = value->getRVal();
Logger::cout() << "llvm values:\n" << " ptr: " << *ptr << " dim: " << *dim << " val: " << *val << '\n';
const LLType* pt = ptr->getType()->getContainedType(0);
const LLType* t = val->getType();
const LLType* finalTy;
size_t aggrsz = 0;
if (size_t arrsz = checkRectArrayInit(pt, finalTy)) {
Type* valtype = value->getType()->toBasetype();
// handle rectangular init
if (size_t arrsz = checkRectArrayInit(pt, finalTy))
{
assert(finalTy == t);
LLConstant* c = isaConstant(dim);
assert(c);
dim = llvm::ConstantExpr::getMul(c, DtoConstSize_t(arrsz));
ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(finalTy), "tmp");
}
else if (isaStruct(t)) {
// handle null aggregate
else if (isaStruct(t))
{
aggrsz = getABITypeSize(t);
LLConstant* c = isaConstant(val);
if (c && c->isNullValue()) {
LLValue* nbytes;
if (aggrsz == 1)
nbytes = dim;
else
nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp");
DtoMemSetZero(ptr,nbytes);
return;
}
else {
ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp");
}
assert(c && c->isNullValue());
LLValue* nbytes;
if (aggrsz == 1)
nbytes = dim;
else
nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp");
DtoMemSetZero(ptr,nbytes);
return;
}
else {
// handle general aggregate case
else if (DtoIsPassedByRef(valtype))
{
aggrsz = getABITypeSize(pt);
ptr = gIR->ir->CreateBitCast(ptr, getVoidPtrType(), "tmp");
val = gIR->ir->CreateBitCast(val, getVoidPtrType(), "tmp");
}
else
{
Logger::cout() << "no special handling" << '\n';
assert(t == pt);
}

View File

@@ -14,8 +14,7 @@ LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c);
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
void DtoArrayInit(LLValue* l, LLValue* r);
void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val);
void DtoArrayInit(DValue* array, DValue* value);
void DtoArrayAssign(LLValue* l, LLValue* r);
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
void DtoSetArrayToNull(LLValue* v);

View File

@@ -251,6 +251,7 @@ void DtoResolveClass(ClassDeclaration* cd)
#else
iri->vtblTy = isaStruct(itc->ir.vtblType->get());
#endif
assert(iri->vtblTy);
// set index
iri->index = interIdx++;

View File

@@ -345,7 +345,7 @@ void DtoAssign(DValue* lhs, DValue* rhs)
Type* t2 = DtoDType(rhs->getType());
if (t->ty == Tstruct) {
if (t2 != t) {
if (!t->equals(t2)) {
// TODO: fix this, use 'rhs' for something
DtoAggrZeroInit(lhs->getLVal());
}
@@ -359,11 +359,8 @@ void DtoAssign(DValue* lhs, DValue* rhs)
if (DSliceValue* s2 = rhs->isSlice()) {
DtoArrayCopySlices(s, s2);
}
else if (t->next == t2) {
if (s->len)
DtoArrayInit(s->ptr, s->len, rhs->getRVal());
else
DtoArrayInit(s->ptr, rhs->getRVal());
else if (t->next->equals(t2)) {
DtoArrayInit(s, rhs);
}
else {
DtoArrayCopyToSlice(s, rhs);
@@ -388,7 +385,7 @@ void DtoAssign(DValue* lhs, DValue* rhs)
DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
}
else {
DtoArrayInit(lhs->getLVal(), rhs->getRVal());
DtoArrayInit(lhs, rhs);
}
}
else if (t->ty == Tdelegate) {

View File

@@ -2702,18 +2702,20 @@ DValue* StructLiteralExp::toElem(IRState* p)
LLValue* mem = 0;
bool isinplace = true;
// already has memory (r-value of assignment)
IRExp* topexp = p->topexp();
if (topexp && topexp->e2 == this && !topexp->v->isSlice())
{
assert(topexp->e2 == this);
sptr = topexp->v->getLVal();
}
// temporary struct literal
if (!p->topexp() || p->topexp()->e2 != this)
else
{
sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
isinplace = false;
}
// already has memory
else
{
assert(p->topexp()->e2 == this);
sptr = p->topexp()->v->getLVal();
}
// num elements in literal
unsigned n = elements->dim;

View File

@@ -51,7 +51,6 @@ dmd/inline.c
dmd/interpret.c
dmd/lexer.c
dmd/lexer.h
dmd/link.c
dmd/lstring.c
dmd/lstring.h
dmd/macro.c

View File

@@ -1,11 +1,21 @@
project.name = llvmdc
-- options
-- we always make vtables opaque, it simply kills performance...
OPAQUE_VTBLS = 1
-- use of boehm gc
if OS == "windows" then
USE_BOEHM_GC = 0
USE_BOEHM_GC = 0
else
USE_BOEHM_GC = 1
addoption("no-boehm", "Disable use of the Boehm GC")
if options["no-boehm"] then
USE_BOEHM_GC = 0
else
USE_BOEHM_GC = 1
end
end
-- idgen

View File

@@ -97,13 +97,3 @@ size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
}
return (len*elemsz)/newelemsz;
}
// creating args for main
void _d_main_args(uint n, char** args, ref char[][] res)
{
assert(res.length == n);
foreach(i,v; args[0..n])
{
res[i] = v[0 .. strlen(v)];
}
}

27
tangotests/arrays4.d Normal file
View File

@@ -0,0 +1,27 @@
module tangotests.arrays4;
struct Str { int a,b; }
void main() {
Str[] arr = new Str[64];
auto tmp = Str(1,2);
arr[] = tmp;
assert(arr[0].a == 1);
assert(arr[0].b == 2);
assert(arr[13].a == 1);
assert(arr[13].b == 2);
assert(arr[42].a == 1);
assert(arr[42].b == 2);
assert(arr[63].a == 1);
assert(arr[63].b == 2);
arr[] = Str(3,4);
assert(arr[0].a == 3);
assert(arr[0].b == 4);
assert(arr[13].a == 3);
assert(arr[13].b == 4);
assert(arr[42].a == 3);
assert(arr[42].b == 4);
assert(arr[63].a == 3);
assert(arr[63].b == 4);
}

View File

@@ -1,5 +1,6 @@
module vararg4;
import tango.core.Vararg;
extern(C) int printf(char*, ...);
void vafunc(...)
{

View File

@@ -1,5 +1,6 @@
module vararg5;
import tango.core.Vararg;
extern(C) int printf(char*, ...);
void func(...)
{
char[] str = va_arg!(char[])(_argptr);