annotate dmd/clone.c @ 650:aa6a0b7968f7

Added test case for bug #100 Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 05 Oct 2008 17:28:15 +0200
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