Mercurial > projects > ldc
diff dmd2/interpret.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 75c53f8f67a4 |
children | 54b3c1394d62 |
line wrap: on
line diff
--- a/dmd2/interpret.c Thu May 28 00:07:21 2009 +0200 +++ b/dmd2/interpret.c Sat May 30 17:23:32 2009 +0100 @@ -12,7 +12,7 @@ #include <stdlib.h> #include <assert.h> -#include "mem.h" +#include "rmem.h" #include "statement.h" #include "expression.h" @@ -69,7 +69,7 @@ else if (ident == Id::aaValues) return interpret_aaValues(istate, arguments); - if (cantInterpret || semanticRun == 1) + if (cantInterpret || semanticRun == 3) return NULL; if (needThis() || isNested() || !fbody) @@ -77,13 +77,13 @@ return NULL; } - if (semanticRun == 0 && scope) + if (semanticRun < 3 && scope) { semantic3(scope); - if (global.errors) // if errors compiling this function - return NULL; + if (global.errors) // if errors compiling this function + return NULL; } - if (semanticRun < 2) + if (semanticRun < 4) return NULL; Type *tb = type->toBasetype(); @@ -987,7 +987,11 @@ { Expression *e = EXP_CANT_INTERPRET; VarDeclaration *v = d->isVarDeclaration(); +#if IN_LLVM StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); +#else + SymbolDeclaration *s = d->isSymbolDeclaration(); +#endif if (v) { #if DMDV2 @@ -1513,6 +1517,80 @@ } } /* Assignment to struct member of the form: + * v.var = e2 + */ + else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) + { VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; + VarDeclaration *v = ve->var->isVarDeclaration(); + + if (v->isDataseg()) + return EXP_CANT_INTERPRET; + if (fp && !v->value) + { error("variable %s is used before initialization", v->toChars()); + return e; + } + if (v->value == NULL && v->init->isVoidInitializer()) + { /* Since a void initializer initializes to undefined + * values, it is valid here to use the default initializer. + * No attempt is made to determine if someone actually relies + * on the void value - to do that we'd need a VoidExp. + * That's probably a good enhancement idea. + */ + v->value = v->type->defaultInit(); + } + Expression *vie = v->value; + if (vie->op == TOKvar) + { + Declaration *d = ((VarExp *)vie)->var; + vie = getVarExp(e1->loc, istate, d); + } + if (vie->op != TOKstructliteral) + return EXP_CANT_INTERPRET; + StructLiteralExp *se = (StructLiteralExp *)vie; + VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); + if (!vf) + return EXP_CANT_INTERPRET; + int fieldi = se->getFieldIndex(type, vf->offset); + if (fieldi == -1) + return EXP_CANT_INTERPRET; + Expression *ev = se->getField(type, vf->offset); + if (fp) + e2 = (*fp)(type, ev, e2); + else + e2 = Cast(type, type, e2); + if (e2 == EXP_CANT_INTERPRET) + return e2; + + if (!v->isParameter()) + { + for (size_t i = 0; 1; i++) + { + if (i == istate->vars.dim) + { istate->vars.push(v); + break; + } + if (v == (VarDeclaration *)istate->vars.data[i]) + break; + } + } + + /* Create new struct literal reflecting updated fieldi + */ + Expressions *expsx = new Expressions(); + expsx->setDim(se->elements->dim); + for (size_t j = 0; j < expsx->dim; j++) + { + if (j == fieldi) + expsx->data[j] = (void *)e2; + else + expsx->data[j] = se->elements->data[j]; + } + v->value = new StructLiteralExp(se->loc, se->sd, expsx); + v->value->type = se->type; + + e = Cast(type, type, post ? ev : e2); + } + /* Assignment to struct member of the form: * *(symoffexp) = e2 */ else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) @@ -2159,21 +2237,29 @@ Expression *DotVarExp::interpret(InterState *istate) { Expression *e = EXP_CANT_INTERPRET; - Expression *ex = e1->interpret(istate); - - // Constant fold structliteral.member - if (ex != EXP_CANT_INTERPRET && ex->op == TOKstructliteral) - { StructLiteralExp *se = (StructLiteralExp *)ex; +#if LOG + printf("DotVarExp::interpret() %s\n", toChars()); +#endif - VarDeclaration* v; - if (v = var->isVarDeclaration()) - { - e = se->getField(type, v->offset); - if (!e) - e = EXP_CANT_INTERPRET; + Expression *ex = e1->interpret(istate); + if (ex != EXP_CANT_INTERPRET) + { + if (ex->op == TOKstructliteral) + { StructLiteralExp *se = (StructLiteralExp *)ex; + VarDeclaration *v = var->isVarDeclaration(); + if (v) + { e = se->getField(type, v->offset); + if (!e) + e = EXP_CANT_INTERPRET; + return e; + } } } +#if LOG + if (e == EXP_CANT_INTERPRET) + printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); +#endif return e; }