diff mbox series

[committed] d: Merge upstream dmd b0df0e982

Message ID 20200607145119.27973-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd b0df0e982 | expand

Commit Message

Iain Buclaw June 7, 2020, 2:51 p.m. UTC
Hi,

This patch merges the D front-end implementation with upstream dmd
b0df0e982.  Adds a struct ParameterList to encapulate parameter and
vararg information in the front-end.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.


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.
---
 gcc/d/d-builtins.cc       |   6 +-
 gcc/d/d-codegen.cc        |  12 ++--
 gcc/d/d-target.cc         |   2 +-
 gcc/d/dmd/MERGE           |   2 +-
 gcc/d/dmd/arrayop.c       |   2 +-
 gcc/d/dmd/clone.c         |  22 +++----
 gcc/d/dmd/cond.c          |   2 +-
 gcc/d/dmd/cppmangle.c     |   6 +-
 gcc/d/dmd/dcast.c         |  12 ++--
 gcc/d/dmd/dclass.c        |   2 +-
 gcc/d/dmd/declaration.h   |   6 +-
 gcc/d/dmd/delegatize.c    |   2 +-
 gcc/d/dmd/dinterpret.c    |   8 +--
 gcc/d/dmd/dmangle.c       |   4 +-
 gcc/d/dmd/doc.c           |  11 ++--
 gcc/d/dmd/dstruct.c       |   2 +-
 gcc/d/dmd/dtemplate.c     |  84 ++++++++++++------------
 gcc/d/dmd/escape.c        |  18 +++---
 gcc/d/dmd/expression.c    |  32 +++++-----
 gcc/d/dmd/expressionsem.c |  22 +++----
 gcc/d/dmd/func.c          |  99 ++++++++++++++--------------
 gcc/d/dmd/hdrgen.c        |  10 +--
 gcc/d/dmd/hdrgen.h        |   2 +-
 gcc/d/dmd/initsem.c       |   3 +-
 gcc/d/dmd/json.c          |   2 +-
 gcc/d/dmd/mtype.c         | 131 +++++++++++++++++++++++---------------
 gcc/d/dmd/mtype.h         |  80 +++++++++++++----------
 gcc/d/dmd/opover.c        |  10 +--
 gcc/d/dmd/optimize.c      |   2 +-
 gcc/d/dmd/parse.c         |  36 ++++++-----
 gcc/d/dmd/parse.h         |   2 +-
 gcc/d/dmd/statementsem.c  |  23 +++----
 gcc/d/dmd/traits.c        |  18 +++---
 gcc/d/types.cc            |  17 ++---
 34 files changed, 369 insertions(+), 323 deletions(-)
diff mbox series

Patch

diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index bd7e3eb15d7..33221ea3229 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -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);
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 301793f1b74..83e757d5a38 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -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);
 	    }
 
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index 29f5eaf5c28..71156e34a9c 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -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 ();
     }
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 56a47bb61a3..6ccb79c643b 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -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.
diff --git a/gcc/d/dmd/arrayop.c b/gcc/d/dmd/arrayop.c
index 16ce3a90f37..3ec07e2b068 100644
--- a/gcc/d/dmd/arrayop.c
+++ b/gcc/d/dmd/arrayop.c
@@ -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;
diff --git a/gcc/d/dmd/clone.c b/gcc/d/dmd/clone.c
index 7f91a10bbaa..a704d1397fe 100644
--- a/gcc/d/dmd/clone.c
+++ b/gcc/d/dmd/clone.c
@@ -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);
diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c
index 63f294a587c..12fef59d820 100644
--- a/gcc/d/dmd/cond.c
+++ b/gcc/d/dmd/cond.c
@@ -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);
diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c
index f39c2484460..ee19bd1932a 100644
--- a/gcc/d/dmd/cppmangle.c
+++ b/gcc/d/dmd/cppmangle.c
@@ -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);
     }
