Showing with 189 additions and 162 deletions.
  1. +0 −89 src/attrib.c
  2. +0 −2 src/attrib.h
  3. +14 −19 src/declaration.c
  4. +120 −18 src/hdrgen.c
  5. +2 −0 src/hdrgen.h
  6. +5 −1 src/import.c
  7. +3 −14 src/json.c
  8. +2 −0 src/magicport.json
  9. +5 −15 src/parse.c
  10. +1 −1 test/fail_compilation/fail170.d
  11. +1 −1 test/fail_compilation/fail179.d
  12. +2 −2 test/fail_compilation/fail180.d
  13. +34 −0 test/fail_compilation/failattr.d
89 changes: 0 additions & 89 deletions src/attrib.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,95 +394,6 @@ Scope *StorageClassDeclaration::newScope(Scope *sc)
return createNewScope(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign, sc->inlining);
}

/*************************************************
* Pick off one of the storage classes from stc,
* and return a pointer to a string representation of it.
* stc is reduced by the one picked.
* tmp[] is a buffer big enough to hold that string.
*/
const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
{
struct SCstring
{
StorageClass stc;
TOK tok;
const char *id;
};

static SCstring table[] =
{
{ STCauto, TOKauto },
{ STCscope, TOKscope },
{ STCstatic, TOKstatic },
{ STCextern, TOKextern },
{ STCconst, TOKconst },
{ STCfinal, TOKfinal },
{ STCabstract, TOKabstract },
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
{ STCoverride, TOKoverride },
{ STClazy, TOKlazy },
{ STCalias, TOKalias },
{ STCout, TOKout },
{ STCin, TOKin },
{ STCmanifest, TOKenum },
{ STCimmutable, TOKimmutable },
{ STCshared, TOKshared },
{ STCnothrow, TOKnothrow },
{ STCwild, TOKwild },
{ STCpure, TOKpure },
{ STCref, TOKref },
{ STCtls },
{ STCgshared, TOKgshared },
{ STCnogc, TOKat, "nogc" },
{ STCproperty, TOKat, "property" },
{ STCsafe, TOKat, "safe" },
{ STCtrusted, TOKat, "trusted" },
{ STCsystem, TOKat, "system" },
{ STCdisable, TOKat, "disable" },
{ 0, TOKreserved }
};

for (int i = 0; table[i].stc; i++)
{
StorageClass tbl = table[i].stc;
assert(tbl & STCStorageClass);
if (stc & tbl)
{
stc &= ~tbl;
if (tbl == STCtls) // TOKtls was removed
return "__thread";

TOK tok = table[i].tok;
if (tok == TOKat)
{
tmp[0] = '@';
strcpy(tmp + 1, table[i].id);
return tmp;
}
else
return Token::toChars(tok);
}
}
//printf("stc = %llx\n", (unsigned long long)stc);
return NULL;
}

void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
{
while (stc)
{
const size_t BUFFER_LEN = 20;
char tmp[BUFFER_LEN];
const char *p = stcToChars(tmp, stc);
if (!p)
break;
assert(strlen(p) < BUFFER_LEN);
buf->writestring(p);
buf->writeByte(' ');
}
}

/********************************* DeprecatedDeclaration ****************************/

DeprecatedDeclaration::DeprecatedDeclaration(Expression *msg, Dsymbols *decl)
Expand Down
2 changes: 0 additions & 2 deletions src/attrib.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class StorageClassDeclaration : public AttribDeclaration
Scope *newScope(Scope *sc);
bool oneMember(Dsymbol **ps, Identifier *ident);

static const char *stcToChars(char tmp[], StorageClass& stc);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
void accept(Visitor *v) { v->visit(this); }
};

Expand Down
33 changes: 14 additions & 19 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "statement.h"
#include "ctfe.h"
#include "target.h"
#include "hdrgen.h"

/************************************
* Check to see the aggregate type is nested and its context pointer is
Expand Down Expand Up @@ -826,9 +827,10 @@ void VarDeclaration::semantic(Scope *sc)
scope = NULL;
}

/* Pick up storage classes from context, but skip synchronized
/* Pick up storage classes from context, but except synchronized,
* override, abstract, and final.
*/
storage_class |= (sc->stc & ~STCsynchronized);
storage_class |= (sc->stc & ~(STCsynchronized | STCoverride | STCabstract | STCfinal));
if (storage_class & STCextern && init)
error("extern symbols cannot have initializers");

Expand Down Expand Up @@ -1133,24 +1135,17 @@ void VarDeclaration::semantic(Scope *sc)
else if (type->isWild())
storage_class |= STCwild;

if (storage_class & (STCmanifest | STCstatic | STCgshared))
if (StorageClass stc = storage_class & (STCsynchronized | STCoverride | STCabstract | STCfinal))
{
}
else if (isSynchronized())
{
error("variable %s cannot be synchronized", toChars());
}
else if (isOverride())
{
error("override cannot be applied to variable");
}
else if (isAbstract())
{
error("abstract cannot be applied to variable");
}
else if (storage_class & STCfinal)
{
error("final cannot be applied to variable, perhaps you meant const?");
if (stc == STCfinal)
error("cannot be final, perhaps you meant const?");
else
{
OutBuffer buf;
stcToBuffer(&buf, stc);
error("cannot be %s", buf.peekString());
}
storage_class &= ~stc; // strip off
}

if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
Expand Down
Loading