comparison dmd/clone.c @ 159:5acec6b2eef8 trunk

[svn r175] merged dmd 1.029
author ChristianK
date Thu, 01 May 2008 15:15:28 +0200
parents
children aaade6ded589
comparison
equal deleted inserted replaced
158:287540c5f05e 159:5acec6b2eef8
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
31 #if V2
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
92 #if V2
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