From a4d86a6e9f850e6e5b255da1949ebe45d8560182 Mon Sep 17 00:00:00 2001 From: k-hara Date: Wed, 29 Jan 2014 22:39:35 +0900 Subject: [PATCH 1/2] [Refactoring] clean up Dsymbol::semantic --- src/expression.c | 87 ++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/src/expression.c b/src/expression.c index 2c6ed56a536b..166036f16f44 100644 --- a/src/expression.c +++ b/src/expression.c @@ -3396,15 +3396,7 @@ Expression *DsymbolExp::semantic(Scope *sc) #endif Lagain: - EnumMember *em; Expression *e; - VarDeclaration *v; - FuncDeclaration *f; - FuncLiteralDeclaration *fld; - OverloadSet *o; - Import *imp; - Package *pkg; - Type *t; //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars()); //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind()); @@ -3416,40 +3408,36 @@ Expression *DsymbolExp::semantic(Scope *sc) if (s != olds && !s->isFuncDeclaration()) checkDeprecated(sc, s); - // BUG: This should happen after overload resolution for functions, not before - if (s->needThis()) + if (s->needThis() && hasThis(sc)) { - if (hasThis(sc) && !s->isFuncDeclaration()) + // For functions, this should happen after overload resolution + if (!s->isFuncDeclaration()) { // Supply an implicit 'this', as in // this.ident - - DotVarExp *de; - - de = new DotVarExp(loc, new ThisExp(loc), s->isDeclaration()); + DotVarExp *de = new DotVarExp(loc, new ThisExp(loc), s->isDeclaration()); return de->semantic(sc); } } - em = s->isEnumMember(); - if (em) + if (EnumMember *em = s->isEnumMember()) { return em->getVarExp(loc, sc); } - v = s->isVarDeclaration(); - if (v) + if (VarDeclaration *v = s->isVarDeclaration()) { //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars()); if (!type) - { if ((!v->type || !v->type->deco) && v->scope) + { + if ((!v->type || !v->type->deco) && v->scope) v->semantic(v->scope); type = v->type; if (!v->type) - { error("forward reference of %s %s", s->kind(), s->toChars()); + { + error("forward reference of %s %s", s->kind(), s->toChars()); return new ErrorExp(); } } - if ((v->storage_class & STCmanifest) && v->init) { if (v->scope) @@ -3461,7 +3449,8 @@ Expression *DsymbolExp::semantic(Scope *sc) } e = v->init->toExpression(v->type); if (!e) - { error("cannot make expression out of initializer for %s", v->toChars()); + { + error("cannot make expression out of initializer for %s", v->toChars()); return new ErrorExp(); } e = e->copy(); @@ -3475,14 +3464,13 @@ Expression *DsymbolExp::semantic(Scope *sc) e = e->semantic(sc); return e->deref(); } - fld = s->isFuncLiteralDeclaration(); - if (fld) - { //printf("'%s' is a function literal\n", fld->toChars()); + if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration()) + { + //printf("'%s' is a function literal\n", fld->toChars()); e = new FuncExp(loc, fld); return e->semantic(sc); } - f = s->isFuncDeclaration(); - if (f) + if (FuncDeclaration *f = s->isFuncDeclaration()) { f = f->toAliasFunc(); if (!f->functionSemantic()) @@ -3497,56 +3485,49 @@ Expression *DsymbolExp::semantic(Scope *sc) fd->type = f->type; return new VarExp(loc, fd, hasOverloads); } - o = s->isOverloadSet(); - if (o) - { //printf("'%s' is an overload set\n", o->toChars()); + if (OverloadSet *o = s->isOverloadSet()) + { + //printf("'%s' is an overload set\n", o->toChars()); return new OverExp(loc, o); } - imp = s->isImport(); - if (imp) + + if (Import *imp = s->isImport()) { if (!imp->pkg) - { error("forward reference of import %s", imp->toChars()); + { + error("forward reference of import %s", imp->toChars()); return new ErrorExp(); } ScopeExp *ie = new ScopeExp(loc, imp->pkg); return ie->semantic(sc); } - pkg = s->isPackage(); - if (pkg) + if (Package *pkg = s->isPackage()) { - ScopeExp *ie; - - ie = new ScopeExp(loc, pkg); + ScopeExp *ie = new ScopeExp(loc, pkg); return ie->semantic(sc); } - Module *mod = s->isModule(); - if (mod) + if (Module *mod = s->isModule()) { - ScopeExp *ie; - - ie = new ScopeExp(loc, mod); + ScopeExp *ie = new ScopeExp(loc, mod); return ie->semantic(sc); } - t = s->getType(); - if (t) + if (Type *t = s->getType()) { TypeExp *te = new TypeExp(loc, t); return te->semantic(sc); } - TupleDeclaration *tup = s->isTupleDeclaration(); - if (tup) + if (TupleDeclaration *tup = s->isTupleDeclaration()) { e = new TupleExp(loc, tup); e = e->semantic(sc); return e; } - TemplateInstance *ti = s->isTemplateInstance(); - if (ti) - { if (!ti->semanticRun) + if (TemplateInstance *ti = s->isTemplateInstance()) + { + if (!ti->semanticRun) ti->semantic(sc); s = ti->toAlias(); if (!s->isTemplateInstance()) @@ -3557,9 +3538,7 @@ Expression *DsymbolExp::semantic(Scope *sc) e = e->semantic(sc); return e; } - - TemplateDeclaration *td = s->isTemplateDeclaration(); - if (td) + if (TemplateDeclaration *td = s->isTemplateDeclaration()) { Dsymbol *p = td->toParent2(); FuncDeclaration *fdthis = hasThis(sc); From 244c5ac393bac632f1bff518c7155afd67986f5f Mon Sep 17 00:00:00 2001 From: k-hara Date: Wed, 29 Jan 2014 22:41:32 +0900 Subject: [PATCH 2/2] fix Issue 12023 - template mixin fails within template class --- src/expression.c | 13 +++++++++++-- test/runnable/mixin1.d | 44 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/expression.c b/src/expression.c index 166036f16f44..38eceac8820d 100644 --- a/src/expression.c +++ b/src/expression.c @@ -3408,6 +3408,17 @@ Expression *DsymbolExp::semantic(Scope *sc) if (s != olds && !s->isFuncDeclaration()) checkDeprecated(sc, s); + if (VarDeclaration *v = s->isVarDeclaration()) + { + /* Bugzilla 12023: forward reference should be resolved + * before 's->needThis()' is called. + */ + if ((!v->type || !v->type->deco) && v->scope) + { + v->semantic(v->scope); + s = v->toAlias(); // Need this if 'v' is a tuple variable + } + } if (s->needThis() && hasThis(sc)) { // For functions, this should happen after overload resolution @@ -3429,8 +3440,6 @@ Expression *DsymbolExp::semantic(Scope *sc) //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars()); if (!type) { - if ((!v->type || !v->type->deco) && v->scope) - v->semantic(v->scope); type = v->type; if (!v->type) { diff --git a/test/runnable/mixin1.d b/test/runnable/mixin1.d index 4c24c8368290..8c0d8bf95bc3 100644 --- a/test/runnable/mixin1.d +++ b/test/runnable/mixin1.d @@ -3,6 +3,8 @@ module mixin1; import std.stdio; +alias TypeTuple(T...) = T; + /*******************************************/ mixin template Foo(T) @@ -1259,6 +1261,47 @@ void test11767() static assert(!__traits(compiles, S11767)); } +/*******************************************/ +// 12023 + +void Delete12023(Object obj) {} + +template MessageCode12023() +{ + alias typeof(this) C; + + struct MessageDeinitHelper + { + C m_outer; + + ~this() + { + m_outer.DoDeinitMessaging(); + } + } + + CToClient toClient = null; + TypeTuple!(CToClient) toClients; + + class CToClient {} + + void DoDeinitMessaging() + { + Delete12023(toClient); + Delete12023(toClients); + } +} + +class TurretCannon12023(ProjectileClass) +{ + mixin MessageCode12023; +} + +void test12023() +{ + auto tc = new TurretCannon12023!Object(); +} + /*******************************************/ int main() @@ -1309,6 +1352,7 @@ int main() test42(); test9417(); test11767(); + test12023(); printf("Success\n"); return 0;