Fix #20889 - ImportC: Usage of typedef types decays to original type (#20904)

This commit is contained in:
Dennis 2025-02-20 15:01:09 +01:00 committed by GitHub
parent 54a142412c
commit 1d8658d722
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 56 additions and 4 deletions

View file

@ -5526,6 +5526,12 @@ final class CParser(AST) : Parser!AST
if (pt && *pt) if (pt && *pt)
t = *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]); auto tab = cast(void*[void*])(typedefTab[$ - 1]);
tab[cast(void*)id] = cast(void*)t; tab[cast(void*)id] = cast(void*)t;
typedefTab[$ - 1] = cast(void*)tab; typedefTab[$ - 1] = cast(void*)tab;

View file

@ -1830,6 +1830,7 @@ public:
Type* pto; Type* pto;
Type* rto; Type* rto;
Type* arrayof; Type* arrayof;
Identifier* typedefIdent;
Mcache() : Mcache() :
cto(), cto(),
ito(), ito(),
@ -1841,10 +1842,11 @@ public:
swcto(), swcto(),
pto(), pto(),
rto(), 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), cto(cto),
ito(ito), ito(ito),
sto(sto), sto(sto),
@ -1855,7 +1857,8 @@ public:
swcto(swcto), swcto(swcto),
pto(pto), pto(pto),
rto(rto), rto(rto),
arrayof(arrayof) arrayof(arrayof),
typedefIdent(typedefIdent)
{} {}
}; };
@ -4066,6 +4069,7 @@ struct HdrGenState final
bool ddoc; bool ddoc;
bool fullDump; bool fullDump;
bool importcHdr; bool importcHdr;
bool inCAlias;
bool doFuncBodies; bool doFuncBodies;
bool vcg_ast; bool vcg_ast;
bool skipConstraints; bool skipConstraints;
@ -4084,6 +4088,7 @@ struct HdrGenState final
ddoc(), ddoc(),
fullDump(), fullDump(),
importcHdr(), importcHdr(),
inCAlias(),
doFuncBodies(), doFuncBodies(),
vcg_ast(), vcg_ast(),
skipConstraints(), skipConstraints(),
@ -4099,11 +4104,12 @@ struct HdrGenState final
inEnumDecl() 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), hdrgen(hdrgen),
ddoc(ddoc), ddoc(ddoc),
fullDump(fullDump), fullDump(fullDump),
importcHdr(importcHdr), importcHdr(importcHdr),
inCAlias(inCAlias),
doFuncBodies(doFuncBodies), doFuncBodies(doFuncBodies),
vcg_ast(vcg_ast), vcg_ast(vcg_ast),
skipConstraints(skipConstraints), skipConstraints(skipConstraints),

View file

@ -59,6 +59,7 @@ struct HdrGenState
bool ddoc; /// true if generating Ddoc file bool ddoc; /// true if generating Ddoc file
bool fullDump; /// true if generating a full AST dump file bool fullDump; /// true if generating a full AST dump file
bool importcHdr; /// true if generating a .di file from an ImportC 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 doFuncBodies; /// include function bodies in output
bool vcg_ast; /// write out codegen-ast bool vcg_ast; /// write out codegen-ast
bool skipConstraints; // skip constraints when doing templates bool skipConstraints; // skip constraints when doing templates
@ -1777,7 +1778,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring(" = "); buf.writestring(" = ");
if (stcToBuffer(buf, d.storage_class)) if (stcToBuffer(buf, d.storage_class))
buf.writeByte(' '); buf.writeByte(' ');
hgs.inCAlias = hgs.importcHdr;
typeToBuffer(d.type, null, buf, hgs); typeToBuffer(d.type, null, buf, hgs);
hgs.inCAlias = false;
hgs.declstring = false; hgs.declstring = false;
} }
buf.writeByte(';'); buf.writeByte(';');
@ -4449,6 +4452,11 @@ private void typeToBufferx(Type t, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring("noreturn"); buf.writestring("noreturn");
} }
if (hgs.importcHdr && !hgs.inCAlias && t.mcache && t.mcache.typedefIdent)
{
buf.writestring(t.mcache.typedefIdent.toString());
return;
}
switch (t.ty) switch (t.ty)
{ {

View file

@ -302,6 +302,10 @@ extern (C++) abstract class Type : ASTNode
Type pto; // merged pointer to this type Type pto; // merged pointer to this type
Type rto; // reference to this type Type rto; // reference to this type
Type arrayof; // array of 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; Mcache* mcache;

View file

@ -41,6 +41,18 @@ extern (C)
int x = void; int x = void;
} }
alias weird = int[(cast(foo*)cast(void*)0).x.sizeof]; 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 __DATE__ = 1+/;
/+enum int __TIME__ = 1+/; /+enum int __TIME__ = 1+/;
/+enum int __TIMESTAMP__ = 1+/; /+enum int __TIMESTAMP__ = 1+/;
@ -96,3 +108,19 @@ struct foo {
int x; int x;
}; };
typedef int weird[sizeof(((struct foo *)((void*)0))->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];