annotate dmd/ReturnStatement.d @ 178:e3afd1303184

Many small bugs fixed Made all classes derive from TObject to detect memory leaks (functionality is disabled for now) Began work on overriding backend memory allocations (to avoid memory leaks)
author korDen
date Sun, 17 Oct 2010 07:42:00 +0400
parents a43c65469219
children b0d41ff5e0df
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.ReturnStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
114
e28b18c23469 added a module dmd.common for commonly used stuff
Trass3r
parents: 93
diff changeset
3 import dmd.common;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.Loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
5 import dmd.Statement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
6 import dmd.GotoStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.STC;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
8 import dmd.CompoundStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
9 import dmd.Id;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
10 import dmd.AssignExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11 import dmd.ExpStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
12 import dmd.FuncDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import dmd.IntegerExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14 import dmd.ThisExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15 import dmd.StructDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
16 import dmd.TypeFunction;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
17 import dmd.CSX;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 import dmd.RET;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 import dmd.TOK;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
21 import dmd.Expression;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22 import dmd.StructLiteralExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23 import dmd.TypeStruct;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 import dmd.Scope;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25 import dmd.OutBuffer;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 import dmd.HdrGenState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27 import dmd.InterState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 import dmd.InlineCostState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29 import dmd.InlineDoState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 import dmd.InlineScanState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31 import dmd.IRState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 import dmd.TY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33 import dmd.WANT;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34 import dmd.VarExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 import dmd.VarDeclaration;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
36 import dmd.GlobalExpressions;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 import dmd.BE;
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
38 import dmd.Global;
67
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
39
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40 import dmd.codegen.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42 import dmd.backend.Blockx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
43 import dmd.backend.elem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 import dmd.backend.TYM;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
45 import dmd.backend.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 import dmd.backend.OPER;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 import dmd.backend.mTY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 import dmd.backend.BC;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49
67
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
50 import core.stdc.string;
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
51
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52 class ReturnStatement : Statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
53 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 Expression exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
55
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
56 this(Loc loc, Expression exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
57 {
178
e3afd1303184 Many small bugs fixed
korDen
parents: 155
diff changeset
58 register();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
59 super(loc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
60 this.exp = exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
61 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
62
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
63 override Statement syntaxCopy()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
64 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
65 Expression e = exp ? exp.syntaxCopy() : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 return new ReturnStatement(loc, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
68
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
69 override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70 {
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
71 buf.printf("return ");
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
72 if (exp)
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
73 exp.toCBuffer(buf, hgs);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
74 buf.writeByte(';');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
75 buf.writenl();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
76 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 79
diff changeset
78 override Statement semantic(Scope sc)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
80 //printf("ReturnStatement.semantic() %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
81
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
82 FuncDeclaration fd = sc.parent.isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
83 Scope scx = sc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
84 int implicit0 = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
85
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
86 if (sc.fes)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
87 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
88 // Find scope of function foreach is in
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
89 for (; 1; scx = scx.enclosing)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
90 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
91 assert(scx);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
92 if (scx.func !is fd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
93 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
94 fd = scx.func; // fd is now function enclosing foreach
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
95 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
96 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
97 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
98 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
99
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
100 Type tret = fd.type.nextOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
101 if (fd.tintro) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
102 /* We'll be implicitly casting the return expression to tintro
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
103 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
104 tret = fd.tintro.nextOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
105 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
106
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
107 Type tbret = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
108
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
109 if (tret) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
110 tbret = tret.toBasetype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
111 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
112
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
113 // main() returns 0, even if it returns void
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
114 if (!exp && (!tbret || tbret.ty == TY.Tvoid) && fd.isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
115 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
116 implicit0 = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
117 exp = new IntegerExp(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
118 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
119
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
120 if (sc.incontract || scx.incontract)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
121 error("return statements cannot be in contracts");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
122
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
123 if (sc.tf || scx.tf)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
124 error("return statements cannot be in finally, scope(exit) or scope(success) bodies");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
125
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
126 if (fd.isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
127 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
128 // Constructors implicitly do:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
129 // return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
130 if (exp && exp.op != TOK.TOKthis) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
131 error("cannot return expression from constructor");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
132 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
133
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
134 exp = new ThisExp(Loc(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
135 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
136
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
137 if (!exp) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
138 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
139 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
140
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
141 if (exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
142 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
143 fd.hasReturnExp |= 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
144
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
145 exp = exp.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
146 exp = resolveProperties(sc, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
147 exp = exp.optimize(WANT.WANTvalue);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
148
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
149 if (fd.nrvo_can && exp.op == TOK.TOKvar) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
150 VarExp ve = cast(VarExp)exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
151 VarDeclaration v = ve.var.isVarDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
152
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
153 if ((cast(TypeFunction)fd.type).isref) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
154 // Function returns a reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
155 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
156 } else if (!v || v.isOut() || v.isRef()) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
157 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
158 } else if (tbret.ty == TY.Tstruct && (cast(TypeStruct)tbret).sym.dtor) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
159 // Struct being returned has destructors
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
160 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
161 } else if (fd.nrvo_var is null) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
162 if (!v.isDataseg() && !v.isParameter() && v.toParent2() == fd) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
163 //printf("Setting nrvo to %s\n", v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
164 fd.nrvo_var = v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
165 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
166 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
167 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
168 } else if (fd.nrvo_var != v) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
169 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
170 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
171 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
172 fd.nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
173 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
174
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
175 if (fd.returnLabel && tbret.ty != TY.Tvoid) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
176 ;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
177 } else if (fd.inferRetType) {
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
178 auto tf = cast(TypeFunction)fd.type;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
179 assert(tf.ty == TY.Tfunction);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
180 Type tfret = tf.nextOf();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
181 if (tfret)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
182 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
183 if (!exp.type.equals(tfret))
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
184 error("mismatched function return type inference of %s and %s", exp.type.toChars(), tfret.toChars());
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
185 /* The "refness" is determined by the first return statement,
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
186 * not all of them. This means:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
187 * return 3; return x; // ok, x can be a value
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
188 * return x; return 3; // error, 3 is not an lvalue
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
189 */
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
190 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
191 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
192 {
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
193 if (tf.isref)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
194 { /* Determine "refness" of function return:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
195 * if it's an lvalue, return by ref, else return by value
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
196 */
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
197 if (exp.isLvalue())
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
198 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
199 /* Return by ref
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
200 * (but first ensure it doesn't fail the "check for
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
201 * escaping reference" test)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
202 */
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
203 uint errors = global.errors;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
204 global.gag++;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
205 exp.checkEscapeRef();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
206 global.gag--;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
207 if (errors != global.errors)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
208 { tf.isref = false; // return by value
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
209 global.errors = errors;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
210 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
211 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
212 else
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
213 tf.isref = false; // return by value
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
214 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
215 tf.next = exp.type;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
216 fd.type = tf.semantic(loc, sc);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
217
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
218 if (!fd.tintro)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
219 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
220 tret = fd.type.nextOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
221 tbret = tret.toBasetype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
222 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
223 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
224 } else if (tbret.ty != TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
225 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
226 exp = exp.implicitCastTo(sc, tret);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
227 exp = exp.optimize(WANT.WANTvalue);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
228 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
229 } else if (fd.inferRetType) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
230 if (fd.type.nextOf())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
231 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
232 if (fd.type.nextOf().ty != TY.Tvoid) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
233 error("mismatched function return type inference of void and %s", fd.type.nextOf().toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
234 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
235 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
236 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
237 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
238 (cast(TypeFunction*)fd.type).next = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
239 fd.type = fd.type.semantic(loc, sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
240 if (!fd.tintro)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
241 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
242 tret = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
243 tbret = tret;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
244 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
245 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
246 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
247 else if (tbret.ty != TY.Tvoid) {// if non-void return
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
248 error("return expression expected");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
249 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
250
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
251 if (sc.fes)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
252 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
253 Statement s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
254
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
255 if (exp && !implicit0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
256 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
257 exp = exp.implicitCastTo(sc, tret);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
258 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
259 if (!exp || exp.op == TOK.TOKint64 || exp.op == TOK.TOKfloat64 ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
260 exp.op == TOK.TOKimaginary80 || exp.op == TOK.TOKcomplex80 ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
261 exp.op == TOK.TOKthis || exp.op == TOK.TOKsuper || exp.op == TOK.TOKnull ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
262 exp.op == TOK.TOKstring)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
263 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
264 sc.fes.cases.push(cast(void*)this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
265 // Construct: return cases.dim+1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
266 s = new ReturnStatement(Loc(0), new IntegerExp(sc.fes.cases.dim + 1));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
267 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
268 else if (fd.type.nextOf().toBasetype() == Type.tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
269 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
270 s = new ReturnStatement(Loc(0), null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
271 sc.fes.cases.push(cast(void*)s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
272
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
273 // Construct: { exp; return cases.dim + 1; }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
274 Statement s1 = new ExpStatement(loc, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
275 Statement s2 = new ReturnStatement(Loc(0), new IntegerExp(sc.fes.cases.dim + 1));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
276 s = new CompoundStatement(loc, s1, s2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
277 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
278 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
279 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
280 // Construct: return vresult;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
281 if (!fd.vresult)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
282 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
283 // Declare vresult
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
284 VarDeclaration v = new VarDeclaration(loc, tret, Id.result, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
285 v.noauto = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
286 v.semantic(scx);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
287 if (!scx.insert(v)) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
288 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
289 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
290 v.parent = fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
291 fd.vresult = v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
292 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
293
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
294 s = new ReturnStatement(Loc(0), new VarExp(Loc(0), fd.vresult));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
295 sc.fes.cases.push(cast(void*)s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
296
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
297 // Construct: { vresult = exp; return cases.dim + 1; }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
298 exp = new AssignExp(loc, new VarExp(Loc(0), fd.vresult), exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
299 exp.op = TOK.TOKconstruct;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
300 exp = exp.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
301 Statement s1 = new ExpStatement(loc, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
302 Statement s2 = new ReturnStatement(Loc(0), new IntegerExp(sc.fes.cases.dim + 1));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
303 s = new CompoundStatement(loc, s1, s2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
304 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
305 return s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
306 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
307
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
308 if (exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
309 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
310 if (fd.returnLabel && tbret.ty != TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
311 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
312 assert(fd.vresult);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
313 VarExp v = new VarExp(Loc(0), fd.vresult);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
314
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
315 exp = new AssignExp(loc, v, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
316 exp.op = TOK.TOKconstruct;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
317 exp = exp.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
318 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
319
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
320 if ((cast(TypeFunction)fd.type).isref && !fd.isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
321 { // Function returns a reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
322 if (tbret.isMutable())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
323 exp = exp.modifiableLvalue(sc, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
324 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
325 exp = exp.toLvalue(sc, exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
326
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
327 exp.checkEscapeRef();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
328 }
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
329 else
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
330 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
331 //exp.dump(0);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
332 //exp.print();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
333 exp.checkEscape();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
334 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
335 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
336
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
337 /* BUG: need to issue an error on:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
338 * this
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
339 * { if (x) return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
340 * super();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
341 * }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
342 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
343
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
344 if (sc.callSuper & CSX.CSXany_ctor && !(sc.callSuper & (CSX.CSXthis_ctor | CSX.CSXsuper_ctor))) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
345 error("return without calling constructor");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
346 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
347
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
348 sc.callSuper |= CSX.CSXreturn;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
349
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
350 // See if all returns are instead to be replaced with a goto returnLabel;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
351 if (fd.returnLabel)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
352 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
353 GotoStatement gs = new GotoStatement(loc, Id.returnLabel);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
354
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
355 gs.label = fd.returnLabel;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
356 if (exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
357 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
358 /* Replace: return exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
359 * with: exp; goto returnLabel;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
360 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
361 Statement s = new ExpStatement(Loc(0), exp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
362 return new CompoundStatement(loc, s, gs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
363 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
364 return gs;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
365 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
366
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
367 if (exp && tbret.ty == Tvoid && !implicit0)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
368 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
369 /* Replace:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
370 * return exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
371 * with:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
372 * exp; return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
373 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
374 Statement s = new ExpStatement(loc, exp);
79
43073c7c7769 updated to 2.035
Trass3r
parents: 73
diff changeset
375 exp = null;
43073c7c7769 updated to 2.035
Trass3r
parents: 73
diff changeset
376 s = s.semantic(sc);
43073c7c7769 updated to 2.035
Trass3r
parents: 73
diff changeset
377 loc = Loc();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
378 return new CompoundStatement(loc, s, this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
379 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
380
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
381 return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
382 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
383
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
384 override BE blockExit()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
385 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
386 BE result = BE.BEreturn;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
387 if (exp && exp.canThrow())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
388 result |= BE.BEthrow;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
389
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
390 return result;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
391 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
392
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
393 override Expression interpret(InterState istate)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
394 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
395 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
396 printf("ReturnStatement.interpret(%s)\n", exp ? exp.toChars() : "");
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
397 }
155
a43c65469219 + Statement.interpret()
trass3r
parents: 135
diff changeset
398 mixin(START);
63
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
399 if (!exp)
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
400 return EXP_VOID_INTERPRET;
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
401 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
402 Expression e = exp.interpret(istate);
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
403 printf("e = %p\n", e);
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
404 return e;
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
405 } else {
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
406 return exp.interpret(istate);
cab4c37afb89 A bunch of implementations
korDen
parents: 0
diff changeset
407 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
408 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
409
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
410 override int inlineCost(InlineCostState* ics)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
411 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
412 // Can't handle return statements nested in if's
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
413 if (ics.nested)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
414 return COST_MAX;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
415 return exp ? exp.inlineCost(ics) : 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
416 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
417
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
418 override Expression doInline(InlineDoState ids)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
419 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
420 //printf("ReturnStatement.doInline() '%s'\n", exp ? exp.toChars() : "");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
421 return exp ? exp.doInline(ids) : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
422 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
423
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
424 override Statement inlineScan(InlineScanState* iss)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
425 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
426 //printf("ReturnStatement.inlineScan()\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
427 if (exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
428 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
429 exp = exp.inlineScan(iss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
430 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
431 return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
432 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
433
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
434 override void toIR(IRState* irs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
435 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
436 Blockx* blx = irs.blx;
68
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 67
diff changeset
437
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
438 incUsage(irs, loc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
439 if (exp)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
440 {
68
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 67
diff changeset
441 //printf("%.*s %.*s\n", exp.classinfo.name, exp.toChars());
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
442 elem *e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
443
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
444 FuncDeclaration func = irs.getFunc();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
445 assert(func);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
446 assert(func.type.ty == TY.Tfunction);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
447 TypeFunction tf = cast(TypeFunction)(func.type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
448
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
449 RET retmethod = tf.retStyle();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
450 if (retmethod == RET.RETstack)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
451 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
452 elem* es;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
453
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
454 /* If returning struct literal, write result
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
455 * directly into return value
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
456 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
457 if (exp.op == TOK.TOKstructliteral)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
458 {
68
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 67
diff changeset
459 StructLiteralExp se = cast(StructLiteralExp)exp;
67
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
460 enum objectSize = __traits(classInstanceSize, StructLiteralExp);
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
461 ubyte save[objectSize];
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
462 memcpy(save.ptr, cast(void*)se, objectSize);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
463 se.sym = irs.shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
464 se.soffset = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
465 se.fillHoles = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
466 e = exp.toElem(irs);
67
f708f0452e81 some of the backend/codegen stuff implemented
korDen
parents: 63
diff changeset
467 memcpy(cast(void*)se, save.ptr, objectSize);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
468 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
469 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
470 e = exp.toElem(irs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
471
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
472 assert(e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
473
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
474 if (exp.op == TOK.TOKstructliteral || (func.nrvo_can && func.nrvo_var))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
475 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
476 // Return value via hidden pointer passed as parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
477 // Write exp; return shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
478 es = e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
479 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
480 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
481 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
482 // Return value via hidden pointer passed as parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
483 // Write *shidden=exp; return shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
484 int op;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
485 tym_t ety;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
486
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
487 ety = e.Ety;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
488 es = el_una(OPER.OPind,ety,el_var(irs.shidden));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
489 op = (tybasic(ety) == TYM.TYstruct) ? OPER.OPstreq : OPER.OPeq;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
490 es = el_bin(op, ety, es, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
491 if (op == OPER.OPstreq)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
492 es.Enumbytes = cast(uint)exp.type.size();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
493 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
494 /* Call postBlit() on *shidden
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
495 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
496 Type tb = exp.type.toBasetype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
497 //if (tb.ty == TY.Tstruct) exp.dump(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
498 if ((exp.op == TOK.TOKvar || exp.op == TOK.TOKdotvar || exp.op == TOK.TOKstar) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
499 tb.ty == TY.Tstruct)
68
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 67
diff changeset
500 {
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 67
diff changeset
501 StructDeclaration sd = (cast(TypeStruct)tb).sym;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
502 if (sd.postblit)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
503 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
504 FuncDeclaration fd = sd.postblit;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
505 elem* ec = el_var(irs.shidden);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
506 ec = callfunc(loc, irs, 1, Type.tvoid, ec, tb.pointerTo(), fd, fd.type, null, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
507 es = el_bin(OPER.OPcomma, ec.Ety, es, ec);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
508 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
509
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
510 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
511 /* It has been moved, so disable destructor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
512 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
513 if (exp.op == TOK.TOKvar)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
514 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
515 VarExp ve = cast(VarExp)exp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
516 VarDeclaration v = ve.var.isVarDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
517 if (v && v.rundtor)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
518 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
519 elem* er = el_var(v.rundtor.toSymbol());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
520 er = el_bin(OPER.OPeq, TYM.TYint, er, el_long(TYM.TYint, 0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
521 es = el_bin(OPER.OPcomma, TYM.TYint, es, er);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
522 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
523 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
524 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
525 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
526 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
527 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
528 e = el_var(irs.shidden);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
529 e = el_bin(OPER.OPcomma, e.Ety, es, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
530 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
531 ///version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
532 else if (tf.isref)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
533 { // Reference return, so convert to a pointer
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
534 Expression ae = exp.addressOf(null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
535 e = ae.toElem(irs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
536 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
537 ///}
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
538 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
539 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
540 e = exp.toElem(irs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
541 assert(e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
542 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
543
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
544 block_appendexp(blx.curblock, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
545 block_next(blx, BC.BCretexp, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
546 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
547 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
548 block_next(blx, BC.BCret, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
549 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
550
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
551 override ReturnStatement isReturnStatement() { return this; }
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
552 }