mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-12 06:49:02 +02:00
[svn r175] merged dmd 1.029
This commit is contained in:
175
dmd/clone.c
Normal file
175
dmd/clone.c
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2008 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "aggregate.h"
|
||||
#include "scope.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
|
||||
|
||||
/*********************************
|
||||
* Generate expression that calls opClone()
|
||||
* for each member of the struct
|
||||
* (can be NULL for members that don't need one)
|
||||
*/
|
||||
|
||||
#if V2
|
||||
Expression *StructDeclaration::cloneMembers()
|
||||
{
|
||||
Expression *e = NULL;
|
||||
|
||||
for (size_t i = 0; i < fields.dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)fields.data[i];
|
||||
VarDeclaration *v = s->isVarDeclaration();
|
||||
assert(v && v->storage_class & STCfield);
|
||||
Type *tv = v->type->toBasetype();
|
||||
size_t dim = 1;
|
||||
while (tv->ty == Tsarray)
|
||||
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||
tv = tv->nextOf()->toBasetype();
|
||||
}
|
||||
if (tv->ty == Tstruct)
|
||||
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||
StructDeclaration *sd = ts->sym;
|
||||
if (sd->opclone)
|
||||
{ Expression *ex;
|
||||
|
||||
// this.v
|
||||
ex = new ThisExp(0);
|
||||
ex = new DotVarExp(0, ex, v, 0);
|
||||
|
||||
if (dim == 1)
|
||||
{ // this.v.opClone()
|
||||
ex = new DotVarExp(0, ex, sd->opclone, 0);
|
||||
ex = new CallExp(0, ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// _callOpClones(&this.v, opclone, dim)
|
||||
Expressions *args = new Expressions();
|
||||
args->push(new AddrExp(0, ex));
|
||||
args->push(new SymOffExp(0, sd->opclone, 0));
|
||||
args->push(new IntegerExp(dim));
|
||||
FuncDeclaration *ec = FuncDeclaration::genCfunc(Type::tvoid, "_callOpClones");
|
||||
ex = new CallExp(0, new VarExp(0, ec), args);
|
||||
}
|
||||
e = Expression::combine(e, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************
|
||||
* Create inclusive destructor for struct by aggregating
|
||||
* all the destructors in dtors[] with the destructors for
|
||||
* all the members.
|
||||
*/
|
||||
|
||||
FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
||||
{
|
||||
//printf("StructDeclaration::buildDtor() %s\n", toChars());
|
||||
Expression *e = NULL;
|
||||
|
||||
#if V2
|
||||
for (size_t i = 0; i < fields.dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)fields.data[i];
|
||||
VarDeclaration *v = s->isVarDeclaration();
|
||||
assert(v && v->storage_class & STCfield);
|
||||
Type *tv = v->type->toBasetype();
|
||||
size_t dim = 1;
|
||||
while (tv->ty == Tsarray)
|
||||
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||
tv = tv->nextOf()->toBasetype();
|
||||
}
|
||||
if (tv->ty == Tstruct)
|
||||
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||
StructDeclaration *sd = ts->sym;
|
||||
if (sd->dtor)
|
||||
{ Expression *ex;
|
||||
|
||||
// this.v
|
||||
ex = new ThisExp(0);
|
||||
ex = new DotVarExp(0, ex, v, 0);
|
||||
|
||||
if (dim == 1)
|
||||
{ // this.v.dtor()
|
||||
ex = new DotVarExp(0, ex, sd->dtor, 0);
|
||||
ex = new CallExp(0, ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Typeinfo.destroy(cast(void*)&this.v);
|
||||
Expression *ea = new AddrExp(0, ex);
|
||||
ea = new CastExp(0, ea, Type::tvoid->pointerTo());
|
||||
Expressions *args = new Expressions();
|
||||
args->push(ea);
|
||||
|
||||
Expression *et = v->type->getTypeInfo(sc);
|
||||
et = new DotIdExp(0, et, Id::destroy);
|
||||
|
||||
ex = new CallExp(0, et, args);
|
||||
}
|
||||
e = Expression::combine(ex, e); // combine in reverse order
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build our own "destructor" which executes e
|
||||
*/
|
||||
if (e)
|
||||
{ //printf("Building __fieldDtor()\n");
|
||||
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__fieldDtor"));
|
||||
dd->fbody = new ExpStatement(0, e);
|
||||
dtors.shift(dd);
|
||||
members->push(dd);
|
||||
dd->semantic(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (dtors.dim)
|
||||
{
|
||||
case 0:
|
||||
return NULL;
|
||||
|
||||
case 1:
|
||||
return (FuncDeclaration *)dtors.data[0];
|
||||
|
||||
default:
|
||||
e = NULL;
|
||||
for (size_t i = 0; i < dtors.dim; i++)
|
||||
{ FuncDeclaration *fd = (FuncDeclaration *)dtors.data[i];
|
||||
Expression *ex = new ThisExp(0);
|
||||
ex = new DotVarExp(0, ex, fd);
|
||||
ex = new CallExp(0, ex);
|
||||
e = Expression::combine(ex, e);
|
||||
}
|
||||
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__aggrDtor"));
|
||||
dd->fbody = new ExpStatement(0, e);
|
||||
members->push(dd);
|
||||
dd->semantic(sc);
|
||||
return dd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user