# HG changeset patch # User Leandro Lucarella # Date 1262801901 10800 # Node ID 6820110de31134375928f9b250cb3584006cba39 # Parent c94049033c204d19d128fbefb0020c5c9eff9828 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(-) diff -r c94049033c20 -r 6820110de311 dmd/declaration.h --- a/dmd/declaration.h Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/declaration.h Wed Jan 06 15:18:21 2010 -0300 @@ -763,6 +763,7 @@ 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); diff -r c94049033c20 -r 6820110de311 dmd/func.c --- a/dmd/func.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/func.c Wed Jan 06 15:18:21 2010 -0300 @@ -850,6 +850,7 @@ } #endif +#if 0 // Propagate storage class from tuple parameters to their element-parameters. if (f->parameters) { @@ -867,6 +868,7 @@ } } } +#endif /* Declare all the function parameters as variables * and install them in parameters[] @@ -2491,6 +2493,34 @@ } #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. diff -r c94049033c20 -r 6820110de311 dmd/mtype.c --- a/dmd/mtype.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/mtype.c Wed Jan 06 15:18:21 2010 -0300 @@ -2965,7 +2965,12 @@ 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 @@ 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 @@ 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(); - - if (arg->storageClass & (STCout | STCref | STClazy)) + Type *t = fparam->type->toBasetype(); + + 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 (arg->defaultArg) + if (!(fparam->storageClass & STClazy) && t->ty == Tvoid) + error(loc, "cannot have parameter of type %s", fparam->type->toChars()); + + 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();