diff --git a/src/enum.c b/src/enum.c index d0530592ba3e..ec46053cce91 100644 --- a/src/enum.c +++ b/src/enum.c @@ -513,6 +513,7 @@ EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type) { this->ed = NULL; this->value = value; + this->origValue = value; this->type = type; this->loc = loc; this->vd = NULL; @@ -534,9 +535,13 @@ Dsymbol *EnumMember::syntaxCopy(Dsymbol *s) em->loc = loc; em->value = e; em->type = t; + em->origValue = origValue ? origValue->syntaxCopy() : NULL; } else + { em = new EnumMember(loc, ident, e, t); + em->origValue = origValue ? origValue->syntaxCopy() : NULL; + } return em; } @@ -613,6 +618,10 @@ void EnumMember::semantic(Scope *sc) { e = e->implicitCastTo(sc, ed->memtype); e = e->ctfeInterpret(); + + // save origValue for better json output + origValue = e; + if (!ed->isAnonymous()) e = e->castTo(sc, ed->type); } @@ -621,6 +630,9 @@ void EnumMember::semantic(Scope *sc) e = e->implicitCastTo(sc, type); e = e->ctfeInterpret(); assert(ed->isAnonymous()); + + // save origValue for better json output + origValue = e; } value = e; } @@ -638,6 +650,10 @@ void EnumMember::semantic(Scope *sc) Expression *e = new IntegerExp(loc, 0, Type::tint32); e = e->implicitCastTo(sc, t); e = e->ctfeInterpret(); + + // save origValue for better json output + origValue = e; + if (!ed->isAnonymous()) e = e->castTo(sc, ed->type); value = e; @@ -689,6 +705,15 @@ void EnumMember::semantic(Scope *sc) e = e->castTo(sc, eprev->type); e = e->ctfeInterpret(); + // save origValue (without cast) for better json output + if (e->op != TOKerror) // avoid duplicate diagnostics + { + assert(emprev->origValue); + origValue = new AddExp(loc, emprev->origValue, new IntegerExp(loc, 1, Type::tint32)); + origValue = origValue->semantic(sc); + origValue = origValue->ctfeInterpret(); + } + if (e->op == TOKerror) goto Lerrors; if (e->type->isfloating()) @@ -706,6 +731,7 @@ void EnumMember::semantic(Scope *sc) value = e; } + assert(origValue); semanticRun = PASSsemanticdone; } diff --git a/src/enum.h b/src/enum.h index 98250842bab8..4cc7654aa652 100644 --- a/src/enum.h +++ b/src/enum.h @@ -84,6 +84,9 @@ class EnumMember : public Dsymbol * 3. type id = value */ Expression *value; + Expression *origValue; // A cast() is injected to 'value' after semantic(), + // but 'origValue' will preserve the original value, + // or previous value + 1 if none was specified. Type *type; EnumDeclaration *ed; diff --git a/src/json.c b/src/json.c index ecc07560a11a..890bc1024b0a 100644 --- a/src/json.c +++ b/src/json.c @@ -451,6 +451,12 @@ class ToJsonVisitor : public Visitor if (s->prot() != PROTpublic) property("protection", Pprotectionnames[s->prot()]); + if (EnumMember *em = s->isEnumMember()) + { + if (em->origValue) + property("value", em->origValue->toChars()); + } + property("comment", (const char *)s->comment); property("line", "char", &s->loc); diff --git a/test/compilable/extra-files/json.out b/test/compilable/extra-files/json.out index c78b6c6a24b6..b271de03be68 100644 --- a/test/compilable/extra-files/json.out +++ b/test/compilable/extra-files/json.out @@ -507,6 +507,64 @@ "deco" : "xC6Object", "originalType" : "Object", "init" : "Object()" + }, + { + "name" : "Numbers", + "kind" : "enum", + "line" : 101, + "char" : 1, + "baseDeco" : "i", + "members" : [ + { + "name" : "unspecified1", + "kind" : "enum member", + "value" : "0", + "line" : 103, + "char" : 5 + }, + { + "name" : "one", + "kind" : "enum member", + "value" : "2", + "line" : 104, + "char" : 5 + }, + { + "name" : "two", + "kind" : "enum member", + "value" : "3", + "line" : 105, + "char" : 5 + }, + { + "name" : "FILE_NOT_FOUND", + "kind" : "enum member", + "value" : "101", + "line" : 106, + "char" : 5 + }, + { + "name" : "unspecified3", + "kind" : "enum member", + "value" : "102", + "line" : 107, + "char" : 5 + }, + { + "name" : "unspecified4", + "kind" : "enum member", + "value" : "103", + "line" : 108, + "char" : 5 + }, + { + "name" : "four", + "kind" : "enum member", + "value" : "4", + "line" : 109, + "char" : 5 + } + ] } ] } diff --git a/test/compilable/json.d b/test/compilable/json.d index c8ffa3d32e51..52352487c0e6 100644 --- a/test/compilable/json.d +++ b/test/compilable/json.d @@ -96,3 +96,15 @@ class C_9755 /** Issue 10011 - init property is wrong for object initializer. */ const Object c_10011 = new Object(); + +/// +enum Numbers +{ + unspecified1, + one = 2, + two = 3, + FILE_NOT_FOUND = 101, + unspecified3, + unspecified4, + four = 4, +}