Skip to content

Commit

Permalink
Set prefix attributes in storage_class of (Unittest|New|Delete)Declar…
Browse files Browse the repository at this point in the history
…ation

Partially fix issue 8081.
  • Loading branch information
9rnsr committed Oct 5, 2014
1 parent 9c7b5ba commit 067d3bc
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 64 deletions.
6 changes: 3 additions & 3 deletions src/declaration.h
Expand Up @@ -840,7 +840,7 @@ class UnitTestDeclaration : public FuncDeclaration
// toObjFile() these nested functions after this one
FuncDeclarations deferredNested;

UnitTestDeclaration(Loc loc, Loc endloc, char *codedoc);
UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
AggregateDeclaration *isThis();
Expand All @@ -858,7 +858,7 @@ class NewDeclaration : public FuncDeclaration
Parameters *arguments;
int varargs;

NewDeclaration(Loc loc, Loc endloc, Parameters *arguments, int varargs);
NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, int varargs);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
const char *kind();
Expand All @@ -876,7 +876,7 @@ class DeleteDeclaration : public FuncDeclaration
public:
Parameters *arguments;

DeleteDeclaration(Loc loc, Loc endloc, Parameters *arguments);
DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
const char *kind();
Expand Down
28 changes: 14 additions & 14 deletions src/func.c
Expand Up @@ -4949,16 +4949,16 @@ static Identifier *unitTestId(Loc loc)
return Lexer::uniqueId(buf.peekString());
}

UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc, char *codedoc)
: FuncDeclaration(loc, endloc, unitTestId(loc), STCundefined, NULL)
UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc)
: FuncDeclaration(loc, endloc, unitTestId(loc), stc, NULL)
{
this->codedoc = codedoc;
}

Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
{
assert(!s);
UnitTestDeclaration *utd = new UnitTestDeclaration(loc, endloc, codedoc);
UnitTestDeclaration *utd = new UnitTestDeclaration(loc, endloc, storage_class, codedoc);
return FuncDeclaration::syntaxCopy(utd);
}

Expand All @@ -4978,7 +4978,7 @@ void UnitTestDeclaration::semantic(Scope *sc)
if (global.params.useUnitTests)
{
if (!type)
type = new TypeFunction(NULL, Type::tvoid, false, LINKd);
type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
Scope *sc2 = sc->push();
sc2->linkage = LINKd;
FuncDeclaration::semantic(sc2);
Expand Down Expand Up @@ -5023,8 +5023,8 @@ bool UnitTestDeclaration::addPostInvariant()

/********************************* NewDeclaration ****************************/

NewDeclaration::NewDeclaration(Loc loc, Loc endloc, Parameters *arguments, int varargs)
: FuncDeclaration(loc, endloc, Id::classNew, STCstatic, NULL)
NewDeclaration::NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, int varargs)
: FuncDeclaration(loc, endloc, Id::classNew, STCstatic | stc, NULL)
{
this->arguments = arguments;
this->varargs = varargs;
Expand All @@ -5033,8 +5033,8 @@ NewDeclaration::NewDeclaration(Loc loc, Loc endloc, Parameters *arguments, int v
Dsymbol *NewDeclaration::syntaxCopy(Dsymbol *s)
{
assert(!s);
NewDeclaration *f = new NewDeclaration(loc, endloc, NULL, varargs);
f->arguments = Parameter::arraySyntaxCopy(arguments);
NewDeclaration *f = new NewDeclaration(loc, endloc,
storage_class, Parameter::arraySyntaxCopy(arguments), varargs);
return FuncDeclaration::syntaxCopy(f);
}

Expand All @@ -5057,7 +5057,7 @@ void NewDeclaration::semantic(Scope *sc)
}
Type *tret = Type::tvoid->pointerTo();
if (!type)
type = new TypeFunction(arguments, tret, varargs, LINKd);
type = new TypeFunction(arguments, tret, varargs, LINKd, storage_class);

type = type->semantic(loc, sc);
assert(type->ty == Tfunction);
Expand Down Expand Up @@ -5100,17 +5100,17 @@ bool NewDeclaration::addPostInvariant()

/********************************* DeleteDeclaration ****************************/

DeleteDeclaration::DeleteDeclaration(Loc loc, Loc endloc, Parameters *arguments)
: FuncDeclaration(loc, endloc, Id::classDelete, STCstatic, NULL)
DeleteDeclaration::DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments)
: FuncDeclaration(loc, endloc, Id::classDelete, STCstatic | stc, NULL)
{
this->arguments = arguments;
}

Dsymbol *DeleteDeclaration::syntaxCopy(Dsymbol *s)
{
assert(!s);
DeleteDeclaration *f = new DeleteDeclaration(loc, endloc, NULL);
f->arguments = Parameter::arraySyntaxCopy(arguments);
DeleteDeclaration *f = new DeleteDeclaration(loc, endloc,
storage_class, Parameter::arraySyntaxCopy(arguments));
return FuncDeclaration::syntaxCopy(f);
}

