annotate dmd/clone.c @ 1638:0de4525a9ed6

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