[svn r131] Fixed #11

All associative array properties now work as they should.

Fixed problems with some cases of array.length and array.ptr.

Fixed some problems with array properties.

Fixed 'in' contracts.
This commit is contained in:
Tomas Lindquist Olsen
2007-11-30 12:56:52 +01:00
parent 32ebd9617e
commit 0a226c956f
10 changed files with 169 additions and 61 deletions

View File

@@ -259,11 +259,11 @@ int main(int argc, char *argv[])
global.params.link = 1;
global.params.useAssert = 0;
global.params.useInvariants = 0;
global.params.useIn = 0;
global.params.useIn = 1;
global.params.useOut = 0;
global.params.useArrayBounds = 0;
global.params.useSwitchError = 0;
global.params.useInline = 0;
global.params.useInline = 0; // this one messes things up to a point where codegen breaks
global.params.obj = 1;
global.params.Dversion = 2;

View File

@@ -1513,9 +1513,8 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
static char *name[2] = { "_adReverseChar", "_adReverseWchar" };
nm = name[n->ty == Twchar];
fd = FuncDeclaration::genCfunc(Type::tindex, nm);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
fd->llvmRunTimeHack = true;
((TypeFunction*)fd->type)->llvmRetInPtr = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1532,9 +1531,8 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
static char *name[2] = { "_adSortChar", "_adSortWchar" };
nm = name[n->ty == Twchar];
fd = FuncDeclaration::genCfunc(Type::tindex, nm);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
fd->llvmRunTimeHack = true;
((TypeFunction*)fd->type)->llvmRetInPtr = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1552,9 +1550,8 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
assert(size);
dup = (ident == Id::dup);
fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse);
fd->llvmRunTimeHack = true;
((TypeFunction*)fd->type)->llvmRetInPtr = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1572,10 +1569,9 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
FuncDeclaration *fd;
Expressions *arguments;
fd = FuncDeclaration::genCfunc(tint32->arrayOf(),
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(),
(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
fd->llvmRunTimeHack = true;
((TypeFunction*)fd->type)->llvmRetInPtr = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -2277,6 +2273,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen);
fd->llvmRunTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
@@ -2291,7 +2288,8 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
int size = key->size(e->loc);
assert(size);
fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaKeys);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys);
fd->llvmRunTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
@@ -2305,12 +2303,13 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
FuncDeclaration *fd;
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaValues);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues);
fd->llvmRunTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
size_t keysize = key->size(e->loc);
keysize = (keysize + 3) & ~3; // BUG: 64 bit pointers?
keysize = (keysize + 4 - 1) & ~(4 - 1);
arguments->push(new IntegerExp(0, keysize, Type::tsize_t));
arguments->push(new IntegerExp(0, next->size(e->loc), Type::tsize_t));
e = new CallExp(e->loc, ec, arguments);
@@ -2322,7 +2321,8 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
FuncDeclaration *fd;
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tint64, Id::aaRehash);
fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash);
fd->llvmRunTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e->addressOf(sc));

View File

@@ -48,6 +48,20 @@ static llvm::Value* to_pkey(DValue* key)
return pkey;
}
// returns the keytype typeinfo
static llvm::Value* to_keyti(DValue* key)
{
// keyti param
Type* keytype = key->getType();
keytype->getTypeInfo(NULL);
TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
assert(tid);
DtoResolveDsymbol(Type::typeinfo);
DtoForceDeclareDsymbol(tid);
assert(tid->llvmValue);
return tid->llvmValue;
}
/////////////////////////////////////////////////////////////////////////////////////
DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key)
@@ -64,14 +78,7 @@ DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key)
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
Type* keytype = key->getType();
keytype->getTypeInfo(NULL);
TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
assert(tid);
DtoResolveDsymbol(Type::typeinfo);
DtoForceDeclareDsymbol(tid);
assert(tid->llvmValue);
llvm::Value* keyti = tid->llvmValue;
llvm::Value* keyti = to_keyti(key);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param
@@ -89,7 +96,7 @@ DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key)
args.push_back(valsize);
// call runtime
llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaGet");
llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.index");
// cast return value
const llvm::Type* targettype = llvm::PointerType::get(DtoType(type));
@@ -119,14 +126,7 @@ DValue* DtoAAIn(Type* type, DValue* aa, DValue* key)
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
Type* keytype = key->getType();
keytype->getTypeInfo(NULL);
TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
assert(tid);
DtoResolveDsymbol(Type::typeinfo);
DtoForceDeclareDsymbol(tid);
assert(tid->llvmValue);
llvm::Value* keyti = tid->llvmValue;
llvm::Value* keyti = to_keyti(key);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param
@@ -140,7 +140,7 @@ DValue* DtoAAIn(Type* type, DValue* aa, DValue* key)
args.push_back(pkey);
// call runtime
llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaIn");
llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.in");
// cast return value
const llvm::Type* targettype = DtoType(type);
@@ -151,3 +151,38 @@ DValue* DtoAAIn(Type* type, DValue* aa, DValue* key)
}
/////////////////////////////////////////////////////////////////////////////////////
void DtoAARemove(DValue* aa, DValue* key)
{
// call:
// extern(C) void _aaDel(AA aa, TypeInfo keyti, void* pkey)
// first get the runtime function
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDel");
const llvm::FunctionType* funcTy = func->getFunctionType();
Logger::cout() << "_aaDel = " << *func << '\n';
// aa param
llvm::Value* aaval = aa->getRVal();
Logger::cout() << "aaval: " << *aaval << '\n';
Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
llvm::Value* keyti = to_keyti(key);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param
llvm::Value* pkey = to_pkey(key);
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
// build arg vector
std::vector<llvm::Value*> args;
args.push_back(aaval);
args.push_back(keyti);
args.push_back(pkey);
// call runtime
gIR->ir->CreateCall(func, args.begin(), args.end(),"");
}