Expand All @@ -5132,7 +5132,7 @@ void DeleteDeclaration::semantic(Scope *sc)
error("new allocators only are for class or struct definitions");
}
if (!type)
type = new TypeFunction(arguments, Type::tvoid, 0, LINKd);
type = new TypeFunction(arguments, Type::tvoid, 0, LINKd, storage_class);

type = type->semantic(loc, sc);
assert(type->ty == Tfunction);
Expand Down
14 changes: 10 additions & 4 deletions src/hdrgen.c
Expand Up @@ -1828,22 +1828,24 @@ class PrettyPrintVisitor : public Visitor

void visit(StaticCtorDeclaration *d)
{
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class & ~STCstatic);
if (d->isSharedStaticCtorDeclaration())
buf->writestring("shared ");
buf->writestring("static this()");
if (hgs->hdrgen && !hgs->tpltMember)
{
buf->writestring("static this();");
buf->writeByte(';');
buf->writenl();
return;
}
buf->writestring("static this()");
bodyToBuffer(d);
else
bodyToBuffer(d);
}

void visit(StaticDtorDeclaration *d)
{
if (hgs->hdrgen)
return;
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class & ~STCstatic);
if (d->isSharedStaticDtorDeclaration())
buf->writestring("shared ");
buf->writestring("static ~this()");
Expand All @@ -1854,6 +1856,7 @@ class PrettyPrintVisitor : public Visitor
{
if (hgs->hdrgen)
return;
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class);
buf->writestring("invariant");
bodyToBuffer(d);
}
Expand All @@ -1862,19 +1865,22 @@ class PrettyPrintVisitor : public Visitor
{
if (hgs->hdrgen)
return;
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class);
buf->writestring("unittest");
bodyToBuffer(d);
}

void visit(NewDeclaration *d)
{
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class & ~STCstatic);
buf->writestring("new");
parametersToBuffer(d->arguments, d->varargs);
bodyToBuffer(d);
}

void visit(DeleteDeclaration *d)
{
StorageClassDeclaration::stcToCBuffer(buf, d->storage_class & ~STCstatic);
buf->writestring("delete");
parametersToBuffer(d->arguments, 0);
bodyToBuffer(d);
Expand Down
66 changes: 37 additions & 29 deletions src/parse.c
Expand Up @@ -404,7 +404,7 @@ Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl, PrefixAttributes
{
// invariant {}
// invariant() {}
s = parseInvariant();
s = parseInvariant(pAttrs);
}
else
{
Expand All @@ -415,17 +415,17 @@ Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl, PrefixAttributes
}

case TOKunittest:
s = parseUnitTest();
s = parseUnitTest(pAttrs);
if (*pLastDecl)
(*pLastDecl)->ddocUnittest = (UnitTestDeclaration *)s;
break;

case TOKnew:
s = parseNew();
s = parseNew(pAttrs);
break;

case TOKdelete:
s = parseDelete();
s = parseDelete(pAttrs);
break;

case TOKcolon:
Expand Down Expand Up @@ -1764,10 +1764,10 @@ Dsymbol *Parser::parseSharedStaticDtor(PrefixAttributes *pAttrs)
* Current token is 'invariant'.
*/

InvariantDeclaration *Parser::parseInvariant()
Dsymbol *Parser::parseInvariant(PrefixAttributes *pAttrs)
{
InvariantDeclaration *f;
Loc loc = token.loc;
StorageClass stc = pAttrs ? pAttrs->storageClass : STCundefined;

nextToken();
if (token.value == TOKlparen) // optional ()
Expand All @@ -1776,7 +1776,9 @@ InvariantDeclaration *Parser::parseInvariant()
check(TOKrparen);
}

f = new InvariantDeclaration(loc, Loc(), STCundefined);
InvariantDeclaration *f = new InvariantDeclaration(loc, Loc(), stc);
if (pAttrs)
pAttrs->storageClass = STCundefined;
f->fbody = parseStatement(PScurly);
return f;
}
Expand All @@ -1787,16 +1789,16 @@ InvariantDeclaration *Parser::parseInvariant()
* Current token is 'unittest'.
*/

UnitTestDeclaration *Parser::parseUnitTest()
Dsymbol *Parser::parseUnitTest(PrefixAttributes *pAttrs)
{
UnitTestDeclaration *f;
Statement *body;
Loc loc = token.loc;
StorageClass stc = pAttrs ? pAttrs->storageClass : STCundefined;

nextToken();

const utf8_t *begPtr = token.ptr + 1; // skip '{'
const utf8_t *endPtr = NULL;
body = parseStatement(PScurly, &endPtr);
Statement *sbody = parseStatement(PScurly, &endPtr);

/** Extract unittest body as a string. Must be done eagerly since memory
will be released by the lexer before doc gen. */
Expand All @@ -1820,8 +1822,10 @@ UnitTestDeclaration *Parser::parseUnitTest()
}
}

f = new UnitTestDeclaration(loc, token.loc, docline);
f->fbody = body;
UnitTestDeclaration *f = new UnitTestDeclaration(loc, token.loc, stc, docline);
if (pAttrs)
pAttrs->storageClass = STCundefined;
f->fbody = sbody;
return f;
}

