Skip to content

Commit

Permalink
[Refactoring] TypeFunction::purityLevel
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Jun 14, 2014
1 parent a30376f commit f4cb15c
Showing 1 changed file with 63 additions and 57 deletions.
120 changes: 63 additions & 57 deletions src/mtype.c
Expand Up @@ -5770,71 +5770,77 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
void TypeFunction::purityLevel()
{
TypeFunction *tf = this;
if (tf->purity == PUREfwdref)
{ /* Evaluate what kind of purity based on the modifiers for the parameters
if (tf->purity != PUREfwdref)
return;

/* Evaluate what kind of purity based on the modifiers for the parameters
*/
tf->purity = PUREstrong; // assume strong until something weakens it

size_t dim = Parameter::dim(tf->parameters);
if (!dim)
return;
for (size_t i = 0; i < dim; i++)
{
Parameter *fparam = Parameter::getNth(tf->parameters, i);
Type *t = fparam->type;
if (!t)
continue;

if (fparam->storageClass & (STClazy | STCout))
{
tf->purity = PUREweak;
break;
}
if (fparam->storageClass & STCref)
{
if (t->mod & MODimmutable)
continue;
if (t->mod & (MODconst | MODwild))
{
tf->purity = PUREconst;
continue;
}
tf->purity = PUREweak;
break;
}

t = t->toBasetype();
if (!t->hasPointers())
continue;
if (t->mod & MODimmutable)
continue;

/* The rest of this is too strict; fix later.
* For example, the only pointer members of a struct may be immutable,
* which would maintain strong purity.
*/
tf->purity = PUREstrong; // assume strong until something weakens it
if (tf->parameters)
if (t->mod & (MODconst | MODwild))
{
size_t dim = Parameter::dim(tf->parameters);
for (size_t i = 0; i < dim; i++)
{ Parameter *fparam = Parameter::getNth(tf->parameters, i);
if (fparam->storageClass & STClazy)
{
tf->purity = PUREweak;
break;
}
if (fparam->storageClass & STCout)
{
tf->purity = PUREweak;
break;
}
if (!fparam->type)
tf->purity = PUREconst;
continue;
}
if (Type *tn = t->nextOf())
{
tn = tn->toBasetype();
if (tn->ty == Tpointer || tn->ty == Tarray)
{
/* Accept immutable(T)* and immutable(T)[] as being strongly pure
*/
if (tn->mod & MODimmutable)
continue;
if (fparam->storageClass & STCref)
if (tn->mod & (MODconst | MODwild))
{
if (!(fparam->type->mod & (MODconst | MODimmutable | MODwild)))
{ tf->purity = PUREweak;
break;
}
if (fparam->type->mod & MODconst)
{ tf->purity = PUREconst;
continue;
}
}
Type *t = fparam->type->toBasetype();
if (!t->hasPointers())
continue;
if (t->mod & MODimmutable)
continue;
/* The rest of this is too strict; fix later.
* For example, the only pointer members of a struct may be immutable,
* which would maintain strong purity.
*/
if (t->mod & (MODconst | MODwild))
{ tf->purity = PUREconst;
tf->purity = PUREconst;
continue;
}
Type *tn = t->nextOf();
if (tn)
{ tn = tn->toBasetype();
if (tn->ty == Tpointer || tn->ty == Tarray)
{ /* Accept immutable(T)* and immutable(T)[] as being strongly pure
*/
if (tn->mod & MODimmutable)
continue;
if (tn->mod & (MODconst | MODwild))
{ tf->purity = PUREconst;
continue;
}
}
}
/* Should catch delegates and function pointers, and fold in their purity
*/
tf->purity = PUREweak; // err on the side of too strict
break;
}
}
/* Should catch delegates and function pointers, and fold in their purity
*/

tf->purity = PUREweak; // err on the side of too strict
break;
}
}

Expand Down

0 comments on commit f4cb15c

Please sign in to comment.