Skip to content

Commit

Permalink
[Refactoring] Add hasIdentityOpEquals
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed May 7, 2013
1 parent 654de78 commit 95cc8b1
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
3 changes: 2 additions & 1 deletion src/aggregate.h
Expand Up @@ -107,7 +107,8 @@ struct AggregateDeclaration : ScopeDsymbol
void toJson(JsonOut *json);
void toDocBuffer(OutBuffer *buf, Scope *sc);

FuncDeclaration *hasIdentityOpAssign(Scope *sc, Dsymbol *assign);
FuncDeclaration *hasIdentityOpAssign(Scope *sc);
FuncDeclaration *hasIdentityOpEquals(Scope *sc);

char *mangle(bool isv = false);

Expand Down
9 changes: 3 additions & 6 deletions src/class.c
Expand Up @@ -767,13 +767,10 @@ void ClassDeclaration::semantic(Scope *sc)
Module::dprogress++;

dtor = buildDtor(sc);
if (Dsymbol *assign = search_function(this, Id::assign))
if (FuncDeclaration *f = hasIdentityOpAssign(sc))
{
if (FuncDeclaration *f = hasIdentityOpAssign(sc, assign))
{
if (!(f->storage_class & STCdisable))
error("identity assignment operator overload is illegal");
}
if (!(f->storage_class & STCdisable))
error("identity assignment operator overload is illegal");
}
sc->pop();

Expand Down
43 changes: 27 additions & 16 deletions src/clone.c
Expand Up @@ -28,8 +28,9 @@
* Check given opAssign symbol is really identity opAssign or not.
*/

FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc, Dsymbol *assign)
FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc)
{
Dsymbol *assign = search_function(this, Id::assign);
if (assign)
{
/* check identity opAssign exists
Expand Down Expand Up @@ -135,14 +136,13 @@ int StructDeclaration::needOpAssign()

FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{
Dsymbol *assign = search_function(this, Id::assign);
if (assign)
if (FuncDeclaration *f = hasIdentityOpAssign(sc))
{
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?)
hasIdentityAssign = 1;
return f;
}
// Even if non-identity opAssign is defined, built-in identity opAssign
// will be defined.

if (!needOpAssign())
return NULL;
Expand Down Expand Up @@ -220,6 +220,8 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
fop->fbody = new CompoundStatement(0, s1, s2);

Dsymbol *s = fop;
#if 1 // workaround until fixing issue 1528
Dsymbol *assign = search_function(this, Id::assign);
if (assign && assign->isTemplateDeclaration())
{
// Wrap a template around the function declaration
Expand All @@ -230,6 +232,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0);
s = tempdecl;
}
#endif
members->push(s);
s->addMember(sc, this, 1);
this->hasIdentityAssign = 1; // temporary mark identity assignable
Expand Down Expand Up @@ -318,12 +321,7 @@ int StructDeclaration::needOpEquals()
#undef X
}

/******************************************
* Build opEquals for struct.
* const bool opEquals(const S s) { ... }
*/

FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
FuncDeclaration *AggregateDeclaration::hasIdentityOpEquals(Scope *sc)
{
Dsymbol *eq = search_function(this, Id::eq);
if (eq)
Expand Down Expand Up @@ -352,8 +350,22 @@ FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
global.endGagging(errors);

if (f)
return (f->storage_class & STCdisable) ? NULL : f;
return NULL;
return f;
}
return NULL;
}

/******************************************
* Build opEquals for struct.
* const bool opEquals(const S s) { ... }
*/

FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
{
if (FuncDeclaration *f = hasIdentityOpEquals(sc))
{
hasIdentityEquals = (f->storage_class & STCdisable) ? 0 : 1;
return (f->storage_class & STCdisable) ? NULL : f;
}

if (!needOpEquals())
Expand Down Expand Up @@ -423,7 +435,6 @@ FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
* return ( *cast(const S*)(p) ).opEquals( *cast(const S*)(q) );
* }
*/

Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCin, Type::tvoidptr, Id::p, NULL));
parameters->push(new Parameter(STCin, Type::tvoidptr, Id::q, NULL));
Expand Down
4 changes: 2 additions & 2 deletions src/struct.c
Expand Up @@ -682,8 +682,8 @@ void StructDeclaration::semantic(Scope *sc)
postblit = buildPostBlit(sc2);
cpctor = buildCpCtor(sc2);

hasIdentityAssign = (buildOpAssign(sc2) != NULL);
hasIdentityEquals = (buildOpEquals(sc2) != NULL);
buildOpAssign(sc2);
buildOpEquals(sc2);

xeq = buildXopEquals(sc2);
#endif
Expand Down

0 comments on commit 95cc8b1

Please sign in to comment.