annotate dmd/statement.c @ 270:d9d5d59873d8 trunk

[svn r291] Fixed a bunch of the old Phobos tests to work with Tango. Branch statements now emit a new block after it. Fixed the _adSort runtime function had a bad signature. Added a missing dot prefix on compiler generated string tables for string switch. Fixed, PTRSIZE seems like it was wrong on 64bit, now it definitely gets set properly.
author lindquist
date Mon, 16 Jun 2008 16:01:19 +0200
parents 88252a1af660
children 665b81613475
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
159
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2 // Compiler implementation of the D programming language
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3 // Copyright (c) 1999-2007 by Digital Mars
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
4 // All Rights Reserved
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
5 // written by Walter Bright
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
6 // http://www.digitalmars.com
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
7 // License for redistribution is by either the Artistic License
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
9 // See the included readme.txt for details.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
10
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
11 #include <stdio.h>
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
12 #include <stdlib.h>
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
13 #include <assert.h>
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
14
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
15 #include "mem.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
16
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
17 #include "statement.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
18 #include "expression.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
19 #include "cond.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
20 #include "init.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
21 #include "staticassert.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
22 #include "mtype.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
23 #include "scope.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
24 #include "declaration.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
25 #include "aggregate.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
26 #include "id.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
27 #include "hdrgen.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
28 #include "parse.h"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
29
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
30 /******************************** Statement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
31
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
32 Statement::Statement(Loc loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
33 : loc(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
34 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
35 #ifdef _DH
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
36 // If this is an in{} contract scope statement (skip for determining
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
37 // inlineStatus of a function body for header content)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
38 incontract = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
39 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
40 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
41
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
42 Statement *Statement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
43 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
44 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
45 return NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
46 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
47
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
48 void Statement::print()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
49 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
50 fprintf(stdmsg, "%s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
51 fflush(stdmsg);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
52 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
53
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
54 char *Statement::toChars()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
55 { OutBuffer *buf;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
56 HdrGenState hgs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
57
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
58 buf = new OutBuffer();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
59 toCBuffer(buf, &hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
60 return buf->toChars();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
61 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
62
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
63 void Statement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
64 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
65 buf->printf("Statement::toCBuffer()");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
66 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
67 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
68
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
69 Statement *Statement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
70 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
71 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
72 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
73
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
74 // Same as semantic(), but do create a new scope
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
75
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
76 Statement *Statement::semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
77 { Scope *scd;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
78 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
79
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
80 scd = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
81 if (sbreak)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
82 scd->sbreak = sbreak;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
83 if (scontinue)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
84 scd->scontinue = scontinue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
85 s = semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
86 scd->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
87 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
88 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
89
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
90 void Statement::error(const char *format, ...)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
91 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
92 va_list ap;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
93 va_start(ap, format);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
94 ::verror(loc, format, ap);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
95 va_end( ap );
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
96 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
97
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
98 int Statement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
99 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
100 //printf("Statement::hasBreak()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
101 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
102 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
103
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
104 int Statement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
105 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
106 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
107 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
108
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
109 // TRUE if statement uses exception handling
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
110
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
111 int Statement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
112 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
113 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
114 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
115
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
116 // TRUE if statement may fall off the end without a throw or return
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
117
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
118 int Statement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
119 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
120 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
121 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
122
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
123 // TRUE if statement 'comes from' somewhere else, like a goto
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
124
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
125 int Statement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
126 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
127 //printf("Statement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
128 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
129 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
130
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
131 /****************************************
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
132 * If this statement has code that needs to run in a finally clause
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
133 * at the end of the current scope, return that code in the form of
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
134 * a Statement.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
135 * Output:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
136 * *sentry code executed upon entry to the scope
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
137 * *sexception code executed upon exit from the scope via exception
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
138 * *sfinally code executed in finally block
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
139 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
140
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
141 void Statement::scopeCode(Statement **sentry, Statement **sexception, Statement **sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
142 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
143 //printf("Statement::scopeCode()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
144 //print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
145 *sentry = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
146 *sexception = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
147 *sfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
148 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
149
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
150 /*********************************
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
151 * Flatten out the scope by presenting the statement
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
152 * as an array of statements.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
153 * Returns NULL if no flattening necessary.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
154 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
155
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
156 Statements *Statement::flatten(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
157 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
158 return NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
159 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
160
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
161
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
162 /******************************** ExpStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
163
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
164 ExpStatement::ExpStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
165 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
166 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
167 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
168 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
169
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
170 Statement *ExpStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
171 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
172 Expression *e = exp ? exp->syntaxCopy() : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
173 ExpStatement *es = new ExpStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
174 return es;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
175 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
176
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
177 void ExpStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
178 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
179 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
180 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
181 buf->writeByte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
182 if (!hgs->FLinit.init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
183 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
184 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
185
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
186 Statement *ExpStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
187 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
188 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
189 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
190 //printf("ExpStatement::semantic() %s\n", exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
191 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
192 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
193 exp->checkSideEffect(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
194 exp = exp->optimize(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
195 //exp = exp->optimize(isDeclarationStatement() ? WANTvalue : 0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
196 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
197 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
198 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
199
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
200 int ExpStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
201 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
202 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
203 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
204 if (exp->op == TOKassert)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
205 { AssertExp *a = (AssertExp *)exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
206
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
207 if (a->e1->isBool(FALSE)) // if it's an assert(0)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
208 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
209 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
210 else if (exp->op == TOKhalt)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
211 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
212 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
213 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
214 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
215
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
216 /******************************** CompileStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
217
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
218 CompileStatement::CompileStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
219 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
220 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
221 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
222 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
223
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
224 Statement *CompileStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
225 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
226 Expression *e = exp->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
227 CompileStatement *es = new CompileStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
228 return es;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
229 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
230
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
231 void CompileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
232 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
233 buf->writestring("mixin(");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
234 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
235 buf->writestring(");");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
236 if (!hgs->FLinit.init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
237 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
238 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
239
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
240 Statement *CompileStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
241 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
242 //printf("CompileStatement::semantic() %s\n", exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
243 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
244 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
245 exp = exp->optimize(WANTvalue | WANTinterpret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
246 if (exp->op != TOKstring)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
247 { error("argument to mixin must be a string, not (%s)", exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
248 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
249 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
250 StringExp *se = (StringExp *)exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
251 se = se->toUTF8(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
252 Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
253 p.loc = loc;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
254 p.nextToken();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
255
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
256 Statements *statements = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
257 while (p.token.value != TOKeof)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
258 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
259 Statement *s = p.parseStatement(PSsemi | PScurlyscope);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
260 statements->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
261 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
262
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
263 Statement *s = new CompoundStatement(loc, statements);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
264 return s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
265 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
266
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
267
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
268 /******************************** DeclarationStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
269
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
270 DeclarationStatement::DeclarationStatement(Loc loc, Dsymbol *declaration)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
271 : ExpStatement(loc, new DeclarationExp(loc, declaration))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
272 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
273 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
274
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
275 DeclarationStatement::DeclarationStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
276 : ExpStatement(loc, exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
277 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
278 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
279
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
280 Statement *DeclarationStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
281 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
282 DeclarationStatement *ds = new DeclarationStatement(loc, exp->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
283 return ds;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
284 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
285
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
286 void DeclarationStatement::scopeCode(Statement **sentry, Statement **sexception, Statement **sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
287 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
288 //printf("DeclarationStatement::scopeCode()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
289 //print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
290
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
291 *sentry = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
292 *sexception = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
293 *sfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
294
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
295 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
296 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
297 if (exp->op == TOKdeclaration)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
298 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
299 DeclarationExp *de = (DeclarationExp *)(exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
300 VarDeclaration *v = de->declaration->isVarDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
301 if (v)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
302 { Expression *e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
303
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
304 e = v->callAutoDtor();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
305 if (e)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
306 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
307 //printf("dtor is: "); e->print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
308 *sfinally = new ExpStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
309 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
310 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
311 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
312 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
313 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
314
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
315 void DeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
316 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
317 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
318 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
319
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
320
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
321 /******************************** CompoundStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
322
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
323 CompoundStatement::CompoundStatement(Loc loc, Statements *s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
324 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
325 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
326 statements = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
327 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
328
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
329 CompoundStatement::CompoundStatement(Loc loc, Statement *s1, Statement *s2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
330 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
331 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
332 statements = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
333 statements->reserve(2);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
334 statements->push(s1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
335 statements->push(s2);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
336 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
337
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
338 Statement *CompoundStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
339 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
340 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
341 a->setDim(statements->dim);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
342 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
343 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
344 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
345 s = s->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
346 a->data[i] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
347 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
348 CompoundStatement *cs = new CompoundStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
349 return cs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
350 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
351
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
352
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
353 Statement *CompoundStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
354 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
355
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
356 //printf("CompoundStatement::semantic(this = %p, sc = %p)\n", this, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
357
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
358 for (size_t i = 0; i < statements->dim; )
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
359 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
360 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
361 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
362 { Statements *a = s->flatten(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
363
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
364 if (a)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
365 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
366 statements->remove(i);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
367 statements->insert(i, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
368 continue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
369 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
370 s = s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
371 statements->data[i] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
372 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
373 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
374 Statement *sentry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
375 Statement *sexception;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
376 Statement *sfinally;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
377
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
378 s->scopeCode(&sentry, &sexception, &sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
379 if (sentry)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
380 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
381 sentry = sentry->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
382 statements->data[i] = sentry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
383 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
384 if (sexception)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
385 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
386 if (i + 1 == statements->dim && !sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
387 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
388 #if 1
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
389 sexception = sexception->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
390 #else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
391 statements->push(sexception);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
392 if (sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
393 // Assume sexception does not throw
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
394 statements->push(sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
395 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
396 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
397 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
398 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
399 /* Rewrite:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
400 * s; s1; s2;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
401 * As:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
402 * s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
403 * try { s1; s2; }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
404 * catch (Object __o)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
405 * { sexception; throw __o; }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
406 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
407 Statement *body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
408 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
409
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
410 for (int j = i + 1; j < statements->dim; j++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
411 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
412 a->push(statements->data[j]);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
413 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
414 body = new CompoundStatement(0, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
415 body = new ScopeStatement(0, body);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
416
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
417 static int num;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
418 char name[3 + sizeof(num) * 3 + 1];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
419 sprintf(name, "__o%d", ++num);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
420 Identifier *id = Lexer::idPool(name);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
421
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
422 Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
423 handler = new CompoundStatement(0, sexception, handler);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
424
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
425 Array *catches = new Array();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
426 Catch *ctch = new Catch(0, NULL, id, handler);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
427 catches->push(ctch);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
428 s = new TryCatchStatement(0, body, catches);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
429
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
430 if (sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
431 s = new TryFinallyStatement(0, s, sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
432 s = s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
433 statements->setDim(i + 1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
434 statements->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
435 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
436 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
437 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
438 else if (sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
439 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
440 if (0 && i + 1 == statements->dim)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
441 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
442 statements->push(sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
443 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
444 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
445 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
446 /* Rewrite:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
447 * s; s1; s2;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
448 * As:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
449 * s; try { s1; s2; } finally { sfinally; }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
450 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
451 Statement *body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
452 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
453
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
454 for (int j = i + 1; j < statements->dim; j++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
455 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
456 a->push(statements->data[j]);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
457 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
458 body = new CompoundStatement(0, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
459 s = new TryFinallyStatement(0, body, sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
460 s = s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
461 statements->setDim(i + 1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
462 statements->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
463 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
464 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
465 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
466 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
467 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
468 i++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
469 }
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 215
diff changeset
470 if (statements->dim == 1 && !isAsmBlockStatement())
159
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
471 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
472 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
473 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
474
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
475 Statements *CompoundStatement::flatten(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
476 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
477 return statements;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
478 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
479
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
480 ReturnStatement *CompoundStatement::isReturnStatement()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
481 { int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
482 ReturnStatement *rs = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
483
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
484 for (i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
485 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
486
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
487 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
488 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
489 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
490 rs = s->isReturnStatement();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
491 if (rs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
492 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
493 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
494 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
495 return rs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
496 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
497
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
498 void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
499 { int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
500
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
501 for (i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
502 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
503
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
504 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
505 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
506 s->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
507 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
508 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
509
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
510 int CompoundStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
511 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
512 for (int i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
513 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
514
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
515 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
516 if (s && s->usesEH())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
517 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
518 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
519 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
520 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
521
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
522 int CompoundStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
523 { int falloff = TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
524
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
525 //printf("CompoundStatement::fallOffEnd() %s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
526 for (int i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
527 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
528
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
529 if (!s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
530 continue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
531
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
532 if (!falloff && global.params.warnings && !s->comeFrom())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
533 {
215
a58d8f4b84df [svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents: 159
diff changeset
534 warning("%s: statement is not reachable", s->loc.toChars());
159
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
535 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
536 falloff = s->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
537 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
538 return falloff;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
539 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
540
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
541 int CompoundStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
542 { int comefrom = FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
543
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
544 //printf("CompoundStatement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
545 for (int i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
546 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
547
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
548 if (!s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
549 continue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
550
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
551 comefrom |= s->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
552 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
553 return comefrom;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
554 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
555
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
556
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
557 /**************************** UnrolledLoopStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
558
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
559 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
560 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
561 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
562 statements = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
563 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
564 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
565
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
566 Statement *UnrolledLoopStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
567 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
568 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
569 a->setDim(statements->dim);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
570 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
571 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
572 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
573 s = s->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
574 a->data[i] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
575 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
576 UnrolledLoopStatement *cs = new UnrolledLoopStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
577 return cs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
578 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
579
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
580
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
581 Statement *UnrolledLoopStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
582 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
583 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
584
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
585 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
586
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
587 sc->noctor++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
588 Scope *scd = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
589 scd->sbreak = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
590 scd->scontinue = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
591
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
592 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
593 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
594 Statement *s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
595 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
596 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
597 s = s->semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
598 statements->data[i] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
599 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
600 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
601
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
602 scd->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
603 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
604 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
605 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
606
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
607 void UnrolledLoopStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
608 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
609 buf->writestring("unrolled {");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
610 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
611
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
612 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
613 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
614
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
615 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
616 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
617 s->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
618 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
619
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
620 buf->writeByte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
621 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
622 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
623
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
624 int UnrolledLoopStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
625 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
626 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
627 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
628
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
629 int UnrolledLoopStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
630 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
631 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
632 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
633
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
634 int UnrolledLoopStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
635 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
636 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
637 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
638
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
639 s = (Statement *) statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
640 if (s && s->usesEH())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
641 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
642 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
643 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
644 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
645
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
646 int UnrolledLoopStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
647 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
648 //printf("UnrolledLoopStatement::fallOffEnd()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
649 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
650 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
651
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
652 if (s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
653 s->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
654 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
655 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
656 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
657
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
658
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
659 int UnrolledLoopStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
660 { int comefrom = FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
661
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
662 //printf("UnrolledLoopStatement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
663 for (size_t i = 0; i < statements->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
664 { Statement *s = (Statement *)statements->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
665
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
666 if (!s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
667 continue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
668
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
669 comefrom |= s->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
670 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
671 return comefrom;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
672 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
673
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
674
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
675 /******************************** ScopeStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
676
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
677 ScopeStatement::ScopeStatement(Loc loc, Statement *s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
678 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
679 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
680 this->statement = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
681 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
682
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
683 Statement *ScopeStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
684 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
685 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
686
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
687 s = statement ? statement->syntaxCopy() : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
688 s = new ScopeStatement(loc, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
689 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
690 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
691
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
692
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
693 Statement *ScopeStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
694 { ScopeDsymbol *sym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
695
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
696 //printf("ScopeStatement::semantic(sc = %p)\n", sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
697 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
698 { Statements *a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
699
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
700 sym = new ScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
701 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
702 sc = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
703
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
704 a = statement->flatten(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
705 if (a)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
706 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
707 statement = new CompoundStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
708 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
709
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
710 statement = statement->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
711 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
712 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
713 Statement *sentry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
714 Statement *sexception;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
715 Statement *sfinally;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
716
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
717 statement->scopeCode(&sentry, &sexception, &sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
718 if (sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
719 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
720 //printf("adding sfinally\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
721 statement = new CompoundStatement(loc, statement, sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
722 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
723 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
724
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
725 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
726 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
727 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
728 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
729
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
730 int ScopeStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
731 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
732 //printf("ScopeStatement::hasBreak() %s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
733 return statement ? statement->hasBreak() : FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
734 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
735
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
736 int ScopeStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
737 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
738 return statement ? statement->hasContinue() : FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
739 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
740
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
741 int ScopeStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
742 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
743 return statement ? statement->usesEH() : FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
744 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
745
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
746 int ScopeStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
747 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
748 return statement ? statement->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
749 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
750
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
751 int ScopeStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
752 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
753 //printf("ScopeStatement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
754 return statement ? statement->comeFrom() : FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
755 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
756
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
757 void ScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
758 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
759 buf->writeByte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
760 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
761
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
762 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
763 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
764
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
765 buf->writeByte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
766 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
767 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
768
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
769 /******************************** WhileStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
770
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
771 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
772 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
773 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
774 condition = c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
775 body = b;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
776 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
777 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
778
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
779 Statement *WhileStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
780 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
781 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
782 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
783 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
784
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
785
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
786 Statement *WhileStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
787 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
788 #if 0
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
789 if (condition->op == TOKmatch)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
790 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
791 /* Rewrite while (condition) body as:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
792 * if (condition)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
793 * do
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
794 * body
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
795 * while ((_match = _match.opNext), _match);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
796 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
797
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
798 Expression *ew = new IdentifierExp(0, Id::_match);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
799 ew = new DotIdExp(0, ew, Id::next);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
800 ew = new AssignExp(0, new IdentifierExp(0, Id::_match), ew);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
801 ////ew = new EqualExp(TOKnotequal, 0, ew, new NullExp(0));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
802 Expression *ev = new IdentifierExp(0, Id::_match);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
803 //ev = new CastExp(0, ev, Type::tvoidptr);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
804 ew = new CommaExp(0, ew, ev);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
805 Statement *sw = new DoStatement(loc, body, ew);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
806 Statement *si = new IfStatement(loc, condition, sw, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
807 return si->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
808 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
809 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
810
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
811 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
812
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
813 condition = condition->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
814 condition = resolveProperties(sc, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
815 condition = condition->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
816 condition = condition->checkToBoolean();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
817
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
818 sc->noctor++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
819
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
820 Scope *scd = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
821 scd->sbreak = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
822 scd->scontinue = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
823 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
824 body = body->semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
825 scd->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
826
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
827 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
828
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
829 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
830 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
831
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
832 int WhileStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
833 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
834 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
835 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
836
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
837 int WhileStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
838 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
839 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
840 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
841
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
842 int WhileStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
843 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
844 return body ? body->usesEH() : 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
845 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
846
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
847 int WhileStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
848 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
849 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
850 body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
851 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
852 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
853
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
854 int WhileStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
855 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
856 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
857 return body->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
858 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
859 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
860
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
861 void WhileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
862 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
863 buf->writestring("while (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
864 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
865 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
866 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
867 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
868 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
869 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
870
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
871 /******************************** DoStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
872
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
873 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
874 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
875 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
876 body = b;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
877 condition = c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
878 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
879 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
880
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
881 Statement *DoStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
882 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
883 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
884 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
885 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
886
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
887
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
888 Statement *DoStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
889 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
890 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
891
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
892 sc->noctor++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
893 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
894 body = body->semanticScope(sc, this, this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
895 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
896 condition = condition->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
897 condition = resolveProperties(sc, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
898 condition = condition->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
899
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
900 condition = condition->checkToBoolean();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
901
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
902 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
903 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
904
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
905 int DoStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
906 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
907 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
908 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
909
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
910 int DoStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
911 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
912 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
913 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
914
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
915 int DoStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
916 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
917 return body ? body->usesEH() : 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
918 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
919
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
920 int DoStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
921 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
922 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
923 body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
924 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
925 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
926
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
927 int DoStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
928 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
929 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
930 return body->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
931 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
932 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
933
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
934 void DoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
935 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
936 buf->writestring("do");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
937 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
938 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
939 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
940 buf->writestring("while (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
941 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
942 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
943 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
944
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
945 /******************************** ForStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
946
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
947 ForStatement::ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
948 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
949 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
950 this->init = init;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
951 this->condition = condition;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
952 this->increment = increment;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
953 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
954 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
955 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
956
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
957 Statement *ForStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
958 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
959 Statement *i = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
960 if (init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
961 i = init->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
962 Expression *c = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
963 if (condition)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
964 c = condition->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
965 Expression *inc = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
966 if (increment)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
967 inc = increment->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
968 ForStatement *s = new ForStatement(loc, i, c, inc, body->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
969 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
970 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
971
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
972 Statement *ForStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
973 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
974 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
975
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
976 ScopeDsymbol *sym = new ScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
977 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
978 sc = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
979 if (init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
980 init = init->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
981 if (!condition)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
982 // Use a default value
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
983 condition = new IntegerExp(loc, 1, Type::tboolean);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
984 sc->noctor++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
985 condition = condition->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
986 condition = resolveProperties(sc, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
987 condition = condition->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
988 condition = condition->checkToBoolean();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
989 if (increment)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
990 increment = increment->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
991
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
992 sc->sbreak = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
993 sc->scontinue = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
994 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
995 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
996
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
997 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
998 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
999 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1000
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1001 void ForStatement::scopeCode(Statement **sentry, Statement **sexception, Statement **sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1002 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1003 //printf("ForStatement::scopeCode()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1004 //print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1005 if (init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1006 init->scopeCode(sentry, sexception, sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1007 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1008 Statement::scopeCode(sentry, sexception, sfinally);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1009 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1010
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1011 int ForStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1012 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1013 //printf("ForStatement::hasBreak()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1014 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1015 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1016
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1017 int ForStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1018 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1019 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1020 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1021
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1022 int ForStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1023 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1024 return (init && init->usesEH()) || body->usesEH();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1025 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1026
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1027 int ForStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1028 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1029 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1030 body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1031 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1032 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1033
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1034 int ForStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1035 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1036 //printf("ForStatement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1037 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1038 { int result = body->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1039 //printf("result = %d\n", result);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1040 return result;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1041 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1042 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1043 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1044
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1045 void ForStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1046 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1047 buf->writestring("for (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1048 if (init)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1049 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1050 hgs->FLinit.init++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1051 hgs->FLinit.decl = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1052 init->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1053 if (hgs->FLinit.decl > 0)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1054 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1055 hgs->FLinit.decl = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1056 hgs->FLinit.init--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1057 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1058 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1059 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1060 if (condition)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1061 { buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1062 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1063 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1064 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1065 if (increment)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1066 { buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1067 increment->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1068 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1069 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1070 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1071 buf->writebyte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1072 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1073 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1074 buf->writebyte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1075 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1076 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1077
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1078 /******************************** ForeachStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1079
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1080 ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Arguments *arguments,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1081 Expression *aggr, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1082 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1083 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1084 this->op = op;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1085 this->arguments = arguments;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1086 this->aggr = aggr;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1087 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1088 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1089
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1090 this->key = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1091 this->value = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1092
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1093 this->func = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1094 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1095
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1096 Statement *ForeachStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1097 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1098 Arguments *args = Argument::arraySyntaxCopy(arguments);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1099 Expression *exp = aggr->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1100 ForeachStatement *s = new ForeachStatement(loc, op, args, exp,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1101 body ? body->syntaxCopy() : NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1102 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1103 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1104
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1105 Statement *ForeachStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1106 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1107 //printf("ForeachStatement::semantic() %p\n", this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1108 ScopeDsymbol *sym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1109 Statement *s = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1110 int dim = arguments->dim;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1111 int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1112 TypeAArray *taa = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1113
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1114 Type *tn = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1115 Type *tnv = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1116
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1117 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1118
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1119 func = sc->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1120 if (func->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1121 func = func->fes->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1122
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1123 aggr = aggr->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1124 aggr = resolveProperties(sc, aggr);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1125 if (!aggr->type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1126 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1127 error("invalid foreach aggregate %s", aggr->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1128 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1129 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1130
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1131 inferApplyArgTypes(op, arguments, aggr);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1132
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1133 /* Check for inference errors
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1134 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1135 if (dim != arguments->dim)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1136 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1137 //printf("dim = %d, arguments->dim = %d\n", dim, arguments->dim);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1138 error("cannot uniquely infer foreach argument types");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1139 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1140 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1141
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1142 Type *tab = aggr->type->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1143
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1144 if (tab->ty == Ttuple) // don't generate new scope for tuple loops
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1145 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1146 if (dim < 1 || dim > 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1147 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1148 error("only one (value) or two (key,value) arguments for tuple foreach");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1149 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1150 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1151
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1152 TypeTuple *tuple = (TypeTuple *)tab;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1153 Statements *statements = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1154 //printf("aggr: op = %d, %s\n", aggr->op, aggr->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1155 size_t n;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1156 TupleExp *te = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1157 if (aggr->op == TOKtuple) // expression tuple
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1158 { te = (TupleExp *)aggr;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1159 n = te->exps->dim;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1160 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1161 else if (aggr->op == TOKtype) // type tuple
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1162 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1163 n = Argument::dim(tuple->arguments);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1164 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1165 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1166 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1167 for (size_t j = 0; j < n; j++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1168 { size_t k = (op == TOKforeach) ? j : n - 1 - j;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1169 Expression *e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1170 Type *t;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1171 if (te)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1172 e = (Expression *)te->exps->data[k];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1173 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1174 t = Argument::getNth(tuple->arguments, k)->type;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1175 Argument *arg = (Argument *)arguments->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1176 Statements *st = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1177
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1178 if (dim == 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1179 { // Declare key
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1180 if (arg->storageClass & (STCout | STCref | STClazy))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1181 error("no storage class for key %s", arg->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1182 TY keyty = arg->type->ty;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1183 if ((keyty != Tint32 && keyty != Tuns32) &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1184 (global.params.is64bit && keyty != Tint64 && keyty != Tuns64)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1185 )
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1186 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1187 error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint",arg->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1188 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1189 Initializer *ie = new ExpInitializer(0, new IntegerExp(k));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1190 VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1191 var->storage_class |= STCconst;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1192 DeclarationExp *de = new DeclarationExp(loc, var);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1193 st->push(new ExpStatement(loc, de));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1194 arg = (Argument *)arguments->data[1]; // value
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1195 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1196 // Declare value
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1197 if (arg->storageClass & (STCout | STCref | STClazy))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1198 error("no storage class for value %s", arg->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1199 Dsymbol *var;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1200 if (te)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1201 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1202 if (e->type->toBasetype()->ty == Tfunction &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1203 e->op == TOKvar)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1204 { VarExp *ve = (VarExp *)e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1205 var = new AliasDeclaration(loc, arg->ident, ve->var);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1206 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1207 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1208 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1209 arg->type = e->type;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1210 Initializer *ie = new ExpInitializer(0, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1211 VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1212 if (e->isConst())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1213 v->storage_class |= STCconst;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1214 #if V2
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1215 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1216 v->storage_class |= STCfinal;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1217 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1218 var = v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1219 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1220 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1221 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1222 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1223 var = new AliasDeclaration(loc, arg->ident, t);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1224 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1225 DeclarationExp *de = new DeclarationExp(loc, var);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1226 st->push(new ExpStatement(loc, de));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1227
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1228 st->push(body->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1229 s = new CompoundStatement(loc, st);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1230 s = new ScopeStatement(loc, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1231 statements->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1232 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1233
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1234 s = new UnrolledLoopStatement(loc, statements);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1235 s = s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1236 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1237 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1238
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1239 for (i = 0; i < dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1240 { Argument *arg = (Argument *)arguments->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1241 if (!arg->type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1242 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1243 error("cannot infer type for %s", arg->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1244 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1245 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1246 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1247
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1248 sym = new ScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1249 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1250 sc = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1251
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1252 sc->noctor++;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1253
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1254 switch (tab->ty)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1255 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1256 case Tarray:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1257 case Tsarray:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1258 if (dim < 1 || dim > 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1259 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1260 error("only one or two arguments for array foreach");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1261 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1262 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1263
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1264 /* Look for special case of parsing char types out of char type
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1265 * array.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1266 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1267 tn = tab->nextOf()->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1268 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1269 { Argument *arg;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1270
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1271 i = (dim == 1) ? 0 : 1; // index of value
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1272 arg = (Argument *)arguments->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1273 arg->type = arg->type->semantic(loc, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1274 tnv = arg->type->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1275 if (tnv->ty != tn->ty &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1276 (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1277 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1278 if (arg->storageClass & STCref)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1279 error("foreach: value of UTF conversion cannot be ref");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1280 if (dim == 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1281 { arg = (Argument *)arguments->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1282 if (arg->storageClass & STCref)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1283 error("foreach: key cannot be ref");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1284 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1285 goto Lapply;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1286 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1287 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1288
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1289 for (i = 0; i < dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1290 { // Declare args
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1291 Argument *arg = (Argument *)arguments->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1292 VarDeclaration *var;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1293
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1294 var = new VarDeclaration(loc, arg->type, arg->ident, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1295 var->storage_class |= STCforeach;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1296 var->storage_class |= arg->storageClass & (STCin | STCout | STCref);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1297 #if 1
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1298 DeclarationExp *de = new DeclarationExp(loc, var);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1299 de->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1300 #else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1301 var->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1302 if (!sc->insert(var))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1303 error("%s already defined", var->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1304 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1305 if (dim == 2 && i == 0)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1306 key = var;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1307 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1308 value = var;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1309 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1310
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1311 sc->sbreak = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1312 sc->scontinue = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1313 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1314
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1315 if (!value->type->equals(tab->next))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1316 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1317 if (aggr->op == TOKstring)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1318 aggr = aggr->implicitCastTo(sc, value->type->arrayOf());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1319 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1320 error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1321 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1322
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1323 if (key &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1324 ((key->type->ty != Tint32 && key->type->ty != Tuns32) &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1325 (global.params.is64bit && key->type->ty != Tint64 && key->type->ty != Tuns64)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1326 )
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1327 )
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1328 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1329 error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint", key->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1330 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1331
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1332 if (key && key->storage_class & (STCout | STCref))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1333 error("foreach: key cannot be out or ref");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1334 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1335
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1336 case Taarray:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1337 taa = (TypeAArray *)tab;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1338 if (dim < 1 || dim > 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1339 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1340 error("only one or two arguments for associative array foreach");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1341 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1342 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1343 if (op == TOKforeach_reverse)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1344 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1345 error("no reverse iteration on associative arrays");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1346 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1347 goto Lapply;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1348
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1349 case Tclass:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1350 case Tstruct:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1351 case Tdelegate:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1352 Lapply:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1353 { FuncDeclaration *fdapply;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1354 Arguments *args;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1355 Expression *ec;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1356 Expression *e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1357 FuncLiteralDeclaration *fld;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1358 Argument *a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1359 Type *t;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1360 Expression *flde;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1361 Identifier *id;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1362 Type *tret;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1363
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1364 tret = func->type->nextOf();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1365
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1366 // Need a variable to hold value from any return statements in body.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1367 if (!sc->func->vresult && tret && tret != Type::tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1368 { VarDeclaration *v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1369
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1370 v = new VarDeclaration(loc, tret, Id::result, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1371 v->noauto = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1372 v->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1373 if (!sc->insert(v))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1374 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1375 v->parent = sc->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1376 sc->func->vresult = v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1377 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1378
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1379 /* Turn body into the function literal:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1380 * int delegate(ref T arg) { body }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1381 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1382 args = new Arguments();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1383 for (i = 0; i < dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1384 { Argument *arg = (Argument *)arguments->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1385
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1386 arg->type = arg->type->semantic(loc, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1387 if (arg->storageClass & STCref)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1388 id = arg->ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1389 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1390 { // Make a copy of the ref argument so it isn't
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1391 // a reference.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1392 VarDeclaration *v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1393 Initializer *ie;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1394 char applyArg[10 + sizeof(i)*3 + 1];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1395
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1396 sprintf(applyArg, "__applyArg%d", i);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1397 id = Lexer::idPool(applyArg);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1398
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1399 ie = new ExpInitializer(0, new IdentifierExp(0, id));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1400 v = new VarDeclaration(0, arg->type, arg->ident, ie);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1401 s = new DeclarationStatement(0, v);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1402 body = new CompoundStatement(loc, s, body);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1403 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1404 a = new Argument(STCref, arg->type, id, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1405 args->push(a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1406 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1407 t = new TypeFunction(args, Type::tint32, 0, LINKd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1408 fld = new FuncLiteralDeclaration(loc, 0, t, TOKdelegate, this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1409 fld->fbody = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1410 flde = new FuncExp(loc, fld);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1411 flde = flde->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1412
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1413 // Resolve any forward referenced goto's
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1414 for (int i = 0; i < gotos.dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1415 { CompoundStatement *cs = (CompoundStatement *)gotos.data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1416 GotoStatement *gs = (GotoStatement *)cs->statements->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1417
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1418 if (!gs->label->statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1419 { // 'Promote' it to this scope, and replace with a return
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1420 cases.push(gs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1421 s = new ReturnStatement(0, new IntegerExp(cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1422 cs->statements->data[0] = (void *)s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1423 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1424 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1425
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1426 if (tab->ty == Taarray)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1427 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1428 // Check types
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1429 Argument *arg = (Argument *)arguments->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1430 if (dim == 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1431 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1432 if (arg->storageClass & STCref)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1433 error("foreach: index cannot be ref");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1434 if (!arg->type->equals(taa->index))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1435 error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1436 arg = (Argument *)arguments->data[1];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1437 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1438 if (!arg->type->equals(taa->nextOf()))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1439 error("foreach: value must be type %s, not %s", taa->nextOf()->toChars(), arg->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1440
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1441 /* Call:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1442 * _aaApply(aggr, keysize, flde)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1443 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1444 if (dim == 2)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1445 fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1446 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1447 fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1448 fdapply->runTimeHack = true;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1449 ec = new VarExp(0, fdapply);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1450 Expressions *exps = new Expressions();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1451 exps->push(aggr);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1452 size_t keysize = taa->key->size();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1453 keysize = (keysize + 3) & ~3;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1454 exps->push(new IntegerExp(0, keysize, Type::tsize_t));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1455 exps->push(flde);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1456 e = new CallExp(loc, ec, exps);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1457 e->type = Type::tindex; // don't run semantic() on e
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1458 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1459 else if (tab->ty == Tarray || tab->ty == Tsarray)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1460 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1461 /* Call:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1462 * _aApply(aggr, flde)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1463 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1464 static char fntab[9][3] =
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1465 { "cc","cw","cd",
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1466 "wc","cc","wd",
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1467 "dc","dw","dd"
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1468 };
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1469 char fdname[7+1+2+ sizeof(dim)*3 + 1];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1470 int flag;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1471
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1472 switch (tn->ty)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1473 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1474 case Tchar: flag = 0; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1475 case Twchar: flag = 3; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1476 case Tdchar: flag = 6; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1477 default: assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1478 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1479 switch (tnv->ty)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1480 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1481 case Tchar: flag += 0; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1482 case Twchar: flag += 1; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1483 case Tdchar: flag += 2; break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1484 default: assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1485 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1486 const char *r = (op == TOKforeach_reverse) ? "R" : "";
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1487 int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1488 assert(j < sizeof(fdname));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1489 fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1490 fdapply->runTimeHack = true;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1491
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1492 ec = new VarExp(0, fdapply);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1493 Expressions *exps = new Expressions();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1494 if (tab->ty == Tsarray)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1495 aggr = aggr->castTo(sc, tn->arrayOf());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1496 exps->push(aggr);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1497 exps->push(flde);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1498 e = new CallExp(loc, ec, exps);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1499 e->type = Type::tindex; // don't run semantic() on e
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1500 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1501 else if (tab->ty == Tdelegate)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1502 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1503 /* Call:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1504 * aggr(flde)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1505 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1506 Expressions *exps = new Expressions();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1507 exps->push(flde);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1508 e = new CallExp(loc, aggr, exps);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1509 e = e->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1510 if (e->type != Type::tint32)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1511 error("opApply() function for %s must return an int", tab->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1512 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1513 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1514 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1515 /* Call:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1516 * aggr.apply(flde)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1517 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1518 ec = new DotIdExp(loc, aggr,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1519 (op == TOKforeach_reverse) ? Id::applyReverse
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1520 : Id::apply);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1521 Expressions *exps = new Expressions();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1522 exps->push(flde);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1523 e = new CallExp(loc, ec, exps);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1524 e = e->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1525 if (e->type != Type::tint32)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1526 error("opApply() function for %s must return an int", tab->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1527 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1528
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1529 if (!cases.dim)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1530 // Easy case, a clean exit from the loop
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1531 s = new ExpStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1532 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1533 { // Construct a switch statement around the return value
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1534 // of the apply function.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1535 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1536
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1537 // default: break; takes care of cases 0 and 1
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1538 s = new BreakStatement(0, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1539 s = new DefaultStatement(0, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1540 a->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1541
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1542 // cases 2...
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1543 for (int i = 0; i < cases.dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1544 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1545 s = (Statement *)cases.data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1546 s = new CaseStatement(0, new IntegerExp(i + 2), s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1547 a->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1548 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1549
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1550 s = new CompoundStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1551 s = new SwitchStatement(loc, e, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1552 s = s->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1553 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1554 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1555 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1556
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1557 default:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1558 error("foreach: %s is not an aggregate type", aggr->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1559 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1560 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1561 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1562 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1563 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1564 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1565
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1566 int ForeachStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1567 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1568 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1569 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1570
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1571 int ForeachStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1572 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1573 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1574 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1575
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1576 int ForeachStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1577 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1578 return body->usesEH();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1579 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1580
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1581 int ForeachStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1582 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1583 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1584 body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1585 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1586 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1587
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1588 int ForeachStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1589 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1590 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1591 return body->comeFrom();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1592 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1593 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1594
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1595 void ForeachStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1596 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1597 buf->writestring(Token::toChars(op));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1598 buf->writestring(" (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1599 int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1600 for (int i = 0; i < arguments->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1601 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1602 Argument *a = (Argument *)arguments->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1603 if (i)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1604 buf->writestring(", ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1605 if (a->storageClass & STCref)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1606 buf->writestring((global.params.Dversion == 1)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1607 ? (char*)"inout " : (char*)"ref ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1608 if (a->type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1609 a->type->toCBuffer(buf, a->ident, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1610 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1611 buf->writestring(a->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1612 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1613 buf->writestring("; ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1614 aggr->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1615 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1616 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1617 buf->writebyte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1618 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1619 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1620 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1621 buf->writebyte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1622 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1623 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1624
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1625 /******************************** IfStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1626
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1627 IfStatement::IfStatement(Loc loc, Argument *arg, Expression *condition, Statement *ifbody, Statement *elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1628 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1629 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1630 this->arg = arg;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1631 this->condition = condition;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1632 this->ifbody = ifbody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1633 this->elsebody = elsebody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1634 this->match = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1635 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1636
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1637 Statement *IfStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1638 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1639 Statement *i = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1640 if (ifbody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1641 i = ifbody->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1642
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1643 Statement *e = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1644 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1645 e = elsebody->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1646
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1647 Argument *a = arg ? arg->syntaxCopy() : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1648 IfStatement *s = new IfStatement(loc, a, condition->syntaxCopy(), i, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1649 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1650 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1651
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1652 Statement *IfStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1653 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1654 condition = condition->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1655 condition = resolveProperties(sc, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1656 condition = condition->checkToBoolean();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1657
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1658 // If we can short-circuit evaluate the if statement, don't do the
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1659 // semantic analysis of the skipped code.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1660 // This feature allows a limited form of conditional compilation.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1661 condition = condition->optimize(WANTflags);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1662
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1663 // Evaluate at runtime
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1664 unsigned cs0 = sc->callSuper;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1665 unsigned cs1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1666
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1667 Scope *scd;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1668 if (arg)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1669 { /* Declare arg, which we will set to be the
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1670 * result of condition.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1671 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1672 ScopeDsymbol *sym = new ScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1673 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1674 scd = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1675
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1676 Type *t = arg->type ? arg->type : condition->type;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1677 match = new VarDeclaration(loc, t, arg->ident, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1678 match->noauto = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1679 match->semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1680 if (!scd->insert(match))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1681 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1682 match->parent = sc->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1683
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1684 /* Generate:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1685 * (arg = condition)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1686 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1687 VarExp *v = new VarExp(0, match);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1688 condition = new AssignExp(loc, v, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1689 condition = condition->semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1690 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1691 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1692 scd = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1693 ifbody = ifbody->semantic(scd);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1694 scd->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1695
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1696 cs1 = sc->callSuper;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1697 sc->callSuper = cs0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1698 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1699 elsebody = elsebody->semanticScope(sc, NULL, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1700 sc->mergeCallSuper(loc, cs1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1701
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1702 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1703 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1704
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1705 int IfStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1706 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1707 return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1708 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1709
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1710 int IfStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1711 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1712 if (!ifbody || ifbody->fallOffEnd() ||
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1713 !elsebody || elsebody->fallOffEnd())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1714 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1715 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1716 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1717
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1718
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1719 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1720 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1721 buf->writestring("if (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1722 if (arg)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1723 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1724 if (arg->type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1725 arg->type->toCBuffer(buf, arg->ident, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1726 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1727 buf->writestring(arg->ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1728 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1729 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1730 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1731 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1732 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1733 ifbody->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1734 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1735 { buf->writestring("else");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1736 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1737 elsebody->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1738 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1739 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1740
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1741 /******************************** ConditionalStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1742
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1743 ConditionalStatement::ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1744 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1745 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1746 this->condition = condition;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1747 this->ifbody = ifbody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1748 this->elsebody = elsebody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1749 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1750
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1751 Statement *ConditionalStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1752 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1753 Statement *e = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1754 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1755 e = elsebody->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1756 ConditionalStatement *s = new ConditionalStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1757 condition->syntaxCopy(), ifbody->syntaxCopy(), e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1758 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1759 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1760
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1761 Statement *ConditionalStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1762 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1763 //printf("ConditionalStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1764
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1765 // If we can short-circuit evaluate the if statement, don't do the
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1766 // semantic analysis of the skipped code.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1767 // This feature allows a limited form of conditional compilation.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1768 if (condition->include(sc, NULL))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1769 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1770 ifbody = ifbody->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1771 return ifbody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1772 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1773 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1774 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1775 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1776 elsebody = elsebody->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1777 return elsebody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1778 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1779 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1780
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1781 Statements *ConditionalStatement::flatten(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1782 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1783 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1784
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1785 if (condition->include(sc, NULL))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1786 s = ifbody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1787 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1788 s = elsebody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1789
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1790 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1791 a->push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1792 return a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1793 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1794
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1795 int ConditionalStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1796 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1797 return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1798 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1799
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1800 void ConditionalStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1801 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1802 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1803 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1804 if (ifbody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1805 ifbody->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1806 if (elsebody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1807 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1808 buf->writestring("else");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1809 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1810 elsebody->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1811 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1812 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1813 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1814
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1815
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1816 /******************************** PragmaStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1817
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1818 PragmaStatement::PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1819 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1820 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1821 this->ident = ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1822 this->args = args;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1823 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1824 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1825
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1826 Statement *PragmaStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1827 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1828 Statement *b = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1829 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1830 b = body->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1831 PragmaStatement *s = new PragmaStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1832 ident, Expression::arraySyntaxCopy(args), b);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1833 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1834 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1835
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1836 Statement *PragmaStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1837 { // Should be merged with PragmaDeclaration
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1838 //printf("PragmaStatement::semantic() %s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1839 //printf("body = %p\n", body);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1840 if (ident == Id::msg)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1841 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1842 if (args)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1843 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1844 for (size_t i = 0; i < args->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1845 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1846 Expression *e = (Expression *)args->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1847
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1848 e = e->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1849 e = e->optimize(WANTvalue | WANTinterpret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1850 if (e->op == TOKstring)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1851 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1852 StringExp *se = (StringExp *)e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1853 fprintf(stdmsg, "%.*s", (int)se->len, se->string);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1854 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1855 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1856 error("string expected for message, not '%s'", e->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1857 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1858 fprintf(stdmsg, "\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1859 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1860 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1861 else if (ident == Id::lib)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1862 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1863 if (!args || args->dim != 1)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1864 error("string expected for library name");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1865 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1866 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1867 Expression *e = (Expression *)args->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1868
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1869 e = e->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1870 e = e->optimize(WANTvalue | WANTinterpret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1871 args->data[0] = (void *)e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1872 if (e->op != TOKstring)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1873 error("string expected for library name, not '%s'", e->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1874 else if (global.params.verbose)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1875 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1876 StringExp *se = (StringExp *)e;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1877 char *name = (char *)mem.malloc(se->len + 1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1878 memcpy(name, se->string, se->len);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1879 name[se->len] = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1880 printf("library %s\n", name);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1881 mem.free(name);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1882 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1883 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1884 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1885 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1886 error("unrecognized pragma(%s)", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1887
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1888 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1889 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1890 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1891 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1892 return body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1893 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1894
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1895 int PragmaStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1896 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1897 return body && body->usesEH();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1898 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1899
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1900 int PragmaStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1901 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1902 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1903 return body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1904 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1905 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1906
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1907 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1908 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1909 buf->writestring("pragma (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1910 buf->writestring(ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1911 if (args && args->dim)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1912 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1913 buf->writestring(", ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1914 argsToCBuffer(buf, args, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1915 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1916 buf->writeByte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1917 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1918 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1919 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1920 buf->writeByte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1921 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1922
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1923 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1924
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1925 buf->writeByte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1926 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1927 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1928 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1929 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1930 buf->writeByte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1931 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1932 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1933 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1934
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1935
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1936 /******************************** StaticAssertStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1937
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1938 StaticAssertStatement::StaticAssertStatement(StaticAssert *sa)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1939 : Statement(sa->loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1940 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1941 this->sa = sa;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1942 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1943
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1944 Statement *StaticAssertStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1945 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1946 StaticAssertStatement *s = new StaticAssertStatement((StaticAssert *)sa->syntaxCopy(NULL));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1947 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1948 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1949
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1950 Statement *StaticAssertStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1951 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1952 sa->semantic2(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1953 return NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1954 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1955
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1956 void StaticAssertStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1957 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1958 sa->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1959 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1960
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1961
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1962 /******************************** SwitchStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1963
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1964 SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1965 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1966 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1967 condition = c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1968 body = b;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1969 sdefault = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1970 cases = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1971 hasNoDefault = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1972 // LLVMDC
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1973 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1974 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1975
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1976 Statement *SwitchStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1977 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1978 SwitchStatement *s = new SwitchStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1979 condition->syntaxCopy(), body->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1980 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1981 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1982
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1983 Statement *SwitchStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1984 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1985 //printf("SwitchStatement::semantic(%p)\n", this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1986 assert(!cases); // ensure semantic() is only run once
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1987
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1988 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1989
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1990 condition = condition->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1991 condition = resolveProperties(sc, condition);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1992 if (condition->type->isString())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1993 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1994 // If it's not an array, cast it to one
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1995 if (condition->type->ty != Tarray)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1996 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1997 condition = condition->implicitCastTo(sc, condition->type->nextOf()->arrayOf());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1998 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
1999 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2000 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2001 { condition = condition->integralPromotions(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2002 condition->checkIntegral();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2003 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2004 condition = condition->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2005
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2006 sc = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2007 sc->sbreak = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2008 sc->sw = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2009
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2010 cases = new Array();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2011 sc->noctor++; // BUG: should use Scope::mergeCallSuper() for each case instead
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2012 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2013 sc->noctor--;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2014
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2015 // Resolve any goto case's with exp
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2016 for (int i = 0; i < gotoCases.dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2017 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2018 GotoCaseStatement *gcs = (GotoCaseStatement *)gotoCases.data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2019
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2020 if (!gcs->exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2021 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2022 gcs->error("no case statement following goto case;");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2023 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2024 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2025
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2026 for (Scope *scx = sc; scx; scx = scx->enclosing)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2027 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2028 if (!scx->sw)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2029 continue;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2030 for (int j = 0; j < scx->sw->cases->dim; j++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2031 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2032 CaseStatement *cs = (CaseStatement *)scx->sw->cases->data[j];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2033
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2034 if (cs->exp->equals(gcs->exp))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2035 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2036 gcs->cs = cs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2037 goto Lfoundcase;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2038 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2039 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2040 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2041 gcs->error("case %s not found", gcs->exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2042
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2043 Lfoundcase:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2044 ;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2045 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2046
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2047 if (!sc->sw->sdefault)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2048 { hasNoDefault = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2049
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2050 if (global.params.warnings)
215
a58d8f4b84df [svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents: 159
diff changeset
2051 { warning("%s: switch statement has no default", loc.toChars());
159
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2052 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2053
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2054 // Generate runtime error if the default is hit
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2055 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2056 CompoundStatement *cs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2057 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2058
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2059 if (global.params.useSwitchError)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2060 s = new SwitchErrorStatement(loc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2061 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2062 { Expression *e = new HaltExp(loc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2063 s = new ExpStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2064 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2065
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2066 a->reserve(4);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2067 a->push(body);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2068 a->push(new BreakStatement(loc, NULL));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2069 sc->sw->sdefault = new DefaultStatement(loc, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2070 a->push(sc->sw->sdefault);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2071 cs = new CompoundStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2072 body = cs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2073 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2074
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2075 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2076 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2077 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2078
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2079 int SwitchStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2080 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2081 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2082 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2083
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2084 int SwitchStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2085 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2086 return body ? body->usesEH() : 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2087 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2088
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2089 int SwitchStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2090 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2091 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2092 body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2093 return TRUE; // need to do this better
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2094 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2095
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2096 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2097 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2098 buf->writestring("switch (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2099 condition->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2100 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2101 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2102 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2103 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2104 if (!body->isScopeStatement())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2105 { buf->writebyte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2106 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2107 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2108 buf->writebyte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2109 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2110 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2111 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2112 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2113 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2114 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2115 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2116 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2117
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2118 /******************************** CaseStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2119
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2120 CaseStatement::CaseStatement(Loc loc, Expression *exp, Statement *s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2121 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2122 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2123 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2124 this->statement = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2125 cblock = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2126 bodyBB = NULL;
262
88252a1af660 [svn r280] Fixed a bunch of issues with switch statements. Ended up a bit far reaching...
lindquist
parents: 232
diff changeset
2127 llvmIdx = NULL;
159
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2128 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2129
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2130 Statement *CaseStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2131 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2132 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2133 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2134 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2135
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2136 Statement *CaseStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2137 { SwitchStatement *sw = sc->sw;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2138
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2139 //printf("CaseStatement::semantic() %s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2140 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2141 if (sw)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2142 { int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2143
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2144 exp = exp->implicitCastTo(sc, sw->condition->type);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2145 exp = exp->optimize(WANTvalue | WANTinterpret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2146 if (exp->op != TOKstring && exp->op != TOKint64)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2147 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2148 error("case must be a string or an integral constant, not %s", exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2149 exp = new IntegerExp(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2150 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2151
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2152 for (i = 0; i < sw->cases->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2153 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2154 CaseStatement *cs = (CaseStatement *)sw->cases->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2155
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2156 //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2157 if (cs->exp->equals(exp))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2158 { error("duplicate case %s in switch statement", exp->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2159 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2160 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2161 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2162
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2163 sw->cases->push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2164
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2165 // Resolve any goto case's with no exp to this case statement
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2166 for (i = 0; i < sw->gotoCases.dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2167 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2168 GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2169
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2170 if (!gcs->exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2171 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2172 gcs->cs = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2173 sw->gotoCases.remove(i); // remove from array
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2174 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2175 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2176 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2177 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2178 error("case not in switch statement");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2179 statement = statement->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2180 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2181 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2182
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2183 int CaseStatement::compare(Object *obj)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2184 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2185 // Sort cases so we can do an efficient lookup
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2186 CaseStatement *cs2 = (CaseStatement *)(obj);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2187
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2188 return exp->compare(cs2->exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2189 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2190
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2191 int CaseStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2192 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2193 return statement->usesEH();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2194 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2195
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2196 int CaseStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2197 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2198 return statement->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2199 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2200
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2201 int CaseStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2202 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2203 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2204 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2205
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2206 void CaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2207 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2208 buf->writestring("case ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2209 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2210 buf->writebyte(':');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2211 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2212 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2213 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2214
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2215 /******************************** DefaultStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2216
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2217 DefaultStatement::DefaultStatement(Loc loc, Statement *s)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2218 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2219 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2220 this->statement = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2221 #if IN_GCC
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2222 + cblock = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2223 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2224 bodyBB = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2225 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2226
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2227 Statement *DefaultStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2228 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2229 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2230 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2231 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2232
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2233 Statement *DefaultStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2234 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2235 if (sc->sw)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2236 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2237 if (sc->sw->sdefault)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2238 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2239 error("switch statement already has a default");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2240 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2241 sc->sw->sdefault = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2242 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2243 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2244 error("default not in switch statement");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2245 statement = statement->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2246 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2247 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2248
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2249 int DefaultStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2250 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2251 return statement->usesEH();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2252 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2253
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2254 int DefaultStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2255 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2256 return statement->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2257 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2258
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2259 int DefaultStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2260 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2261 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2262 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2263
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2264 void DefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2265 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2266 buf->writestring("default:\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2267 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2268 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2269
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2270 /******************************** GotoDefaultStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2271
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2272 GotoDefaultStatement::GotoDefaultStatement(Loc loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2273 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2274 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2275 sw = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2276 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2277 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2278
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2279 Statement *GotoDefaultStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2280 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2281 GotoDefaultStatement *s = new GotoDefaultStatement(loc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2282 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2283 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2284
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2285 Statement *GotoDefaultStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2286 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2287 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2288 sw = sc->sw;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2289 if (!sw)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2290 error("goto default not in switch statement");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2291 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2292 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2293
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2294 int GotoDefaultStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2295 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2296 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2297 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2298
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2299 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2300 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2301 buf->writestring("goto default;\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2302 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2303
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2304 /******************************** GotoCaseStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2305
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2306 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2307 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2308 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2309 cs = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2310 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2311 enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2312 sw = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2313 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2314
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2315 Statement *GotoCaseStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2316 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2317 Expression *e = exp ? exp->syntaxCopy() : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2318 GotoCaseStatement *s = new GotoCaseStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2319 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2320 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2321
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2322 Statement *GotoCaseStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2323 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2324 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2325 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2326 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2327
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2328 if (!sc->sw)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2329 error("goto case not in switch statement");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2330 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2331 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2332 sw = sc->sw;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2333 sc->sw->gotoCases.push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2334 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2335 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2336 exp = exp->implicitCastTo(sc, sc->sw->condition->type);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2337 exp = exp->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2338 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2339 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2340 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2341 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2342
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2343 int GotoCaseStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2344 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2345 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2346 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2347
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2348 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2349 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2350 buf->writestring("goto case");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2351 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2352 { buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2353 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2354 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2355 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2356 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2357 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2358
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2359 /******************************** SwitchErrorStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2360
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2361 SwitchErrorStatement::SwitchErrorStatement(Loc loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2362 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2363 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2364 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2365
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2366 int SwitchErrorStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2367 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2368 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2369 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2370
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2371 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2372 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2373 buf->writestring("SwitchErrorStatement::toCBuffer()");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2374 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2375 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2376
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2377 /******************************** ReturnStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2378
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2379 ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2380 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2381 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2382 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2383 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2384 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2385
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2386 Statement *ReturnStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2387 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2388 Expression *e = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2389 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2390 e = exp->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2391 ReturnStatement *s = new ReturnStatement(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2392 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2393 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2394
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2395 Statement *ReturnStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2396 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2397 //printf("ReturnStatement::semantic() %s\n", toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2398 this->enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2399
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2400 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2401 Scope *scx = sc;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2402 int implicit0 = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2403
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2404 if (sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2405 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2406 // Find scope of function foreach is in
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2407 for (; 1; scx = scx->enclosing)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2408 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2409 assert(scx);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2410 if (scx->func != fd)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2411 { fd = scx->func; // fd is now function enclosing foreach
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2412 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2413 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2414 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2415 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2416
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2417 Type *tret = fd->type->nextOf();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2418 if (fd->tintro)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2419 tret = fd->tintro->nextOf();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2420 Type *tbret = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2421
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2422 if (tret)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2423 tbret = tret->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2424
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2425 // main() returns 0, even if it returns void
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2426 if (!exp && (!tbret || tbret->ty == Tvoid) && fd->isMain())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2427 { implicit0 = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2428 exp = new IntegerExp(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2429 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2430
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2431 if (sc->incontract || scx->incontract)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2432 error("return statements cannot be in contracts");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2433 if (sc->tf || scx->tf)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2434 error("return statements cannot be in finally, scope(exit) or scope(success) bodies");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2435
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2436 if (fd->isCtorDeclaration())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2437 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2438 // Constructors implicitly do:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2439 // return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2440 if (exp && exp->op != TOKthis)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2441 error("cannot return expression from constructor");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2442 exp = new ThisExp(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2443 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2444
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2445 if (!exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2446 fd->nrvo_can = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2447
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2448 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2449 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2450 fd->hasReturnExp |= 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2451
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2452 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2453 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2454 exp = exp->optimize(WANTvalue);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2455
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2456 if (fd->nrvo_can && exp->op == TOKvar)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2457 { VarExp *ve = (VarExp *)exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2458 VarDeclaration *v = ve->var->isVarDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2459
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2460 if (!v || v->isOut() || v->isRef())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2461 fd->nrvo_can = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2462 else if (fd->nrvo_var == NULL)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2463 { if (!v->isDataseg() && !v->isParameter() && v->toParent2() == fd)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2464 fd->nrvo_var = v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2465 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2466 fd->nrvo_can = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2467 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2468 else if (fd->nrvo_var != v)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2469 fd->nrvo_can = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2470 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2471 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2472 fd->nrvo_can = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2473
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2474 if (fd->returnLabel && tbret->ty != Tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2475 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2476 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2477 else if (fd->inferRetType)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2478 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2479 if (fd->type->nextOf())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2480 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2481 if (!exp->type->equals(fd->type->nextOf()))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2482 error("mismatched function return type inference of %s and %s",
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2483 exp->type->toChars(), fd->type->nextOf()->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2484 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2485 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2486 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2487 fd->type->next = exp->type;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2488 fd->type = fd->type->semantic(loc, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2489 if (!fd->tintro)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2490 { tret = fd->type->nextOf();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2491 tbret = tret->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2492 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2493 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2494 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2495 else if (tbret->ty != Tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2496 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2497 exp = exp->implicitCastTo(sc, tret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2498 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2499 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2500 else if (fd->inferRetType)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2501 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2502 if (fd->type->nextOf())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2503 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2504 if (fd->type->nextOf()->ty != Tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2505 error("mismatched function return type inference of void and %s",
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2506 fd->type->nextOf()->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2507 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2508 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2509 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2510 fd->type->next = Type::tvoid;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2511 fd->type = fd->type->semantic(loc, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2512 if (!fd->tintro)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2513 { tret = Type::tvoid;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2514 tbret = tret;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2515 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2516 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2517 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2518 else if (tbret->ty != Tvoid) // if non-void return
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2519 error("return expression expected");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2520
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2521 if (sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2522 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2523 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2524
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2525 if (exp && !implicit0)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2526 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2527 exp = exp->implicitCastTo(sc, tret);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2528 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2529 if (!exp || exp->op == TOKint64 || exp->op == TOKfloat64 ||
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2530 exp->op == TOKimaginary80 || exp->op == TOKcomplex80 ||
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2531 exp->op == TOKthis || exp->op == TOKsuper || exp->op == TOKnull ||
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2532 exp->op == TOKstring)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2533 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2534 sc->fes->cases.push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2535 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2536 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2537 else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2538 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2539 Statement *s1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2540 Statement *s2;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2541
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2542 s = new ReturnStatement(0, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2543 sc->fes->cases.push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2544
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2545 // Construct: { exp; return cases.dim + 1; }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2546 s1 = new ExpStatement(loc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2547 s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2548 s = new CompoundStatement(loc, s1, s2);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2549 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2550 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2551 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2552 VarExp *v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2553 Statement *s1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2554 Statement *s2;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2555
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2556 // Construct: return vresult;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2557 if (!fd->vresult)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2558 { VarDeclaration *v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2559
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2560 v = new VarDeclaration(loc, tret, Id::result, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2561 v->noauto = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2562 v->semantic(scx);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2563 if (!scx->insert(v))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2564 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2565 v->parent = fd;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2566 fd->vresult = v;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2567 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2568
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2569 v = new VarExp(0, fd->vresult);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2570 s = new ReturnStatement(0, v);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2571 sc->fes->cases.push(s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2572
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2573 // Construct: { vresult = exp; return cases.dim + 1; }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2574 v = new VarExp(0, fd->vresult);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2575 exp = new AssignExp(loc, v, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2576 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2577 s1 = new ExpStatement(loc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2578 s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2579 s = new CompoundStatement(loc, s1, s2);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2580 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2581 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2582 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2583
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2584 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2585 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2586 if (fd->returnLabel && tbret->ty != Tvoid)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2587 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2588 assert(fd->vresult);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2589 VarExp *v = new VarExp(0, fd->vresult);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2590
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2591 exp = new AssignExp(loc, v, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2592 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2593 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2594 //exp->dump(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2595 //exp->print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2596 exp->checkEscape();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2597 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2598
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2599 /* BUG: need to issue an error on:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2600 * this
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2601 * { if (x) return;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2602 * super();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2603 * }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2604 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2605
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2606 if (sc->callSuper & CSXany_ctor &&
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2607 !(sc->callSuper & (CSXthis_ctor | CSXsuper_ctor)))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2608 error("return without calling constructor");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2609
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2610 sc->callSuper |= CSXreturn;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2611
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2612 // See if all returns are instead to be replaced with a goto returnLabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2613 if (fd->returnLabel)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2614 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2615 GotoStatement *gs = new GotoStatement(loc, Id::returnLabel);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2616
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2617 gs->label = fd->returnLabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2618 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2619 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2620
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2621 s = new ExpStatement(0, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2622 return new CompoundStatement(loc, s, gs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2623 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2624 return gs;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2625 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2626
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2627 if (exp && tbret->ty == Tvoid && !fd->isMain())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2628 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2629
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2630 s = new ExpStatement(loc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2631 loc = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2632 exp = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2633 return new CompoundStatement(loc, s, this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2634 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2635
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2636 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2637 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2638
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2639 int ReturnStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2640 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2641 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2642 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2643
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2644 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2645 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2646 buf->printf("return ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2647 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2648 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2649 buf->writeByte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2650 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2651 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2652
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2653 /******************************** BreakStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2654
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2655 BreakStatement::BreakStatement(Loc loc, Identifier *ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2656 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2657 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2658 this->ident = ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2659 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2660 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2661
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2662 Statement *BreakStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2663 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2664 BreakStatement *s = new BreakStatement(loc, ident);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2665 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2666 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2667
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2668 Statement *BreakStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2669 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2670 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2671 // If:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2672 // break Identifier;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2673 if (ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2674 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2675 Scope *scx;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2676 FuncDeclaration *thisfunc = sc->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2677
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2678 for (scx = sc; scx; scx = scx->enclosing)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2679 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2680 LabelStatement *ls;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2681
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2682 if (scx->func != thisfunc) // if in enclosing function
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2683 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2684 if (sc->fes) // if this is the body of a foreach
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2685 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2686 /* Post this statement to the fes, and replace
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2687 * it with a return value that caller will put into
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2688 * a switch. Caller will figure out where the break
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2689 * label actually is.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2690 * Case numbers start with 2, not 0, as 0 is continue
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2691 * and 1 is break.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2692 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2693 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2694 sc->fes->cases.push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2695 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2696 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2697 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2698 break; // can't break to it
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2699 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2700
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2701 ls = scx->slabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2702 if (ls && ls->ident == ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2703 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2704 Statement *s = ls->statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2705
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2706 if (!s->hasBreak())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2707 error("label '%s' has no break", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2708 if (ls->tf != sc->tf)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2709 error("cannot break out of finally block");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2710
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2711 this->target = ls;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2712 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2713 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2714 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2715 error("enclosing label '%s' for break not found", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2716 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2717 else if (!sc->sbreak)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2718 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2719 if (sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2720 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2721
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2722 // Replace break; with return 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2723 s = new ReturnStatement(0, new IntegerExp(1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2724 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2725 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2726 error("break is not inside a loop or switch");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2727 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2728 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2729 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2730
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2731 int BreakStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2732 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2733 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2734 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2735
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2736 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2737 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2738 buf->writestring("break");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2739 if (ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2740 { buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2741 buf->writestring(ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2742 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2743 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2744 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2745 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2746
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2747 /******************************** ContinueStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2748
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2749 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2750 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2751 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2752 this->ident = ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2753 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2754 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2755
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2756 Statement *ContinueStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2757 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2758 ContinueStatement *s = new ContinueStatement(loc, ident);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2759 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2760 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2761
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2762 Statement *ContinueStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2763 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2764 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2765 //printf("ContinueStatement::semantic() %p\n", this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2766 if (ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2767 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2768 Scope *scx;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2769 FuncDeclaration *thisfunc = sc->func;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2770
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2771 for (scx = sc; scx; scx = scx->enclosing)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2772 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2773 LabelStatement *ls;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2774
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2775 if (scx->func != thisfunc) // if in enclosing function
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2776 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2777 if (sc->fes) // if this is the body of a foreach
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2778 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2779 for (; scx; scx = scx->enclosing)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2780 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2781 ls = scx->slabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2782 if (ls && ls->ident == ident && ls->statement == sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2783 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2784 // Replace continue ident; with return 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2785 return new ReturnStatement(0, new IntegerExp(0));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2786 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2787 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2788
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2789 /* Post this statement to the fes, and replace
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2790 * it with a return value that caller will put into
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2791 * a switch. Caller will figure out where the break
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2792 * label actually is.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2793 * Case numbers start with 2, not 0, as 0 is continue
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2794 * and 1 is break.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2795 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2796 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2797 sc->fes->cases.push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2798 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2799 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2800 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2801 break; // can't continue to it
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2802 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2803
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2804 ls = scx->slabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2805 if (ls && ls->ident == ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2806 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2807 Statement *s = ls->statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2808
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2809 if (!s->hasContinue())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2810 error("label '%s' has no continue", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2811 if (ls->tf != sc->tf)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2812 error("cannot continue out of finally block");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2813
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2814 this->target = ls;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2815 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2816 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2817 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2818 error("enclosing label '%s' for continue not found", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2819 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2820 else if (!sc->scontinue)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2821 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2822 if (sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2823 { Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2824
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2825 // Replace continue; with return 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2826 s = new ReturnStatement(0, new IntegerExp(0));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2827 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2828 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2829 error("continue is not inside a loop");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2830 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2831 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2832 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2833
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2834 int ContinueStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2835 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2836 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2837 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2838
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2839 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2840 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2841 buf->writestring("continue");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2842 if (ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2843 { buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2844 buf->writestring(ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2845 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2846 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2847 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2848 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2849
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2850 /******************************** SynchronizedStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2851
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2852 SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2853 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2854 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2855 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2856 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2857 this->esync = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2858 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2859
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2860 SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2861 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2862 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2863 this->exp = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2864 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2865 this->esync = esync;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2866 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2867
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2868 Statement *SynchronizedStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2869 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2870 Expression *e = exp ? exp->syntaxCopy() : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2871 SynchronizedStatement *s = new SynchronizedStatement(loc, e, body ? body->syntaxCopy() : NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2872 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2873 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2874
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2875 Statement *SynchronizedStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2876 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2877 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2878 { ClassDeclaration *cd;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2879
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2880 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2881 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2882 cd = exp->type->isClassHandle();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2883 if (!cd)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2884 error("can only synchronize on class objects, not '%s'", exp->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2885 else if (cd->isInterfaceDeclaration())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2886 { Type *t = new TypeIdentifier(0, Id::Object);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2887
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2888 t = t->semantic(0, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2889 exp = new CastExp(loc, exp, t);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2890 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2891 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2892 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2893 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2894 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2895 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2896 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2897
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2898 int SynchronizedStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2899 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2900 return FALSE; //TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2901 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2902
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2903 int SynchronizedStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2904 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2905 return FALSE; //TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2906 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2907
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2908 int SynchronizedStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2909 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2910 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2911 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2912
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2913 int SynchronizedStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2914 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2915 return body ? body->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2916 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2917
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2918 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2919 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2920 buf->writestring("synchronized");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2921 if (exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2922 { buf->writebyte('(');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2923 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2924 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2925 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2926 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2927 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2928 buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2929 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2930 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2931 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2932
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2933 /******************************** WithStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2934
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2935 WithStatement::WithStatement(Loc loc, Expression *exp, Statement *body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2936 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2937 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2938 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2939 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2940 wthis = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2941 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2942
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2943 Statement *WithStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2944 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2945 WithStatement *s = new WithStatement(loc, exp->syntaxCopy(), body ? body->syntaxCopy() : NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2946 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2947 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2948
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2949 Statement *WithStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2950 { ScopeDsymbol *sym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2951 Initializer *init;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2952
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2953 //printf("WithStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2954 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2955 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2956 if (exp->op == TOKimport)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2957 { ScopeExp *es = (ScopeExp *)exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2958
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2959 sym = es->sds;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2960 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2961 else if (exp->op == TOKtype)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2962 { TypeExp *es = (TypeExp *)exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2963
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2964 sym = es->type->toDsymbol(sc)->isScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2965 if (!sym)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2966 { error("%s has no members", es->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2967 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2968 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2969 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2970 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2971 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2972 { Type *t = exp->type;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2973
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2974 assert(t);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2975 t = t->toBasetype();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2976 if (t->isClassHandle())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2977 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2978 init = new ExpInitializer(loc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2979 wthis = new VarDeclaration(loc, exp->type, Id::withSym, init);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2980 wthis->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2981
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2982 sym = new WithScopeSymbol(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2983 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2984 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2985 else if (t->ty == Tstruct)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2986 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2987 Expression *e = exp->addressOf(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2988 init = new ExpInitializer(loc, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2989 wthis = new VarDeclaration(loc, e->type, Id::withSym, init);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2990 wthis->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2991 sym = new WithScopeSymbol(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2992 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2993 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2994 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2995 { error("with expressions must be class objects, not '%s'", exp->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2996 return NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2997 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2998 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
2999 sc = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3000
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3001 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3002 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3003
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3004 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3005
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3006 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3007 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3008
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3009 void WithStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3010 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3011 buf->writestring("with (");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3012 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3013 buf->writestring(")\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3014 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3015 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3016 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3017
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3018 int WithStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3019 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3020 return body ? body->usesEH() : 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3021 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3022
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3023 int WithStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3024 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3025 return body ? body->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3026 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3027
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3028 /******************************** TryCatchStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3029
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3030 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3031 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3032 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3033 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3034 this->catches = catches;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3035 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3036
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3037 Statement *TryCatchStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3038 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3039 Array *a = new Array();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3040 a->setDim(catches->dim);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3041 for (int i = 0; i < a->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3042 { Catch *c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3043
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3044 c = (Catch *)catches->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3045 c = c->syntaxCopy();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3046 a->data[i] = c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3047 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3048 TryCatchStatement *s = new TryCatchStatement(loc, body->syntaxCopy(), a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3049 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3050 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3051
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3052 Statement *TryCatchStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3053 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3054 body = body->semanticScope(sc, NULL /*this*/, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3055
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3056 for (int i = 0; i < catches->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3057 { Catch *c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3058
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3059 c = (Catch *)catches->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3060 c->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3061
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3062 // Determine if current catch 'hides' any previous catches
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3063 for (int j = 0; j < i; j++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3064 { Catch *cj = (Catch *)catches->data[j];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3065 char *si = c->loc.toChars();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3066 char *sj = cj->loc.toChars();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3067
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3068 if (c->type->toBasetype()->implicitConvTo(cj->type->toBasetype()))
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3069 error("catch at %s hides catch at %s", sj, si);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3070 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3071 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3072 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3073 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3074
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3075 int TryCatchStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3076 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3077 return FALSE; //TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3078 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3079
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3080 int TryCatchStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3081 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3082 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3083 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3084
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3085 int TryCatchStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3086 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3087 int result = FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3088
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3089 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3090 result = body->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3091 for (int i = 0; i < catches->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3092 { Catch *c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3093
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3094 c = (Catch *)catches->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3095 if (c->handler)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3096 result |= c->handler->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3097 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3098 return result;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3099 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3100
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3101 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3102 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3103 buf->writestring("try");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3104 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3105 if (body)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3106 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3107 int i;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3108 for (i = 0; i < catches->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3109 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3110 Catch *c = (Catch *)catches->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3111 c->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3112 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3113 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3114
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3115 /******************************** Catch ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3116
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3117 Catch::Catch(Loc loc, Type *t, Identifier *id, Statement *handler)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3118 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3119 //printf("Catch(%s, loc = %s)\n", id->toChars(), loc.toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3120 this->loc = loc;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3121 this->type = t;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3122 this->ident = id;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3123 this->handler = handler;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3124 var = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3125 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3126
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3127 Catch *Catch::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3128 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3129 Catch *c = new Catch(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3130 (type ? type->syntaxCopy() : NULL),
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3131 ident,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3132 (handler ? handler->syntaxCopy() : NULL));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3133 return c;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3134 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3135
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3136 void Catch::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3137 { ScopeDsymbol *sym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3138
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3139 //printf("Catch::semantic(%s)\n", ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3140
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3141 #ifndef IN_GCC
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3142 if (sc->tf)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3143 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3144 /* This is because the _d_local_unwind() gets the stack munged
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3145 * up on this. The workaround is to place any try-catches into
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3146 * a separate function, and call that.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3147 * To fix, have the compiler automatically convert the finally
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3148 * body into a nested function.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3149 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3150 error(loc, "cannot put catch statement inside finally block");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3151 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3152 #endif
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3153
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3154 sym = new ScopeDsymbol();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3155 sym->parent = sc->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3156 sc = sc->push(sym);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3157
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3158 if (!type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3159 type = new TypeIdentifier(0, Id::Object);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3160 type = type->semantic(loc, sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3161 if (!type->toBasetype()->isClassHandle())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3162 error("can only catch class objects, not '%s'", type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3163 else if (ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3164 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3165 var = new VarDeclaration(loc, type, ident, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3166 var->parent = sc->parent;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3167 sc->insert(var);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3168 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3169 handler = handler->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3170
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3171 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3172 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3173
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3174 void Catch::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3175 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3176 buf->writestring("catch");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3177 if (type)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3178 { buf->writebyte('(');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3179 type->toCBuffer(buf, ident, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3180 buf->writebyte(')');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3181 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3182 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3183 buf->writebyte('{');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3184 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3185 handler->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3186 buf->writebyte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3187 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3188 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3189
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3190 /****************************** TryFinallyStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3191
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3192 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3193 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3194 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3195 this->body = body;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3196 this->finalbody = finalbody;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3197 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3198 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3199
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3200 Statement *TryFinallyStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3201 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3202 TryFinallyStatement *s = new TryFinallyStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3203 body->syntaxCopy(), finalbody->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3204 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3205 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3206
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3207 Statement *TryFinallyStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3208 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3209 //printf("TryFinallyStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3210
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3211 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3212 sc->tfOfTry = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3213 body = body->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3214 sc->tfOfTry = enclosingtryfinally;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3215
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3216 sc = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3217 sc->tf = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3218 sc->sbreak = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3219 sc->scontinue = NULL; // no break or continue out of finally block
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3220 finalbody = finalbody->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3221 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3222 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3223 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3224
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3225 void TryFinallyStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3226 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3227 buf->printf("try\n{\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3228 body->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3229 buf->printf("}\nfinally\n{\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3230 finalbody->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3231 buf->writeByte('}');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3232 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3233 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3234
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3235 int TryFinallyStatement::hasBreak()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3236 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3237 return FALSE; //TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3238 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3239
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3240 int TryFinallyStatement::hasContinue()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3241 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3242 return FALSE; //TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3243 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3244
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3245 int TryFinallyStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3246 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3247 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3248 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3249
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3250 int TryFinallyStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3251 { int result;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3252
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3253 result = body ? body->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3254 // if (finalbody)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3255 // result = finalbody->fallOffEnd();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3256 return result;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3257 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3258
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3259 /****************************** OnScopeStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3260
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3261 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3262 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3263 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3264 this->tok = tok;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3265 this->statement = statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3266 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3267
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3268 Statement *OnScopeStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3269 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3270 OnScopeStatement *s = new OnScopeStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3271 tok, statement->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3272 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3273 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3274
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3275 Statement *OnScopeStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3276 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3277 /* semantic is called on results of scopeCode() */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3278 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3279 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3280
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3281 void OnScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3282 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3283 buf->writestring(Token::toChars(tok));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3284 buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3285 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3286 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3287
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3288 int OnScopeStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3289 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3290 return (tok != TOKon_scope_success);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3291 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3292
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3293 void OnScopeStatement::scopeCode(Statement **sentry, Statement **sexception, Statement **sfinally)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3294 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3295 //printf("OnScopeStatement::scopeCode()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3296 //print();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3297 *sentry = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3298 *sexception = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3299 *sfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3300 switch (tok)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3301 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3302 case TOKon_scope_exit:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3303 *sfinally = statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3304 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3305
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3306 case TOKon_scope_failure:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3307 *sexception = statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3308 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3309
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3310 case TOKon_scope_success:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3311 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3312 /* Create:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3313 * sentry: int x = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3314 * sexception: x = 1;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3315 * sfinally: if (!x) statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3316 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3317 static int num;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3318 char name[5 + sizeof(num) * 3 + 1];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3319 sprintf(name, "__osf%d", ++num);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3320 Identifier *id = Lexer::idPool(name);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3321
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3322 ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3323 VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3324 *sentry = new DeclarationStatement(loc, v);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3325
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3326 Expression *e = new IntegerExp(1);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3327 e = new AssignExp(0, new VarExp(0, v), e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3328 *sexception = new ExpStatement(0, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3329
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3330 e = new VarExp(0, v);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3331 e = new NotExp(0, e);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3332 *sfinally = new IfStatement(0, NULL, e, statement, NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3333
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3334 break;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3335 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3336
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3337 default:
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3338 assert(0);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3339 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3340 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3341
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3342 /******************************** ThrowStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3343
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3344 ThrowStatement::ThrowStatement(Loc loc, Expression *exp)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3345 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3346 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3347 this->exp = exp;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3348 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3349
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3350 Statement *ThrowStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3351 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3352 ThrowStatement *s = new ThrowStatement(loc, exp->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3353 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3354 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3355
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3356 Statement *ThrowStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3357 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3358 //printf("ThrowStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3359
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3360 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3361 fd->hasReturnExp |= 2;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3362
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3363 if (sc->incontract)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3364 error("Throw statements cannot be in contracts");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3365 exp = exp->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3366 exp = resolveProperties(sc, exp);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3367 if (!exp->type->toBasetype()->isClassHandle())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3368 error("can only throw class objects, not type %s", exp->type->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3369 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3370 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3371
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3372 int ThrowStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3373 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3374 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3375 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3376
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3377 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3378 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3379 buf->printf("throw ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3380 exp->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3381 buf->writeByte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3382 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3383 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3384
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3385 /******************************** VolatileStatement **************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3386
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3387 VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3388 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3389 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3390 this->statement = statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3391 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3392
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3393 Statement *VolatileStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3394 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3395 VolatileStatement *s = new VolatileStatement(loc,
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3396 statement ? statement->syntaxCopy() : NULL);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3397 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3398 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3399
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3400 Statement *VolatileStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3401 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3402 statement = statement ? statement->semantic(sc) : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3403 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3404 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3405
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3406 Statements *VolatileStatement::flatten(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3407 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3408 Statements *a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3409
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3410 a = statement ? statement->flatten(sc) : NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3411 if (a)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3412 { for (int i = 0; i < a->dim; i++)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3413 { Statement *s = (Statement *)a->data[i];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3414
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3415 s = new VolatileStatement(loc, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3416 a->data[i] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3417 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3418 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3419
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3420 return a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3421 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3422
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3423 int VolatileStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3424 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3425 return statement ? statement->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3426 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3427
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3428 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3429 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3430 buf->writestring("volatile");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3431 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3432 { if (statement->isScopeStatement())
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3433 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3434 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3435 buf->writebyte(' ');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3436 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3437 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3438 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3439
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3440
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3441 /******************************** GotoStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3442
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3443 GotoStatement::GotoStatement(Loc loc, Identifier *ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3444 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3445 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3446 this->ident = ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3447 this->label = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3448 this->tf = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3449 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3450 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3451
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3452 Statement *GotoStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3453 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3454 GotoStatement *s = new GotoStatement(loc, ident);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3455 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3456 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3457
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3458 Statement *GotoStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3459 { FuncDeclaration *fd = sc->parent->isFuncDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3460
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3461 //printf("GotoStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3462 tf = sc->tf;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3463 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3464 label = fd->searchLabel(ident);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3465 if (!label->statement && sc->fes)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3466 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3467 /* Either the goto label is forward referenced or it
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3468 * is in the function that the enclosing foreach is in.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3469 * Can't know yet, so wrap the goto in a compound statement
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3470 * so we can patch it later, and add it to a 'look at this later'
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3471 * list.
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3472 */
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3473 Statements *a = new Statements();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3474 Statement *s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3475
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3476 a->push(this);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3477 s = new CompoundStatement(loc, a);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3478 sc->fes->gotos.push(s); // 'look at this later' list
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3479 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3480 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3481 if (label->statement && label->statement->tf != sc->tf)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3482 error("cannot goto in or out of finally block");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3483 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3484 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3485
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3486 int GotoStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3487 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3488 return FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3489 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3490
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3491 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3492 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3493 buf->writestring("goto ");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3494 buf->writestring(ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3495 buf->writebyte(';');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3496 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3497 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3498
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3499 /******************************** LabelStatement ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3500
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3501 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3502 : Statement(loc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3503 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3504 this->ident = ident;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3505 this->statement = statement;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3506 this->tf = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3507 this->enclosingtryfinally = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3508 this->lblock = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3509 this->isReturnLabel = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3510 this->llvmBB = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3511 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3512
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3513 Statement *LabelStatement::syntaxCopy()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3514 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3515 LabelStatement *s = new LabelStatement(loc, ident, statement->syntaxCopy());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3516 return s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3517 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3518
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3519 Statement *LabelStatement::semantic(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3520 { LabelDsymbol *ls;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3521 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3522
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3523 //printf("LabelStatement::semantic()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3524 ls = fd->searchLabel(ident);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3525 if (ls->statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3526 error("Label '%s' already defined", ls->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3527 else
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3528 ls->statement = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3529 tf = sc->tf;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3530 enclosingtryfinally = sc->tfOfTry;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3531 sc = sc->push();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3532 sc->scopesym = sc->enclosing->scopesym;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3533 sc->callSuper |= CSXlabel;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3534 sc->slabel = this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3535 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3536 statement = statement->semantic(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3537 sc->pop();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3538 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3539 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3540
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3541 Statements *LabelStatement::flatten(Scope *sc)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3542 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3543 Statements *a = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3544
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3545 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3546 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3547 a = statement->flatten(sc);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3548 if (a)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3549 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3550 if (!a->dim)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3551 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3552 a->push(new ExpStatement(loc, NULL));
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3553 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3554 Statement *s = (Statement *)a->data[0];
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3555
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3556 s = new LabelStatement(loc, ident, s);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3557 a->data[0] = s;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3558 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3559 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3560
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3561 return a;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3562 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3563
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3564
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3565 int LabelStatement::usesEH()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3566 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3567 return statement ? statement->usesEH() : FALSE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3568 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3569
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3570 int LabelStatement::fallOffEnd()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3571 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3572 return statement ? statement->fallOffEnd() : TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3573 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3574
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3575 int LabelStatement::comeFrom()
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3576 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3577 //printf("LabelStatement::comeFrom()\n");
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3578 return TRUE;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3579 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3580
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3581 void LabelStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3582 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3583 buf->writestring(ident->toChars());
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3584 buf->writebyte(':');
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3585 buf->writenl();
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3586 if (statement)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3587 statement->toCBuffer(buf, hgs);
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3588 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3589
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3590
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3591 /******************************** LabelDsymbol ***************************/
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3592
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3593 LabelDsymbol::LabelDsymbol(Identifier *ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3594 : Dsymbol(ident)
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3595 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3596 statement = NULL;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3597 asmLabelNum = 0;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3598 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3599
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3600 LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3601 {
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3602 return this;
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3603 }
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3604
5acec6b2eef8 [svn r175] merged dmd 1.029
ChristianK
parents: 148
diff changeset
3605