mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r38] * resizing dynamic arrays support
* throw is replaced with assert(0) * catch is ignored * better foreach support * various bugfixes
This commit is contained in:
@@ -1173,12 +1173,11 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
if (arg->storageClass & (STCout | STCref | STClazy))
|
||||
error("no storage class for key %s", arg->ident->toChars());
|
||||
TY keyty = arg->type->ty;
|
||||
if ((keyty != Tint32 && keyty != Tuns32) ||
|
||||
(global.params.is64bit &&
|
||||
keyty != Tint64 && keyty != Tuns64)
|
||||
if ((keyty != Tint32 && keyty != Tuns32) &&
|
||||
(global.params.is64bit && keyty != Tint64 && keyty != Tuns64)
|
||||
)
|
||||
{
|
||||
error("foreach: key type must be int or uint, not %s", arg->type->toChars());
|
||||
error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint",arg->type->toChars());
|
||||
}
|
||||
Initializer *ie = new ExpInitializer(0, new IntegerExp(k));
|
||||
VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie);
|
||||
@@ -1315,13 +1314,12 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
}
|
||||
|
||||
if (key &&
|
||||
((key->type->ty != Tint32 && key->type->ty != Tuns32) ||
|
||||
(global.params.is64bit &&
|
||||
key->type->ty != Tint64 && key->type->ty != Tuns64)
|
||||
((key->type->ty != Tint32 && key->type->ty != Tuns32) &&
|
||||
(global.params.is64bit && key->type->ty != Tint64 && key->type->ty != Tuns64)
|
||||
)
|
||||
)
|
||||
{
|
||||
error("foreach: key type must be int or uint, not %s", key->type->toChars());
|
||||
error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint", key->type->toChars());
|
||||
}
|
||||
|
||||
if (key && key->storage_class & (STCout | STCref))
|
||||
|
||||
43
gen/arrays.c
43
gen/arrays.c
@@ -98,7 +98,7 @@ llvm::Value* LLVM_DtoNullArray(llvm::Value* v)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
void LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
{
|
||||
assert(gIR);
|
||||
if (dst->getType() == src->getType())
|
||||
@@ -118,7 +118,7 @@ llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
|
||||
return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
||||
new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -130,14 +130,11 @@ llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(src->getType()->getContainedType(0));
|
||||
llvm::Type* dstty = llvm::PointerType::get(arrty->getElementType());
|
||||
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
||||
|
||||
llvm::Value* dstlen = LLVM_DtoGEP(dst,zero,zero,"tmp",gIR->scopebb());
|
||||
llvm::Value* dstlen = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
||||
llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
||||
new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
|
||||
|
||||
llvm::Value* dstptr = LLVM_DtoGEP(dst,zero,one,"tmp",gIR->scopebb());
|
||||
llvm::Value* dstptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
|
||||
llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
|
||||
}
|
||||
@@ -350,6 +347,7 @@ static llvm::Value* get_slice_ptr(elem* e, llvm::Value*& sz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLVM_DtoArrayCopy(elem* dst, elem* src)
|
||||
{
|
||||
Logger::cout() << "Array copy ((((" << *src->mem << ")))) into ((((" << *dst->mem << "))))\n";
|
||||
@@ -387,3 +385,34 @@ llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr)
|
||||
values.push_back(ptr);
|
||||
return llvm::ConstantStruct::get(type,values);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty)
|
||||
{
|
||||
size_t sz = gTargetData->getTypeSize(ty);
|
||||
llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false);
|
||||
llvm::Value* bytesize = llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
|
||||
|
||||
llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty));
|
||||
|
||||
llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize);
|
||||
|
||||
llvm::Value* lenptr = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(dim,lenptr,gIR->scopebb());
|
||||
llvm::Value* ptrptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(newptr,ptrptr,gIR->scopebb());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz)
|
||||
{
|
||||
llvm::Value* ptr = LLVM_DtoGEPi(arr, 0, 1, "tmp", gIR->scopebb());
|
||||
llvm::Value* ptrld = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
|
||||
llvm::Value* newptr = LLVM_DtoRealloc(ptrld, sz);
|
||||
new llvm::StoreInst(newptr,ptr,gIR->scopebb());
|
||||
llvm::Value* len = LLVM_DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb());
|
||||
new llvm::StoreInst(sz,len,gIR->scopebb());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
21
gen/arrays.h
21
gen/arrays.h
@@ -2,21 +2,18 @@
|
||||
#define LLVMC_GEN_ARRAYS_H
|
||||
|
||||
const llvm::StructType* LLVM_DtoArrayType(Type* t);
|
||||
|
||||
const llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t);
|
||||
|
||||
llvm::Value* LLVM_DtoNullArray(llvm::Value* v);
|
||||
|
||||
llvm::Value* LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r);
|
||||
|
||||
void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
|
||||
|
||||
llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* si);
|
||||
|
||||
void LLVM_DtoArrayCopy(elem* dst, elem* src);
|
||||
|
||||
void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r);
|
||||
|
||||
llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr);
|
||||
|
||||
void LLVM_DtoArrayCopy(elem* dst, elem* src);
|
||||
void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r);
|
||||
void LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r);
|
||||
void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
|
||||
llvm::Value* LLVM_DtoNullArray(llvm::Value* v);
|
||||
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty);
|
||||
void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
|
||||
|
||||
#endif // LLVMC_GEN_ARRAYS_H
|
||||
|
||||
@@ -34,7 +34,8 @@ llvm::Value* elem::getValue()
|
||||
break;
|
||||
|
||||
case VAR:
|
||||
case REF: {
|
||||
case REF:
|
||||
case ARRAYLEN:
|
||||
if (val) {
|
||||
return val;
|
||||
}
|
||||
@@ -52,7 +53,6 @@ llvm::Value* elem::getValue()
|
||||
return new llvm::LoadInst(mem, "tmp", gIR->scopebb());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case VAL:
|
||||
case NUL:
|
||||
|
||||
@@ -19,7 +19,8 @@ struct elem : Object
|
||||
CONST,
|
||||
NUL,
|
||||
REF,
|
||||
SLICE
|
||||
SLICE,
|
||||
ARRAYLEN
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -35,40 +35,17 @@ void CompoundStatement::toIR(IRState* p)
|
||||
Logger::println("CompoundStatement::toIR(%d):\n<<<\n%s>>>", csi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
/*
|
||||
const char* labelname;
|
||||
bool insterm = false;
|
||||
|
||||
if (!p->scopes()) {
|
||||
labelname = "bb";
|
||||
insterm = true;
|
||||
}
|
||||
else
|
||||
labelname = "entry";
|
||||
|
||||
//if (!llvm::isa<llvm::TerminatorInst>(p->topfunc()->back().back()))
|
||||
// insterm = true;
|
||||
|
||||
llvm::BasicBlock* bb = new llvm::BasicBlock(labelname, p->topfunc());
|
||||
|
||||
if (insterm) {
|
||||
new llvm::BranchInst(bb,p->topbb());
|
||||
}
|
||||
|
||||
p->bbs.push(bb);
|
||||
*/
|
||||
|
||||
size_t n = statements->dim;
|
||||
for (size_t i=0; i<n; i++)
|
||||
for (int i=0; i<statements->dim; i++)
|
||||
{
|
||||
Statement* s = (Statement*)statements->data[i];
|
||||
if (s)
|
||||
s->toIR(p);
|
||||
else
|
||||
Logger::println("NULL statement found in CompoundStatement !! :S");
|
||||
s->toIR(p);
|
||||
else {
|
||||
Logger::println("NULL statement found in CompoundStatement !! :S");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
//p->bbs.pop();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -476,17 +453,17 @@ void TryCatchStatement::toIR(IRState* p)
|
||||
Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(0 && "try-catch is not properly");
|
||||
Logger::println("*** ATTENTION: try-catch is not yet fully implemented, only the try block will be emitted.");
|
||||
|
||||
assert(body);
|
||||
body->toIR(p);
|
||||
|
||||
assert(catches);
|
||||
/*assert(catches);
|
||||
for(size_t i=0; i<catches->dim; ++i)
|
||||
{
|
||||
Catch* c = (Catch*)catches->data[i];
|
||||
c->handler->toIR(p);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -497,11 +474,16 @@ void ThrowStatement::toIR(IRState* p)
|
||||
Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(0 && "throw is not implemented");
|
||||
Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);");
|
||||
|
||||
llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
|
||||
LLVM_DtoAssert(NULL, line, NULL);
|
||||
|
||||
/*
|
||||
assert(exp);
|
||||
elem* e = exp->toElem(p);
|
||||
delete e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -622,7 +604,6 @@ void ForeachStatement::toIR(IRState* p)
|
||||
LOG_SCOPE;
|
||||
|
||||
//assert(arguments->dim == 1);
|
||||
assert(key == 0);
|
||||
assert(value != 0);
|
||||
assert(body != 0);
|
||||
assert(aggr != 0);
|
||||
@@ -642,6 +623,7 @@ void ForeachStatement::toIR(IRState* p)
|
||||
|
||||
const llvm::Type* keytype = key ? LLVM_DtoType(key->type) : LLVM_DtoSize_t();
|
||||
llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
|
||||
if (key) key->llvmValue = keyvar;
|
||||
|
||||
const llvm::Type* valtype = LLVM_DtoType(value->type);
|
||||
llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint());
|
||||
|
||||
72
gen/toir.c
72
gen/toir.c
@@ -118,8 +118,10 @@ elem* VarExp::toElem(IRState* p)
|
||||
e->mem = tid->llvmValue;
|
||||
e->type = elem::VAR;
|
||||
}
|
||||
else
|
||||
assert(0 && "only magic supported is typeinfo");
|
||||
else {
|
||||
Logger::println("unsupported: %s\n", vd->toChars());
|
||||
assert(0 && "only magic supported is typeinfo");
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -331,9 +333,23 @@ elem* AssignExp::toElem(IRState* p)
|
||||
elem* r = e2->toElem(p);
|
||||
p->lvals.pop_back();
|
||||
|
||||
if (l->type == elem::ARRAYLEN)
|
||||
{
|
||||
LLVM_DtoResizeDynArray(l->mem, r->getValue());
|
||||
delete r;
|
||||
delete l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle function argument - allocate temp storage for it :/ annoying
|
||||
if (l->mem == 0) {
|
||||
LLVM_DtoGiveArgumentStorage(l);
|
||||
assert(l->val);
|
||||
if (llvm::isa<llvm::Argument>(l->val))
|
||||
LLVM_DtoGiveArgumentStorage(l);
|
||||
else {
|
||||
Logger::cout() << "here it comes... " << *l->val << '\n';
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
//e->val = l->store(r->getValue());
|
||||
|
||||
@@ -1826,12 +1842,16 @@ elem* NewExp::toElem(IRState* p)
|
||||
if (arguments->dim == 1) {
|
||||
elem* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||
llvm::Value* dimval = sz->getValue();
|
||||
llvm::Value* usedimval = dimval;
|
||||
/*llvm::Value* usedimval = dimval;
|
||||
if (dimval->getType() != llvm::Type::Int32Ty)
|
||||
usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb());
|
||||
e->mem = new llvm::MallocInst(t,usedimval,"tmp",p->scopebb());
|
||||
usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb());*/
|
||||
|
||||
LLVM_DtoSetArray(p->toplval(), dimval, e->mem);
|
||||
//e->mem = LLVM_DtoRealloc(0,t);
|
||||
//new llvm::MallocInst(t,usedimval,"tmp",p->scopebb());
|
||||
|
||||
//LLVM_DtoSetArray(p->toplval(), dimval, e->mem);
|
||||
|
||||
LLVM_DtoNewDynArray(p->toplval(), dimval, t);
|
||||
delete sz;
|
||||
}
|
||||
else {
|
||||
@@ -1948,11 +1968,18 @@ elem* ArrayLengthExp::toElem(IRState* p)
|
||||
elem* e = new elem;
|
||||
elem* u = e1->toElem(p);
|
||||
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb());
|
||||
e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
|
||||
e->type = elem::VAL;
|
||||
|
||||
if (p->inLvalue)
|
||||
{
|
||||
e->mem = u->mem;
|
||||
e->type = elem::ARRAYLEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb());
|
||||
e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
|
||||
e->type = elem::VAL;
|
||||
}
|
||||
delete u;
|
||||
|
||||
return e;
|
||||
@@ -1965,27 +1992,16 @@ elem* AssertExp::toElem(IRState* p)
|
||||
Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
elem* e = new elem;
|
||||
elem* u = e1->toElem(p);
|
||||
elem* m = msg ? msg->toElem(p) : 0;
|
||||
elem* m = msg ? msg->toElem(p) : NULL;
|
||||
|
||||
llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
|
||||
LLVM_DtoAssert(u->getValue(), loca, m ? m->val : NULL);
|
||||
|
||||
std::vector<llvm::Value*> llargs;
|
||||
llargs.resize(3);
|
||||
llargs[0] = LLVM_DtoBoolean(u->getValue());
|
||||
llargs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
|
||||
llargs[2] = m ? m->val : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
|
||||
|
||||
delete m;
|
||||
delete u;
|
||||
|
||||
//Logger::cout() << *llargs[0] << '|' << *llargs[1] << '\n';
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(p->module, "_d_assert");
|
||||
assert(fn);
|
||||
llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", p->scopebb());
|
||||
call->setCallingConv(llvm::CallingConv::C);
|
||||
|
||||
return e;
|
||||
return new elem;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
63
gen/tollvm.c
63
gen/tollvm.c
@@ -997,3 +997,66 @@ void LLVM_DtoGiveArgumentStorage(elem* l)
|
||||
l->mem = allocainst;
|
||||
l->vardecl->llvmValue = l->mem;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, const llvm::Type* ty)
|
||||
{
|
||||
/*size_t sz = gTargetData->getTypeSize(ty);
|
||||
llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false);
|
||||
if (ptr == 0) {
|
||||
llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
ptr = llvm::ConstantPointerNull::get(i8pty);
|
||||
}
|
||||
return LLVM_DtoRealloc(ptr, n);*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, llvm::Value* n)
|
||||
{
|
||||
assert(ptr);
|
||||
assert(n);
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc");
|
||||
assert(fn);
|
||||
|
||||
llvm::Value* newptr = ptr;
|
||||
|
||||
llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
if (ptr->getType() != i8pty) {
|
||||
newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb());
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
args.push_back(newptr);
|
||||
args.push_back(n);
|
||||
llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb());
|
||||
|
||||
return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLVM_DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg)
|
||||
{
|
||||
assert(loc);
|
||||
std::vector<llvm::Value*> llargs;
|
||||
llargs.resize(3);
|
||||
llargs[0] = cond ? LLVM_DtoBoolean(cond) : llvm::ConstantInt::getFalse();
|
||||
llargs[1] = loc;
|
||||
llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
|
||||
assert(fn);
|
||||
llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
||||
call->setCallingConv(llvm::CallingConv::C);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,4 +44,9 @@ llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std:
|
||||
|
||||
void LLVM_DtoGiveArgumentStorage(elem* e);
|
||||
|
||||
llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
|
||||
llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, llvm::Value* len);
|
||||
|
||||
void LLVM_DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg);
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
@@ -9,14 +9,15 @@ fi
|
||||
# build runtime
|
||||
$dc_cmd internal/contract.d \
|
||||
internal/arrays.d \
|
||||
internal/mem.d \
|
||||
internal/moduleinit.d \
|
||||
-c -noruntime -odobj || exit 1
|
||||
|
||||
llvm-as -f -o=obj/moduleinit_backend.bc internal/moduleinit_backend.ll || exit 1
|
||||
llvm-link -f -o=../lib/llvmdcore.bc obj/contract.bc obj/arrays.bc obj/moduleinit.bc obj/moduleinit_backend.bc || exit 1
|
||||
llvm-link -f -o=../lib/llvmdcore.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/moduleinit_backend.bc || exit 1
|
||||
|
||||
$dc_cmd internal/objectimpl.d -c -odobj || exit 1
|
||||
llvm-link -f -o=obj/all.bc obj/contract.bc obj/arrays.bc obj/moduleinit.bc obj/objectimpl.bc obj/moduleinit_backend.bc || exit 1
|
||||
llvm-link -f -o=obj/all.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/objectimpl.bc obj/moduleinit_backend.bc || exit 1
|
||||
|
||||
opt -f -std-compile-opts -o=../lib/llvmdcore.bc obj/all.bc || exit 1
|
||||
|
||||
|
||||
16
lphobos/internal/mem.d
Normal file
16
lphobos/internal/mem.d
Normal file
@@ -0,0 +1,16 @@
|
||||
module internal.mem;
|
||||
|
||||
extern(C):
|
||||
|
||||
void* realloc(void*,size_t);
|
||||
void free(void*);
|
||||
|
||||
void* _d_realloc(void* ptr, size_t n)
|
||||
{
|
||||
return realloc(ptr, n);
|
||||
}
|
||||
|
||||
void _d_free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
10
test/arrays3.d
Normal file
10
test/arrays3.d
Normal file
@@ -0,0 +1,10 @@
|
||||
module arrays3;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] arr;
|
||||
{arr = new int[25];}
|
||||
{assert(arr.length == 25);}
|
||||
{arr.length = arr.length + 5;}
|
||||
{assert(arr.length == 30);}
|
||||
}
|
||||
14
test/bug7.d
Normal file
14
test/bug7.d
Normal file
@@ -0,0 +1,14 @@
|
||||
module bug7;
|
||||
|
||||
class love { }
|
||||
void bug() {
|
||||
love[] child;
|
||||
child.length=1;
|
||||
assert(child[0] is null);
|
||||
child[0]=null;
|
||||
assert(child[0] is null);
|
||||
}
|
||||
void main()
|
||||
{
|
||||
bug();
|
||||
}
|
||||
15
test/foreach2.d
Normal file
15
test/foreach2.d
Normal file
@@ -0,0 +1,15 @@
|
||||
module foreach2;
|
||||
|
||||
void main()
|
||||
{
|
||||
static arr = [1.0, 2.0, 4.0, 8.0, 16.0];
|
||||
foreach(i,v; arr)
|
||||
{
|
||||
printf("arr[%d] = %f\n", i, v);
|
||||
}
|
||||
printf("-------------------------------\n");
|
||||
foreach_reverse(i,v; arr)
|
||||
{
|
||||
printf("arr[%d] = %f\n", i, v);
|
||||
}
|
||||
}
|
||||
19
test/foreach3.d
Normal file
19
test/foreach3.d
Normal file
@@ -0,0 +1,19 @@
|
||||
module foreach3;
|
||||
|
||||
void main()
|
||||
{
|
||||
static str = ['h','e','l','l','o'];
|
||||
foreach(i,v; str) {
|
||||
printf("%c",v);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
foreach(i,v; str) {
|
||||
v++;
|
||||
}
|
||||
|
||||
foreach(i,v; str) {
|
||||
printf("%c",v);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
10
test/memory1.d
Normal file
10
test/memory1.d
Normal file
@@ -0,0 +1,10 @@
|
||||
module memory1;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto a = new int[16];
|
||||
{printf("array.length = %u\n", a.length);}
|
||||
{a.length = a.length + 1;}
|
||||
{printf("array.length = %u\n", a.length);}
|
||||
{assert(a.length == 17);}
|
||||
}
|
||||
26
test/throw1.d
Normal file
26
test/throw1.d
Normal file
@@ -0,0 +1,26 @@
|
||||
module throw1;
|
||||
|
||||
extern(C) int rand();
|
||||
|
||||
class C
|
||||
{
|
||||
}
|
||||
|
||||
void func()
|
||||
{
|
||||
if (rand() & 1)
|
||||
throw new C;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
func();
|
||||
}
|
||||
catch(Object)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user