/* Compiler implementation of the D programming language * Copyright (C) 2009-2021 by The D Language Foundation, All Rights Reserved * written by Walter Bright * http://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. * http://www.boost.org/LICENSE_1_0.txt * https://github.com/D-Programming-Language/dmd/blob/master/src/aliasthis.c */ #include "root/dsystem.h" #include "mars.h" #include "identifier.h" #include "aliasthis.h" #include "scope.h" #include "aggregate.h" #include "dsymbol.h" #include "mtype.h" #include "declaration.h" #include "expression.h" #include "tokens.h" Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag) { AggregateDeclaration *ad = isAggregate(e->type); if (ad && ad->aliasthis) { unsigned olderrors = gag ? global.startGagging() : 0; Loc loc = e->loc; Type *tthis = (e->op == TOKtype ? e->type : NULL); e = new DotIdExp(loc, e, ad->aliasthis->ident); e = expressionSemantic(e, sc); if (tthis && ad->aliasthis->needThis()) { if (e->op == TOKvar) { if (FuncDeclaration *fd = ((VarExp *)e)->var->isFuncDeclaration()) { // Bugzilla 13009: Support better match for the overloaded alias this. bool hasOverloads = false; if (FuncDeclaration *f = fd->overloadModMatch(loc, tthis, hasOverloads)) { if (!hasOverloads) fd = f; // use exact match e = new VarExp(loc, fd, hasOverloads); e->type = f->type; e = new CallExp(loc, e); goto L1; } } } /* non-@property function is not called inside typeof(), * so resolve it ahead. */ { int save = sc->intypeof; sc->intypeof = 1; // bypass "need this" error check e = resolveProperties(sc, e); sc->intypeof = save; } L1: e = new TypeExp(loc, new TypeTypeof(loc, e)); e = expressionSemantic(e, sc); } e = resolveProperties(sc, e); if (gag && global.endGagging(olderrors)) e = NULL; } return e; } AliasThis::AliasThis(Loc loc, Identifier *ident) : Dsymbol(NULL) // it's anonymous (no identifier) { this->loc = loc; this->ident = ident; } Dsymbol *AliasThis::syntaxCopy(Dsymbol *s) { assert(!s); return new AliasThis(loc, ident); } const char *AliasThis::kind() const { return "alias this"; }