File tree Expand file tree Collapse file tree 3 files changed +54
-20
lines changed
Expand file tree Collapse file tree 3 files changed +54
-20
lines changed Original file line number Diff line number Diff 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+ }
Original file line number Diff line number Diff 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 ); });
Original file line number Diff line number Diff 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:
You can’t perform that action at this time.
0 commit comments