diff --git a/compiler/src/dmd/dtoh.d b/compiler/src/dmd/dtoh.d index 6badbada3b32..f8b8ec822ffa 100644 --- a/compiler/src/dmd/dtoh.d +++ b/compiler/src/dmd/dtoh.d @@ -536,6 +536,13 @@ public: } /// Checks whether `t` is a type that can be exported to C++ + private static bool containsSizeT(AST.Type t) + { + for (auto tp = t.isTypePointer(); tp; tp = t.isTypePointer()) + t = tp.next; + return t == AST.Type.tsize_t || t == AST.Type.tptrdiff_t; + } + private bool isSupportedType(AST.Type t) { if (!t) @@ -951,7 +958,7 @@ public: return; } - if (vd.originalType && vd.type == AST.Type.tsize_t) + if (vd.originalType && containsSizeT(vd.type)) origType = vd.originalType; scope(exit) origType = null; @@ -1131,9 +1138,10 @@ public: return; } - // for function pointers we need to original type - if (ad.originalType && ad.type.ty == AST.Tpointer && - (cast(AST.TypePointer)t).nextOf.ty == AST.Tfunction) + // for function pointers and size_t/ptrdiff_t we need the original type + if (ad.originalType && + ((ad.type.ty == AST.Tpointer && (cast(AST.TypePointer)t).nextOf.ty == AST.Tfunction) || + containsSizeT(ad.type))) { origType = ad.originalType; } @@ -1414,7 +1422,10 @@ public: buf.writestring(", "); assert(vd.type); assert(vd.ident); + if (vd.originalType && containsSizeT(vd.type)) + origType = vd.originalType; typeToBuffer(vd.type, vd, true); + origType = null; // Don't print default value for first parameter to not clash // with the default ctor defined above if (!first) @@ -3012,6 +3023,11 @@ public: */ private void ensureDeclared(AST.Dsymbol sym) { + // size_t and ptrdiff_t are provided by #include + if (auto ad = sym.isAliasDeclaration()) + if (ad.ident == Id._size_t || ad.ident == Id._ptrdiff_t) + return; + auto par = sym.toParent2(); auto ed = sym.isEnumDeclaration(); diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index a5b710cfd503..ee13aea91141 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -676,7 +676,7 @@ class Dsymbol : public ASTNode struct BitArray final { - typedef uint64_t Chunk_t; + typedef size_t Chunk_t; enum : uint64_t { ChunkSize = 8LLU }; enum : uint64_t { BitsPerChunk = 64LLU }; @@ -684,14 +684,14 @@ struct BitArray final private: ~BitArray(); size_t len; - uint64_t* ptr; + size_t* ptr; public: BitArray() : len(), ptr() { } - BitArray(uint64_t len, uint64_t* ptr = nullptr) : + BitArray(size_t len, size_t* ptr = nullptr) : len(len), ptr(ptr) {} diff --git a/compiler/test/compilable/dtoh_18015.d b/compiler/test/compilable/dtoh_18015.d new file mode 100644 index 000000000000..f86a9d3120b8 --- /dev/null +++ b/compiler/test/compilable/dtoh_18015.d @@ -0,0 +1,48 @@ +/* +REQUIRED_ARGS: -HC -c -o- +PERMUTE_ARGS: +TEST_OUTPUT: +--- +// Automatically generated by Digital Mars D Compiler + +#pragma once + +#include +#include +#include +#include + +struct BitArray final +{ + typedef size_t Chunk_t; + size_t len; + size_t* ptr; + BitArray() : + len(), + ptr() + { + } + BitArray(size_t len, size_t* ptr = nullptr) : + len(len), + ptr(ptr) + {} +}; + +typedef ptrdiff_t MyDiff; + +--- +*/ + +// https://github.com/dlang/dmd/issues/18015 +// dtoh: Insufficient size_t/ptrdiff_t detection + +extern(C++): + +struct BitArray +{ + alias Chunk_t = size_t; + size_t len; + size_t* ptr; +} + +alias MyDiff = ptrdiff_t;