Expand All @@ -1831,18 +1835,20 @@ UnitTestDeclaration *Parser::parseUnitTest()
* Current token is 'new'.
*/

NewDeclaration *Parser::parseNew()
Dsymbol *Parser::parseNew(PrefixAttributes *pAttrs)
{
NewDeclaration *f;
Parameters *arguments;
int varargs;
Loc loc = token.loc;
StorageClass stc = pAttrs ? pAttrs->storageClass : STCundefined;

nextToken();
arguments = parseParameters(&varargs);
f = new NewDeclaration(loc, Loc(), arguments, varargs);
parseContracts(f);
return f;

int varargs;
Parameters *arguments = parseParameters(&varargs);
NewDeclaration *f = new NewDeclaration(loc, Loc(), stc, arguments, varargs);
if (pAttrs)
pAttrs->storageClass = STCundefined;
Dsymbol *s = parseContracts(f);
return s;
}

/*****************************************
Expand All @@ -1851,20 +1857,22 @@ NewDeclaration *Parser::parseNew()
* Current token is 'delete'.
*/

DeleteDeclaration *Parser::parseDelete()
Dsymbol *Parser::parseDelete(PrefixAttributes *pAttrs)
{
DeleteDeclaration *f;
Parameters *arguments;
int varargs;
Loc loc = token.loc;
StorageClass stc = pAttrs ? pAttrs->storageClass : STCundefined;

nextToken();
arguments = parseParameters(&varargs);

int varargs;
Parameters *arguments = parseParameters(&varargs);
if (varargs)
error("... not allowed in delete function parameter list");
f = new DeleteDeclaration(loc, Loc(), arguments);
parseContracts(f);
return f;
DeleteDeclaration *f = new DeleteDeclaration(loc, Loc(), stc, arguments);
if (pAttrs)
pAttrs->storageClass = STCundefined;
Dsymbol *s = parseContracts(f);
return s;
}

/**********************************************
Expand Down
8 changes: 4 additions & 4 deletions src/parse.h
Expand Up @@ -103,10 +103,10 @@ class Parser : public Lexer
Dsymbol *parseStaticDtor(PrefixAttributes *pAttrs);
Dsymbol *parseSharedStaticCtor(PrefixAttributes *pAttrs);
Dsymbol *parseSharedStaticDtor(PrefixAttributes *pAttrs);
InvariantDeclaration *parseInvariant();
UnitTestDeclaration *parseUnitTest();
NewDeclaration *parseNew();
DeleteDeclaration *parseDelete();
Dsymbol *parseInvariant(PrefixAttributes *pAttrs);
Dsymbol *parseUnitTest(PrefixAttributes *pAttrs);
Dsymbol *parseNew(PrefixAttributes *pAttrs);
Dsymbol *parseDelete(PrefixAttributes *pAttrs);
Parameters *parseParameters(int *pvarargs, TemplateParameters **tpl = NULL);
EnumDeclaration *parseEnum();
Dsymbol *parseAggregate();
Expand Down
16 changes: 16 additions & 0 deletions test/compilable/extra-files/header1.d
Expand Up @@ -158,6 +158,16 @@ static ~this()
{
}

pure nothrow @safe @nogc static this() {}
pure nothrow @safe @nogc static ~this() {}
static this() pure nothrow @safe @nogc {}
static ~this() pure nothrow @safe @nogc {}

pure nothrow @safe @nogc shared static this() {}
pure nothrow @safe @nogc shared static ~this() {}
shared static this() pure nothrow @safe @nogc {}
shared static ~this() pure nothrow @safe @nogc {}

interface iFoo{}
class xFoo: iFoo{}

Expand Down Expand Up @@ -222,6 +232,12 @@ class Test
alias A!(short) getHShort;
alias A!(ushort) getHUShort;
alias A!(real) getHReal;

pure nothrow @safe @nogc unittest {}
pure nothrow @safe @nogc invariant {}

pure nothrow @safe @nogc new (size_t sz) { return null; }
pure nothrow @safe @nogc delete (void* p) { }
}

template templ( T )
Expand Down
8 changes: 6 additions & 2 deletions test/compilable/extra-files/header1.di
Expand Up @@ -133,6 +133,10 @@ template Foo(T, int V)
}
}
static this();
nothrow pure @nogc @safe static this();
nothrow pure @nogc @safe static this();
nothrow pure @nogc @safe shared static this();
nothrow pure @nogc @safe shared static this();
interface iFoo
{
}
Expand Down Expand Up @@ -199,6 +203,8 @@ class Test
alias A!short getHShort;
alias A!ushort getHUShort;
alias A!real getHReal;
nothrow pure @nogc @safe new(size_t sz);
nothrow pure @nogc @safe delete(void* p);
}
void templ(T)(T val)
{
Expand Down Expand Up @@ -314,8 +320,6 @@ void foo6591()()
}
version (unittest)
{
nothrow pure {}
nothrow pure {}
public {}
extern (C) {}
align{}
Expand Down

0 comments on commit 067d3bc

Please sign in to comment.