Mercurial > projects > ldc
changeset 1621:fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Both DMD revisions are for fixing bugzilla 2029 (Typesafe variadic
functions don't work in CTFE).
The DMD r314 commit message is:
bugzilla 2029 (Typesafe variadic functions don't work in CTFE
The DMD r315 commit message is:
bugzilla 2029 - try again
---
dmd/constfold.c | 11 ++++-
dmd/declaration.c | 21 +++++++++-
dmd/declaration.h | 10 ++++-
dmd/expression.c | 1 +
dmd/interpret.c | 111 +++++++++++++++++++++++++++++++++++++++++++++--------
dmd/mars.h | 2 +-
dmd/mtype.c | 2 +-
7 files changed, 135 insertions(+), 23 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:22 -0300 |
parents | 0333945a915e |
children | a542ef277a84 |
files | dmd/constfold.c dmd/declaration.c dmd/declaration.h dmd/expression.c dmd/interpret.c dmd/mars.h dmd/mtype.c |
diffstat | 7 files changed, 135 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/constfold.c Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/constfold.c Wed Jan 06 15:18:22 2010 -0300 @@ -863,7 +863,7 @@ } Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) -{ Expression *e; +{ Loc loc = e1->loc; int cmp; @@ -1055,12 +1055,12 @@ return e1; Type *tb = to->toBasetype(); + Type *typeb = type->toBasetype(); /* Allow casting from one string type to another */ if (e1->op == TOKstring) { - Type *typeb = type->toBasetype(); if (tb->ty == Tarray && typeb->ty == Tarray && tb->nextOf()->size() == typeb->nextOf()->size()) { @@ -1068,8 +1068,15 @@ } } + if (e1->op == TOKarrayliteral && typeb == tb) + { + return e1; + } + if (e1->isConst() != 1) + { return EXP_CANT_INTERPRET; + } if (tb->ty == Tbool) e = new IntegerExp(loc, e1->toInteger() != 0, type);
--- a/dmd/declaration.c Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/declaration.c Wed Jan 06 15:18:22 2010 -0300 @@ -309,6 +309,9 @@ { sem = 1; basetype = basetype->semantic(loc, sc); sem = 2; +#if DMDV2 + type = type->addStorageClass(storage_class); +#endif type = type->semantic(loc, sc); if (sc->parent->isFuncDeclaration() && init) semantic2(sc); @@ -441,8 +444,10 @@ } this->inSemantic = 1; +#if DMDV1 // don't really know why this is here if (storage_class & STCconst) error("cannot be const"); +#endif storage_class |= sc->stc & STCdeprecated; @@ -473,11 +478,12 @@ goto L2; // it's a symbolic alias #if DMDV2 + type = type->addStorageClass(storage_class); if (storage_class & (STCref | STCnothrow | STCpure)) { // For 'ref' to be attached to function types, and picked // up by Type::resolve(), it has to go into sc. sc = sc->push(); - sc->stc |= storage_class & (STCref | STCnothrow | STCpure); + sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared); type->resolve(loc, sc, &e, &t, &s); sc = sc->pop(); } @@ -1341,7 +1347,7 @@ { #if 0 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); - printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); + printf("%llx, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); printf("parent = '%s'\n", parent->toChars()); #endif Dsymbol *parent = this->toParent(); @@ -1364,6 +1370,17 @@ return 0; } +/******************************************** + * Can variable be read and written by CTFE? + */ + +int VarDeclaration::isCTFE() +{ + //printf("VarDeclaration::isCTFE(%p, '%s')\n", this, toChars()); + //printf("%llx\n", storage_class); + return (storage_class & STCctfe) || !isDataseg(); +} + int VarDeclaration::hasPointers() { //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
--- a/dmd/declaration.h Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/declaration.h Wed Jan 06 15:18:22 2010 -0300 @@ -79,9 +79,16 @@ STCshared = 0x20000000, // accessible from multiple threads STCgshared = 0x40000000, // accessible from multiple threads // but not typed as "shared" - STC_TYPECTOR = (STCconst | STCimmutable | STCshared), + STCwild = 0x80000000, // for "wild" type constructor + STC_TYPECTOR = (STCconst | STCimmutable | STCshared | STCwild), }; +#define STCproperty 0x100000000LL +#define STCsafe 0x200000000LL +#define STCtrusted 0x400000000LL +#define STCsystem 0x800000000LL +#define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static + struct Match { int count; // number of matches found @@ -290,6 +297,7 @@ int isImportedSymbol(); int isDataseg(); int isThreadlocal(); + int isCTFE(); int hasPointers(); #if DMDV2 int canTakeAddressOf();
--- a/dmd/expression.c Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/expression.c Wed Jan 06 15:18:22 2010 -0300 @@ -711,6 +711,7 @@ Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i)); t = t->semantic(loc, sc); VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc)); + v->storage_class |= STCctfe; v->semantic(sc); v->parent = sc->parent; //sc->insert(v);
--- a/dmd/interpret.c Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/interpret.c Wed Jan 06 15:18:22 2010 -0300 @@ -48,6 +48,10 @@ Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); Expression *interpret_aaValues(InterState *istate, Expressions *arguments); +Expression *interpret_length(InterState *istate, Expression *earg); +Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd); +Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd); + /************************************* * Attempt to interpret a function given the arguments. * Input: @@ -66,12 +70,27 @@ #endif if (global.errors) return NULL; + +#if DMDV1 if (ident == Id::aaLen) return interpret_aaLen(istate, arguments); else if (ident == Id::aaKeys) return interpret_aaKeys(istate, arguments); else if (ident == Id::aaValues) return interpret_aaValues(istate, arguments); +#endif +#if DMDV2 + if (thisarg && + (!arguments || arguments->dim == 0)) + { + if (ident == Id::length) + return interpret_length(istate, thisarg); + else if (ident == Id::keys) + return interpret_keys(istate, thisarg, this); + else if (ident == Id::values) + return interpret_values(istate, thisarg, this); + } +#endif if (cantInterpret || semanticRun == 3) return NULL; @@ -94,9 +113,9 @@ assert(tb->ty == Tfunction); TypeFunction *tf = (TypeFunction *)tb; Type *tret = tf->next->toBasetype(); - if (tf->varargs) + if (tf->varargs && arguments && parameters && arguments->dim != parameters->dim) { cantInterpret = 1; - error("Variadic functions are not yet implemented in CTFE"); + error("C-style variadic functions are not yet implemented in CTFE"); return NULL; } @@ -1004,7 +1023,7 @@ } else { e = v->value; - if (v->isDataseg()) + if (!v->isCTFE()) { error(loc, "static variable %s cannot be read at compile time", v->toChars()); e = EXP_CANT_INTERPRET; } @@ -1136,9 +1155,7 @@ ex = e->interpret(istate); if (ex == EXP_CANT_INTERPRET) - { delete expsx; - return EXP_CANT_INTERPRET; - } + goto Lerror; /* If any changes, do Copy On Write */ @@ -1160,14 +1177,18 @@ { expandTuples(expsx); if (expsx->dim != elements->dim) - { delete expsx; - return EXP_CANT_INTERPRET; - } + goto Lerror; ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx); ae->type = type; return ae; } return this; + +Lerror: + if (expsx) + delete expsx; + error("cannot interpret array literal"); + return EXP_CANT_INTERPRET; } Expression *AssocArrayLiteralExp::interpret(InterState *istate) @@ -1594,12 +1615,12 @@ VarExp *ve = (VarExp *)e1; VarDeclaration *v = ve->var->isVarDeclaration(); assert(v); - if (v && v->isDataseg()) + if (v && !v->isCTFE()) { // Can't modify global or static data error("%s cannot be modified at compile time", v->toChars()); return EXP_CANT_INTERPRET; } - if (v && !v->isDataseg()) + if (v && v->isCTFE()) { Expression *ev = v->value; if (fp && !ev) @@ -1635,7 +1656,7 @@ else if (e1->op == TOKdotvar && aggregate->op == TOKvar) { VarDeclaration *v = ((VarExp *)aggregate)->var->isVarDeclaration(); - if (v->isDataseg()) + if (!v->isCTFE()) { // Can't modify global or static data error("%s cannot be modified at compile time", v->toChars()); return EXP_CANT_INTERPRET; @@ -1707,7 +1728,7 @@ { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; VarDeclaration *v = soe->var->isVarDeclaration(); - if (v->isDataseg()) + if (!v->isCTFE()) { error("%s cannot be modified at compile time", v->toChars()); return EXP_CANT_INTERPRET; @@ -1753,7 +1774,7 @@ { IndexExp *ie = (IndexExp *)e1; VarExp *ve = (VarExp *)ie->e1; VarDeclaration *v = ve->var->isVarDeclaration(); - if (!v || v->isDataseg()) + if (!v || !v->isCTFE()) { error("%s cannot be modified at compile time", v ? v->toChars(): "void"); return EXP_CANT_INTERPRET; @@ -1916,7 +1937,7 @@ IndexExp * ie = (IndexExp *)aggregate; VarExp *ve = (VarExp *)(ie->e1); VarDeclaration *v = ve->var->isVarDeclaration(); - if (!v || v->isDataseg()) + if (!v || !v->isCTFE()) { error("%s cannot be modified at compile time", v ? v->toChars(): "void"); return EXP_CANT_INTERPRET; @@ -2008,7 +2029,7 @@ SliceExp * sexp = (SliceExp *)e1; VarExp *ve = (VarExp *)(sexp->e1); VarDeclaration *v = ve->var->isVarDeclaration(); - if (!v || v->isDataseg()) + if (!v || !v->isCTFE()) { error("%s cannot be modified at compile time", v->toChars()); return EXP_CANT_INTERPRET; @@ -2636,6 +2657,8 @@ /******************************* Special Functions ***************************/ +#if DMDV1 + Expression *interpret_aaLen(InterState *istate, Expressions *arguments) { if (!arguments || arguments->dim != 1) @@ -2690,3 +2713,59 @@ return e; } +#endif + +#if DMDV2 + +Expression *interpret_length(InterState *istate, Expression *earg) +{ + //printf("interpret_length()\n"); + earg = earg->interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return NULL; + if (earg->op != TOKassocarrayliteral) + return NULL; + AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; + Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t); + return e; +} + +Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd) +{ +#if LOG + printf("interpret_keys()\n"); +#endif + earg = earg->interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return NULL; + if (earg->op != TOKassocarrayliteral) + return NULL; + AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; + Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); + assert(fd->type->ty == Tfunction); + assert(fd->type->nextOf()->ty == Tarray); + Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf(); + e->type = new TypeSArray(elemType, new IntegerExp(aae->keys->dim)); + return e; +} + +Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd) +{ + //printf("interpret_values()\n"); + earg = earg->interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return NULL; + if (earg->op != TOKassocarrayliteral) + return NULL; + AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; + Expression *e = new ArrayLiteralExp(aae->loc, aae->values); + assert(fd->type->ty == Tfunction); + assert(fd->type->nextOf()->ty == Tarray); + Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf(); + e->type = new TypeSArray(elemType, new IntegerExp(aae->values->dim)); + //printf("result is %s\n", e->toChars()); + return e; +} + +#endif +
--- a/dmd/mars.h Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/mars.h Wed Jan 06 15:18:22 2010 -0300 @@ -417,7 +417,7 @@ MATCHexact // exact match }; -typedef unsigned StorageClass; +typedef uint64_t StorageClass; void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
--- a/dmd/mtype.c Wed Jan 06 15:18:22 2010 -0300 +++ b/dmd/mtype.c Wed Jan 06 15:18:22 2010 -0300 @@ -5466,7 +5466,7 @@ /***************************** Parameter *****************************/ -Parameter::Parameter(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg) +Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg) { this->type = type; this->ident = ident;