2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
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.
15 #include "aggregate.h"
18 #include "declaration.h"
21 #include "expression.h"
22 #include "statement.h"
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)
32 Expression
*StructDeclaration::cloneMembers()
36 for (size_t i
= 0; i
< fields
.dim
; i
++)
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();
43 while (tv
->ty
== Tsarray
)
44 { TypeSArray
*ta
= (TypeSArray
*)tv
;
45 dim
*= ((TypeSArray
*)tv
)->dim
->toInteger();
46 tv
= tv
->nextOf()->toBasetype();
48 if (tv
->ty
== Tstruct
)
49 { TypeStruct
*ts
= (TypeStruct
*)tv
;
50 StructDeclaration
*sd
= ts
->sym
;
56 ex
= new DotVarExp(0, ex
, v
, 0);
60 ex
= new DotVarExp(0, ex
, sd
->opclone
, 0);
61 ex
= new CallExp(0, ex
);
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
);
73 e
= Expression::combine(e
, ex
);
81 /*****************************************
82 * Create inclusive destructor for struct by aggregating
83 * all the destructors in dtors[] with the destructors for
87 FuncDeclaration
*AggregateDeclaration::buildDtor(Scope
*sc
)
89 //printf("StructDeclaration::buildDtor() %s\n", toChars());
93 for (size_t i
= 0; i
< fields
.dim
; i
++)
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();
100 while (tv
->ty
== Tsarray
)
101 { TypeSArray
*ta
= (TypeSArray
*)tv
;
102 dim
*= ((TypeSArray
*)tv
)->dim
->toInteger();
103 tv
= tv
->nextOf()->toBasetype();
105 if (tv
->ty
== Tstruct
)
106 { TypeStruct
*ts
= (TypeStruct
*)tv
;
107 StructDeclaration
*sd
= ts
->sym
;
113 ex
= new DotVarExp(0, ex
, v
, 0);
117 ex
= new DotVarExp(0, ex
, sd
->dtor
, 0);
118 ex
= new CallExp(0, ex
);
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();
128 Expression
*et
= v
->type
->getTypeInfo(sc
);
129 et
= new DotIdExp(0, et
, Id::destroy
);
131 ex
= new CallExp(0, et
, args
);
133 e
= Expression::combine(ex
, e
); // combine in reverse order
138 /* Build our own "destructor" which executes e
141 { //printf("Building __fieldDtor()\n");
142 DtorDeclaration
*dd
= new DtorDeclaration(0, 0, Lexer::idPool("__fieldDtor"));
143 dd
->fbody
= new ExpStatement(0, e
);
156 return (FuncDeclaration
*)dtors
.data
[0];
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
);
167 DtorDeclaration
*dd
= new DtorDeclaration(0, 0, Lexer::idPool("__aggrDtor"));
168 dd
->fbody
= new ExpStatement(0, e
);