mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
initial label/goto support.
This commit is contained in:
@@ -3464,7 +3464,8 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
|
||||
this->statement = statement;
|
||||
this->tf = NULL;
|
||||
this->lblock = NULL;
|
||||
this->isReturnLabel = 0;
|
||||
this->isReturnLabel = 0;
|
||||
this->llvmBB = NULL;
|
||||
}
|
||||
|
||||
Statement *LabelStatement::syntaxCopy()
|
||||
|
||||
@@ -51,7 +51,8 @@ enum TOK;
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
class Value;
|
||||
class BasicBlock;
|
||||
}
|
||||
|
||||
// Back end
|
||||
@@ -714,7 +715,9 @@ struct LabelStatement : Statement
|
||||
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
void toIR(IRState *irs);
|
||||
void toIR(IRState *irs);
|
||||
|
||||
llvm::BasicBlock* llvmBB;
|
||||
};
|
||||
|
||||
struct LabelDsymbol : Dsymbol
|
||||
|
||||
131
gen/arrays.c
131
gen/arrays.c
@@ -127,65 +127,16 @@ void LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
|
||||
{
|
||||
const llvm::PointerType* ptrty = llvm::cast<llvm::PointerType>(l->getType());
|
||||
if (llvm::isa<llvm::ArrayType>(ptrty->getContainedType(0)))
|
||||
const llvm::Type* t = ptrty->getContainedType(0);
|
||||
const llvm::ArrayType* arrty = llvm::cast_or_null<llvm::ArrayType>(t);
|
||||
if (arrty)
|
||||
{
|
||||
const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(ptrty->getContainedType(0));
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
args.resize(3);
|
||||
args[0] = LLVM_DtoGEP(l,zero,zero,"tmp",gIR->scopebb());
|
||||
args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
||||
args[2] = r;
|
||||
|
||||
const char* funcname = NULL;
|
||||
|
||||
if (llvm::isa<llvm::PointerType>(arrty->getElementType())) {
|
||||
funcname = "_d_array_init_pointer";
|
||||
|
||||
const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
|
||||
if (args[0]->getType() != dstty)
|
||||
args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
|
||||
|
||||
const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
if (args[2]->getType() != valty)
|
||||
args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
|
||||
}
|
||||
else if (r->getType() == llvm::Type::Int1Ty) {
|
||||
funcname = "_d_array_init_i1";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::Int8Ty) {
|
||||
funcname = "_d_array_init_i8";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::Int16Ty) {
|
||||
funcname = "_d_array_init_i16";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::Int32Ty) {
|
||||
funcname = "_d_array_init_i32";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::Int64Ty) {
|
||||
funcname = "_d_array_init_i64";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::FloatTy) {
|
||||
funcname = "_d_array_init_float";
|
||||
}
|
||||
else if (r->getType() == llvm::Type::DoubleTy) {
|
||||
funcname = "_d_array_init_double";
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
Logger::cout() << *args[0] << '|' << *args[2] << '\n';
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
|
||||
assert(fn);
|
||||
llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
|
||||
call->setCallingConv(llvm::CallingConv::C);
|
||||
|
||||
Logger::println("array init call ok");
|
||||
llvm::Value* ptr = LLVM_DtoGEPi(l,0,0,"tmp",gIR->scopebb());
|
||||
llvm::Value* dim = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
||||
llvm::Value* val = r;
|
||||
LLVM_DtoArrayInit(ptr, dim, val);
|
||||
}
|
||||
else if (llvm::isa<llvm::StructType>(ptrty->getContainedType(0)))
|
||||
else if (llvm::isa<llvm::StructType>(t))
|
||||
{
|
||||
assert(0 && "Only static arrays support initialisers atm");
|
||||
}
|
||||
@@ -195,6 +146,61 @@ void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
|
||||
{
|
||||
const llvm::Type* t = ptr->getType()->getContainedType(0);
|
||||
|
||||
std::vector<llvm::Value*> args(3,NULL);
|
||||
args[0] = ptr;
|
||||
args[1] = dim;
|
||||
args[2] = val;
|
||||
|
||||
const char* funcname = NULL;
|
||||
|
||||
if (llvm::isa<llvm::PointerType>(t)) {
|
||||
funcname = "_d_array_init_pointer";
|
||||
|
||||
const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
|
||||
if (args[0]->getType() != dstty)
|
||||
args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
|
||||
|
||||
const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
if (args[2]->getType() != valty)
|
||||
args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
|
||||
}
|
||||
else if (t == llvm::Type::Int1Ty) {
|
||||
funcname = "_d_array_init_i1";
|
||||
}
|
||||
else if (t == llvm::Type::Int8Ty) {
|
||||
funcname = "_d_array_init_i8";
|
||||
}
|
||||
else if (t == llvm::Type::Int16Ty) {
|
||||
funcname = "_d_array_init_i16";
|
||||
}
|
||||
else if (t == llvm::Type::Int32Ty) {
|
||||
funcname = "_d_array_init_i32";
|
||||
}
|
||||
else if (t == llvm::Type::Int64Ty) {
|
||||
funcname = "_d_array_init_i64";
|
||||
}
|
||||
else if (t == llvm::Type::FloatTy) {
|
||||
funcname = "_d_array_init_float";
|
||||
}
|
||||
else if (t == llvm::Type::DoubleTy) {
|
||||
funcname = "_d_array_init_double";
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
|
||||
assert(fn);
|
||||
llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
|
||||
call->setCallingConv(llvm::CallingConv::C);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
|
||||
{
|
||||
Logger::cout() << "LLVM_DtoSetArray(" << *arr << ", " << *dim << ", " << *ptr << ")\n";
|
||||
@@ -369,8 +375,9 @@ llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty)
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
|
||||
{
|
||||
const llvm::Type* ty = LLVM_DtoType(dty);
|
||||
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());
|
||||
@@ -378,6 +385,12 @@ void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* t
|
||||
llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty));
|
||||
|
||||
llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize);
|
||||
|
||||
if (doinit) {
|
||||
elem* e = dty->defaultInit()->toElem(gIR);
|
||||
LLVM_DtoArrayInit(newptr,dim,e->getValue());
|
||||
delete e;
|
||||
}
|
||||
|
||||
llvm::Value* lenptr = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(dim,lenptr,gIR->scopebb());
|
||||
@@ -402,5 +415,3 @@ void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz)
|
||||
new llvm::StoreInst(sz,len,gIR->scopebb());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@ 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_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val);
|
||||
void LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r);
|
||||
void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
|
||||
void LLVM_DtoNullArray(llvm::Value* v);
|
||||
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty);
|
||||
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
|
||||
void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
|
||||
|
||||
#endif // LLVMC_GEN_ARRAYS_H
|
||||
|
||||
@@ -695,6 +695,45 @@ void ForeachStatement::toIR(IRState* p)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LabelStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("LabelStatement::toIR(): %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(tf == NULL);
|
||||
assert(!isReturnLabel);
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
if (llvmBB)
|
||||
llvmBB->moveBefore(oldend);
|
||||
else
|
||||
llvmBB = new llvm::BasicBlock("label", p->topfunc(), oldend);
|
||||
|
||||
new llvm::BranchInst(llvmBB, p->scopebb());
|
||||
p->scope() = IRScope(llvmBB,oldend);
|
||||
statement->toIR(p);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GotoStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("GotoStatement::toIR(): %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(tf == NULL);
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
llvm::BasicBlock* bb = new llvm::BasicBlock("aftergoto", p->topfunc(), oldend);
|
||||
|
||||
if (label->statement->llvmBB == NULL)
|
||||
label->statement->llvmBB = new llvm::BasicBlock("label", p->topfunc());
|
||||
new llvm::BranchInst(label->statement->llvmBB, p->scopebb());
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
|
||||
@@ -720,10 +759,10 @@ STUBST(AsmStatement);
|
||||
//STUBST(TryCatchStatement);
|
||||
//STUBST(TryFinallyStatement);
|
||||
STUBST(VolatileStatement);
|
||||
STUBST(LabelStatement);
|
||||
//STUBST(LabelStatement);
|
||||
//STUBST(ThrowStatement);
|
||||
STUBST(GotoCaseStatement);
|
||||
STUBST(GotoDefaultStatement);
|
||||
STUBST(GotoStatement);
|
||||
//STUBST(GotoStatement);
|
||||
//STUBST(UnrolledLoopStatement);
|
||||
//STUBST(OnScopeStatement);
|
||||
|
||||
97
gen/toir.c
97
gen/toir.c
@@ -1837,21 +1837,11 @@ elem* NewExp::toElem(IRState* p)
|
||||
e->mem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
|
||||
}
|
||||
else if (newtype->ty == Tarray) {
|
||||
t = LLVM_DtoType(newtype->next);
|
||||
assert(arguments);
|
||||
if (arguments->dim == 1) {
|
||||
elem* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||
llvm::Value* dimval = sz->getValue();
|
||||
/*llvm::Value* usedimval = dimval;
|
||||
if (dimval->getType() != llvm::Type::Int32Ty)
|
||||
usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb());*/
|
||||
|
||||
//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);
|
||||
LLVM_DtoNewDynArray(p->toplval(), dimval, newtype->next);
|
||||
delete sz;
|
||||
}
|
||||
else {
|
||||
@@ -2433,112 +2423,127 @@ STUB(AssocArrayLiteralExp);
|
||||
|
||||
unsigned Type::totym() { return 0; }
|
||||
|
||||
type *
|
||||
Type::toCtype() {
|
||||
type * Type::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type * Type::toCParamtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
Symbol * Type::toSymbol()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeTypedef::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeTypedef::toCParamtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TypedefDeclaration::toDebug()
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
type *
|
||||
TypeEnum::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeStruct::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
StructDeclaration::toDebug()
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
Symbol * TypeClass::toSymbol()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned TypeFunction::totym()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeFunction::toCtype()
|
||||
type * TypeFunction::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeSArray::toCtype()
|
||||
type * TypeSArray::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *TypeSArray::toCParamtype() { return 0; }
|
||||
|
||||
type *
|
||||
TypeDArray::toCtype()
|
||||
type *TypeSArray::toCParamtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeAArray::toCtype()
|
||||
type * TypeDArray::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypePointer::toCtype()
|
||||
type * TypeAArray::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeDelegate::toCtype()
|
||||
type * TypePointer::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type *
|
||||
TypeClass::toCtype()
|
||||
type * TypeDelegate::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ClassDeclaration::toDebug()
|
||||
type * TypeClass::toCtype()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ClassDeclaration::toDebug()
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2546,32 +2551,32 @@ ClassDeclaration::toDebug()
|
||||
void
|
||||
EnumDeclaration::toDebug()
|
||||
{
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int
|
||||
Dsymbol::cvMember(unsigned char*)
|
||||
int Dsymbol::cvMember(unsigned char*)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
EnumDeclaration::cvMember(unsigned char*)
|
||||
int EnumDeclaration::cvMember(unsigned char*)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
FuncDeclaration::cvMember(unsigned char*)
|
||||
int FuncDeclaration::cvMember(unsigned char*)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
VarDeclaration::cvMember(unsigned char*)
|
||||
int VarDeclaration::cvMember(unsigned char*)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
TypedefDeclaration::cvMember(unsigned char*)
|
||||
int TypedefDeclaration::cvMember(unsigned char*)
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2580,8 +2585,11 @@ void obj_includelib(char*){}
|
||||
AsmStatement::AsmStatement(Loc loc, Token *tokens) :
|
||||
Statement(loc)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
Statement *AsmStatement::syntaxCopy() {
|
||||
Statement *AsmStatement::syntaxCopy()
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2598,14 +2606,15 @@ void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
int AsmStatement::comeFrom()
|
||||
{
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
backend_init()
|
||||
{
|
||||
// now lazily loaded
|
||||
//LLVM_D_InitRuntime();
|
||||
// lazily loaded
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -12,7 +12,8 @@ void _writef(T)(T t) {
|
||||
for (int i=1; i<t.length; ++i) { _writef(','); _writef(t[i]); }
|
||||
_writef(']');
|
||||
} else
|
||||
static if(is(T==int)) printf("%i", t); else
|
||||
static if(is(T: int)) printf("%i", t); else
|
||||
static if(is(T: real)) printf("%f", t); else
|
||||
static assert(false, "Cannot print "~T.stringof);
|
||||
}
|
||||
|
||||
@@ -20,5 +21,6 @@ void writef(T...)(T t) {
|
||||
foreach (v; t) _writef(v);
|
||||
}
|
||||
void writefln(T...)(T t) {
|
||||
writef(t, "\n"[]);
|
||||
writef(t, "\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -3,5 +3,7 @@ module arrays4;
|
||||
void main()
|
||||
{
|
||||
auto arr = new int[4];
|
||||
{auto arrcat = arr ~ arr;}
|
||||
auto arrcat = arr ~ arr;
|
||||
assert(arrcat.length == arr.length * 2);
|
||||
}
|
||||
|
||||
|
||||
14
test/arrays5.d
Normal file
14
test/arrays5.d
Normal file
@@ -0,0 +1,14 @@
|
||||
module arrays5;
|
||||
//import std.stdio;
|
||||
void main()
|
||||
{
|
||||
auto arr = new float[5];
|
||||
arr[4] = 1f;
|
||||
//writefln(arr);
|
||||
assert(arr[0] !<>= 0f);
|
||||
assert(arr[1] !<>= 0f);
|
||||
assert(arr[2] !<>= 0f);
|
||||
assert(arr[3] !<>= 0f);
|
||||
assert(arr[4] == 1f);
|
||||
}
|
||||
|
||||
11
test/goto1.d
Normal file
11
test/goto1.d
Normal file
@@ -0,0 +1,11 @@
|
||||
module goto1;
|
||||
|
||||
void main()
|
||||
{
|
||||
int i;
|
||||
goto lbl;
|
||||
i++;
|
||||
lbl:
|
||||
assert(i == 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user