Skip to content

Commit

Permalink
accept @pure @nothrow @return attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jan 26, 2015
1 parent 6e5d1c9 commit 2deb407
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 37 deletions.
85 changes: 48 additions & 37 deletions src/parse.c
Expand Up @@ -138,8 +138,9 @@ Dsymbols *Parser::parseModule()
Expressions *exps = NULL;
StorageClass stc = parseAttribute(&exps);

if (stc == STCproperty || stc == STCnogc || stc == STCdisable ||
stc == STCsafe || stc == STCtrusted || stc == STCsystem)
if (stc & (STCproperty | STCnogc | STCdisable |
STCsafe | STCtrusted | STCsystem |
STCpure | STCnothrow | STCreturn))
{
error("@%s attribute for module declaration is not supported", token.toChars());
}
Expand Down Expand Up @@ -986,45 +987,51 @@ StorageClass Parser::parseAttribute(Expressions **pudas)
nextToken();
Expressions *udas = NULL;
StorageClass stc = 0;
if (token.value == TOKidentifier)
switch (token.value)
{
if (token.ident == Id::property)
stc = STCproperty;
else if (token.ident == Id::nogc)
stc = STCnogc;
else if (token.ident == Id::safe)
stc = STCsafe;
else if (token.ident == Id::trusted)
stc = STCtrusted;
else if (token.ident == Id::system)
stc = STCsystem;
else if (token.ident == Id::disable)
stc = STCdisable;
else
{
// Allow identifier, template instantiation, or function call
Expression *exp = parsePrimaryExp();
if (token.value == TOKlparen)
case TOKidentifier:
if (token.ident == Id::property)
stc = STCproperty;
else if (token.ident == Id::nogc)
stc = STCnogc;
else if (token.ident == Id::safe)
stc = STCsafe;
else if (token.ident == Id::trusted)
stc = STCtrusted;
else if (token.ident == Id::system)
stc = STCsystem;
else if (token.ident == Id::disable)
stc = STCdisable;
else
{
Loc loc = token.loc;
exp = new CallExp(loc, exp, parseArguments());
// Allow identifier, template instantiation, or function call
Expression *exp = parsePrimaryExp();
if (token.value == TOKlparen)
{
Loc loc = token.loc;
exp = new CallExp(loc, exp, parseArguments());
}

udas = new Expressions();
udas->push(exp);
}
break;

udas = new Expressions();
udas->push(exp);
}
}
else if (token.value == TOKlparen)
{
// @( ArgumentList )
// Concatenate with existing
if (peekNext() == TOKrparen)
error("empty attribute list is not allowed");
udas = parseArguments();
}
else
{
error("@identifier or @(ArgumentList) expected, not @%s", token.toChars());
case TOKlparen:
// @( ArgumentList )
// Concatenate with existing
if (peekNext() == TOKrparen)
error("empty attribute list is not allowed");
udas = parseArguments();
break;

case TOKpure: stc = STCpure; break;
case TOKnothrow: stc = STCnothrow; break;
case TOKreturn: stc = STCreturn; break;

default:
error("@identifier or @(ArgumentList) expected, not @%s", token.toChars());
break;
}

if (stc)
Expand Down Expand Up @@ -6202,6 +6209,10 @@ bool Parser::skipAttributes(Token *t, Token **pt)
break;
case TOKat:
t = peek(t);
if (t->value == TOKpure ||
t->value == TOKnothrow ||
t->value == TOKreturn)
break;
if (t->value == TOKidentifier)
{
/* @identifier
Expand Down
9 changes: 9 additions & 0 deletions test/runnable/mars1.d
Expand Up @@ -1252,6 +1252,15 @@ void test13784()
}


////////////////////////////////////////////////////////////////////////

struct At
{
@property auto info() @safe @nothrow @pure @return const { return this; }

@pure @nothrow @return ref int info2(ref int x) { return x; }
}

////////////////////////////////////////////////////////////////////////

int main()
Expand Down

0 comments on commit 2deb407

Please sign in to comment.