mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +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 Type = dmd.mtype.Type;
|
||||
alias Parameter = dmd.mtype.Parameter;
|
||||
alias Tarray = dmd.mtype.Tarray;
|
||||
alias Taarray = dmd.mtype.Taarray;
|
||||
alias Tbool = dmd.mtype.Tbool;
|
||||
alias Tchar = dmd.mtype.Tchar;
|
||||
|
|
|
@ -389,6 +389,8 @@ public:
|
|||
{
|
||||
Int,
|
||||
Numeric,
|
||||
String,
|
||||
Enum,
|
||||
Other
|
||||
}
|
||||
|
||||
|
@ -438,6 +440,12 @@ public:
|
|||
AST.Tuns32,
|
||||
AST.Tint64, AST.Tuns64:
|
||||
return EnumKind.Numeric;
|
||||
case AST.Tarray:
|
||||
if (type.isString())
|
||||
return EnumKind.String;
|
||||
break;
|
||||
case AST.Tenum:
|
||||
return EnumKind.Enum;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -673,33 +681,41 @@ public:
|
|||
}
|
||||
|
||||
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;
|
||||
EnumKind kind = getEnumKind(type);
|
||||
|
||||
if (kind != EnumKind.Other)
|
||||
final switch (kind)
|
||||
{
|
||||
hasNumericConstant = true;
|
||||
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
||||
}
|
||||
else
|
||||
{
|
||||
hasTypedConstant = true;
|
||||
buf.writestring("ENUM_CONSTANT(");
|
||||
case EnumKind.Int, EnumKind.Numeric:
|
||||
hasNumericConstant = true;
|
||||
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
||||
break;
|
||||
|
||||
case EnumKind.String, EnumKind.Enum:
|
||||
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);
|
||||
buf.writestring(", ");
|
||||
buf.writestring(vd.ident.toString());
|
||||
buf.writestring(", ");
|
||||
auto e = AST.initializerToExpression(vd._init);
|
||||
if (kind != EnumKind.Other)
|
||||
if (kind == EnumKind.Int || kind == EnumKind.Numeric)
|
||||
{
|
||||
auto ie = e.isIntegerExp();
|
||||
visitInteger(ie.toInteger(), type);
|
||||
}
|
||||
else
|
||||
{
|
||||
e.accept(this);
|
||||
}
|
||||
buf.writestringln(")");
|
||||
buf.writenl();
|
||||
return;
|
||||
|
@ -1267,7 +1283,7 @@ public:
|
|||
buf.writestring("ANON_ENUM_KEY(");
|
||||
else if (!manifestConstants)
|
||||
buf.writestring("ANON_ENUM_KEY_NUMERIC(");
|
||||
else if (manifestConstants && memberKind != EnumKind.Other)
|
||||
else if (manifestConstants && memberKind == EnumKind.Int || memberKind == EnumKind.Numeric)
|
||||
{
|
||||
hasNumericConstant = true;
|
||||
buf.writestring("ENUM_CONSTANT_NUMERIC(");
|
||||
|
@ -1280,7 +1296,7 @@ public:
|
|||
writeEnumTypeName(memberType);
|
||||
buf.printf(", %s, ", m.ident.toChars());
|
||||
|
||||
if (memberKind != EnumKind.Other)
|
||||
if (kind == EnumKind.Int || kind == EnumKind.Numeric)
|
||||
{
|
||||
auto ie = cast(AST.IntegerExp)m.value;
|
||||
visitInteger(ie.toInteger(), memberType);
|
||||
|
|
|
@ -42,6 +42,9 @@ TEST_OUTPUT:
|
|||
# define ENUM_CONSTANT(type, name, value) static type const name = value;
|
||||
#endif
|
||||
|
||||
struct Foo;
|
||||
struct FooCpp;
|
||||
|
||||
ENUM_CONSTANT_NUMERIC(int32_t, Anon, 10)
|
||||
|
||||
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(int64_t, AnonMixedTwo, 2LL)
|
||||
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,
|
||||
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