Mercurial > projects > ldc
diff dmd/expression.c @ 336:aaade6ded589 trunk
[svn r357] Merged DMD 1.033
author | lindquist |
---|---|
date | Sat, 12 Jul 2008 19:38:31 +0200 |
parents | 7086a84ab3d6 |
children | 62715be72a06 |
line wrap: on
line diff
--- a/dmd/expression.c Sat Jul 12 17:04:36 2008 +0200 +++ b/dmd/expression.c Sat Jul 12 19:38:31 2008 +0200 @@ -111,6 +111,9 @@ precedence[TOKassert] = PREC_primary; precedence[TOKfunction] = PREC_primary; precedence[TOKvar] = PREC_primary; +#if DMDV2 + precedence[TOKdefault] = PREC_primary; +#endif // post precedence[TOKdotti] = PREC_primary; @@ -195,6 +198,89 @@ precedence[TOKcomma] = PREC_expr; } +/************************************************************* + * Given var, we need to get the + * right 'this' pointer if var is in an outer class, but our + * existing 'this' pointer is in an inner class. + * Input: + * e1 existing 'this' + * ad struct or class we need the correct 'this' for + * var the specific member of ad we're accessing + */ + +Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad, + Expression *e1, Declaration *var) +{ + //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars()); + L1: + Type *t = e1->type->toBasetype(); + //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars()); + + /* If e1 is not the 'this' pointer for ad + */ + if (ad && + !(t->ty == Tpointer && t->nextOf()->ty == Tstruct && + ((TypeStruct *)t->nextOf())->sym == ad) + && + !(t->ty == Tstruct && + ((TypeStruct *)t)->sym == ad) + ) + { + ClassDeclaration *cd = ad->isClassDeclaration(); + ClassDeclaration *tcd = t->isClassHandle(); + + /* e1 is the right this if ad is a base class of e1 + */ + if (!cd || !tcd || + !(tcd == cd || cd->isBaseOf(tcd, NULL)) + ) + { + /* Only classes can be inner classes with an 'outer' + * member pointing to the enclosing class instance + */ + if (tcd && tcd->isNested()) + { /* e1 is the 'this' pointer for an inner class: tcd. + * Rewrite it as the 'this' pointer for the outer class. + */ + + e1 = new DotVarExp(loc, e1, tcd->vthis); + e1->type = tcd->vthis->type; + // Do not call checkNestedRef() + //e1 = e1->semantic(sc); + + // Skip up over nested functions, and get the enclosing + // class type. + int n = 0; + Dsymbol *s; + for (s = tcd->toParent(); + s && s->isFuncDeclaration(); + s = s->toParent()) + { FuncDeclaration *f = s->isFuncDeclaration(); + if (f->vthis) + { + //printf("rewriting e1 to %s's this\n", f->toChars()); + n++; + e1 = new VarExp(loc, f->vthis); + } + } + if (s && s->isClassDeclaration()) + { e1->type = s->isClassDeclaration()->type; + if (n > 1) + e1 = e1->semantic(sc); + } + else + e1 = e1->semantic(sc); + goto L1; + } + /* Can't find a path from e1 to ad + */ + e1->error("this for %s needs to be type %s not type %s", + var->toChars(), ad->toChars(), t->toChars()); + } + } + return e1; +} + /***************************************** * Determine if 'this' is available. * If it is, return the FuncDeclaration that has it. @@ -383,6 +469,32 @@ } } +/********************************************* + * Call copy constructor for struct value argument. + */ +#if DMDV2 +Expression *callCpCtor(Loc loc, Scope *sc, Expression *e) +{ + Type *tb = e->type->toBasetype(); + assert(tb->ty == Tstruct); + StructDeclaration *sd = ((TypeStruct *)tb)->sym; + if (sd->cpctor) + { + /* Create a variable tmp, and replace the argument e with: + * (tmp = e),tmp + * and let AssignExp() handle the construction. + * This is not the most efficent, ideally tmp would be constructed + * directly onto the stack. + */ + Identifier *idtmp = Lexer::uniqueId("__tmp"); + VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e)); + Expression *ae = new DeclarationExp(loc, tmp); + e = new CommaExp(loc, ae, new VarExp(loc, tmp)); + e = e->semantic(sc); + } + return e; +} +#endif /**************************************** * Now that we know the exact type of the function we're calling, @@ -432,7 +544,15 @@ error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); break; } - arg = p->defaultArg->copy(); + arg = p->defaultArg; +#if DMDV2 + if (arg->op == TOKdefault) + { DefaultInitExp *de = (DefaultInitExp *)arg; + arg = de->resolve(loc, sc); + } + else +#endif + arg = arg->copy(); arguments->push(arg); nargs++; } @@ -572,7 +692,7 @@ tb = arg->type->toBasetype(); if (tb->ty == Tsarray) { TypeSArray *ts = (TypeSArray *)tb; - Type *ta = tb->next->arrayOf(); + Type *ta = ts->next->arrayOf(); if (ts->size(arg->loc) == 0) { arg = new NullExp(arg->loc); arg->type = ta; @@ -580,7 +700,19 @@ else arg = arg->castTo(sc, ta); } - +#if DMDV2 + if (tb->ty == Tstruct) + { + arg = callCpCtor(loc, sc, arg); + } + + // Give error for overloaded function addresses + if (arg->op == TOKsymoff) + { SymOffExp *se = (SymOffExp *)arg; + if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) + arg->error("function %s is overloaded", arg->toChars()); + } +#endif arg->rvalue(); } arg = arg->optimize(WANTvalue); @@ -609,6 +741,7 @@ void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) { + //if (precedence[e->op] == 0) e->dump(0); if (precedence[e->op] < pr) { buf->writeByte('('); @@ -706,7 +839,7 @@ Expression *Expression::semantic(Scope *sc) { #if LOGSEMANTIC - printf("Expression::semantic()\n"); + printf("Expression::semantic() %s\n", toChars()); #endif if (type) type = type->semantic(loc, sc); @@ -747,6 +880,7 @@ dump(0); halt(); #endif + type = Type::tint32; } } @@ -939,7 +1073,7 @@ e = new NullExp(loc); else e = new AddrExp(loc, this); - e->type = tb->next->pointerTo(); + e->type = ts->next->pointerTo(); } return e; } @@ -970,7 +1104,7 @@ { Expression *e; e = new PtrExp(loc, this); - e->type = type->next; + e->type = ((TypeReference *)type)->next; return e; } return this; @@ -994,6 +1128,18 @@ return FALSE; } +/******************************** + * Can this expression throw an exception? + * Valid only after semantic() pass. + */ + +int Expression::canThrow() +{ + return TRUE; +} + + + Expressions *Expression::arraySyntaxCopy(Expressions *exps) { Expressions *a = NULL; @@ -1019,6 +1165,7 @@ //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : ""); if (type && !type->isscalar()) { + //printf("%s, loc = %d\n", toChars(), loc.linnum); error("integral constant must be scalar type, not %s", type->toChars()); type = Type::terror; } @@ -1093,9 +1240,13 @@ } default: - print(); - type->print(); - assert(0); + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { type->print(); + assert(0); + } break; } break; @@ -1246,10 +1397,17 @@ goto L3; default: + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { #ifdef DEBUG - t->print(); + t->print(); #endif - assert(0); + assert(0); + } + break; } } else if (v & 0x8000000000000000LL) @@ -1993,7 +2151,8 @@ fd->nestedFrameRef = 1; } #endif - sc->callSuper |= CSXthis; + if (!sc->intypeof) + sc->callSuper |= CSXthis; return this; Lerr: @@ -2102,7 +2261,8 @@ } #endif - sc->callSuper |= CSXsuper; + if (!sc->intypeof) + sc->callSuper |= CSXsuper; return this; @@ -3396,6 +3556,7 @@ { #if LOGSEMANTIC printf("NewAnonClassExp::semantic() %s\n", toChars()); + //printf("thisexp = %p\n", thisexp); //printf("type: %s\n", type->toChars()); #endif @@ -3982,6 +4143,8 @@ #endif typeidType = typeidType->semantic(loc, sc); e = typeidType->getTypeInfo(sc); + if (e->loc.linnum == 0) + e->loc = loc; // so there's at least some line number info return e; } @@ -4258,7 +4421,7 @@ buf->writestring(" == "); tspec->toCBuffer(buf, NULL, hgs); } -#if V2 +#if DMDV2 if (parameters) { // First parameter is already output, so start with second for (int i = 1; i < parameters->dim; i++) @@ -4830,6 +4993,16 @@ return new TypeExp(loc, t); } + TupleDeclaration *tup = s->isTupleDeclaration(); + if (tup) + { + if (eleft) + error("cannot have e.tuple"); + e = new TupleExp(loc, tup); + e = e->semantic(sc); + return e; + } + ScopeDsymbol *sds = s->isScopeDsymbol(); if (sds) { @@ -4973,55 +5146,19 @@ if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution { AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); - L1: - Type *t = e1->type->toBasetype(); - - if (ad && - !(t->ty == Tpointer && t->next->ty == Tstruct && - ((TypeStruct *)t->next)->sym == ad) - && - !(t->ty == Tstruct && - ((TypeStruct *)t)->sym == ad) - ) - { - ClassDeclaration *cd = ad->isClassDeclaration(); - ClassDeclaration *tcd = t->isClassHandle(); - - if (!cd || !tcd || - !(tcd == cd || cd->isBaseOf(tcd, NULL)) - ) - { - if (tcd && tcd->isNested()) - { // Try again with outer scope - - e1 = new DotVarExp(loc, e1, tcd->vthis); - e1 = e1->semantic(sc); - - // Skip over nested functions, and get the enclosing - // class type. - Dsymbol *s = tcd->toParent(); - while (s && s->isFuncDeclaration()) - { FuncDeclaration *f = s->isFuncDeclaration(); - if (f->vthis) - { - e1 = new VarExp(loc, f->vthis); - } - s = s->toParent(); - } - if (s && s->isClassDeclaration()) - e1->type = s->isClassDeclaration()->type; - - e1 = e1->semantic(sc); - goto L1; - } -#ifdef DEBUG - printf("2: "); -#endif - error("this for %s needs to be type %s not type %s", - var->toChars(), ad->toChars(), t->toChars()); + e1 = getRightThis(loc, sc, ad, e1, var); + if (!sc->noaccesscheck) + accessCheck(loc, sc, e1, var); + + VarDeclaration *v = var->isVarDeclaration(); + if (v && v->isConst()) + { ExpInitializer *ei = v->getExpInitializer(); + if (ei) + { Expression *e = ei->exp->copy(); + e = e->semantic(sc); + return e; } } - accessCheck(loc, sc, e1, var); } } //printf("-DotVarExp::semantic('%s')\n", toChars()); @@ -5211,7 +5348,7 @@ return e; Lerr: - return new IntegerExp(0); + return new IntegerExp(loc, 0, Type::tint32); } void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -5239,44 +5376,9 @@ e1 = e1->semantic(sc); type = new TypeDelegate(func->type); type = type->semantic(loc, sc); -//----------------- - /* For func, we need to get the - * right 'this' pointer if func is in an outer class, but our - * existing 'this' pointer is in an inner class. - * This code is analogous to that used for variables - * in DotVarExp::semantic(). - */ AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration(); - L10: - Type *t = e1->type; - if (func->needThis() && ad && - !(t->ty == Tpointer && t->next->ty == Tstruct && - ((TypeStruct *)t->next)->sym == ad) && - !(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad) - ) - { - ClassDeclaration *cd = ad->isClassDeclaration(); - ClassDeclaration *tcd = t->isClassHandle(); - - if (!cd || !tcd || - !(tcd == cd || cd->isBaseOf(tcd, NULL)) - ) - { - if (tcd && tcd->isNested()) - { // Try again with outer scope - - e1 = new DotVarExp(loc, e1, tcd->vthis); - e1 = e1->semantic(sc); - goto L10; - } -#ifdef DEBUG - printf("3: "); -#endif - error("this for %s needs to be type %s not type %s", - func->toChars(), ad->toChars(), t->toChars()); - } - } -//----------------- + if (func->needThis()) + e1 = getRightThis(loc, sc, ad, e1, func); } return this; } @@ -5535,7 +5637,7 @@ DotTemplateExp *dte; AggregateDeclaration *ad; UnaExp *ue = (UnaExp *)(e1); - + if (e1->op == TOKdotvar) { // Do overload resolution dve = (DotVarExp *)(e1); @@ -5560,40 +5662,20 @@ } ad = td->toParent()->isAggregateDeclaration(); } - /* Now that we have the right function f, we need to get the - * right 'this' pointer if f is in an outer class, but our - * existing 'this' pointer is in an inner class. - * This code is analogous to that used for variables - * in DotVarExp::semantic(). + if (f->needThis()) + { + ue->e1 = getRightThis(loc, sc, ad, ue->e1, f); + } + + /* Cannot call public functions from inside invariant + * (because then the invariant would have infinite recursion) */ - L10: - Type *t = ue->e1->type->toBasetype(); - if (f->needThis() && ad && - !(t->ty == Tpointer && t->next->ty == Tstruct && - ((TypeStruct *)t->next)->sym == ad) && - !(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad) + if (sc->func && sc->func->isInvariantDeclaration() && + ue->e1->op == TOKthis && + f->addPostInvariant() ) { - ClassDeclaration *cd = ad->isClassDeclaration(); - ClassDeclaration *tcd = t->isClassHandle(); - - if (!cd || !tcd || - !(tcd == cd || cd->isBaseOf(tcd, NULL)) - ) - { - if (tcd && tcd->isNested()) - { // Try again with outer scope - - ue->e1 = new DotVarExp(loc, ue->e1, tcd->vthis); - ue->e1 = ue->e1->semantic(sc); - goto L10; - } -#ifdef DEBUG - printf("1: "); -#endif - error("this for %s needs to be type %s not type %s", - f->toChars(), ad->toChars(), t->toChars()); - } + error("cannot call public/export function %s from invariant", f->toChars()); } checkDeprecated(sc, f); @@ -5647,15 +5729,18 @@ } else { + if (!sc->intypeof) + { #if 0 - if (sc->callSuper & (CSXthis | CSXsuper)) - error("reference to this before super()"); + if (sc->callSuper & (CSXthis | CSXsuper)) + error("reference to this before super()"); #endif - if (sc->noctor || sc->callSuper & CSXlabel) - error("constructor calls not allowed in loops or after labels"); - if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) - error("multiple constructor calls"); - sc->callSuper |= CSXany_ctor | CSXsuper_ctor; + if (sc->noctor || sc->callSuper & CSXlabel) + error("constructor calls not allowed in loops or after labels"); + if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) + error("multiple constructor calls"); + sc->callSuper |= CSXany_ctor | CSXsuper_ctor; + } f = f->overloadResolve(loc, arguments); checkDeprecated(sc, f); @@ -5680,15 +5765,18 @@ } else { + if (!sc->intypeof) + { #if 0 - if (sc->callSuper & (CSXthis | CSXsuper)) - error("reference to this before super()"); + if (sc->callSuper & (CSXthis | CSXsuper)) + error("reference to this before super()"); #endif - if (sc->noctor || sc->callSuper & CSXlabel) - error("constructor calls not allowed in loops or after labels"); - if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) - error("multiple constructor calls"); - sc->callSuper |= CSXany_ctor | CSXthis_ctor; + if (sc->noctor || sc->callSuper & CSXlabel) + error("constructor calls not allowed in loops or after labels"); + if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) + error("multiple constructor calls"); + sc->callSuper |= CSXany_ctor | CSXthis_ctor; + } f = cd->ctor; f = f->overloadResolve(loc, arguments);