Mercurial > projects > ldc
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 |