-
-
Notifications
You must be signed in to change notification settings - Fork 594
/
aliasthis.d
112 lines (103 loc) · 3.26 KB
/
aliasthis.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* Compiler implementation of the
* $(LINK2 http://www.dlang.org, D programming language).
*
* Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.d, _aliasthis.d)
* Documentation: https://dlang.org/phobos/dmd_aliasthis.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/aliasthis.d
*/
module dmd.aliasthis;
import core.stdc.stdio;
import dmd.aggregate;
import dmd.dscope;
import dmd.dsymbol;
import dmd.expression;
import dmd.expressionsem;
import dmd.globals;
import dmd.identifier;
import dmd.mtype;
import dmd.opover;
import dmd.tokens;
import dmd.visitor;
/***********************************************************
* alias ident this;
*/
extern (C++) final class AliasThis : Dsymbol
{
Identifier ident;
extern (D) this(const ref Loc loc, Identifier ident)
{
super(null); // it's anonymous (no identifier)
this.loc = loc;
this.ident = ident;
}
override Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
return new AliasThis(loc, ident);
}
override const(char)* kind() const
{
return "alias this";
}
AliasThis isAliasThis()
{
return this;
}
override void accept(Visitor v)
{
v.visit(this);
}
}
Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false)
{
AggregateDeclaration ad = isAggregate(e.type);
if (ad && ad.aliasthis)
{
uint olderrors = gag ? global.startGagging() : 0;
Loc loc = e.loc;
Type tthis = (e.op == TOK.type ? e.type : null);
e = new DotIdExp(loc, e, ad.aliasthis.ident);
e = e.expressionSemantic(sc);
if (tthis && ad.aliasthis.needThis())
{
if (e.op == TOK.variable)
{
if (auto fd = (cast(VarExp)e).var.isFuncDeclaration())
{
// https://issues.dlang.org/show_bug.cgi?id=13009
// Support better match for the overloaded alias this.
bool hasOverloads;
if (auto 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 = e.expressionSemantic(sc);
}
e = resolveProperties(sc, e);
if (gag && global.endGagging(olderrors))
e = null;
}
return e;
}