Allow returning something of type void in a function that returns void
[delight/core.git] / dmd2 / delegatize.c
blobdca5517a9eb8e97eb4459f3ba1311542f121b665
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 #include <stdio.h>
12 #include <assert.h>
14 #include "mars.h"
15 #include "expression.h"
16 #include "statement.h"
17 #include "mtype.h"
18 #include "utf.h"
19 #include "declaration.h"
20 #include "aggregate.h"
21 #include "scope.h"
23 /********************************************
24 * Convert from expression to delegate that returns the expression,
25 * i.e. convert:
26 * expr
27 * to:
28 * t delegate() { return expr; }
31 Expression *Expression::toDelegate(Scope *sc, Type *t)
33 //printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
34 TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
35 FuncLiteralDeclaration *fld =
36 new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
37 Expression *e;
38 #if 1
39 sc = sc->push();
40 sc->parent = fld; // set current function to be the delegate
41 e = this;
42 e->scanForNestedRef(sc);
43 sc = sc->pop();
44 #else
45 e = this->syntaxCopy();
46 #endif
47 Statement *s = new ReturnStatement(loc, e);
48 fld->fbody = s;
49 e = new FuncExp(loc, fld);
50 e = e->semantic(sc);
51 return e;
54 /******************************
55 * Perform scanForNestedRef() on an array of Expressions.
58 void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
60 //printf("arrayExpressionScanForNestedRef(%p)\n", a);
61 if (a)
63 for (int i = 0; i < a->dim; i++)
64 { Expression *e = (Expression *)a->data[i];
66 if (e)
68 e->scanForNestedRef(sc);
74 void Expression::scanForNestedRef(Scope *sc)
76 //printf("Expression::scanForNestedRef(%s)\n", toChars());
79 void SymOffExp::scanForNestedRef(Scope *sc)
81 //printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
82 VarDeclaration *v = var->isVarDeclaration();
83 if (v)
84 v->checkNestedReference(sc, 0);
87 void VarExp::scanForNestedRef(Scope *sc)
89 //printf("VarExp::scanForNestedRef(%s)\n", toChars());
90 VarDeclaration *v = var->isVarDeclaration();
91 if (v)
92 v->checkNestedReference(sc, 0);
95 void ThisExp::scanForNestedRef(Scope *sc)
97 assert(var);
98 var->isVarDeclaration()->checkNestedReference(sc, 0);
101 void SuperExp::scanForNestedRef(Scope *sc)
103 ThisExp::scanForNestedRef(sc);
106 void FuncExp::scanForNestedRef(Scope *sc)
108 //printf("FuncExp::scanForNestedRef(%s)\n", toChars());
109 //fd->parent = sc->parent;
112 void DeclarationExp::scanForNestedRef(Scope *sc)
114 //printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
115 declaration->parent = sc->parent;
118 void NewExp::scanForNestedRef(Scope *sc)
120 //printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
122 if (thisexp)
123 thisexp->scanForNestedRef(sc);
124 arrayExpressionScanForNestedRef(sc, newargs);
125 arrayExpressionScanForNestedRef(sc, arguments);
128 void UnaExp::scanForNestedRef(Scope *sc)
130 e1->scanForNestedRef(sc);
133 void BinExp::scanForNestedRef(Scope *sc)
135 e1->scanForNestedRef(sc);
136 e2->scanForNestedRef(sc);
139 void CallExp::scanForNestedRef(Scope *sc)
141 //printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
142 e1->scanForNestedRef(sc);
143 arrayExpressionScanForNestedRef(sc, arguments);
147 void IndexExp::scanForNestedRef(Scope *sc)
149 e1->scanForNestedRef(sc);
151 if (lengthVar)
152 { //printf("lengthVar\n");
153 lengthVar->parent = sc->parent;
155 e2->scanForNestedRef(sc);
159 void SliceExp::scanForNestedRef(Scope *sc)
161 e1->scanForNestedRef(sc);
163 if (lengthVar)
164 { //printf("lengthVar\n");
165 lengthVar->parent = sc->parent;
167 if (lwr)
168 lwr->scanForNestedRef(sc);
169 if (upr)
170 upr->scanForNestedRef(sc);
174 void ArrayLiteralExp::scanForNestedRef(Scope *sc)
176 arrayExpressionScanForNestedRef(sc, elements);
180 void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
182 arrayExpressionScanForNestedRef(sc, keys);
183 arrayExpressionScanForNestedRef(sc, values);
187 void StructLiteralExp::scanForNestedRef(Scope *sc)
189 arrayExpressionScanForNestedRef(sc, elements);
193 void TupleExp::scanForNestedRef(Scope *sc)
195 arrayExpressionScanForNestedRef(sc, exps);
199 void ArrayExp::scanForNestedRef(Scope *sc)
201 e1->scanForNestedRef(sc);
202 arrayExpressionScanForNestedRef(sc, arguments);
206 void CondExp::scanForNestedRef(Scope *sc)
208 econd->scanForNestedRef(sc);
209 e1->scanForNestedRef(sc);
210 e2->scanForNestedRef(sc);