fix Issue 23143 - ImportC: forward enum declarations need to be supported

This commit is contained in:
Walter Bright 2022-07-08 22:21:31 -07:00 committed by The Dlang Bot
parent b156f0a9fc
commit a0f6f845ec
5 changed files with 46 additions and 3 deletions

View file

@ -1675,7 +1675,7 @@ final class CParser(AST) : Parser!AST
auto stags = applySpecifier(stag, specifier);
symbols.push(stags);
if (tt.tok == TOK.enum_)
if (0 && tt.tok == TOK.enum_) // C11 proscribes enums with no members, but we allow it
{
if (!tt.members)
error(tt.loc, "`enum %s` has no members", stag.toChars());

View file

@ -2441,6 +2441,15 @@ Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds)
auto sd = s.isScopeDsymbol(); // new declaration
auto sd2 = s2.isScopeDsymbol(); // existing declaration
static if (log) void print(EnumDeclaration sd)
{
printf("members: %p\n", sd.members);
printf("symtab: %p\n", sd.symtab);
printf("endlinnum: %d\n", sd.endlinnum);
printf("type: %s\n", sd.type.toChars());
printf("memtype: %s\n", sd.memtype.toChars());
}
if (!sd2)
{
/* Look in tag table
@ -2473,6 +2482,23 @@ Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds)
{
sd2.members = sd.members; // transfer definition to sd2
sd.members = null;
if (auto ed2 = sd2.isEnumDeclaration())
{
auto ed = sd.isEnumDeclaration();
if (ed.memtype != ed2.memtype)
return null; // conflict
// transfer ed's members to sd2
ed2.members.foreachDsymbol( (s)
{
if (auto em = s.isEnumMember())
em.ed = ed2;
});
ed2.type = ed.type;
ed2.memtype = ed.memtype;
ed2.added = false;
}
return sd2;
}
else

View file

@ -2023,7 +2023,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
override void visit(EnumDeclaration ed)
{
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), ed.toChars());
//printf("EnumDeclaration::semantic() %p %s\n", this, ed.toChars());
//printf("EnumDeclaration::semantic() %p %s\n", ed, ed.toChars());
if (ed.semanticRun >= PASS.semanticdone)
return; // semantic() already completed
if (ed.semanticRun == PASS.semantic)
@ -5716,6 +5716,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
*/
void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
{
//printf("addEnumMembers(ed: %p)\n", ed);
if (ed.added)
return;
ed.added = true;
@ -5739,6 +5740,7 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
em.ed = ed;
if (isCEnum)
{
//printf("adding EnumMember %s to %p\n", em.toChars(), ed);
em.addMember(sc, ed); // add em to ed's symbol table
em.addMember(sc, sds); // add em to symbol table that ed is in
em.parent = ed; // restore it after previous addMember() changed it

View file

@ -697,3 +697,19 @@ int i;
_Static_assert( sizeof (s).x == sizeof(int), "" );
_Static_assert( sizeof (fn)() == sizeof(int), "" );
_Static_assert( sizeof (i)++ == sizeof(int), "" );
// https://issues.dlang.org/show_bug.cgi?id=23143
enum E1;
enum E1 {
m3,
m4 = m3
};
typedef enum E2 T1;
enum E2 {
m1,
m2 = m1
};

View file

@ -25,7 +25,6 @@ fail_compilation/failcstuff1.c(260): Error: identifier or `(` expected
fail_compilation/failcstuff1.c(301): Error: illegal type combination
fail_compilation/failcstuff1.c(352): Error: found `2` when expecting `:`
fail_compilation/failcstuff1.c(352): Error: found `:` instead of statement
fail_compilation/failcstuff1.c(400): Error: `enum ENUM` has no members
fail_compilation/failcstuff1.c(450): Error: static array parameters are not supported
fail_compilation/failcstuff1.c(450): Error: static or type qualifier used in non-outermost array type derivation
fail_compilation/failcstuff1.c(451): Error: static or type qualifier used in non-outermost array type derivation