aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/parse.c
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/parse.c
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/parse.c')
-rw-r--r--gcc/d/dmd/parse.c113
1 files changed, 97 insertions, 16 deletions
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();