109 changes: 78 additions & 31 deletions src/denum.d

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/doc.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module ddmd.doc;

import core.stdc.ctype;
import core.stdc.stdlib;
import core.stdc.stdio;
import core.stdc.string;
import core.stdc.time;
import ddmd.aggregate;
Expand Down Expand Up @@ -329,6 +330,8 @@ extern (C++) static Dsymbol getEponymousMember(TemplateDeclaration td)
return ad;
if (FuncDeclaration fd = td.onemember.isFuncDeclaration())
return fd;
if (auto em = td.onemember.isEnumMember())
return null; // Keep backward compatibility. See compilable/ddoc9.d
if (VarDeclaration vd = td.onemember.isVarDeclaration())
return td.constraint ? null : vd;
return null;
Expand Down
11 changes: 6 additions & 5 deletions src/enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "root.h"
#include "dsymbol.h"
#include "declaration.h"
#include "tokens.h"

class Identifier;
Expand Down Expand Up @@ -70,25 +71,25 @@ class EnumDeclaration : public ScopeDsymbol
};


class EnumMember : public Dsymbol
class EnumMember : public VarDeclaration
{
public:
/* Can take the following forms:
* 1. id
* 2. id = value
* 3. type id = value
*/
Expression *value;
Expression *&value();

// A cast() is injected to 'value' after semantic(),
// but 'origValue' will preserve the original value,
// or previous value + 1 if none was specified.
Expression *origValue;
Type *type;
Type *origType;

EnumDeclaration *ed;
VarDeclaration *vd;

EnumMember(Loc loc, Identifier *id, Expression *value, Type *type);
EnumMember(Loc loc, Identifier *id, Expression *value, Type *origType);
Dsymbol *syntaxCopy(Dsymbol *s);
const char *kind();
void semantic(Scope *sc);
Expand Down
2 changes: 1 addition & 1 deletion src/iasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,7 @@ static void asm_merge_symbol(OPND *o1, Dsymbol *s)
em = s->isEnumMember();
if (em)
{
o1->disp = em->value->toInteger();
o1->disp = em->value()->toInteger();
return;
}
o1->s = s; // a C identifier
Expand Down
4 changes: 2 additions & 2 deletions src/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -745,8 +745,8 @@ public:
override void visit(EnumMember s)
{
objectStart();
jsonProperties(s);
property("type", "deco", s.type);
jsonProperties(cast(Dsymbol)s);
property("type", "deco", s.origType);
objectEnd();
}

Expand Down
39 changes: 23 additions & 16 deletions src/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -7101,6 +7101,13 @@ public:
L2:
s = sm.toAlias();
}

