Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/dmd/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,15 @@ public:
if (t.isImmutable() || t.isShared())
return error(t);

/* __c_long and __c_ulong get special mangling
*/
const id = t.sym.ident;
//printf("struct id = '%s'\n", id.toChars());
if (id == Id.__c_long)
return writeBasicType(t, 0, 'l');
else if (id == Id.__c_ulong)
return writeBasicType(t, 0, 'm');

doSymbol(t);
}

Expand Down
96 changes: 62 additions & 34 deletions src/dmd/cppmanglewin.d
Original file line number Diff line number Diff line change
Expand Up @@ -404,42 +404,70 @@ public:
override void visit(TypeEnum type)
{
//printf("visit(TypeEnum); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
if (checkTypeSaved(type))
return;
mangleModifier(type);
buf.writeByte('W');
switch (type.sym.memtype.ty)
const id = type.sym.ident;
char c;
if (id == Id.__c_long_double)
c = 'O'; // VC++ long double
else if (id == Id.__c_long)
c = 'J'; // VC++ long
else if (id == Id.__c_ulong)
c = 'K'; // VC++ unsigned long
else
c = 0;
if (c)
{
case Tchar:
case Tint8:
buf.writeByte('0');
break;
case Tuns8:
buf.writeByte('1');
break;
case Tint16:
buf.writeByte('2');
break;
case Tuns16:
buf.writeByte('3');
break;
case Tint32:
buf.writeByte('4');
break;
case Tuns32:
buf.writeByte('5');
break;
case Tint64:
buf.writeByte('6');
break;
case Tuns64:
buf.writeByte('7');
break;
default:
visit(cast(Type)type);
break;
if (type.isImmutable() || type.isShared())
{
visit(cast(Type)type);
return;
}
if (type.isConst() && ((flags & IS_NOT_TOP_TYPE) || (flags & IS_DMC)))
{
if (checkTypeSaved(type))
return;
}
mangleModifier(type);
buf.writeByte(c);
}
else
{
if (checkTypeSaved(type))
return;
mangleModifier(type);
buf.writeByte('W');
switch (type.sym.memtype.ty)
{
case Tchar:
case Tint8:
buf.writeByte('0');
break;
case Tuns8:
buf.writeByte('1');
break;
case Tint16:
buf.writeByte('2');
break;
case Tuns16:
buf.writeByte('3');
break;
case Tint32:
buf.writeByte('4');
break;
case Tuns32:
buf.writeByte('5');
break;
case Tint64:
buf.writeByte('6');
break;
case Tuns64:
buf.writeByte('7');
break;
default:
visit(cast(Type)type);
break;
}
mangleIdent(type.sym);
}
mangleIdent(type.sym);
flags &= ~IS_NOT_TOP_TYPE;
flags &= ~IGNORE_CONST;
}
Expand Down
28 changes: 28 additions & 0 deletions src/dmd/denum.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

module dmd.denum;

import core.stdc.stdio;

import dmd.gluelayer;
import dmd.declaration;
import dmd.dscope;
Expand Down Expand Up @@ -195,6 +197,13 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return errorReturn();
if (semanticRun == PASS.init || !members)
{
if (isSpecial())
{
/* Allow these special enums to not need a member list
*/
return memtype.getProperty(loc, id, 0);
}

error("is forward referenced looking for `.%s`", id.toChars());
return errorReturn();
}
Expand Down Expand Up @@ -249,6 +258,18 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return e;
}

/****************
* Determine if enum is a 'special' one.
* Returns:
* true if special
*/
final bool isSpecial() const nothrow @nogc
{
return (ident == Id.__c_long ||
ident == Id.__c_ulong ||
ident == Id.__c_long_double) && memtype;
}

Expression getDefaultValue(const ref Loc loc)
{
//printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
Expand All @@ -261,6 +282,13 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
goto Lerrors;
if (semanticRun == PASS.init || !members)
{
if (isSpecial())
{
/* Allow these special enums to not need a member list
*/
return memtype.defaultInit(loc);
}

error(loc, "forward reference of `%s.init`", toChars());
goto Lerrors;
}
Expand Down
13 changes: 12 additions & 1 deletion src/dmd/glue.d
Original file line number Diff line number Diff line change
Expand Up @@ -1434,8 +1434,19 @@ uint totym(Type tx)
break;

case Tenum:
t = totym(tx.toBasetype());
{
Type tb = tx.toBasetype();
const id = tx.toDsymbol(null).ident;
if (id == Id.__c_long)
t = tb.ty == Tint32 ? TYlong : TYllong;
else if (id == Id.__c_ulong)
t = tb.ty == Tuns32 ? TYulong : TYullong;
else if (id == Id.__c_long_double)
t = TYdouble;
else
t = totym(tb);
break;
}

case Tident:
case Ttypeof:
Expand Down
13 changes: 13 additions & 0 deletions src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,19 @@ extern (C++) final class TypeBasic : Type
TypeVector tv = cast(TypeVector)to;
tob = tv.elementType();
}
else if (to.ty == Tenum)
{
EnumDeclaration ed = (cast(TypeEnum)to).sym;
if (ed.isSpecial())
{
/* Special enums that allow implicit conversions to them
* with a MATCH.convert
*/
tob = to.toBasetype().isTypeBasic();
}
else
return MATCH.nomatch;
}
else
tob = to.isTypeBasic();
if (!tob)
Expand Down
17 changes: 13 additions & 4 deletions src/dmd/toctype.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import dmd.backend.ty;
import dmd.backend.type;

import dmd.declaration;
import dmd.denum;
import dmd.dstruct;
import dmd.globals;
import dmd.glue;
Expand Down Expand Up @@ -170,18 +171,26 @@ public:
//printf("TypeEnum::toCtype() '%s'\n", t.sym.toChars());
if (t.mod == 0)
{
if (!t.sym.memtype)
EnumDeclaration sym = t.sym;
auto symMemtype = sym.memtype;
if (!symMemtype)
{
// https://issues.dlang.org/show_bug.cgi?id=13792
t.ctype = Type_toCtype(Type.tvoid);
}
else if (t.sym.memtype.toBasetype().ty == Tint32)
else if (sym.ident == Id.__c_long)
{
t.ctype = type_enum(t.sym.toPrettyChars(true), Type_toCtype(t.sym.memtype));
t.ctype = type_fake(totym(t));
t.ctype.Tcount++;
return;
}
else if (symMemtype.toBasetype().ty == Tint32)
{
t.ctype = type_enum(sym.toPrettyChars(true), Type_toCtype(symMemtype));
}
else
{
t.ctype = Type_toCtype(t.sym.memtype);
t.ctype = Type_toCtype(symMemtype);
}

if (global.params.symdebugref)
Expand Down
8 changes: 7 additions & 1 deletion src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -3380,7 +3380,13 @@ private extern(C++) final class DotExpVisitor : Visitor
mt.sym.dsymbolSemantic(null);
if (!mt.sym.members)
{
if (!(flag & 1))
if (mt.sym.isSpecial())
{
/* Special enums forward to the base type
*/
e = mt.sym.memtype.dotExp(sc, e, ident, flag);
}
else if (!(flag & 1))
{
mt.sym.error("is forward referenced when looking for `%s`", ident.toChars());
e = new ErrorExp();
Expand Down
Loading