diff -r 81a419c39768 dmd/expression.c --- a/dmd/expression.c Sun Apr 19 21:25:38 2009 +0800 +++ b/dmd/expression.c Tue Apr 21 19:47:56 2009 +0800 @@ -5570,12 +5570,25 @@ return e; } #endif - else - { - e = e1->type->dotExp(sc, e1, ident); - e = e->semantic(sc); - return e; - } + else { + unsigned errors = global.errors; + global.gag++; + e = e1->type->dotExp(sc, e1, ident); + global.gag--; + if (errors != global.errors) // if failed to find the property + { + global.errors = errors; + StringExp *se = new StringExp(loc, ident->toChars()); + e = new DotIdExp(loc, e1, Id::opDot); + e = new CallExp2(loc, e, se); + } + else + { + e = e1->type->dotExp(sc, e1, ident); + e = e->semantic(sc); + } + return e; + } } void DotIdExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -6166,6 +6179,14 @@ { UnaExp::semantic(sc); + if (e1->isCallExp2()) + { + CallExp2 *ce = (CallExp2*)e1; + StringExp *se = (StringExp*)ce -> arguments->data[0]; + e1 = ce -> e1; + arguments->shift( se ); + e1 = e1 -> semantic(sc); + } /* Look for e1 being a lazy parameter */ if (e1->op == TOKvar) diff -r 81a419c39768 dmd/expression.h --- a/dmd/expression.h Sun Apr 19 21:25:38 2009 +0800 +++ b/dmd/expression.h Tue Apr 21 19:47:56 2009 +0800 @@ -136,6 +136,7 @@ virtual int isBit(); virtual int checkSideEffect(int flag); virtual int canThrow(); + virtual bool isCallExp2(){return false;} virtual int inlineCost(InlineCostState *ics); virtual Expression *doInline(InlineDoState *ids); @@ -897,6 +898,16 @@ Expression *inlineScan(InlineScanState *iss); }; +struct CallExp2 : CallExp +{ + CallExp2(Loc loc, Expression *e, Expressions *exps):CallExp(loc, e, exps){}; + CallExp2(Loc loc, Expression *e):CallExp(loc, e){}; + CallExp2(Loc loc, Expression *e, Expression *earg1):CallExp(loc, e, earg1){}; + CallExp2(Loc loc, Expression *e, Expression *earg1, Expression *earg2):CallExp(loc, e, earg1, earg2){}; + bool isCallExp2(){return true;} + +}; + struct AddrExp : UnaExp { AddrExp(Loc loc, Expression *e); diff -r 81a419c39768 dmd/mtype.c --- a/dmd/mtype.c Sun Apr 19 21:25:38 2009 +0800 +++ b/dmd/mtype.c Tue Apr 21 19:47:56 2009 +0800 @@ -6049,15 +6049,15 @@ /* Look for overloaded opDot() to see if we should forward request * to it. */ - Dsymbol *fd = search_function(sym, Id::opDot); +/* Dsymbol *fd = search_function(sym, Id::opDot); if (fd) - { /* Rewrite e.ident as: + {*/ /* Rewrite e.ident as: * e.opId().ident */ - e = build_overload(e->loc, sc, e, NULL, fd->ident); +/* e = build_overload(e->loc, sc, e, NULL, fd->ident); e = new DotIdExp(e->loc, e, ident); return e->semantic(sc); - } + }*/ } return Type::dotExp(sc, e, ident); diff -r 81a419c39768 dmd/opover.c --- a/dmd/opover.c Sun Apr 19 21:25:38 2009 +0800 +++ b/dmd/opover.c Tue Apr 21 19:47:56 2009 +0800 @@ -142,7 +142,7 @@ Identifier * ShrAssignExp::opId() { return Id::shrass; } Identifier *UshrAssignExp::opId() { return Id::ushrass; } Identifier * CatAssignExp::opId() { return Id::catass; } - + int EqualExp::isCommutative() { return TRUE; } Identifier *EqualExp::opId() { return Id::eq; } diff -r 81a419c39768 dmd/traits.c --- a/dmd/traits.c Sun Apr 19 21:25:38 2009 +0800 +++ b/dmd/traits.c Tue Apr 21 19:47:56 2009 +0800 @@ -285,34 +285,23 @@ { size_t dim = ScopeDsymbol::dim(sd->members); for (size_t i = 0; i < dim; i++) { - Dsymbol *sm = ScopeDsymbol::getNth(sd->members, i); - //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars()); - if (sm->ident) - { - //printf("\t%s\n", sm->ident->toChars()); - char *str = sm->ident->toChars(); + Dsymbol *sm = ScopeDsymbol::getNth(sd->members, i); - /* Skip if already present in exps[] - */ - for (size_t j = 0; j < exps->dim; j++) - { StringExp *se2 = (StringExp *)exps->data[j]; - if (strcmp(str, (char *)se2->string) == 0) - goto Lnext; - } - - StringExp *se = new StringExp(loc, str); - exps->push(se); - } - Lnext: - ; - } + if (sm->ident&& (sm->isFuncDeclaration()|| sm->isVarDeclaration())) + { + // if stringof works for functions which need arguments we won't need to push the ident here + // we can simply retrieve that by utilizing stringof + exps->push(new StringExp(loc, sm->ident->toChars())); + exps->push(new DsymbolExp(loc, sm)); + } + } ClassDeclaration *cd = sd->isClassDeclaration(); if (cd && cd->baseClass && ident == Id::allMembers) sd = cd->baseClass; // do again with base class else break; } - Expression *e = new ArrayLiteralExp(loc, exps); + Expression *e = new TupleExp(loc, exps); e = e->semantic(sc); return e; }