本文整理汇总了C++中Dsymbol::isVarDeclaration方法的典型用法代码示例。如果您正苦于以下问题:C++ Dsymbol::isVarDeclaration方法的具体用法?C++ Dsymbol::isVarDeclaration怎么用?C++ Dsymbol::isVarDeclaration使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Dsymbol
的用法示例。
在下文中一共展示了Dsymbol::isVarDeclaration方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: build_classinfo_flags
static unsigned build_classinfo_flags(ClassDeclaration* cd)
{
// adapted from original dmd code
unsigned flags = 0;
flags |= cd->isCOMclass(); // IUnknown
bool hasOffTi = false;
if (cd->ctor)
flags |= 8;
if (cd->isabstract)
flags |= 64;
for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
{
if (!cd2->members)
continue;
for (size_t i = 0; i < cd2->members->dim; i++)
{
Dsymbol *sm = static_cast<Dsymbol *>(cd2->members->data[i]);
if (sm->isVarDeclaration() && !sm->isVarDeclaration()->isDataseg()) // is this enough?
hasOffTi = true;
//printf("sm = %s %s\n", sm->kind(), sm->toChars());
if (sm->hasPointers())
goto L2;
}
}
flags |= 2; // no pointers
L2:
if (hasOffTi)
flags |= 4;
// always define the typeinfo field.
// why would ever not do this?
flags |= 32;
return flags;
}
示例2: isPOD
/***************************************
* Return true if struct is POD (Plain Old Data).
* This is defined as:
* not nested
* no postblits, constructors, destructors, or assignment operators
* no fields with with any of those
* The idea being these are compatible with C structs.
*
* Note that D struct constructors can mean POD, since there is always default
* construction with no ctor, but that interferes with OPstrpar which wants it
* on the stack in memory, not in registers.
*/
bool StructDeclaration::isPOD()
{
if (enclosing || cpctor || postblit || ctor || dtor)
return false;
/* Recursively check any fields have a constructor.
* We should cache the results of this.
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (!sd->isPOD())
return false;
}
}
return true;
}
示例3: needOpEquals
int StructDeclaration::needOpEquals()
{
#define X 0
if (X) printf("StructDeclaration::needOpEquals() %s\n", toChars());
if (hasIdentityEquals)
goto Lneed;
#if 0
if (isUnionDeclaration())
goto Ldontneed;
#endif
/* If any of the fields has an opEquals, then we
* need it too.
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
#if 0
if (tv->isfloating())
goto Lneed;
if (tv->ty == Tarray)
goto Lneed;
if (tv->ty == Tclass)
goto Lneed;
#endif
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->needOpEquals())
goto Lneed;
}
}
Ldontneed:
if (X) printf("\tdontneed\n");
return 0;
Lneed:
if (X) printf("\tneed\n");
return 1;
#undef X
}
示例4: codegen
void TemplateMixin::codegen(Ir* p)
{
if (!errors && members)
{
for (unsigned i = 0; i < members->dim; i++)
{
Dsymbol *s = static_cast<Dsymbol *>(members->data[i]);
if (s->isVarDeclaration())
continue;
s->codegen(p);
}
}
}
示例5: needOpAssign
int StructDeclaration::needOpAssign()
{
#define X 0
if (X) printf("StructDeclaration::needOpAssign() %s\n", toChars());
if (hasIdentityAssign)
goto Lneed; // because has identity==elaborate opAssign
if (dtor || postblit)
goto Lneed;
/* If any of the fields need an opAssign, then we
* need it too.
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->needOpAssign())
goto Lneed;
}
}
Ldontneed:
if (X) printf("\tdontneed\n");
return 0;
Lneed:
if (X) printf("\tneed\n");
return 1;
#undef X
}
示例6: calcZeroInit
int StructDeclaration::calcZeroInit()
{
// Determine if struct is all zeros or not
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd && !vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
return 0;
}
else if (!vd->type->isZeroInit(loc))
{
return 0;
}
}
}
return 1;
}
示例7: Parameter
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], size_t dim)
{
#if 1
/*
* Pass a reference to the TypeInfo_Tuple corresponding to the types of the
* arguments. Source compatibility is maintained by computing _arguments[]
* at the start of the called function by offseting into the TypeInfo_Tuple
* reference.
*/
Parameters *args = new Parameters;
args->setDim(dim);
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL);
(*args)[i] = arg;
}
TypeTuple *tup = new TypeTuple(args);
Expression *e = tup->getTypeInfo(sc);
e = e->optimize(WANTvalue);
assert(e->op == TOKsymoff); // should be SymOffExp
return e;
#else
/* Improvements:
* 1) create an array literal instead,
* as it would eliminate the extra dereference of loading the
* static variable.
*/
ArrayInitializer *ai = new ArrayInitializer(0);
VarDeclaration *v;
Type *t;
Expression *e;
OutBuffer buf;
Identifier *id;
char *name;
// Generate identifier for _arguments[]
buf.writestring("_arguments_");
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
t->toDecoBuffer(&buf);
}
buf.writeByte(0);
id = Lexer::idPool((char *)buf.data);
Module *m = sc->module;
Dsymbol *s = m->symtab->lookup(id);
if (s && s->parent == m)
{ // Use existing one
v = s->isVarDeclaration();
assert(v);
}
else
{ // Generate new one
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
e = t->getTypeInfo(sc);
ai->addInit(new IntegerExp(i), new ExpInitializer(Loc(), e));
}
t = Type::typeinfo->type->arrayOf();
ai->type = t;
v = new VarDeclaration(0, t, id, ai);
m->members->push(v);
m->symtabInsert(v);
sc = sc->push();
sc->linkage = LINKc;
sc->stc = STCstatic | STCcomdat;
ai->semantic(sc, t);
v->semantic(sc);
v->parent = m;
sc = sc->pop();
}
e = new VarExp(Loc(), v);
e = e->semantic(sc);
return e;
#endif
}
示例8: Parameter
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
{
#if 1
/* Get the corresponding TypeInfo_Tuple and
* point at its elements[].
*/
/* Create the TypeTuple corresponding to the types of args[]
*/
Parameters *args = new Parameters;
args->setDim(dim);
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL);
args->tdata()[i] = arg;
}
TypeTuple *tup = new TypeTuple(args);
Expression *e = tup->getTypeInfo(sc);
e = e->optimize(WANTvalue);
assert(e->op == TOKsymoff); // should be SymOffExp
#if BREAKABI
/*
* Should just pass a reference to TypeInfo_Tuple instead,
* but that would require existing code to be recompiled.
* Source compatibility can be maintained by computing _arguments[]
* at the start of the called function by offseting into the
* TypeInfo_Tuple reference.
*/
#else
// Advance to elements[] member of TypeInfo_Tuple
SymOffExp *se = (SymOffExp *)e;
se->offset += PTRSIZE + PTRSIZE;
// Set type to TypeInfo[]*
se->type = Type::typeinfo->type->arrayOf()->pointerTo();
// Indirect to get the _arguments[] value
e = new PtrExp(0, se);
e->type = se->type->next;
#endif
return e;
#else
/* Improvements:
* 1) create an array literal instead,
* as it would eliminate the extra dereference of loading the
* static variable.
*/
ArrayInitializer *ai = new ArrayInitializer(0);
VarDeclaration *v;
Type *t;
Expression *e;
OutBuffer buf;
Identifier *id;
char *name;
// Generate identifier for _arguments[]
buf.writestring("_arguments_");
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
t->toDecoBuffer(&buf);
}
buf.writeByte(0);
id = Lexer::idPool((char *)buf.data);
Module *m = sc->module;
Dsymbol *s = m->symtab->lookup(id);
if (s && s->parent == m)
{ // Use existing one
v = s->isVarDeclaration();
assert(v);
}
else
{ // Generate new one
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
e = t->getTypeInfo(sc);
ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
}
t = Type::typeinfo->type->arrayOf();
ai->type = t;
v = new VarDeclaration(0, t, id, ai);
m->members->push(v);
m->symtabInsert(v);
sc = sc->push();
sc->linkage = LINKc;
sc->stc = STCstatic | STCcomdat;
ai->semantic(sc, t);
v->semantic(sc);
v->parent = m;
sc = sc->pop();
}
e = new VarExp(0, v);
e = e->semantic(sc);
return e;
#endif
//.........这里部分代码省略.........
示例9: semantic
void AliasDeclaration::semantic(Scope *sc)
{
//printf("AliasDeclaration::semantic() %s\n", toChars());
if (aliassym)
{
if (aliassym->isTemplateInstance())
aliassym->semantic(sc);
return;
}
this->inSemantic = 1;
#if DMDV1 // don't really know why this is here
if (storage_class & STCconst)
error("cannot be const");
#endif
storage_class |= sc->stc & STCdeprecated;
// Given:
// alias foo.bar.abc def;
// it is not knowable from the syntax whether this is an alias
// for a type or an alias for a symbol. It is up to the semantic()
// pass to distinguish.
// If it is a type, then type is set and getType() will return that
// type. If it is a symbol, then aliassym is set and type is NULL -
// toAlias() will return aliasssym.
Dsymbol *s;
Type *t;
Expression *e;
/* This section is needed because resolve() will:
* const x = 3;
* alias x y;
* try to alias y to 3.
*/
s = type->toDsymbol(sc);
if (s
#if DMDV2
` && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
#endif
)
goto L2; // it's a symbolic alias
#if DMDV2
type = type->addStorageClass(storage_class);
if (storage_class & (STCref | STCnothrow | STCpure | STCdisable))
{ // For 'ref' to be attached to function types, and picked
// up by Type::resolve(), it has to go into sc.
sc = sc->push();
sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable);
type->resolve(loc, sc, &e, &t, &s);
sc = sc->pop();
}
else
#endif
type->resolve(loc, sc, &e, &t, &s);
if (s)
{
goto L2;
}
else if (e)
{
// Try to convert Expression to Dsymbol
if (e->op == TOKvar)
{ s = ((VarExp *)e)->var;
goto L2;
}
else if (e->op == TOKfunction)
{ s = ((FuncExp *)e)->fd;
goto L2;
}
else
{ error("cannot alias an expression %s", e->toChars());
t = e->type;
}
}
else if (t)
{
type = t;
}
if (overnext)
ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0;
return;
L2:
//printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
type = NULL;
VarDeclaration *v = s->isVarDeclaration();
if (0 && v && v->linkage == LINKdefault)
{
error("forward reference of %s", v->toChars());
s = NULL;
}
else
{
FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
if (f)
{
//.........这里部分代码省略.........
示例10: assert
FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
{
//printf("AggregateDeclaration::buildDtor() %s\n", toChars());
Expression *e = NULL;
#if DMDV2
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_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 && dim)
{ Expression *ex;
// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (v->type->toBasetype()->ty == Tstruct)
{ // 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());
Expression *et = v->type->getTypeInfo(sc);
et = new DotIdExp(0, et, Id::destroy);
ex = new CallExp(0, et, ea);
}
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(loc, 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 dtors[0];
default:
e = NULL;
for (size_t i = 0; i < dtors.dim; i++)
{ FuncDeclaration *fd = dtors[i];
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, fd, 0);
ex = new CallExp(0, ex);
e = Expression::combine(ex, e);
}
DtorDeclaration *dd = new DtorDeclaration(loc, 0, Lexer::idPool("__aggrDtor"));
dd->fbody = new ExpStatement(0, e);
members->push(dd);
dd->semantic(sc);
return dd;
}
}
示例11: DotVarExp
FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
{
Dsymbol *eq = search_function(this, Id::eq);
if (eq)
{
/* check identity opEquals exists
*/
Type *tthis = type->constOf();
Expression *er = new NullExp(loc, tthis); // dummy rvalue
Expression *el = new IdentifierExp(loc, Id::p); // dummy lvalue
el->type = tthis;
Expressions ar; ar.push(er);
Expressions al; al.push(el);
FuncDeclaration *f = NULL;
unsigned errors = global.startGagging(); // Do not report errors, even if the
unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it.
global.speculativeGag = global.gag;
sc = sc->push();
sc->speculative = true;
f = resolveFuncCall(loc, sc, eq, NULL, er, &ar, 1);
if (!f) f = resolveFuncCall(loc, sc, eq, NULL, er, &al, 1);
sc = sc->pop();
global.speculativeGag = oldspec;
global.endGagging(errors);
if (f)
return (f->storage_class & STCdisable) ? NULL : f;
return NULL;
}
if (!needOpEquals())
return NULL;
//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCin, type, Id::p, NULL));
TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
tf->mod = MODconst;
tf = (TypeFunction *)tf->semantic(loc, sc);
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::eq, STCundefined, tf);
Expression *e = NULL;
/* Do memberwise compare
*/
//printf("\tmemberwise compare\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
assert(0); // what should we do with this?
// this.v == s.v;
EqualExp *ec = new EqualExp(TOKequal, loc,
new DotVarExp(loc, new ThisExp(loc), v, 0),
new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0));
if (e)
e = new AndAndExp(loc, e, ec);
else
e = ec;
}
if (!e)
e = new IntegerExp(loc, 1, Type::tbool);
fop->fbody = new ReturnStatement(loc, e);
members->push(fop);
fop->addMember(sc, this, 1);
sc = sc->push();
sc->stc = 0;
sc->linkage = LINKd;
fop->semantic(sc);
sc->pop();
//printf("-StructDeclaration::buildOpEquals() %s\n", toChars());
return fop;
}
示例12: VarExp
FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{
Dsymbol *assign = search_function(this, Id::assign);
if (assign)
{
if (FuncDeclaration *f = hasIdentityOpAssign(sc, assign))
return f;
// Even if non-identity opAssign is defined, built-in identity opAssign
// will be defined. (Is this an exception of operator overloading rule?)
}
if (!needOpAssign())
return NULL;
//printf("StructDeclaration::buildOpAssign() %s\n", toChars());
Parameters *fparams = new Parameters;
fparams->push(new Parameter(STCnodtor, type, Id::p, NULL));
Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd);
((TypeFunction *)ftype)->isref = 1;
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::assign, STCundefined, ftype);
Expression *e = NULL;
if (postblit)
{ /* Swap:
* tmp = *this; *this = s; tmp.dtor();
*/
//printf("\tswap copy\n");
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp;
AssignExp *ec = NULL;
if (dtor)
{
tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0));
tmp->noscope = 1;
tmp->storage_class |= STCctfe;
e = new DeclarationExp(0, tmp);
ec = new AssignExp(0,
new VarExp(0, tmp),
new ThisExp(0)
);
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
ec = new AssignExp(0,
new ThisExp(0),
new IdentifierExp(0, Id::p));
ec->op = TOKblit;
e = Expression::combine(e, ec);
if (dtor)
{
/* Instead of running the destructor on s, run it
* on tmp. This avoids needing to copy tmp back in to s.
*/
Expression *ec2 = new DotVarExp(0, new VarExp(0, tmp), dtor, 0);
ec2 = new CallExp(0, ec2);
e = Expression::combine(e, ec2);
}
}
else
{ /* Do memberwise copy
*/
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
// this.v = s.v;
AssignExp *ec = new AssignExp(0,
new DotVarExp(0, new ThisExp(0), v, 0),
new DotVarExp(0, new IdentifierExp(0, Id::p), v, 0));
e = Expression::combine(e, ec);
}
}
Statement *s1 = new ExpStatement(0, e);
/* Add:
* return this;
*/
e = new ThisExp(0);
Statement *s2 = new ReturnStatement(0, e);
fop->fbody = new CompoundStatement(0, s1, s2);
Dsymbol *s = fop;
if (assign && assign->isTemplateDeclaration())
{
// Wrap a template around the function declaration
TemplateParameters *tpl = new TemplateParameters();
Dsymbols *decldefs = new Dsymbols();
decldefs->push(s);
TemplateDeclaration *tempdecl =
new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0);
s = tempdecl;
}
members->push(s);
s->addMember(sc, this, 1);
this->hasIdentityAssign = 1; // temporary mark identity assignable
//.........这里部分代码省略.........
示例13: if
FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{
if (FuncDeclaration *f = hasIdentityOpAssign(sc))
{
hasIdentityAssign = 1;
return f;
}
// Even if non-identity opAssign is defined, built-in identity opAssign
// will be defined.
if (!needOpAssign())
return NULL;
//printf("StructDeclaration::buildOpAssign() %s\n", toChars());
StorageClass stc = STCsafe | STCnothrow | STCpure;
Loc declLoc = this->loc;
Loc loc = Loc(); // internal code should have no loc to prevent coverage
if (dtor || postblit)
{
if (dtor)
stc = mergeFuncAttrs(stc, dtor->storage_class);
}
else
{
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (FuncDeclaration *f = sd->hasIdentityOpAssign(sc))
stc = mergeFuncAttrs(stc, f->storage_class);
}
}
}
Parameters *fparams = new Parameters;
fparams->push(new Parameter(STCnodtor, type, Id::p, NULL));
Type *tf = new TypeFunction(fparams, handle, 0, LINKd, stc | STCref);
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
Expression *e = NULL;
if (stc & STCdisable)
{
}
else if (dtor || postblit)
{
/* Do swap this and rhs
* tmp = this; this = s; tmp.dtor();
*/
//printf("\tswap copy\n");
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp;
AssignExp *ec = NULL;
if (dtor)
{
tmp = new VarDeclaration(loc, type, idtmp, new VoidInitializer(loc));
tmp->noscope = 1;
tmp->storage_class |= STCctfe;
e = new DeclarationExp(loc, tmp);
ec = new AssignExp(loc,
new VarExp(loc, tmp),
new ThisExp(loc)
);
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
ec = new AssignExp(loc,
new ThisExp(loc),
new IdentifierExp(loc, Id::p));
ec->op = TOKblit;
e = Expression::combine(e, ec);
if (dtor)
{
/* Instead of running the destructor on s, run it
* on tmp. This avoids needing to copy tmp back in to s.
*/
Expression *ec2 = new DotVarExp(loc, new VarExp(loc, tmp), dtor, 0);
ec2 = new CallExp(loc, ec2);
e = Expression::combine(e, ec2);
}
}
else
{
/* Do memberwise copy
*/
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
//.........这里部分代码省略.........
示例14: VarExp
FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{
if (!needOpAssign())
return NULL;
//printf("StructDeclaration::buildOpAssign() %s\n", toChars());
FuncDeclaration *fop = NULL;
Parameters *fparams = new Parameters;
fparams->push(new Parameter(STCnodtor, type, Id::p, NULL));
Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd);
#if STRUCTTHISREF
((TypeFunction *)ftype)->isref = 1;
#endif
fop = new FuncDeclaration(loc, 0, Id::assign, STCundefined, ftype);
Expression *e = NULL;
if (postblit)
{ /* Swap:
* tmp = *this; *this = s; tmp.dtor();
*/
//printf("\tswap copy\n");
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp;
AssignExp *ec = NULL;
if (dtor)
{
tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0));
tmp->noscope = 1;
tmp->storage_class |= STCctfe;
e = new DeclarationExp(0, tmp);
ec = new AssignExp(0,
new VarExp(0, tmp),
#if STRUCTTHISREF
new ThisExp(0)
#else
new PtrExp(0, new ThisExp(0))
#endif
);
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
ec = new AssignExp(0,
#if STRUCTTHISREF
new ThisExp(0),
#else
new PtrExp(0, new ThisExp(0)),
#endif
new IdentifierExp(0, Id::p));
ec->op = TOKblit;
e = Expression::combine(e, ec);
if (dtor)
{
/* Instead of running the destructor on s, run it
* on tmp. This avoids needing to copy tmp back in to s.
*/
Expression *ec2 = new DotVarExp(0, new VarExp(0, tmp), dtor, 0);
ec2 = new CallExp(0, ec2);
e = Expression::combine(e, ec2);
}
}
else
{ /* Do memberwise copy
*/
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
// this.v = s.v;
AssignExp *ec = new AssignExp(0,
new DotVarExp(0, new ThisExp(0), v, 0),
new DotVarExp(0, new IdentifierExp(0, Id::p), v, 0));
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
}
Statement *s1 = new ExpStatement(0, e);
/* Add:
* return this;
*/
e = new ThisExp(0);
Statement *s2 = new ReturnStatement(0, e);
fop->fbody = new CompoundStatement(0, s1, s2);
members->push(fop);
fop->addMember(sc, this, 1);
sc = sc->push();
sc->stc = 0;
sc->linkage = LINKd;
fop->semantic(sc);
sc->pop();
//.........这里部分代码省略.........
示例15: DotVarExp
FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
{
Dsymbol *eq = search_function(this, Id::eq);
if (eq)
{
for (size_t i = 0; i <= 1; i++)
{
Expression *e =
i == 0 ? new NullExp(loc, type->constOf()) // dummy rvalue
: type->constOf()->defaultInit(); // dummy lvalue
Expressions *arguments = new Expressions();
arguments->push(e);
// check identity opEquals exists
FuncDeclaration *fd = eq->isFuncDeclaration();
if (fd)
{ fd = fd->overloadResolve(loc, e, arguments, 1);
if (fd && !(fd->storage_class & STCdisable))
return fd;
}
TemplateDeclaration *td = eq->isTemplateDeclaration();
if (td)
{ fd = td->deduceFunctionTemplate(sc, loc, NULL, e, arguments, 1);
if (fd && !(fd->storage_class & STCdisable))
return fd;
}
}
return NULL;
}
if (!needOpEquals())
return NULL;
//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCin, type, Id::p, NULL));
TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
tf->mod = MODconst;
tf = (TypeFunction *)tf->semantic(loc, sc);
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::eq, STCundefined, tf);
Expression *e = NULL;
/* Do memberwise compare
*/
//printf("\tmemberwise compare\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
assert(0); // what should we do with this?
// this.v == s.v;
EqualExp *ec = new EqualExp(TOKequal, loc,
new DotVarExp(loc, new ThisExp(loc), v, 0),
new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0));
if (e)
e = new AndAndExp(loc, e, ec);
else
e = ec;
}
if (!e)
e = new IntegerExp(loc, 1, Type::tbool);
fop->fbody = new ReturnStatement(loc, e);
members->push(fop);
fop->addMember(sc, this, 1);
sc = sc->push();
sc->stc = 0;
sc->linkage = LINKd;
fop->semantic(sc);
sc->pop();
//printf("-StructDeclaration::buildOpEquals() %s\n", toChars());
return fop;
}