Skip to content

Commit e92dcf0

Browse files
committed
moved the enum member analysis
1 parent 93323f0 commit e92dcf0

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

compiler/src/dmd/enumsem.d

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,3 +718,46 @@ void enumMemberSemantic(Scope* sc, EnumMember em)
718718
assert(em.origValue);
719719
em.semanticRun = PASS.semanticdone;
720720
}
721+
722+
/*********************************
723+
* Perform semantic2 analysis on enum declaration `ed`.
724+
*/
725+
void enumSemantic2(Scope* sc, EnumDeclaration ed)
726+
{
727+
if (ed.semanticRun >= PASS.semantic2done)
728+
return;
729+
730+
if (ed.semanticRun < PASS.semanticdone)
731+
{
732+
error(ed.loc, "forward reference to enum `%s`", ed.toChars());
733+
ed.semanticRun = PASS.semantic2done;
734+
return;
735+
}
736+
737+
assert(ed.semanticRun == PASS.semanticdone);
738+
ed.semanticRun = PASS.semantic2;
739+
740+
if (!ed.members || !ed.symtab || ed.errors)
741+
{
742+
ed.semanticRun = PASS.semantic2done;
743+
return;
744+
}
745+
746+
if (sc)
747+
{
748+
sc = sc.startCTFE();
749+
sc.setNoFree();
750+
}
751+
752+
// Ensure all enum members have their values computed
753+
foreach (s; *ed.members)
754+
{
755+
if (EnumMember em = s.isEnumMember())
756+
{
757+
if (em.semanticRun < PASS.semanticdone)
758+
em.dsymbolSemantic(sc);
759+
}
760+
}
761+
762+
ed.semanticRun = PASS.semantic2done;
763+
}

compiler/src/dmd/semantic2.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,12 @@ private extern(C++) final class Semantic2Visitor : Visitor
692692
visit(cast(AggregateDeclaration) cd);
693693
}
694694

695+
override void visit(EnumDeclaration ed)
696+
{
697+
import dmd.enumsem : enumSemantic2;
698+
enumSemantic2(sc, ed);
699+
}
700+
695701
override void visit(TupleDeclaration td)
696702
{
697703
td.foreachVar((s) { s.accept(this); });

compiler/src/dmd/statementsem.d

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,31 +1961,16 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
19611961
ed = ds.isEnumDeclaration();
19621962

19631963
// Circular references
1964-
if (ed)
1964+
// Check if enum semantic analysis is not yet complete
1965+
if (ed && ed.semanticRun < PASS.semantic2done)
19651966
{
1966-
// Check if inside the initializer of one of the enum's members
1967-
for (Scope* scx = sc; scx; scx = scx.enclosing)
1968-
{
1969-
if (scx.scopesym && scx.scopesym.isEnumDeclaration() && scx.scopesym == ed)
1970-
{
1971-
error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
1972-
sc.pop();
1973-
return setError();
1974-
}
1975-
}
1976-
1977-
// Check if enum semantic analysis is not yet complete
1978-
if (ed.semanticRun < PASS.semanticdone)
1979-
{
1980-
error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
1981-
sc.pop();
1982-
return setError();
1983-
}
1967+
error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
1968+
sc.pop();
1969+
return setError();
19841970
}
19851971

19861972
if (ed && ss.cases.length < ed.members.length)
19871973
{
1988-
// Remove the old check for incomplete enum members
19891974
int missingMembers = 0;
19901975
const maxShown = global.params.v.errorSupplementCount();
19911976
Lmembers:

0 commit comments

Comments
 (0)