diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-01-07 18:03:33 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-01-07 18:22:36 +0100 |
commit | dddea6d4d81cac76ff64cde178e2d5f7fe09fb55 (patch) | |
tree | f8c2345d5a980c6523798c1388a777e05fdaf500 /gcc/d/dmd/parse.c | |
parent | d54029179cbe817eaf9b6899339b0151cff3c00e (diff) | |
download | gcc-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.c | 113 |
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(); |