if (dtype)
{
tree parms = TYPE_ARG_TYPES (type);
- int varargs_p = 1;
+ VarArg varargs_p = VARARGvariadic;
Parameters *args = new Parameters;
args->reserve (list_length (parms));
tree argtype = TREE_VALUE (parm);
if (argtype == void_type_node)
{
- varargs_p = 0;
+ varargs_p = VARARGnone;
break;
}
/* GCC generic and placeholder built-ins are marked as variadic, yet
have no named parameters, and so can't be represented in D. */
- if (args->length != 0 || !varargs_p)
+ if (args->length != 0 || varargs_p == VARARGnone)
{
dtype = TypeFunction::create (args, dtype, varargs_p, LINKc);
return dtype->addMod (mod);
/* Lazy declarations are converted to delegates. */
if (decl->storage_class & STClazy)
{
- TypeFunction *tf = TypeFunction::create (NULL, decl->type, false, LINKd);
+ TypeFunction *tf = TypeFunction::create (NULL, decl->type,
+ VARARGnone, LINKd);
TypeDelegate *t = TypeDelegate::create (tf);
return build_ctype (t->merge2 ());
}
/* Lazy parameters are converted to delegates. */
if (arg->storageClass & STClazy)
{
- TypeFunction *tf = TypeFunction::create (NULL, arg->type, false, LINKd);
+ TypeFunction *tf = TypeFunction::create (NULL, arg->type,
+ VARARGnone, LINKd);
TypeDelegate *t = TypeDelegate::create (tf);
return build_ctype (t->merge2 ());
}
}
}
- size_t nparams = Parameter::dim (tf->parameters);
+ size_t nparams = tf->parameterList.length ();
/* if _arguments[] is the first argument. */
- size_t varargs = (tf->linkage == LINKd && tf->varargs == 1);
+ size_t varargs = tf->isDstyleVariadic ();
/* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
for (size_t i = 0; i < arguments->length; ++i)
if (i - varargs < nparams && i >= varargs)
{
/* Actual arguments for declared formal arguments. */
- Parameter *parg = Parameter::getNth (tf->parameters, i - varargs);
+ Parameter *parg = tf->parameterList[i - varargs];
targ = convert_for_argument (targ, parg);
}
else if (arg->storageClass & STClazy)
{
/* Mangle as delegate. */
- Type *td = TypeFunction::create (NULL, t, 0, LINKd);
+ Type *td = TypeFunction::create (NULL, t, VARARGnone, LINKd);
td = TypeDelegate::create (td);
t = t->merge2 ();
}
-1831b24fffe35fd0e332c194fdf8723ba3c930a5
+b0df0e982cc44bd09a9061acfc8160f29767334a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
/* Construct the function
*/
- TypeFunction *ftype = new TypeFunction(fparams, exp->e1->type, 0, LINKc, stc);
+ TypeFunction *ftype = new TypeFunction(ParameterList(fparams), exp->e1->type, LINKc, stc);
//printf("fd: %s %s\n", ident->toChars(), ftype->toChars());
FuncDeclaration *fd = new FuncDeclaration(Loc(), Loc(), ident, STCundefined, ftype);
fd->fbody = fbody;
{
if (f->errors)
return NULL;
- int varargs;
- Parameters *fparams = f->getParameters(&varargs);
- if (fparams->length >= 1)
+ ParameterList fparams = f->getParameterList();
+ if (fparams.length())
{
- Parameter *fparam0 = Parameter::getNth(fparams, 0);
+ Parameter *fparam0 = fparams[0];
if (fparam0->type->toDsymbol(NULL) != ad)
f = NULL;
}
Parameters *fparams = new Parameters;
fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL));
- TypeFunction *tf = new TypeFunction(fparams, sd->handleType(), 0, LINKd, stc | STCref);
+ TypeFunction *tf = new TypeFunction(ParameterList(fparams), sd->handleType(), LINKd, stc | STCref);
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
fop->storage_class |= STCinference;
*/
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
- tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd);
+ tfeqptr = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);
tfeqptr->mod = MODconst;
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &scx);
}
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL));
- TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
+ TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);
Identifier *id = Id::xopEquals;
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
*/
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
- tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd);
+ tfcmpptr = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);
tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &scx);
}
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL));
- TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd);
+ TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);
Identifier *id = Id::xopCmp;
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
static TypeFunction *tftohash;
if (!tftohash)
{
- tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
+ tftohash = new TypeFunction(ParameterList(), Type::thash_t, LINKd);
tftohash->mod = MODconst;
tftohash = (TypeFunction *)tftohash->merge();
}
Parameters *parameters = new Parameters();
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
- TypeFunction *tf = new TypeFunction(parameters, Type::thash_t, 0, LINKd, STCnothrow | STCtrusted);
+ TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::thash_t,
+ LINKd, STCnothrow | STCtrusted);
Identifier *id = Id::xtoHash;
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
static Expression *wrapAndCall(Loc loc, Statement *s)
{
- TypeFunction *tf = new TypeFunction(new Parameters(), NULL, 0, LINKdefault, 0);
+ TypeFunction *tf = new TypeFunction(ParameterList(), NULL, LINKdefault, 0);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, loc, tf, TOKreserved, NULL);
fd->fbody = s;
FuncExp *fe = new FuncExp(loc, fd);
if (tf->linkage == LINKcpp) //Template args accept extern "C" symbols with special mangling
{
assert(tf->ty == Tfunction);
- mangleFunctionParameters(tf->parameters, tf->varargs);
+ mangleFunctionParameters(tf->parameterList.parameters,
+ tf->parameterList.varargs);
}
}
if (t->isref)
tn = tn->referenceTo();
tn->accept(this);
- mangleFunctionParameters(t->parameters, t->varargs);
+ mangleFunctionParameters(t->parameterList.parameters,
+ t->parameterList.varargs);
buf->writeByte('E');
append(t);
}
* and see if we can convert the function argument to the modded type
*/
- size_t nparams = Parameter::dim(tf->parameters);
- size_t j = (tf->linkage == LINKd && tf->varargs == 1); // if TypeInfoArray was prepended
+ size_t nparams = tf->parameterList.length();
+ size_t j = tf->isDstyleVariadic(); // if TypeInfoArray was prepended
if (e->e1->op == TOKdotvar)
{
/* Treat 'this' as just another function argument
Type *targ = earg->type->toBasetype();
if (i - j < nparams)
{
- Parameter *fparam = Parameter::getNth(tf->parameters, i - j);
+ Parameter *fparam = tf->parameterList[i - j];
if (fparam->storageClass & STClazy)
return; // not sure what to do with this
Type *tparam = fparam->type;
Expressions *args = (fd == e->allocator) ? e->newargs : e->arguments;
- size_t nparams = Parameter::dim(tf->parameters);
- size_t j = (tf->linkage == LINKd && tf->varargs == 1); // if TypeInfoArray was prepended
+ size_t nparams = tf->parameterList.length();
+ size_t j = tf->isDstyleVariadic(); // if TypeInfoArray was prepended
for (size_t i = j; i < e->arguments->length; ++i)
{
Expression *earg = (*args)[i];
Type *targ = earg->type->toBasetype();
if (i - j < nparams)
{
- Parameter *fparam = Parameter::getNth(tf->parameters, i - j);
+ Parameter *fparam = tf->parameterList[i - j];
if (fparam->storageClass & STClazy)
return; // not sure what to do with this
Type *tparam = fparam->type;
{
//printf("Creating default this(){} for class %s\n", toChars());
TypeFunction *btf = fd->type->toTypeFunction();
- TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class);
+ TypeFunction *tf = new TypeFunction(ParameterList(), NULL, LINKd, fd->storage_class);
tf->mod = btf->mod;
tf->purity = btf->purity;
tf->isnothrow = btf->isnothrow;
void buildResultVar(Scope *sc, Type *tret);
Statement *mergeFrequire(Statement *);
Statement *mergeFensure(Statement *, Identifier *oid);
- Parameters *getParameters(int *pvarargs);
+ ParameterList getParameterList();
static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
{
public:
Parameters *parameters;
- int varargs;
+ VarArg varargs;
- NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, int varargs);
+ NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, VarArg varargs);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
const char *kind() const;
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), e->toChars());
Loc loc = e->loc;
- TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
+ TypeFunction *tf = new TypeFunction(ParameterList(), t, LINKd);
if (t->hasWild())
tf->mod = MODwild;
FuncLiteralDeclaration *fld =
Type *tb = fd->type->toBasetype();
assert(tb->ty == Tfunction);
TypeFunction *tf = (TypeFunction *)tb;
- if (tf->varargs && arguments &&
+ if (tf->parameterList.varargs != VARARGnone && arguments &&
((fd->parameters && arguments->length != fd->parameters->length) || (!fd->parameters && arguments->length)))
{
fd->error("C-style variadic functions are not yet implemented in CTFE");
for (size_t i = 0; i < dim; i++)
{
Expression *earg = (*arguments)[i];
- Parameter *fparam = Parameter::getNth(tf->parameters, i);
+ Parameter *fparam = tf->parameterList[i];
if (fparam->storageClass & (STCout | STCref))
{
for (size_t i = 0; i < dim; i++)
{
Expression *earg = eargs[i];
- Parameter *fparam = Parameter::getNth(tf->parameters, i);
+ Parameter *fparam = tf->parameterList[i];
VarDeclaration *v = (*fd->parameters)[i];
ctfeStack.push(v);
size_t numParams = fd->parameters->length;
assert(numParams == 1 || numParams == 2);
- Parameter *fparam = Parameter::getNth(((TypeFunction *)fd->type)->parameters, numParams - 1);
+ Parameter *fparam = ((TypeFunction *)fd->type)->parameterList[numParams - 1];
bool wantRefValue = 0 != (fparam->storageClass & (STCout | STCref));
Expressions args;
}
// Write argument types
- paramsToDecoBuffer(t->parameters);
+ paramsToDecoBuffer(t->parameterList.parameters);
//if (buf->data[buf->offset - 1] == '@') halt();
- buf->writeByte('Z' - t->varargs); // mark end of arg list
+ buf->writeByte('Z' - t->parameterList.varargs); // mark end of arg list
if (tret != NULL)
visitWithMask(tret, 0);
for (size_t i = 0; i < a->length; i++)
{
TypeFunction *tf = isTypeFunction((*a)[i]);
- if (tf && tf->varargs == 1 && cmp("...", p, len) == 0)
+ if (tf && tf->parameterList.varargs == VARARGvariadic && cmp("...", p, len) == 0)
return true;
}
return false;
static Parameter *isFunctionParameter(Dsymbol *s, const utf8_t *p, size_t len)
{
TypeFunction *tf = isTypeFunction(s);
- if (tf && tf->parameters)
+ if (tf && tf->parameterList.parameters)
{
- for (size_t k = 0; k < tf->parameters->length; k++)
+ for (size_t k = 0; k < tf->parameterList.parameters->length; k++)
{
- Parameter *fparam = (*tf->parameters)[k];
+ Parameter *fparam = (*tf->parameterList.parameters)[k];
if (fparam->ident && cmp(fparam->ident->toChars(), p, len) == 0)
{
return fparam;
TypeFunction *tf = a->length == 1 ? isTypeFunction(s) : NULL;
if (tf)
{
- size_t pcount = (tf->parameters ? tf->parameters->length : 0) + (int)(tf->varargs == 1);
+ size_t pcount = (tf->parameterList.parameters ? tf->parameterList.parameters->length : 0) +
+ (int)(tf->parameterList.varargs == VARARGvariadic);
if (pcount != paramcount)
{
warning(s->loc, "Ddoc: parameter count mismatch");
static TypeFunction *tftostring;
if (!tftostring)
{
- tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
+ tftostring = new TypeFunction(ParameterList(), Type::tstring, LINKd);
tftostring = tftostring->merge()->toTypeFunction();
}
scx->parent = fd;
- Parameters *fparameters = tf->parameters;
- int fvarargs = tf->varargs;
+ Parameters *fparameters = tf->parameterList.parameters;
+ VarArg fvarargs = tf->parameterList.varargs;
size_t nfparams = Parameter::dim(fparameters);
for (size_t i = 0; i < nfparams; i++)
Parameter *fparam = Parameter::getNth(fparameters, i);
fparam->storageClass &= (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
fparam->storageClass |= STCparameter;
- if (fvarargs == 2 && i + 1 == nfparams)
+ if (fvarargs == VARARGtypesafe && i + 1 == nfparams)
fparam->storageClass |= STCvariadic;
}
for (size_t i = 0; i < fparameters->length; i++)
fd->inferRetType = true;
// Shouldn't run semantic on default arguments and return type.
- for (size_t i = 0; i < tf->parameters->length; i++)
- (*tf->parameters)[i]->defaultArg = NULL;
+ for (size_t i = 0; i < tf->parameterList.parameters->length; i++)
+ (*tf->parameterList.parameters)[i]->defaultArg = NULL;
tf->next = NULL;
// Resolve parameter types and 'auto ref's.
size_t fptupindex = IDX_NOTFOUND;
MATCH match = MATCHexact;
MATCH matchTiargs = MATCHexact;
- Parameters *fparameters; // function parameter list
- int fvarargs; // function varargs
+ ParameterList fparameters; // function parameter list
unsigned wildmatch = 0;
size_t inferStart = 0;
//printf("tiargs matchTiargs = %d\n", matchTiargs);
}
- fparameters = fd->getParameters(&fvarargs);
- nfparams = Parameter::dim(fparameters); // number of function parameters
- nfargs = fargs ? fargs->length : 0; // number of function arguments
+ fparameters = fd->getParameterList();
+ nfparams = fparameters.length(); // number of function parameters
+ nfargs = fargs ? fargs->length : 0; // number of function arguments
/* Check for match of function arguments with variadic template
* parameter, such as:
*/
for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
{
- Parameter *fparam = (*fparameters)[fptupindex];
+ Parameter *fparam = (*fparameters.parameters)[fptupindex];
if (fparam->type->ty != Tident)
continue;
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
if (!tp->ident->equals(tid->ident) || tid->idents.length)
continue;
- if (fvarargs) // variadic function doesn't
+ if (fparameters.varargs != VARARGnone) // variadic function doesn't
goto Lnomatch; // go with variadic template
goto L1;
size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs
for (size_t parami = 0; parami < nfparams; parami++)
{
- Parameter *fparam = Parameter::getNth(fparameters, parami);
+ Parameter *fparam = fparameters[parami];
// Apply function parameter storage classes to parameter types
Type *prmtype = fparam->type->addStorageClass(fparam->storageClass);
size_t rem = 0;
for (size_t j = parami + 1; j < nfparams; j++)
{
- Parameter *p = Parameter::getNth(fparameters, j);
+ Parameter *p = fparameters[j];
if (!reliesOnTident(p->type, parameters, inferStart))
{
Type *pt = p->type->syntaxCopy()->semantic(fd->loc, paramscope);
for (size_t j = 0; j < tt_dim; j++, ++argi)
{
Parameter *p = (*tt->arguments)[j];
- if (j == tt_dim - 1 && fvarargs == 2 && parami + 1 == nfparams && argi < nfargs)
+ if (j == tt_dim - 1 && fparameters.varargs == VARARGtypesafe &&
+ parami + 1 == nfparams && argi < nfargs)
{
prmtype = p->type;
goto Lvarargs;
}
}
- if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs)
+ if (fparameters.varargs == VARARGtypesafe && parami + 1 == nfparams && argi + 1 < nfargs)
goto Lvarargs;
unsigned wm = 0;
/* The following code for variadic arguments closely
* matches TypeFunction::callMatch()
*/
- if (!(fvarargs == 2 && parami + 1 == nfparams))
+ if (!(fparameters.varargs == VARARGtypesafe && parami + 1 == nfparams))
goto Lnomatch;
/* Check for match with function parameter T...
++argi;
}
//printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
- if (argi != nfargs2 && !fvarargs)
+ if (argi != nfargs2 && fparameters.varargs == VARARGnone)
goto Lnomatch;
}
Scope *scx = sc2->push();
// Shouldn't run semantic on default arguments and return type.
- for (size_t i = 0; i < tf->parameters->length; i++)
- (*tf->parameters)[i]->defaultArg = NULL;
+ for (size_t i = 0; i < tf->parameterList.parameters->length; i++)
+ (*tf->parameterList.parameters)[i]->defaultArg = NULL;
if (fd->isCtorDeclaration())
{
// For constructors, emitting return type is necessary for
if (fd && fd->type)
{
TypeFunction *tf = (TypeFunction *)fd->type;
- buf.writestring(parametersTypeToChars(tf->parameters, tf->varargs));
+ buf.writestring(parametersTypeToChars(tf->parameterList));
}
}
if (tparam && tparam->ty == Tfunction)
{
TypeFunction *tp = (TypeFunction *)tparam;
- if (t->varargs != tp->varargs ||
+ if (t->parameterList.varargs != tp->parameterList.varargs ||
t->linkage != tp->linkage)
{
result = MATCHnomatch;
return;
}
- size_t nfargs = Parameter::dim(t->parameters);
- size_t nfparams = Parameter::dim(tp->parameters);
+ size_t nfargs = t->parameterList.length();
+ size_t nfparams = tp->parameterList.length();
// bug 2579 fix: Apply function parameter storage classes to parameter types
for (size_t i = 0; i < nfparams; i++)
{
- Parameter *fparam = Parameter::getNth(tp->parameters, i);
+ Parameter *fparam = tp->parameterList[i];
fparam->type = fparam->type->addStorageClass(fparam->storageClass);
fparam->storageClass &= ~(STC_TYPECTOR | STCin);
}
/* See if 'A' of the template parameter matches 'A'
* of the type of the last function parameter.
*/
- Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1);
+ Parameter *fparam = tp->parameterList[nfparams - 1];
assert(fparam);
assert(fparam->type);
if (fparam->type->ty != Tident)
}
for (size_t i = 0; i < tuple_dim; i++)
{
- Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i);
+ Parameter *arg = t->parameterList[nfparams - 1 + i];
if (!arg->type->equals(tup->objects[i]))
{
result = MATCHnomatch;
tup->objects.setDim(tuple_dim);
for (size_t i = 0; i < tuple_dim; i++)
{
- Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i);
+ Parameter *arg = t->parameterList[nfparams - 1 + i];
tup->objects[i] = arg->type;
}
(*dedtypes)[tupi] = tup;
L2:
for (size_t i = 0; i < nfparams; i++)
{
- Parameter *a = Parameter::getNth(t->parameters, i);
- Parameter *ap = Parameter::getNth(tp->parameters, i);
+ Parameter *a = t->parameterList[i];
+ Parameter *ap = tp->parameterList[i];
if (!a->isCovariant(t->isref, ap) ||
!deduceType(a->type, sc, ap->type, parameters, dedtypes))
TypeFunction *tf = (TypeFunction *)e->fd->type;
//printf("\ttof = %s\n", tof->toChars());
//printf("\ttf = %s\n", tf->toChars());
- size_t dim = Parameter::dim(tf->parameters);
+ size_t dim = tf->parameterList.length();
- if (Parameter::dim(tof->parameters) != dim ||
- tof->varargs != tf->varargs)
+ if (tof->parameterList.length() != dim ||
+ tof->parameterList.varargs != tf->parameterList.varargs)
return;
Objects *tiargs = new Objects();
size_t u = 0;
for (; u < dim; u++)
{
- Parameter *p = Parameter::getNth(tf->parameters, u);
+ Parameter *p = tf->parameterList[u];
if (p->type->ty == Tident &&
((TypeIdentifier *)p->type)->ident == tp->ident)
{
}
}
assert(u < dim);
- Parameter *pto = Parameter::getNth(tof->parameters, u);
+ Parameter *pto = tof->parameterList[u];
if (!pto)
break;
Type *t = pto->type->syntaxCopy(); // Bugzilla 11774
void visit(TypeFunction *t)
{
- size_t dim = Parameter::dim(t->parameters);
+ size_t dim = t->parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(t->parameters, i);
+ Parameter *fparam = t->parameterList[i];
fparam->type->accept(this);
if (result)
return;
*/
//printf("tp = %p, td->parameters->length = %d, tiargs->length = %d\n", tp, td->parameters->length, ti->tiargs->length);
TypeFunction *tf = (TypeFunction *)fd->type;
- if (size_t dim = Parameter::dim(tf->parameters))
+ if (size_t dim = tf->parameterList.length())
{
TemplateParameter *tp = td->isVariadic();
if (tp && td->parameters->length > 1)
for (size_t i = 0; i < dim; i++)
{
// 'auto ref' needs inference.
- if (Parameter::getNth(tf->parameters, i)->storageClass & STCauto)
+ if (tf->parameterList[i]->storageClass & STCauto)
return 1;
}
}
{
if (!fd->errors)
{
- Parameters *fparameters = fd->getParameters(NULL);
- size_t nfparams = Parameter::dim(fparameters); // Num function parameters
+ ParameterList fparameters = fd->getParameterList();
+ size_t nfparams = fparameters.length(); // Num function parameters
for (size_t j = 0; j < nfparams; j++)
{
- Parameter *fparam = Parameter::getNth(fparameters, j);
+ Parameter *fparam = fparameters[j];
if (fparam->storageClass & STCautoref) // if "auto ref"
{
if (!fargs)
else
{
// Perform 'return' inference on parameter
- if (tf->ty == Tfunction && tf->parameters)
+ if (tf->ty == Tfunction)
{
- const size_t dim = Parameter::dim(tf->parameters);
+ const size_t dim = tf->parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *p = Parameter::getNth(tf->parameters, i);
+ Parameter *p = tf->parameterList[i];
if (p->ident == v->ident)
{
p->storageClass |= STCreturn;
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
- size_t j = (tf->linkage == LINKd && tf->varargs == 1);
+ size_t j = tf->isDstyleVariadic();
for (size_t i = j; i < e->arguments->length; ++i)
{
Expression *arg = (*e->arguments)[i];
- size_t nparams = Parameter::dim(tf->parameters);
+ size_t nparams = tf->parameterList.length();
if (i - j < nparams && i >= j)
{
- Parameter *p = Parameter::getNth(tf->parameters, i - j);
+ Parameter *p = tf->parameterList[i - j];
const StorageClass stc = tf->parameterStorageClass(p);
if ((stc & (STCscope)) && (stc & STCreturn))
arg->accept(this);
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
- size_t j = (tf->linkage == LINKd && tf->varargs == 1);
+ size_t j = tf->isDstyleVariadic();
for (size_t i = j; i < e->arguments->length; ++i)
{
Expression *arg = (*e->arguments)[i];
- size_t nparams = Parameter::dim(tf->parameters);
+ size_t nparams = tf->parameterList.length();
if (i - j < nparams && i >= j)
{
- Parameter *p = Parameter::getNth(tf->parameters, i - j);
+ Parameter *p = tf->parameterList[i - j];
const StorageClass stc = tf->parameterStorageClass(p);
if ((stc & (STCout | STCref)) && (stc & STCreturn))
arg->accept(this);
assert(arguments);
assert(fd || tf->next);
size_t nargs = arguments ? arguments->length : 0;
- size_t nparams = Parameter::dim(tf->parameters);
+ size_t nparams = tf->parameterList.length();
unsigned olderrors = global.errors;
bool err = false;
*prettype = Type::terror;
Expression *eprefix = NULL;
*peprefix = NULL;
- if (nargs > nparams && tf->varargs == 0)
+ if (nargs > nparams && tf->parameterList.varargs == VARARGnone)
{
error(loc, "expected %llu arguments, not %llu for non-variadic function type %s", (ulonglong)nparams, (ulonglong)nargs, tf->toChars());
return true;
if (i < nparams)
{
- Parameter *p = Parameter::getNth(tf->parameters, i);
+ Parameter *p = tf->parameterList[i];
if (!arg)
{
if (!p->defaultArg)
{
- if (tf->varargs == 2 && i + 1 == nparams)
+ if (tf->parameterList.varargs == VARARGtypesafe && i + 1 == nparams)
goto L2;
error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
return true;
nargs++;
}
- if (tf->varargs == 2 && i + 1 == nparams)
+ if (tf->parameterList.varargs == VARARGtypesafe && i + 1 == nparams)
{
//printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
{
assert(arg);
if (i < nparams)
{
- Parameter *p = Parameter::getNth(tf->parameters, i);
+ Parameter *p = tf->parameterList[i];
if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
{
break;
}
- if (tf->varargs == 1)
+ if (tf->parameterList.varargs == VARARGvariadic)
{
const char *p = tf->linkage == LINKc ? "extern(C)" : "extern(C++)";
if (arg->type->ty == Tarray)
lastthrow = i;
if (firstdtor == -1 && arg->type->needsDestruction())
{
- Parameter *p = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
+ Parameter *p = (i >= (ptrdiff_t)nparams ? NULL : tf->parameterList[i]);
if (!(p && (p->storageClass & (STClazy | STCref | STCout))))
firstdtor = i;
}
{
Expression *arg = (*arguments)[i];
- Parameter *parameter = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
+ Parameter *parameter = (i >= (ptrdiff_t)nparams ? NULL : tf->parameterList[i]);
const bool isRef = (parameter && (parameter->storageClass & (STCref | STCout)));
const bool isLazy = (parameter && (parameter->storageClass & STClazy));
//if (eprefix) printf("eprefix: %s\n", eprefix->toChars());
// If D linkage and variadic, add _arguments[] as first argument
- if (tf->linkage == LINKd && tf->varargs == 1)
+ if (tf->isDstyleVariadic())
{
assert(arguments->length >= nparams);
TypeFunction *tf = (TypeFunction *)fd->type;
//printf("\ttof = %s\n", tof->toChars());
//printf("\ttf = %s\n", tf->toChars());
- size_t dim = Parameter::dim(tf->parameters);
+ size_t dim = tf->parameterList.length();
- if (Parameter::dim(tof->parameters) != dim ||
- tof->varargs != tf->varargs)
+ if (tof->parameterList.length() != dim ||
+ tof->parameterList.varargs != tf->parameterList.varargs)
goto L1;
Objects *tiargs = new Objects();
size_t u = 0;
for (; u < dim; u++)
{
- Parameter *p = Parameter::getNth(tf->parameters, u);
+ Parameter *p = tf->parameterList[u];
if (p->type->ty == Tident &&
((TypeIdentifier *)p->type)->ident == tp->ident)
{
}
}
assert(u < dim);
- Parameter *pto = Parameter::getNth(tof->parameters, u);
+ Parameter *pto = tof->parameterList[u];
Type *t = pto->type;
if (t->ty == Terror)
goto L1;
*/
convertMatch = true;
- TypeFunction *tfy = new TypeFunction(tfx->parameters, tof->next, tfx->varargs, tfx->linkage, STCundefined);
+ TypeFunction *tfy = new TypeFunction(tfx->parameterList, tof->next, tfx->linkage, STCundefined);
tfy->mod = tfx->mod;
tfy->isnothrow = tfx->isnothrow;
tfy->isnogc = tfx->isnogc;
exp->td->semantic(sc);
TypeFunction *tfl = (TypeFunction *)exp->fd->type;
- size_t dim = Parameter::dim(tfl->parameters);
+ size_t dim = tfl->parameterList.length();
if (arguments->length < dim)
{ // Default arguments are always typed, so they don't need inference.
- Parameter *p = Parameter::getNth(tfl->parameters, arguments->length);
+ Parameter *p = tfl->parameterList[arguments->length];
if (p->defaultArg)
dim = arguments->length;
}
- if ((!tfl->varargs && arguments->length == dim) ||
- ( tfl->varargs && arguments->length >= dim))
+ if ((tfl->parameterList.varargs == VARARGnone && arguments->length == dim) ||
+ (tfl->parameterList.varargs != VARARGnone && arguments->length >= dim))
{
Objects *tiargs = new Objects();
tiargs->reserve(exp->td->parameters->length);
{
TemplateParameter *tp = (*exp->td->parameters)[i];
for (size_t u = 0; u < dim; u++)
- { Parameter *p = Parameter::getNth(tfl->parameters, u);
+ { Parameter *p = tfl->parameterList[u];
if (p->type->ty == Tident &&
((TypeIdentifier *)p->type)->ident == tp->ident)
{ Expression *e = (*arguments)[u];
/* Generate tuple from function parameter types.
*/
assert(tded->ty == Tfunction);
- Parameters *params = ((TypeFunction *)tded)->parameters;
- size_t dim = Parameter::dim(params);
+ TypeFunction *tdedf = (TypeFunction *)tded;
+ size_t dim = tdedf->parameterList.length();
Parameters *args = new Parameters;
args->reserve(dim);
for (size_t i = 0; i < dim; i++)
{
- Parameter *arg = Parameter::getNth(params, i);
+ Parameter *arg = tdedf->parameterList[i];
assert(arg && arg->type);
/* If one of the default arguments was an error,
don't return an invalid tuple
// lazy paramaters can be called without violating purity and safety
Type *tw = ve->var->type;
Type *tc = ve->var->type->substWildTo(MODconst);
- TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd, STCsafe | STCpure);
+ TypeFunction *tf = new TypeFunction(ParameterList(), tc, LINKd, STCsafe | STCpure);
(tf = (TypeFunction *)tf->semantic(exp->loc, sc))->next = tw; // hack for bug7757
TypeDelegate *t = new TypeDelegate(tf);
ve->type = t->semantic(exp->loc, sc);
//printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
::error(exp->loc, "%s %s %s is not callable using argument types %s",
- p, exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs),
+ p, exp->e1->toChars(), parametersTypeToChars(tf->parameterList),
buf.peekString());
return setError();
//printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
::error(exp->loc, "%s %s is not callable using argument types %s",
- exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs),
+ exp->e1->toChars(), parametersTypeToChars(tf->parameterList),
buf.peekString());
exp->f = NULL;
* __require();
*/
Loc loc = fdx->frequire->loc;
- TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd);
+ TypeFunction *tf = new TypeFunction(ParameterList(), Type::tvoid, LINKd);
tf->isnothrow = f->isnothrow;
tf->isnogc = f->isnogc;
tf->purity = f->purity;
p = new Parameter(STCref | STCconst, f->nextOf(), fdx->outId, NULL);
fparams->push(p);
}
- TypeFunction *tf = new TypeFunction(fparams, Type::tvoid, 0, LINKd);
+ TypeFunction *tf = new TypeFunction(ParameterList(fparams), Type::tvoid, LINKd);
tf->isnothrow = f->isnothrow;
tf->isnogc = f->isnogc;
tf->purity = f->purity;
//if (vthis) printf("\tvthis->type = %s\n", vthis->type->toChars());
// Declare hidden variable _arguments[] and _argptr
- if (f->varargs == 1)
+ if (f->parameterList.varargs == VARARGvariadic)
{
if (f->linkage == LINKd)
{
sc2->insert(_arguments);
_arguments->parent = this;
}
- if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
+ if (f->linkage == LINKd || f->parameterList.length())
{
// Declare _argptr
Type *t = target.va_listType(loc, sc);
/* Declare all the function parameters as variables
* and install them in parameters[]
*/
- size_t nparams = Parameter::dim(f->parameters);
+ size_t nparams = f->parameterList.length();
if (nparams)
{
/* parameters[] has all the tuples removed, as the back end
parameters->reserve(nparams);
for (size_t i = 0; i < nparams; i++)
{
- Parameter *fparam = Parameter::getNth(f->parameters, i);
+ Parameter *fparam = f->parameterList[i];
Identifier *id = fparam->ident;
StorageClass stc = 0;
if (!id)
VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
//printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
stc |= STCparameter;
- if (f->varargs == 2 && i + 1 == nparams)
+ if (f->parameterList.varargs == VARARGtypesafe && i + 1 == nparams)
stc |= STCvariadic;
if (flags & FUNCFLAGinferScope && !(fparam->storageClass & STCscope))
stc |= STCmaybescope;
// Declare the tuple symbols and put them in the symbol table,
// but not in parameters[].
- if (f->parameters)
+ if (f->parameterList.parameters)
{
- for (size_t i = 0; i < f->parameters->length; i++)
+ for (size_t i = 0; i < f->parameterList.parameters->length; i++)
{
- Parameter *fparam = (*f->parameters)[i];
+ Parameter *fparam = (*f->parameterList.parameters)[i];
if (!fparam->ident)
continue; // never used, so ignore
// Infer STCscope
if (parameters)
{
- size_t nfparams = Parameter::dim(f->parameters);
+ size_t nfparams = f->parameterList.length();
assert(nfparams == parameters->length);
for (size_t u = 0; u < parameters->length; u++)
{
if (v->storage_class & STCmaybescope)
{
//printf("Inferring scope for %s\n", v->toChars());
- Parameter *p = Parameter::getNth(f->parameters, u);
+ Parameter *p = f->parameterList[u];
v->storage_class &= ~STCmaybescope;
v->storage_class |= STCscope | STCscopeinferred;
p->storageClass |= STCscope | STCscopeinferred;
TypeFunction *tf = type->toTypeFunction();
TypeFunction *tg = g->type->toTypeFunction();
- size_t nfparams = Parameter::dim(tf->parameters);
+ size_t nfparams = tf->parameterList.length();
/* If both functions have a 'this' pointer, and the mods are not
* the same and g's is not const, then this is less specialized.
args.setDim(nfparams);
for (size_t u = 0; u < nfparams; u++)
{
- Parameter *p = Parameter::getNth(tf->parameters, u);
+ Parameter *p = tf->parameterList[u];
Expression *e;
if (p->storageClass & (STCref | STCout))
{
/* A variadic parameter list is less specialized than a
* non-variadic one.
*/
- if (tf->varargs && !tg->varargs)
+ if (tf->parameterList.varargs && !tg->parameterList.varargs)
goto L1; // less specialized
return m;
TypeFunction *tf = (TypeFunction *)fd->type;
::errorSupplemental(fd->loc, "%s%s", fd->toPrettyChars(),
- parametersTypeToChars(tf->parameters, tf->varargs));
+ parametersTypeToChars(tf->parameterList));
}
else
{
fd->ident->toChars(), fargsBuf.peekString());
else
fd->error(loc, "%s%s is not callable using argument types %s",
- parametersTypeToChars(tf->parameters, tf->varargs),
+ parametersTypeToChars(tf->parameterList),
tf->modToChars(),
fargsBuf.peekString());
}
{
TypeFunction *tf1 = m.lastf->type->toTypeFunction();
TypeFunction *tf2 = m.nextf->type->toTypeFunction();
- const char *lastprms = parametersTypeToChars(tf1->parameters, tf1->varargs);
- const char *nextprms = parametersTypeToChars(tf2->parameters, tf2->varargs);
+ const char *lastprms = parametersTypeToChars(tf1->parameterList);
+ const char *nextprms = parametersTypeToChars(tf2->parameterList);
::error(loc, "%s.%s called with argument types %s matches both:\n"
"%s: %s%s\nand:\n%s: %s%s",
s->parent->toPrettyChars(), s->ident->toChars(),
//printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars());
- size_t dim = Parameter::dim(tf->parameters);
+ size_t dim = tf->parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(tf->parameters, i);
+ Parameter *fparam = tf->parameterList[i];
if (!fparam->type)
continue;
Type *tprmi = (fparam->storageClass & (STClazy | STCout | STCref))
}
else
{
- tf = new TypeFunction(fparams, treturn, 0, LINKc, stc);
+ tf = new TypeFunction(ParameterList(fparams), treturn, LINKc, stc);
fd = new FuncDeclaration(Loc(), Loc(), id, STCstatic, tf);
fd->protection = Prot(PROTpublic);
fd->linkage = LINKc;
void FuncDeclaration::checkDmain()
{
TypeFunction *tf = type->toTypeFunction();
- const size_t nparams = Parameter::dim(tf->parameters);
+ const size_t nparams = tf->parameterList.length();
bool argerr = false;
if (nparams == 1)
{
- Parameter *fparam0 = Parameter::getNth(tf->parameters, 0);
+ Parameter *fparam0 = tf->parameterList[0];
Type *t = fparam0->type->toBasetype();
if (t->ty != Tarray ||
t->nextOf()->ty != Tarray ||
error("must return int or void");
else if (tf->nextOf()->ty != Tint32 && tf->nextOf()->ty != Tvoid)
error("must return int or void, not %s", tf->nextOf()->toChars());
- else if (tf->varargs || nparams >= 2 || argerr)
+ else if (tf->parameterList.varargs || nparams >= 2 || argerr)
error("parameters must be main() or main(string[] args)");
}
* it is variadic or not.
*/
-Parameters *FuncDeclaration::getParameters(int *pvarargs)
+ParameterList FuncDeclaration::getParameterList()
{
- Parameters *fparameters = NULL;
- int fvarargs = 0;
-
if (type)
{
TypeFunction *fdtype = type->toTypeFunction();
- fparameters = fdtype->parameters;
- fvarargs = fdtype->varargs;
+ return fdtype->parameterList;
}
- if (pvarargs)
- *pvarargs = fvarargs;
- return fparameters;
+
+ return ParameterList();
}
*/
if (ad && (!parent->isTemplateInstance() || parent->isTemplateMixin()))
{
- const size_t dim = Parameter::dim(tf->parameters);
+ const size_t dim = tf->parameterList.length();
if (StructDeclaration *sd = ad->isStructDeclaration())
{
- if (dim == 0 && tf->varargs == 0) // empty default ctor w/o any varargs
+ if (dim == 0 && tf->parameterList.varargs == VARARGnone) // empty default ctor w/o any varargs
{
if (fbody || !(storage_class & STCdisable) || dim)
{
}
sd->noDefaultCtor = true;
}
- else if (dim == 0 && tf->varargs) // allow varargs only ctor
+ else if (dim == 0 && tf->parameterList.varargs) // allow varargs only ctor
{
}
- else if (dim && Parameter::getNth(tf->parameters, 0)->defaultArg)
+ else if (dim && tf->parameterList[0]->defaultArg)
{
// if the first parameter has a default argument, then the rest does as well
if (storage_class & STCdisable)
}
}
- else if (dim == 0 && tf->varargs == 0)
+ else if (dim == 0 && tf->parameterList.varargs == VARARGnone)
{
ad->defaultCtor = this;
}
if (ident == Id::postblit && semanticRun < PASSsemantic)
ad->postblits.push(this);
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
sc = sc->push();
sc->stc &= ~STCstatic; // not static
if (ident == Id::dtor && semanticRun < PASSsemantic)
ad->dtors.push(this);
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
sc = sc->push();
sc->stc &= ~STCstatic; // not a static destructor
return;
}
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
return;
}
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
)
ad->invs.push(this);
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
sc = sc->push();
sc->stc &= ~STCstatic; // not a static invariant
if (global.params.useUnitTests)
{
if (!type)
- type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(), Type::tvoid, LINKd, storage_class);
Scope *sc2 = sc->push();
sc2->linkage = LINKd;
FuncDeclaration::semantic(sc2);
/********************************* NewDeclaration ****************************/
-NewDeclaration::NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams, int varargs)
+NewDeclaration::NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams, VarArg varargs)
: FuncDeclaration(loc, endloc, Id::classNew, STCstatic | stc, NULL)
{
this->parameters = fparams;
}
Type *tret = Type::tvoid->pointerTo();
if (!type)
- type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(parameters, varargs), tret, LINKd, storage_class);
type = type->semantic(loc, sc);
// Check that there is at least one argument of type size_t
TypeFunction *tf = type->toTypeFunction();
- if (Parameter::dim(tf->parameters) < 1)
+ if (tf->parameterList.length() < 1)
{
error("at least one argument of type size_t expected");
}
else
{
- Parameter *fparam = Parameter::getNth(tf->parameters, 0);
+ Parameter *fparam = tf->parameterList[0];
if (!fparam->type->equals(Type::tsize_t))
error("first argument must be type size_t, not %s", fparam->type->toChars());
}
return;
}
if (!type)
- type = new TypeFunction(parameters, Type::tvoid, 0, LINKd, storage_class);
+ type = new TypeFunction(ParameterList(parameters), Type::tvoid, LINKd, storage_class);
type = type->semantic(loc, sc);
// Check that there is only one argument of type void*
TypeFunction *tf = type->toTypeFunction();
- if (Parameter::dim(tf->parameters) != 1)
+ if (tf->parameterList.length() != 1)
{
error("one argument of type void* expected");
}
else
{
- Parameter *fparam = Parameter::getNth(tf->parameters, 0);
+ Parameter *fparam = tf->parameterList[0];
if (!fparam->type->equals(Type::tvoid->pointerTo()))
error("one argument of type void* expected, not %s", fparam->type->toChars());
}
if (ident)
buf->writestring(ident);
- parametersToBuffer(t->parameters, t->varargs);
+ parametersToBuffer(t->parameterList.parameters, t->parameterList.varargs);
/* Use postfix style for attributes
*/
}
buf->writeByte(')');
}
- parametersToBuffer(t->parameters, t->varargs);
+ parametersToBuffer(t->parameterList.parameters, t->parameterList.varargs);
t->inuse--;
}
// Don't print tf->mod, tf->trust, and tf->linkage
if (!f->inferRetType && tf->next)
typeToBuffer(tf->next, NULL);
- parametersToBuffer(tf->parameters, tf->varargs);
+ parametersToBuffer(tf->parameterList.parameters, tf->parameterList.varargs);
CompoundStatement *cs = f->fbody->isCompoundStatement();
Statement *s1;
}
}
-const char *parametersTypeToChars(Parameters *parameters, int varargs)
+const char *parametersTypeToChars(ParameterList pl)
{
OutBuffer buf;
HdrGenState hgs;
PrettyPrintVisitor v(&buf, &hgs);
- v.parametersToBuffer(parameters, varargs);
+ v.parametersToBuffer(pl.parameters, pl.varargs);
return buf.extractString();
}
void moduleToBuffer(OutBuffer *buf, Module *m);
-const char *parametersTypeToChars(Parameters *parameters, int varargs);
+const char *parametersTypeToChars(ParameterList pl);
bool stcToBuffer(OutBuffer *buf, StorageClass stc);
const char *stcToChars(StorageClass& stc);
TOK tok = (t->ty == Tdelegate) ? TOKdelegate : TOKfunction;
/* Rewrite as empty delegate literal { }
*/
- Parameters *parameters = new Parameters;
- Type *tf = new TypeFunction(parameters, NULL, 0, LINKd);
+ Type *tf = new TypeFunction(ParameterList(), NULL, LINKd);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(i->loc, Loc(), tf, tok, NULL);
fd->fbody = new CompoundStatement(i->loc, new Statements());
fd->endloc = i->loc;
TypeFunction *tf = (TypeFunction *)d->type;
if (tf && tf->ty == Tfunction)
- property("parameters", tf->parameters);
+ property("parameters", tf->parameterList.parameters);
property("endline", "endchar", &d->endloc);
{
TypeFunction *tf = (TypeFunction *)t;
Type *tret = stripDefaultArgs(tf->next);
- Parameters *params = N::stripParams(tf->parameters);
- if (tret == tf->next && params == tf->parameters)
+ Parameters *params = N::stripParams(tf->parameterList.parameters);
+ if (tret == tf->next && params == tf->parameterList.parameters)
goto Lnot;
tf = (TypeFunction *)tf->copy();
- tf->parameters = params;
+ tf->parameterList.parameters = params;
tf->next = tret;
//printf("strip %s\n <- %s\n", tf->toChars(), t->toChars());
t = tf;
assert(next);
Type *tret = next->substWildTo(m);
- Parameters *params = parameters;
+ Parameters *params = parameterList.parameters;
if (mod & MODwild)
- params = parameters->copy();
+ params = parameterList.parameters->copy();
for (size_t i = 0; i < params->length; i++)
{
Parameter *p = (*params)[i];
Type *t = p->type->substWildTo(m);
if (t == p->type)
continue;
- if (params == parameters)
- params = parameters->copy();
+ if (params == parameterList.parameters)
+ params = parameterList.parameters->copy();
(*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
}
- if (next == tret && params == parameters)
+ if (next == tret && params == parameterList.parameters)
return this;
// Similar to TypeFunction::syntaxCopy;
- TypeFunction *t = new TypeFunction(params, tret, varargs, linkage);
+ TypeFunction *t = new TypeFunction(ParameterList(params, parameterList.varargs),
+ tret, linkage);
t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod);
t->isnothrow = isnothrow;
t->isnogc = isnogc;
/***************************** TypeFunction *****************************/
-TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
+TypeFunction::TypeFunction(const ParameterList &pl, Type *treturn, LINK linkage, StorageClass stc)
: TypeNext(Tfunction, treturn)
{
//if (!treturn) *(char*)0=0;
// assert(treturn);
- assert(0 <= varargs && varargs <= 2);
- this->parameters = parameters;
- this->varargs = varargs;
+ assert(VARARGnone <= pl.varargs && pl.varargs <= VARARGtypesafe);
+ this->parameterList = pl;
this->linkage = linkage;
this->inuse = 0;
this->isnothrow = false;
this->trust = TRUSTtrusted;
}
-TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
+TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc)
{
- return new TypeFunction(parameters, treturn, varargs, linkage, stc);
+ return new TypeFunction(ParameterList(parameters, varargs), treturn, linkage, stc);
}
const char *TypeFunction::kind()
Type *TypeFunction::syntaxCopy()
{
Type *treturn = next ? next->syntaxCopy() : NULL;
- Parameters *params = Parameter::arraySyntaxCopy(parameters);
- TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
+ Parameters *parameters = Parameter::arraySyntaxCopy(parameterList.parameters);
+ TypeFunction *t = new TypeFunction(ParameterList(parameters, parameterList.varargs),
+ treturn, linkage);
t->mod = mod;
t->isnothrow = isnothrow;
t->isnogc = isnogc;
t1 = (TypeFunction *)this;
t2 = (TypeFunction *)t;
- if (t1->varargs != t2->varargs)
+ if (t1->parameterList.varargs != t2->parameterList.varargs)
goto Ldistinct;
- if (t1->parameters && t2->parameters)
+ if (t1->parameterList.parameters && t2->parameterList.parameters)
{
- size_t dim = Parameter::dim(t1->parameters);
- if (dim != Parameter::dim(t2->parameters))
+ size_t dim = t1->parameterList.length();
+ if (dim != t2->parameterList.length())
goto Ldistinct;
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam1 = Parameter::getNth(t1->parameters, i);
- Parameter *fparam2 = Parameter::getNth(t2->parameters, i);
+ Parameter *fparam1 = t1->parameterList[i];
+ Parameter *fparam2 = t2->parameterList[i];
if (!fparam1->type->equals(fparam2->type))
{
notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
}
}
- else if (t1->parameters != t2->parameters)
+ else if (t1->parameterList.parameters != t2->parameterList.parameters)
{
- size_t dim1 = !t1->parameters ? 0 : t1->parameters->length;
- size_t dim2 = !t2->parameters ? 0 : t2->parameters->length;
+ size_t dim1 = t1->parameterList.length();
+ size_t dim2 = t2->parameterList.length();
if (dim1 || dim2)
goto Ldistinct;
}
* as semantic() will get called again on this.
*/
TypeFunction *tf = copy()->toTypeFunction();
- if (parameters)
+ if (parameterList.parameters)
{
- tf->parameters = parameters->copy();
- for (size_t i = 0; i < parameters->length; i++)
+ tf->parameterList.parameters = parameterList.parameters->copy();
+ for (size_t i = 0; i < parameterList.parameters->length; i++)
{
void *pp = mem.xmalloc(sizeof(Parameter));
- Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameters)[i], sizeof(Parameter));
- (*tf->parameters)[i] = p;
+ Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameterList.parameters)[i],
+ sizeof(Parameter));
+ (*tf->parameterList.parameters)[i] = p;
}
}
}
unsigned char wildparams = 0;
- if (tf->parameters)
+ if (tf->parameterList.parameters)
{
/* Create a scope for evaluating the default arguments for the parameters
*/
argsc->protection = Prot(PROTpublic);
argsc->func = NULL;
- size_t dim = Parameter::dim(tf->parameters);
+ size_t dim = tf->parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(tf->parameters, i);
+ Parameter *fparam = tf->parameterList[i];
inuse++;
fparam->type = fparam->type->semantic(loc, argsc);
inuse--;
/* Reset number of parameters, and back up one to do this fparam again,
* now that it is a tuple
*/
- dim = Parameter::dim(tf->parameters);
+ dim = tf->parameterList.length();
i--;
continue;
}
}
tf->iswild = wildparams;
- if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
+ if (tf->isproperty && (tf->parameterList.varargs != VARARGnone || tf->parameterList.length() > 2))
{
error(loc, "properties can only have zero, one, or two parameter");
errors = true;
}
- if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
+ if (tf->parameterList.varargs == VARARGvariadic && tf->linkage != LINKd && tf->parameterList.length() == 0)
{
error(loc, "variadic functions with non-D linkage must have at least one parameter");
errors = true;
/* Evaluate what kind of purity based on the modifiers for the parameters
*/
- const size_t dim = Parameter::dim(tf->parameters);
+ const size_t dim = tf->parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(tf->parameters, i);
+ Parameter *fparam = tf->parameterList[i];
Type *t = fparam->type;
if (!t)
continue;
}
}
- size_t nparams = Parameter::dim(parameters);
+ size_t nparams = parameterList.length();
size_t nargs = args ? args->length : 0;
if (nparams == nargs)
;
else if (nargs > nparams)
{
- if (varargs == 0)
+ if (parameterList.varargs == VARARGnone)
goto Nomatch; // too many args; no match
match = MATCHconvert; // match ... with a "conversion" match level
}
{
if (u >= nparams)
break;
- Parameter *p = Parameter::getNth(parameters, u);
+ Parameter *p = parameterList[u];
Expression *arg = (*args)[u];
assert(arg);
Type *tprm = p->type;
{
MATCH m;
- Parameter *p = Parameter::getNth(parameters, u);
+ Parameter *p = parameterList[u];
assert(p);
if (u >= nargs)
{
/* prefer matching the element type rather than the array
* type when more arguments are present with T[]...
*/
- if (varargs == 2 && u + 1 == nparams && nargs > nparams)
+ if (parameterList.varargs == VARARGtypesafe && u + 1 == nparams && nargs > nparams)
goto L1;
//printf("\tm = %d\n", m);
if (m == MATCHnomatch) // if no match
{
L1:
- if (varargs == 2 && u + 1 == nparams) // if last varargs param
+ if (parameterList.varargs == VARARGtypesafe && u + 1 == nparams) // if last varargs param
{
Type *tb = p->type->toBasetype();
TypeSArray *tsa;
*/
bool TypeFunction::hasLazyParameters()
{
- size_t dim = Parameter::dim(parameters);
+ size_t dim = parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(parameters, i);
+ Parameter *fparam = parameterList[i];
if (fparam->storageClass & STClazy)
return true;
}
return false;
}
+/*******************************
+ * Check for `extern (D) U func(T t, ...)` variadic function type,
+ * which has `_arguments[]` added as the first argument.
+ * Returns:
+ * true if D-style variadic
+ */
+bool TypeFunction::isDstyleVariadic() const
+{
+ return linkage == LINKd && parameterList.varargs == VARARGvariadic;
+}
+
/***************************
* Examine function signature for parameter p and see if
* the value of p can 'escape' the scope of the function.
// See if p can escape via any of the other parameters
if (purity == PUREweak)
{
- const size_t dim = Parameter::dim(parameters);
+ const size_t dim = parameterList.length();
for (size_t i = 0; i < dim; i++)
{
- Parameter *fparam = Parameter::getNth(parameters, i);
+ Parameter *fparam = parameterList[i];
Type *t = fparam->type;
if (!t)
continue;
(stc & STCsafe && t->trust < TRUSTtrusted))
{
// Klunky to change these
- TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
+ TypeFunction *tf = new TypeFunction(t->parameterList, t->next, t->linkage, 0);
tf->mod = t->mod;
tf->fargs = fargs;
tf->purity = t->purity;
return new NullExp(Loc(), Type::tnull);
}
+/***********************************************************
+ * Encapsulate Parameters* so .length and [i] can be used on it.
+ * https://dlang.org/spec/function.html#ParameterList
+ */
+
+ParameterList::ParameterList(Parameters *parameters, VarArg varargs)
+{
+ this->parameters = parameters;
+ this->varargs = varargs;
+}
+
+size_t ParameterList::length()
+{
+ return Parameter::dim(parameters);
+}
+
/***************************** Parameter *****************************/
Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
TypeDelegate *td = (TypeDelegate *)tel;
TypeFunction *tf = td->next->toTypeFunction();
- if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
+ if (!tf->parameterList.varargs == VARARGnone && tf->parameterList.length() == 0)
{
return tf->next; // return type of delegate
}
// If !=0, give warning on implicit conversion
extern unsigned char impcnvWarn[TMAX][TMAX];
+enum VarArg
+{
+ VARARGnone = 0, /// fixed number of arguments
+ VARARGvariadic = 1, /// T t, ...) can be C-style (core.stdc.stdarg) or D-style (core.vararg)
+ VARARGtypesafe = 2 /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
+ /// or https://dlang.org/spec/function.html#typesafe_variadic_functions
+};
+
class Type : public RootObject
{
public:
PUREstrong = 4 // parameters are values or immutable
};
+class Parameter : public RootObject
+{
+public:
+ StorageClass storageClass;
+ Type *type;
+ Identifier *ident;
+ Expression *defaultArg;
+
+ Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
+ static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
+ Parameter *syntaxCopy();
+ Type *isLazyArray();
+ // kludge for template.isType()
+ int dyncast() const { return DYNCAST_PARAMETER; }
+ virtual void accept(Visitor *v) { v->visit(this); }
+
+ static Parameters *arraySyntaxCopy(Parameters *parameters);
+ static size_t dim(Parameters *parameters);
+ static Parameter *getNth(Parameters *parameters, d_size_t nth, d_size_t *pn = NULL);
+ const char *toChars();
+ bool isCovariant(bool returnByRef, const Parameter *p) const;
+ static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to);
+};
+
+struct ParameterList
+{
+ Parameters *parameters;
+ VarArg varargs;
+
+ ParameterList(Parameters *parameters = NULL, VarArg varargs = VARARGnone);
+
+ size_t length();
+ Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
+};
+
class TypeFunction : public TypeNext
{
public:
// .next is the return type
- Parameters *parameters; // function parameters
- int varargs; // 1: T t, ...) style for variable number of arguments
- // 2: T t ...) style for variable number of arguments
+ ParameterList parameterList; // function parameters
+
bool isnothrow; // true: nothrow
bool isnogc; // true: is @nogc
bool isproperty; // can be called without parentheses
int inuse;
- TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc = 0);
- static TypeFunction *create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc = 0);
+ TypeFunction(const ParameterList &pl, Type *treturn, LINK linkage, StorageClass stc = 0);
+ static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0);
const char *kind();
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
void purityLevel();
bool hasLazyParameters();
+ bool isDstyleVariadic() const;
bool parameterEscapes(Parameter *p);
StorageClass parameterStorageClass(Parameter *p);
Type *addStorageClass(StorageClass stc);
/**************************************************************/
-//enum InOut { None, In, Out, InOut, Lazy };
-
-class Parameter : public RootObject
-{
-public:
- //enum InOut inout;
- StorageClass storageClass;
- Type *type;
- Identifier *ident;
- Expression *defaultArg;
-
- Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
- static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
- Parameter *syntaxCopy();
- Type *isLazyArray();
- // kludge for template.isType()
- int dyncast() const { return DYNCAST_PARAMETER; }
- virtual void accept(Visitor *v) { v->visit(this); }
-
- static Parameters *arraySyntaxCopy(Parameters *parameters);
- static size_t dim(Parameters *parameters);
- static Parameter *getNth(Parameters *parameters, d_size_t nth, d_size_t *pn = NULL);
- const char *toChars();
- bool isCovariant(bool returnByRef, const Parameter *p) const;
- static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to);
-};
-
bool arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);
{ size_t nparams;
Parameter *p;
- if (Parameter::dim(tf->parameters) != 1)
+ if (tf->parameterList.length() != 1)
goto Lnomatch;
- p = Parameter::getNth(tf->parameters, 0);
+ p = tf->parameterList[0];
if (p->type->ty != Tdelegate)
goto Lnomatch;
tf = (TypeFunction *)p->type->nextOf();
/* We now have tf, the type of the delegate. Match it against
* the parameters, filling in missing parameter types.
*/
- nparams = Parameter::dim(tf->parameters);
- if (nparams == 0 || tf->varargs)
+ nparams = tf->parameterList.length();
+ if (nparams == 0 || tf->parameterList.varargs != VARARGnone)
goto Lnomatch; // not enough parameters
if (parameters->length != nparams)
goto Lnomatch; // not enough parameters
for (size_t u = 0; u < nparams; u++)
{
p = (*parameters)[u];
- Parameter *param = Parameter::getNth(tf->parameters, u);
+ Parameter *param = tf->parameterList[u];
if (p->type)
{
if (!p->type->equals(param->type))
TypeFunction *tf = (TypeFunction *)t1;
for (size_t i = 0; i < e->arguments->length; i++)
{
- Parameter *p = Parameter::getNth(tf->parameters, i);
+ Parameter *p = tf->parameterList[i];
bool keep = p && (p->storageClass & (STCref | STCout)) != 0;
expOptimize((*e->arguments)[i], WANTvalue, keep);
}
/* Just a regular constructor
*/
- int varargs;
+ VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
stc = parsePostfix(stc, &udas);
- if (varargs != 0 || Parameter::dim(parameters) != 0)
+ if (varargs != VARARGnone || Parameter::dim(parameters) != 0)
{
if (stc & STCstatic)
error(loc, "constructor cannot be static");
Expression *constraint = tpl ? parseConstraint() : NULL;
- Type *tf = new TypeFunction(parameters, NULL, varargs, linkage, stc); // RetrunType -> auto
+ Type *tf = new TypeFunction(ParameterList(parameters, varargs),
+ NULL, linkage, stc); // ReturnType -> auto
tf = tf->addSTC(stc);
CtorDeclaration *f = new CtorDeclaration(loc, Loc(), stc, tf);
nextToken();
- int varargs;
+ VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
NewDeclaration *f = new NewDeclaration(loc, Loc(), stc, parameters, varargs);
if (pAttrs)
nextToken();
- int varargs;
+ VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
- if (varargs)
+ if (varargs != VARARGnone)
error("... not allowed in delete function parameter list");
DeleteDeclaration *f = new DeleteDeclaration(loc, Loc(), stc, parameters);
if (pAttrs)
* Parse parameter list.
*/
-Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
+Parameters *Parser::parseParameters(VarArg *pvarargs, TemplateParameters **tpl)
{
Parameters *parameters = new Parameters();
- int varargs = 0;
+ VarArg varargs = VARARGnone;
int hasdefault = 0;
check(TOKlparen);
break;
case TOKdotdotdot:
- varargs = 1;
+ varargs = VARARGvariadic;
nextToken();
break;
if (storageClass & (STCout | STCref))
error("variadic argument cannot be out or ref");
- varargs = 2;
+ varargs = VARARGtypesafe;
parameters->push(new Parameter(storageClass, at, ai, ae));
nextToken();
break;
TOK save = token.value;
nextToken();
- int varargs;
+ VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
StorageClass stc = parsePostfix(STCundefined, NULL);
- TypeFunction *tf = new TypeFunction(parameters, t, varargs, linkage, stc);
+ TypeFunction *tf = new TypeFunction(ParameterList(parameters, varargs),
+ t, linkage, stc);
if (stc & (STCconst | STCimmutable | STCshared | STCwild | STCreturn))
{
if (save == TOKfunction)
}
}
- int varargs;
+ VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
/* Parse const/immutable/shared/inout/nothrow/pure/return postfix
*/
StorageClass stc = parsePostfix(storageClass, pudas);
// merge prefix storage classes
- Type *tf = new TypeFunction(parameters, t, varargs, linkage, stc);
+ Type *tf = new TypeFunction(ParameterList(parameters, varargs),
+ t, linkage, stc);
tf = tf->addSTC(stc);
if (pdisable)
*pdisable = stc & STCdisable ? 1 : 0;
TemplateParameters *tpl = NULL;
Parameters *parameters = NULL;
- int varargs = 0;
+ VarArg varargs = VARARGnone;
Type *tret = NULL;
StorageClass stc = 0;
TOK save = TOKreserved;
if (!parameters)
parameters = new Parameters();
- TypeFunction *tf = new TypeFunction(parameters, tret, varargs, linkage, stc);
+ TypeFunction *tf = new TypeFunction(ParameterList(parameters, varargs),
+ tret, linkage, stc);
tf = (TypeFunction *)tf->addSTC(stc);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, Loc(), tf, save, NULL);
Dsymbol *parseUnitTest(PrefixAttributes *pAttrs);
Dsymbol *parseNew(PrefixAttributes *pAttrs);
Dsymbol *parseDelete(PrefixAttributes *pAttrs);
- Parameters *parseParameters(int *pvarargs, TemplateParameters **tpl = NULL);
+ Parameters *parseParameters(VarArg *pvarargs, TemplateParameters **tpl = NULL);
EnumDeclaration *parseEnum();
Dsymbol *parseAggregate();
BaseClasses *parseBaseClasses();
{
if (FuncDeclaration *fd = sapplyOld->isFuncDeclaration())
{
- int fvarargs; // ignored (opApply shouldn't take variadics)
- Parameters *fparameters = fd->getParameters(&fvarargs);
+ ParameterList fparameters = fd->getParameterList();
- if (Parameter::dim(fparameters) == 1)
+ if (fparameters.length() == 1)
{
// first param should be the callback function
- Parameter *fparam = Parameter::getNth(fparameters, 0);
+ Parameter *fparam = fparameters[0];
if ((fparam->type->ty == Tpointer || fparam->type->ty == Tdelegate) &&
fparam->type->nextOf()->ty == Tfunction)
{
TypeFunction *tf = (TypeFunction *)fparam->type->nextOf();
- foreachParamCount = Parameter::dim(tf->parameters);
+ foreachParamCount = tf->parameterList.length();
foundMismatch = true;
}
}
tfld = (TypeFunction *)tab->nextOf();
Lget:
//printf("tfld = %s\n", tfld->toChars());
- if (tfld->parameters->length == 1)
+ if (tfld->parameterList.parameters->length == 1)
{
- Parameter *p = Parameter::getNth(tfld->parameters, 0);
+ Parameter *p = tfld->parameterList[0];
if (p->type && p->type->ty == Tdelegate)
{
Type *t = p->type->semantic(loc, sc2);
p->type = p->type->addStorageClass(p->storageClass);
if (tfld)
{
- Parameter *prm = Parameter::getNth(tfld->parameters, i);
+ Parameter *prm = tfld->parameterList[i];
//printf("\tprm = %s%s\n", (prm->storageClass&STCref?"ref ":""), prm->ident->toChars());
stc = prm->storageClass & STCref;
id = p->ident; // argument copy is not need.
}
// Bugzilla 13840: Throwable nested function inside nothrow function is acceptable.
StorageClass stc = mergeFuncAttrs(STCsafe | STCpure | STCnogc, fs->func);
- tfld = new TypeFunction(params, Type::tint32, 0, LINKd, stc);
+ tfld = new TypeFunction(ParameterList(params), Type::tint32, LINKd, stc);
fs->cases = new Statements();
fs->gotos = new ScopeStatements();
FuncLiteralDeclaration *fld = new FuncLiteralDeclaration(loc, Loc(), tfld, TOKdelegate, fs);
dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
if (dim == 2)
dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
- fldeTy[i] = new TypeDelegate(new TypeFunction(dgparams, Type::tint32, 0, LINKd));
+ fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams),
+ Type::tint32, LINKd));
params->push(new Parameter(0, fldeTy[i], NULL, NULL));
fdapply[i] = FuncDeclaration::genCfunc(params, Type::tint32, name[i]);
}
dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
if (dim == 2)
dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
- dgty = new TypeDelegate(new TypeFunction(dgparams, Type::tint32, 0, LINKd));
+ dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams),
+ Type::tint32, LINKd));
params->push(new Parameter(0, dgty, NULL, NULL));
fdapply = FuncDeclaration::genCfunc(params, Type::tint32, fdname);
return dimError(e, 1, dim);
LINK link;
- int varargs;
+ VarArg varargs;
RootObject *o = (*e->args)[0];
Type *t = isType(o);
TypeFunction *tf = NULL;
if (tf)
{
link = tf->linkage;
- varargs = tf->varargs;
+ varargs = tf->parameterList.varargs;
}
else
{
return new ErrorExp();
}
link = fd->linkage;
- fd->getParameters(&varargs);
+ varargs = fd->getParameterList().varargs;
}
const char *style;
switch (varargs)
else if (t->ty == Tpointer && t->nextOf()->ty == Tfunction)
tf = (TypeFunction *)t->nextOf();
}
- Parameters* fparams;
+ ParameterList fparams;
if (tf)
{
- fparams = tf->parameters;
+ fparams = tf->parameterList;
}
else
{
o->toChars(), o1->toChars());
return new ErrorExp();
}
- fparams = fd->getParameters(NULL);
+ fparams = fd->getParameterList();
}
StorageClass stc;
}
ex = ex->ctfeInterpret();
uinteger_t ii = ex->toUInteger();
- if (ii >= Parameter::dim(fparams))
+ if (ii >= fparams.length())
{
- e->error("parameter index must be in range 0..%u not %s", (unsigned)Parameter::dim(fparams), ex->toChars());
+ e->error("parameter index must be in range 0..%u not %s", (unsigned)fparams.length(), ex->toChars());
return new ErrorExp();
}
unsigned n = (unsigned)ii;
- Parameter *p = Parameter::getNth(fparams, n);
+ Parameter *p = fparams[n];
stc = p->storageClass;
// This mirrors hdrgen.visit(Parameter p)
Variadic functions with D linkage have an additional hidden argument
with the name _arguments passed to the function. */
- if (t->varargs == 1 && t->linkage == LINKd)
+ if (t->isDstyleVariadic ())
{
tree type = build_ctype (Type::typeinfotypelist->type);
fnparams = chainon (fnparams, build_tree_list (0, type));
}
- if (t->parameters)
- {
- size_t n_args = Parameter::dim (t->parameters);
+ size_t n_args = t->parameterList.length ();
- for (size_t i = 0; i < n_args; i++)
- {
- tree type = parameter_type (Parameter::getNth (t->parameters, i));
- fnparams = chainon (fnparams, build_tree_list (0, type));
- }
+ for (size_t i = 0; i < n_args; i++)
+ {
+ tree type = parameter_type (t->parameterList[i]);
+ fnparams = chainon (fnparams, build_tree_list (0, type));
}
/* When the last parameter is void_list_node, that indicates a fixed length
parameter list, otherwise function is treated as variadic. */
- if (t->varargs != 1)
+ if (t->parameterList.varargs != VARARGvariadic)
fnparams = chainon (fnparams, void_list_node);
if (t->next != NULL)