2 /* Compiler implementation of the D programming language
3 * Copyright (C) 2009-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/aliasthis.c
11 #include "root/dsystem.h"
14 #include "identifier.h"
15 #include "aliasthis.h"
17 #include "aggregate.h"
20 #include "declaration.h"
23 Expression
*semantic(Expression
*e
, Scope
*sc
);
25 Expression
*resolveAliasThis(Scope
*sc
, Expression
*e
, bool gag
)
27 AggregateDeclaration
*ad
= isAggregate(e
->type
);
29 if (ad
&& ad
->aliasthis
)
31 unsigned olderrors
= gag
? global
.startGagging() : 0;
34 Type
*tthis
= (e
->op
== TOKtype
? e
->type
: NULL
);
35 e
= new DotIdExp(loc
, e
, ad
->aliasthis
->ident
);
37 if (tthis
&& ad
->aliasthis
->needThis())
41 if (FuncDeclaration
*fd
= ((VarExp
*)e
)->var
->isFuncDeclaration())
43 // Bugzilla 13009: Support better match for the overloaded alias this.
44 bool hasOverloads
= false;
45 if (FuncDeclaration
*f
= fd
->overloadModMatch(loc
, tthis
, hasOverloads
))
48 fd
= f
; // use exact match
49 e
= new VarExp(loc
, fd
, hasOverloads
);
51 e
= new CallExp(loc
, e
);
56 /* non-@property function is not called inside typeof(),
57 * so resolve it ahead.
60 int save
= sc
->intypeof
;
61 sc
->intypeof
= 1; // bypass "need this" error check
62 e
= resolveProperties(sc
, e
);
67 e
= new TypeExp(loc
, new TypeTypeof(loc
, e
));
70 e
= resolveProperties(sc
, e
);
72 if (gag
&& global
.endGagging(olderrors
))
79 AliasThis::AliasThis(Loc loc
, Identifier
*ident
)
80 : Dsymbol(NULL
) // it's anonymous (no identifier)
86 Dsymbol
*AliasThis::syntaxCopy(Dsymbol
*s
)
89 return new AliasThis(loc
, ident
);
92 void AliasThis::semantic(Scope
*sc
)
94 if (semanticRun
!= PASSinit
)
106 semanticRun
= PASSsemantic
;
108 Dsymbol
*p
= sc
->parent
->pastMixin();
109 AggregateDeclaration
*ad
= p
->isAggregateDeclaration();
112 ::error(loc
, "alias this can only be a member of aggregate, not %s %s",
113 p
->kind(), p
->toChars());
118 Dsymbol
*s
= ad
->search(loc
, ident
);
121 s
= sc
->search(loc
, ident
, NULL
);
123 ::error(loc
, "%s is not a member of %s", s
->toChars(), ad
->toChars());
125 ::error(loc
, "undefined identifier %s", ident
->toChars());
128 else if (ad
->aliasthis
&& s
!= ad
->aliasthis
)
130 ::error(loc
, "there can be only one alias this");
134 if (ad
->type
->ty
== Tstruct
&& ((TypeStruct
*)ad
->type
)->sym
!= ad
)
136 AggregateDeclaration
*ad2
= ((TypeStruct
*)ad
->type
)->sym
;
137 assert(ad2
->type
== Type::terror
);
138 ad
->aliasthis
= ad2
->aliasthis
;
142 /* disable the alias this conversion so the implicit conversion check
145 ad
->aliasthis
= NULL
;
148 if (sx
->isAliasDeclaration())
150 Declaration
*d
= sx
->isDeclaration();
151 if (d
&& !d
->isTupleDeclaration())
155 if (ad
->type
->implicitConvTo(t
) > MATCHnomatch
)
157 ::error(loc
, "alias this is not reachable as %s already converts to %s", ad
->toChars(), t
->toChars());
162 semanticRun
= PASSsemanticdone
;
165 const char *AliasThis::kind() const