From f432256494a339e1bdf683cf47fdd6f8b77cb6f5 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Tue, 29 Dec 2020 16:20:49 +0100 Subject: [PATCH] Implement -preview=complex --- src/dmd/cli.d | 2 ++ src/dmd/cppmangle.d | 8 +++++++- src/dmd/denum.d | 5 ++++- src/dmd/dtoh.d | 12 ++++++++++++ src/dmd/frontend.h | 5 +++++ src/dmd/globals.d | 3 ++- src/dmd/globals.h | 3 ++- src/dmd/glue.d | 6 ++++++ src/dmd/id.d | 3 +++ src/dmd/lexer.d | 18 +++++++++++++++++- src/dmd/target.d | 16 +++++++++++++++- src/dmd/toctype.d | 5 ++++- test/compilable/previewhelp.d | 1 + 13 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/dmd/cli.d b/src/dmd/cli.d index 0c70815c9757..d4aaa5de730a 100644 --- a/src/dmd/cli.d +++ b/src/dmd/cli.d @@ -794,6 +794,8 @@ dmd -cov -unittest myprog.d "'in' contracts of overridden methods must be a superset of parent contract"), Feature("shortenedMethods", "shortenedMethods", "allow use of => for methods and top-level functions in addition to lambdas"), + Feature("complex", "previewComplex", + "remove complex and imaginary types from the language"), // DEPRECATED previews // trigger deprecation message once D repositories don't use this flag anymore Feature("markdown", "markdown", "enable Markdown replacements in Ddoc", false, false), diff --git a/src/dmd/cppmangle.d b/src/dmd/cppmangle.d index b9261b4af632..264cb6b51824 100644 --- a/src/dmd/cppmangle.d +++ b/src/dmd/cppmangle.d @@ -1835,7 +1835,7 @@ extern(C++): if (t.isImmutable() || t.isShared()) return error(t); - /* __c_(u)long(long) get special mangling + /* __c_(u)long(long) and others get special mangling */ const id = t.sym.ident; //printf("enum id = '%s'\n", id.toChars()); @@ -1849,6 +1849,12 @@ extern(C++): return writeBasicType(t, 0, 'x'); else if (id == Id.__c_ulonglong) return writeBasicType(t, 0, 'y'); + else if (id == Id.__c_complex_float) + return writeBasicType(t, 'C', 'f'); + else if (id == Id.__c_complex_double) + return writeBasicType(t, 'C', 'd'); + else if (id == Id.__c_complex_long_double) + return writeBasicType(t, 'C', 'e'); doSymbol(t); } diff --git a/src/dmd/denum.d b/src/dmd/denum.d index 7f1364fa215a..b44174bbf893 100644 --- a/src/dmd/denum.d +++ b/src/dmd/denum.d @@ -470,5 +470,8 @@ bool isSpecialEnumIdent(const Identifier ident) @nogc nothrow ident == Id.__c_longlong || ident == Id.__c_ulonglong || ident == Id.__c_long_double || - ident == Id.__c_wchar_t; + ident == Id.__c_wchar_t || + ident == Id.__c_complex_float || + ident == Id.__c_complex_double || + ident == Id.__c_complex_long_double; } diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index f6e99f42a502..e769f1cb80e4 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -38,6 +38,9 @@ private struct DMDType __gshared Identifier c_ulonglong; __gshared Identifier c_long_double; __gshared Identifier c_wchar_t; + __gshared Identifier c_complex_float; + __gshared Identifier c_complex_double; + __gshared Identifier c_complex_long_double; static void _init() { @@ -47,6 +50,9 @@ private struct DMDType c_ulonglong = Identifier.idPool("__c_ulonglong"); c_long_double = Identifier.idPool("__c_long_double"); c_wchar_t = Identifier.idPool("__c_wchar_t"); + c_complex_float = Identifier.idPool("__c_complex_float"); + c_complex_double = Identifier.idPool("__c_complex_double"); + c_complex_long_double = Identifier.idPool("__c_complex_long_double"); } } @@ -1744,6 +1750,12 @@ public: buf.writestring("long double"); else if (ed.ident == DMDType.c_wchar_t) buf.writestring("wchar_t"); + else if (ed.ident == DMDType.c_complex_float) + buf.writestring("_Complex float"); + else if (ed.ident == DMDType.c_complex_double) + buf.writestring("_Complex double"); + else if (ed.ident == DMDType.c_complex_long_double) + buf.writestring("_Complex long double"); else { //ed.print(); diff --git a/src/dmd/frontend.h b/src/dmd/frontend.h index 85d9510526e9..f24a71530548 100644 --- a/src/dmd/frontend.h +++ b/src/dmd/frontend.h @@ -6825,6 +6825,7 @@ struct Param bool vgc; bool vfield; bool vcomplex; + bool previewComplex; uint8_t symdebug; bool symdebugref; bool optimize; @@ -6958,6 +6959,7 @@ struct Param vgc(), vfield(), vcomplex(), + previewComplex(), symdebug(), symdebugref(), optimize(), @@ -7396,6 +7398,9 @@ struct Id static Identifier* __c_ulonglong; static Identifier* __c_long_double; static Identifier* __c_wchar_t; + static Identifier* __c_complex_float; + static Identifier* __c_complex_double; + static Identifier* __c_complex_long_double; static Identifier* cpp_type_info_ptr; static Identifier* _assert; static Identifier* _unittest; diff --git a/src/dmd/globals.d b/src/dmd/globals.d index ec031ab93ae3..83de3979b266 100644 --- a/src/dmd/globals.d +++ b/src/dmd/globals.d @@ -165,7 +165,8 @@ extern (C++) struct Param bool vtemplatesListInstances; // collect and list statistics on template instantiations origins. TODO: make this an enum when we want to list other kinds of instances bool vgc; // identify gc usage bool vfield; // identify non-mutable field variables - bool vcomplex; // identify complex/imaginary type usage + bool vcomplex; // deprecate complex imaginary types + bool previewComplex; // remove complex and imaginary types ubyte symdebug; // insert debug symbolic information bool symdebugref; // insert debug information for all referenced types, too bool optimize; // run optimizer diff --git a/src/dmd/globals.h b/src/dmd/globals.h index 0d302a38dc05..3cc136b31238 100644 --- a/src/dmd/globals.h +++ b/src/dmd/globals.h @@ -145,7 +145,8 @@ struct Param bool vtemplatesListInstances; // collect and list statistics on template instantiations origins bool vgc; // identify gc usage bool vfield; // identify non-mutable field variables - bool vcomplex; // identify complex/imaginary type usage + bool vcomplex; // deprecate complex imaginary types + bool previewComplex; // remove complex and imaginary types unsigned char symdebug; // insert debug symbolic information bool symdebugref; // insert debug information for all referenced types, too bool optimize; // run optimizer diff --git a/src/dmd/glue.d b/src/dmd/glue.d index 6e6dc25ed5d4..77ca0175351c 100644 --- a/src/dmd/glue.d +++ b/src/dmd/glue.d @@ -1278,6 +1278,12 @@ tym_t totym(Type tx) t = tb.ty == Tuns32 ? TYulong : TYullong; else if (id == Id.__c_long_double) t = TYdouble; + else if (id == Id.__c_complex_float) + t = TYcfloat; + else if (id == Id.__c_complex_double) + t = TYcdouble; + else if (id == Id.__c_complex_long_double) + t = TYcldouble; else t = totym(tb); break; diff --git a/src/dmd/id.d b/src/dmd/id.d index b988427945b0..3fc51fa10518 100644 --- a/src/dmd/id.d +++ b/src/dmd/id.d @@ -125,6 +125,9 @@ immutable Msgtable[] msgtable = { "__c_ulonglong" }, { "__c_long_double" }, { "__c_wchar_t" }, + { "__c_complex_float" }, + { "__c_complex_double" }, + { "__c_complex_long_double" }, { "cpp_type_info_ptr", "__cpp_type_info_ptr" }, { "_assert", "assert" }, { "_unittest", "unittest" }, diff --git a/src/dmd/lexer.d b/src/dmd/lexer.d index 994ebbe8a9c0..d54075bade63 100644 --- a/src/dmd/lexer.d +++ b/src/dmd/lexer.d @@ -575,6 +575,22 @@ class Lexer p++; } } + if (global.params.previewComplex) + { + switch (t.value) + { + case TOK.imaginary32: + case TOK.imaginary64: + case TOK.imaginary80: + case TOK.complex32: + case TOK.complex64: + case TOK.complex80: + t.value = TOK.identifier; + break; + default: + break; + } + } //printf("t.value = %d\n",t.value); return; } @@ -2242,7 +2258,7 @@ class Lexer p++; break; } - if (*p == 'i' || *p == 'I') + if ((*p == 'i' || *p == 'I') && !global.params.previewComplex) { if (*p == 'I') error("use 'i' suffix instead of 'I'"); diff --git a/src/dmd/target.d b/src/dmd/target.d index 6d25051e6389..0707134a45aa 100644 --- a/src/dmd/target.d +++ b/src/dmd/target.d @@ -579,7 +579,21 @@ extern (C++) struct Target return false; // returns a pointer } - Type tn = tf.next.toBasetype(); + Type tn = tf.next; + if (auto te = tn.isTypeEnum()) + { + if (te.sym.isSpecial()) + { + // Special enums with target-specific return style + if (te.sym.ident == Id.__c_complex_float) + tn = Type.tcomplex32.castMod(tn.mod); + else if (te.sym.ident == Id.__c_complex_double) + tn = Type.tcomplex64.castMod(tn.mod); + else if (te.sym.ident == Id.__c_complex_long_double) + tn = Type.tcomplex80.castMod(tn.mod); + } + } + tn = tn.toBasetype(); //printf("tn = %s\n", tn.toChars()); d_uns64 sz = tn.size(); Type tns = tn; diff --git a/src/dmd/toctype.d b/src/dmd/toctype.d index c6648ea31d3e..11ecd65aa58d 100644 --- a/src/dmd/toctype.d +++ b/src/dmd/toctype.d @@ -206,7 +206,10 @@ public: // https://issues.dlang.org/show_bug.cgi?id=13792 t.ctype = Type_toCtype(Type.tvoid); } - else if (sym.ident == Id.__c_long) + else if (sym.ident == Id.__c_long || + sym.ident == Id.__c_complex_float || + sym.ident == Id.__c_complex_double || + sym.ident == Id.__c_complex_long_double) { t.ctype = type_fake(totym(t)); t.ctype.Tcount++; diff --git a/test/compilable/previewhelp.d b/test/compilable/previewhelp.d index 391adca8fc42..9497659d581e 100644 --- a/test/compilable/previewhelp.d +++ b/test/compilable/previewhelp.d @@ -18,5 +18,6 @@ Upcoming language changes listed by -preview=name: =in `in` on parameters means `scope const [ref]` and accepts rvalues =inclusiveincontracts 'in' contracts of overridden methods must be a superset of parent contract =shortenedMethods allow use of => for methods and top-level functions in addition to lambdas + =complex remove complex and imaginary types from the language ---- */