if (auto em = s.isEnumMember())
{
// It's not a type, it's an expression
*pe = em.getVarExp(loc, sc);
return;
}
if (VarDeclaration v = s.isVarDeclaration())
{
/* This is mostly same with DsymbolExp::semantic(), but we cannot use it
Expand Down Expand Up @@ -7139,12 +7146,6 @@ public:
return;
}
}
if (EnumMember em = s.isEnumMember())
{
// It's not a type, it's an expression
*pe = em.getVarExp(loc, sc);
return;
}
L1:
Type t = s.getType();
if (!t)
Expand Down Expand Up @@ -7316,6 +7317,8 @@ public:
resolve(loc, sc, &e, &t, &s);
if (t && t.ty != Tident)
s = t.toDsymbol(sc);
if (e)
s = getDsymbol(e);
return s;
}

Expand Down Expand Up @@ -7875,6 +7878,12 @@ public:
if (!s.isFuncDeclaration()) // because of overloading
s.checkDeprecated(e.loc, sc);
s = s.toAlias();

if (auto em = s.isEnumMember())
{
return em.getVarExp(e.loc, sc);
}

VarDeclaration v = s.isVarDeclaration();
if (v && (!v.type || !v.type.deco))
{
Expand All @@ -7901,11 +7910,7 @@ public:
{
return new TypeExp(e.loc, s.getType());
}
EnumMember em = s.isEnumMember();
if (em)
{
return em.getVarExp(e.loc, sc);
}

TemplateMixin tm = s.isTemplateMixin();
if (tm)
{
Expand Down Expand Up @@ -8731,6 +8736,12 @@ public:
if (!s.isFuncDeclaration()) // because of overloading
s.checkDeprecated(e.loc, sc);
s = s.toAlias();

if (auto em = s.isEnumMember())
{
return em.getVarExp(e.loc, sc);
}

VarDeclaration v = s.isVarDeclaration();
if (v && (!v.type || !v.type.deco))
{
Expand All @@ -8757,11 +8768,7 @@ public:
{
return new TypeExp(e.loc, s.getType());
}
EnumMember em = s.isEnumMember();
if (em)
{
return em.getVarExp(e.loc, sc);
}

TemplateMixin tm = s.isTemplateMixin();
if (tm)
{
Expand Down
4 changes: 2 additions & 2 deletions src/tocvdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ unsigned cv4_Denum(EnumDeclaration *e)
{ EnumMember *sf = (*e->members)[i]->isEnumMember();
if (sf)
{
dinteger_t value = sf->value->toInteger();
dinteger_t value = sf->value()->toInteger();
unsigned fnamelen1 = fnamelen;

// store only member's simple name
Expand Down Expand Up @@ -233,7 +233,7 @@ unsigned cv4_Denum(EnumDeclaration *e)
if (fieldi > nfields)
break; // chop off the rest

dinteger_t value = sf->value->toInteger();
dinteger_t value = sf->value()->toInteger();
TOWORD(dt->data + j,(config.fulltypes == CV8) ? LF_ENUMERATE_V3 : LF_ENUMERATE);
unsigned attribute = 0;
TOWORD(dt->data + j + 2,attribute);
Expand Down
2 changes: 1 addition & 1 deletion src/visitor.d
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ public:

void visit(EnumMember s)
{
visit(cast(Dsymbol)s);
visit(cast(VarDeclaration)s);
}

void visit(Import s)
Expand Down
2 changes: 1 addition & 1 deletion src/visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ class Visitor
virtual void visit(StaticAssert *s) { visit((Dsymbol *)s); }
virtual void visit(DebugSymbol *s) { visit((Dsymbol *)s); }
virtual void visit(VersionSymbol *s) { visit((Dsymbol *)s); }
virtual void visit(EnumMember *s) { visit((Dsymbol *)s); }
virtual void visit(EnumMember *s) { visit((VarDeclaration *)s); }
virtual void visit(Import *s) { visit((Dsymbol *)s); }
virtual void visit(OverloadSet *s) { visit((Dsymbol *)s); }
virtual void visit(LabelDsymbol *s) { visit((Dsymbol *)s); }
Expand Down
5 changes: 5 additions & 0 deletions test/compilable/ddoc9.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ struct Struct(T) { }
/// Union Documentation
union Union(T) { }

/// Template documentation with anonymous enum
template TemplateWithAnonEnum(T)
{
enum { TemplateWithAnonEnum = 1 }
}
4 changes: 4 additions & 0 deletions test/compilable/extra-files/ddoc9.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ <h1>ddoc9</h1>
</big></dt>
<dd><u>Union</u> Documentation<br><br>

</dd>
<dt><big><a name="TemplateWithAnonEnum"></a>template <u>TemplateWithAnonEnum</u>(T)</big></dt>
<dd>Template documentation with anonymous enum<br><br>

</dd>
</dl>

Expand Down
6 changes: 6 additions & 0 deletions test/compilable/imports/test15150a.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module imports.test15150a;

enum
{
x
}
3 changes: 3 additions & 0 deletions test/compilable/imports/test15150b.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module imports.test15150b;

import imports.test15150a : x;
8 changes: 8 additions & 0 deletions test/compilable/test15150.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// PERMUTE_ARGS:

module test15150;

import imports.test15150a;
import imports.test15150b;

enum y = x;
4 changes: 2 additions & 2 deletions test/fail_compilation/fail10528.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ TEST_OUTPUT:
---
fail_compilation/fail10528.d(19): Error: module fail10528 variable a10528.a is private
fail_compilation/fail10528.d(20): Error: variable a10528.a is not accessible from module fail10528
fail_compilation/fail10528.d(22): Error: variable a10528.b is not accessible from module fail10528
fail_compilation/fail10528.d(23): Error: variable a10528.b is not accessible from module fail10528
fail_compilation/fail10528.d(22): Error: module fail10528 enum member a10528.b is private
fail_compilation/fail10528.d(23): Error: enum member a10528.b is not accessible from module fail10528
fail_compilation/fail10528.d(25): Error: variable a10528.S.c is not accessible from module fail10528
fail_compilation/fail10528.d(26): Error: variable a10528.S.c is not accessible from module fail10528
fail_compilation/fail10528.d(28): Error: variable a10528.C.d is not accessible from module fail10528
Expand Down