View File

@@ -3,5 +3,6 @@
DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key);
DValue* DtoAAIn(Type* type, DValue* aa, DValue* key);
void DtoAARemove(DValue* aa, DValue* key);
#endif // LLVMDC_GEN_AA_H

View File

@@ -808,8 +808,10 @@ llvm::Value* DtoArrayLen(DValue* v)
return s->len;
}
const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
assert(arrTy);
return DtoConstSize_t(arrTy->getNumElements());
if (arrTy)
return DtoConstSize_t(arrTy->getNumElements());
else
return DtoLoad(DtoGEPi(s->ptr, 0,0, "tmp"));
}
return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
}
@@ -831,9 +833,13 @@ llvm::Value* DtoArrayPtr(DValue* v)
if (t->ty == Tarray) {
if (DSliceValue* s = v->isSlice()) {
if (s->len) return s->ptr;
const llvm::Type* t = s->ptr->getType()->getContainedType(0);
Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
assert(arrTy);
return DtoGEPi(s->ptr, 0,0, "tmp");
if (arrTy)
return DtoGEPi(s->ptr, 0,0, "tmp");
else
return DtoLoad(DtoGEPi(s->ptr, 0,1, "tmp"));
}
return DtoLoad(DtoGEPi(v->getRVal(), 0,1, "tmp"));
}

View File

@@ -256,6 +256,8 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
if (fdecl->llvmRunTimeHack) {
gIR->declareList.push_back(fdecl);
TypeFunction* tf = (TypeFunction*)fdecl->type;
tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
return;
}

View File

@@ -904,7 +904,7 @@ DValue* CallExp::toElem(IRState* p)
Logger::cout() << "what are we calling? : " << *funcval << '\n';
}
assert(llfnty);
//Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
// argument handling
llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
@@ -2572,6 +2572,19 @@ DValue* InExp::toElem(IRState* p)
return DtoAAIn(type, aa, key);
}
DValue* RemoveExp::toElem(IRState* p)
{
Logger::print("RemoveExp::toElem: %s\n", toChars());
LOG_SCOPE;
DValue* aa = e1->toElem(p);
DValue* key = e2->toElem(p);
DtoAARemove(aa, key);
return NULL; // does not produce anything useful
}
//////////////////////////////////////////////////////////////////////////////////////////
DValue* AssocArrayLiteralExp::toElem(IRState* p)
@@ -2583,6 +2596,20 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
assert(values);
assert(keys->dim == values->dim);
Type* aatype = DtoDType(type);
Type* vtype = aatype->next;
DValue* aa;
if (p->topexp() && p->topexp()->e2 == this)
{
aa = p->topexp()->v;
}
else
{
llvm::Value* tmp = new llvm::AllocaInst(DtoType(type),"aaliteral",p->topallocapoint());
aa = new DVarValue(type, tmp, true);
}
const size_t n = keys->dim;
for (size_t i=0; i<n; ++i)
{
@@ -2590,9 +2617,17 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
Expression* eval = (Expression*)values->data[i];
Logger::println("(%u) aa[%s] = %s", i, ekey->toChars(), eval->toChars());
// index
DValue* key = ekey->toElem(p);
DValue* mem = DtoAAIndex(vtype, aa, key);
// store
DValue* val = eval->toElem(p);
DtoAssign(mem, val);
}
assert(0);
return aa;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2666,7 +2701,7 @@ STUB(BoolExp);
//STUB(CommaExp);
//STUB(ArrayLengthExp);
//STUB(HaltExp);
STUB(RemoveExp);
//STUB(RemoveExp);
//STUB(ArrayLiteralExp);
//STUB(AssocArrayLiteralExp);
//STUB(StructLiteralExp);

