mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 17:11:44 +03:00
[svn r329] Cleaned up a bunch of array code for handling special slice cases no
longer relevant.
This commit is contained in:
parent
86d299a641
commit
ac3744a59d
5 changed files with 92 additions and 247 deletions
121
gen/arrays.cpp
121
gen/arrays.cpp
|
@ -241,6 +241,7 @@ void DtoArrayInit(DValue* array, DValue* value)
|
||||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
||||||
{
|
{
|
||||||
Logger::println("SetArray");
|
Logger::println("SetArray");
|
||||||
|
assert(isaStruct(arr->getType()->getContainedType(0)));
|
||||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||||
DtoStore(ptr, DtoGEPi(arr,0,1));
|
DtoStore(ptr, DtoGEPi(arr,0,1));
|
||||||
}
|
}
|
||||||
|
@ -349,48 +350,10 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
|
static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz)
|
||||||
{
|
{
|
||||||
|
assert(e->len != 0);
|
||||||
const LLType* t = e->ptr->getType()->getContainedType(0);
|
const LLType* t = e->ptr->getType()->getContainedType(0);
|
||||||
LLValue* ret = 0;
|
sz = gIR->ir->CreateMul(DtoConstSize_t(getABITypeSize(t)), e->len, "tmp");
|
||||||
if (e->len != 0) {
|
return e->ptr;
|
||||||
// this means it's a real slice
|
|
||||||
ret = e->ptr;
|
|
||||||
|
|
||||||
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
|
||||||
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
|
||||||
|
|
||||||
if (isaConstantInt(e->len)) {
|
|
||||||
sz = llvm::ConstantExpr::getMul(elemsz, isaConstant(e->len));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sz = llvm::BinaryOperator::createMul(elemsz,e->len,"tmp",gIR->scopebb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isaArray(t)) {
|
|
||||||
ret = DtoGEPi(e->ptr, 0, 0);
|
|
||||||
|
|
||||||
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
|
||||||
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
|
||||||
|
|
||||||
size_t numelements = isaArray(t)->getNumElements();
|
|
||||||
llvm::ConstantInt* nelems = llvm::ConstantInt::get(DtoSize_t(), numelements, false);
|
|
||||||
|
|
||||||
sz = llvm::ConstantExpr::getMul(elemsz, nelems);
|
|
||||||
}
|
|
||||||
else if (isaStruct(t)) {
|
|
||||||
ret = DtoGEPi(e->ptr, 0, 1);
|
|
||||||
ret = DtoLoad(ret);
|
|
||||||
|
|
||||||
size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
|
|
||||||
llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
|
|
||||||
|
|
||||||
LLValue* len = DtoGEPi(e->ptr, 0, 0);
|
|
||||||
len = DtoLoad(len);
|
|
||||||
sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
|
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
|
||||||
|
@ -895,37 +858,28 @@ LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* ne
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r)
|
LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r)
|
||||||
{
|
{
|
||||||
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
LLValue *len1, *ptr1, *len2, *ptr2;
|
||||||
|
|
||||||
if (r == NULL) {
|
assert(l);
|
||||||
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
|
assert(r);
|
||||||
LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
|
|
||||||
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
|
||||||
|
|
||||||
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
|
// compare lengths
|
||||||
const LLPointerType* pty = isaPointer(lp->getType());
|
len1 = DtoArrayLen(l);
|
||||||
LLValue* rp = llvm::ConstantPointerNull::get(pty);
|
len2 = DtoArrayLen(r);
|
||||||
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
LLValue* b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,len1,len2,"tmp");
|
||||||
|
|
||||||
LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
|
// compare pointers
|
||||||
return b;
|
ptr1 = DtoArrayPtr(l);
|
||||||
}
|
ptr2 = DtoArrayPtr(r);
|
||||||
else {
|
LLValue* b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,ptr1,ptr2,"tmp");
|
||||||
assert(l->getType() == r->getType());
|
|
||||||
|
|
||||||
LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
|
// combine
|
||||||
LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0),"tmp");
|
LLValue* res = gIR->ir->CreateAnd(b1,b2,"tmp");
|
||||||
LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
|
||||||
|
|
||||||
LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
|
// return result
|
||||||
LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1),"tmp");
|
return (op == TOKnotidentity) ? gIR->ir->CreateNot(res) : res;
|
||||||
LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
|
|
||||||
|
|
||||||
LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -954,26 +908,21 @@ LLValue* DtoArrayLen(DValue* v)
|
||||||
|
|
||||||
Type* t = DtoDType(v->getType());
|
Type* t = DtoDType(v->getType());
|
||||||
if (t->ty == Tarray) {
|
if (t->ty == Tarray) {
|
||||||
if (DSliceValue* s = v->isSlice()) {
|
if (DSliceValue* s = v->isSlice())
|
||||||
if (s->len) {
|
return s->len;
|
||||||
return s->len;
|
else if (v->isNull())
|
||||||
}
|
return DtoConstSize_t(0);
|
||||||
const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
|
||||||
if (arrTy)
|
|
||||||
return DtoConstSize_t(arrTy->getNumElements());
|
|
||||||
else
|
|
||||||
return DtoLoad(DtoGEPi(s->ptr, 0,0));
|
|
||||||
}
|
|
||||||
return DtoLoad(DtoGEPi(v->getRVal(), 0,0));
|
return DtoLoad(DtoGEPi(v->getRVal(), 0,0));
|
||||||
}
|
}
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
|
assert(!v->isNull());
|
||||||
LLValue* rv = v->getRVal();
|
LLValue* rv = v->getRVal();
|
||||||
Logger::cout() << "casting: " << *rv << '\n';
|
|
||||||
const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
|
const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
|
||||||
|
assert(t);
|
||||||
return DtoConstSize_t(t->getNumElements());
|
return DtoConstSize_t(t->getNumElements());
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0 && "unsupported array for len");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,19 +934,15 @@ LLValue* DtoArrayPtr(DValue* v)
|
||||||
|
|
||||||
Type* t = DtoDType(v->getType());
|
Type* t = DtoDType(v->getType());
|
||||||
if (t->ty == Tarray) {
|
if (t->ty == Tarray) {
|
||||||
if (DSliceValue* s = v->isSlice()) {
|
if (DSliceValue* s = v->isSlice())
|
||||||
if (s->len) return s->ptr;
|
return s->ptr;
|
||||||
const LLType* t = s->ptr->getType()->getContainedType(0);
|
else if (v->isNull())
|
||||||
Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
|
return getNullPtr(getPtrToType(DtoType(t->next)));
|
||||||
const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
|
|
||||||
if (arrTy)
|
|
||||||
return DtoGEPi(s->ptr, 0,0);
|
|
||||||
else
|
|
||||||
return DtoLoad(DtoGEPi(s->ptr, 0,1));
|
|
||||||
}
|
|
||||||
return DtoLoad(DtoGEPi(v->getRVal(), 0,1));
|
return DtoLoad(DtoGEPi(v->getRVal(), 0,1));
|
||||||
}
|
}
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
|
assert(!v->isSlice());
|
||||||
|
assert(!v->isNull());
|
||||||
return DtoGEPi(v->getRVal(), 0,0);
|
return DtoGEPi(v->getRVal(), 0,0);
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
@ -33,7 +33,7 @@ void DtoStaticArrayCopy(LLValue* dst, LLValue* src);
|
||||||
LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r);
|
LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r);
|
||||||
LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r);
|
LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r);
|
||||||
|
|
||||||
LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r);
|
LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r);
|
||||||
|
|
||||||
LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty);
|
LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty);
|
||||||
|
|
||||||
|
|
|
@ -912,45 +912,8 @@ void ForeachStatement::toIR(IRState* p)
|
||||||
Type* aggrtype = DtoDType(aggr->type);
|
Type* aggrtype = DtoDType(aggr->type);
|
||||||
|
|
||||||
// get length and pointer
|
// get length and pointer
|
||||||
LLValue* val = 0;
|
LLValue* niters = DtoArrayLen(aggrval);
|
||||||
LLValue* niters = 0;
|
LLValue* val = DtoArrayPtr(aggrval);
|
||||||
|
|
||||||
// static array
|
|
||||||
if (aggrtype->ty == Tsarray)
|
|
||||||
{
|
|
||||||
Logger::println("foreach over static array");
|
|
||||||
val = aggrval->getRVal();
|
|
||||||
assert(isaPointer(val->getType()));
|
|
||||||
const llvm::ArrayType* arrty = isaArray(val->getType()->getContainedType(0));
|
|
||||||
assert(arrty);
|
|
||||||
size_t nelems = arrty->getNumElements();
|
|
||||||
if(nelems == 0)
|
|
||||||
return;
|
|
||||||
niters = llvm::ConstantInt::get(keytype,nelems,false);
|
|
||||||
}
|
|
||||||
// dynamic array
|
|
||||||
else if (aggrtype->ty == Tarray)
|
|
||||||
{
|
|
||||||
if (DSliceValue* slice = aggrval->isSlice()) {
|
|
||||||
Logger::println("foreach over slice");
|
|
||||||
niters = slice->len;
|
|
||||||
assert(niters);
|
|
||||||
val = slice->ptr;
|
|
||||||
assert(val);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Logger::println("foreach over dynamic array");
|
|
||||||
val = aggrval->getRVal();
|
|
||||||
niters = DtoGEPi(val,0,0);
|
|
||||||
niters = DtoLoad(niters, "numiterations");
|
|
||||||
val = DtoGEPi(val,0,1);
|
|
||||||
val = DtoLoad(val, "collection");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(0 && "aggregate type is not Tarray or Tsarray");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (niters->getType() != keytype)
|
if (niters->getType() != keytype)
|
||||||
{
|
{
|
||||||
|
@ -1001,10 +964,7 @@ void ForeachStatement::toIR(IRState* p)
|
||||||
// get value for this iteration
|
// get value for this iteration
|
||||||
LLConstant* zero = llvm::ConstantInt::get(keytype,0,false);
|
LLConstant* zero = llvm::ConstantInt::get(keytype,0,false);
|
||||||
LLValue* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
|
LLValue* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
|
||||||
if (aggrtype->ty == Tsarray)
|
value->ir.irLocal->value = DtoGEP1(val,loadedKey);
|
||||||
value->ir.irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
|
|
||||||
else if (aggrtype->ty == Tarray)
|
|
||||||
value->ir.irLocal->value = llvm::GetElementPtrInst::Create(val,loadedKey,"tmp",p->scopebb());
|
|
||||||
|
|
||||||
if (!value->isRef() && !value->isOut()) {
|
if (!value->isRef() && !value->isOut()) {
|
||||||
DValue* dst = new DVarValue(value->type, valvar, true);
|
DValue* dst = new DVarValue(value->type, valvar, true);
|
||||||
|
|
159
gen/toir.cpp
159
gen/toir.cpp
|
@ -1529,108 +1529,56 @@ DValue* SliceExp::toElem(IRState* p)
|
||||||
Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars());
|
Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
Type* t = DtoDType(type);
|
// this is the new slicing code, it's different in that a full slice will no longer retain the original pointer.
|
||||||
Type* e1type = DtoDType(e1->type);
|
// but this was broken if there *was* no original pointer, ie. a slice of a slice...
|
||||||
|
// now all slices have *both* the 'len' and 'ptr' fields set to != null.
|
||||||
|
|
||||||
DValue* v = e1->toElem(p);
|
// value being sliced
|
||||||
LLValue* vmem = v->getRVal();
|
LLValue* elen;
|
||||||
assert(vmem);
|
LLValue* eptr;
|
||||||
|
DValue* e = e1->toElem(p);
|
||||||
|
|
||||||
LLValue* zero = DtoConstUint(0);
|
// handle pointer slicing
|
||||||
LLValue* one = DtoConstUint(1);
|
Type* etype = e1->type->toBasetype();
|
||||||
|
if (etype->ty == Tpointer)
|
||||||
LLValue* emem = 0;
|
|
||||||
LLValue* earg = 0;
|
|
||||||
|
|
||||||
// partial slice
|
|
||||||
if (lwr)
|
|
||||||
{
|
{
|
||||||
assert(upr);
|
assert(lwr);
|
||||||
p->arrays.push_back(v);
|
eptr = e->getRVal();
|
||||||
DValue* lo = lwr->toElem(p);
|
|
||||||
|
|
||||||
bool lwr_is_zero = false;
|
|
||||||
if (DConstValue* cv = lo->isConst())
|
|
||||||
{
|
|
||||||
assert(llvm::isa<llvm::ConstantInt>(cv->c));
|
|
||||||
|
|
||||||
if (e1type->ty == Tpointer) {
|
|
||||||
emem = v->getRVal();
|
|
||||||
}
|
|
||||||
else if (e1type->ty == Tarray) {
|
|
||||||
LLValue* tmp = DtoGEP(vmem,zero,one);
|
|
||||||
emem = DtoLoad(tmp);
|
|
||||||
}
|
|
||||||
else if (e1type->ty == Tsarray) {
|
|
||||||
emem = DtoGEP(vmem,zero,zero);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assert(emem);
|
|
||||||
|
|
||||||
llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c);
|
|
||||||
if (!(lwr_is_zero = c->isZero())) {
|
|
||||||
emem = DtoGEP1(emem,cv->c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (e1type->ty == Tarray) {
|
|
||||||
LLValue* tmp = DtoGEP(vmem,zero,one);
|
|
||||||
tmp = DtoLoad(tmp);
|
|
||||||
emem = DtoGEP1(tmp,lo->getRVal());
|
|
||||||
}
|
|
||||||
else if (e1type->ty == Tsarray) {
|
|
||||||
emem = DtoGEP(vmem,zero,lo->getRVal());
|
|
||||||
}
|
|
||||||
else if (e1type->ty == Tpointer) {
|
|
||||||
emem = DtoGEP1(v->getRVal(),lo->getRVal());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Logger::println("type = %s", e1type->toChars());
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DValue* up = upr->toElem(p);
|
|
||||||
p->arrays.pop_back();
|
|
||||||
|
|
||||||
if (DConstValue* cv = up->isConst())
|
|
||||||
{
|
|
||||||
assert(llvm::isa<llvm::ConstantInt>(cv->c));
|
|
||||||
if (lwr_is_zero) {
|
|
||||||
earg = cv->c;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (lo->isConst()) {
|
|
||||||
LLConstant* clo = llvm::cast<llvm::Constant>(lo->getRVal());
|
|
||||||
LLConstant* cup = llvm::cast<llvm::Constant>(cv->c);
|
|
||||||
earg = llvm::ConstantExpr::getSub(cup, clo);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
earg = llvm::BinaryOperator::createSub(cv->c, lo->getRVal(), "tmp", p->scopebb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (lwr_is_zero) {
|
|
||||||
earg = up->getRVal();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
earg = llvm::BinaryOperator::createSub(up->getRVal(), lo->getRVal(), "tmp", p->scopebb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// full slice
|
// array slice
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emem = vmem;
|
eptr = DtoArrayPtr(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (earg) Logger::cout() << "slice exp result, length = " << *earg << '\n';
|
// has lower bound, pointer needs adjustment
|
||||||
Logger::cout() << "slice exp result, ptr = " << *emem << '\n';
|
if (lwr)
|
||||||
|
{
|
||||||
|
// must have upper bound too then
|
||||||
|
assert(upr);
|
||||||
|
|
||||||
return new DSliceValue(type,earg,emem);
|
// get bounds (make sure $ works)
|
||||||
|
p->arrays.push_back(e);
|
||||||
|
DValue* lo = lwr->toElem(p);
|
||||||
|
DValue* up = upr->toElem(p);
|
||||||
|
p->arrays.pop_back();
|
||||||
|
LLValue* vlo = lo->getRVal();
|
||||||
|
LLValue* vup = up->getRVal();
|
||||||
|
|
||||||
|
// offset by lower
|
||||||
|
eptr = DtoGEP1(eptr, vlo);
|
||||||
|
|
||||||
|
// adjust length
|
||||||
|
elen = p->ir->CreateSub(vup, vlo, "tmp");
|
||||||
|
}
|
||||||
|
// no bounds or full slice -> just convert to slice
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(e1->type->toBasetype()->ty != Tpointer);
|
||||||
|
elen = DtoArrayLen(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DSliceValue(type, elen, eptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2340,23 +2288,17 @@ DValue* IdentityExp::toElem(IRState* p)
|
||||||
DValue* u = e1->toElem(p);
|
DValue* u = e1->toElem(p);
|
||||||
DValue* v = e2->toElem(p);
|
DValue* v = e2->toElem(p);
|
||||||
|
|
||||||
|
Type* t1 = e1->type->toBasetype();
|
||||||
|
|
||||||
|
// handle dynarray specially
|
||||||
|
if (t1->ty == Tarray)
|
||||||
|
return new DImValue(type, DtoDynArrayIs(op,u,v));
|
||||||
|
|
||||||
LLValue* l = u->getRVal();
|
LLValue* l = u->getRVal();
|
||||||
LLValue* r = v->getRVal();
|
LLValue* r = v->getRVal();
|
||||||
|
|
||||||
Type* t1 = DtoDType(e1->type);
|
|
||||||
|
|
||||||
LLValue* eval = 0;
|
LLValue* eval = 0;
|
||||||
|
|
||||||
if (t1->ty == Tarray) {
|
if (t1->ty == Tdelegate) {
|
||||||
if (v->isNull()) {
|
|
||||||
r = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(l->getType() == r->getType());
|
|
||||||
}
|
|
||||||
eval = DtoDynArrayIs(op,l,r);
|
|
||||||
}
|
|
||||||
else if (t1->ty == Tdelegate) {
|
|
||||||
if (v->isNull()) {
|
if (v->isNull()) {
|
||||||
r = NULL;
|
r = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2623,9 +2565,10 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||||
// slice assignment (copy)
|
// slice assignment (copy)
|
||||||
if (DSliceValue* s = topval->isSlice())
|
if (DSliceValue* s = topval->isSlice())
|
||||||
{
|
{
|
||||||
dstMem = s->ptr;
|
assert(s->ptr->getType()->getContainedType(0) == llStoType->getContainedType(0));
|
||||||
|
dstMem = DtoBitCast(s->ptr, getPtrToType(llStoType));
|
||||||
sliceInPlace = true;
|
sliceInPlace = true;
|
||||||
assert(s->len == NULL);
|
// FIXME: insert bounds checks
|
||||||
}
|
}
|
||||||
// static array assignment
|
// static array assignment
|
||||||
else if (topval->getType()->toBasetype()->ty == Tsarray)
|
else if (topval->getType()->toBasetype()->ty == Tsarray)
|
||||||
|
|
|
@ -87,13 +87,8 @@ const LLType* DtoType(Type* t)
|
||||||
return DtoComplexType(t);
|
return DtoComplexType(t);
|
||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
case Tpointer: {
|
case Tpointer:
|
||||||
assert(t->next);
|
return getPtrToType(DtoType(t->next));
|
||||||
if (t->next->ty == Tvoid)
|
|
||||||
return (const LLType*)getPtrToType(LLType::Int8Ty);
|
|
||||||
else
|
|
||||||
return (const LLType*)getPtrToType(DtoType(t->next));
|
|
||||||
}
|
|
||||||
|
|
||||||
// arrays
|
// arrays
|
||||||
case Tarray:
|
case Tarray:
|
||||||
|
@ -612,6 +607,8 @@ llvm::GlobalVariable* isaGlobalVar(LLValue* v)
|
||||||
|
|
||||||
const LLPointerType* getPtrToType(const LLType* t)
|
const LLPointerType* getPtrToType(const LLType* t)
|
||||||
{
|
{
|
||||||
|
if (t == LLType::VoidTy)
|
||||||
|
t = LLType::Int8Ty;
|
||||||
return LLPointerType::get(t, 0);
|
return LLPointerType::get(t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue