d: Merge upstream dmd b0df0e982

Adds a struct ParameterList to encapulate parameter and vararg
information in the front-end.

Reviewed-on: https://github.com/dlang/dmd/pull/11226

gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd b0df0e982.
	* d-builtins.cc (build_frontend_type): Use VarArg for varargs_p.
	* d-codegen.cc (declaration_type): Call TypeFunction::create with
	argument VARARGnone.
	(parameter_type): Likewise.
	(d_build_call): Use new field names and member functions.
	* d-target.cc (Target::cppParameterType): Call TypeFunction::create
	with argument VARARGnone.
	* types.cc (TypeVisitor::visit (TypeFunction *): Use new field names
	and member functions.
This commit is contained in:
Iain Buclaw 2020-06-07 16:50:46 +02:00
parent 5aaccde3db
commit c3a2ba10b2
34 changed files with 369 additions and 323 deletions

View File

@ -282,7 +282,7 @@ build_frontend_type (tree type)
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));
@ -293,7 +293,7 @@ build_frontend_type (tree type)
tree argtype = TREE_VALUE (parm);
if (argtype == void_type_node)
{
varargs_p = 0;
varargs_p = VARARGnone;
break;
}
@ -316,7 +316,7 @@ build_frontend_type (tree type)
/* 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);

View File

@ -144,7 +144,8 @@ declaration_type (Declaration *decl)
/* 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 ());
}
@ -193,7 +194,8 @@ parameter_type (Parameter *arg)
/* 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 ());
}
@ -1885,9 +1887,9 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
}
}
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)
@ -1898,7 +1900,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
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);
}

View File

@ -368,7 +368,7 @@ TargetCPP::parameterType (Parameter *arg)
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 ();
}

View File

@ -1,4 +1,4 @@
1831b24fffe35fd0e332c194fdf8723ba3c930a5
b0df0e982cc44bd09a9061acfc8160f29767334a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.

View File

@ -66,7 +66,7 @@ FuncDeclaration *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc)
/* 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;

View File

@ -117,11 +117,10 @@ FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc)
{
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;
}
@ -246,7 +245,7 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
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;
@ -505,7 +504,7 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
*/
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);
}
@ -534,7 +533,7 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
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);
@ -585,7 +584,7 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
*/
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);
}
@ -619,7 +618,7 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
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);
@ -718,7 +717,7 @@ FuncDeclaration *buildXtoHash(StructDeclaration *sd, Scope *sc)
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();
}
@ -740,7 +739,8 @@ FuncDeclaration *buildXtoHash(StructDeclaration *sd, Scope *sc)
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);

View File

@ -122,7 +122,7 @@ static void lowerArrayAggregate(StaticForeach *sfe, Scope *sc)
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);

View File

@ -657,7 +657,8 @@ class CppMangleVisitor : public Visitor
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);
}
}
@ -982,7 +983,8 @@ public:
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);
}

View File

@ -838,8 +838,8 @@ MATCH implicitConvTo(Expression *e, Type *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
@ -855,7 +855,7 @@ MATCH implicitConvTo(Expression *e, Type *t)
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;
@ -1124,15 +1124,15 @@ MATCH implicitConvTo(Expression *e, Type *t)
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;

View File

@ -803,7 +803,7 @@ Lancestorsdone:
{
//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;

View File

@ -664,7 +664,7 @@ public:
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);
@ -866,9 +866,9 @@ class NewDeclaration : public FuncDeclaration
{
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;

View File

@ -39,7 +39,7 @@ Expression *toDelegate(Expression *e, Type* t, Scope *sc)
//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 =

View File

@ -760,7 +760,7 @@ static Expression *interpretFunction(UnionExp *pue, FuncDeclaration *fd, InterSt
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");
@ -795,7 +795,7 @@ static Expression *interpretFunction(UnionExp *pue, FuncDeclaration *fd, InterSt
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))
{
@ -859,7 +859,7 @@ static Expression *interpretFunction(UnionExp *pue, FuncDeclaration *fd, InterSt
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);
@ -6554,7 +6554,7 @@ Expression *interpret_aaApply(UnionExp *pue, InterState *istate, Expression *aa,
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;

View File

@ -261,9 +261,9 @@ public:
}
// 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);

View File

@ -127,7 +127,7 @@ bool isCVariadicParameter(Dsymbols *a, const utf8_t *p, size_t len)
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;
@ -138,11 +138,11 @@ bool isCVariadicParameter(Dsymbols *a, const utf8_t *p, size_t len)
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;
@ -1733,7 +1733,8 @@ void ParamSection::write(Loc loc, DocComment *, Scope *sc, Dsymbols *a, OutBuffe
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");

View File

@ -45,7 +45,7 @@ FuncDeclaration *search_toString(StructDeclaration *sd)
static TypeFunction *tftostring;
if (!tftostring)
{
tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
tftostring = new TypeFunction(ParameterList(), Type::tstring, LINKd);
tftostring = tftostring->merge()->toTypeFunction();
}

View File

@ -786,8 +786,8 @@ bool TemplateDeclaration::evaluateConstraint(
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++)
@ -795,7 +795,7 @@ bool TemplateDeclaration::evaluateConstraint(
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++)
@ -943,8 +943,8 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
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.
@ -1110,8 +1110,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
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;
@ -1200,9 +1199,9 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
//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:
@ -1235,14 +1234,14 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
*/
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;
@ -1320,7 +1319,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
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);
@ -1348,7 +1347,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
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);
@ -1432,7 +1431,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
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;
@ -1629,7 +1629,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
}
}
if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs)
if (fparameters.varargs == VARARGtypesafe && parami + 1 == nfparams && argi + 1 < nfargs)
goto Lvarargs;
unsigned wm = 0;
@ -1699,7 +1699,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
/* 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...
@ -1833,7 +1833,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
++argi;
}
//printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
if (argi != nfargs2 && !fvarargs)
if (argi != nfargs2 && fparameters.varargs == VARARGnone)
goto Lnomatch;
}
@ -2681,8 +2681,8 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(
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
@ -2755,7 +2755,7 @@ const char *TemplateDeclaration::toChars()
if (fd && fd->type)
{
TypeFunction *tf = (TypeFunction *)fd->type;
buf.writestring(parametersTypeToChars(tf->parameters, tf->varargs));
buf.writestring(parametersTypeToChars(tf->parameterList));
}
}
@ -3537,20 +3537,20 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
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);
}
@ -3564,7 +3564,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
/* 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)
@ -3605,7 +3605,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
}
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;
@ -3620,7 +3620,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
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;
@ -3638,8 +3638,8 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
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))
@ -4422,10 +4422,10 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
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();
@ -4437,7 +4437,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
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)
{
@ -4445,7 +4445,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
}
}
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
@ -4577,10 +4577,10 @@ bool reliesOnTident(Type *t, TemplateParameters *tparams, size_t iStart)
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;
@ -7182,7 +7182,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
*/
//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)
@ -7201,7 +7201,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
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;
}
}
@ -7904,11 +7904,11 @@ int TemplateInstance::compare(RootObject *o)
{
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)

View File

@ -707,12 +707,12 @@ static void inferReturn(FuncDeclaration *fd, VarDeclaration *v)
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;
@ -950,14 +950,14 @@ static void escapeByValue(Expression *e, EscapeByResults *er)
/* 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);
@ -1146,15 +1146,15 @@ static void escapeByRef(Expression *e, EscapeByResults *er)
/* 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);

View File

@ -1385,14 +1385,14 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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;
@ -1446,13 +1446,13 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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;
@ -1465,7 +1465,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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());
{
@ -1620,7 +1620,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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))
{
@ -1733,7 +1733,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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)
@ -1823,7 +1823,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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;
}
@ -1853,7 +1853,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
{
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));
@ -1945,7 +1945,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
//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);
@ -4678,10 +4678,10 @@ MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
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();
@ -4693,7 +4693,7 @@ MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
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)
{
@ -4701,7 +4701,7 @@ MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
}
}
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;
@ -4745,7 +4745,7 @@ MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
*/
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;

View File

@ -1653,16 +1653,16 @@ public:
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);
@ -1671,7 +1671,7 @@ public:
{
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];
@ -2025,13 +2025,13 @@ public:
/* 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
@ -2911,7 +2911,7 @@ public:
// 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);
@ -3419,7 +3419,7 @@ public:
//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();
@ -3492,7 +3492,7 @@ public:
//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;

View File

@ -1287,7 +1287,7 @@ static void buildEnsureRequire(FuncDeclaration *fdx)
* __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;
@ -1320,7 +1320,7 @@ static void buildEnsureRequire(FuncDeclaration *fdx)
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;
@ -1519,7 +1519,7 @@ void FuncDeclaration::semantic3(Scope *sc)
//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)
{
@ -1550,7 +1550,7 @@ void FuncDeclaration::semantic3(Scope *sc)
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);
@ -1565,7 +1565,7 @@ void FuncDeclaration::semantic3(Scope *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
@ -1575,7 +1575,7 @@ void FuncDeclaration::semantic3(Scope *sc)
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)
@ -1590,7 +1590,7 @@ void FuncDeclaration::semantic3(Scope *sc)
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;
@ -1608,11 +1608,11 @@ void FuncDeclaration::semantic3(Scope *sc)
// 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
@ -2313,7 +2313,7 @@ void FuncDeclaration::semantic3(Scope *sc)
// 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++)
{
@ -2321,7 +2321,7 @@ void FuncDeclaration::semantic3(Scope *sc)
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;
@ -3317,7 +3317,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
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.
@ -3342,7 +3342,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
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))
{
@ -3360,7 +3360,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
/* 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;
@ -3446,7 +3446,7 @@ struct FuncCandidateWalker
TypeFunction *tf = (TypeFunction *)fd->type;
::errorSupplemental(fd->loc, "%s%s", fd->toPrettyChars(),
parametersTypeToChars(tf->parameters, tf->varargs));
parametersTypeToChars(tf->parameterList));
}
else
{
@ -3590,7 +3590,7 @@ FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
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());
}
@ -3609,8 +3609,8 @@ FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
{
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(),
@ -4066,10 +4066,10 @@ bool FuncDeclaration::parametersIntersect(Type *t)
//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))
@ -4252,7 +4252,7 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, I
}
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;
@ -4269,11 +4269,11 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, I
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 ||
@ -4288,7 +4288,7 @@ void FuncDeclaration::checkDmain()
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)");
}
@ -4640,20 +4640,15 @@ bool FuncDeclaration::hasNestedFrameRefs()
* 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();
}
@ -4865,11 +4860,11 @@ void CtorDeclaration::semantic(Scope *sc)
*/
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)
{
@ -4880,10 +4875,10 @@ void CtorDeclaration::semantic(Scope *sc)
}
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)
@ -4898,7 +4893,7 @@ void CtorDeclaration::semantic(Scope *sc)
}
}
else if (dim == 0 && tf->varargs == 0)
else if (dim == 0 && tf->parameterList.varargs == VARARGnone)
{
ad->defaultCtor = this;
}
@ -4972,7 +4967,7 @@ void PostBlitDeclaration::semantic(Scope *sc)
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
@ -5048,7 +5043,7 @@ void DtorDeclaration::semantic(Scope *sc)
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
@ -5135,7 +5130,7 @@ void StaticCtorDeclaration::semantic(Scope *sc)
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
@ -5261,7 +5256,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
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
@ -5387,7 +5382,7 @@ void InvariantDeclaration::semantic(Scope *sc)
)
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
@ -5468,7 +5463,7 @@ void UnitTestDeclaration::semantic(Scope *sc)
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);
@ -5498,7 +5493,7 @@ bool UnitTestDeclaration::addPostInvariant()
/********************************* 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;
@ -5536,19 +5531,19 @@ void NewDeclaration::semantic(Scope *sc)
}
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());
}
@ -5614,19 +5609,19 @@ void DeleteDeclaration::semantic(Scope *sc)
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());
}

View File

@ -918,7 +918,7 @@ public:
if (ident)
buf->writestring(ident);
parametersToBuffer(t->parameters, t->varargs);
parametersToBuffer(t->parameterList.parameters, t->parameterList.varargs);
/* Use postfix style for attributes
*/
@ -988,7 +988,7 @@ public:
}
buf->writeByte(')');
}
parametersToBuffer(t->parameters, t->varargs);
parametersToBuffer(t->parameterList.parameters, t->parameterList.varargs);
t->inuse--;
}
@ -2012,7 +2012,7 @@ public:
// 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;
@ -3469,11 +3469,11 @@ void arrayObjectsToBuffer(OutBuffer *buf, Objects *objects)
}
}
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();
}

View File

@ -46,7 +46,7 @@ void arrayObjectsToBuffer(OutBuffer *buf, Objects *objects);
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);

View File

@ -182,8 +182,7 @@ public:
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;

View File

@ -679,7 +679,7 @@ public:
TypeFunction *tf = (TypeFunction *)d->type;
if (tf && tf->ty == Tfunction)
property("parameters", tf->parameters);
property("parameters", tf->parameterList.parameters);
property("endline", "endchar", &d->endloc);

View File

@ -1567,11 +1567,11 @@ Type *stripDefaultArgs(Type *t)
{
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;
@ -1985,24 +1985,25 @@ Type *TypeFunction::substWildTo(unsigned)
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;
@ -5119,14 +5120,13 @@ bool TypeReference::isZeroInit(Loc)
/***************************** 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;
@ -5167,9 +5167,9 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, L
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()
@ -5180,8 +5180,9 @@ 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;
@ -5233,19 +5234,19 @@ int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
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))
{
@ -5287,10 +5288,10 @@ int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
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;
}
@ -5447,14 +5448,15 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
* 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;
}
}
@ -5513,7 +5515,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
}
unsigned char wildparams = 0;
if (tf->parameters)
if (tf->parameterList.parameters)
{
/* Create a scope for evaluating the default arguments for the parameters
*/
@ -5522,10 +5524,10 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
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--;
@ -5728,7 +5730,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
/* 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;
}
@ -5770,13 +5772,13 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
}
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;
@ -5880,10 +5882,10 @@ void TypeFunction::purityLevel()
/* 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;
@ -5968,13 +5970,13 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
}
}
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
}
@ -5983,7 +5985,7 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
{
if (u >= nparams)
break;
Parameter *p = Parameter::getNth(parameters, u);
Parameter *p = parameterList[u];
Expression *arg = (*args)[u];
assert(arg);
Type *tprm = p->type;
@ -6016,7 +6018,7 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
{
MATCH m;
Parameter *p = Parameter::getNth(parameters, u);
Parameter *p = parameterList[u];
assert(p);
if (u >= nargs)
{
@ -6107,14 +6109,14 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
/* 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;
@ -6192,16 +6194,27 @@ Nomatch:
*/
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.
@ -6254,10 +6267,10 @@ StorageClass TypeFunction::parameterStorageClass(Parameter *p)
// 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;
@ -6305,7 +6318,7 @@ Type *TypeFunction::addStorageClass(StorageClass stc)
(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;
@ -9298,6 +9311,22 @@ Expression *TypeNull::defaultInit(Loc)
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)
@ -9355,7 +9384,7 @@ Type *Parameter::isLazyArray()
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
}

View File

@ -126,6 +126,14 @@ extern unsigned char impcnvType2[TMAX][TMAX];
// 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:
@ -587,14 +595,48 @@ enum PURE
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
@ -610,13 +652,14 @@ public:
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);
@ -919,32 +962,5 @@ public:
/**************************************************************/
//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);

View File

@ -1923,9 +1923,9 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *parameters, int fla
{ 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();
@ -1934,8 +1934,8 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *parameters, int fla
/* 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
@ -1943,7 +1943,7 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *parameters, int fla
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))

View File

@ -531,7 +531,7 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue)
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);
}

View File

@ -1603,10 +1603,10 @@ Dsymbol *Parser::parseCtor(PrefixAttributes *pAttrs)
/* 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");
@ -1621,7 +1621,8 @@ Dsymbol *Parser::parseCtor(PrefixAttributes *pAttrs)
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);
@ -1929,7 +1930,7 @@ Dsymbol *Parser::parseNew(PrefixAttributes *pAttrs)
nextToken();
int varargs;
VarArg varargs;
Parameters *parameters = parseParameters(&varargs);
NewDeclaration *f = new NewDeclaration(loc, Loc(), stc, parameters, varargs);
if (pAttrs)
@ -1951,9 +1952,9 @@ Dsymbol *Parser::parseDelete(PrefixAttributes *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)
@ -1966,10 +1967,10 @@ Dsymbol *Parser::parseDelete(PrefixAttributes *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);
@ -1989,7 +1990,7 @@ Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
break;
case TOKdotdotdot:
varargs = 1;
varargs = VARARGvariadic;
nextToken();
break;
@ -2076,7 +2077,7 @@ Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
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;
@ -3406,11 +3407,12 @@ Type *Parser::parseBasicType2(Type *t)
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)
@ -3572,14 +3574,15 @@ Type *Parser::parseDeclarator(Type *t, int *palt, Identifier **pident,
}
}
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;
@ -4159,7 +4162,7 @@ Dsymbol *Parser::parseFunctionLiteral()
TemplateParameters *tpl = NULL;
Parameters *parameters = NULL;
int varargs = 0;
VarArg varargs = VARARGnone;
Type *tret = NULL;
StorageClass stc = 0;
TOK save = TOKreserved;
@ -4235,7 +4238,8 @@ Dsymbol *Parser::parseFunctionLiteral()
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);

View File

@ -103,7 +103,7 @@ public:
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();

View File

@ -897,18 +897,17 @@ public:
{
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;
}
}
@ -1433,9 +1432,9 @@ public:
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);
@ -1460,7 +1459,7 @@ public:
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.
@ -1497,7 +1496,7 @@ public:
}
// 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);
@ -1575,7 +1574,8 @@ public:
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]);
}
@ -1640,7 +1640,8 @@ public:
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);

View File

@ -969,7 +969,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
return dimError(e, 1, dim);
LINK link;
int varargs;
VarArg varargs;
RootObject *o = (*e->args)[0];
Type *t = isType(o);
TypeFunction *tf = NULL;
@ -985,7 +985,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
if (tf)
{
link = tf->linkage;
varargs = tf->varargs;
varargs = tf->parameterList.varargs;
}
else
{
@ -997,7 +997,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
return new ErrorExp();
}
link = fd->linkage;
fd->getParameters(&varargs);
varargs = fd->getParameterList().varargs;
}
const char *style;
switch (varargs)
@ -1034,10 +1034,10 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
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
{
@ -1049,7 +1049,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
o->toChars(), o1->toChars());
return new ErrorExp();
}
fparams = fd->getParameters(NULL);
fparams = fd->getParameterList();
}
StorageClass stc;
@ -1064,14 +1064,14 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
}
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)

View File

@ -709,26 +709,23 @@ public:
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)