aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-01-07 22:00:24 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-01-09 23:45:46 +0100
commit7a103daef78a8f9fc9b2af7c28123f25e8fa7163 (patch)
tree39e4a1d02b2f424b4d77c4e0b0cdff875467e41d /gcc/d
parentacae7b21bc026150c2c01465e4ab0eacb20bd44d (diff)
downloadgcc-7a103daef78a8f9fc9b2af7c28123f25e8fa7163.zip
gcc-7a103daef78a8f9fc9b2af7c28123f25e8fa7163.tar.gz
gcc-7a103daef78a8f9fc9b2af7c28123f25e8fa7163.tar.bz2
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.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/declaration.c45
-rw-r--r--gcc/d/dmd/declaration.h1
-rw-r--r--gcc/d/dmd/denum.c34
-rw-r--r--gcc/d/dmd/dsymbol.c23
-rw-r--r--gcc/d/dmd/dsymbol.h2
-rw-r--r--gcc/d/dmd/enum.h2
-rw-r--r--gcc/d/dmd/expression.c26
-rw-r--r--gcc/d/dmd/expression.h3
-rw-r--r--gcc/d/dmd/expressionsem.c9
-rw-r--r--gcc/d/dmd/mtype.c21
-rw-r--r--gcc/d/dmd/parse.c132
-rw-r--r--gcc/d/dmd/traits.c4
13 files changed, 245 insertions, 59 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index f6c8f6f..a34fd41 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -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.
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index f196bc8..72a07d9b8 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -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);
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 19e4d1a..a464f9b 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -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);
diff --git a/gcc/d/dmd/denum.c b/gcc/d/dmd/denum.c
index b881fb6..d15d94a 100644
--- a/gcc/d/dmd/denum.c
+++ b/gcc/d/dmd/denum.c
@@ -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]);
@@ -745,6 +767,14 @@ 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);
return ::semantic(e, sc);
}
diff --git a/gcc/d/dmd/dsymbol.c b/gcc/d/dmd/dsymbol.c
index d74fe6c..5b4fad4 100644
--- a/gcc/d/dmd/dsymbol.c
+++ b/gcc/d/dmd/dsymbol.c
@@ -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");
- }
- 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 true;
}
+
+ return false;
}
/**********************************
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 5fa509b..6555f12 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -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();
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index 481ff0c..6d389ed 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -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);
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index a3c3f72..395dc56 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -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())
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index ccfaa65..d84878f 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -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);
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index f519389..ecafd9d 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -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)
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 42f90fa..ceee70a 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -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();
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index 80aaac0..2664af2 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -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)
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 2f00c88..46b7d96 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -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)
{