diff --git a/gcc/d/dmd/dcast.c b/gcc/d/dmd/dcast.c
index 20e8dc61438..ad91a65f6ad 100644
--- a/gcc/d/dmd/dcast.c
+++ b/gcc/d/dmd/dcast.c
@@ -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;
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
index 535679e10be..3d6f6227eb3 100644
--- a/gcc/d/dmd/dclass.c
+++ b/gcc/d/dmd/dclass.c
@@ -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;
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 17098998544..e74106391dc 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -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;
diff --git a/gcc/d/dmd/delegatize.c b/gcc/d/dmd/delegatize.c
index 88c565f1670..3aec39372c1 100644
--- a/gcc/d/dmd/delegatize.c
+++ b/gcc/d/dmd/delegatize.c
@@ -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 =
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 7c7238d6b8d..6b4a2b73a7f 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -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;
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index c1a186de645..d6acafee5de 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -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);
 
diff --git a/gcc/d/dmd/doc.c b/gcc/d/dmd/doc.c
index e0bf94086d9..0738f4202d9 100644
--- a/gcc/d/dmd/doc.c
+++ b/gcc/d/dmd/doc.c
@@ -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");
diff --git a/gcc/d/dmd/dstruct.c b/gcc/d/dmd/dstruct.c
index 891d469cebf..f5a99541a67 100644
--- a/gcc/d/dmd/dstruct.c
+++ b/gcc/d/dmd/dstruct.c
@@ -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();
         }
 
diff --git a/gcc/d/dmd/dtemplate.c b/gcc/d/dmd/dtemplate.c
index b126295f07e..34fd621a9f9 100644
--- a/gcc/d/dmd/dtemplate.c
+++ b/gcc/d/dmd/dtemplate.c
@@ -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)
diff --git a/gcc/d/dmd/escape.c b/gcc/d/dmd/escape.c
index df43a7f84bb..b3fccd9ef46 100644
--- a/gcc/d/dmd/escape.c
+++ b/gcc/d/dmd/escape.c
@@ -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);
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index 29103c1bac3..ca4a6e97d21 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -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;
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 4db9591a597..9112b7bc307 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -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;
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index eb8d5dbf2dd..aa09f3e7f65 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -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());
     }
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index d61a244175f..af933bd2e88 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -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();
 }
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index 96c915a99dd..1bad506bb28 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -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);
diff --git a/gcc/d/dmd/initsem.c b/gcc/d/dmd/initsem.c
index b566ec4fa68..9381da46b29 100644
--- a/gcc/d/dmd/initsem.c
+++ b/gcc/d/dmd/initsem.c
@@ -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;
diff --git a/gcc/d/dmd/json.c b/gcc/d/dmd/json.c
index 20e8c426a7f..0c3b7b617b8 100644
--- a/gcc/d/dmd/json.c
+++ b/gcc/d/dmd/json.c
@@ -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);
 
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index e2511a4fd62..d7144879fba 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -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
             }
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 4efeddd7af5..89105d93e3f 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -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);
diff --git a/gcc/d/dmd/opover.c b/gcc/d/dmd/opover.c
index 21737a3a795..847cee93d35 100644
--- a/gcc/d/dmd/opover.c
+++ b/gcc/d/dmd/opover.c
@@ -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))
diff --git a/gcc/d/dmd/optimize.c b/gcc/d/dmd/optimize.c
index fa736dc2a75..82f3aee99fd 100644
--- a/gcc/d/dmd/optimize.c
+++ b/gcc/d/dmd/optimize.c
@@ -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);
                 }
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index 7d858d715ce..e983501bde1 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -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);
 
diff --git a/gcc/d/dmd/parse.h b/gcc/d/dmd/parse.h
index a93a8e6c4bf..dae7b634db4 100644
--- a/gcc/d/dmd/parse.h
+++ b/gcc/d/dmd/parse.h
@@ -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();
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index cd48d9c03cf..33ca46729b0 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -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);
 
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 46cacf3e4c5..bc1e2c3c234 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -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)
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 0fda81c31e7..f3a1c473f7a 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -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)