# HG changeset patch # User lindquist # Date 1194545608 -3600 # Node ID 70d6113eeb8c1612fac72c8ab1f87ef8079b7738 # Parent 3f949c6e2e9d4fd574d298748798a19fc1b715a2 [svn r96] Updated to DMD 1.023. Regular bugfixes. diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/declaration.c --- a/dmd/declaration.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/declaration.c Thu Nov 08 19:13:28 2007 +0100 @@ -770,7 +770,8 @@ } 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 @@ 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::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 @@ 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) diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/declaration.h --- a/dmd/declaration.h Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/declaration.h Thu Nov 08 19:13:28 2007 +0100 @@ -424,6 +424,23 @@ /**************************************************************/ +#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 @@ 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 @@ 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); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/expression.c --- a/dmd/expression.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/expression.c Thu Nov 08 19:13:28 2007 +0100 @@ -852,10 +852,13 @@ 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 @@ 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 @@ } 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 @@ 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()); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/expression.h --- a/dmd/expression.h Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/expression.h Thu Nov 08 19:13:28 2007 +0100 @@ -118,7 +118,7 @@ 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 @@ 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); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/func.c --- a/dmd/func.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/func.c Thu Nov 08 19:13:28 2007 +0100 @@ -557,6 +557,8 @@ if (!parent) { + if (global.errors) + return; printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc); assert(0); } diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/inline.c --- a/dmd/inline.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/inline.c Thu Nov 08 19:13:28 2007 +0100 @@ -546,8 +546,6 @@ ; else { - ExpInitializer *ie; - ExpInitializer *ieto; VarDeclaration *vto; vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); @@ -559,16 +557,18 @@ 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 *ForeachStatement::inlineScan(InlineScanState *iss) { aggr = aggr->inlineScan(iss); - body = body->inlineScan(iss); + if (body) + body = body->inlineScan(iss); return this; } @@ -864,7 +865,8 @@ { 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 @@ #endif isSynchronized() || isImportedSymbol() || +#if V2 + closureVars.dim || // no nested references to this frame +#else nestedFrameRef || // no nested references to this frame +#endif (isVirtual() && !isFinal()) )) { diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/link.c --- a/dmd/link.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/link.c Thu Nov 08 19:13:28 2007 +0100 @@ -278,15 +278,16 @@ /* 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 diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/mars.c --- a/dmd/mars.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/mars.c Thu Nov 08 19:13:28 2007 +0100 @@ -71,7 +71,7 @@ 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)); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/mtype.c --- a/dmd/mtype.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/mtype.c Thu Nov 08 19:13:28 2007 +0100 @@ -489,7 +489,7 @@ } -Expression *Type::defaultInit() +Expression *Type::defaultInit(Loc loc) { #if LOGDEFAULTINIT printf("Type::defaultInit() '%s'\n", toChars()); @@ -556,8 +556,7 @@ { 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 @@ 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 @@ return e; } #endif - Expression *ex = defaultInit(); - ex->loc = e->loc; + Expression *ex = defaultInit(e->loc); return ex; } } @@ -1327,7 +1325,7 @@ return e; } -Expression *TypeBasic::defaultInit() +Expression *TypeBasic::defaultInit(Loc loc) { integer_t value = 0; #if LOGDEFAULTINIT @@ -1353,9 +1351,9 @@ case Tcomplex32: case Tcomplex64: case Tcomplex80: - return getProperty(0, Id::nan); - } - return new IntegerExp(0, value, this); + return getProperty(loc, Id::nan); + } + return new IntegerExp(loc, value, this); } int TypeBasic::isZeroInit() @@ -1825,6 +1823,14 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #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 @@ { if (!sym->symtab) goto Lfwd; - e = defaultInit(); + e = defaultInit(loc); } else { @@ -3849,14 +3855,14 @@ 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 @@ return m; } -Expression *TypeTypedef::defaultInit() +Expression *TypeTypedef::defaultInit(Loc loc) { Expression *e; Type *bt; @@ -4037,7 +4043,7 @@ 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 @@ return sym->structalign; } -Expression *TypeStruct::defaultInit() +Expression *TypeStruct::defaultInit(Loc loc) { Symbol *s; Declaration *d; @@ -4701,13 +4707,13 @@ 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; } diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/mtype.h --- a/dmd/mtype.h Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/mtype.h Thu Nov 08 19:13:28 2007 +0100 @@ -227,7 +227,7 @@ 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 @@ int isscalar(); int isunsigned(); MATCH implicitConvTo(Type *to); - Expression *defaultInit(); + Expression *defaultInit(Loc loc); int isZeroInit(); int builtinTypeInfo(); @@ -314,7 +314,7 @@ 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 @@ int isZeroInit(); int checkBoolean(); MATCH implicitConvTo(Type *to); - Expression *defaultInit(); + Expression *defaultInit(Loc loc); int builtinTypeInfo(); TypeInfoDeclaration *getTypeInfoDeclaration(); int hasPointers(); @@ -362,7 +362,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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(); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/optimize.c --- a/dmd/optimize.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/optimize.c Thu Nov 08 19:13:28 2007 +0100 @@ -284,7 +284,7 @@ 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()); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/parse.c --- a/dmd/parse.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/parse.c Thu Nov 08 19:13:28 2007 +0100 @@ -2248,6 +2248,9 @@ break; continue; + case TOKeof: + break; + default: continue; } @@ -2288,6 +2291,10 @@ nextToken(); break; + case TOKeof: + error("found EOF instead of initializer"); + break; + default: value = parseInitializer(); is->addInit(NULL, value); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/statement.c --- a/dmd/statement.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/statement.c Thu Nov 08 19:13:28 2007 +0100 @@ -642,25 +642,18 @@ } 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; diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/template.c --- a/dmd/template.c Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/template.c Thu Nov 08 19:13:28 2007 +0100 @@ -75,6 +75,7 @@ return (Tuple *)o; } + /*********************** * Try to get arg as a type. */ @@ -202,12 +203,15 @@ 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 @@ 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 @@ //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 @@ * 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 @@ 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 @@ 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 @@ * 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 @@ //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 @@ 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 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 @@ //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 @@ if (t) { // Must match already deduced type + m = MATCHexact; if (!t->equals(ta)) goto Lnomatch; } @@ -2987,7 +3059,8 @@ } #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 @@ } 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 @@ 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 @@ semantic3(sc2); } + // Give additional context info if error occurred during instantiation + if (global.errors != errorsave) + { + error("error instantiating"); + } + sc2->pop(); scope->pop(); diff -r 3f949c6e2e9d -r 70d6113eeb8c dmd/template.h --- a/dmd/template.h Wed Nov 07 04:52:56 2007 +0100 +++ b/dmd/template.h Thu Nov 08 19:13:28 2007 +0100 @@ -78,6 +78,7 @@ TemplateDeclaration *isTemplateDeclaration() { return this; } TemplateTupleParameter *isVariadic(); + int isOverloadable(); }; struct TemplateParameter diff -r 3f949c6e2e9d -r 70d6113eeb8c gen/toir.cpp --- a/gen/toir.cpp Wed Nov 07 04:52:56 2007 +0100 +++ b/gen/toir.cpp Thu Nov 08 19:13:28 2007 +0100 @@ -66,7 +66,8 @@ //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 @@ { Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - assert(0); + assert(0 && "no complex yet"); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -331,7 +332,7 @@ { Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - assert(0); + assert(0 && "no complex yet"); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -462,10 +463,14 @@ 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 @@ 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(r->isConst()->c); - TypeStruct* ts = (TypeStruct*)e1type->next; + TypeStruct* ts = (TypeStruct*)e1next; std::vector 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 @@ 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 @@ if (!llvm::isa(mem->getType()) || !llvm::isa(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 @@ 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(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); diff -r 3f949c6e2e9d -r 70d6113eeb8c gen/tollvm.cpp --- a/gen/tollvm.cpp Wed Nov 07 04:52:56 2007 +0100 +++ b/gen/tollvm.cpp Thu Nov 08 19:13:28 2007 +0100 @@ -795,12 +795,15 @@ ////////////////////////////////////////////////////////////////////////////////////////// -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 @@ void DtoAssign(DValue* lhs, DValue* rhs) { + Logger::cout() << "DtoAssign(...);\n"; Type* t = DtoDType(lhs->getType()); Type* t2 = DtoDType(rhs->getType()); @@ -1425,7 +1429,7 @@ 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); diff -r 3f949c6e2e9d -r 70d6113eeb8c gen/tollvm.h --- a/gen/tollvm.h Wed Nov 07 04:52:56 2007 +0100 +++ b/gen/tollvm.h Thu Nov 08 19:13:28 2007 +0100 @@ -34,7 +34,7 @@ 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(); diff -r 3f949c6e2e9d -r 70d6113eeb8c lphobos/std/c/linux/socket.d --- a/lphobos/std/c/linux/socket.d Wed Nov 07 04:52:56 2007 +0100 +++ b/lphobos/std/c/linux/socket.d Thu Nov 08 19:13:28 2007 +0100 @@ -331,7 +331,7 @@ } -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; diff -r 3f949c6e2e9d -r 70d6113eeb8c test/bug51.d --- a/test/bug51.d Wed Nov 07 04:52:56 2007 +0100 +++ b/test/bug51.d Thu Nov 08 19:13:28 2007 +0100 @@ -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() {} diff -r 3f949c6e2e9d -r 70d6113eeb8c test/bug55.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug55.d Thu Nov 08 19:13:28 2007 +0100 @@ -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); +} diff -r 3f949c6e2e9d -r 70d6113eeb8c test/bug56.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug56.d Thu Nov 08 19:13:28 2007 +0100 @@ -0,0 +1,8 @@ +module bug56; + +void main() +{ + int[] a; + a = [1,2,3]; + {int[] b = [4,5,6];} +} \ No newline at end of file diff -r 3f949c6e2e9d -r 70d6113eeb8c test/ray.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ray.d Thu Nov 08 19:13:28 2007 +0100 @@ -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