View File

@@ -14,8 +14,8 @@
<projectname>llvmdc</projectname>
<projectdirectory>.</projectdirectory>
<absoluteprojectpath>false</absoluteprojectpath>
<description></description>
<defaultencoding></defaultencoding>
<description/>
<defaultencoding/>
</general>
<kdevautoproject>
<general/>
@@ -156,7 +156,7 @@
<includePaths>.;</includePaths>
</codecompletion>
<creategettersetter>
<prefixGet></prefixGet>
<prefixGet/>
<prefixSet>set</prefixSet>
<prefixVariable>m_,_</prefixVariable>
<parameterName>theValue</parameterName>
@@ -168,14 +168,16 @@
<synchronize>true</synchronize>
<orientation>Vertical</orientation>
</splitheadersource>
<references/>
<references>
<pcs>LLVM</pcs>
</references>
</kdevcppsupport>
<kdevcustomproject>
<run>
<directoryradio>executable</directoryradio>
<mainprogram>/home/tomas/kdevprojects/llvmdc</mainprogram>
<programargs></programargs>
<globaldebugarguments></globaldebugarguments>
<programargs/>
<globaldebugarguments/>
<globalcwd>/home/tomas/kdevprojects/llvmdc</globalcwd>
<useglobalprogram>false</useglobalprogram>
<terminal>false</terminal>
@@ -398,13 +400,13 @@
</blacklist>
<build>
<buildtool>make</buildtool>
<builddir></builddir>
<builddir/>
</build>
<other>
<prio>0</prio>
<otherbin></otherbin>
<defaulttarget></defaulttarget>
<otheroptions></otheroptions>
<otherbin/>
<defaulttarget/>
<otheroptions/>
<selectedenvironment>default</selectedenvironment>
<environments>
<default/>
@@ -415,9 +417,9 @@
<numberofjobs>0</numberofjobs>
<prio>0</prio>
<dontact>false</dontact>
<makebin></makebin>
<defaulttarget></defaulttarget>
<makeoptions></makeoptions>
<makebin/>
<defaulttarget/>
<makeoptions/>
<selectedenvironment>default</selectedenvironment>
<environments>
<default/>
@@ -432,11 +434,11 @@
</cppsupportpart>
<kdevdebugger>
<general>
<gdbpath></gdbpath>
<dbgshell></dbgshell>
<configGdbScript></configGdbScript>
<runShellScript></runShellScript>
<runGdbScript></runGdbScript>
<gdbpath/>
<dbgshell/>
<configGdbScript/>
<runShellScript/>
<runGdbScript/>
<breakonloadinglibs>true</breakonloadinglibs>
<separatetty>false</separatetty>
<floatingtoolbar>false</floatingtoolbar>

View File

@@ -98,8 +98,9 @@ alias BB* AA;
size_t aligntsize(size_t tsize)
{
// Is pointer alignment on the x64 4 bytes or 8?
return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
// Is pointer alignment on the x86-64 4 bytes or 8?
//return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
return (tsize + 3) & (~3);
}
extern (C):
@@ -742,7 +743,8 @@ body
* length pairs of key/value pairs.
*/
extern (C)
version(none) // not used, C variadics can't be implemented in LLVM on x86-64
{
BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
{
auto valuesize = ti.next.tsize(); // value size
@@ -819,5 +821,5 @@ BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
}
return result;
}
}

25
test/aa6.d Normal file
View File

@@ -0,0 +1,25 @@
module aa6;
void main()
{
int[int] aa;
aa = [1:1, 2:4, 3:9, 4:16];
printf("---\n");
foreach(int k, int v; aa)
printf("aa[%d] = %d\n", k, v);
aa.rehash;
printf("---\n");
foreach(int k, int v; aa)
printf("aa[%d] = %d\n", k, v);
size_t n = aa.length;
assert(n == 4);
int[] keys = aa.keys;
assert(keys[] == [1,2,3,4][]);
int[] vals = aa.values;
assert(vals[] == [1,4,9,16][]);
aa.remove(3);
printf("---\n");
foreach(int k, int v; aa)
printf("aa[%d] = %d\n", k, v);
assert(aa.length == 3);
}