aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-01-07 18:03:33 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-01-07 18:22:36 +0100
commitdddea6d4d81cac76ff64cde178e2d5f7fe09fb55 (patch)
treef8c2345d5a980c6523798c1388a777e05fdaf500 /gcc/d/dmd
parentd54029179cbe817eaf9b6899339b0151cff3c00e (diff)
downloadgcc-dddea6d4d81cac76ff64cde178e2d5f7fe09fb55.zip
gcc-dddea6d4d81cac76ff64cde178e2d5f7fe09fb55.tar.gz
gcc-dddea6d4d81cac76ff64cde178e2d5f7fe09fb55.tar.bz2
d: Merge upstream dmd 9038e64c5.
Adds support for using user-defined attributes on function arguments and single-parameter alias declarations. These attributes behave analogous to existing UDAs. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 9038e64c5. * d-builtins.cc (build_frontend_type): Update call to Parameter::create.
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/arrayop.c8
-rw-r--r--gcc/d/dmd/clone.c16
-rw-r--r--gcc/d/dmd/cond.c2
-rw-r--r--gcc/d/dmd/declaration.c2
-rw-r--r--gcc/d/dmd/dtemplate.c2
-rw-r--r--gcc/d/dmd/expression.c2
-rw-r--r--gcc/d/dmd/expressionsem.c5
-rw-r--r--gcc/d/dmd/func.c24
-rw-r--r--gcc/d/dmd/hdrgen.c12
-rw-r--r--gcc/d/dmd/mtype.c30
-rw-r--r--gcc/d/dmd/mtype.h7
-rw-r--r--gcc/d/dmd/parse.c113
-rw-r--r--gcc/d/dmd/statementsem.c24
-rw-r--r--gcc/d/dmd/traits.c39
15 files changed, 216 insertions, 72 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 1629b45..25b2b3a 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-a5c86f5b92c4cd3afde910c89881ccaea11de554
+9038e64c5b67a10763d32893f53bb6c610df3595
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 72abd5e..20cdb6f 100644
--- a/gcc/d/dmd/arrayop.c
+++ b/gcc/d/dmd/arrayop.c
@@ -51,7 +51,7 @@ FuncDeclaration *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc)
Parameter *p = (*fparams)[0];
// foreach (i; 0 .. p.length)
Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach,
- new Parameter(0, NULL, Id::p, NULL),
+ new Parameter(0, NULL, Id::p, NULL, NULL),
new IntegerExp(Loc(), 0, Type::tsize_t),
new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)),
new ExpStatement(Loc(), loopbody),
@@ -422,7 +422,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
void visit(Expression *e)
{
Identifier *id = Identifier::generateId("c", fparams->length);
- Parameter *param = new Parameter(0, e->type, id, NULL);
+ Parameter *param = new Parameter(0, e->type, id, NULL, NULL);
fparams->shift(param);
result = new IdentifierExp(Loc(), id);
}
@@ -441,7 +441,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
void visit(ArrayLiteralExp *e)
{
Identifier *id = Identifier::generateId("p", fparams->length);
- Parameter *param = new Parameter(STCconst, e->type, id, NULL);
+ Parameter *param = new Parameter(STCconst, e->type, id, NULL, NULL);
fparams->shift(param);
Expression *ie = new IdentifierExp(Loc(), id);
Expression *index = new IdentifierExp(Loc(), Id::p);
@@ -451,7 +451,7 @@ Expression *buildArrayLoop(Expression *e, Parameters *fparams)
void visit(SliceExp *e)
{
Identifier *id = Identifier::generateId("p", fparams->length);
- Parameter *param = new Parameter(STCconst, e->type, id, NULL);
+ Parameter *param = new Parameter(STCconst, e->type, id, NULL, NULL);
fparams->shift(param);
Expression *ie = new IdentifierExp(Loc(), id);
Expression *index = new IdentifierExp(Loc(), Id::p);
diff --git a/gcc/d/dmd/clone.c b/gcc/d/dmd/clone.c
index dd22fb3..73c4a66 100644
--- a/gcc/d/dmd/clone.c
+++ b/gcc/d/dmd/clone.c
@@ -244,7 +244,7 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
}
Parameters *fparams = new Parameters;
- fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL));
+ fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL, NULL));
TypeFunction *tf = new TypeFunction(ParameterList(fparams), sd->handleType(), LINKd, stc | STCref);
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
@@ -503,7 +503,7 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
/* const bool opEquals(ref const S s);
*/
Parameters *parameters = new Parameters;
- parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
tfeqptr = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);
tfeqptr->mod = MODconst;
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &scx);
@@ -531,8 +531,8 @@ FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc)
Loc loc = Loc(); // loc is unnecessary so errors are gagged
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));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tbool, LINKd);
Identifier *id = Id::xopEquals;
@@ -583,7 +583,7 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
/* const int opCmp(ref const S s);
*/
Parameters *parameters = new Parameters;
- parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL, NULL));
tfcmpptr = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);
tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &scx);
@@ -616,8 +616,8 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
Loc loc = Loc(); // loc is unnecessary so errors are gagged
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));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL, NULL));
TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::tint32, LINKd);
Identifier *id = Id::xopCmp;
@@ -738,7 +738,7 @@ FuncDeclaration *buildXtoHash(StructDeclaration *sd, Scope *sc)
Loc loc = Loc(); // internal code should have no loc to prevent coverage
Parameters *parameters = new Parameters();
- parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
+ parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL, NULL));
TypeFunction *tf = new TypeFunction(ParameterList(parameters), Type::thash_t,
LINKd, STCnothrow | STCtrusted);
diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c
index 9f76e83..2ea3d40 100644
--- a/gcc/d/dmd/cond.c
+++ b/gcc/d/dmd/cond.c
@@ -257,7 +257,7 @@ static void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc)
{
Parameters *params = pparams[j];
Parameter *p = sfe->aggrfe ? (*sfe->aggrfe->parameters)[i] : sfe->rangefe->prm;
- params->push(new Parameter(p->storageClass, p->type, p->ident, NULL));
+ params->push(new Parameter(p->storageClass, p->type, p->ident, NULL, NULL));
}
}
Expression *res[2];
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index f490cc5..f196bc8 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -224,7 +224,7 @@ Type *TupleDeclaration::getType()
{
Type *t = (*types)[i];
//printf("type = %s\n", t->toChars());
- Parameter *arg = new Parameter(0, t, NULL, NULL);
+ Parameter *arg = new Parameter(0, t, NULL, NULL, NULL);
(*args)[i] = arg;
if (!t->deco)
hasdeco = 0;
diff --git a/gcc/d/dmd/dtemplate.c b/gcc/d/dmd/dtemplate.c
index 1035f82..316f105 100644
--- a/gcc/d/dmd/dtemplate.c
+++ b/gcc/d/dmd/dtemplate.c
@@ -6805,7 +6805,7 @@ bool TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
for (size_t i = 0; i < dim; i++)
{
Parameter *arg = (*tt->arguments)[i];
- if (flags & 2 && arg->ident)
+ if (flags & 2 && (arg->ident || arg->userAttribDecl))
tiargs->insert(j + i, arg);
else
tiargs->insert(j + i, arg->type);
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index 7891832..a3c3f72 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -1953,7 +1953,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
args->setDim(arguments->length - nparams);
for (size_t i = 0; i < arguments->length - nparams; i++)
{
- Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL);
+ Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL, NULL);
(*args)[i] = arg;
}
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 7dfe995..f519389 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -2051,7 +2051,7 @@ public:
for (size_t i = 0; i < cd->baseclasses->length; i++)
{
BaseClass *b = (*cd->baseclasses)[i];
- args->push(new Parameter(STCin, b->type, NULL, NULL));
+ args->push(new Parameter(STCin, b->type, NULL, NULL, NULL));
}
tded = new TypeTuple(args);
}
@@ -2100,7 +2100,8 @@ public:
return setError();
args->push(new Parameter(arg->storageClass, arg->type,
(e->tok2 == TOKparameters) ? arg->ident : NULL,
- (e->tok2 == TOKparameters) ? arg->defaultArg : NULL));
+ (e->tok2 == TOKparameters) ? arg->defaultArg : NULL,
+ arg->userAttribDecl));
}
tded = new TypeTuple(args);
break;
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index fe1ad11..53621adc 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -1221,6 +1221,15 @@ Ldone:
Compiler::genCmain(sc);
assert(type->ty != Terror || errors);
+
+ // semantic for parameters' UDAs
+ const size_t nparams = f->parameterList.length();
+ for (size_t i = 0; i < nparams; i++)
+ {
+ Parameter *param = f->parameterList[i];
+ if (param && param->userAttribDecl)
+ param->userAttribDecl->semantic(sc);
+ }
}
void FuncDeclaration::semantic2(Scope *sc)
@@ -1237,6 +1246,17 @@ void FuncDeclaration::semantic2(Scope *sc)
{
objc()->checkLinkage(this);
}
+ if (!type || type->ty != Tfunction)
+ return;
+ TypeFunction *f = type->toTypeFunction();
+ const size_t nparams = f->parameterList.length();
+ // semantic for parameters' UDAs
+ for (size_t i = 0; i < nparams; i++)
+ {
+ Parameter *param = f->parameterList[i];
+ if (param && param->userAttribDecl)
+ param->userAttribDecl->semantic2(sc);
+ }
}
/****************************************************
@@ -1317,7 +1337,7 @@ static void buildEnsureRequire(FuncDeclaration *fdx)
Parameter *p = NULL;
if (fdx->outId)
{
- p = new Parameter(STCref | STCconst, f->nextOf(), fdx->outId, NULL);
+ p = new Parameter(STCref | STCconst, f->nextOf(), fdx->outId, NULL, NULL);
fparams->push(p);
}
TypeFunction *tf = new TypeFunction(ParameterList(fparams), Type::tvoid, LINKd);
@@ -1603,6 +1623,8 @@ void FuncDeclaration::semantic3(Scope *sc)
parameters->push(v);
localsymtab->insert(v);
v->parent = this;
+ if (fparam->userAttribDecl)
+ v->userAttribDecl = fparam->userAttribDecl;
}
}
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index fd4d162..a04a8c5 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -3097,6 +3097,18 @@ public:
void visit(Parameter *p)
{
+ if (p->userAttribDecl)
+ {
+ buf->writestring("@");
+ bool isAnonymous = p->userAttribDecl->atts->length > 0
+ && (*p->userAttribDecl->atts)[0]->op != TOKcall;
+ if (isAnonymous)
+ buf->writestring("(");
+ argsToBuffer(p->userAttribDecl->atts);
+ if (isAnonymous)
+ buf->writestring(")");
+ buf->writestring(" ");
+ }
if (p->storageClass & STCauto)
buf->writestring("auto ");
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 94e2082..42f90fa 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -1543,7 +1543,7 @@ Type *stripDefaultArgs(Type *t)
{
Parameter *p = (*params)[i];
Type *ta = stripDefaultArgs(p->type);
- if (ta != p->type || p->defaultArg || p->ident)
+ if (ta != p->type || p->defaultArg || p->ident || p->userAttribDecl)
{
if (params == parameters)
{
@@ -1552,7 +1552,7 @@ Type *stripDefaultArgs(Type *t)
for (size_t j = 0; j < params->length; j++)
(*params)[j] = (*parameters)[j];
}
- (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL);
+ (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL, NULL);
}
}
}
@@ -1996,7 +1996,7 @@ Type *TypeFunction::substWildTo(unsigned)
continue;
if (params == parameterList.parameters)
params = parameterList.parameters->copy();
- (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
+ (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL, NULL);
}
if (next == tret && params == parameterList.parameters)
return this;
@@ -4914,7 +4914,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int
if (fd_aaLen == NULL)
{
Parameters *fparams = new Parameters();
- fparams->push(new Parameter(STCin, this, NULL, NULL));
+ fparams->push(new Parameter(STCin, this, NULL, NULL, NULL));
fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
TypeFunction *tf = fd_aaLen->type->toTypeFunction();
tf->purity = PUREconst;
@@ -5821,7 +5821,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
}
(*newparams)[j] = new Parameter(
- stc, narg->type, narg->ident, narg->defaultArg);
+ stc, narg->type, narg->ident, narg->defaultArg, narg->userAttribDecl);
}
fparam->type = new TypeTuple(newparams);
}
@@ -9098,7 +9098,7 @@ TypeTuple::TypeTuple(Expressions *exps)
{ Expression *e = (*exps)[i];
if (e->type->ty == Ttuple)
e->error("cannot form tuple of tuples");
- Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
+ Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL, NULL);
(*arguments)[i] = arg;
}
}
@@ -9124,15 +9124,15 @@ TypeTuple::TypeTuple(Type *t1)
: Type(Ttuple)
{
arguments = new Parameters();
- arguments->push(new Parameter(0, t1, NULL, NULL));
+ arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
}
TypeTuple::TypeTuple(Type *t1, Type *t2)
: Type(Ttuple)
{
arguments = new Parameters();
- arguments->push(new Parameter(0, t1, NULL, NULL));
- arguments->push(new Parameter(0, t2, NULL, NULL));
+ arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
+ arguments->push(new Parameter(0, t2, NULL, NULL, NULL));
}
const char *TypeTuple::kind()
@@ -9436,17 +9436,20 @@ size_t ParameterList::length()
/***************************** Parameter *****************************/
-Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
+Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident,
+ Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
{
this->type = type;
this->ident = ident;
this->storageClass = storageClass;
this->defaultArg = defaultArg;
+ this->userAttribDecl = userAttribDecl;
}
-Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
+Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident,
+ Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
{
- return new Parameter(storageClass, type, ident, defaultArg);
+ return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);
}
Parameter *Parameter::syntaxCopy()
@@ -9454,7 +9457,8 @@ Parameter *Parameter::syntaxCopy()
return new Parameter(storageClass,
type ? type->syntaxCopy() : NULL,
ident,
- defaultArg ? defaultArg->syntaxCopy() : NULL);
+ defaultArg ? defaultArg->syntaxCopy() : NULL,
+ userAttribDecl ? (UserAttributeDeclaration *) userAttribDecl->syntaxCopy(NULL) : NULL);
}
Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index b0878c8..28dba1c 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -623,9 +623,12 @@ public:
Type *type;
Identifier *ident;
Expression *defaultArg;
+ UserAttributeDeclaration *userAttribDecl; // user defined attributes
- Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
- static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
+ Parameter(StorageClass storageClass, Type *type, Identifier *ident,
+ Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
+ static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
+ Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
Parameter *syntaxCopy();
Type *isLazyArray();
// kludge for template.isType()
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index be861fa..e414a4d 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -1110,7 +1110,7 @@ StorageClass Parser::parsePostfix(StorageClass storageClass, Expressions **pudas
// Disallow:
// void function() @uda fp;
// () @uda { return 1; }
- error("user defined attributes cannot appear as postfixes");
+ error("user-defined attributes cannot appear as postfixes");
}
continue;
}
@@ -1979,9 +1979,11 @@ Parameters *Parser::parseParameters(VarArg *pvarargs, TemplateParameters **tpl)
StorageClass storageClass = 0;
StorageClass stc;
Expression *ae;
+ Expressions *udas = NULL;
for (;1; nextToken())
{
+ L3:
switch (token.value)
{
case TOKrparen:
@@ -2016,6 +2018,28 @@ Parameters *Parser::parseParameters(VarArg *pvarargs, TemplateParameters **tpl)
stc = STCwild;
goto L2;
+ case TOKat:
+ {
+ Expressions *exps = NULL;
+ StorageClass stc2 = parseAttribute(&exps);
+ if (stc2 == STCproperty || stc2 == STCnogc ||
+ stc2 == STCdisable || stc2 == STCsafe ||
+ stc2 == STCtrusted || stc2 == STCsystem)
+ {
+ error("`@%s` attribute for function parameter is not supported", token.toChars());
+ }
+ else
+ {
+ udas = UserAttributeDeclaration::concat(udas, exps);
+ }
+ if (token.value == TOKdotdotdot)
+ error("variadic parameter cannot have user-defined attributes");
+ if (stc2)
+ nextToken();
+ goto L3;
+ // Don't call nextToken again.
+ }
+
case TOKin: stc = STCin; goto L2;
case TOKout: stc = STCout; goto L2;
case TOKref: stc = STCref; goto L2;
@@ -2068,6 +2092,30 @@ Parameters *Parser::parseParameters(VarArg *pvarargs, TemplateParameters **tpl)
error("default argument expected for %s",
ai ? ai->toChars() : at->toChars());
}
+ Parameter *param = new Parameter(storageClass, at, ai, ae, NULL);
+ if (udas)
+ {
+ Dsymbols *a = new Dsymbols();
+ UserAttributeDeclaration *udad = new UserAttributeDeclaration(udas, a);
+ param->userAttribDecl = udad;
+ }
+ if (token.value == TOKat)
+ {
+ Expressions *exps = NULL;
+ StorageClass stc2 = parseAttribute(&exps);
+ if (stc2 == STCproperty || stc2 == STCnogc ||
+ stc2 == STCdisable || stc2 == STCsafe ||
+ stc2 == STCtrusted || stc2 == STCsystem)
+ {
+ error("`@%s` attribute for function parameter is not supported", token.toChars());
+ }
+ else
+ {
+ error("user-defined attributes cannot appear as postfixes", token.toChars());
+ }
+ if (stc2)
+ nextToken();
+ }
if (token.value == TOKdotdotdot)
{ /* This is:
* at ai ...
@@ -2076,11 +2124,11 @@ Parameters *Parser::parseParameters(VarArg *pvarargs, TemplateParameters **tpl)
if (storageClass & (STCout | STCref))
error("variadic argument cannot be out or ref");
varargs = VARARGtypesafe;
- parameters->push(new Parameter(storageClass, at, ai, ae));
+ parameters->push(param);
nextToken();
break;
}
- parameters->push(new Parameter(storageClass, at, ai, ae));
+ parameters->push(param);
if (token.value == TOKcomma)
{ nextToken();
goto L1;
@@ -3779,6 +3827,21 @@ Dsymbols *Parser::parseDeclarations(bool autodecl, PrefixAttributes *pAttrs, con
tpl = parseTemplateParameterList();
check(TOKassign);
+ bool hasParsedAttributes = false;
+ if (token.value == TOKat)
+ {
+ if (!hasParsedAttributes)
+ {
+ hasParsedAttributes = true;
+ storage_class = STCundefined;
+ link = linkage;
+ setAlignment = false;
+ ealign = NULL;
+ udas = NULL;
+ parseStorageClasses(storage_class, link, setAlignment, ealign, udas);
+ }
+ }
+
Declaration *v;
if (token.value == TOKfunction ||
token.value == TOKdelegate ||
@@ -3796,21 +3859,39 @@ Dsymbols *Parser::parseDeclarations(bool autodecl, PrefixAttributes *pAttrs, con
// identifier => expression
Dsymbol *s = parseFunctionLiteral();
+
+ if (udas != NULL)
+ {
+ if (storage_class != 0)
+ error("Cannot put a storage-class in an alias declaration.");
+ // shouldn't have set these variables
+ assert(link == linkage && !setAlignment && ealign == NULL);
+ TemplateDeclaration *tpl_ = (TemplateDeclaration *) s;
+ assert(tpl_ != NULL && tpl_->members->length == 1);
+ FuncLiteralDeclaration *fd = (FuncLiteralDeclaration *) (*tpl_->members)[0];
+ TypeFunction *tf = (TypeFunction *) fd->type;
+ assert(tf->parameterList.length() > 0);
+ Dsymbols *as = new Dsymbols();
+ (*tf->parameterList.parameters)[0]->userAttribDecl = new UserAttributeDeclaration(udas, as);
+ }
v = new AliasDeclaration(loc, ident, s);
}
else
{
// StorageClasses type
-
- storage_class = STCundefined;
- link = linkage;
- setAlignment = false;
- ealign = NULL;
- udas = NULL;
- parseStorageClasses(storage_class, link, setAlignment, ealign, udas);
+ if (!hasParsedAttributes)
+ {
+ hasParsedAttributes = true;
+ storage_class = STCundefined;
+ link = linkage;
+ setAlignment = false;
+ ealign = NULL;
+ udas = NULL;
+ parseStorageClasses(storage_class, link, setAlignment, ealign, udas);
+ }
if (udas)
- error("user defined attributes not allowed for %s declarations", Token::toChars(tok));
+ error("user-defined attributes not allowed for %s declarations", Token::toChars(tok));
t = parseType();
v = new AliasDeclaration(loc, ident, t);
@@ -3991,7 +4072,7 @@ L2:
*/
if (udas)
- error("user defined attributes not allowed for %s declarations", Token::toChars(tok));
+ error("user-defined attributes not allowed for %s declarations", Token::toChars(tok));
if (token.value == TOKassign)
{
@@ -4221,7 +4302,7 @@ Dsymbol *Parser::parseFunctionLiteral()
parameters = new Parameters();
Identifier *id = Identifier::generateId("__T");
Type *t = new TypeIdentifier(loc, id);
- parameters->push(new Parameter(0, t, token.ident, NULL));
+ parameters->push(new Parameter(0, t, token.ident, NULL, NULL));
tpl = new TemplateParameters();
TemplateParameter *tp = new TemplateTypeParameter(loc, id, NULL, NULL);
@@ -4811,7 +4892,7 @@ Statement *Parser::parseForeach(Loc loc, bool *isRange, bool isDecl)
if (!ai)
error("no identifier for declarator %s", at->toChars());
Larg:
- Parameter *p = new Parameter(storageClass, at, ai, NULL);
+ Parameter *p = new Parameter(storageClass, at, ai, NULL, NULL);
parameters->push(p);
if (token.value == TOKcomma)
{ nextToken();
@@ -5335,14 +5416,14 @@ Statement *Parser::parseStatement(int flags, const utf8_t** endPtr, Loc *pEndloc
Type *at = NULL; // infer parameter type
nextToken();
check(TOKassign);
- param = new Parameter(storageClass, at, ai, NULL);
+ param = new Parameter(storageClass, at, ai, NULL, NULL);
}
else if (isDeclaration(&token, 2, TOKassign, NULL))
{
Identifier *ai;
Type *at = parseType(&ai);
check(TOKassign);
- param = new Parameter(storageClass, at, ai, NULL);
+ param = new Parameter(storageClass, at, ai, NULL, NULL);
}
condition = parseExpression();
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index 4ff07f6..2fe0d9e 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -1494,7 +1494,7 @@ public:
s = new ExpStatement(Loc(), v);
fs->_body = new CompoundStatement(loc, s, fs->_body);
}
- params->push(new Parameter(stc, p->type, id, NULL));
+ params->push(new Parameter(stc, p->type, id, NULL, NULL));
}
// Bugzilla 13840: Throwable nested function inside nothrow function is acceptable.
StorageClass stc = mergeFuncAttrs(STCsafe | STCpure | STCnogc, fs->func);
@@ -1570,15 +1570,15 @@ public:
if (!fdapply[i])
{
params = new Parameters();
- params->push(new Parameter(0, Type::tvoid->pointerTo(), NULL, NULL));
- params->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
+ params->push(new Parameter(0, Type::tvoid->pointerTo(), NULL, NULL, NULL));
+ params->push(new Parameter(STCin, Type::tsize_t, NULL, NULL, NULL));
Parameters* dgparams = new Parameters;
- dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
+ dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL, NULL));
if (dim == 2)
- dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
+ dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL, NULL));
fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams),
Type::tint32, LINKd));
- params->push(new Parameter(0, fldeTy[i], NULL, NULL));
+ params->push(new Parameter(0, fldeTy[i], NULL, NULL, NULL));
fdapply[i] = FuncDeclaration::genCfunc(params, Type::tint32, name[i]);
}
@@ -1637,14 +1637,14 @@ public:
FuncDeclaration *fdapply;
TypeDelegate *dgty;
params = new Parameters();
- params->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL));
+ params->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL, NULL));
Parameters* dgparams = new Parameters;
- dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
+ dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL, NULL));
if (dim == 2)
- dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL));
+ dgparams->push(new Parameter(0, Type::tvoidptr, NULL, NULL, NULL));
dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams),
Type::tint32, LINKd));
- params->push(new Parameter(0, dgty, NULL, NULL));
+ params->push(new Parameter(0, dgty, NULL, NULL, NULL));
fdapply = FuncDeclaration::genCfunc(params, Type::tint32, fdname);
if (tab->ty == Tsarray)
@@ -3192,7 +3192,7 @@ public:
cs->push(new ExpStatement(ss->loc, tmp));
Parameters* args = new Parameters;
- args->push(new Parameter(0, ClassDeclaration::object->type, NULL, NULL));
+ args->push(new Parameter(0, ClassDeclaration::object->type, NULL, NULL, NULL));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter);
Expression *e = new CallExp(ss->loc, new VarExp(ss->loc, fdenter, false), new VarExp(ss->loc, tmp));
@@ -3234,7 +3234,7 @@ public:
cs->push(new ExpStatement(ss->loc, v));
Parameters* args = new Parameters;
- args->push(new Parameter(0, t->pointerTo(), NULL, NULL));
+ args->push(new Parameter(0, t->pointerTo(), NULL, NULL, NULL));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalenter, STCnothrow);
Expression *e = new AddrExp(ss->loc, tmpExp);
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 6585299..2f00c88 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -658,7 +658,8 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
if (e->ident != Id::compiles &&
e->ident != Id::isSame &&
e->ident != Id::identifier &&
- e->ident != Id::getProtection && e->ident != Id::getVisibility)
+ e->ident != Id::getProtection && e->ident != Id::getVisibility &&
+ e->ident != Id::getAttributes)
{
// Pretend we're in a deprecated scope so that deprecation messages
// aren't triggered when checking if a symbol is deprecated
@@ -905,8 +906,12 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
Identifier *id = NULL;
if (Parameter *po = isParameter(o))
{
+ if (!po->ident)
+ {
+ e->error("argument `%s` has no identifier", po->type->toChars());
+ return new ErrorExp();
+ }
id = po->ident;
- assert(id);
}
else
{
@@ -1245,23 +1250,39 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
}
else if (e->ident == Id::getAttributes)
{
+ /* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that
+ * a symbol should not be folded to a constant.
+ * Bit 1 means don't convert Parameter to Type if Parameter has an identifier
+ */
+ if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 3))
+ return new ErrorExp();
+
if (dim != 1)
return dimError(e, 1, dim);
RootObject *o = (*e->args)[0];
+ Parameter *po = isParameter(o);
Dsymbol *s = getDsymbolWithoutExpCtx(o);
- if (!s)
+ UserAttributeDeclaration *udad = NULL;
+ if (po)
{
- e->error("first argument is not a symbol");
- return new ErrorExp();
+ udad = po->userAttribDecl;
}
- if (Import *imp = s->isImport())
+ else if (s)
{
- s = imp->mod;
+ if (Import *imp = s->isImport())
+ {
+ s = imp->mod;
+ }
+ //printf("getAttributes %s, attrs = %p, scope = %p\n", s->toChars(), s->userAttribDecl, s->_scope);
+ udad = s->userAttribDecl;
+ }
+ else
+ {
+ e->error("first argument is not a symbol");
+ return new ErrorExp();
}
- //printf("getAttributes %s, attrs = %p, scope = %p\n", s->toChars(), s->userAttribDecl, s->_scope);
- UserAttributeDeclaration *udad = s->userAttribDecl;
Expressions *exps = udad ? udad->getAttributes() : new Expressions();
TupleExp *tup = new TupleExp(e->loc, exps);
return semantic(tup, sc);