diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index 50a67fab31..9f1eab7fc6 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -5526,6 +5526,12 @@ final class CParser(AST) : Parser!AST if (pt && *pt) t = *pt; } + if (t.mcache && t.mcache.typedefIdent) + { + t = t.copy(); + t.mcache = null; + } + t.getMcache().typedefIdent = id; auto tab = cast(void*[void*])(typedefTab[$ - 1]); tab[cast(void*)id] = cast(void*)t; typedefTab[$ - 1] = cast(void*)tab; diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index a2be68f215..3940db22d7 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -1830,6 +1830,7 @@ public: Type* pto; Type* rto; Type* arrayof; + Identifier* typedefIdent; Mcache() : cto(), ito(), @@ -1841,10 +1842,11 @@ public: swcto(), pto(), rto(), - arrayof() + arrayof(), + typedefIdent() { } - Mcache(Type* cto, Type* ito = nullptr, Type* sto = nullptr, Type* scto = nullptr, Type* wto = nullptr, Type* wcto = nullptr, Type* swto = nullptr, Type* swcto = nullptr, Type* pto = nullptr, Type* rto = nullptr, Type* arrayof = nullptr) : + Mcache(Type* cto, Type* ito = nullptr, Type* sto = nullptr, Type* scto = nullptr, Type* wto = nullptr, Type* wcto = nullptr, Type* swto = nullptr, Type* swcto = nullptr, Type* pto = nullptr, Type* rto = nullptr, Type* arrayof = nullptr, Identifier* typedefIdent = nullptr) : cto(cto), ito(ito), sto(sto), @@ -1855,7 +1857,8 @@ public: swcto(swcto), pto(pto), rto(rto), - arrayof(arrayof) + arrayof(arrayof), + typedefIdent(typedefIdent) {} }; @@ -4066,6 +4069,7 @@ struct HdrGenState final bool ddoc; bool fullDump; bool importcHdr; + bool inCAlias; bool doFuncBodies; bool vcg_ast; bool skipConstraints; @@ -4084,6 +4088,7 @@ struct HdrGenState final ddoc(), fullDump(), importcHdr(), + inCAlias(), doFuncBodies(), vcg_ast(), skipConstraints(), @@ -4099,11 +4104,12 @@ struct HdrGenState final inEnumDecl() { } - HdrGenState(bool hdrgen, bool ddoc = false, bool fullDump = false, bool importcHdr = false, bool doFuncBodies = false, bool vcg_ast = false, bool skipConstraints = false, bool showOneMember = true, bool errorMsg = false, bool fullQual = false, int32_t tpltMember = 0, int32_t autoMember = 0, int32_t forStmtInit = 0, int32_t insideFuncBody = 0, int32_t insideAggregate = 0, bool declstring = false, EnumDeclaration* inEnumDecl = nullptr) : + HdrGenState(bool hdrgen, bool ddoc = false, bool fullDump = false, bool importcHdr = false, bool inCAlias = false, bool doFuncBodies = false, bool vcg_ast = false, bool skipConstraints = false, bool showOneMember = true, bool errorMsg = false, bool fullQual = false, int32_t tpltMember = 0, int32_t autoMember = 0, int32_t forStmtInit = 0, int32_t insideFuncBody = 0, int32_t insideAggregate = 0, bool declstring = false, EnumDeclaration* inEnumDecl = nullptr) : hdrgen(hdrgen), ddoc(ddoc), fullDump(fullDump), importcHdr(importcHdr), + inCAlias(inCAlias), doFuncBodies(doFuncBodies), vcg_ast(vcg_ast), skipConstraints(skipConstraints), diff --git a/compiler/src/dmd/hdrgen.d b/compiler/src/dmd/hdrgen.d index c641579575..0ef955a033 100644 --- a/compiler/src/dmd/hdrgen.d +++ b/compiler/src/dmd/hdrgen.d @@ -59,6 +59,7 @@ struct HdrGenState bool ddoc; /// true if generating Ddoc file bool fullDump; /// true if generating a full AST dump file bool importcHdr; /// true if generating a .di file from an ImportC file + bool inCAlias; /// Set to prevent ImportC translating typedefs as `alias X = X` bool doFuncBodies; /// include function bodies in output bool vcg_ast; /// write out codegen-ast bool skipConstraints; // skip constraints when doing templates @@ -1777,7 +1778,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) buf.writestring(" = "); if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); + hgs.inCAlias = hgs.importcHdr; typeToBuffer(d.type, null, buf, hgs); + hgs.inCAlias = false; hgs.declstring = false; } buf.writeByte(';'); @@ -4449,6 +4452,11 @@ private void typeToBufferx(Type t, ref OutBuffer buf, ref HdrGenState hgs) buf.writestring("noreturn"); } + if (hgs.importcHdr && !hgs.inCAlias && t.mcache && t.mcache.typedefIdent) + { + buf.writestring(t.mcache.typedefIdent.toString()); + return; + } switch (t.ty) { diff --git a/compiler/src/dmd/mtype.d b/compiler/src/dmd/mtype.d index 5846613c9c..84899d003c 100644 --- a/compiler/src/dmd/mtype.d +++ b/compiler/src/dmd/mtype.d @@ -302,6 +302,10 @@ extern (C++) abstract class Type : ASTNode Type pto; // merged pointer to this type Type rto; // reference to this type Type arrayof; // array of this type + + // ImportC: store the name of the typedef resolving to this type + // So `uint8_t x;` will be printed as `uint8_t x;` and not as the resolved `ubyte x;` + Identifier typedefIdent; } Mcache* mcache; diff --git a/compiler/test/compilable/ctod.i b/compiler/test/compilable/ctod.i index 5a631714d0..e9041d0bcc 100644 --- a/compiler/test/compilable/ctod.i +++ b/compiler/test/compilable/ctod.i @@ -41,6 +41,18 @@ extern (C) int x = void; } alias weird = int[(cast(foo*)cast(void*)0).x.sizeof]; + alias ULONG = ulong; + alias ULONG_Deluxe = ulong; + alias ULONG_PTR = ulong*; + alias Callback = void* function(); + struct Test + { + ULONG_Deluxe d = void; + ULONG_Deluxe* p = void; + ULONG_PTR q = void; + Callback cb = void; + } + extern __gshared int[cast(ULONG)3] arr; /+enum int __DATE__ = 1+/; /+enum int __TIME__ = 1+/; /+enum int __TIMESTAMP__ = 1+/; @@ -96,3 +108,19 @@ struct foo { int x; }; typedef int weird[sizeof(((struct foo *)((void*)0))->x)]; + +// https://github.com/dlang/dmd/issues/20889 +typedef unsigned long long ULONG; +typedef ULONG ULONG_Deluxe; +typedef ULONG_Deluxe *ULONG_PTR; +typedef void *(*Callback)(); + +struct Test +{ + ULONG_Deluxe d; + ULONG_Deluxe *p; + ULONG_PTR q; + Callback cb; +}; + +int arr[(ULONG) 3];