Merge DMD r301: a little refactor and harmonize

---
 dmd/declaration.h |    1 +
 dmd/func.c        |   30 ++++++++++++++++++++++++++++++
 dmd/mtype.c       |   51 +++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 68 insertions(+), 14 deletions(-)
This commit is contained in:
Leandro Lucarella
2010-01-06 15:18:21 -03:00
parent 2cdf1f6679
commit 072ac6c4e3
3 changed files with 68 additions and 14 deletions

View File

@@ -763,6 +763,7 @@ struct FuncDeclaration : Declaration
int needsClosure();
Statement *mergeFrequire(Statement *);
Statement *mergeFensure(Statement *);
Parameters *getParameters(int *pvarargs);
// LDC: give argument types to runtime functions
static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name);

View File

@@ -850,6 +850,7 @@ void FuncDeclaration::semantic3(Scope *sc)
}
#endif
#if 0
// Propagate storage class from tuple parameters to their element-parameters.
if (f->parameters)
{
@@ -867,6 +868,7 @@ void FuncDeclaration::semantic3(Scope *sc)
}
}
}
#endif
/* Declare all the function parameters as variables
* and install them in parameters[]
@@ -2491,6 +2493,34 @@ Lyes:
}
#endif
/*********************************************
* Return the function's parameter list, and whether
* it is variadic or not.
*/
Parameters *FuncDeclaration::getParameters(int *pvarargs)
{ Parameters *fparameters;
int fvarargs;
if (type)
{
assert(type->ty == Tfunction);
TypeFunction *fdtype = (TypeFunction *)type;
fparameters = fdtype->parameters;
fvarargs = fdtype->varargs;
}
else // Constructors don't have type's
{ CtorDeclaration *fctor = isCtorDeclaration();
assert(fctor);
fparameters = fctor->arguments;
fvarargs = fctor->varargs;
}
if (pvarargs)
*pvarargs = fvarargs;
return fparameters;
}
/****************************** FuncAliasDeclaration ************************/
// Used as a way to import a set of functions from another scope into this one.

View File

@@ -2965,7 +2965,12 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
return this;
}
//printf("TypeFunction::semantic() this = %p\n", this);
//printf("TypeFunction::semantic() %s, sc->stc = %x\n", toChars(), sc->stc);
/* Copy in order to not mess up original.
* This can produce redundant copies if inferring return type,
* as semantic() will get called again on this.
*/
TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
memcpy(tf, this, sizeof(TypeFunction));
if (parameters)
@@ -2982,10 +2987,12 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
if (tf->next)
{
tf->next = tf->next->semantic(loc,sc);
#if !SARRAYVALUE
if (tf->next->toBasetype()->ty == Tsarray)
{ error(loc, "functions cannot return static array %s", tf->next->toChars());
tf->next = Type::terror;
}
#endif
if (tf->next->toBasetype()->ty == Tfunction)
{ error(loc, "functions cannot return a function");
tf->next = Type::terror;
@@ -3008,44 +3015,60 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
size_t dim = Parameter::dim(tf->parameters);
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = Parameter::getNth(tf->parameters, i);
{ Parameter *fparam = Parameter::getNth(tf->parameters, i);
tf->inuse++;
arg->type = arg->type->semantic(loc, argsc);
fparam->type = fparam->type->semantic(loc, argsc);
if (tf->inuse == 1) tf->inuse--;
// each function needs its own copy of a tuple arg, since
// they mustn't share arg flags like inreg, ...
if (arg->type->ty == Ttuple) {
arg->type = arg->type->syntaxCopy();
if (fparam->type->ty == Ttuple) {
fparam->type = fparam->type->syntaxCopy();
tf->inuse++;
arg->type = arg->type->semantic(loc,sc);
fparam->type = fparam->type->semantic(loc,sc);
if (tf->inuse == 1) tf->inuse--;
}
Type *t = arg->type->toBasetype();
Type *t = fparam->type->toBasetype();
if (arg->storageClass & (STCout | STCref | STClazy))
if (fparam->storageClass & (STCout | STCref | STClazy))
{
if (t->ty == Tsarray)
error(loc, "cannot have out or ref parameter of type %s", t->toChars());
}
if (!(arg->storageClass & STClazy) && t->ty == Tvoid)
error(loc, "cannot have parameter of type %s", arg->type->toChars());
if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
error(loc, "cannot have parameter of type %s", fparam->type->toChars());
if (arg->defaultArg)
if (fparam->defaultArg)
{
arg->defaultArg = arg->defaultArg->semantic(argsc);
arg->defaultArg = resolveProperties(argsc, arg->defaultArg);
arg->defaultArg = arg->defaultArg->implicitCastTo(argsc, arg->type);
fparam->defaultArg = fparam->defaultArg->semantic(argsc);
fparam->defaultArg = resolveProperties(argsc, fparam->defaultArg);
fparam->defaultArg = fparam->defaultArg->implicitCastTo(argsc, fparam->type);
}
/* If arg turns out to be a tuple, the number of parameters may
* change.
*/
if (t->ty == Ttuple)
{ dim = Parameter::dim(tf->parameters);
{
// Propagate storage class from tuple parameters to their element-parameters.
TypeTuple *tt = (TypeTuple *)t;
if (tt->arguments)
{
size_t tdim = tt->arguments->dim;
for (size_t j = 0; j < tdim; j++)
{ Parameter *narg = (Parameter *)tt->arguments->data[j];
narg->storageClass = fparam->storageClass;
}
}
/* Reset number of parameters, and back up one to do this arg again,
* now that it is the first element of a tuple
*/
dim = Parameter::dim(tf->parameters);
i--;
continue;
}
}
argsc->pop();