本文整理汇总了C++中Expressions::push方法的典型用法代码示例。如果您正苦于以下问题:C++ Expressions::push方法的具体用法?C++ Expressions::push怎么用?C++ Expressions::push使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Expressions
的用法示例。
在下文中一共展示了Expressions::push方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Expressions
/***************************************
* This works by transforming a struct initializer into
* a struct literal. In the future, the two should be the
* same thing.
*/
Expression *StructInitializer::toExpression()
{ Expression *e;
//printf("StructInitializer::toExpression() %s\n", toChars());
if (!ad) // if fwd referenced
{
return NULL;
}
StructDeclaration *sd = ad->isStructDeclaration();
if (!sd)
return NULL;
Expressions *elements = new Expressions();
for (size_t i = 0; i < value.dim; i++)
{
if (field.data[i])
goto Lno;
Initializer *iz = (Initializer *)value.data[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
if (!ex)
goto Lno;
elements->push(ex);
}
e = new StructLiteralExp(loc, sd, elements);
e->type = sd->type;
return e;
Lno:
delete elements;
//error(loc, "struct initializers as expressions are not allowed");
return NULL;
}
示例2: arrayExpressionSemantic
Expressions *UserAttributeDeclaration::getAttributes()
{
if (scope)
{
Scope *sc = scope;
scope = NULL;
arrayExpressionSemantic(atts, sc);
}
Expressions *exps = new Expressions();
if (userAttribDecl)
exps->push(new TupleExp(Loc(), userAttribDecl->getAttributes()));
if (atts && atts->dim)
exps->push(new TupleExp(Loc(), atts));
return exps;
}
示例3: NullExp
FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc, Dsymbol *assign)
{
if (assign)
{
/* check identity opAssign exists
*/
Expression *er = new NullExp(loc, type); // dummy rvalue
Expression *el = new IdentifierExp(loc, Id::p); // dummy lvalue
el->type = type;
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, assign, NULL, er, &ar, 1);
if (!f) f = resolveFuncCall(loc, sc, assign, NULL, er, &al, 1);
sc = sc->pop();
global.speculativeGag = oldspec;
global.endGagging(errors);
if (f)
{
int varargs;
Parameters *fparams = f->getParameters(&varargs);
if (fparams->dim >= 1)
{
Parameter *arg0 = Parameter::getNth(fparams, 0);
if (arg0->type->toDsymbol(NULL) != this)
f = NULL;
}
}
// BUGS: This detection mechanism cannot find some opAssign-s like follows:
// struct S { void opAssign(ref immutable S) const; }
return f;
}
return NULL;
}
示例4: visit
void visit(SliceExp *e)
{
Identifier *id = Identifier::generateId("p", fparams->dim);
Parameter *param = new Parameter(STCconst, e->type, id, NULL);
fparams->shift(param);
Expression *ie = new IdentifierExp(Loc(), id);
Expressions *arguments = new Expressions();
Expression *index = new IdentifierExp(Loc(), Id::p);
arguments->push(index);
result = new ArrayExp(Loc(), ie, arguments);
}
示例5: Parameter
Expression *SliceExp::buildArrayLoop(Parameters *fparams)
{
Identifier *id = Identifier::generateId("p", fparams->dim);
Parameter *param = new Parameter(STCconst, type, id, NULL);
fparams->shift(param);
Expression *e = new IdentifierExp(0, id);
Expressions *arguments = new Expressions();
Expression *index = new IdentifierExp(0, Id::p);
arguments->push(index);
e = new ArrayExp(0, e, arguments);
return e;
}
示例6: setScope
void UserAttributeDeclaration::setScope(Scope *sc)
{
//printf("UserAttributeDeclaration::setScope() %p\n", this);
if (decl)
{
Scope *newsc = sc;
#if 1
if (atts && atts->dim)
{
// create new one for changes
newsc = new Scope(*sc);
newsc->flags &= ~SCOPEfree;
// Append new atts to old one
if (!newsc->userAttributes || newsc->userAttributes->dim == 0)
newsc->userAttributes = atts;
else
{
// Create a tuple that combines them
Expressions *exps = new Expressions();
exps->push(new TupleExp(Loc(), newsc->userAttributes));
exps->push(new TupleExp(Loc(), atts));
newsc->userAttributes = exps;
}
}
#endif
for (size_t i = 0; i < decl->dim; i++)
{ Dsymbol *s = (*decl)[i];
s->setScope(newsc); // yes, the only difference from semantic()
}
if (newsc != sc)
{
sc->offset = newsc->offset;
newsc->pop();
}
}
}
示例7: if
Expressions *UserAttributeDeclaration::concat(Expressions *udas1, Expressions *udas2)
{
Expressions *udas;
if (!udas1 || udas1->dim == 0)
udas = udas2;
else if (!udas2 || udas2->dim == 0)
udas = udas1;
else
{
/* Create a new tuple that combines them
* (do not append to left operand, as this is a copy-on-write operation)
*/
udas = new Expressions();
udas->push(new TupleExp(Loc(), udas1));
udas->push(new TupleExp(Loc(), udas2));
}
return udas;
}
示例8: while
/***********************************
* Parse list of extended asm clobbers.
* Grammar:
* | Clobbers:
* | StringLiteral
* | StringLiteral , Clobbers
* Params:
* p = parser state
* Returns:
* array of parsed clobber expressions
*/
static Expressions *parseExtAsmClobbers(Parser *p)
{
Expressions *clobbers = NULL;
while (1)
{
Expression *clobber;
switch (p->token.value)
{
case TOKsemicolon:
case TOKcolon:
case TOKeof:
return clobbers;
case TOKstring:
clobber = p->parsePrimaryExp();
if (!clobbers)
clobbers = new Expressions();
clobbers->push(clobber);
if (p->token.value == TOKcomma)
p->nextToken();
break;
default:
p->error("expected constant string constraint for clobber name, not `%s`",
p->token.toChars());
goto Lerror;
}
}
Lerror:
while (p->token.value != TOKrcurly &&
p->token.value != TOKsemicolon &&
p->token.value != TOKeof)
p->nextToken();
return clobbers;
}
示例9: FuncDeclaration_toObjFile
void FuncDeclaration_toObjFile(FuncDeclaration *fd, bool multiobj)
{
ClassDeclaration *cd = fd->parent->isClassDeclaration();
//printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", fd, fd->parent->toChars(), fd->toChars());
//if (type) printf("type = %s\n", type->toChars());
#if 0
//printf("line = %d\n", getWhere() / LINEINC);
EEcontext *ee = env->getEEcontext();
if (ee->EEcompile == 2)
{
if (ee->EElinnum < (getWhere() / LINEINC) ||
ee->EElinnum > (endwhere / LINEINC)
)
return; // don't compile this function
ee->EEfunc = toSymbol(this);
}
#endif
if (fd->semanticRun >= PASSobj) // if toObjFile() already run
return;
if (fd->type && fd->type->ty == Tfunction && ((TypeFunction *)fd->type)->next == NULL)
return;
// If errors occurred compiling it, such as bugzilla 6118
if (fd->type && fd->type->ty == Tfunction && ((TypeFunction *)fd->type)->next->ty == Terror)
return;
if (global.errors)
return;
if (!fd->fbody)
return;
UnitTestDeclaration *ud = fd->isUnitTestDeclaration();
if (ud && !global.params.useUnitTests)
return;
if (multiobj && !fd->isStaticDtorDeclaration() && !fd->isStaticCtorDeclaration())
{
obj_append(fd);
return;
}
if (fd->semanticRun == PASSsemanticdone)
{
/* What happened is this function failed semantic3() with errors,
* but the errors were gagged.
* Try to reproduce those errors, and then fail.
*/
fd->error("errors compiling the function");
return;
}
assert(fd->semanticRun == PASSsemantic3done);
assert(fd->ident != Id::empty);
for (FuncDeclaration *fd2 = fd; fd2; )
{
if (fd2->inNonRoot())
return;
if (fd2->isNested())
fd2 = fd2->toParent2()->isFuncDeclaration();
else
break;
}
FuncDeclaration *fdp = fd->toParent2()->isFuncDeclaration();
if (fd->isNested())
{
if (fdp && fdp->semanticRun < PASSobj)
{
if (fdp->semantic3Errors)
return;
/* Can't do unittest's out of order, they are order dependent in that their
* execution is done in lexical order.
*/
if (UnitTestDeclaration *udp = fdp->isUnitTestDeclaration())
{
udp->deferredNested.push(fd);
return;
}
}
}
if (fd->isArrayOp && isDruntimeArrayOp(fd->ident))
{
// Implementation is in druntime
return;
}
// start code generation
fd->semanticRun = PASSobj;
if (global.params.verbose)
fprintf(global.stdmsg, "function %s\n", fd->toPrettyChars());
Symbol *s = toSymbol(fd);
func_t *f = s->Sfunc;
//.........这里部分代码省略.........
示例10: semantic
//.........这里部分代码省略.........
baseclasses->shift(b);
baseClass = tc->sym;
assert(!baseClass->isInterfaceDeclaration());
b->base = baseClass;
}
interfaces_dim = baseclasses->dim;
interfaces = baseclasses->tdata();
if (baseClass)
{
if (baseClass->storage_class & STCfinal)
error("cannot inherit from final class %s", baseClass->toChars());
interfaces_dim--;
interfaces++;
// Copy vtbl[] from base class
vtbl.setDim(baseClass->vtbl.dim);
memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);
// Inherit properties from base class
com = baseClass->isCOMclass();
isscope = baseClass->isscope;
vthis = baseClass->vthis;
storage_class |= baseClass->storage_class & STC_TYPECTOR;
}
else
{
// No base class, so this is the root of the class hierarchy
vtbl.setDim(0);
vtbl.push(this); // leave room for classinfo as first member
}
protection = sc->protection;
storage_class |= sc->stc;
if (sizeok == SIZEOKnone)
{
interfaceSemantic(sc);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
s->addMember(sc, this, 1);
}
/* If this is a nested class, add the hidden 'this'
* member which is a pointer to the enclosing scope.
*/
if (vthis) // if inheriting from nested class
{ // Use the base class's 'this' member
isnested = true;
if (storage_class & STCstatic)
error("static class cannot inherit from nested class %s", baseClass->toChars());
if (toParent2() != baseClass->toParent2() &&
(!toParent2() ||
!baseClass->toParent2()->getType() ||
!baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL)))
{
if (toParent2())
{
error("is nested within %s, but super class %s is nested within %s",
toParent2()->toChars(),
示例11: if
/*********************************
* Operator overloading for op=
*/
Expression *BinAssignExp::op_overload(Scope *sc)
{
//printf("BinAssignExp::op_overload() (%s)\n", toChars());
#if DMDV2
if (e1->op == TOKarray)
{
ArrayExp *ae = (ArrayExp *)e1;
ae->e1 = ae->e1->semantic(sc);
ae->e1 = resolveProperties(sc, ae->e1);
AggregateDeclaration *ad = isAggregate(ae->e1->type);
if (ad)
{
/* Rewrite a[args]+=e2 as:
* a.opIndexOpAssign!("+")(e2, args);
*/
Dsymbol *fd = search_function(ad, Id::opIndexOpAssign);
if (fd)
{
Expressions *a = new Expressions();
a->push(e2);
for (size_t i = 0; i < ae->arguments->dim; i++)
a->push(ae->arguments->tdata()[i]);
Objects *targsi = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi);
e = new CallExp(loc, e, a);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis)
{
/* Rewrite a[arguments] op= e2 as:
* a.aliasthis[arguments] op= e2
*/
Expression *e1 = ae->copy();
((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
}
}
else if (e1->op == TOKslice)
{
SliceExp *se = (SliceExp *)e1;
se->e1 = se->e1->semantic(sc);
se->e1 = resolveProperties(sc, se->e1);
AggregateDeclaration *ad = isAggregate(se->e1->type);
if (ad)
{
/* Rewrite a[lwr..upr]+=e2 as:
* a.opSliceOpAssign!("+")(e2, lwr, upr);
*/
Dsymbol *fd = search_function(ad, Id::opSliceOpAssign);
if (fd)
{
Expressions *a = new Expressions();
a->push(e2);
if (se->lwr)
{ a->push(se->lwr);
a->push(se->upr);
}
Objects *targsi = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, targsi);
e = new CallExp(loc, e, a);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis)
{
/* Rewrite a[lwr..upr] op= e2 as:
* a.aliasthis[lwr..upr] op= e2
*/
Expression *e1 = se->copy();
((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
}
}
#endif
BinExp::semantic(sc);
e1 = resolveProperties(sc, e1);
e2 = resolveProperties(sc, e2);
//.........这里部分代码省略.........
示例12: if
/*********************************
* Operator overloading for op=
*/
Expression *BinAssignExp::op_overload(Scope *sc)
{
//printf("BinAssignExp::op_overload() (%s)\n", toChars());
#if DMDV2
if (e1->op == TOKarray)
{
ArrayExp *ae = (ArrayExp *)e1;
ae->e1 = ae->e1->semantic(sc);
ae->e1 = resolveProperties(sc, ae->e1);
AggregateDeclaration *ad = isAggregate(ae->e1->type);
if (ad)
{
/* Rewrite a[args]+=e2 as:
* a.opIndexOpAssign!("+")(e2, args);
*/
Dsymbol *fd = search_function(ad, Id::opIndexOpAssign);
if (fd)
{
ae = resolveOpDollar(sc, ae);
Expressions *a = (Expressions *)ae->arguments->copy();
a->insert(0, e2);
Objects *tiargs = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, tiargs);
e = new CallExp(loc, e, a);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis && ae->e1->type != att1)
{
/* Rewrite a[arguments] op= e2 as:
* a.aliasthis[arguments] op= e2
*/
Expression *e1 = ae->copy();
((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident);
BinExp *be = (BinExp *)copy();
if (!be->att1 && ae->e1->type->checkAliasThisRec())
be->att1 = ae->e1->type;
be->e1 = e1;
if (Expression *e = be->trySemantic(sc))
return e;
}
att1 = NULL;
}
}
else if (e1->op == TOKslice)
{
SliceExp *se = (SliceExp *)e1;
se->e1 = se->e1->semantic(sc);
se->e1 = resolveProperties(sc, se->e1);
AggregateDeclaration *ad = isAggregate(se->e1->type);
if (ad)
{
/* Rewrite a[lwr..upr]+=e2 as:
* a.opSliceOpAssign!("+")(e2, lwr, upr);
*/
Dsymbol *fd = search_function(ad, Id::opSliceOpAssign);
if (fd)
{
se = resolveOpDollar(sc, se);
Expressions *a = new Expressions();
a->push(e2);
assert(!se->lwr || se->upr);
if (se->lwr)
{ a->push(se->lwr);
a->push(se->upr);
}
Objects *tiargs = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, tiargs);
e = new CallExp(loc, e, a);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis && se->e1->type != att1)
{
/* Rewrite a[lwr..upr] op= e2 as:
* a.aliasthis[lwr..upr] op= e2
*/
Expression *e1 = se->copy();
((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident);
BinExp *be = (BinExp *)copy();
if (!be->att1 && se->e1->type->checkAliasThisRec())
be->att1 = se->e1->type;
be->e1 = e1;
if (Expression *e = be->trySemantic(sc))
return e;
}
att1 = NULL;
}
//.........这里部分代码省略.........
示例13: 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;
}
示例14: ErrorExp
//.........这里部分代码省略.........
{
Type *tb = t->toBasetype();
if (tb != t)
tb->accept(this);
}
virtual void visit(TypeError *t) { visit((Type *)t); }
virtual void visit(TypeNext *t) { assert(0); }
virtual void visit(TypeBasic *t)
{
if (t->ty == Tvoid)
setpointer(offset);
}
virtual void visit(TypeVector *t) { }
virtual void visit(TypeArray *t) { assert(0); }
virtual void visit(TypeSArray *t)
{
d_uns64 arrayoff = offset;
d_uns64 nextsize = t->next->size();
d_uns64 dim = t->dim->toInteger();
for (d_uns64 i = 0; i < dim; i++)
{
offset = arrayoff + i * nextsize;
t->next->accept(this);
}
offset = arrayoff;
}
virtual void visit(TypeDArray *t) { setpointer(offset + sz_size_t); } // dynamic array is {length,ptr}
virtual void visit(TypeAArray *t) { setpointer(offset); }
virtual void visit(TypePointer *t)
{
if (t->nextOf()->ty != Tfunction) // don't mark function pointers
setpointer(offset);
}
virtual void visit(TypeReference *t) { setpointer(offset); }
virtual void visit(TypeClass *t) { setpointer(offset); }
virtual void visit(TypeFunction *t) { }
virtual void visit(TypeDelegate *t) { setpointer(offset); } // delegate is {context, function}
virtual void visit(TypeQualified *t) { assert(0); } // assume resolved
virtual void visit(TypeIdentifier *t) { assert(0); }
virtual void visit(TypeInstance *t) { assert(0); }
virtual void visit(TypeTypeof *t) { assert(0); }
virtual void visit(TypeReturn *t) { assert(0); }
virtual void visit(TypeEnum *t) { visit((Type *)t); }
virtual void visit(TypeTuple *t) { visit((Type *)t); }
virtual void visit(TypeSlice *t) { assert(0); }
virtual void visit(TypeNull *t) { assert(0); }
virtual void visit(TypeStruct *t)
{
d_uns64 structoff = offset;
for (size_t i = 0; i < t->sym->fields.dim; i++)
{
VarDeclaration *v = t->sym->fields[i];
offset = structoff + v->offset;
if (v->type->ty == Tclass)
setpointer(offset);
else
v->type->accept(this);
}
offset = structoff;
}
// a "toplevel" class is treated as an instance, while TypeClass fields are treated as references
void visitClass(TypeClass* t)
{
d_uns64 classoff = offset;
// skip vtable-ptr and monitor
if (t->sym->baseClass)
visitClass((TypeClass*)t->sym->baseClass->type);
for (size_t i = 0; i < t->sym->fields.dim; i++)
{
VarDeclaration *v = t->sym->fields[i];
offset = classoff + v->offset;
v->type->accept(this);
}
offset = classoff;
}
Array<d_uns64>* data;
d_uns64 offset;
d_uns64 sz_size_t;
};
PointerBitmapVisitor pbv(&data, sz_size_t);
if (t->ty == Tclass)
pbv.visitClass((TypeClass*)t);
else
t->accept(&pbv);
Expressions* exps = new Expressions;
exps->push(new IntegerExp(e->loc, sz, Type::tsize_t));
for (d_uns64 i = 0; i < cntdata; i++)
exps->push(new IntegerExp(e->loc, data[(size_t)i], Type::tsize_t));
ArrayLiteralExp* ale = new ArrayLiteralExp(e->loc, exps);
ale->type = Type::tsize_t->sarrayOf(cntdata + 1);
return ale;
}
示例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;
}