mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 18:40:57 +08:00
d: Support deprecated, @disable, and user-defined attributes on enum members
Reviewed-on: https://github.com/dlang/dmd/pull/12108 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 9bba772fa.
This commit is contained in:
parent
acae7b21bc
commit
7a103daef7
@ -1,4 +1,4 @@
|
||||
e598f69c0726ad1bf6b2e15e0b60d7cead737fad
|
||||
9bba772fa67c6864e551bc87097402f691d947d4
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
@ -155,6 +155,51 @@ int Declaration::checkModify(Loc loc, Scope *sc, Type *, Expression *e1, int fla
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an error if an attempt to call a disabled method is made
|
||||
*
|
||||
* If the declaration is disabled but inside a disabled function,
|
||||
* returns `true` but do not issue an error message.
|
||||
*
|
||||
* Params:
|
||||
* loc = Location information of the call
|
||||
* sc = Scope in which the call occurs
|
||||
* isAliasedDeclaration = if `true` searches overload set
|
||||
*
|
||||
* Returns:
|
||||
* `true` if this `Declaration` is `@disable`d, `false` otherwise.
|
||||
*/
|
||||
bool Declaration::checkDisabled(Loc loc, Scope *sc, bool isAliasedDeclaration)
|
||||
{
|
||||
if (!(storage_class & STCdisable))
|
||||
return false;
|
||||
|
||||
if (sc->func && (sc->func->storage_class & STCdisable))
|
||||
return true;
|
||||
|
||||
Dsymbol *p = toParent();
|
||||
if (p && isPostBlitDeclaration())
|
||||
{
|
||||
p->error(loc, "is not copyable because it is annotated with `@disable`");
|
||||
return true;
|
||||
}
|
||||
|
||||
// if the function is @disabled, maybe there
|
||||
// is an overload in the overload set that isn't
|
||||
if (isAliasedDeclaration)
|
||||
{
|
||||
FuncDeclaration *fd = isFuncDeclaration();
|
||||
if (fd)
|
||||
{
|
||||
for (FuncDeclaration *ovl = fd; ovl; ovl = (FuncDeclaration *)ovl->overnext)
|
||||
if (!(ovl->storage_class & STCdisable))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
error(loc, "cannot be used because it is annotated with `@disable`");
|
||||
return true;
|
||||
}
|
||||
|
||||
Dsymbol *Declaration::search(const Loc &loc, Identifier *ident, int flags)
|
||||
{
|
||||
Dsymbol *s = Dsymbol::search(loc, ident, flags);
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
void semantic(Scope *sc);
|
||||
const char *kind() const;
|
||||
d_uns64 size(Loc loc);
|
||||
bool checkDisabled(Loc loc, Scope *sc, bool isAliasedDeclaration = false);
|
||||
int checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag);
|
||||
|
||||
Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "errors.h"
|
||||
#include "enum.h"
|
||||
#include "attrib.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "id.h"
|
||||
@ -504,6 +505,18 @@ EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *origTyp
|
||||
this->origType = origType;
|
||||
}
|
||||
|
||||
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *memType,
|
||||
StorageClass stc, UserAttributeDeclaration *uad, DeprecatedDeclaration *dd)
|
||||
: VarDeclaration(loc, NULL, id ? id : Id::empty, new ExpInitializer(loc, value))
|
||||
{
|
||||
this->ed = NULL;
|
||||
this->origValue = value;
|
||||
this->origType = memType;
|
||||
this->storage_class = stc;
|
||||
this->userAttribDecl = uad;
|
||||
this->depdecl = dd;
|
||||
}
|
||||
|
||||
Expression *&EnumMember::value()
|
||||
{
|
||||
return ((ExpInitializer*)_init)->exp;
|
||||
@ -536,6 +549,7 @@ void EnumMember::semantic(Scope *sc)
|
||||
return;
|
||||
}
|
||||
assert(ed);
|
||||
|
||||
ed->semantic(sc);
|
||||
if (ed->errors)
|
||||
goto Lerrors;
|
||||
@ -552,8 +566,16 @@ void EnumMember::semantic(Scope *sc)
|
||||
|
||||
protection = ed->isAnonymous() ? ed->protection : Prot(Prot::public_);
|
||||
linkage = LINKd;
|
||||
storage_class = STCmanifest;
|
||||
userAttribDecl = ed->isAnonymous() ? ed->userAttribDecl : NULL;
|
||||
storage_class |= STCmanifest;
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
if (ed->isAnonymous())
|
||||
{
|
||||
if (userAttribDecl)
|
||||
userAttribDecl->userAttribDecl = ed->userAttribDecl;
|
||||
else
|
||||
userAttribDecl = ed->userAttribDecl;
|
||||
}
|
||||
|
||||
// The first enum member is special
|
||||
bool first = (this == (*ed->members)[0]);
|
||||
@ -743,6 +765,14 @@ void EnumMember::semantic(Scope *sc)
|
||||
Expression *EnumMember::getVarExp(Loc loc, Scope *sc)
|
||||
{
|
||||
semantic(sc);
|
||||
if (errors)
|
||||
return new ErrorExp();
|
||||
checkDisabled(loc, sc);
|
||||
|
||||
if (depdecl && !depdecl->_scope)
|
||||
depdecl->_scope = sc;
|
||||
checkDeprecated(loc, sc);
|
||||
|
||||
if (errors)
|
||||
return new ErrorExp();
|
||||
Expression *e = new VarExp(loc, this);
|
||||
|
@ -760,7 +760,7 @@ void Dsymbol::deprecation(const char *format, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
|
||||
bool Dsymbol::checkDeprecated(Loc loc, Scope *sc)
|
||||
{
|
||||
if (global.params.useDeprecated != DIAGNOSTICoff && isDeprecated())
|
||||
{
|
||||
@ -768,17 +768,17 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
|
||||
for (Dsymbol *sp = sc->parent; sp; sp = sp->parent)
|
||||
{
|
||||
if (sp->isDeprecated())
|
||||
goto L1;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Scope *sc2 = sc; sc2; sc2 = sc2->enclosing)
|
||||
{
|
||||
if (sc2->scopesym && sc2->scopesym->isDeprecated())
|
||||
goto L1;
|
||||
return false;
|
||||
|
||||
// If inside a StorageClassDeclaration that is deprecated
|
||||
if (sc2->stc & STCdeprecated)
|
||||
goto L1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *message = NULL;
|
||||
@ -793,20 +793,11 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
|
||||
deprecation(loc, "is deprecated - %s", message);
|
||||
else
|
||||
deprecation(loc, "is deprecated");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
L1:
|
||||
Declaration *d = isDeclaration();
|
||||
if (d && d->storage_class & STCdisable)
|
||||
{
|
||||
if (!(sc->func && sc->func->storage_class & STCdisable))
|
||||
{
|
||||
if (d->toParent() && d->isPostBlitDeclaration())
|
||||
d->toParent()->error(loc, "is not copyable because it is annotated with @disable");
|
||||
else
|
||||
error(loc, "is not callable because it is annotated with @disable");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
|
@ -175,7 +175,7 @@ public:
|
||||
void error(const char *format, ...);
|
||||
void deprecation(Loc loc, const char *format, ...);
|
||||
void deprecation(const char *format, ...);
|
||||
void checkDeprecated(Loc loc, Scope *sc);
|
||||
bool checkDeprecated(Loc loc, Scope *sc);
|
||||
Module *getModule();
|
||||
Module *getAccessModule();
|
||||
Dsymbol *pastMixin();
|
||||
|
@ -85,6 +85,8 @@ public:
|
||||
EnumDeclaration *ed;
|
||||
|
||||
EnumMember(Loc loc, Identifier *id, Expression *value, Type *origType);
|
||||
EnumMember(Loc loc, Identifier *id, Expression *value, Type *memType,
|
||||
StorageClass stc, UserAttributeDeclaration *uad, DeprecatedDeclaration *dd);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
const char *kind() const;
|
||||
void semantic(Scope *sc);
|
||||
|
@ -2344,9 +2344,18 @@ bool Expression::checkArithmetic()
|
||||
return checkValue();
|
||||
}
|
||||
|
||||
void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
|
||||
bool Expression::checkDeprecated(Scope *sc, Dsymbol *s)
|
||||
{
|
||||
s->checkDeprecated(loc, sc);
|
||||
return s->checkDeprecated(loc, sc);
|
||||
}
|
||||
|
||||
bool Expression::checkDisabled(Scope *sc, Dsymbol *s)
|
||||
{
|
||||
if (Declaration *d = s->isDeclaration())
|
||||
{
|
||||
return d->checkDisabled(loc, sc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
@ -2661,11 +2670,8 @@ bool Expression::checkPostblit(Scope *sc, Type *t)
|
||||
StructDeclaration *sd = ((TypeStruct *)t)->sym;
|
||||
if (sd->postblit)
|
||||
{
|
||||
if (sd->postblit->storage_class & STCdisable)
|
||||
{
|
||||
sd->error(loc, "is not copyable because it is annotated with @disable");
|
||||
if (sd->postblit->checkDisabled(loc, sc))
|
||||
return true;
|
||||
}
|
||||
//checkDeprecated(sc, sd->postblit); // necessary?
|
||||
checkPurity(sc, sd->postblit);
|
||||
checkSafety(sc, sd->postblit);
|
||||
@ -3715,14 +3721,22 @@ Lagain:
|
||||
else
|
||||
{
|
||||
if (!s->isFuncDeclaration()) // functions are checked after overloading
|
||||
{
|
||||
s->checkDeprecated(loc, sc);
|
||||
if (d)
|
||||
d->checkDisabled(loc, sc);
|
||||
}
|
||||
|
||||
// Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
|
||||
s = s->toAlias();
|
||||
|
||||
//printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
|
||||
if (s != olds && !s->isFuncDeclaration())
|
||||
{
|
||||
s->checkDeprecated(loc, sc);
|
||||
if (d)
|
||||
d->checkDisabled(loc, sc);
|
||||
}
|
||||
}
|
||||
|
||||
if (EnumMember *em = s->isEnumMember())
|
||||
|
@ -181,7 +181,8 @@ public:
|
||||
bool checkNoBool();
|
||||
bool checkIntegral();
|
||||
bool checkArithmetic();
|
||||
void checkDeprecated(Scope *sc, Dsymbol *s);
|
||||
bool checkDeprecated(Scope *sc, Dsymbol *s);
|
||||
bool checkDisabled(Scope *sc, Dsymbol *s);
|
||||
bool checkPurity(Scope *sc, FuncDeclaration *f);
|
||||
bool checkPurity(Scope *sc, VarDeclaration *v);
|
||||
bool checkSafety(Scope *sc, FuncDeclaration *f);
|
||||
|
@ -1218,6 +1218,7 @@ public:
|
||||
if (!f || f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, f);
|
||||
exp->checkDisabled(sc, f);
|
||||
exp->checkPurity(sc, f);
|
||||
exp->checkSafety(sc, f);
|
||||
exp->checkNogc(sc, f);
|
||||
@ -1246,6 +1247,7 @@ public:
|
||||
if (!f || f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, f);
|
||||
exp->checkDisabled(sc, f);
|
||||
exp->checkPurity(sc, f);
|
||||
exp->checkSafety(sc, f);
|
||||
exp->checkNogc(sc, f);
|
||||
@ -1313,6 +1315,7 @@ public:
|
||||
if (!f || f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, f);
|
||||
exp->checkDisabled(sc, f);
|
||||
exp->checkPurity(sc, f);
|
||||
exp->checkSafety(sc, f);
|
||||
exp->checkNogc(sc, f);
|
||||
@ -1341,6 +1344,7 @@ public:
|
||||
if (!f || f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, f);
|
||||
exp->checkDisabled(sc, f);
|
||||
exp->checkPurity(sc, f);
|
||||
exp->checkSafety(sc, f);
|
||||
exp->checkNogc(sc, f);
|
||||
@ -3214,6 +3218,7 @@ public:
|
||||
}
|
||||
|
||||
exp->checkDeprecated(sc, exp->f);
|
||||
exp->checkDisabled(sc, exp->f);
|
||||
exp->checkPurity(sc, exp->f);
|
||||
exp->checkSafety(sc, exp->f);
|
||||
exp->checkNogc(sc, exp->f);
|
||||
@ -3307,6 +3312,7 @@ public:
|
||||
if (!exp->f || exp->f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, exp->f);
|
||||
exp->checkDisabled(sc, exp->f);
|
||||
exp->checkPurity(sc, exp->f);
|
||||
exp->checkSafety(sc, exp->f);
|
||||
exp->checkNogc(sc, exp->f);
|
||||
@ -3345,6 +3351,7 @@ public:
|
||||
if (!exp->f || exp->f->errors)
|
||||
return setError();
|
||||
exp->checkDeprecated(sc, exp->f);
|
||||
exp->checkDisabled(sc, exp->f);
|
||||
exp->checkPurity(sc, exp->f);
|
||||
exp->checkSafety(sc, exp->f);
|
||||
exp->checkNogc(sc, exp->f);
|
||||
@ -3587,6 +3594,7 @@ public:
|
||||
}
|
||||
|
||||
exp->checkDeprecated(sc, exp->f);
|
||||
exp->checkDisabled(sc, exp->f);
|
||||
exp->checkPurity(sc, exp->f);
|
||||
exp->checkSafety(sc, exp->f);
|
||||
exp->checkNogc(sc, exp->f);
|
||||
@ -8381,6 +8389,7 @@ Expression *semanticY(DotIdExp *exp, Scope *sc, int flag)
|
||||
s = s->toAlias();
|
||||
|
||||
exp->checkDeprecated(sc, s);
|
||||
exp->checkDisabled(sc, s);
|
||||
|
||||
EnumMember *em = s->isEnumMember();
|
||||
if (em)
|
||||
|
@ -1762,10 +1762,10 @@ bool Type::needsNested()
|
||||
|
||||
void Type::checkDeprecated(Loc loc, Scope *sc)
|
||||
{
|
||||
Dsymbol *s = toDsymbol(sc);
|
||||
|
||||
if (s)
|
||||
if (Dsymbol *s = toDsymbol(sc))
|
||||
{
|
||||
s->checkDeprecated(loc, sc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6956,7 +6956,12 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
|
||||
if (d && (d->storage_class & STCtemplateparameter))
|
||||
s = s->toAlias();
|
||||
else
|
||||
s->checkDeprecated(loc, sc); // check for deprecated aliases
|
||||
{
|
||||
// check for deprecated aliases
|
||||
s->checkDeprecated(loc, sc);
|
||||
if (d)
|
||||
d->checkDisabled(loc, sc, true);
|
||||
}
|
||||
|
||||
s = s->toAlias();
|
||||
//printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
|
||||
@ -8045,7 +8050,11 @@ L1:
|
||||
// return noMember(sc, e, ident, flag);
|
||||
}
|
||||
if (!s->isFuncDeclaration()) // because of overloading
|
||||
{
|
||||
s->checkDeprecated(e->loc, sc);
|
||||
if (Declaration *d = s->isDeclaration())
|
||||
d->checkDisabled(e->loc, sc);
|
||||
}
|
||||
s = s->toAlias();
|
||||
|
||||
EnumMember *em = s->isEnumMember();
|
||||
@ -8749,7 +8758,11 @@ L1:
|
||||
// return noMember(sc, e, ident, flag);
|
||||
}
|
||||
if (!s->isFuncDeclaration()) // because of overloading
|
||||
{
|
||||
s->checkDeprecated(e->loc, sc);
|
||||
if (Declaration *d = s->isDeclaration())
|
||||
d->checkDisabled(e->loc, sc);
|
||||
}
|
||||
s = s->toAlias();
|
||||
|
||||
EnumMember *em = s->isEnumMember();
|
||||
|
@ -216,6 +216,24 @@ Lerr:
|
||||
return new Dsymbols();
|
||||
}
|
||||
|
||||
static StorageClass parseDeprecatedAttribute(Parser *p, Expression **msg)
|
||||
{
|
||||
if (p->peekNext() != TOKlparen)
|
||||
return STCdeprecated;
|
||||
|
||||
p->nextToken();
|
||||
p->check(TOKlparen);
|
||||
Expression *e = p->parseAssignExp();
|
||||
p->check(TOKrparen);
|
||||
if (*msg)
|
||||
{
|
||||
p->error("conflicting storage class `deprecated(%s)` and `deprecated(%s)`",
|
||||
(*msg)->toChars(), e->toChars());
|
||||
}
|
||||
*msg = e;
|
||||
return STCundefined;
|
||||
}
|
||||
|
||||
struct PrefixAttributes
|
||||
{
|
||||
StorageClass storageClass;
|
||||
@ -626,21 +644,12 @@ Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl, PrefixAttributes
|
||||
|
||||
case TOKdeprecated:
|
||||
{
|
||||
if (peek(&token)->value != TOKlparen)
|
||||
Expression *e = NULL;
|
||||
if (StorageClass _stc = parseDeprecatedAttribute(this, &pAttrs->depmsg))
|
||||
{
|
||||
stc = STCdeprecated;
|
||||
stc = _stc;
|
||||
goto Lstc;
|
||||
}
|
||||
nextToken();
|
||||
check(TOKlparen);
|
||||
Expression *e = parseAssignExp();
|
||||
check(TOKrparen);
|
||||
if (pAttrs->depmsg)
|
||||
{
|
||||
error("conflicting storage class 'deprecated(%s)' and 'deprecated(%s)'",
|
||||
pAttrs->depmsg->toChars(), e->toChars());
|
||||
}
|
||||
pAttrs->depmsg = e;
|
||||
a = parseBlock(pLastDecl, pAttrs);
|
||||
if (pAttrs->depmsg)
|
||||
{
|
||||
@ -2185,7 +2194,7 @@ EnumDeclaration *Parser::parseEnum()
|
||||
Type *memtype;
|
||||
Loc loc = token.loc;
|
||||
|
||||
//printf("Parser::parseEnum()\n");
|
||||
// printf("Parser::parseEnum()\n");
|
||||
nextToken();
|
||||
if (token.value == TOKidentifier)
|
||||
{
|
||||
@ -2213,36 +2222,96 @@ EnumDeclaration *Parser::parseEnum()
|
||||
nextToken();
|
||||
else if (token.value == TOKlcurly)
|
||||
{
|
||||
bool isAnonymousEnum = !id;
|
||||
|
||||
//printf("enum definition\n");
|
||||
e->members = new Dsymbols();
|
||||
nextToken();
|
||||
const utf8_t *comment = token.blockComment;
|
||||
while (token.value != TOKrcurly)
|
||||
{
|
||||
/* Can take the following forms:
|
||||
/* Can take the following forms...
|
||||
* 1. ident
|
||||
* 2. ident = value
|
||||
* 3. type ident = value
|
||||
* ... prefixed by valid attributes
|
||||
*/
|
||||
|
||||
loc = token.loc;
|
||||
|
||||
Type *type = NULL;
|
||||
Identifier *ident = NULL;
|
||||
Token *tp = peek(&token);
|
||||
if (token.value == TOKidentifier &&
|
||||
(tp->value == TOKassign || tp->value == TOKcomma || tp->value == TOKrcurly))
|
||||
|
||||
Expressions *udas = NULL;
|
||||
StorageClass stc = STCundefined;
|
||||
Expression *deprecationMessage = NULL;
|
||||
|
||||
while (token.value != TOKrcurly &&
|
||||
token.value != TOKcomma &&
|
||||
token.value != TOKassign)
|
||||
{
|
||||
ident = token.ident;
|
||||
type = NULL;
|
||||
nextToken();
|
||||
switch (token.value)
|
||||
{
|
||||
case TOKat:
|
||||
if (StorageClass _stc = parseAttribute(&udas))
|
||||
{
|
||||
if (_stc == STCdisable)
|
||||
stc |= _stc;
|
||||
else
|
||||
{
|
||||
OutBuffer buf;
|
||||
stcToBuffer(&buf, _stc);
|
||||
error("`%s` is not a valid attribute for enum members", buf.peekChars());
|
||||
}
|
||||
nextToken();
|
||||
}
|
||||
break;
|
||||
case TOKdeprecated:
|
||||
if (StorageClass _stc = parseDeprecatedAttribute(this, &deprecationMessage))
|
||||
{
|
||||
stc |= _stc;
|
||||
nextToken();
|
||||
}
|
||||
break;
|
||||
case TOKidentifier:
|
||||
{
|
||||
Token *tp = peek(&token);
|
||||
if (tp->value == TOKassign || tp->value == TOKcomma || tp->value == TOKrcurly)
|
||||
{
|
||||
ident = token.ident;
|
||||
type = NULL;
|
||||
nextToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Ldefault;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Ldefault:
|
||||
if (isAnonymousEnum)
|
||||
{
|
||||
type = parseType(&ident, NULL);
|
||||
if (type == Type::terror)
|
||||
{
|
||||
type = NULL;
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("`%s` is not a valid attribute for enum members", token.toChars());
|
||||
nextToken();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (type && type != Type::terror)
|
||||
{
|
||||
type = parseType(&ident, NULL);
|
||||
if (!ident)
|
||||
error("no identifier for declarator %s", type->toChars());
|
||||
if (id || memtype)
|
||||
if (!isAnonymousEnum)
|
||||
error("type only allowed if anonymous enum and no enum type");
|
||||
}
|
||||
|
||||
@ -2255,11 +2324,22 @@ EnumDeclaration *Parser::parseEnum()
|
||||
else
|
||||
{
|
||||
value = NULL;
|
||||
if (type)
|
||||
if (type && type != Type::terror && isAnonymousEnum)
|
||||
error("if type, there must be an initializer");
|
||||
}
|
||||
|
||||
EnumMember *em = new EnumMember(loc, ident, value, type);
|
||||
UserAttributeDeclaration *uad = NULL;
|
||||
if (udas)
|
||||
uad = new UserAttributeDeclaration(udas, NULL);
|
||||
|
||||
DeprecatedDeclaration *dd = NULL;
|
||||
if (deprecationMessage)
|
||||
{
|
||||
dd = new DeprecatedDeclaration(deprecationMessage, NULL);
|
||||
stc |= STCdeprecated;
|
||||
}
|
||||
|
||||
EnumMember *em = new EnumMember(loc, ident, value, type, stc, uad, dd);
|
||||
e->members->push(em);
|
||||
|
||||
if (token.value == TOKrcurly)
|
||||
|
@ -313,7 +313,6 @@ static Expression *isDsymX(TraitsExp *e, bool (*fp)(Dsymbol *s))
|
||||
return True(e);
|
||||
}
|
||||
|
||||
static bool isFuncDisabled(FuncDeclaration *f) { return f->isDisabled(); }
|
||||
static bool isFuncAbstractFunction(FuncDeclaration *f) { return f->isAbstract(); }
|
||||
static bool isFuncVirtualFunction(FuncDeclaration *f) { return f->isVirtual(); }
|
||||
static bool isFuncVirtualMethod(FuncDeclaration *f) { return f->isVirtualMethod(); }
|
||||
@ -337,6 +336,7 @@ static Expression *isFuncX(TraitsExp *e, bool (*fp)(FuncDeclaration *f))
|
||||
return True(e);
|
||||
}
|
||||
|
||||
static bool isDeclDisabled(Declaration *d) { return d->isDisabled(); }
|
||||
static bool isDeclFuture(Declaration *d) { return d->isFuture(); }
|
||||
static bool isDeclRef(Declaration *d) { return d->isRef(); }
|
||||
static bool isDeclOut(Declaration *d) { return d->isOut(); }
|
||||
@ -811,7 +811,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
|
||||
if (dim != 1)
|
||||
return dimError(e, 1, dim);
|
||||
|
||||
return isFuncX(e, &isFuncDisabled);
|
||||
return isDeclX(e, &isDeclDisabled);
|
||||
}
|
||||
else if (e->ident == Id::isAbstractFunction)
|
||||
{
|
||||
|
17
gcc/testsuite/gdc.test/compilable/test17908.d
Normal file
17
gcc/testsuite/gdc.test/compilable/test17908.d
Normal file
@ -0,0 +1,17 @@
|
||||
// PERMUTE ARGS:
|
||||
|
||||
@disable void foo() {}
|
||||
void foo(int) {}
|
||||
alias g = foo;
|
||||
|
||||
// make sure the order of declaration
|
||||
// doesn't change anything
|
||||
void bar(int) {}
|
||||
@disable void bar() {}
|
||||
alias h = bar;
|
||||
|
||||
void main()
|
||||
{
|
||||
g(10);
|
||||
h(10);
|
||||
}
|
58
gcc/testsuite/gdc.test/compilable/test9701.d
Normal file
58
gcc/testsuite/gdc.test/compilable/test9701.d
Normal file
@ -0,0 +1,58 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
|
||||
template AliasSeq(TList...)
|
||||
{
|
||||
alias AliasSeq = TList;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
uda4,
|
||||
uda5,
|
||||
uda6,
|
||||
uda8,
|
||||
uda9
|
||||
}
|
||||
|
||||
enum Enum
|
||||
{
|
||||
value0,
|
||||
@("uda1") value1,
|
||||
@("uda2", "uda3", 42) value2,
|
||||
@uda4 value3,
|
||||
@uda5 @uda6 value4,
|
||||
@("uda7") @uda8 value5,
|
||||
@uda9 @("uda10") value6,
|
||||
deprecated value7,
|
||||
deprecated("message") value8,
|
||||
}
|
||||
|
||||
@("uda0")
|
||||
enum
|
||||
{
|
||||
value0,
|
||||
@("uda1") value1,
|
||||
@("uda2") @("uda3") value2,
|
||||
@uda4 value3,
|
||||
@uda5 @uda6 value4,
|
||||
@("uda7") @uda8 value5,
|
||||
@uda9 @("uda10") value6
|
||||
}
|
||||
|
||||
static assert(__traits(getAttributes, Enum.value0).length == 0);
|
||||
static assert(__traits(getAttributes, Enum.value1) == AliasSeq!("uda1"));
|
||||
static assert(__traits(getAttributes, Enum.value2) == AliasSeq!("uda2", "uda3", 42));
|
||||
static assert(__traits(getAttributes, Enum.value3) == AliasSeq!(uda4));
|
||||
static assert(__traits(getAttributes, Enum.value4) == AliasSeq!(uda5, uda6));
|
||||
static assert(__traits(getAttributes, Enum.value5) == AliasSeq!("uda7", uda8));
|
||||
static assert(__traits(getAttributes, Enum.value6) == AliasSeq!(uda9, "uda10"));
|
||||
static assert(__traits(isDeprecated, Enum.value7));
|
||||
static assert(__traits(isDeprecated, Enum.value8));
|
||||
|
||||
static assert(__traits(getAttributes, value0) == AliasSeq!("uda0"));
|
||||
static assert(__traits(getAttributes, value1) == AliasSeq!("uda0", "uda1"));
|
||||
static assert(__traits(getAttributes, value2) == AliasSeq!("uda0", "uda2", "uda3"));
|
||||
static assert(__traits(getAttributes, value3) == AliasSeq!("uda0", uda4));
|
||||
static assert(__traits(getAttributes, value4) == AliasSeq!("uda0", uda5, uda6));
|
||||
static assert(__traits(getAttributes, value5) == AliasSeq!("uda0", "uda7", uda8));
|
||||
static assert(__traits(getAttributes, value6) == AliasSeq!("uda0", uda9, "uda10"));
|
43
gcc/testsuite/gdc.test/compilable/vcg-ast.d
Normal file
43
gcc/testsuite/gdc.test/compilable/vcg-ast.d
Normal file
@ -0,0 +1,43 @@
|
||||
module vcg;
|
||||
// REQUIRED_ARGS: -vcg-ast -o-
|
||||
// PERMUTE_ARGS:
|
||||
|
||||
template Seq(A...)
|
||||
{
|
||||
alias Seq = A;
|
||||
}
|
||||
|
||||
auto a = Seq!(1,2,3);
|
||||
|
||||
|
||||
template R(T)
|
||||
{
|
||||
struct _R { T elem; }
|
||||
}
|
||||
|
||||
typeof(R!int._R.elem) x;
|
||||
|
||||
|
||||
static foreach(enum i; 0..3)
|
||||
{
|
||||
mixin("int a" ~ i.stringof ~ " = 1;");
|
||||
}
|
||||
|
||||
void foo()
|
||||
{
|
||||
static foreach(enum i; 0..3)
|
||||
{
|
||||
mixin("int a" ~ i.stringof ~ " = 1;");
|
||||
}
|
||||
}
|
||||
|
||||
class C
|
||||
{
|
||||
invariant {}
|
||||
invariant (true);
|
||||
|
||||
int foo() in{} out{} out(r){} in(true) out(; true) out(r; true)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/disable.d(50): Error: function disable.DisabledOpAssign.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(53): Error: function disable.DisabledPostblit.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(56): Error: function disable.HasDtor.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(60): Error: generated function disable.Nested!(DisabledOpAssign).Nested.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(63): Error: generated function disable.Nested!(DisabledPostblit).Nested.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(66): Error: generated function disable.Nested!(HasDtor).Nested.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(70): Error: generated function disable.NestedDtor!(DisabledOpAssign).NestedDtor.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(73): Error: generated function disable.NestedDtor!(DisabledPostblit).NestedDtor.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(76): Error: generated function disable.NestedDtor!(HasDtor).NestedDtor.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/disable.d(56): Error: function `disable.DisabledOpAssign.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(59): Error: function `disable.DisabledPostblit.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(62): Error: function `disable.HasDtor.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(66): Error: generated function `disable.Nested!(DisabledOpAssign).Nested.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(69): Error: generated function `disable.Nested!(DisabledPostblit).Nested.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(72): Error: generated function `disable.Nested!(HasDtor).Nested.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(76): Error: generated function `disable.NestedDtor!(DisabledOpAssign).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(79): Error: generated function `disable.NestedDtor!(DisabledPostblit).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(82): Error: generated function `disable.NestedDtor!(HasDtor).NestedDtor.opAssign` cannot be used because it is annotated with `@disable`
|
||||
fail_compilation/disable.d(84): Error: enum member `disable.Enum1.value` cannot be used because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
struct DisabledOpAssign {
|
||||
@ -44,6 +45,11 @@ struct NestedDtor (T)
|
||||
~this() {}
|
||||
}
|
||||
|
||||
enum Enum1
|
||||
{
|
||||
@disable value
|
||||
}
|
||||
|
||||
void main ()
|
||||
{
|
||||
DisabledOpAssign o;
|
||||
@ -74,4 +80,6 @@ void main ()
|
||||
|
||||
NestedDtor!(HasDtor) ndd;
|
||||
ndd = NestedDtor!(HasDtor)();
|
||||
|
||||
auto v1 = Enum1.value;
|
||||
}
|
||||
|
@ -43,12 +43,12 @@ void bar() pure @safe
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail10968.d(66): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(67): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(68): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(71): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(72): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(73): Error: struct fail10968.SD is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail10968.d(66): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail10968.d(67): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail10968.d(68): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail10968.d(71): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail10968.d(72): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail10968.d(73): Error: struct fail10968.SD is not copyable because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail11355.d(28): Error: struct fail11355.A is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail11355.d(28): Error: struct fail11355.A is not copyable because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail15044.d(30): Error: generated function fail15044.V.opAssign is not callable because it is annotated with @disable
|
||||
fail_compilation/fail15044.d(30): Error: generated function `fail15044.V.opAssign` cannot be used because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail341.d(26): Error: struct fail341.S is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail341.d(27): Error: function fail341.foo is not callable because it is annotated with @disable
|
||||
fail_compilation/fail341.d(26): Error: struct fail341.S is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail341.d(27): Error: function `fail341.foo` cannot be used because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail9346.d(26): Error: struct fail9346.S is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail9346.d(27): Error: struct fail9346.S is not copyable because it is annotated with @disable
|
||||
fail_compilation/fail9346.d(26): Error: struct fail9346.S is not copyable because it is annotated with `@disable`
|
||||
fail_compilation/fail9346.d(27): Error: struct fail9346.S is not copyable because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_contracts1.d(8): Error: `(identifier) { ... }` or `(identifier; expression)` following `out` expected, not `)`
|
||||
---
|
||||
*/
|
||||
|
||||
void foo() out()){}
|
@ -0,0 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_contracts2.d(8): Error: missing `do { ... }` after `in` or `out`
|
||||
---
|
||||
*/
|
||||
|
||||
void foo()in{}{}
|
14
gcc/testsuite/gdc.test/fail_compilation/fail_contracts3.d
Normal file
14
gcc/testsuite/gdc.test/fail_compilation/fail_contracts3.d
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_contracts3.d(13): Error: function `fail_contracts3.D.foo` cannot have an in contract when overridden function `fail_contracts3.C.foo` does not have an in contract
|
||||
---
|
||||
*/
|
||||
|
||||
class C {
|
||||
void foo(){}
|
||||
}
|
||||
|
||||
class D : C {
|
||||
override void foo()in{}do{}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_contracts4.d(8): Error: missing `do { ... }` for function literal
|
||||
---
|
||||
*/
|
||||
|
||||
enum x = delegate int()in(true) out(;true) out(r; true) in{} out(r){};
|
15
gcc/testsuite/gdc.test/fail_compilation/test17908a.d
Normal file
15
gcc/testsuite/gdc.test/fail_compilation/test17908a.d
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test17908a.d(10): Error: function `test17908a.foo` cannot be used because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
|
||||
@disable void foo();
|
||||
@disable void foo(int) {}
|
||||
alias g = foo;
|
||||
|
||||
void main()
|
||||
{
|
||||
g(10);
|
||||
}
|
14
gcc/testsuite/gdc.test/fail_compilation/test17908b.d
Normal file
14
gcc/testsuite/gdc.test/fail_compilation/test17908b.d
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test17908b.d(13): Error: function `test17908b.foobar` cannot be used because it is annotated with `@disable`
|
||||
---
|
||||
*/
|
||||
void foobar() {}
|
||||
@disable void foobar(int) {}
|
||||
alias i = foobar;
|
||||
|
||||
void main()
|
||||
{
|
||||
i(10);
|
||||
}
|
63
gcc/testsuite/gdc.test/fail_compilation/test9701.d
Normal file
63
gcc/testsuite/gdc.test/fail_compilation/test9701.d
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
TEST_OUTPUT
|
||||
---
|
||||
fail_compilation/test9701.d(38): Error: `@safe` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(39): Error: `@system` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(40): Error: `@trusted` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(41): Error: `@nogc` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(42): Error: `pure` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(43): Error: `shared` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(44): Error: `inout` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(45): Error: `immutable` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(46): Error: `const` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(47): Error: `synchronized` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(48): Error: `scope` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(49): Error: `auto` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(50): Error: `ref` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(51): Error: `__gshared` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(52): Error: `final` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(53): Error: `extern` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(54): Error: `export` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(55): Error: `nothrow` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(56): Error: `public` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(57): Error: `private` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(58): Error: `package` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(59): Error: `static` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(60): Error: `static` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(61): Error: `static` is not a valid attribute for enum members
|
||||
fail_compilation/test9701.d(62): Error: `static` is not a valid attribute for enum members
|
||||
---
|
||||
*/
|
||||
|
||||
// This test exists to verify that parsing of enum member attributes rejects invalid attributes
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
|
||||
enum Enum
|
||||
{
|
||||
@safe safe,
|
||||
@system system,
|
||||
@trusted trusted,
|
||||
@nogc nogc,
|
||||
pure pure_,
|
||||
shared shared_,
|
||||
inout inout_,
|
||||
immutable immutable_,
|
||||
const const_,
|
||||
synchronized synchronized_,
|
||||
scope scope_,
|
||||
auto auto_,
|
||||
ref ref_,
|
||||
__gshared __gshared_,
|
||||
final final_,
|
||||
extern extern_,
|
||||
export export_,
|
||||
nothrow nothrow_,
|
||||
public public_,
|
||||
private private_,
|
||||
package package_,
|
||||
static static1,
|
||||
@("a") static static2,
|
||||
static @("a") static3,
|
||||
@("a") static @("b") static3,
|
||||
}
|
22
gcc/testsuite/gdc.test/fail_compilation/test9701b.d
Normal file
22
gcc/testsuite/gdc.test/fail_compilation/test9701b.d
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
REQUIRED_ARGS: -de
|
||||
TEST_OUTPUT
|
||||
---
|
||||
fail_compilation/test9701b.d(20): Deprecation: enum member `test9701b.Enum.e0` is deprecated
|
||||
fail_compilation/test9701b.d(21): Deprecation: enum member `test9701b.Enum.e1` is deprecated - message
|
||||
---
|
||||
*/
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=9701
|
||||
|
||||
enum Enum
|
||||
{
|
||||
deprecated e0,
|
||||
deprecated("message") e1,
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
auto value = Enum.e0;
|
||||
auto value2 = Enum.e1;
|
||||
}
|
57
gcc/testsuite/gdc.test/fail_compilation/udaparams.d
Normal file
57
gcc/testsuite/gdc.test/fail_compilation/udaparams.d
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/udaparams.d(31): Error: variadic parameter cannot have user-defined attributes
|
||||
fail_compilation/udaparams.d(32): Error: variadic parameter cannot have user-defined attributes
|
||||
fail_compilation/udaparams.d(34): Error: user-defined attributes cannot appear as postfixes
|
||||
fail_compilation/udaparams.d(35): Error: user-defined attributes cannot appear as postfixes
|
||||
fail_compilation/udaparams.d(36): Error: user-defined attributes cannot appear as postfixes
|
||||
fail_compilation/udaparams.d(38): Error: `@safe` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(39): Error: `@safe` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(40): Error: `@safe` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(43): Error: `@system` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(44): Error: `@trusted` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(45): Error: `@nogc` attribute for function parameter is not supported
|
||||
fail_compilation/udaparams.d(51): Error: Cannot put a storage-class in an alias declaration.
|
||||
fail_compilation/udaparams.d(52): Error: Cannot put a storage-class in an alias declaration.
|
||||
fail_compilation/udaparams.d(53): Error: semicolon expected to close `alias` declaration
|
||||
fail_compilation/udaparams.d(53): Error: declaration expected, not `=>`
|
||||
fail_compilation/udaparams.d(54): Error: semicolon expected to close `alias` declaration
|
||||
fail_compilation/udaparams.d(54): Error: declaration expected, not `=>`
|
||||
fail_compilation/udaparams.d(57): Error: basic type expected, not `@`
|
||||
fail_compilation/udaparams.d(57): Error: identifier expected for template value parameter
|
||||
fail_compilation/udaparams.d(57): Error: found `@` when expecting `)`
|
||||
fail_compilation/udaparams.d(57): Error: basic type expected, not `3`
|
||||
fail_compilation/udaparams.d(57): Error: found `3` when expecting `)`
|
||||
fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration
|
||||
fail_compilation/udaparams.d(57): Error: declaration expected, not `)`
|
||||
---
|
||||
*/
|
||||
|
||||
void vararg1(int a, @(10) ...);
|
||||
extern(C) void vararg2(int a, @(10) ...);
|
||||
|
||||
void rhsuda(int a @(10));
|
||||
void rhsuda2(int @(10));
|
||||
void rhsuda3(int[] arr @(10) ...);
|
||||
|
||||
void wrongAttr1(@safe int);
|
||||
void wrongAttr2(@safe void function());
|
||||
void wrongAttr3(@safe void delegate());
|
||||
|
||||
|
||||
void test16(A)(A a @system);
|
||||
void test16(A)(A a @trusted);
|
||||
void test16(A)(A a @nogc);
|
||||
|
||||
// lambdas without parentheses
|
||||
alias test19a = @safe b => 1 + 2;
|
||||
alias test19b = @system b => 1 + 2;
|
||||
alias test19c = @nogc b => 1 + 2;
|
||||
alias test19d = @(2) @system b => 1 + 2;
|
||||
alias test19e = @safe @(2) b => 1 + 2;
|
||||
alias test19f = extern(C++) b => 1 + 2;
|
||||
alias test19g = align(2) b => 1 + 2;
|
||||
|
||||
// UDAs on Template parameter aren't supported
|
||||
void test21(@(3) T)(T t) {}
|
Loading…
x
Reference in New Issue
Block a user