mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 13:40:11 +03:00
Merge pull request #11642 from wilzbach/fix-dtoh
Fix Issue 21208 - C/C++ header generation for {string,enum} enums
This commit is contained in:
commit
6cd107f79f
3 changed files with 94 additions and 12 deletions
|
@ -44,6 +44,7 @@ struct ASTCodegen
|
||||||
alias MODFlags = dmd.mtype.MODFlags;
|
alias MODFlags = dmd.mtype.MODFlags;
|
||||||
alias Type = dmd.mtype.Type;
|
alias Type = dmd.mtype.Type;
|
||||||
alias Parameter = dmd.mtype.Parameter;
|
alias Parameter = dmd.mtype.Parameter;
|
||||||
|
alias Tarray = dmd.mtype.Tarray;
|
||||||
alias Taarray = dmd.mtype.Taarray;
|
alias Taarray = dmd.mtype.Taarray;
|
||||||
alias Tbool = dmd.mtype.Tbool;
|
alias Tbool = dmd.mtype.Tbool;
|
||||||
alias Tchar = dmd.mtype.Tchar;
|
alias Tchar = dmd.mtype.Tchar;
|
||||||
|
|
|
@ -389,6 +389,8 @@ public:
|
||||||
{
|
{
|
||||||
Int,
|
Int,
|
||||||
Numeric,
|
Numeric,
|
||||||
|
String,
|
||||||
|
Enum,
|
||||||
Other
|
Other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,6 +440,12 @@ public:
|
||||||
AST.Tuns32,
|
AST.Tuns32,
|
||||||
AST.Tint64, AST.Tuns64:
|
AST.Tint64, AST.Tuns64:
|
||||||
return EnumKind.Numeric;
|
return EnumKind.Numeric;
|
||||||
|
case AST.Tarray:
|
||||||
|
if (type.isString())
|
||||||
|
return EnumKind.String;
|
||||||
|
break;
|
||||||
|
case AST.Tenum:
|
||||||
|
return EnumKind.Enum;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -673,33 +681,41 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vd.storage_class & AST.STC.manifest &&
|
if (vd.storage_class & AST.STC.manifest &&
|
||||||
vd._init && vd._init.isExpInitializer())
|
vd._init && vd._init.isExpInitializer() && vd.type !is null)
|
||||||
{
|
{
|
||||||
AST.Type type = vd.type;
|
AST.Type type = vd.type;
|
||||||
EnumKind kind = getEnumKind(type);
|
EnumKind kind = getEnumKind(type);
|
||||||
|
|
||||||
if (kind != EnumKind.Other)
|
final switch (kind)
|
||||||
{
|
{
|
||||||
hasNumericConstant = true;
|
case EnumKind.Int, EnumKind.Numeric:
|
||||||
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
hasNumericConstant = true;
|
||||||
}
|
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
hasTypedConstant = true;
|
case EnumKind.String, EnumKind.Enum:
|
||||||
buf.writestring("ENUM_CONSTANT(");
|
hasTypedConstant = true;
|
||||||
|
buf.writestring("ENUM_CONSTANT(");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumKind.Other:
|
||||||
|
buf.printf("// ignoring enum `%s` because type `%s` is currently not supported for enum constants.\n", vd.toPrettyChars(), type.toChars());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
writeEnumTypeName(type);
|
writeEnumTypeName(type);
|
||||||
buf.writestring(", ");
|
buf.writestring(", ");
|
||||||
buf.writestring(vd.ident.toString());
|
buf.writestring(vd.ident.toString());
|
||||||
buf.writestring(", ");
|
buf.writestring(", ");
|
||||||
auto e = AST.initializerToExpression(vd._init);
|
auto e = AST.initializerToExpression(vd._init);
|
||||||
if (kind != EnumKind.Other)
|
if (kind == EnumKind.Int || kind == EnumKind.Numeric)
|
||||||
{
|
{
|
||||||
auto ie = e.isIntegerExp();
|
auto ie = e.isIntegerExp();
|
||||||
visitInteger(ie.toInteger(), type);
|
visitInteger(ie.toInteger(), type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
e.accept(this);
|
e.accept(this);
|
||||||
|
}
|
||||||
buf.writestringln(")");
|
buf.writestringln(")");
|
||||||
buf.writenl();
|
buf.writenl();
|
||||||
return;
|
return;
|
||||||
|
@ -1267,7 +1283,7 @@ public:
|
||||||
buf.writestring("ANON_ENUM_KEY(");
|
buf.writestring("ANON_ENUM_KEY(");
|
||||||
else if (!manifestConstants)
|
else if (!manifestConstants)
|
||||||
buf.writestring("ANON_ENUM_KEY_NUMERIC(");
|
buf.writestring("ANON_ENUM_KEY_NUMERIC(");
|
||||||
else if (manifestConstants && memberKind != EnumKind.Other)
|
else if (manifestConstants && memberKind == EnumKind.Int || memberKind == EnumKind.Numeric)
|
||||||
{
|
{
|
||||||
hasNumericConstant = true;
|
hasNumericConstant = true;
|
||||||
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
||||||
|
@ -1280,7 +1296,7 @@ public:
|
||||||
writeEnumTypeName(memberType);
|
writeEnumTypeName(memberType);
|
||||||
buf.printf(", %s, ", m.ident.toChars());
|
buf.printf(", %s, ", m.ident.toChars());
|
||||||
|
|
||||||
if (memberKind != EnumKind.Other)
|
if (kind == EnumKind.Int || kind == EnumKind.Numeric)
|
||||||
{
|
{
|
||||||
auto ie = cast(AST.IntegerExp)m.value;
|
auto ie = cast(AST.IntegerExp)m.value;
|
||||||
visitInteger(ie.toInteger(), memberType);
|
visitInteger(ie.toInteger(), memberType);
|
||||||
|
|
|
@ -42,6 +42,9 @@ TEST_OUTPUT:
|
||||||
# define ENUM_CONSTANT(type, name, value) static type const name = value;
|
# define ENUM_CONSTANT(type, name, value) static type const name = value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
struct FooCpp;
|
||||||
|
|
||||||
ENUM_CONSTANT_NUMERIC(int32_t, Anon, 10)
|
ENUM_CONSTANT_NUMERIC(int32_t, Anon, 10)
|
||||||
|
|
||||||
ENUM_CONSTANT_NUMERIC(bool, Anon2, true)
|
ENUM_CONSTANT_NUMERIC(bool, Anon2, true)
|
||||||
|
@ -86,6 +89,42 @@ END_ENUM_TYPE(const char*, EnumWithImplicitType, ENUMWITHIMPLICITTYPE, enumwithi
|
||||||
ENUM_CONSTANT_NUMERIC(int32_t, AnonMixedOne, 1)
|
ENUM_CONSTANT_NUMERIC(int32_t, AnonMixedOne, 1)
|
||||||
ENUM_CONSTANT_NUMERIC(int64_t, AnonMixedTwo, 2LL)
|
ENUM_CONSTANT_NUMERIC(int64_t, AnonMixedTwo, 2LL)
|
||||||
ENUM_CONSTANT(const char*, AnonMixedA, "a")
|
ENUM_CONSTANT(const char*, AnonMixedA, "a")
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_ENUM(STC, STC, stc)
|
||||||
|
ENUM_KEY(int32_t, a, 1, STC, STC, stc, STC)
|
||||||
|
ENUM_KEY(int32_t, b, 2, STC, STC, stc, STC)
|
||||||
|
END_ENUM(STC, STC, stc)
|
||||||
|
|
||||||
|
ENUM_CONSTANT(STC, STC_D, (STC)3)
|
||||||
|
|
||||||
|
// ignoring non-cpp struct Foo because of linkage
|
||||||
|
BEGIN_ENUM_TYPE(Foo, MyEnum, MYENUM, myenum)
|
||||||
|
ENUM_KEY_TYPE(Foo, A, Foo(42), MyEnum, MYENUM, myenum, ME)
|
||||||
|
ENUM_KEY_TYPE(Foo, B, Foo(84), MyEnum, MYENUM, myenum, ME)
|
||||||
|
END_ENUM_TYPE(Foo, MyEnum, MYENUM, myenum)
|
||||||
|
|
||||||
|
ENUM_CONSTANT(MyEnum, test, Foo(42))
|
||||||
|
|
||||||
|
struct FooCpp
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
FooCpp() : i() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEGIN_ENUM_TYPE(FooCpp, MyEnumCpp, MYENUMCPP, myenumcpp)
|
||||||
|
ENUM_KEY_TYPE(FooCpp, A, FooCpp(42), MyEnumCpp, MYENUMCPP, myenumcpp, MEC)
|
||||||
|
ENUM_KEY_TYPE(FooCpp, B, FooCpp(84), MyEnumCpp, MYENUMCPP, myenumcpp, MEC)
|
||||||
|
END_ENUM_TYPE(FooCpp, MyEnumCpp, MYENUMCPP, myenumcpp)
|
||||||
|
|
||||||
|
ENUM_CONSTANT(MyEnum, testCpp, Foo(42))
|
||||||
|
|
||||||
|
// ignoring enum `dtoh_enum.b` because type `int[]` is currently not supported for enum constants.
|
||||||
|
// ignoring enum `dtoh_enum.c` because type `int[int]` is currently not supported for enum constants.
|
||||||
|
// ignoring function dtoh_enum.foo because it's extern
|
||||||
|
// ignoring enum `dtoh_enum.d` because type `extern (C) void function()` is currently not supported for enum constants.
|
||||||
|
// ignoring variable dtoh_enum.e_b because of linkage
|
||||||
|
// ignoring enum `dtoh_enum.e` because type `immutable(bool)*` is currently not supported for enum constants.
|
||||||
---
|
---
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -141,3 +180,29 @@ enum
|
||||||
long AnonMixedTwo = 2,
|
long AnonMixedTwo = 2,
|
||||||
string AnonMixedA = "a"
|
string AnonMixedA = "a"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum STC
|
||||||
|
{
|
||||||
|
a = 1,
|
||||||
|
b = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum STC_D = STC.a | STC.b;
|
||||||
|
|
||||||
|
struct Foo { int i; }
|
||||||
|
enum MyEnum { A = Foo(42), B = Foo(84) }
|
||||||
|
enum test = MyEnum.A;
|
||||||
|
|
||||||
|
extern(C++) struct FooCpp { int i; }
|
||||||
|
enum MyEnumCpp { A = FooCpp(42), B = FooCpp(84) }
|
||||||
|
enum testCpp = MyEnum.A;
|
||||||
|
|
||||||
|
// currently unsupported enums
|
||||||
|
enum b = [1, 2, 3];
|
||||||
|
enum c = [2: 3];
|
||||||
|
|
||||||
|
extern(C) void foo();
|
||||||
|
enum d = &foo;
|
||||||
|
|
||||||
|
immutable bool e_b;
|
||||||
|
enum e = &e_b;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue