mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-27 01:53:13 +01:00
[svn r96] Updated to DMD 1.023.
Regular bugfixes.
This commit is contained in:
@@ -770,7 +770,8 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
|
||||
if (!init && !sc->inunion && !isStatic() && !isConst() && fd &&
|
||||
!(storage_class & (STCfield | STCin | STCforeach)))
|
||||
!(storage_class & (STCfield | STCin | STCforeach)) &&
|
||||
type->size() != 0)
|
||||
{
|
||||
// Provide a default initializer
|
||||
//printf("Providing default initializer for '%s'\n", toChars());
|
||||
@@ -863,19 +864,19 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
t = type->toBasetype();
|
||||
if (t->ty == Tsarray)
|
||||
{
|
||||
dim = ((TypeSArray *)t)->dim->toInteger();
|
||||
// If multidimensional static array, treat as one large array
|
||||
while (1)
|
||||
ei->exp = ei->exp->semantic(sc);
|
||||
if (!ei->exp->implicitConvTo(type))
|
||||
{
|
||||
t = t->next->toBasetype();
|
||||
if (t->ty != Tsarray)
|
||||
break;
|
||||
if (t->next->toBasetype()->ty == Tbit)
|
||||
// t->size() gives size in bytes, convert to bits
|
||||
dim *= t->size() * 8;
|
||||
else
|
||||
dim = ((TypeSArray *)t)->dim->toInteger();
|
||||
// If multidimensional static array, treat as one large array
|
||||
while (1)
|
||||
{
|
||||
t = t->nextOf()->toBasetype();
|
||||
if (t->ty != Tsarray)
|
||||
break;
|
||||
dim *= ((TypeSArray *)t)->dim->toInteger();
|
||||
e1->type = new TypeSArray(t->next, new IntegerExp(0, dim, Type::tindex));
|
||||
e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
|
||||
}
|
||||
}
|
||||
e1 = new SliceExp(loc, e1, NULL, NULL);
|
||||
}
|
||||
@@ -1042,7 +1043,7 @@ void VarDeclaration::checkCtorConstInit()
|
||||
|
||||
void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
||||
{
|
||||
if (!isDataseg() && parent != sc->parent && parent)
|
||||
if (parent && !isDataseg() && parent != sc->parent)
|
||||
{
|
||||
FuncDeclaration *fdv = toParent()->isFuncDeclaration();
|
||||
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
|
||||
@@ -1180,6 +1181,24 @@ void TypeInfoDeclaration::semantic(Scope *sc)
|
||||
assert(linkage == LINKc);
|
||||
}
|
||||
|
||||
/***************************** TypeInfoConstDeclaration **********************/
|
||||
|
||||
#if V2
|
||||
TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
|
||||
: TypeInfoDeclaration(tinfo, 0)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************** TypeInfoInvariantDeclaration **********************/
|
||||
|
||||
#if V2
|
||||
TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
|
||||
: TypeInfoDeclaration(tinfo, 0)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************** TypeInfoStructDeclaration **********************/
|
||||
|
||||
TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
|
||||
|
||||
@@ -424,6 +424,23 @@ enum ILS
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
#if V2
|
||||
|
||||
enum BUILTIN
|
||||
{
|
||||
BUILTINunknown = -1, // not known if this is a builtin
|
||||
BUILTINnot, // this is not a builtin
|
||||
BUILTINsin, // std.math.sin
|
||||
BUILTINcos, // std.math.cos
|
||||
BUILTINtan, // std.math.tan
|
||||
BUILTINsqrt, // std.math.sqrt
|
||||
BUILTINfabs, // std.math.fabs
|
||||
};
|
||||
|
||||
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments);
|
||||
|
||||
#endif
|
||||
|
||||
struct FuncDeclaration : Declaration
|
||||
{
|
||||
Array *fthrows; // Array of Type's of exceptions (not used)
|
||||
@@ -453,7 +470,6 @@ struct FuncDeclaration : Declaration
|
||||
int inlineNest; // !=0 if nested inline
|
||||
int cantInterpret; // !=0 if cannot interpret function
|
||||
int semanticRun; // !=0 if semantic3() had been run
|
||||
int nestedFrameRef; // !=0 if nested variables referenced frame ptr
|
||||
ForeachStatement *fes; // if foreach body, this is the foreach
|
||||
int introducing; // !=0 if 'introducing' function
|
||||
Type *tintro; // if !=NULL, then this is the type
|
||||
@@ -473,6 +489,20 @@ struct FuncDeclaration : Declaration
|
||||
VarDeclaration *nrvo_var; // variable to replace with shidden
|
||||
Symbol *shidden; // hidden pointer passed to function
|
||||
|
||||
#if V2
|
||||
enum BUILTIN builtin; // set if this is a known, builtin
|
||||
// function we can evaluate at compile
|
||||
// time
|
||||
|
||||
int tookAddressOf; // set if someone took the address of
|
||||
// this function
|
||||
Dsymbols closureVars; // local variables in this function
|
||||
// which are referenced by nested
|
||||
// functions
|
||||
#else
|
||||
int nestedFrameRef; // !=0 if nested variables referenced
|
||||
#endif
|
||||
|
||||
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
|
||||
@@ -852,10 +852,13 @@ Expression *Expression::checkIntegral()
|
||||
return this;
|
||||
}
|
||||
|
||||
void Expression::checkArithmetic()
|
||||
Expression *Expression::checkArithmetic()
|
||||
{
|
||||
if (!type->isintegral() && !type->isfloating())
|
||||
error("'%s' is not an arithmetic type", toChars());
|
||||
{ error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars());
|
||||
return new IntegerExp(0);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
|
||||
@@ -6990,6 +6993,31 @@ Expression *AssignExp::semantic(Scope *sc)
|
||||
e2 = resolveProperties(sc, e2);
|
||||
assert(e1->type);
|
||||
|
||||
/* Rewrite tuple assignment as a tuple of assignments.
|
||||
*/
|
||||
if (e1->op == TOKtuple && e2->op == TOKtuple)
|
||||
{ TupleExp *tup1 = (TupleExp *)e1;
|
||||
TupleExp *tup2 = (TupleExp *)e2;
|
||||
size_t dim = tup1->exps->dim;
|
||||
if (dim != tup2->exps->dim)
|
||||
{
|
||||
error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim);
|
||||
}
|
||||
else
|
||||
{ Expressions *exps = new Expressions;
|
||||
exps->setDim(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{ Expression *ex1 = (Expression *)tup1->exps->data[i];
|
||||
Expression *ex2 = (Expression *)tup2->exps->data[i];
|
||||
exps->data[i] = (void *) new AssignExp(loc, ex1, ex2);
|
||||
}
|
||||
Expression *e = new TupleExp(loc, exps);
|
||||
e = e->semantic(sc);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
t1 = e1->type->toBasetype();
|
||||
|
||||
if (t1->ty == Tfunction)
|
||||
@@ -7032,21 +7060,14 @@ Expression *AssignExp::semantic(Scope *sc)
|
||||
}
|
||||
|
||||
if (e1->op == TOKslice &&
|
||||
t1->next &&
|
||||
!(t1->next->equals(e2->type->next) /*||
|
||||
(t1->next->ty == Tchar && e2->op == TOKstring)*/)
|
||||
t1->nextOf() &&
|
||||
e2->implicitConvTo(t1->nextOf())
|
||||
// !(t1->nextOf()->equals(e2->type->nextOf()))
|
||||
)
|
||||
{ // memset
|
||||
ismemset = 1; // make it easy for back end to tell what this is
|
||||
e2 = e2->implicitCastTo(sc, t1->next);
|
||||
}
|
||||
#if 0
|
||||
else if (e1->op == TOKslice &&
|
||||
e2->op == TOKstring &&
|
||||
((StringExp *)e2)->len == 1)
|
||||
{ // memset
|
||||
e2 = e2->implicitCastTo(sc, e1->type->next);
|
||||
}
|
||||
#endif
|
||||
else if (t1->ty == Tsarray)
|
||||
{
|
||||
error("cannot assign to static array %s", e1->toChars());
|
||||
@@ -7197,10 +7218,10 @@ Expression *MinAssignExp::semantic(Scope *sc)
|
||||
e = scaleFactor(sc);
|
||||
else
|
||||
{
|
||||
e1 = e1->checkArithmetic();
|
||||
e2 = e2->checkArithmetic();
|
||||
type = e1->type;
|
||||
typeCombine(sc);
|
||||
e1->checkArithmetic();
|
||||
e2->checkArithmetic();
|
||||
if (type->isreal() || type->isimaginary())
|
||||
{
|
||||
assert(e2->type->isfloating());
|
||||
|
||||
@@ -118,7 +118,7 @@ struct Expression : Object
|
||||
void checkScalar();
|
||||
void checkNoBool();
|
||||
Expression *checkIntegral();
|
||||
void checkArithmetic();
|
||||
Expression *checkArithmetic();
|
||||
void checkDeprecated(Scope *sc, Dsymbol *s);
|
||||
virtual Expression *checkToBoolean();
|
||||
Expression *checkToPointer();
|
||||
@@ -364,6 +364,7 @@ struct TupleExp : Expression
|
||||
Expression *optimize(int result);
|
||||
Expression *interpret(InterState *istate);
|
||||
Expression *castTo(Scope *sc, Type *t);
|
||||
elem *toElem(IRState *irs);
|
||||
|
||||
int inlineCost(InlineCostState *ics);
|
||||
Expression *doInline(InlineDoState *ids);
|
||||
|
||||
@@ -557,6 +557,8 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
if (global.errors)
|
||||
return;
|
||||
printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
32
dmd/inline.c
32
dmd/inline.c
@@ -546,8 +546,6 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
|
||||
;
|
||||
else
|
||||
{
|
||||
ExpInitializer *ie;
|
||||
ExpInitializer *ieto;
|
||||
VarDeclaration *vto;
|
||||
|
||||
vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init);
|
||||
@@ -559,16 +557,18 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
|
||||
ids->from.push(vd);
|
||||
ids->to.push(vto);
|
||||
|
||||
if (vd->init->isVoidInitializer())
|
||||
if (vd->init)
|
||||
{
|
||||
vto->init = new VoidInitializer(vd->init->loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ie = vd->init->isExpInitializer();
|
||||
assert(ie);
|
||||
ieto = new ExpInitializer(ie->loc, ie->exp->doInline(ids));
|
||||
vto->init = ieto;
|
||||
if (vd->init->isVoidInitializer())
|
||||
{
|
||||
vto->init = new VoidInitializer(vd->init->loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpInitializer *ie = vd->init->isExpInitializer();
|
||||
assert(ie);
|
||||
vto->init = new ExpInitializer(ie->loc, ie->exp->doInline(ids));
|
||||
}
|
||||
}
|
||||
de->declaration = (Dsymbol *) (void *)vto;
|
||||
}
|
||||
@@ -854,7 +854,8 @@ Statement *ForStatement::inlineScan(InlineScanState *iss)
|
||||
Statement *ForeachStatement::inlineScan(InlineScanState *iss)
|
||||
{
|
||||
aggr = aggr->inlineScan(iss);
|
||||
body = body->inlineScan(iss);
|
||||
if (body)
|
||||
body = body->inlineScan(iss);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -864,7 +865,8 @@ Statement *ForeachRangeStatement::inlineScan(InlineScanState *iss)
|
||||
{
|
||||
lwr = lwr->inlineScan(iss);
|
||||
upr = upr->inlineScan(iss);
|
||||
body = body->inlineScan(iss);
|
||||
if (body)
|
||||
body = body->inlineScan(iss);
|
||||
return this;
|
||||
}
|
||||
#endif
|
||||
@@ -1288,7 +1290,11 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
|
||||
#endif
|
||||
isSynchronized() ||
|
||||
isImportedSymbol() ||
|
||||
#if V2
|
||||
closureVars.dim || // no nested references to this frame
|
||||
#else
|
||||
nestedFrameRef || // no nested references to this frame
|
||||
#endif
|
||||
(isVirtual() && !isFinal())
|
||||
))
|
||||
{
|
||||
|
||||
@@ -278,15 +278,16 @@ int runLINK()
|
||||
/* Standard libraries must go after user specified libraries
|
||||
* passed with -l.
|
||||
*/
|
||||
//argv.push((void *)"-lphobos"); // turns into /usr/lib/libphobos.a
|
||||
//argv.push((void *)"-lpthread");
|
||||
//argv.push((void *)"-lm");
|
||||
|
||||
std::string corelibpath = global.params.runtimeImppath;
|
||||
corelibpath.append("/llvmdcore.bc");
|
||||
argv.append(global.params.objfiles);
|
||||
argv.push((void *)corelibpath.c_str());
|
||||
|
||||
|
||||
//argv.push((void *)"-lphobos"); // turns into /usr/lib/libphobos.a
|
||||
//argv.push((void *)"-lpthread");
|
||||
argv.push((void *)"-l=m");
|
||||
|
||||
if (!global.params.quiet)
|
||||
{
|
||||
// Print it
|
||||
|
||||
@@ -71,7 +71,7 @@ Global::Global()
|
||||
copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen";
|
||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||
llvmdc_version = "0.1";
|
||||
version = "v1.022";
|
||||
version = "v1.023";
|
||||
global.structalign = 8;
|
||||
|
||||
memset(¶ms, 0, sizeof(Param));
|
||||
|
||||
64
dmd/mtype.c
64
dmd/mtype.c
@@ -489,7 +489,7 @@ void Type::checkDeprecated(Loc loc, Scope *sc)
|
||||
}
|
||||
|
||||
|
||||
Expression *Type::defaultInit()
|
||||
Expression *Type::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("Type::defaultInit() '%s'\n", toChars());
|
||||
@@ -556,8 +556,7 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
|
||||
{
|
||||
if (ty == Tvoid)
|
||||
error(loc, "void does not have an initializer");
|
||||
e = defaultInit();
|
||||
e->loc = loc;
|
||||
e = defaultInit(loc);
|
||||
}
|
||||
else if (ident == Id::mangleof)
|
||||
{
|
||||
@@ -634,7 +633,7 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
e->isBool(0) &&
|
||||
v->type->toBasetype()->ty == Tstruct)
|
||||
{
|
||||
e = v->type->defaultInit();
|
||||
e = v->type->defaultInit(loc);
|
||||
}
|
||||
}
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
@@ -644,8 +643,7 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
Expression *ex = defaultInit();
|
||||
ex->loc = e->loc;
|
||||
Expression *ex = defaultInit(e->loc);
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
@@ -1327,7 +1325,7 @@ Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
return e;
|
||||
}
|
||||
|
||||
Expression *TypeBasic::defaultInit()
|
||||
Expression *TypeBasic::defaultInit(Loc loc)
|
||||
{ integer_t value = 0;
|
||||
|
||||
#if LOGDEFAULTINIT
|
||||
@@ -1353,9 +1351,9 @@ Expression *TypeBasic::defaultInit()
|
||||
case Tcomplex32:
|
||||
case Tcomplex64:
|
||||
case Tcomplex80:
|
||||
return getProperty(0, Id::nan);
|
||||
return getProperty(loc, Id::nan);
|
||||
}
|
||||
return new IntegerExp(0, value, this);
|
||||
return new IntegerExp(loc, value, this);
|
||||
}
|
||||
|
||||
int TypeBasic::isZeroInit()
|
||||
@@ -1825,6 +1823,14 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
|
||||
dim = semanticLength(sc, tbn, dim);
|
||||
|
||||
dim = dim->optimize(WANTvalue | WANTinterpret);
|
||||
if (sc->parameterSpecialization && dim->op == TOKvar &&
|
||||
((VarExp *)dim)->var->storage_class & STCtemplateparameter)
|
||||
{
|
||||
/* It could be a template parameter N which has no value yet:
|
||||
* template Foo(T : T[N], size_t N);
|
||||
*/
|
||||
return this;
|
||||
}
|
||||
integer_t d1 = dim->toInteger();
|
||||
dim = dim->castTo(sc, tsize_t);
|
||||
dim = dim->optimize(WANTvalue);
|
||||
@@ -1969,12 +1975,12 @@ MATCH TypeSArray::implicitConvTo(Type *to)
|
||||
return Type::implicitConvTo(to);
|
||||
}
|
||||
|
||||
Expression *TypeSArray::defaultInit()
|
||||
Expression *TypeSArray::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeSArray::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
return next->defaultInit();
|
||||
return next->defaultInit(loc);
|
||||
}
|
||||
|
||||
int TypeSArray::isZeroInit()
|
||||
@@ -2127,13 +2133,13 @@ MATCH TypeDArray::implicitConvTo(Type *to)
|
||||
return Type::implicitConvTo(to);
|
||||
}
|
||||
|
||||
Expression *TypeDArray::defaultInit()
|
||||
Expression *TypeDArray::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeDArray::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
@@ -2341,13 +2347,13 @@ void TypeAArray::toPrettyBracket(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writeByte(']');
|
||||
}
|
||||
|
||||
Expression *TypeAArray::defaultInit()
|
||||
Expression *TypeAArray::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeAArray::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
@@ -2449,13 +2455,13 @@ int TypePointer::isscalar()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Expression *TypePointer::defaultInit()
|
||||
Expression *TypePointer::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypePointer::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
@@ -2516,13 +2522,13 @@ Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
return next->dotExp(sc, e, ident);
|
||||
}
|
||||
|
||||
Expression *TypeReference::defaultInit()
|
||||
Expression *TypeReference::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeReference::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
@@ -3000,13 +3006,13 @@ void TypeDelegate::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hg
|
||||
#endif
|
||||
}
|
||||
|
||||
Expression *TypeDelegate::defaultInit()
|
||||
Expression *TypeDelegate::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeDelegate::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
@@ -3800,7 +3806,7 @@ Expression *TypeEnum::getProperty(Loc loc, Identifier *ident)
|
||||
{
|
||||
if (!sym->symtab)
|
||||
goto Lfwd;
|
||||
e = defaultInit();
|
||||
e = defaultInit(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3849,14 +3855,14 @@ MATCH TypeEnum::implicitConvTo(Type *to)
|
||||
return m;
|
||||
}
|
||||
|
||||
Expression *TypeEnum::defaultInit()
|
||||
Expression *TypeEnum::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeEnum::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
// Initialize to first member of enum
|
||||
Expression *e;
|
||||
e = new IntegerExp(0, sym->defaultval, this);
|
||||
e = new IntegerExp(loc, sym->defaultval, this);
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -4024,7 +4030,7 @@ MATCH TypeTypedef::implicitConvTo(Type *to)
|
||||
return m;
|
||||
}
|
||||
|
||||
Expression *TypeTypedef::defaultInit()
|
||||
Expression *TypeTypedef::defaultInit(Loc loc)
|
||||
{ Expression *e;
|
||||
Type *bt;
|
||||
|
||||
@@ -4037,7 +4043,7 @@ Expression *TypeTypedef::defaultInit()
|
||||
return sym->init->toExpression();
|
||||
}
|
||||
bt = sym->basetype;
|
||||
e = bt->defaultInit();
|
||||
e = bt->defaultInit(loc);
|
||||
e->type = this;
|
||||
while (bt->ty == Tsarray)
|
||||
{
|
||||
@@ -4316,7 +4322,7 @@ unsigned TypeStruct::memalign(unsigned salign)
|
||||
return sym->structalign;
|
||||
}
|
||||
|
||||
Expression *TypeStruct::defaultInit()
|
||||
Expression *TypeStruct::defaultInit(Loc loc)
|
||||
{ Symbol *s;
|
||||
Declaration *d;
|
||||
|
||||
@@ -4701,13 +4707,13 @@ MATCH TypeClass::implicitConvTo(Type *to)
|
||||
return MATCHnomatch;
|
||||
}
|
||||
|
||||
Expression *TypeClass::defaultInit()
|
||||
Expression *TypeClass::defaultInit(Loc loc)
|
||||
{
|
||||
#if LOGDEFAULTINIT
|
||||
printf("TypeClass::defaultInit() '%s'\n", toChars());
|
||||
#endif
|
||||
Expression *e;
|
||||
e = new NullExp(0);
|
||||
e = new NullExp(loc);
|
||||
e->type = this;
|
||||
return e;
|
||||
}
|
||||
|
||||
24
dmd/mtype.h
24
dmd/mtype.h
@@ -227,7 +227,7 @@ struct Type : Object
|
||||
virtual Expression *getProperty(Loc loc, Identifier *ident);
|
||||
virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||
virtual unsigned memalign(unsigned salign);
|
||||
virtual Expression *defaultInit();
|
||||
virtual Expression *defaultInit(Loc loc = 0);
|
||||
virtual int isZeroInit(); // if initializer is 0
|
||||
virtual dt_t **toDt(dt_t **pdt);
|
||||
Identifier *getTypeInfoIdent(int internal);
|
||||
@@ -279,7 +279,7 @@ struct TypeBasic : Type
|
||||
int isscalar();
|
||||
int isunsigned();
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
int builtinTypeInfo();
|
||||
|
||||
@@ -314,7 +314,7 @@ struct TypeSArray : TypeArray
|
||||
int isZeroInit();
|
||||
unsigned memalign(unsigned salign);
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
dt_t **toDtElem(dt_t **pdt, Expression *e);
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
@@ -342,7 +342,7 @@ struct TypeDArray : TypeArray
|
||||
int isZeroInit();
|
||||
int checkBoolean();
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int builtinTypeInfo();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
@@ -362,7 +362,7 @@ struct TypeAArray : TypeArray
|
||||
void toDecoBuffer(OutBuffer *buf);
|
||||
void toPrettyBracket(OutBuffer *buf, HdrGenState *hgs);
|
||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
int checkBoolean();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
@@ -383,7 +383,7 @@ struct TypePointer : Type
|
||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||
MATCH implicitConvTo(Type *to);
|
||||
int isscalar();
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
@@ -398,7 +398,7 @@ struct TypeReference : Type
|
||||
d_uns64 size(Loc loc);
|
||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
};
|
||||
|
||||
@@ -445,7 +445,7 @@ struct TypeDelegate : Type
|
||||
Type *semantic(Loc loc, Scope *sc);
|
||||
d_uns64 size(Loc loc);
|
||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
int checkBoolean();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
@@ -530,7 +530,7 @@ struct TypeStruct : Type
|
||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||
unsigned memalign(unsigned salign);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
int checkBoolean();
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
@@ -564,7 +564,7 @@ struct TypeEnum : Type
|
||||
int isunsigned();
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Type *toBasetype();
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
@@ -599,7 +599,7 @@ struct TypeTypedef : Type
|
||||
int checkBoolean();
|
||||
Type *toBasetype();
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
@@ -626,7 +626,7 @@ struct TypeClass : Type
|
||||
ClassDeclaration *isClassHandle();
|
||||
int isBaseOf(Type *t, int *poffset);
|
||||
MATCH implicitConvTo(Type *to);
|
||||
Expression *defaultInit();
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
int isauto();
|
||||
|
||||
@@ -284,7 +284,7 @@ Expression *CallExp::optimize(int result)
|
||||
if (fd)
|
||||
{
|
||||
Expression *eresult = fd->interpret(NULL, arguments);
|
||||
if (eresult)
|
||||
if (eresult && eresult != EXP_VOID_INTERPRET)
|
||||
e = eresult;
|
||||
else if (result & WANTinterpret)
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
|
||||
@@ -2248,6 +2248,9 @@ Initializer *Parser::parseInitializer()
|
||||
break;
|
||||
continue;
|
||||
|
||||
case TOKeof:
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -2288,6 +2291,10 @@ Initializer *Parser::parseInitializer()
|
||||
nextToken();
|
||||
break;
|
||||
|
||||
case TOKeof:
|
||||
error("found EOF instead of initializer");
|
||||
break;
|
||||
|
||||
default:
|
||||
value = parseInitializer();
|
||||
is->addInit(NULL, value);
|
||||
|
||||
@@ -642,25 +642,18 @@ int UnrolledLoopStatement::usesEH()
|
||||
}
|
||||
|
||||
int UnrolledLoopStatement::fallOffEnd()
|
||||
{ int falloff = TRUE;
|
||||
|
||||
{
|
||||
//printf("UnrolledLoopStatement::fallOffEnd()\n");
|
||||
for (size_t i = 0; i < statements->dim; i++)
|
||||
{ Statement *s = (Statement *)statements->data[i];
|
||||
|
||||
if (!s)
|
||||
continue;
|
||||
|
||||
if (!falloff && global.params.warnings && !s->comeFrom())
|
||||
{
|
||||
fprintf(stdmsg, "warning - ");
|
||||
s->error("statement is not reachable");
|
||||
}
|
||||
falloff = s->fallOffEnd();
|
||||
if (s)
|
||||
s->fallOffEnd();
|
||||
}
|
||||
return falloff;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int UnrolledLoopStatement::comeFrom()
|
||||
{ int comefrom = FALSE;
|
||||
|
||||
|
||||
125
dmd/template.c
125
dmd/template.c
@@ -75,6 +75,7 @@ Tuple *isTuple(Object *o)
|
||||
return (Tuple *)o;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
* Try to get arg as a type.
|
||||
*/
|
||||
@@ -202,12 +203,15 @@ L1:
|
||||
|
||||
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
|
||||
{
|
||||
//printf("ObjectToCBuffer()\n");
|
||||
Type *t = isType(oarg);
|
||||
Expression *e = isExpression(oarg);
|
||||
Dsymbol *s = isDsymbol(oarg);
|
||||
Tuple *v = isTuple(oarg);
|
||||
if (t)
|
||||
{ //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
|
||||
t->toCBuffer(buf, NULL, hgs);
|
||||
}
|
||||
else if (e)
|
||||
e->toCBuffer(buf, hgs);
|
||||
else if (s)
|
||||
@@ -444,7 +448,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
int dedtypes_dim = dedtypes->dim;
|
||||
|
||||
#if LOG
|
||||
printf("+TemplateDeclaration::matchWithInstance(this = %p, ti = %p, flag = %d)\n", this, ti, flag);
|
||||
printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@@ -486,13 +490,14 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
|
||||
//printf("\targument [%d]\n", i);
|
||||
#if 0
|
||||
printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
||||
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
||||
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
|
||||
if (ttp)
|
||||
printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
|
||||
#endif
|
||||
|
||||
m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
|
||||
//printf("\tm2 = %d\n", m2);
|
||||
|
||||
if (m2 == MATCHnomatch)
|
||||
{
|
||||
@@ -583,7 +588,7 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
|
||||
* as td2.
|
||||
*/
|
||||
|
||||
TemplateInstance ti(0, ident); // create dummy template instance
|
||||
TemplateInstance ti(0, ident); // create dummy template instance
|
||||
Objects dedtypes;
|
||||
|
||||
#define LOG_LEASTAS 0
|
||||
@@ -803,12 +808,12 @@ L2:
|
||||
if (!m && fparam->type->toBasetype()->ty == Tdelegate)
|
||||
{
|
||||
TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype();
|
||||
TypeFunction *tf = (TypeFunction *)td->nextOf();
|
||||
TypeFunction *tf = (TypeFunction *)td->next;
|
||||
|
||||
if (!tf->varargs && Argument::dim(tf->parameters) == 0)
|
||||
{
|
||||
m = farg->type->deduceType(scope, tf->nextOf(), parameters, &dedtypes);
|
||||
if (!m && tf->nextOf()->toBasetype()->ty == Tvoid)
|
||||
m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes);
|
||||
if (!m && tf->next->toBasetype()->ty == Tvoid)
|
||||
m = MATCHconvert;
|
||||
}
|
||||
//printf("\tm2 = %d\n", m);
|
||||
@@ -962,6 +967,15 @@ TemplateTupleParameter *TemplateDeclaration::isVariadic()
|
||||
return ::isVariadic(parameters);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* We can overload templates.
|
||||
*/
|
||||
|
||||
int TemplateDeclaration::isOverloadable()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Given function arguments, figure out which template function
|
||||
* to expand, and return that function.
|
||||
@@ -1152,6 +1166,17 @@ char *TemplateDeclaration::toChars()
|
||||
* Return -1 if not found.
|
||||
*/
|
||||
|
||||
int templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
|
||||
{
|
||||
for (size_t i = 0; i < parameters->dim; i++)
|
||||
{ TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
|
||||
if (tp->ident->equals(id))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
|
||||
{
|
||||
assert(tparam->ty == Tident);
|
||||
@@ -1159,14 +1184,7 @@ int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
|
||||
//printf("\ttident = '%s'\n", tident->toChars());
|
||||
if (tident->idents.dim == 0)
|
||||
{
|
||||
Identifier *id = tident->ident;
|
||||
|
||||
for (size_t i = 0; i < parameters->dim; i++)
|
||||
{ TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
|
||||
if (tp->ident->equals(id))
|
||||
return i;
|
||||
}
|
||||
return templateIdentifierLookup(tident->ident, parameters);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1268,7 +1286,32 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
|
||||
if (tparam->ty == Tsarray)
|
||||
{
|
||||
TypeSArray *tp = (TypeSArray *)tparam;
|
||||
if (dim->toInteger() != tp->dim->toInteger())
|
||||
|
||||
if (tp->dim->op == TOKvar &&
|
||||
((VarExp *)tp->dim)->var->storage_class & STCtemplateparameter)
|
||||
{ int i = templateIdentifierLookup(((VarExp *)tp->dim)->var->ident, parameters);
|
||||
// This code matches code in TypeInstance::deduceType()
|
||||
if (i == -1)
|
||||
goto Lnomatch;
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
TemplateValueParameter *tvp = tp->isTemplateValueParameter();
|
||||
if (!tvp)
|
||||
goto Lnomatch;
|
||||
Expression *e = (Expression *)dedtypes->data[i];
|
||||
if (e)
|
||||
{
|
||||
if (!dim->equals(e))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
{ Type *vt = tvp->valType->semantic(0, sc);
|
||||
MATCH m = (MATCH)dim->implicitConvTo(vt);
|
||||
if (!m)
|
||||
goto Lnomatch;
|
||||
dedtypes->data[i] = dim;
|
||||
}
|
||||
}
|
||||
else if (dim->toInteger() != tp->dim->toInteger())
|
||||
return MATCHnomatch;
|
||||
}
|
||||
else if (tparam->ty == Taarray)
|
||||
@@ -1321,9 +1364,11 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
|
||||
|
||||
MATCH TypeAArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
|
||||
{
|
||||
//printf("TypeAArray::deduceType()\n");
|
||||
//printf("\tthis = %d, ", ty); print();
|
||||
//printf("\ttparam = %d, ", tparam->ty); tparam->print();
|
||||
#if 0
|
||||
printf("TypeAArray::deduceType()\n");
|
||||
printf("\tthis = %d, ", ty); print();
|
||||
printf("\ttparam = %d, ", tparam->ty); tparam->print();
|
||||
#endif
|
||||
|
||||
// Extra check that index type must match
|
||||
if (tparam && tparam->ty == Taarray)
|
||||
@@ -1463,8 +1508,34 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
//printf("tempinst->tempdecl = %p\n", tempinst->tempdecl);
|
||||
//printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
|
||||
if (!tp->tempinst->tempdecl)
|
||||
{ if (!tp->tempinst->name->equals(tempinst->name))
|
||||
goto Lnomatch;
|
||||
{ //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
|
||||
if (!tp->tempinst->name->equals(tempinst->name))
|
||||
{
|
||||
/* Handle case of:
|
||||
* template Foo(T : sa!(T), alias sa)
|
||||
*/
|
||||
int i = templateIdentifierLookup(tp->tempinst->name, parameters);
|
||||
if (i == -1)
|
||||
goto Lnomatch;
|
||||
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
|
||||
// This logic duplicates tpx->matchArg()
|
||||
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
|
||||
if (!ta)
|
||||
goto Lnomatch;
|
||||
Dsymbol *sa = tempinst->tempdecl;
|
||||
if (!sa)
|
||||
goto Lnomatch;
|
||||
if (ta->specAlias && sa != ta->specAlias)
|
||||
goto Lnomatch;
|
||||
if (dedtypes->data[i])
|
||||
{ // Must match already deduced symbol
|
||||
Dsymbol *s = (Dsymbol *)dedtypes->data[i];
|
||||
|
||||
if (s != sa)
|
||||
goto Lnomatch;
|
||||
}
|
||||
dedtypes->data[i] = sa;
|
||||
}
|
||||
}
|
||||
else if (tempinst->tempdecl != tp->tempinst->tempdecl)
|
||||
goto Lnomatch;
|
||||
@@ -1830,6 +1901,7 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
|
||||
if (t)
|
||||
{ // Must match already deduced type
|
||||
|
||||
m = MATCHexact;
|
||||
if (!t->equals(ta))
|
||||
goto Lnomatch;
|
||||
}
|
||||
@@ -2987,7 +3059,8 @@ TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc)
|
||||
}
|
||||
#if LOG
|
||||
printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind());
|
||||
printf("s->parent = '%s'\n", s->parent->toChars());
|
||||
if (s->parent)
|
||||
printf("s->parent = '%s'\n", s->parent->toChars());
|
||||
#endif
|
||||
withsym = scopesym->isWithScopeSymbol();
|
||||
|
||||
@@ -3092,12 +3165,14 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
|
||||
}
|
||||
|
||||
dedtypes.setDim(td->parameters->dim);
|
||||
dedtypes.zero();
|
||||
if (!td->scope)
|
||||
{
|
||||
error("forward reference to template declaration %s", td->toChars());
|
||||
return NULL;
|
||||
}
|
||||
m = td->matchWithInstance(this, &dedtypes, 0);
|
||||
//printf("m = %d\n", m);
|
||||
if (!m) // no match at all
|
||||
continue;
|
||||
|
||||
@@ -3757,6 +3832,8 @@ void TemplateMixin::semantic(Scope *sc)
|
||||
argsym->parent = scy->parent;
|
||||
Scope *scope = scy->push(argsym);
|
||||
|
||||
unsigned errorsave = global.errors;
|
||||
|
||||
// Declare each template parameter as an alias for the argument type
|
||||
declareParameters(scope);
|
||||
|
||||
@@ -3798,6 +3875,12 @@ void TemplateMixin::semantic(Scope *sc)
|
||||
semantic3(sc2);
|
||||
}
|
||||
|
||||
// Give additional context info if error occurred during instantiation
|
||||
if (global.errors != errorsave)
|
||||
{
|
||||
error("error instantiating");
|
||||
}
|
||||
|
||||
sc2->pop();
|
||||
|
||||
scope->pop();
|
||||
|
||||
@@ -78,6 +78,7 @@ struct TemplateDeclaration : ScopeDsymbol
|
||||
TemplateDeclaration *isTemplateDeclaration() { return this; }
|
||||
|
||||
TemplateTupleParameter *isVariadic();
|
||||
int isOverloadable();
|
||||
};
|
||||
|
||||
struct TemplateParameter
|
||||
|
||||
49
gen/toir.cpp
49
gen/toir.cpp
@@ -66,7 +66,8 @@ DValue* DeclarationExp::toElem(IRState* p)
|
||||
//allocainst->setAlignment(vd->type->alignsize()); // TODO
|
||||
vd->llvmValue = allocainst;
|
||||
}
|
||||
DValue* ie = DtoInitializer(vd->init);
|
||||
DVarValue* vv = new DVarValue(type, vd->llvmValue, true);
|
||||
DValue* ie = DtoInitializer(vd->init, vv);
|
||||
delete ie;
|
||||
}
|
||||
|
||||
@@ -322,7 +323,7 @@ DValue* ComplexExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
assert(0);
|
||||
assert(0 && "no complex yet");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -331,7 +332,7 @@ llvm::Constant* ComplexExp::toConstElem(IRState* p)
|
||||
{
|
||||
Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
assert(0);
|
||||
assert(0 && "no complex yet");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -462,10 +463,14 @@ DValue* AssignExp::toElem(IRState* p)
|
||||
|
||||
p->exps.pop_back();
|
||||
|
||||
if (l->isArrayLen())
|
||||
DtoResizeDynArray(l->getLVal(), r->getRVal());
|
||||
else
|
||||
DtoAssign(l, r);
|
||||
DImValue* im = r->isIm();
|
||||
if (!im || !im->inPlace()) {
|
||||
if (l->isArrayLen())
|
||||
DtoResizeDynArray(l->getLVal(), r->getRVal());
|
||||
else
|
||||
DtoAssign(l, r);
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
@@ -639,19 +644,22 @@ DValue* AddExp::toElem(IRState* p)
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
Type* e1type = DtoDType(e1->type);
|
||||
Type* e1next = e1type->next ? DtoDType(e1type->next) : NULL;
|
||||
Type* e2type = DtoDType(e2->type);
|
||||
|
||||
if (e1type != e2type) {
|
||||
if (e1type->ty == Tpointer && e1type->next->ty == Tstruct) {
|
||||
if (e1type->ty == Tpointer && e1next && e1next->ty == Tstruct) {
|
||||
Logger::println("add to AddrExp of struct");
|
||||
assert(r->isConst());
|
||||
llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
|
||||
|
||||
TypeStruct* ts = (TypeStruct*)e1type->next;
|
||||
TypeStruct* ts = (TypeStruct*)e1next;
|
||||
std::vector<unsigned> offsets;
|
||||
llvm::Value* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets);
|
||||
return new DFieldValue(type, v, true);
|
||||
}
|
||||
else if (e1->type->ty == Tpointer) {
|
||||
else if (e1type->ty == Tpointer) {
|
||||
Logger::println("add to AddrExp of struct");
|
||||
llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||
return new DImValue(type, v);
|
||||
}
|
||||
@@ -2667,13 +2675,14 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||
Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
const llvm::Type* t = DtoType(type);
|
||||
Type* ty = DtoDType(type);
|
||||
const llvm::Type* t = DtoType(ty);
|
||||
Logger::cout() << "array literal has llvm type: " << *t << '\n';
|
||||
|
||||
llvm::Value* mem = 0;
|
||||
if (!p->topexp() || p->topexp()->e2 != this) {
|
||||
assert(DtoDType(type)->ty == Tsarray);
|
||||
mem = new llvm::AllocaInst(t,"tmparrayliteral",p->topallocapoint());
|
||||
mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint());
|
||||
}
|
||||
else if (p->topexp()->e2 == this) {
|
||||
DValue* tlv = p->topexp()->v;
|
||||
@@ -2688,8 +2697,10 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||
if (!llvm::isa<llvm::PointerType>(mem->getType()) ||
|
||||
!llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0)))
|
||||
{
|
||||
error("TODO array literals can currently only be used to initialise static arrays");
|
||||
fatal();
|
||||
assert(ty->ty == Tarray);
|
||||
// we need to give this array literal storage
|
||||
const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim);
|
||||
mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2703,7 +2714,14 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||
new llvm::StoreInst(e->getRVal(), elemAddr, p->scopebb());
|
||||
}
|
||||
|
||||
return new DImValue(type, mem, true);
|
||||
if (ty->ty == Tsarray)
|
||||
return new DImValue(type, mem, true);
|
||||
else if (ty->ty == Tarray)
|
||||
return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp"));
|
||||
else {
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2897,6 +2915,7 @@ STUB(RemoveExp);
|
||||
//STUB(ArrayLiteralExp);
|
||||
STUB(AssocArrayLiteralExp);
|
||||
//STUB(StructLiteralExp);
|
||||
STUB(TupleExp);
|
||||
|
||||
#define CONSTSTUB(x) llvm::Constant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); fatal(); return NULL; }
|
||||
CONSTSTUB(Expression);
|
||||
|
||||
@@ -795,12 +795,15 @@ llvm::Constant* DtoConstInitializer(Type* type, Initializer* init)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoInitializer(Initializer* init)
|
||||
DValue* DtoInitializer(Initializer* init, DValue* v)
|
||||
{
|
||||
if (ExpInitializer* ex = init->isExpInitializer())
|
||||
{
|
||||
Logger::println("expression initializer");
|
||||
assert(ex->exp);
|
||||
if (v) gIR->exps.push_back(IRExp(NULL,ex->exp,v));
|
||||
return ex->exp->toElem(gIR);
|
||||
if (v) gIR->exps.pop_back();
|
||||
}
|
||||
else if (init->isVoidInitializer())
|
||||
{
|
||||
@@ -1226,6 +1229,7 @@ llvm::Value* DtoNestedVariable(VarDeclaration* vd)
|
||||
|
||||
void DtoAssign(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
Logger::cout() << "DtoAssign(...);\n";
|
||||
Type* t = DtoDType(lhs->getType());
|
||||
Type* t2 = DtoDType(rhs->getType());
|
||||
|
||||
@@ -1425,7 +1429,7 @@ void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type*
|
||||
llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
|
||||
gIR->ir->CreateCondBr(cond, initbb, endinitbb);
|
||||
gIR->scope() = IRScope(initbb,endinitbb);
|
||||
DValue* ie = DtoInitializer(init);
|
||||
DValue* ie = DtoInitializer(init, NULL);
|
||||
if (!ie->inPlace()) {
|
||||
DValue* dst = new DVarValue(t, gvar, true);
|
||||
DtoAssign(dst, ie);
|
||||
|
||||
@@ -34,7 +34,7 @@ void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance);
|
||||
void DtoInitClass(TypeClass* tc, llvm::Value* dst);
|
||||
|
||||
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
|
||||
elem* DtoInitializer(Initializer* init);
|
||||
DValue* DtoInitializer(Initializer* init, DValue* v);
|
||||
|
||||
llvm::Function* LLVM_DeclareMemSet32();
|
||||
llvm::Function* LLVM_DeclareMemSet64();
|
||||
|
||||
@@ -331,7 +331,7 @@ union in6_addr
|
||||
}
|
||||
|
||||
|
||||
const in6_addr IN6ADDR_ANY;
|
||||
const in6_addr IN6ADDR_ANY = { s6_addr8: 0 };
|
||||
const in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
|
||||
//alias IN6ADDR_ANY IN6ADDR_ANY_INIT;
|
||||
//alias IN6ADDR_LOOPBACK IN6ADDR_LOOPBACK_INIT;
|
||||
|
||||
29
test/bug51.d
29
test/bug51.d
@@ -1,26 +1,5 @@
|
||||
module bug51;
|
||||
|
||||
import std.stdint;
|
||||
|
||||
union in6_addr
|
||||
{
|
||||
private union _in6_u_t
|
||||
{
|
||||
uint8_t[16] u6_addr8;
|
||||
uint16_t[8] u6_addr16;
|
||||
uint32_t[4] u6_addr32;
|
||||
}
|
||||
_in6_u_t in6_u;
|
||||
|
||||
uint8_t[16] s6_addr8;
|
||||
uint16_t[8] s6_addr16;
|
||||
uint32_t[4] s6_addr32;
|
||||
}
|
||||
|
||||
|
||||
const in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
|
||||
const in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
const ubyte[3] arr1 = 0;
|
||||
const ubyte[3] arr2 = [0];
|
||||
const ubyte[3] arr3 = [0:1];
|
||||
void main() {}
|
||||
|
||||
20
test/bug55.d
Normal file
20
test/bug55.d
Normal file
@@ -0,0 +1,20 @@
|
||||
module bug55;
|
||||
|
||||
int atoi(char[] s) {
|
||||
int i, fac=1;
|
||||
bool neg = (s.length) && (s[0] == '-');
|
||||
char[] a = neg ? s[1..$] : s;
|
||||
foreach_reverse(c; a) {
|
||||
i += (c-'0') * fac;
|
||||
fac *= 10;
|
||||
}
|
||||
return !neg ? i : -i;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
printf("64213 = %d\n", atoi("64213"));
|
||||
printf("-64213 = %d\n", atoi("-64213"));
|
||||
assert(atoi("64213") == 64213);
|
||||
assert(atoi("-64213") == -64213);
|
||||
}
|
||||
8
test/bug56.d
Normal file
8
test/bug56.d
Normal file
@@ -0,0 +1,8 @@
|
||||
module bug56;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] a;
|
||||
a = [1,2,3];
|
||||
{int[] b = [4,5,6];}
|
||||
}
|
||||
117
test/ray.d
Normal file
117
test/ray.d
Normal file
@@ -0,0 +1,117 @@
|
||||
//import std.stdio, std.math, std.string;
|
||||
//import tools.base;
|
||||
|
||||
int atoi(char[] s) {
|
||||
int i, fac=1;
|
||||
bool neg = (s.length) && (s[0] == '-');
|
||||
char[] a = neg ? s[1..$] : s;
|
||||
foreach_reverse(c; a) {
|
||||
i += (c-'0') * fac;
|
||||
fac *= 10;
|
||||
}
|
||||
return !neg ? i : -i;
|
||||
}
|
||||
|
||||
pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f64")
|
||||
double sqrt(double val);
|
||||
|
||||
double delta;
|
||||
static this() { delta=sqrt(real.epsilon); }
|
||||
|
||||
struct Vec {
|
||||
double x, y, z;
|
||||
Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); }
|
||||
Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); }
|
||||
Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
|
||||
double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; }
|
||||
Vec unitise() { return opMul(1.0/sqrt(dot(*this))); }
|
||||
}
|
||||
|
||||
struct Pair(T, U) { T first; U second; }
|
||||
typedef Pair!(double, Vec) Hit;
|
||||
|
||||
struct Ray { Vec orig, dir; }
|
||||
|
||||
class Scene {
|
||||
//abstract void intersect(ref Hit, ref Ray);
|
||||
void intersect(ref Hit, ref Ray) {}
|
||||
}
|
||||
|
||||
class Sphere : Scene {
|
||||
Vec center;
|
||||
double radius;
|
||||
//mixin This!("center, radius");
|
||||
this(ref Vec c, double r)
|
||||
{
|
||||
center = c;
|
||||
radius = r;
|
||||
}
|
||||
double ray_sphere(ref Ray ray) {
|
||||
auto v = center - ray.orig, b = v.dot(ray.dir), disc=b*b - v.dot(v) + radius*radius;
|
||||
if (disc < 0) return double.infinity;
|
||||
auto d = sqrt(disc), t2 = b + d;
|
||||
if (t2 < 0) return double.infinity;
|
||||
auto t1 = b - d;
|
||||
return (t1 > 0 ? t1 : t2);
|
||||
}
|
||||
void intersect(ref Hit hit, ref Ray ray) {
|
||||
auto lambda = ray_sphere(ray);
|
||||
if (lambda < hit.first)
|
||||
hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise);
|
||||
}
|
||||
}
|
||||
|
||||
class Group : Scene {
|
||||
Sphere bound;
|
||||
Scene[] children;
|
||||
//mixin This!("bound, children");
|
||||
this (Sphere s, Scene[] c)
|
||||
{
|
||||
bound = s;
|
||||
children = c;
|
||||
}
|
||||
void intersect(ref Hit hit, ref Ray ray) {
|
||||
auto l = bound.ray_sphere(ray);
|
||||
if (l < hit.first) foreach (child; children) child.intersect(hit, ray);
|
||||
}
|
||||
}
|
||||
|
||||
double ray_trace(ref Vec light, ref Ray ray, Scene s) {
|
||||
auto hit=Hit(double.infinity, Vec(0, 0, 0));
|
||||
s.intersect(hit, ray);
|
||||
if (hit.first == double.infinity) return 0.0;
|
||||
auto g = hit.second.dot(light);
|
||||
if (g >= 0) return 0.0;
|
||||
auto p = ray.orig + ray.dir*hit.first + hit.second*delta;
|
||||
auto hit2=Hit(double.infinity, Vec(0, 0, 0));
|
||||
s.intersect(hit2, Ray(p, light*-1.0));
|
||||
return (hit2.first < double.infinity ? 0 : -g);
|
||||
}
|
||||
|
||||
Scene create(int level, ref Vec c, double r) {
|
||||
auto s = new Sphere(c, r);
|
||||
if (level == 1) return s;
|
||||
Scene[] children=[s];
|
||||
double rn = 3*r/sqrt(12.0);
|
||||
for (int dz=-1; dz<=1; dz+=2)
|
||||
for (int dx=-1; dx<=1; dx+=2)
|
||||
children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2);
|
||||
return new Group(new Sphere(c, 3*r), children);
|
||||
}
|
||||
|
||||
void main(string[] args) {
|
||||
int level = (args.length==3 ? args[1].atoi() : 9),
|
||||
n = (args.length==3 ? args[2].atoi() : 512), ss = 4;
|
||||
auto light = Vec(-1, -3, 2).unitise();
|
||||
auto s=create(level, Vec(0, -1, 0), 1);
|
||||
printf("P5\n%d %d\n255", n, n);
|
||||
for (int y=n-1; y>=0; --y)
|
||||
for (int x=0; x<n; ++x) {
|
||||
double g=0;
|
||||
for (int d=0; d<ss*ss; ++d) {
|
||||
auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise();
|
||||
g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s);
|
||||
}
|
||||
printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss)));
|
||||
}
|
||||
}
|
||||
12
test/sqrts.d
Normal file
12
test/sqrts.d
Normal file
@@ -0,0 +1,12 @@
|
||||
module sqrts;
|
||||
|
||||
import std.c.math;
|
||||
|
||||
double sqrt(double d)
|
||||
{
|
||||
return std.c.math.sqrt(d);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user