159
|
1
|
|
2 // Compiler implementation of the D programming language
|
|
3 // Copyright (c) 1999-2008 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.
|
|
10
|
|
11 #include <stdio.h>
|
|
12 #include <assert.h>
|
|
13
|
|
14 #include "root.h"
|
|
15 #include "aggregate.h"
|
|
16 #include "scope.h"
|
|
17 #include "mtype.h"
|
|
18 #include "declaration.h"
|
|
19 #include "module.h"
|
|
20 #include "id.h"
|
|
21 #include "expression.h"
|
|
22 #include "statement.h"
|
|
23
|
|
24
|
|
25 /*********************************
|
|
26 * Generate expression that calls opClone()
|
|
27 * for each member of the struct
|
|
28 * (can be NULL for members that don't need one)
|
|
29 */
|
|
30
|
336
|
31 #if DMDV2
|
159
|
32 Expression *StructDeclaration::cloneMembers()
|
|
33 {
|
|
34 Expression *e = NULL;
|
|
35
|
|
36 for (size_t i = 0; i < fields.dim; i++)
|
|
37 {
|
|
38 Dsymbol *s = (Dsymbol *)fields.data[i];
|
|
39 VarDeclaration *v = s->isVarDeclaration();
|
|
40 assert(v && v->storage_class & STCfield);
|
|
41 Type *tv = v->type->toBasetype();
|
|
42 size_t dim = 1;
|
|
43 while (tv->ty == Tsarray)
|
|
44 { TypeSArray *ta = (TypeSArray *)tv;
|
|
45 dim *= ((TypeSArray *)tv)->dim->toInteger();
|
|
46 tv = tv->nextOf()->toBasetype();
|
|
47 }
|
|
48 if (tv->ty == Tstruct)
|
|
49 { TypeStruct *ts = (TypeStruct *)tv;
|
|
50 StructDeclaration *sd = ts->sym;
|
|
51 if (sd->opclone)
|
|
52 { Expression *ex;
|
|
53
|
|
54 // this.v
|
|
55 ex = new ThisExp(0);
|
|
56 ex = new DotVarExp(0, ex, v, 0);
|
|
57
|
|
58 if (dim == 1)
|
|
59 { // this.v.opClone()
|
|
60 ex = new DotVarExp(0, ex, sd->opclone, 0);
|
|
61 ex = new CallExp(0, ex);
|
|
62 }
|
|
63 else
|
|
64 {
|
|
65 // _callOpClones(&this.v, opclone, dim)
|
|
66 Expressions *args = new Expressions();
|
|
67 args->push(new AddrExp(0, ex));
|
|
68 args->push(new SymOffExp(0, sd->opclone, 0));
|
|
69 args->push(new IntegerExp(dim));
|
|
70 FuncDeclaration *ec = FuncDeclaration::genCfunc(Type::tvoid, "_callOpClones");
|
|
71 ex = new CallExp(0, new VarExp(0, ec), args);
|
|
72 }
|
|
73 e = Expression::combine(e, ex);
|
|
74 }
|
|
75 }
|
|
76 }
|
|
77 return e;
|
|
78 }
|
|
79 #endif
|
|
80
|
|
81 /*****************************************
|
|
82 * Create inclusive destructor for struct by aggregating
|
|
83 * all the destructors in dtors[] with the destructors for
|
|
84 * all the members.
|
|
85 */
|
|
86
|
|
87 FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
|
88 {
|
|
89 //printf("StructDeclaration::buildDtor() %s\n", toChars());
|
|
90 Expression *e = NULL;
|
|
91
|
336
|
92 #if DMDV2
|
159
|
93 for (size_t i = 0; i < fields.dim; i++)
|
|
94 {
|
|
95 Dsymbol *s = (Dsymbol *)fields.data[i];
|
|
96 VarDeclaration *v = s->isVarDeclaration();
|
|
97 assert(v && v->storage_class & STCfield);
|
|
98 Type *tv = v->type->toBasetype();
|
|
99 size_t dim = 1;
|
|
100 while (tv->ty == Tsarray)
|
|
101 { TypeSArray *ta = (TypeSArray *)tv;
|
|
102 dim *= ((TypeSArray *)tv)->dim->toInteger();
|
|
103 tv = tv->nextOf()->toBasetype();
|
|
104 }
|
|
105 if (tv->ty == Tstruct)
|
|
106 { TypeStruct *ts = (TypeStruct *)tv;
|
|
107 StructDeclaration *sd = ts->sym;
|
|
108 if (sd->dtor)
|
|
109 { Expression *ex;
|
|
110
|
|
111 // this.v
|
|
112 ex = new ThisExp(0);
|
|
113 ex = new DotVarExp(0, ex, v, 0);
|
|
114
|
|
115 if (dim == 1)
|
|
116 { // this.v.dtor()
|
|
117 ex = new DotVarExp(0, ex, sd->dtor, 0);
|
|
118 ex = new CallExp(0, ex);
|
|
119 }
|
|
120 else
|
|
121 {
|
|
122 // Typeinfo.destroy(cast(void*)&this.v);
|
|
123 Expression *ea = new AddrExp(0, ex);
|
|
124 ea = new CastExp(0, ea, Type::tvoid->pointerTo());
|
|
125 Expressions *args = new Expressions();
|
|
126 args->push(ea);
|
|
127
|
|
128 Expression *et = v->type->getTypeInfo(sc);
|
|
129 et = new DotIdExp(0, et, Id::destroy);
|
|
130
|
|
131 ex = new CallExp(0, et, args);
|
|
132 }
|
|
133 e = Expression::combine(ex, e); // combine in reverse order
|
|
134 }
|
|
135 }
|
|
136 }
|
|
137
|
|
138 /* Build our own "destructor" which executes e
|
|
139 */
|
|
140 if (e)
|
|
141 { //printf("Building __fieldDtor()\n");
|
|
142 DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__fieldDtor"));
|
|
143 dd->fbody = new ExpStatement(0, e);
|
|
144 dtors.shift(dd);
|
|
145 members->push(dd);
|
|
146 dd->semantic(sc);
|
|
147 }
|
|
148 #endif
|
|
149
|
|
150 switch (dtors.dim)
|
|
151 {
|
|
152 case 0:
|
|
153 return NULL;
|
|
154
|
|
155 case 1:
|
|
156 return (FuncDeclaration *)dtors.data[0];
|
|
157
|
|
158 default:
|
|
159 e = NULL;
|
|
160 for (size_t i = 0; i < dtors.dim; i++)
|
|
161 { FuncDeclaration *fd = (FuncDeclaration *)dtors.data[i];
|
|
162 Expression *ex = new ThisExp(0);
|
|
163 ex = new DotVarExp(0, ex, fd);
|
|
164 ex = new CallExp(0, ex);
|
|
165 e = Expression::combine(ex, e);
|
|
166 }
|
|
167 DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__aggrDtor"));
|
|
168 dd->fbody = new ExpStatement(0, e);
|
|
169 members->push(dd);
|
|
170 dd->semantic(sc);
|
|
171 return dd;
|
|
172 }
|
|
173 }
|
|
174
|
|
175
|