72
|
1 module dmd.UnaExp;
|
|
2
|
114
|
3 import dmd.common;
|
72
|
4 import dmd.Expression;
|
|
5 import dmd.InterState;
|
|
6 import dmd.TY;
|
|
7 import dmd.TypeClass;
|
|
8 import dmd.TypeStruct;
|
|
9 import dmd.Dsymbol;
|
|
10 import dmd.AggregateDeclaration;
|
|
11 import dmd.Type;
|
|
12 import dmd.OutBuffer;
|
|
13 import dmd.Loc;
|
|
14 import dmd.TOK;
|
|
15 import dmd.Scope;
|
|
16 import dmd.InlineCostState;
|
|
17 import dmd.InlineDoState;
|
|
18 import dmd.HdrGenState;
|
|
19 import dmd.InlineScanState;
|
|
20 import dmd.DotIdExp;
|
|
21 import dmd.ArrayExp;
|
|
22 import dmd.CallExp;
|
|
23 import dmd.PREC;
|
|
24 import dmd.Token;
|
|
25 import dmd.expression.Util;
|
|
26
|
0
|
27 class UnaExp : Expression
|
|
28 {
|
|
29 Expression e1;
|
|
30
|
|
31 this(Loc loc, TOK op, int size, Expression e1)
|
|
32 {
|
72
|
33 super(loc, op, size);
|
0
|
34 this.e1 = e1;
|
|
35 }
|
|
36
|
72
|
37 override Expression syntaxCopy()
|
0
|
38 {
|
72
|
39 UnaExp e = cast(UnaExp)copy();
|
|
40 e.type = null;
|
|
41 e.e1 = e.e1.syntaxCopy();
|
|
42
|
0
|
43 return e;
|
|
44 }
|
|
45
|
72
|
46 override Expression semantic(Scope sc)
|
0
|
47 {
|
72
|
48 version (LOGSEMANTIC) {
|
|
49 writef("UnaExp.semantic('%s')\n", toChars());
|
|
50 }
|
|
51 e1 = e1.semantic(sc);
|
|
52 // if (!e1.type)
|
|
53 // error("%s has no value", e1.toChars());
|
0
|
54 return this;
|
|
55 }
|
|
56
|
72
|
57 override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
|
0
|
58 {
|
72
|
59 buf.writestring(Token.toChars(op));
|
0
|
60 expToCBuffer(buf, hgs, e1, precedence[op]);
|
|
61 }
|
|
62
|
72
|
63 override Expression optimize(int result)
|
0
|
64 {
|
72
|
65 e1 = e1.optimize(result);
|
0
|
66 return this;
|
|
67 }
|
|
68
|
72
|
69 override void dump(int indent)
|
0
|
70 {
|
|
71 assert(false);
|
|
72 }
|
|
73
|
72
|
74 override void scanForNestedRef(Scope sc)
|
0
|
75 {
|
64
|
76 e1.scanForNestedRef(sc);
|
0
|
77 }
|
|
78
|
63
|
79 Expression interpretCommon(InterState istate, Expression *(*fp)(Type* a0, Expression* a1))
|
0
|
80 {
|
|
81 assert(false);
|
|
82 }
|
|
83
|
72
|
84 override bool canThrow()
|
0
|
85 {
|
|
86 return e1.canThrow();
|
|
87 }
|
|
88
|
72
|
89 override int inlineCost(InlineCostState* ics)
|
0
|
90 {
|
|
91 return 1 + e1.inlineCost(ics);
|
|
92 }
|
|
93
|
72
|
94 override Expression doInline(InlineDoState ids)
|
0
|
95 {
|
72
|
96 UnaExp ue = cast(UnaExp)copy();
|
|
97
|
|
98 ue.e1 = e1.doInline(ids);
|
0
|
99 return ue;
|
|
100 }
|
|
101
|
72
|
102 override Expression inlineScan(InlineScanState* iss)
|
0
|
103 {
|
72
|
104 e1 = e1.inlineScan(iss);
|
0
|
105 return this;
|
72
|
106 }
|
|
107
|
|
108 /************************************
|
|
109 * Operator overload.
|
|
110 * Check for operator overload, if so, replace
|
|
111 * with function call.
|
|
112 * Return null if not an operator overload.
|
0
|
113 */
|
|
114 Expression op_overload(Scope sc)
|
|
115 {
|
72
|
116 //printf("UnaExp.op_overload() (%s)\n", toChars());
|
|
117 AggregateDeclaration ad;
|
|
118 Dsymbol fd;
|
|
119 Type t1 = e1.type.toBasetype();
|
|
120
|
|
121 if (t1.ty == TY.Tclass)
|
|
122 {
|
|
123 ad = (cast(TypeClass)t1).sym;
|
|
124 goto L1;
|
|
125 }
|
|
126 else if (t1.ty == TY.Tstruct)
|
|
127 {
|
|
128 ad = (cast(TypeStruct)t1).sym;
|
|
129
|
|
130 L1:
|
|
131 fd = search_function(ad, opId());
|
|
132 if (fd)
|
|
133 {
|
|
134 if (op == TOK.TOKarray)
|
|
135 {
|
|
136 /* Rewrite op e1[arguments] as:
|
|
137 * e1.fd(arguments)
|
|
138 */
|
|
139 Expression e = new DotIdExp(loc, e1, fd.ident);
|
|
140 ArrayExp ae = cast(ArrayExp)this;
|
|
141 e = new CallExp(loc, e, ae.arguments);
|
|
142 e = e.semantic(sc);
|
|
143 return e;
|
|
144 }
|
|
145 else
|
|
146 {
|
|
147 // Rewrite +e1 as e1.add()
|
|
148 return build_overload(loc, sc, e1, null, fd.ident);
|
|
149 }
|
|
150 }
|
|
151
|
|
152 version (DMDV2) {
|
|
153 // Didn't find it. Forward to aliasthis
|
|
154 if (ad.aliasthis)
|
|
155 {
|
|
156 /* Rewrite op(e1) as:
|
|
157 * op(e1.aliasthis)
|
|
158 */
|
|
159 Expression e1 = new DotIdExp(loc, this.e1, ad.aliasthis.ident);
|
|
160 Expression e = copy();
|
|
161 (cast(UnaExp)e).e1 = e1;
|
|
162 e = e.semantic(sc);
|
|
163 return e;
|
|
164 }
|
|
165 }
|
|
166 }
|
0
|
167 return null;
|
|
168 }
|
|
169 }
|
|
170
|