[svn r96] Updated to DMD 1.023.

Regular bugfixes.
This commit is contained in:
Tomas Lindquist Olsen
2007-11-08 19:13:28 +01:00
parent ea18cd8e75
commit 454f50ccbc
24 changed files with 496 additions and 167 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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());

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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())
))
{

View File

@@ -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

View File

@@ -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(&params, 0, sizeof(Param));

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -78,6 +78,7 @@ struct TemplateDeclaration : ScopeDsymbol
TemplateDeclaration *isTemplateDeclaration() { return this; }
TemplateTupleParameter *isVariadic();
int isOverloadable();
};
struct TemplateParameter

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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
View 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
View 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
View 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
View File

@@ -0,0 +1,12 @@
module sqrts;
import std.c.math;
double sqrt(double d)
{
return std.c.math.sqrt(d);
}
void main()
{
}