From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 8FC933858410; Mon, 16 Oct 2023 17:49:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8FC933858410 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697478570; bh=JydOvFw5aWcADrd3M6BLXB+npTDWxz+sN7wi14byMzo=; h=From:To:Subject:Date:From; b=bzgQ4Iq40+NCBPKgDOLHkQS5Rkd6ME9tCdRaVu1TnrgJPTep6MaD/FnLlknrCZjpY YFpuGaK3Wf9AITjOhrH31DekYQDxThhIUBFzRTBbGTfJrKVtE3EKTYZKFNZngm3PKu riAvH2ovpo1a++Cu9IHi02kiGccPPqjBNXwvEdcc= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4663] d: Merge upstream dmd, druntime 4c18eed967, phobos d945686a4. X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/master X-Git-Oldrev: c7609acb8a8210188d21b2cd72ecc6d3b2de2ab8 X-Git-Newrev: 964fd402c9b48eb4da91fb3e4e45d4560d6c676c Message-Id: <20231016174930.8FC933858410@sourceware.org> Date: Mon, 16 Oct 2023 17:49:30 +0000 (GMT) List-Id: https://gcc.gnu.org/g:964fd402c9b48eb4da91fb3e4e45d4560d6c676c commit r14-4663-g964fd402c9b48eb4da91fb3e4e45d4560d6c676c Author: Iain Buclaw Date: Sun Oct 15 19:09:05 2023 +0200 d: Merge upstream dmd, druntime 4c18eed967, phobos d945686a4. D front-end changes: - Import latest fixes to mainline. D runtime changes: - Import latest fixes to mainline. Phobos changes: - Import latest fixes to mainline. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 4c18eed967. * d-diagnostic.cc (verrorReport): Update for new front-end interface. (verrorReportSupplemental): Likewise. * d-lang.cc (d_init_options): Likewise. (d_handle_option): Likewise. (d_post_options): Likewise. (d_parse_file): Likewise. * decl.cc (get_symbol_decl): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 4c18eed967. * src/MERGE: Merge upstream phobos d945686a4. Diff: --- gcc/d/d-diagnostic.cc | 4 +- gcc/d/d-lang.cc | 86 +-- gcc/d/decl.cc | 4 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/access.d | 3 +- gcc/d/dmd/aggregate.d | 11 +- gcc/d/dmd/aggregate.h | 1 + gcc/d/dmd/arrayop.d | 11 +- gcc/d/dmd/attrib.d | 7 +- gcc/d/dmd/blockexit.d | 19 +- gcc/d/dmd/canthrow.d | 43 +- gcc/d/dmd/clone.d | 2 +- gcc/d/dmd/compiler.d | 1 - gcc/d/dmd/cond.d | 4 + gcc/d/dmd/constfold.d | 18 +- gcc/d/dmd/cparse.d | 5 +- gcc/d/dmd/cppmangle.d | 10 +- gcc/d/dmd/ctfe.h | 1 - gcc/d/dmd/ctfeexpr.d | 8 +- gcc/d/dmd/dcast.d | 53 +- gcc/d/dmd/dclass.d | 58 +- gcc/d/dmd/declaration.d | 16 +- gcc/d/dmd/denum.d | 5 +- gcc/d/dmd/dimport.d | 2 +- gcc/d/dmd/dinterpret.d | 296 ++++---- gcc/d/dmd/dmangle.d | 20 +- gcc/d/dmd/dmodule.d | 44 +- gcc/d/dmd/doc.d | 2 +- gcc/d/dmd/dstruct.d | 2 +- gcc/d/dmd/dsymbol.d | 87 +-- gcc/d/dmd/dsymbol.h | 4 - gcc/d/dmd/dsymbolsem.d | 306 ++++----- gcc/d/dmd/dtemplate.d | 69 +- gcc/d/dmd/dtoh.d | 20 + gcc/d/dmd/dversion.d | 13 +- gcc/d/dmd/expression.d | 336 +++------ gcc/d/dmd/expression.h | 6 +- gcc/d/dmd/expressionsem.d | 439 ++++++------ gcc/d/dmd/func.d | 36 +- gcc/d/dmd/globals.d | 57 +- gcc/d/dmd/globals.h | 48 +- gcc/d/dmd/hdrgen.d | 760 +++++++++++---------- gcc/d/dmd/iasm.d | 1 + gcc/d/dmd/id.d | 2 + gcc/d/dmd/importc.d | 5 +- gcc/d/dmd/init.d | 8 - gcc/d/dmd/init.h | 2 - gcc/d/dmd/initsem.d | 31 +- gcc/d/dmd/json.d | 4 +- gcc/d/dmd/lexer.d | 75 +- gcc/d/dmd/mtype.d | 6 +- gcc/d/dmd/mustuse.d | 3 +- gcc/d/dmd/nogc.d | 4 +- gcc/d/dmd/nspace.d | 3 +- gcc/d/dmd/ob.d | 20 +- gcc/d/dmd/objc.d | 32 +- gcc/d/dmd/opover.d | 32 +- gcc/d/dmd/optimize.d | 53 +- gcc/d/dmd/parse.d | 15 +- gcc/d/dmd/root/filename.d | 7 +- gcc/d/dmd/root/rootobject.d | 6 +- gcc/d/dmd/semantic2.d | 34 +- gcc/d/dmd/semantic3.d | 48 +- gcc/d/dmd/sideeffect.d | 9 +- gcc/d/dmd/statement.d | 167 +---- gcc/d/dmd/statement.h | 8 +- gcc/d/dmd/statementsem.d | 192 +++++- gcc/d/dmd/staticcond.d | 3 +- gcc/d/dmd/traits.d | 104 +-- gcc/d/dmd/typesem.d | 42 +- gcc/d/dmd/typinf.d | 4 + .../gdc.test/compilable/dtoh_TemplateDeclaration.d | 2 - gcc/testsuite/gdc.test/compilable/issue24174.d | 36 + .../testpull1810.d | 2 +- .../{fail_compilation => compilable}/warn12809.d | 28 +- gcc/testsuite/gdc.test/fail_compilation/ccast.d | 10 +- gcc/testsuite/gdc.test/fail_compilation/fail235.d | 4 +- .../gdc.test/fail_compilation/hexstring.d | 18 + gcc/testsuite/gdc.test/fail_compilation/ice6538.d | 2 +- .../gdc.test/fail_compilation/issue11070.d | 17 + .../gdc.test/fail_compilation/issue3396.d | 24 + .../gdc.test/fail_compilation/reserved_version.d | 98 +-- .../fail_compilation/reserved_version_switch.d | 12 + .../gdc.test/fail_compilation/test20522.d | 23 + gcc/testsuite/gdc.test/runnable/issue11070.d | 19 + gcc/testsuite/gdc.test/runnable/staticaa.d | 27 + gcc/testsuite/gdc.test/runnable/template9.d | 7 + libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/stdc/errno.d | 103 +++ libphobos/libdruntime/core/stdc/fenv.d | 31 + libphobos/libdruntime/core/stdc/math.d | 7 + libphobos/libdruntime/core/sys/linux/dlfcn.d | 14 + libphobos/libdruntime/core/sys/linux/epoll.d | 8 + libphobos/libdruntime/core/sys/linux/link.d | 6 + libphobos/libdruntime/core/sys/linux/perf_event.d | 4 + libphobos/libdruntime/core/sys/linux/sys/eventfd.d | 6 + libphobos/libdruntime/core/sys/linux/sys/inotify.d | 5 + libphobos/libdruntime/core/sys/linux/sys/mman.d | 24 + libphobos/libdruntime/core/sys/posix/dlfcn.d | 12 + libphobos/libdruntime/core/sys/posix/fcntl.d | 35 +- libphobos/libdruntime/core/sys/posix/setjmp.d | 15 + libphobos/libdruntime/core/sys/posix/signal.d | 34 + libphobos/libdruntime/core/sys/posix/sys/mman.d | 2 + libphobos/libdruntime/core/sys/posix/sys/msg.d | 1 + libphobos/libdruntime/core/sys/posix/sys/socket.d | 34 + libphobos/libdruntime/core/sys/posix/sys/stat.d | 60 ++ libphobos/libdruntime/core/sys/posix/sys/types.d | 12 + libphobos/libdruntime/core/sys/posix/ucontext.d | 27 + libphobos/libdruntime/core/thread/fiber.d | 26 + libphobos/src/MERGE | 2 +- libphobos/src/std/algorithm/iteration.d | 6 +- libphobos/src/std/range/primitives.d | 24 +- 112 files changed, 2727 insertions(+), 1941 deletions(-) diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc index b698d4e49b85..b3ad60cb099b 100644 --- a/gcc/d/d-diagnostic.cc +++ b/gcc/d/d-diagnostic.cc @@ -233,7 +233,7 @@ verrorReport (const Loc& loc, const char *format, va_list ap, ErrorKind kind, if (global.gag) global.gaggedErrors++; - if (global.gag && !global.params.showGaggedErrors) + if (global.gag && !global.params.v.showGaggedErrors) return; diag_kind = global.gag ? DK_ANACHRONISM : DK_ERROR; @@ -308,7 +308,7 @@ verrorReportSupplemental (const Loc& loc, const char* format, va_list ap, { if (kind == ErrorKind::error) { - if (global.gag && !global.params.showGaggedErrors) + if (global.gag && !global.params.v.showGaggedErrors) return; } else if (kind == ErrorKind::warning) diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 6509d766708d..902fd86b5abc 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -295,7 +295,6 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) global.compileEnv.vendor = lang_hooks.name; global.params.argv0 = xstrdup (decoded_options[0].arg); - global.params.errorLimit = flag_max_errors; /* Default extern(C++) mangling to C++17. */ global.params.cplusplus = CppStdRevisionCpp17; @@ -303,7 +302,8 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) /* Warnings and deprecations are disabled by default. */ global.params.useDeprecated = DIAGNOSTICinform; global.params.warnings = DIAGNOSTICoff; - global.params.messageStyle = MessageStyle::gnu; + global.params.v.errorLimit = flag_max_errors; + global.params.v.messageStyle = MessageStyle::gnu; global.params.imppath = d_gc_malloc (); global.params.fileImppath = d_gc_malloc (); @@ -458,9 +458,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_fdebug_: if (Identifier::isValidIdentifier (CONST_CAST (char *, arg))) { - if (!global.params.debugids) - global.params.debugids = d_gc_malloc (); - global.params.debugids->push (arg); + DebugCondition::addGlobalIdent (arg); break; } @@ -662,30 +660,30 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, break; case OPT_ftransition_all: - global.params.vfield = value; - global.params.vgc = value; - global.params.vin = value; - global.params.vtls = value; + global.params.v.field = value; + global.params.v.gc = value; + global.params.v.vin = value; + global.params.v.tls = value; break; case OPT_ftransition_field: - global.params.vfield = value; + global.params.v.field = value; break; case OPT_ftransition_in: - global.params.vin = value; + global.params.v.vin = value; break; case OPT_ftransition_nogc: - global.params.vgc = value; + global.params.v.gc = value; break; case OPT_ftransition_templates: - global.params.vtemplates = value; + global.params.v.templates = value; break; case OPT_ftransition_tls: - global.params.vtls = value; + global.params.v.tls = value; break; case OPT_funittest: @@ -695,9 +693,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_fversion_: if (Identifier::isValidIdentifier (CONST_CAST (char *, arg))) { - if (!global.params.versionids) - global.params.versionids = d_gc_malloc (); - global.params.versionids->push (arg); + VersionCondition::addGlobalIdent (arg); break; } @@ -773,7 +769,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, break; case OPT_v: - global.params.verbose = value; + global.params.v.verbose = value; break; case OPT_Wall: @@ -792,7 +788,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_Wspeculative: if (value) - global.params.showGaggedErrors = 1; + global.params.v.showGaggedErrors = 1; break; case OPT_Xf: @@ -916,19 +912,20 @@ d_post_options (const char ** fn) && global.params.warnings == DIAGNOSTICerror) global.params.useDeprecated = DIAGNOSTICerror; - /* Make -fmax-errors visible to frontend's diagnostic machinery. */ - if (OPTION_SET_P (flag_max_errors)) - global.params.errorLimit = flag_max_errors; - if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) flag_excess_precision = EXCESS_PRECISION_STANDARD; global.params.useInline = flag_inline_functions; - global.params.showColumns = flag_show_column; - global.params.printErrorContext = flag_diagnostics_show_caret; + + /* Make -fmax-errors visible to frontend's diagnostic machinery. */ + if (OPTION_SET_P (flag_max_errors)) + global.params.v.errorLimit = flag_max_errors; + + global.params.v.showColumns = flag_show_column; + global.params.v.printErrorContext = flag_diagnostics_show_caret; /* Keep the front-end location type in sync with params. */ - Loc::set (global.params.showColumns, global.params.messageStyle); + Loc::set (global.params.v.showColumns, global.params.v.messageStyle); if (global.params.useInline) global.params.dihdr.fullOutput = true; @@ -941,25 +938,6 @@ d_post_options (const char ** fn) global.compileEnv.ddocOutput = global.params.ddoc.doOutput; global.compileEnv.shortenedMethods = global.params.shortenedMethods; - /* Add in versions given on the command line. */ - if (global.params.versionids) - { - for (size_t i = 0; i < global.params.versionids->length; i++) - { - const char *s = (*global.params.versionids)[i]; - VersionCondition::addGlobalIdent (s); - } - } - - if (global.params.debugids) - { - for (size_t i = 0; i < global.params.debugids->length; i++) - { - const char *s = (*global.params.debugids)[i]; - DebugCondition::addGlobalIdent (s); - } - } - if (warn_return_type == -1) warn_return_type = 0; @@ -1065,7 +1043,7 @@ d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf) static void d_parse_file (void) { - if (global.params.verbose) + if (global.params.v.verbose) { message ("binary %s", global.params.argv0.ptr); message ("version %s", global.versionChars ()); @@ -1175,7 +1153,7 @@ d_parse_file (void) { Module *m = modules[i]; - if (global.params.verbose) + if (global.params.v.verbose) message ("parse %s", m->toChars ()); if (!Module::rootModule) @@ -1227,7 +1205,7 @@ d_parse_file (void) || (d_option.fonly && m != Module::rootModule)) continue; - if (global.params.verbose) + if (global.params.v.verbose) message ("import %s", m->toChars ()); OutBuffer buf; @@ -1246,7 +1224,7 @@ d_parse_file (void) { Module *m = modules[i]; - if (global.params.verbose) + if (global.params.v.verbose) message ("importall %s", m->toChars ()); m->importAll (NULL); @@ -1270,7 +1248,7 @@ d_parse_file (void) continue; } - if (global.params.verbose) + if (global.params.v.verbose) message ("semantic %s", m->toChars ()); dsymbolSemantic (m, NULL); @@ -1301,7 +1279,7 @@ d_parse_file (void) { Module *m = modules[i]; - if (global.params.verbose) + if (global.params.v.verbose) message ("semantic2 %s", m->toChars ()); semantic2 (m, NULL); @@ -1317,7 +1295,7 @@ d_parse_file (void) { Module *m = modules[i]; - if (global.params.verbose) + if (global.params.v.verbose) message ("semantic3 %s", m->toChars ()); semantic3 (m, NULL); @@ -1365,7 +1343,7 @@ d_parse_file (void) (char *) obstack_finish (&buffer)); } - if (global.params.vtemplates) + if (global.params.v.templates) printTemplateStats (); /* Generate JSON files. */ @@ -1417,7 +1395,7 @@ d_parse_file (void) || (d_option.fonly && m != Module::rootModule)) continue; - if (global.params.verbose) + if (global.params.v.verbose) message ("code %s", m->toChars ()); if (!flag_syntax_only) diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 7e612e1cbbce..c80bb8aebd7b 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -968,7 +968,7 @@ public: return; } - if (global.params.verbose) + if (global.params.v.verbose) message ("function %s", d->toPrettyChars ()); tree old_context = start_function (d); @@ -1554,7 +1554,7 @@ get_symbol_decl (Declaration *decl) /* Symbol is going in thread local storage. */ if (decl->isThreadlocal () && !DECL_ARTIFICIAL (decl->csym)) { - if (global.params.vtls) + if (global.params.v.tls) message (decl->loc, "`%s` is thread local", decl->toChars ()); set_decl_tls_model (decl->csym, decl_default_tls_model (decl->csym)); diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index d5dfe0d0eddf..794600274a3b 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -f9efc98fd7954741333f72c6a50af273f3863a1a +4c18eed9674e04c1ca89fbc8bd5c4e483eb5477c The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/access.d b/gcc/d/dmd/access.d index ab9b5d9da485..1010c140b68e 100644 --- a/gcc/d/dmd/access.d +++ b/gcc/d/dmd/access.d @@ -20,6 +20,7 @@ import dmd.dmodule; import dmd.dscope; import dmd.dstruct; import dmd.dsymbol; +import dmd.errors; import dmd.expression; import dmd.location; import dmd.tokens; @@ -47,7 +48,7 @@ bool checkAccess(AggregateDeclaration ad, Loc loc, Scope* sc, Dsymbol smember) if (!symbolIsVisible(sc, smember)) { - ad.error(loc, "%s `%s` is not accessible", smember.kind(), smember.toChars()); + error(loc, "%s `%s` %s `%s` is not accessible", ad.kind(), ad.toPrettyChars(), smember.kind(), smember.toChars()); //printf("smember = %s %s, vis = %d, semanticRun = %d\n", // smember.kind(), smember.toPrettyChars(), smember.visible() smember.semanticRun); return true; diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index 4ae6b6bc5cc2..68b5f1b48f19 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -31,6 +31,7 @@ import dmd.errors; import dmd.expression; import dmd.func; import dmd.globals; +import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.location; @@ -213,7 +214,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol if (!members) { - error(loc, "unknown size"); + .error(loc, "%s `%s` unknown size", kind, toPrettyChars); return false; } @@ -243,7 +244,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol Lfail: // There's unresolvable forward reference. if (type != Type.terror) - error(loc, "no size because of forward reference"); + error(loc, "%s `%s` no size because of forward reference", kind, toPrettyChars); // Don't cache errors from speculative semantic, might be resolvable later. // https://issues.dlang.org/show_bug.cgi?id=16574 if (!global.gag) @@ -337,7 +338,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol else if (v2._init && i < j) { .error(v2.loc, "union field `%s` with default initialization `%s` must be before field `%s`", - v2.toChars(), v2._init.toChars(), vd.toChars()); + v2.toChars(), dmd.hdrgen.toChars(v2._init), vd.toChars()); errors = true; } } @@ -452,7 +453,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol assert(!vx._init.isVoidInitializer()); if (vx.inuse) // https://issues.dlang.org/show_bug.cgi?id=18057 { - vx.error(loc, "recursive initialization of field"); + .error(loc, "%s `%s` recursive initialization of field", vx.kind(), vx.toPrettyChars()); errors = true; } else @@ -753,7 +754,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol s.isTemplateDeclaration() || s.isOverloadSet())) { - s.error("is not a constructor; identifiers starting with `__` are reserved for the implementation"); + .error(s.loc, "%s `%s` is not a constructor; identifiers starting with `__` are reserved for the implementation", s.kind(), s.toPrettyChars()); errors = true; s = null; } diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index 03fe478685cf..4b107e0f2a9b 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -279,6 +279,7 @@ public: ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr + void classError(const char* fmt, const char* arg); static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject); const char *toPrettyChars(bool QualifyTypes = false) override; ClassDeclaration *syntaxCopy(Dsymbol *s) override; diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d index d8430733428d..25bbb3f32ad4 100644 --- a/gcc/d/dmd/arrayop.d +++ b/gcc/d/dmd/arrayop.d @@ -19,6 +19,7 @@ import dmd.astenums; import dmd.declaration; import dmd.dscope; import dmd.dsymbol; +import dmd.errors; import dmd.expression; import dmd.expressionsem; import dmd.func; @@ -92,7 +93,7 @@ bool checkNonAssignmentArrayOp(Expression e, bool suggestion = false) const(char)* s = ""; if (suggestion) s = " (possible missing [])"; - e.error("array operation `%s` without destination memory not allowed%s", e.toChars(), s); + error(e.loc, "array operation `%s` without destination memory not allowed%s", e.toChars(), s); return true; } return false; @@ -121,7 +122,7 @@ Expression arrayOp(BinExp e, Scope* sc) Type tbn = tb.nextOf().toBasetype(); if (tbn.ty == Tvoid) { - e.error("cannot perform array operations on `void[]` arrays"); + error(e.loc, "cannot perform array operations on `void[]` arrays"); return ErrorExp.get(); } if (!isArrayOpValid(e)) @@ -164,7 +165,7 @@ Expression arrayOp(BinAssignExp e, Scope* sc) if (tn && (!tn.isMutable() || !tn.isAssignable())) { - e.error("slice `%s` is not mutable", e.e1.toChars()); + error(e.loc, "slice `%s` is not mutable", e.e1.toChars()); if (e.op == EXP.addAssign) checkPossibleAddCatError!(AddAssignExp, CatAssignExp)(e.isAddAssignExp); return ErrorExp.get(); @@ -370,7 +371,7 @@ bool isArrayOpOperand(Expression e) ErrorExp arrayOpInvalidError(Expression e) { - e.error("invalid array operation `%s` (possible missing [])", e.toChars()); + error(e.loc, "invalid array operation `%s` (possible missing [])", e.toChars()); if (e.op == EXP.add) checkPossibleAddCatError!(AddExp, CatExp)(e.isAddExp()); else if (e.op == EXP.addAssign) @@ -383,5 +384,5 @@ private void checkPossibleAddCatError(AddT, CatT)(AddT ae) if (!ae.e2.type || ae.e2.type.ty != Tarray || !ae.e2.type.implicitConvTo(ae.e1.type)) return; CatT ce = new CatT(ae.loc, ae.e1, ae.e2); - ae.errorSupplemental("did you mean to concatenate (`%s`) instead ?", ce.toChars()); + errorSupplemental(ae.loc, "did you mean to concatenate (`%s`) instead ?", ce.toChars()); } diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index 5a91bc742291..7b5def1f765b 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -33,6 +33,7 @@ import dmd.dmodule; import dmd.dscope; import dmd.dsymbol; import dmd.dsymbolsem : dsymbolSemantic; +import dmd.errors; import dmd.expression; import dmd.expressionsem; import dmd.func; @@ -664,7 +665,7 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration { Package pkg = m.parent ? m.parent.isPackage() : null; if (!pkg || !visibility.pkg.isAncestorPackageOf(pkg)) - error("does not bind to one of ancestor packages of module `%s`", m.toPrettyChars(true)); + .error(loc, "%s `%s` does not bind to one of ancestor packages of module `%s`", kind(), toPrettyChars(false), m.toPrettyChars(true)); } } return AttribDeclaration.addMember(sc, sds); @@ -1473,12 +1474,12 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration { if (sym.isCPPNamespaceDeclaration() || sym.isNspace()) { - exp.error("`@%s` cannot be applied to namespaces", Id.udaGNUAbiTag.toChars()); + .error(exp.loc, "`@%s` cannot be applied to namespaces", Id.udaGNUAbiTag.toChars()); sym.errors = true; } else if (linkage != LINK.cpp) { - exp.error("`@%s` can only apply to C++ symbols", Id.udaGNUAbiTag.toChars()); + .error(exp.loc, "`@%s` can only apply to C++ symbols", Id.udaGNUAbiTag.toChars()); sym.errors = true; } // Only one `@gnuAbiTag` is allowed by semantic2 diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d index a0da77a2898c..31a32cf258cb 100644 --- a/gcc/d/dmd/blockexit.d +++ b/gcc/d/dmd/blockexit.d @@ -98,7 +98,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) if (s.exp.type && s.exp.type.toBasetype().isTypeNoreturn()) result = BE.halt; - result |= canThrow(s.exp, func, eSink !is null); + result |= canThrow(s.exp, func, eSink); } } @@ -153,6 +153,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) if (!(result & BE.fallthru) && !s.comeFrom()) { + version (none) // this warning is completely useless due to insane false positive rate in real life template code if (blockExit(s, func, eSink) != BE.halt && s.hasCode() && s.loc != Loc.initial) // don't emit warning for generated code global.errorSink.warning(s.loc, "statement is not reachable"); @@ -211,7 +212,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) result = BE.fallthru; if (result & BE.fallthru) { - result |= canThrow(s.condition, func, eSink !is null); + result |= canThrow(s.condition, func, eSink); if (!(result & BE.break_) && s.condition.toBool().hasValue(true)) result &= ~BE.fallthru; @@ -230,7 +231,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) } if (s.condition) { - result |= canThrow(s.condition, func, eSink !is null); + result |= canThrow(s.condition, func, eSink); const opt = s.condition.toBool(); if (opt.hasValue(true)) @@ -248,13 +249,13 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) result |= r & ~(BE.fallthru | BE.break_ | BE.continue_); } if (s.increment) - result |= canThrow(s.increment, func, eSink !is null); + result |= canThrow(s.increment, func, eSink); } void visitForeach(ForeachStatement s) { result = BE.fallthru; - result |= canThrow(s.aggr, func, eSink !is null); + result |= canThrow(s.aggr, func, eSink); if (s._body) result |= blockExit(s._body, func, eSink) & ~(BE.break_ | BE.continue_); @@ -270,7 +271,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) { //printf("IfStatement::blockExit(%p)\n", s); result = BE.none; - result |= canThrow(s.condition, func, eSink !is null); + result |= canThrow(s.condition, func, eSink); const opt = s.condition.toBool(); if (opt.hasValue(true)) @@ -309,7 +310,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) void visitSwitch(SwitchStatement s) { result = BE.none; - result |= canThrow(s.condition, func, eSink !is null); + result |= canThrow(s.condition, func, eSink); if (s._body) { @@ -354,7 +355,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) { result = BE.return_; if (s.exp) - result |= canThrow(s.exp, func, eSink !is null); + result |= canThrow(s.exp, func, eSink); } void visitBreak(BreakStatement s) @@ -376,7 +377,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink) void visitWith(WithStatement s) { result = BE.none; - result |= canThrow(s.exp, func, eSink !is null); + result |= canThrow(s.exp, func, eSink); result |= blockExit(s._body, func, eSink); } diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index 4cead300f40a..bb1fd6fc974f 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -20,6 +20,7 @@ import dmd.astenums; import dmd.blockexit : BE, checkThrow; import dmd.declaration; import dmd.dsymbol; +import dmd.errorsink; import dmd.expression; import dmd.func; import dmd.globals; @@ -47,25 +48,25 @@ enum CT : BE } /******************************************** - * Returns true if the expression may throw exceptions. - * If 'mustNotThrow' is true, generate an error if it throws + * If `eSink` is not null, generate an error if `e` throws + * Params: + * e = expression to check for throwing + * func = function + * eSink = if !null, then send error messages to eSink + * Returns: `CT.exception` or `CT.error` if the expression may throw exceptions. */ -extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustNotThrow) +extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, ErrorSink eSink) { //printf("Expression::canThrow(%d) %s\n", mustNotThrow, e.toChars()); // stop walking if we determine this expression can throw extern (C++) final class CanThrow : StoppableVisitor { alias visit = typeof(super).visit; - FuncDeclaration func; - bool mustNotThrow; CT result; public: - extern (D) this(FuncDeclaration func, bool mustNotThrow) scope @safe + extern (D) this() scope @safe { - this.func = func; - this.mustNotThrow = mustNotThrow; } void checkFuncThrows(Expression e, FuncDeclaration f) @@ -73,9 +74,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN auto tf = f.type.toBasetype().isTypeFunction(); if (tf && !tf.isnothrow) { - if (mustNotThrow) + if (eSink) { - e.error("%s `%s` is not `nothrow`", f.kind(), f.toPrettyChars()); + eSink.error(e.loc, "%s `%s` is not `nothrow`", f.kind(), f.toPrettyChars()); if (!f.isDtorDeclaration()) errorSupplementalInferredAttr(f, 10, false, STC.nothrow_); @@ -95,7 +96,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN override void visit(DeclarationExp de) { - result |= Dsymbol_canThrow(de.declaration, func, mustNotThrow); + result |= Dsymbol_canThrow(de.declaration, func, eSink); } override void visit(CallExp ce) @@ -138,12 +139,12 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN if (ce.f) checkFuncThrows(ce, ce.f); - else if (mustNotThrow) + else if (eSink) { auto e1 = ce.e1; if (auto pe = e1.isPtrExp()) // print 'fp' if e1 is (*fp) e1 = pe.e1; - ce.error("`%s` is not `nothrow`", e1.toChars()); + eSink.error(ce.loc, "`%s` is not `nothrow`", e1.toChars()); } result |= CT.exception; } @@ -202,7 +203,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN override void visit(ThrowExp te) { - const res = checkThrow(te.loc, te.e1, func, mustNotThrow ? global.errorSink : null); + const res = checkThrow(te.loc, te.e1, func, eSink); assert((res & ~(CT.exception | CT.error)) == 0); result |= res; } @@ -213,22 +214,22 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN } } - scope CanThrow ct = new CanThrow(func, mustNotThrow); + scope CanThrow ct = new CanThrow(); walkPostorder(e, ct); return ct.result; } /************************************** - * Does symbol, when initialized, throw? + * Does symbol `s`, when initialized, throw? * Mirrors logic in Dsymbol_toElem(). */ -private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow) +private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, ErrorSink eSink) { CT result; int symbolDg(Dsymbol s) { - result |= Dsymbol_canThrow(s, func, mustNotThrow); + result |= Dsymbol_canThrow(s, func, eSink); return 0; } @@ -237,7 +238,7 @@ private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow) { s = s.toAlias(); if (s != vd) - return Dsymbol_canThrow(s, func, mustNotThrow); + return Dsymbol_canThrow(s, func, eSink); if (vd.storage_class & STC.manifest) { } @@ -249,10 +250,10 @@ private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow) if (vd._init) { if (auto ie = vd._init.isExpInitializer()) - result |= canThrow(ie.exp, func, mustNotThrow); + result |= canThrow(ie.exp, func, eSink); } if (vd.needsScopeDtor()) - result |= canThrow(vd.edtor, func, mustNotThrow); + result |= canThrow(vd.edtor, func, eSink); } } else if (auto ad = s.isAttribDeclaration()) diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 181268ec26c4..ca7f398ae7ae 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -1201,7 +1201,7 @@ FuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc) version (all) { // currently rejects - ad.error(inv.loc, "mixing invariants with different `shared`/`synchronized` qualifiers is not supported"); + .error(inv.loc, "%s `%s` mixing invariants with different `shared`/`synchronized` qualifiers is not supported", ad.kind(), ad.toPrettyChars()); e = null; break; } diff --git a/gcc/d/dmd/compiler.d b/gcc/d/dmd/compiler.d index 68ec1d3848dd..e85cc202281d 100644 --- a/gcc/d/dmd/compiler.d +++ b/gcc/d/dmd/compiler.d @@ -13,7 +13,6 @@ module dmd.compiler; import dmd.arraytypes; import dmd.dmodule; -import dmd.dscope; import dmd.expression; import dmd.mtype; import dmd.root.array; diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index 76cef77d8eda..70a7c882eb31 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -691,6 +691,10 @@ extern (C++) final class VersionCondition : DVCondition case "LDC": case "linux": case "LittleEndian": + case "LoongArch32": + case "LoongArch64": + case "LoongArch_HardFloat": + case "LoongArch_SoftFloat": case "MinGW": case "MIPS32": case "MIPS64": diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d index e5526a1c9aaa..ef408cb5b772 100644 --- a/gcc/d/dmd/constfold.d +++ b/gcc/d/dmd/constfold.d @@ -336,7 +336,7 @@ UnionExp Div(const ref Loc loc, Type type, Expression e1, Expression e2) n2 = e2.toInteger(); if (n2 == 0) { - e2.error("divide by 0"); + error(e2.loc, "divide by 0"); emplaceExp!(ErrorExp)(&ue); return ue; } @@ -345,13 +345,13 @@ UnionExp Div(const ref Loc loc, Type type, Expression e1, Expression e2) // Check for int.min / -1 if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64) { - e2.error("integer overflow: `int.min / -1`"); + error(e2.loc, "integer overflow: `int.min / -1`"); emplaceExp!(ErrorExp)(&ue); return ue; } else if (n1 == 0x8000000000000000L) // long.min / -1 { - e2.error("integer overflow: `long.min / -1L`"); + error(e2.loc, "integer overflow: `long.min / -1L`"); emplaceExp!(ErrorExp)(&ue); return ue; } @@ -401,7 +401,7 @@ UnionExp Mod(const ref Loc loc, Type type, Expression e1, Expression e2) n2 = e2.toInteger(); if (n2 == 0) { - e2.error("divide by 0"); + error(e2.loc, "divide by 0"); emplaceExp!(ErrorExp)(&ue); return ue; } @@ -410,13 +410,13 @@ UnionExp Mod(const ref Loc loc, Type type, Expression e1, Expression e2) // Check for int.min % -1 if (n1 == 0xFFFFFFFF80000000UL && type.toBasetype().ty != Tint64) { - e2.error("integer overflow: `int.min %% -1`"); + error(e2.loc, "integer overflow: `int.min %% -1`"); emplaceExp!(ErrorExp)(&ue); return ue; } else if (n1 == 0x8000000000000000L) // long.min % -1 { - e2.error("integer overflow: `long.min %% -1L`"); + error(e2.loc, "integer overflow: `long.min %% -1L`"); emplaceExp!(ErrorExp)(&ue); return ue; } @@ -1135,7 +1135,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) uinteger_t i = e2.toInteger(); if (i >= es1.len) { - e1.error("string index %llu is out of bounds `[0 .. %llu]`", i, cast(ulong)es1.len); + error(e1.loc, "string index %llu is out of bounds `[0 .. %llu]`", i, cast(ulong)es1.len); emplaceExp!(ErrorExp)(&ue); } else @@ -1151,7 +1151,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) if (i >= length && (e1.op == EXP.arrayLiteral || !indexIsInBounds)) { // C code only checks bounds if an ArrayLiteralExp - e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), length); + error(e1.loc, "array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), length); emplaceExp!(ErrorExp)(&ue); } else if (ArrayLiteralExp ale = e1.isArrayLiteralExp()) @@ -1174,7 +1174,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) { if (i >= ale.elements.length) { - e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.length); + error(e1.loc, "array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.length); emplaceExp!(ErrorExp)(&ue); } else diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index b05d81d3b149..d183b8227c88 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -231,6 +231,9 @@ final class CParser(AST) : Parser!AST } goto Lexp; // function call + case TOK.semicolon: + goto Lexp; + default: { /* If tokens look like a declaration, assume it is one @@ -501,7 +504,7 @@ final class CParser(AST) : Parser!AST auto condition = cparseExpression(); check(TOK.rightParenthesis); auto _body = cparseStatement(ParseStatementFlags.scope_); - s = new AST.SwitchStatement(loc, condition, _body, false); + s = new AST.SwitchStatement(loc, null, condition, _body, false, token.loc); break; } diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 0c32fad78034..230bfec17ea9 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -483,7 +483,7 @@ private final class CppMangleVisitor : Visitor } else { - ti.error("internal compiler error: C++ `%s` template value parameter is not supported", tv.valType.toChars()); + .error(ti.loc, "%s `%s` internal compiler error: C++ `%s` template value parameter is not supported", ti.kind, ti.toPrettyChars, tv.valType.toChars()); fatal(); } } @@ -518,13 +518,13 @@ private final class CppMangleVisitor : Visitor } else { - ti.error("internal compiler error: C++ `%s` template alias parameter is not supported", o.toChars()); + .error(ti.loc, "%s `%s` internal compiler error: C++ `%s` template alias parameter is not supported", ti.kind, ti.toPrettyChars, o.toChars()); fatal(); } } else if (tp.isTemplateThisParameter()) { - ti.error("internal compiler error: C++ `%s` template this parameter is not supported", o.toChars()); + .error(ti.loc, "%s `%s` internal compiler error: C++ `%s` template this parameter is not supported", ti.kind, ti.toPrettyChars, o.toChars()); fatal(); } else @@ -573,7 +573,7 @@ private final class CppMangleVisitor : Visitor Type t = isType((*ti.tiargs)[j]); if (t is null) { - ti.error("internal compiler error: C++ `%s` template value parameter is not supported", (*ti.tiargs)[j].toChars()); + .error(ti.loc, "%s `%s` internal compiler error: C++ `%s` template value parameter is not supported", ti.kind, ti.toPrettyChars, (*ti.tiargs)[j].toChars()); fatal(); } t.accept(this); @@ -1011,7 +1011,7 @@ private final class CppMangleVisitor : Visitor // fake mangling for fields to fix https://issues.dlang.org/show_bug.cgi?id=16525 if (!(d.storage_class & (STC.extern_ | STC.field | STC.gshared))) { - d.error("internal compiler error: C++ static non-`__gshared` non-`extern` variables not supported"); + .error(d.loc, "%s `%s` internal compiler error: C++ static non-`__gshared` non-`extern` variables not supported", d.kind, d.toPrettyChars); fatal(); } Dsymbol p = d.toParent(); diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h index 1071edf7c931..bb92778e2534 100644 --- a/gcc/d/dmd/ctfe.h +++ b/gcc/d/dmd/ctfe.h @@ -37,7 +37,6 @@ class VoidInitExp final : public Expression public: VarDeclaration *var; - const char *toChars() const override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d index c0a2ca6a2a55..ddfb57d22d70 100644 --- a/gcc/d/dmd/ctfeexpr.d +++ b/gcc/d/dmd/ctfeexpr.d @@ -147,7 +147,7 @@ extern (C++) final class ThrownExceptionExp : Expression UnionExp ue = void; Expression e = resolveSlice((*thrown.value.elements)[0], &ue); StringExp se = e.toStringExp(); - thrown.error("uncaught CTFE exception `%s(%s)`", thrown.type.toChars(), se ? se.toChars() : e.toChars()); + error(thrown.loc, "uncaught CTFE exception `%s(%s)`", thrown.type.toChars(), se ? se.toChars() : e.toChars()); /* Also give the line where the throw statement was. We won't have it * in the case where the ThrowStatement is generated internally * (eg, in ScopeStatement) @@ -435,7 +435,7 @@ UnionExp copyLiteral(Expression e) emplaceExp!(UnionExp)(&ue, e); return ue; } - e.error("CTFE internal error: literal `%s`", e.toChars()); + error(e.loc, "CTFE internal error: literal `%s`", e.toChars()); assert(0); } @@ -506,7 +506,7 @@ private UnionExp paintTypeOntoLiteralCopy(Type type, Expression lit) // Can't type paint from struct to struct*; this needs another // level of indirection if (lit.op == EXP.structLiteral && isPointer(type)) - lit.error("CTFE internal error: painting `%s`", type.toChars()); + error(lit.loc, "CTFE internal error: painting `%s`", type.toChars()); ue = copyLiteral(lit); } ue.exp().type = type; @@ -1919,7 +1919,7 @@ bool isCtfeValueValid(Expression newval) return true; // uninitialized value default: - newval.error("CTFE internal error: illegal CTFE value `%s`", newval.toChars()); + error(newval.loc, "CTFE internal error: illegal CTFE value `%s`", newval.toChars()); return false; } } diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index d7cb2b1f9708..9f661ea410bb 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -23,6 +23,7 @@ import dmd.declaration; import dmd.dscope; import dmd.dstruct; import dmd.dsymbol; +import dmd.errors; import dmd.escape; import dmd.expression; import dmd.expressionsem; @@ -135,7 +136,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) { if (!t.deco) { - e.error("forward reference to type `%s`", t.toChars()); + error(e.loc, "forward reference to type `%s`", t.toChars()); } else { @@ -143,7 +144,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) //type = type.typeSemantic(loc, sc); //printf("type %s t %s\n", type.deco, t.deco); auto ts = toAutoQualChars(e.type, t); - e.error("cannot implicitly convert expression `%s` of type `%s` to `%s`", + error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", e.toChars(), ts[0], ts[1]); } } @@ -244,7 +245,7 @@ MATCH implicitConvTo(Expression e, Type t) return MATCH.nomatch; if (!e.type) { - e.error("`%s` is not an expression", e.toChars()); + error(e.loc, "`%s` is not an expression", e.toChars()); e.type = Type.terror; } @@ -715,6 +716,14 @@ MATCH implicitConvTo(Expression e, Type t) if (e.postfix != 'd') m = MATCH.convert; return m; + case Tint8: + case Tuns8: + if (e.hexString) + { + m = MATCH.convert; + return m; + } + break; case Tenum: if (tn.isTypeEnum().sym.isSpecial()) { @@ -1671,7 +1680,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) goto Lok; auto ts = toAutoQualChars(e.type, t); - e.error("cannot cast expression `%s` of type `%s` to `%s` because of different sizes", + error(e.loc, "cannot cast expression `%s` of type `%s` to `%s` because of different sizes", e.toChars(), ts[0], ts[1]); return ErrorExp.get(); } @@ -1700,7 +1709,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) const dim = t1b.isTypeSArray().dim.toInteger(); if (tsize == 0 || (dim * fsize) % tsize != 0) { - e.error("cannot cast expression `%s` of type `%s` to `%s` since sizes don't line up", + error(e.loc, "cannot cast expression `%s` of type `%s` to `%s` since sizes don't line up", e.toChars(), e.type.toChars(), t.toChars()); return ErrorExp.get(); } @@ -1743,7 +1752,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) // void delegate() dg; // cast(U*)dg; // ==> cast(U*)dg.ptr; // Note that it happens even when U is a Tfunction! - e.deprecation("casting from %s to %s is deprecated", e.type.toChars(), t.toChars()); + deprecation(e.loc, "casting from %s to %s is deprecated", e.type.toChars(), t.toChars()); goto Lok; } goto Lfail; @@ -1761,7 +1770,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) if (result) return result; } - e.error("cannot cast expression `%s` of type `%s` to `%s`", e.toChars(), e.type.toChars(), t.toChars()); + error(e.loc, "cannot cast expression `%s` of type `%s` to `%s`", e.toChars(), e.type.toChars(), t.toChars()); return ErrorExp.get(); } @@ -1830,7 +1839,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) if (!e.committed && t.ty == Tpointer && t.nextOf().ty == Tvoid && (!sc || !(sc.flags & SCOPE.Cfile))) { - e.error("cannot convert string literal to `void*`"); + error(e.loc, "cannot convert string literal to `void*`"); return ErrorExp.get(); } @@ -1968,7 +1977,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { dchar c; if (const s = utf_decodeChar(se.peekString(), u, c)) - e.error("%.*s", cast(int)s.length, s.ptr); + error(e.loc, "%.*s", cast(int)s.length, s.ptr); else buffer.writeUTF16(c); } @@ -1981,7 +1990,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { dchar c; if (const s = utf_decodeChar(se.peekString(), u, c)) - e.error("%.*s", cast(int)s.length, s.ptr); + error(e.loc, "%.*s", cast(int)s.length, s.ptr); buffer.write4(c); newlen++; } @@ -1993,7 +2002,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { dchar c; if (const s = utf_decodeWchar(se.peekWstring(), u, c)) - e.error("%.*s", cast(int)s.length, s.ptr); + error(e.loc, "%.*s", cast(int)s.length, s.ptr); else buffer.writeUTF8(c); } @@ -2006,7 +2015,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { dchar c; if (const s = utf_decodeWchar(se.peekWstring(), u, c)) - e.error("%.*s", cast(int)s.length, s.ptr); + error(e.loc, "%.*s", cast(int)s.length, s.ptr); buffer.write4(c); newlen++; } @@ -2018,7 +2027,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { uint c = se.peekDstring()[u]; if (!utf_isValidDchar(c)) - e.error("invalid UCS-32 char \\U%08x", c); + error(e.loc, "invalid UCS-32 char \\U%08x", c); else buffer.writeUTF8(c); newlen++; @@ -2032,7 +2041,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { uint c = se.peekDstring()[u]; if (!utf_isValidDchar(c)) - e.error("invalid UCS-32 char \\U%08x", c); + error(e.loc, "invalid UCS-32 char \\U%08x", c); else buffer.writeUTF16(c); newlen++; @@ -2392,7 +2401,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) } else if (f.needThis()) { - e.error("no `this` to create delegate for `%s`", f.toChars()); + error(e.loc, "no `this` to create delegate for `%s`", f.toChars()); return ErrorExp.get(); } else if (f.isNested()) @@ -2402,7 +2411,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) } else { - e.error("cannot cast from function pointer to delegate"); + error(e.loc, "cannot cast from function pointer to delegate"); return ErrorExp.get(); } } @@ -2443,7 +2452,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) int offset; e.func.tookAddressOf++; if (e.func.tintro && e.func.tintro.nextOf().isBaseOf(e.func.type.nextOf(), &offset) && offset) - e.error("%s", msg.ptr); + error(e.loc, "%s", msg.ptr); auto result = e.copy(); result.type = t; return result; @@ -2459,7 +2468,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { int offset; if (f.tintro && f.tintro.nextOf().isBaseOf(f.type.nextOf(), &offset) && offset) - e.error("%s", msg.ptr); + error(e.loc, "%s", msg.ptr); if (f != e.func) // if address not already marked as taken f.tookAddressOf++; auto result = new DelegateExp(e.loc, e.e1, f, false, e.vthis2); @@ -2467,7 +2476,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) return result; } if (e.func.tintro) - e.error("%s", msg.ptr); + error(e.loc, "%s", msg.ptr); } } @@ -2596,7 +2605,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) } } auto ts = toAutoQualChars(tsa ? tsa : e.type, t); - e.error("cannot cast expression `%s` of type `%s` to `%s`", + error(e.loc, "cannot cast expression `%s` of type `%s` to `%s`", e.toChars(), ts[0], ts[1]); return ErrorExp.get(); } @@ -3610,7 +3619,7 @@ Expression integralPromotions(Expression e, Scope* sc) switch (e.type.toBasetype().ty) { case Tvoid: - e.error("void has no value"); + error(e.loc, "void has no value"); return ErrorExp.get(); case Tint8: @@ -3659,7 +3668,7 @@ void fix16997(Scope* sc, UnaExp ue) case Tchar: case Twchar: case Tdchar: - ue.deprecation("integral promotion not done for `%s`, remove '-revert=intpromote' switch or `%scast(int)(%s)`", + deprecation(ue.loc, "integral promotion not done for `%s`, remove '-revert=intpromote' switch or `%scast(int)(%s)`", ue.toChars(), EXPtoString(ue.op).ptr, ue.e1.toChars()); break; diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index b446e77b8799..0fbbb1128e74 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -24,6 +24,7 @@ import dmd.declaration; import dmd.dscope; import dmd.dsymbol; import dmd.dsymbolsem; +import dmd.errors; import dmd.func; import dmd.id; import dmd.identifier; @@ -222,7 +223,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration // Look for special class names if (id == Id.__sizeof || id == Id.__xalignof || id == Id._mangleof) - error("illegal class name"); + classError("%s `%s` illegal class name", null); // BUG: What if this is the wrong TypeInfo, i.e. it is nested? if (id.toChars()[0] == 'T') @@ -230,103 +231,103 @@ extern (C++) class ClassDeclaration : AggregateDeclaration if (id == Id.TypeInfo) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.dtypeinfo = this; } if (id == Id.TypeInfo_Class) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoclass = this; } if (id == Id.TypeInfo_Interface) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfointerface = this; } if (id == Id.TypeInfo_Struct) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfostruct = this; } if (id == Id.TypeInfo_Pointer) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfopointer = this; } if (id == Id.TypeInfo_Array) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoarray = this; } if (id == Id.TypeInfo_StaticArray) { //if (!inObject) - // Type.typeinfostaticarray.error("%s", msg); + // Type.typeinfostaticarray.classError("%s `%s` %s", msg); Type.typeinfostaticarray = this; } if (id == Id.TypeInfo_AssociativeArray) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoassociativearray = this; } if (id == Id.TypeInfo_Enum) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoenum = this; } if (id == Id.TypeInfo_Function) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfofunction = this; } if (id == Id.TypeInfo_Delegate) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfodelegate = this; } if (id == Id.TypeInfo_Tuple) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfotypelist = this; } if (id == Id.TypeInfo_Const) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoconst = this; } if (id == Id.TypeInfo_Invariant) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoinvariant = this; } if (id == Id.TypeInfo_Shared) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfoshared = this; } if (id == Id.TypeInfo_Wild) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfowild = this; } if (id == Id.TypeInfo_Vector) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); Type.typeinfovector = this; } } @@ -334,38 +335,43 @@ extern (C++) class ClassDeclaration : AggregateDeclaration if (id == Id.Object) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); object = this; } if (id == Id.Throwable) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); throwable = this; } if (id == Id.Exception) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); exception = this; } if (id == Id.Error) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); errorException = this; } if (id == Id.cpp_type_info_ptr) { if (!inObject) - error("%s", msg.ptr); + classError("%s `%s` %s", msg.ptr); cpp_type_info_ptr = this; } baseok = Baseok.none; } + final void classError(const(char)* fmt, const(char)* arg) + { + .error(loc, fmt, kind, toPrettyChars, arg); + } + static ClassDeclaration create(const ref Loc loc, Identifier id, BaseClasses* baseclasses, Dsymbols* members, bool inObject) { return new ClassDeclaration(loc, id, baseclasses, members, inObject); @@ -481,7 +487,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration { // .stringof is always defined (but may be hidden by some other symbol) if (ident != Id.stringof && !(flags & IgnoreErrors) && semanticRun < PASS.semanticdone) - error("is forward referenced when looking for `%s`", ident.toChars()); + classError("%s `%s` is forward referenced when looking for `%s`", ident.toChars()); //*(char*)0=0; return null; } @@ -503,7 +509,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration if (!b.sym.symtab) { - error("base `%s` is forward referenced", b.sym.ident.toChars()); + classError("%s `%s` base `%s` is forward referenced", b.sym.ident.toChars()); continue; } @@ -814,7 +820,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration } if (fdambig) - error("ambiguous virtual function `%s`", fdambig.toChars()); + classError("%s `%s` ambiguous virtual function `%s`", fdambig.toChars()); return fdmatch; } diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index b21678ce508c..b65e7e833d4d 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -326,12 +326,12 @@ extern (C++) abstract class Declaration : Dsymbol continue; if (sdv.postblit.isDisabled()) { - p.error(loc, "is not copyable because field `%s` is not copyable", structField.toChars()); + .error(loc, "%s `%s` is not copyable because field `%s` is not copyable", p.kind, p.toPrettyChars, structField.toChars()); return true; } } } - p.error(loc, "is not copyable because it has a disabled postblit"); + .error(loc, "%s `%s` is not copyable because it has a disabled postblit", p.kind, p.toPrettyChars); return true; } } @@ -357,7 +357,7 @@ extern (C++) abstract class Declaration : Dsymbol return true; } } - error(loc, "cannot be used because it is annotated with `@disable`"); + .error(loc, "%s `%s` cannot be used because it is annotated with `@disable`", kind, toPrettyChars); return true; } @@ -388,7 +388,7 @@ extern (C++) abstract class Declaration : Dsymbol { const(char)* s = isParameter() && parent.ident != Id.ensure ? "parameter" : "result"; if (!(flag & ModifyFlags.noError)) - error(loc, "cannot modify %s `%s` in contract", s, toChars()); + error(loc, "%s `%s` cannot modify %s `%s` in contract", kind, toPrettyChars, s, toChars()); return Modifiable.initialization; // do not report type related errors } } @@ -402,7 +402,7 @@ extern (C++) abstract class Declaration : Dsymbol if (scx.func == vthis.parent && (scx.flags & SCOPE.contract)) { if (!(flag & ModifyFlags.noError)) - error(loc, "cannot modify parameter `this` in contract"); + error(loc, "%s `%s` cannot modify parameter `this` in contract", kind, toPrettyChars); return Modifiable.initialization; // do not report type related errors } } @@ -945,7 +945,7 @@ extern (C++) final class AliasDeclaration : Declaration } if (inuse) { - error("recursive alias declaration"); + .error(loc, "%s `%s` recursive alias declaration", kind, toPrettyChars); Lerr: // Avoid breaking "recursive alias" state during errors gagged @@ -1003,7 +1003,7 @@ extern (C++) final class AliasDeclaration : Declaration { if (inuse) { - error("recursive alias declaration"); + .error(loc, "%s `%s` recursive alias declaration", kind, toPrettyChars); return this; } inuse = 1; @@ -1377,7 +1377,7 @@ extern (C++) class VarDeclaration : Declaration Dsymbol parent = toParent(); if (!parent && !(storage_class & STC.static_)) { - error("forward referenced"); + .error(loc, "%s `%s` forward referenced", kind, toPrettyChars); type = Type.terror; } else if (storage_class & (STC.static_ | STC.extern_ | STC.gshared) || diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 955a17dc6e89..98bf4dd2aad1 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -18,6 +18,7 @@ import core.stdc.stdio; import dmd.astenums; import dmd.attrib; +import dmd.errors; import dmd.gluelayer; import dmd.declaration; import dmd.dscope; @@ -191,7 +192,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol return defaultval = memtype.defaultInit(loc); } - error(loc, "is opaque and has no default initializer"); + error(loc, "%s `%s` is opaque and has no default initializer", kind, toPrettyChars); return handleErrors(); } @@ -202,7 +203,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol { if (em.semanticRun < PASS.semanticdone) { - error(loc, "forward reference of `%s.init`", toChars()); + error(loc, "%s `%s` forward reference of `%s.init`", kind, toPrettyChars, toChars()); return handleErrors(); } diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index c4d5ddbc0798..3b8d9f6722d9 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -93,7 +93,7 @@ extern (C++) final class Import : Dsymbol extern (D) void addAlias(Identifier name, Identifier _alias) { if (isstatic) - error("cannot have an import bind list"); + .error(loc, "%s `%s` cannot have an import bind list", kind, toPrettyChars); if (!aliasId) this.ident = null; // make it an anonymous import names.push(name); diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 7cdafda050cd..a43be7d2308f 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -427,17 +427,23 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta { printf("\n********\n%s FuncDeclaration::interpret(istate = %p) %s\n", fd.loc.toChars(), istate, fd.toChars()); } + + void fdError(const(char)* msg) + { + error(fd.loc, "%s `%s` %s", fd.kind, fd.toPrettyChars, msg); + } + assert(pue); if (fd.semanticRun == PASS.semantic3) { - fd.error("circular dependency. Functions cannot be interpreted while being compiled"); + fdError("circular dependency. Functions cannot be interpreted while being compiled"); return CTFEExp.cantexp; } if (!fd.functionSemantic3()) return CTFEExp.cantexp; if (fd.semanticRun < PASS.semantic3done) { - fd.error("circular dependency. Functions cannot be interpreted while being compiled"); + fdError("circular dependency. Functions cannot be interpreted while being compiled"); return CTFEExp.cantexp; } @@ -445,7 +451,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta if (tf.parameterList.varargs != VarArg.none && arguments && ((fd.parameters && arguments.length != fd.parameters.length) || (!fd.parameters && arguments.length))) { - fd.error("C-style variadic functions are not yet implemented in CTFE"); + fdError("C-style variadic functions are not yet implemented in CTFE"); return CTFEExp.cantexp; } @@ -460,7 +466,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta { // error, no this. Prevent segfault. // Here should be unreachable by the strict 'this' check in front-end. - fd.error("need `this` to access member `%s`", fd.toChars()); + error(fd.loc, "%s `%s` need `this` to access member `%s`", fd.kind, fd.toPrettyChars, fd.toChars()); return CTFEExp.cantexp; } @@ -483,7 +489,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta if (!istate && (fparam.storageClass & STC.out_)) { // initializing an out parameter involves writing to it. - earg.error("global `%s` cannot be passed as an `out` parameter at compile time", earg.toChars()); + error(earg.loc, "global `%s` cannot be passed as an `out` parameter at compile time", earg.toChars()); return CTFEExp.cantexp; } // Convert all reference arguments into lvalue references @@ -577,7 +583,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta VarDeclaration vx = earg.isVarExp().var.isVarDeclaration(); if (!vx) { - fd.error("cannot interpret `%s` as a `ref` parameter", earg.toChars()); + error(fd.loc, "%s `%s` cannot interpret `%s` as a `ref` parameter", fd.kind, fd.toPrettyChars, earg.toChars()); return CTFEExp.cantexp; } @@ -634,7 +640,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta { if (ctfeGlobals.callDepth > CTFE_RECURSION_LIMIT) { - fd.error("CTFE recursion limit exceeded"); + fdError("CTFE recursion limit exceeded"); e = CTFEExp.cantexp; break; } @@ -649,7 +655,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta if (istatex.start) { - fd.error("CTFE internal error: failed to resume at statement `%s`", istatex.start.toChars()); + error(fd.loc, "%s `%s` CTFE internal error: failed to resume at statement `%s`", fd.kind, fd.toPrettyChars, istatex.start.toChars()); return CTFEExp.cantexp; } @@ -680,7 +686,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta /* missing a return statement can happen with C functions * https://issues.dlang.org/show_bug.cgi?id=23056 */ - fd.error("no return value from function"); + fdError("no return value from function"); e = CTFEExp.cantexp; } } @@ -1255,7 +1261,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) } if (!scase) { - if (s.hasNoDefault) + if (!s.hasDefault) error(s.loc, "no `default` or `case` for `%s` in `switch` statement", econdition.toChars()); scase = s.sdefault; } @@ -1419,7 +1425,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) setValue(ca.var, ex.thrown); } e = interpretStatement(ca.handler, istate); - if (CTFEExp.isGotoExp(e)) + while (CTFEExp.isGotoExp(e)) { /* This is an optimization that relies on the locality of the jump target. * If the label is in the same catch handler, the following scan @@ -1431,11 +1437,19 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) istatex.start = istate.gotoTarget; // set starting statement istatex.gotoTarget = null; Expression eh = interpretStatement(ca.handler, &istatex); - if (!istatex.start) + if (istatex.start) + { + // The goto target is outside the current scope. + break; + } + // The goto target was within the body. + if (CTFEExp.isCantExp(eh)) { - istate.gotoTarget = null; e = eh; + break; } + *istate = istatex; + e = eh; } break; } @@ -1562,7 +1576,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) ctfeGlobals.stack.push(s.wthis); setValue(s.wthis, e); e = interpretStatement(s._body, istate); - if (CTFEExp.isGotoExp(e)) + while (CTFEExp.isGotoExp(e)) { /* This is an optimization that relies on the locality of the jump target. * If the label is in the same WithStatement, the following scan @@ -1574,11 +1588,19 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) istatex.start = istate.gotoTarget; // set starting statement istatex.gotoTarget = null; Expression ex = interpretStatement(s._body, &istatex); - if (!istatex.start) + if (istatex.start) + { + // The goto target is outside the current scope. + break; + } + // The goto target was within the body. + if (CTFEExp.isCantExp(ex)) { - istate.gotoTarget = null; e = ex; + break; } + *istate = istatex; + e = ex; } ctfeGlobals.stack.pop(s.wthis); result = e; @@ -1673,7 +1695,7 @@ public: printf("type = %s\n", e.type.toChars()); showCtfeExpr(e); } - e.error("cannot interpret `%s` at compile time", e.toChars()); + error(e.loc, "cannot interpret `%s` at compile time", e.toChars()); result = CTFEExp.cantexp; } @@ -1730,7 +1752,7 @@ public: assert(result.op == EXP.structLiteral || result.op == EXP.classReference || result.op == EXP.type); return; } - e.error("value of `this` is not known at compile time"); + error(e.loc, "value of `this` is not known at compile time"); result = CTFEExp.cantexp; } @@ -1819,14 +1841,14 @@ public: if (e.type.ty != Tpointer) { // Probably impossible - e.error("cannot interpret `%s` at compile time", e.toChars()); + error(e.loc, "cannot interpret `%s` at compile time", e.toChars()); result = CTFEExp.cantexp; return; } Type pointee = (cast(TypePointer)e.type).next; if (e.var.isThreadlocal()) { - e.error("cannot take address of thread-local variable %s at compile time", e.var.toChars()); + error(e.loc, "cannot take address of thread-local variable %s at compile time", e.var.toChars()); result = CTFEExp.cantexp; return; } @@ -1881,7 +1903,7 @@ public: result = pue.exp(); return; } - e.error("reinterpreting cast from `%s` to `%s` is not supported in CTFE", val.type.toChars(), e.type.toChars()); + error(e.loc, "reinterpreting cast from `%s` to `%s` is not supported in CTFE", val.type.toChars(), e.type.toChars()); result = CTFEExp.cantexp; return; } @@ -1922,7 +1944,7 @@ public: return; } - e.error("cannot convert `&%s` to `%s` at compile time", e.var.type.toChars(), e.type.toChars()); + error(e.loc, "cannot convert `&%s` to `%s` at compile time", e.var.type.toChars(), e.type.toChars()); result = CTFEExp.cantexp; } @@ -1938,7 +1960,7 @@ public: // We cannot take the address of an imported symbol at compile time if (decl.isImportedSymbol()) { - e.error("cannot take address of imported symbol `%s` at compile time", decl.toChars()); + error(e.loc, "cannot take address of imported symbol `%s` at compile time", decl.toChars()); result = CTFEExp.cantexp; return; } @@ -2183,9 +2205,9 @@ public: } if (!v.isCTFE() && v.isDataseg()) - e.error("static variable `%s` cannot be read at compile time", v.toChars()); + error(e.loc, "static variable `%s` cannot be read at compile time", v.toChars()); else // CTFE initiated from inside a function - e.error("variable `%s` cannot be read at compile time", v.toChars()); + error(e.loc, "variable `%s` cannot be read at compile time", v.toChars()); result = CTFEExp.cantexp; return; } @@ -2277,7 +2299,7 @@ public: } else { - e.error("declaration `%s` is not yet implemented in CTFE", e.toChars()); + error(e.loc, "declaration `%s` is not yet implemented in CTFE", e.toChars()); result = CTFEExp.cantexp; return 1; } @@ -2316,7 +2338,7 @@ public: if (result !is null) return; } - e.error("declaration `%s` is not yet implemented in CTFE", e.toChars()); + error(e.loc, "declaration `%s` is not yet implemented in CTFE", e.toChars()); result = CTFEExp.cantexp; } else if (v.type.size() == 0) @@ -2326,7 +2348,7 @@ public: } else { - e.error("variable `%s` cannot be modified at compile time", v.toChars()); + error(e.loc, "variable `%s` cannot be modified at compile time", v.toChars()); result = CTFEExp.cantexp; } return; @@ -2334,7 +2356,7 @@ public: if (s.isTemplateMixin() || s.isTupleDeclaration()) { // These can be made to work, too lazy now - e.error("declaration `%s` is not yet implemented in CTFE", e.toChars()); + error(e.loc, "declaration `%s` is not yet implemented in CTFE", e.toChars()); result = CTFEExp.cantexp; return; } @@ -2366,13 +2388,13 @@ public: if (result.op == EXP.null_) { - e.error("null pointer dereference evaluating typeid. `%s` is `null`", ex.toChars()); + error(e.loc, "null pointer dereference evaluating typeid. `%s` is `null`", ex.toChars()); result = CTFEExp.cantexp; return; } if (result.op != EXP.classReference) { - e.error("CTFE internal error: determining classinfo"); + error(e.loc, "CTFE internal error: determining classinfo"); result = CTFEExp.cantexp; return; } @@ -2409,7 +2431,7 @@ public: continue; if (ex.op == EXP.voidExpression) { - e.error("CTFE internal error: void element `%s` in sequence", exp.toChars()); + error(e.loc, "CTFE internal error: void element `%s` in sequence", exp.toChars()); assert(0); } @@ -2496,7 +2518,7 @@ public: expandTuples(expsx); if (expsx.length != dim) { - e.error("CTFE internal error: invalid array literal"); + error(e.loc, "CTFE internal error: invalid array literal"); result = CTFEExp.cantexp; return; } @@ -2559,7 +2581,7 @@ public: expandTuples(valuesx); if (keysx.length != valuesx.length) { - e.error("CTFE internal error: invalid AA"); + error(e.loc, "CTFE internal error: invalid AA"); result = CTFEExp.cantexp; return; } @@ -2680,7 +2702,7 @@ public: expandTuples(expsx); if (expsx.length != e.sd.fields.length) { - e.error("CTFE internal error: invalid struct literal"); + error(e.loc, "CTFE internal error: invalid struct literal"); result = CTFEExp.cantexp; return; } @@ -2810,7 +2832,7 @@ public: { if (v.inuse) { - e.error("circular reference to `%s`", v.toPrettyChars()); + error(e.loc, "circular reference to `%s`", v.toPrettyChars()); result = CTFEExp.cantexp; return; } @@ -2855,7 +2877,9 @@ public: result = eref; return; } - e.member.error("`%s` cannot be constructed at compile time, because the constructor has no available source code", e.newtype.toChars()); + auto m = e.member; + error(m.loc, "%s `%s` `%s` cannot be constructed at compile time, because the constructor has no available source code", + m.kind, m.toPrettyChars, e.newtype.toChars()); result = CTFEExp.cantexp; return; } @@ -2897,7 +2921,7 @@ public: result = pue.exp(); return; } - e.error("cannot interpret `%s` at compile time", e.toChars()); + error(e.loc, "cannot interpret `%s` at compile time", e.toChars()); result = CTFEExp.cantexp; } @@ -2998,7 +3022,7 @@ public: } if (e.e1.type.ty == Tpointer || e.e2.type.ty == Tpointer) { - e.error("pointer expression `%s` cannot be interpreted at compile time", e.toChars()); + error(e.loc, "pointer expression `%s` cannot be interpreted at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -3027,7 +3051,7 @@ public: const uinteger_t sz = e1.type.size() * 8; if (i2 < 0 || i2 >= sz) { - e.error("shift by %lld is outside the range 0..%llu", i2, cast(ulong)sz - 1); + error(e.loc, "shift by %lld is outside the range 0..%llu", i2, cast(ulong)sz - 1); result = CTFEExp.cantexp; return; } @@ -3078,13 +3102,13 @@ public: if (e1.isConst() != 1) { // The following should really be an assert() - e1.error("CTFE internal error: non-constant value `%s`", e1.toChars()); + error(e1.loc, "CTFE internal error: non-constant value `%s`", e1.toChars()); emplaceExp!CTFEExp(&ue, EXP.cantExpression); return ue; } if (e2.isConst() != 1) { - e2.error("CTFE internal error: non-constant value `%s`", e2.toChars()); + error(e2.loc, "CTFE internal error: non-constant value `%s`", e2.toChars()); emplaceExp!CTFEExp(&ue, EXP.cantExpression); return ue; } @@ -3095,7 +3119,7 @@ public: *pue = evaluate(e.loc, e.type, e1, e2); result = (*pue).exp(); if (CTFEExp.isCantExp(result)) - e.error("`%s` cannot be interpreted at compile time", e.toChars()); + error(e.loc, "`%s` cannot be interpreted at compile time", e.toChars()); } extern (D) private void interpretCompareCommon(BinExp e, fp2_t fp) @@ -3123,7 +3147,7 @@ public: if (cmp == -1) { char dir = (e.op == EXP.greaterThan || e.op == EXP.greaterOrEqual) ? '<' : '>'; - e.error("the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars()); + error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars()); result = CTFEExp.cantexp; return; } @@ -3141,7 +3165,7 @@ public: return; if (!isCtfeComparable(e1)) { - e.error("cannot compare `%s` at compile time", e1.toChars()); + error(e.loc, "cannot compare `%s` at compile time", e1.toChars()); result = CTFEExp.cantexp; return; } @@ -3150,7 +3174,7 @@ public: return; if (!isCtfeComparable(e2)) { - e.error("cannot compare `%s` at compile time", e2.toChars()); + error(e.loc, "cannot compare `%s` at compile time", e2.toChars()); result = CTFEExp.cantexp; return; } @@ -3277,7 +3301,7 @@ public: Expression e1 = e.e1; if (!istate) { - e.error("value of `%s` is not known at compile time", e1.toChars()); + error(e.loc, "value of `%s` is not known at compile time", e1.toChars()); return; } @@ -3591,14 +3615,14 @@ public: } else { - e.error("pointer expression `%s` cannot be interpreted at compile time", e.toChars()); + error(e.loc, "pointer expression `%s` cannot be interpreted at compile time", e.toChars()); result = CTFEExp.cantexp; return; } if (exceptionOrCant(newval)) { if (CTFEExp.isCantExp(newval)) - e.error("cannot interpret `%s` at compile time", e.toChars()); + error(e.loc, "cannot interpret `%s` at compile time", e.toChars()); return; } } @@ -3607,7 +3631,7 @@ public: { if (existingAA.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only constant `%s`", existingAA.toChars()); + error(e.loc, "cannot modify read-only constant `%s`", existingAA.toChars()); result = CTFEExp.cantexp; return; } @@ -3647,7 +3671,7 @@ public: Type t = e1.type.toBasetype(); if (t.ty != Tarray) { - e.error("`%s` is not yet supported at compile time", e.toChars()); + error(e.loc, "`%s` is not yet supported at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -3725,7 +3749,7 @@ public: auto v = dve.var.isVarDeclaration(); if (!sle || !v) { - e.error("CTFE internal error: dotvar slice assignment"); + error(e.loc, "CTFE internal error: dotvar slice assignment"); result = CTFEExp.cantexp; return; } @@ -3784,12 +3808,12 @@ public: auto v = e1.isDotVarExp().var.isVarDeclaration(); if (!sle || !v) { - e.error("CTFE internal error: dotvar assignment"); + error(e.loc, "CTFE internal error: dotvar assignment"); return CTFEExp.cantexp; } if (sle.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only constant `%s`", sle.toChars()); + error(e.loc, "cannot modify read-only constant `%s`", sle.toChars()); return CTFEExp.cantexp; } @@ -3797,7 +3821,7 @@ public: : ex.isClassReferenceExp().findFieldIndexByName(v); if (fieldi == -1) { - e.error("CTFE internal error: cannot find field `%s` in `%s`", v.toChars(), ex.toChars()); + error(e.loc, "CTFE internal error: cannot find field `%s` in `%s`", v.toChars(), ex.toChars()); return CTFEExp.cantexp; } assert(0 <= fieldi && fieldi < sle.elements.length); @@ -3839,7 +3863,7 @@ public: { if (existingSE.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only string literal `%s`", ie.e1.toChars()); + error(e.loc, "cannot modify read-only string literal `%s`", ie.e1.toChars()); return CTFEExp.cantexp; } existingSE.setCodeUnit(index, cast(dchar)newval.toInteger()); @@ -3847,14 +3871,14 @@ public: } if (aggregate.op != EXP.arrayLiteral) { - e.error("index assignment `%s` is not yet supported in CTFE ", e.toChars()); + error(e.loc, "index assignment `%s` is not yet supported in CTFE ", e.toChars()); return CTFEExp.cantexp; } ArrayLiteralExp existingAE = aggregate.isArrayLiteralExp(); if (existingAE.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only constant `%s`", existingAE.toChars()); + error(e.loc, "cannot modify read-only constant `%s`", existingAE.toChars()); return CTFEExp.cantexp; } @@ -3863,7 +3887,7 @@ public: } else { - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); return CTFEExp.cantexp; } @@ -3899,7 +3923,7 @@ public: newval = resolveSlice(newval); if (CTFEExp.isCantExp(newval)) { - e.error("CTFE internal error: assignment `%s`", e.toChars()); + error(e.loc, "CTFE internal error: assignment `%s`", e.toChars()); return CTFEExp.cantexp; } } @@ -4035,7 +4059,7 @@ public: const srclen = resolveArrayLength(newval); if (srclen != (upperbound - lowerbound)) { - e.error("array length mismatch assigning `[0..%llu]` to `[%llu..%llu]`", + error(e.loc, "array length mismatch assigning `[0..%llu]` to `[%llu..%llu]`", ulong(srclen), ulong(lowerbound), ulong(upperbound)); return CTFEExp.cantexp; } @@ -4045,7 +4069,7 @@ public: { if (existingSE.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only string literal `%s`", existingSE.toChars()); + error(e.loc, "cannot modify read-only string literal `%s`", existingSE.toChars()); return CTFEExp.cantexp; } @@ -4058,7 +4082,7 @@ public: if (aggregate == aggr2 && lowerbound < srcupper && srclower < upperbound) { - e.error("overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`", + error(e.loc, "overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`", ulong(lowerbound), ulong(upperbound), ulong(srclower), ulong(srcupper)); return CTFEExp.cantexp; } @@ -4068,7 +4092,7 @@ public: newval = resolveSlice(newval); if (CTFEExp.isCantExp(newval)) { - e.error("CTFE internal error: slice `%s`", orignewval.toChars()); + error(e.loc, "CTFE internal error: slice `%s`", orignewval.toChars()); return CTFEExp.cantexp; } } @@ -4106,7 +4130,7 @@ public: { if (existingAE.ownedByCtfe != OwnedBy.ctfe) { - e.error("cannot modify read-only constant `%s`", existingAE.toChars()); + error(e.loc, "cannot modify read-only constant `%s`", existingAE.toChars()); return CTFEExp.cantexp; } @@ -4178,7 +4202,7 @@ public: if (aggregate == aggr2 && lowerbound < srcupper && srclower < upperbound) { - e.error("overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`", + error(e.loc, "overlapping slice assignment `[%llu..%llu] = [%llu..%llu]`", ulong(lowerbound), ulong(upperbound), ulong(srclower), ulong(srcupper)); return CTFEExp.cantexp; } @@ -4188,7 +4212,7 @@ public: newval = resolveSlice(newval); if (CTFEExp.isCantExp(newval)) { - e.error("CTFE internal error: slice `%s`", orignewval.toChars()); + error(e.loc, "CTFE internal error: slice `%s`", orignewval.toChars()); return CTFEExp.cantexp; } } @@ -4309,7 +4333,7 @@ public: return interpret(pue, retslice, istate); } - e.error("slice operation `%s = %s` cannot be evaluated at compile time", e1.toChars(), newval.toChars()); + error(e.loc, "slice operation `%s = %s` cannot be evaluated at compile time", e1.toChars(), newval.toChars()); return CTFEExp.cantexp; } @@ -4514,7 +4538,7 @@ public: } if (except) { - e.error("comparison `%s` of pointers to unrelated memory blocks remains indeterminate at compile time because exception `%s` was thrown while evaluating `%s`", e.e1.toChars(), except.toChars(), e.e2.toChars()); + error(e.loc, "comparison `%s` of pointers to unrelated memory blocks remains indeterminate at compile time because exception `%s` was thrown while evaluating `%s`", e.e1.toChars(), except.toChars(), e.e2.toChars()); result = CTFEExp.cantexp; return; } @@ -4537,7 +4561,7 @@ public: // comparison is in the same direction as the first, or else // more than two memory blocks are involved (either two independent // invalid comparisons are present, or else agg3 == agg4). - e.error("comparison `%s` of pointers to unrelated memory blocks is indeterminate at compile time, even when combined with `%s`.", e.e1.toChars(), e.e2.toChars()); + error(e.loc, "comparison `%s` of pointers to unrelated memory blocks is indeterminate at compile time, even when combined with `%s`.", e.e1.toChars(), e.e2.toChars()); result = CTFEExp.cantexp; return; } @@ -4630,14 +4654,14 @@ public: res = true; else { - e.error("`%s` does not evaluate to a `bool`", result.toChars()); + error(e.loc, "`%s` does not evaluate to a `bool`", result.toChars()); result = CTFEExp.cantexp; return; } } else { - e.error("`%s` cannot be interpreted as a `bool`", result.toChars()); + error(e.loc, "`%s` cannot be interpreted as a `bool`", result.toChars()); result = CTFEExp.cantexp; return; } @@ -4667,7 +4691,7 @@ public: } errorSupplemental(callingExp.loc, "called from here: `%s`", callingExp.toChars()); // Quit if it's not worth trying to compress the stack trace - if (ctfeGlobals.callDepth < 6 || global.params.verbose) + if (ctfeGlobals.callDepth < 6 || global.params.v.verbose) return; // Recursion happens if the current function already exists in the call stack. int numToSuppress = 0; @@ -4851,13 +4875,13 @@ public: { // delegate.funcptr() // others - e.error("cannot call `%s` at compile time", e.toChars()); + error(e.loc, "cannot call `%s` at compile time", e.toChars()); result = CTFEExp.cantexp; return; } if (!fd) { - e.error("CTFE internal error: cannot evaluate `%s` at compile time", e.toChars()); + error(e.loc, "CTFE internal error: cannot evaluate `%s` at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -4870,7 +4894,7 @@ public: if (pthis.op == EXP.typeid_) { - pthis.error("static variable `%s` cannot be read at compile time", pthis.toChars()); + error(pthis.loc, "static variable `%s` cannot be read at compile time", pthis.toChars()); result = CTFEExp.cantexp; return; } @@ -4879,7 +4903,7 @@ public: if (pthis.op == EXP.null_) { assert(pthis.type.toBasetype().ty == Tclass); - e.error("function call through null class reference `%s`", pthis.toChars()); + error(e.loc, "function call through null class reference `%s`", pthis.toChars()); result = CTFEExp.cantexp; return; } @@ -4901,7 +4925,7 @@ public: if (fd && fd.semanticRun >= PASS.semantic3done && fd.hasSemantic3Errors()) { - e.error("CTFE failed because of previous errors in `%s`", fd.toChars()); + error(e.loc, "CTFE failed because of previous errors in `%s`", fd.toChars()); result = CTFEExp.cantexp; return; } @@ -4913,7 +4937,7 @@ public: if (!fd.fbody) { - e.error("`%s` cannot be interpreted at compile time, because it has no available source code", fd.toChars()); + error(e.loc, "`%s` cannot be interpreted at compile time, because it has no available source code", fd.toChars()); result = CTFEExp.showcontext; return; } @@ -5092,7 +5116,7 @@ public: } else { - e.error("`%s` does not evaluate to boolean result at compile time", e.econd.toChars()); + error(e.loc, "`%s` does not evaluate to boolean result at compile time", e.econd.toChars()); result = CTFEExp.cantexp; } } @@ -5110,7 +5134,7 @@ public: return; if (e1.op != EXP.string_ && e1.op != EXP.arrayLiteral && e1.op != EXP.slice && e1.op != EXP.null_) { - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -5163,7 +5187,7 @@ public: return; if (e1.op != EXP.arrayLiteral && e1.op != EXP.int64 && e1.op != EXP.float64) { - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -5193,7 +5217,7 @@ public: if (result.op != EXP.vector) return; } - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); result = CTFEExp.cantexp; } @@ -5207,7 +5231,7 @@ public: assert(e1); if (exceptionOrCant(e1)) return; - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); result = CTFEExp.cantexp; } @@ -5221,7 +5245,7 @@ public: assert(e1); if (exceptionOrCant(e1)) return; - e.error("`%s` cannot be evaluated at compile time", e.toChars()); + error(e.loc, "`%s` cannot be evaluated at compile time", e.toChars()); result = CTFEExp.cantexp; } @@ -5246,18 +5270,18 @@ public: if (agg.op == EXP.null_) { - e.error("cannot index through null pointer `%s`", e.e1.toChars()); + error(e.loc, "cannot index through null pointer `%s`", e.e1.toChars()); return false; } if (agg.op == EXP.int64) { - e.error("cannot index through invalid pointer `%s` of value `%s`", e.e1.toChars(), e1.toChars()); + error(e.loc, "cannot index through invalid pointer `%s` of value `%s`", e.e1.toChars(), e1.toChars()); return false; } // Pointer to a non-array variable if (agg.op == EXP.symbolOffset) { - e.error("mutable variable `%s` cannot be %s at compile time, even through a pointer", cast(char*)(modify ? "modified" : "read"), agg.isSymOffExp().var.toChars()); + error(e.loc, "mutable variable `%s` cannot be %s at compile time, even through a pointer", cast(char*)(modify ? "modified" : "read"), agg.isSymOffExp().var.toChars()); return false; } @@ -5266,7 +5290,7 @@ public: dinteger_t len = resolveArrayLength(agg); if (ofs + indx >= len) { - e.error("pointer index `[%lld]` exceeds allocated memory block `[0..%lld]`", ofs + indx, len); + error(e.loc, "pointer index `[%lld]` exceeds allocated memory block `[0..%lld]`", ofs + indx, len); return false; } } @@ -5274,7 +5298,7 @@ public: { if (ofs + indx != 0) { - e.error("pointer index `[%lld]` lies outside memory block `[0..1]`", ofs + indx); + error(e.loc, "pointer index `[%lld]` lies outside memory block `[0..1]`", ofs + indx); return false; } } @@ -5288,7 +5312,7 @@ public: return false; if (e1.op == EXP.null_) { - e.error("cannot index null array `%s`", e.e1.toChars()); + error(e.loc, "cannot index null array `%s`", e.e1.toChars()); return false; } if (auto ve = e1.isVectorExp()) @@ -5306,7 +5330,7 @@ public: { if (e1.op != EXP.arrayLiteral && e1.op != EXP.string_ && e1.op != EXP.slice && e1.op != EXP.vector) { - e.error("cannot determine length of `%s` at compile time", e.e1.toChars()); + error(e.loc, "cannot determine length of `%s` at compile time", e.e1.toChars()); return false; } len = resolveArrayLength(e1); @@ -5325,7 +5349,7 @@ public: return false; if (e2.op != EXP.int64) { - e.error("CTFE internal error: non-integral index `[%s]`", e.e2.toChars()); + error(e.loc, "CTFE internal error: non-integral index `[%s]`", e.e2.toChars()); return false; } @@ -5338,7 +5362,7 @@ public: if (index > iupr - ilwr) { - e.error("index %llu exceeds array length %llu", index, iupr - ilwr); + error(e.loc, "index %llu exceeds array length %llu", index, iupr - ilwr); return false; } *pagg = e1.isSliceExp().e1; @@ -5350,7 +5374,7 @@ public: *pidx = e2.toInteger(); if (len <= *pidx) { - e.error("array index %lld is out of bounds `[0..%lld]`", *pidx, len); + error(e.loc, "array index %lld is out of bounds `[0..%lld]`", *pidx, len); return false; } } @@ -5408,7 +5432,7 @@ public: { assert(0); // does not reach here? } - e.error("cannot index null array `%s`", e.e1.toChars()); + error(e.loc, "cannot index null array `%s`", e.e1.toChars()); result = CTFEExp.cantexp; return; } @@ -5436,7 +5460,7 @@ public: result = findKeyInAA(e.loc, e1.isAssocArrayLiteralExp(), e2); if (!result) { - e.error("key `%s` not found in associative array `%s`", e2.toChars(), e.e1.toChars()); + error(e.loc, "key `%s` not found in associative array `%s`", e2.toChars(), e.e1.toChars()); result = CTFEExp.cantexp; } return; @@ -5464,7 +5488,7 @@ public: return; if (result.op == EXP.void_) { - e.error("`%s` is used before initialized", e.toChars()); + error(e.loc, "`%s` is used before initialized", e.toChars()); errorSupplemental(result.loc, "originally uninitialized here"); result = CTFEExp.cantexp; return; @@ -5487,7 +5511,7 @@ public: return; if (e1.op == EXP.int64) { - e.error("cannot slice invalid pointer `%s` of value `%s`", e.e1.toChars(), e1.toChars()); + error(e.loc, "cannot slice invalid pointer `%s` of value `%s`", e.e1.toChars(), e1.toChars()); result = CTFEExp.cantexp; return; } @@ -5515,19 +5539,19 @@ public: result.type = e.type; return; } - e.error("cannot slice null pointer `%s`", e.e1.toChars()); + error(e.loc, "cannot slice null pointer `%s`", e.e1.toChars()); result = CTFEExp.cantexp; return; } if (agg.op == EXP.symbolOffset) { - e.error("slicing pointers to static variables is not supported in CTFE"); + error(e.loc, "slicing pointers to static variables is not supported in CTFE"); result = CTFEExp.cantexp; return; } if (agg.op != EXP.arrayLiteral && agg.op != EXP.string_) { - e.error("pointer `%s` cannot be sliced at compile time (it does not point to an array)", e.e1.toChars()); + error(e.loc, "pointer `%s` cannot be sliced at compile time (it does not point to an array)", e.e1.toChars()); result = CTFEExp.cantexp; return; } @@ -5536,7 +5560,7 @@ public: //Type *pointee = ((TypePointer *)agg.type)->next; if (sliceBoundsCheck(0, len, ilwr, iupr)) { - e.error("pointer slice `[%lld..%lld]` exceeds allocated memory block `[0..%lld]`", ilwr, iupr, len); + error(e.loc, "pointer slice `[%lld..%lld]` exceeds allocated memory block `[0..%lld]`", ilwr, iupr, len); result = CTFEExp.cantexp; return; } @@ -5584,7 +5608,7 @@ public: { if (e1.op != EXP.arrayLiteral && e1.op != EXP.string_ && e1.op != EXP.null_ && e1.op != EXP.slice && e1.op != EXP.vector) { - e.error("cannot determine length of `%s` at compile time", e1.toChars()); + error(e.loc, "cannot determine length of `%s` at compile time", e1.toChars()); result = CTFEExp.cantexp; return; } @@ -5628,7 +5652,7 @@ public: result = e1; return; } - e1.error("slice `[%llu..%llu]` is out of bounds", ilwr, iupr); + error(e1.loc, "slice `[%llu..%llu]` is out of bounds", ilwr, iupr); result = CTFEExp.cantexp; return; } @@ -5640,7 +5664,7 @@ public: uinteger_t up1 = se.upr.toInteger(); if (sliceBoundsCheck(0, up1 - lo1, ilwr, iupr)) { - e.error("slice `[%llu..%llu]` exceeds array bounds `[0..%llu]`", ilwr, iupr, up1 - lo1); + error(e.loc, "slice `[%llu..%llu]` exceeds array bounds `[0..%llu]`", ilwr, iupr, up1 - lo1); result = CTFEExp.cantexp; return; } @@ -5657,7 +5681,7 @@ public: { if (sliceBoundsCheck(0, dollar, ilwr, iupr)) { - e.error("slice `[%lld..%lld]` exceeds array bounds `[0..%lld]`", ilwr, iupr, dollar); + error(e.loc, "slice `[%lld..%lld]` exceeds array bounds `[0..%lld]`", ilwr, iupr, dollar); result = CTFEExp.cantexp; return; } @@ -5687,7 +5711,7 @@ public: } if (e2.op != EXP.assocArrayLiteral) { - e.error("`%s` cannot be interpreted at compile time", e.toChars()); + error(e.loc, "`%s` cannot be interpreted at compile time", e.toChars()); result = CTFEExp.cantexp; return; } @@ -5769,7 +5793,7 @@ public: if (CTFEExp.isCantExp(result)) { - e.error("`%s` cannot be interpreted at compile time", e.toChars()); + error(e.loc, "`%s` cannot be interpreted at compile time", e.toChars()); return; } // We know we still own it, because we interpreted both e1 and e2 @@ -5811,7 +5835,7 @@ public: case Tclass: if (result.op != EXP.classReference) { - e.error("`delete` on invalid class reference `%s`", result.toChars()); + error(e.loc, "`delete` on invalid class reference `%s`", result.toChars()); result = CTFEExp.cantexp; return; } @@ -5902,7 +5926,7 @@ public: } else if (ultimatePointee.ty != Tvoid && ultimateSrc.ty != Tvoid && !isSafePointerCast(elemtype, pointee)) { - e.error("reinterpreting cast from `%s*` to `%s*` is not supported in CTFE", elemtype.toChars(), pointee.toChars()); + error(e.loc, "reinterpreting cast from `%s*` to `%s*` is not supported in CTFE", elemtype.toChars(), pointee.toChars()); result = CTFEExp.cantexp; return; } @@ -5961,7 +5985,7 @@ public: } if (!isSafePointerCast(origType, pointee)) { - e.error("using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE", origType.toChars(), pointee.toChars()); + error(e.loc, "using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE", origType.toChars(), pointee.toChars()); result = CTFEExp.cantexp; return; } @@ -6005,7 +6029,7 @@ public: Type origType = (cast(SymbolExp)e1).var.type; if (castBackFromVoid && !isSafePointerCast(origType, pointee)) { - e.error("using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE", origType.toChars(), pointee.toChars()); + error(e.loc, "using `void*` to reinterpret cast from `%s*` to `%s*` is not supported in CTFE", origType.toChars(), pointee.toChars()); result = CTFEExp.cantexp; return; } @@ -6022,7 +6046,7 @@ public: e1 = interpretRegion(e1, istate); if (e1.op != EXP.null_) { - e.error("pointer cast from `%s` to `%s` is not supported at compile time", e1.type.toChars(), e.to.toChars()); + error(e.loc, "pointer cast from `%s` to `%s` is not supported at compile time", e1.type.toChars(), e.to.toChars()); result = CTFEExp.cantexp; return; } @@ -6043,7 +6067,7 @@ public: SliceExp se = e1.isSliceExp(); if (!isSafePointerCast(se.e1.type.nextOf(), e.to.nextOf())) { - e.error("array cast from `%s` to `%s` is not supported at compile time", se.e1.type.toChars(), e.to.toChars()); + error(e.loc, "array cast from `%s` to `%s` is not supported at compile time", se.e1.type.toChars(), e.to.toChars()); result = CTFEExp.cantexp; return; } @@ -6056,7 +6080,7 @@ public: // types of identical size. if ((e.to.ty == Tsarray || e.to.ty == Tarray) && (e1.type.ty == Tsarray || e1.type.ty == Tarray) && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf())) { - e.error("array cast from `%s` to `%s` is not supported at compile time", e1.type.toChars(), e.to.toChars()); + error(e.loc, "array cast from `%s` to `%s` is not supported at compile time", e1.type.toChars(), e.to.toChars()); result = CTFEExp.cantexp; return; } @@ -6104,18 +6128,18 @@ public: return; result = scrubReturnValue(e.loc, result); if (StringExp se = result.toStringExp()) - e.error("%s", se.toStringz().ptr); + error(e.loc, "%s", se.toStringz().ptr); else - e.error("%s", result.toChars()); + error(e.loc, "%s", result.toChars()); } else - e.error("`%s` failed", e.toChars()); + error(e.loc, "`%s` failed", e.toChars()); result = CTFEExp.cantexp; return; } else { - e.error("`%s` is not a compile time boolean expression", e1.toChars()); + error(e.loc, "`%s` is not a compile time boolean expression", e1.toChars()); result = CTFEExp.cantexp; return; } @@ -6193,7 +6217,7 @@ public: { if (soe.offset == 0 && soe.var.isFuncDeclaration()) return; - e.error("cannot dereference pointer to static variable `%s` at compile time", soe.var.toChars()); + error(e.loc, "cannot dereference pointer to static variable `%s` at compile time", soe.var.toChars()); result = CTFEExp.cantexp; return; } @@ -6218,9 +6242,9 @@ public: if (result.op != EXP.address) { if (result.op == EXP.null_) - e.error("dereference of null pointer `%s`", e.e1.toChars()); + error(e.loc, "dereference of null pointer `%s`", e.e1.toChars()); else - e.error("dereference of invalid pointer `%s`", result.toChars()); + error(e.loc, "dereference of invalid pointer `%s`", result.toChars()); result = CTFEExp.cantexp; return; } @@ -6251,7 +6275,7 @@ public: { void notImplementedYet() { - e.error("`%s.%s` is not yet implemented at compile time", e.e1.toChars(), e.var.toChars()); + error(e.loc, "`%s.%s` is not yet implemented at compile time", e.e1.toChars(), e.var.toChars()); result = CTFEExp.cantexp; return; } @@ -6280,7 +6304,7 @@ public: VarDeclaration v = e.var.isVarDeclaration(); if (!v) { - e.error("CTFE internal error: `%s`", e.toChars()); + error(e.loc, "CTFE internal error: `%s`", e.toChars()); result = CTFEExp.cantexp; return; } @@ -6288,9 +6312,9 @@ public: if (ex.op == EXP.null_) { if (ex.type.toBasetype().ty == Tclass) - e.error("class `%s` is `null` and cannot be dereferenced", e.e1.toChars()); + error(e.loc, "class `%s` is `null` and cannot be dereferenced", e.e1.toChars()); else - e.error("CTFE internal error: null this `%s`", e.e1.toChars()); + error(e.loc, "CTFE internal error: null this `%s`", e.e1.toChars()); result = CTFEExp.cantexp; return; } @@ -6333,7 +6357,7 @@ public: } if (i == -1) { - e.error("couldn't find field `%s` of type `%s` in `%s`", v.toChars(), e.type.toChars(), se.toChars()); + error(e.loc, "couldn't find field `%s` of type `%s` in `%s`", v.toChars(), e.type.toChars(), se.toChars()); result = CTFEExp.cantexp; return; } @@ -6361,7 +6385,7 @@ public: result = (*se.elements)[i]; if (!result) { - e.error("internal compiler error: null field `%s`", v.toChars()); + error(e.loc, "internal compiler error: null field `%s`", v.toChars()); result = CTFEExp.cantexp; return; } @@ -6370,11 +6394,11 @@ public: const s = vie.var.toChars(); if (v.overlapped) { - e.error("reinterpretation through overlapped field `%s` is not allowed in CTFE", s); + error(e.loc, "reinterpretation through overlapped field `%s` is not allowed in CTFE", s); result = CTFEExp.cantexp; return; } - e.error("cannot read uninitialized variable `%s` in CTFE", s); + error(e.loc, "cannot read uninitialized variable `%s` in CTFE", s); result = CTFEExp.cantexp; return; } @@ -6444,7 +6468,7 @@ public: override void visit(VoidInitExp e) { - e.error("CTFE internal error: trying to read uninitialized variable"); + error(e.loc, "CTFE internal error: trying to read uninitialized variable"); assert(0); } @@ -6472,7 +6496,7 @@ void interpretThrow(ref Expression result, Expression exp, const ref Loc loc, In } else { - exp.error("to be thrown `%s` must be non-null", exp.toChars()); + error(exp.loc, "to be thrown `%s` must be non-null", exp.toChars()); result = ErrorExp.get(); } } @@ -7258,7 +7282,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression auto ale = str.isArrayLiteralExp(); if (!se && !ale) { - str.error("CTFE internal error: cannot foreach `%s`", str.toChars()); + error(str.loc, "CTFE internal error: cannot foreach `%s`", str.toChars()); return CTFEExp.cantexp; } Expressions args = Expressions(numParams); @@ -7410,7 +7434,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression } if (errmsg) { - deleg.error("`%.*s`", cast(int)errmsg.length, errmsg.ptr); + error(deleg.loc, "`%.*s`", cast(int)errmsg.length, errmsg.ptr); return CTFEExp.cantexp; } @@ -7714,6 +7738,6 @@ private void removeHookTraceImpl(ref CallExp ce, ref FuncDeclaration fd) ce = ctfeEmplaceExp!CallExp(ce.loc, ctfeEmplaceExp!VarExp(ce.loc, fd, false), arguments); - if (global.params.verbose) + if (global.params.v.verbose) message("strip %s =>\n %s", oldCE.toChars(), ce.toChars()); } diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 9b7230897129..8fdb1ae835c5 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -142,6 +142,7 @@ import dmd.declaration; import dmd.dmodule; import dmd.dsymbol; import dmd.dtemplate; +import dmd.errors; import dmd.expression; import dmd.func; import dmd.globals; @@ -821,7 +822,7 @@ public: printf("\n"); } if (!ti.tempdecl) - ti.error("is not defined"); + error(ti.loc, "%s `%s` is not defined", ti.kind, ti.toPrettyChars); else mangleParent(ti); @@ -888,7 +889,7 @@ public: buf.writeByte('V'); if (ea.op == EXP.tuple) { - ea.error("sequence is not a valid template value argument"); + error(ea.loc, "sequence is not a valid template value argument"); continue; } // Now that we know it is not an alias, we MUST obtain a value @@ -926,7 +927,7 @@ public: } if (!d.type || !d.type.deco) { - ti.error("forward reference of %s `%s`", d.kind(), d.toChars()); + error(ti.loc, "%s `%s` forward reference of %s `%s`", ti.kind, ti.toPrettyChars, d.kind(), d.toChars()); continue; } } @@ -982,7 +983,8 @@ public: //////////////////////////////////////////////////////////////////////////// override void visit(Expression e) { - e.error("expression `%s` is not a valid template value argument", e.toChars()); + if (!e.type.isTypeError()) + error(e.loc, "expression `%s` is not a valid template value argument", e.toChars()); } override void visit(IntegerExp e) @@ -1040,7 +1042,7 @@ public: { dchar c; if (const s = utf_decodeWchar(slice, u, c)) - e.error("%.*s", cast(int)s.length, s.ptr); + error(e.loc, "%.*s", cast(int)s.length, s.ptr); else tmp.writeUTF8(c); } @@ -1054,7 +1056,7 @@ public: foreach (c; slice) { if (!utf_isValidDchar(c)) - e.error("invalid UCS-32 char \\U%08x", c); + error(e.loc, "invalid UCS-32 char \\U%08x", c); else tmp.writeUTF8(c); } @@ -1300,7 +1302,7 @@ extern (D) void toBuffer(ref OutBuffer buf, const(char)[] id, Dsymbol s) { const len = id.length; if (buf.length + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone - s.error("excessive length %llu for symbol, possible recursive expansion?", cast(ulong)(buf.length + len)); + error(s.loc, "%s `%s` excessive length %llu for symbol, possible recursive expansion?", s.kind, s.toPrettyChars, cast(ulong)(buf.length + len)); else { buf.print(len); @@ -1422,7 +1424,7 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d) (d.isVarDeclaration() && d.isDataseg() && d.storage_class & STC.extern_)))) { if (linkage != LINK.d && d.localNum) - d.error("the same declaration cannot be in multiple scopes with non-D linkage"); + error(d.loc, "%s `%s` the same declaration cannot be in multiple scopes with non-D linkage", d.kind, d.toPrettyChars); final switch (linkage) { @@ -1438,7 +1440,7 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d) return p.toDString(); } case LINK.default_: - d.error("forward declaration"); + error(d.loc, "%s `%s` forward declaration", d.kind, d.toPrettyChars); return d.ident.toString(); case LINK.system: assert(0); diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index eb68b31edeb0..202630304be0 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -468,7 +468,8 @@ extern (C++) final class Module : Package !FileName.equalsExt(srcfilename, dd_ext)) { - error("source file name '%.*s' must have .%.*s extension", + error(loc, "%s `%s` source file name '%.*s' must have .%.*s extension", + kind, toPrettyChars, cast(int)srcfilename.length, srcfilename.ptr, cast(int)mars_ext.length, mars_ext.ptr); fatal(); @@ -528,7 +529,7 @@ extern (C++) final class Module : Package if (!m.read(loc)) return null; - if (global.params.verbose) + if (global.params.v.verbose) { OutBuffer buf; foreach (pid; packages) @@ -593,7 +594,8 @@ extern (C++) final class Module : Package } if (FileName.equals(docfilename, srcfile.toString())) { - error("source file and output file have same name '%s'", srcfile.toChars()); + error(loc, "%s `%s` source file and output file have same name '%s'", + kind, toPrettyChars, srcfile.toChars()); fatal(); } return FileName(docfilename); @@ -793,7 +795,7 @@ extern (C++) final class Module : Package { const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; scope p = new Parser!AST(this, buf, cast(bool) docfile, global.errorSink, &global.compileEnv, doUnittests); - p.transitionIn = global.params.vin; + p.transitionIn = global.params.v.vin; p.nextToken(); p.parseModuleDeclaration(); md = p.md; @@ -852,7 +854,7 @@ extern (C++) final class Module : Package /* Check to see if module name is a valid identifier */ if (!Identifier.isValidIdentifier(this.ident.toChars())) - error("has non-identifier characters in filename, use module declaration instead"); + error(loc, "%s `%s` has non-identifier characters in filename, use module declaration instead", kind, toPrettyChars); } // Insert module into the symbol table Dsymbol s = this; @@ -905,11 +907,11 @@ extern (C++) final class Module : Package if (Module mprev = prev.isModule()) { if (!FileName.equals(srcname, mprev.srcfile.toChars())) - error(loc, "from file %s conflicts with another module %s from file %s", srcname, mprev.toChars(), mprev.srcfile.toChars()); + error(loc, "%s `%s` from file %s conflicts with another module %s from file %s", kind, toPrettyChars, srcname, mprev.toChars(), mprev.srcfile.toChars()); else if (isRoot() && mprev.isRoot()) - error(loc, "from file %s is specified twice on the command line", srcname); + error(loc, "%s `%s` from file %s is specified twice on the command line", kind, toPrettyChars, srcname); else - error(loc, "from file %s must be imported with 'import %s;'", srcname, toPrettyChars()); + error(loc, "%s `%s` from file %s must be imported with 'import %s;'", kind, toPrettyChars, srcname, toPrettyChars()); // https://issues.dlang.org/show_bug.cgi?id=14446 // Return previously parsed module to avoid AST duplication ICE. return mprev; @@ -920,7 +922,7 @@ extern (C++) final class Module : Package if (isPackageFile) amodules.push(this); // Add to global array of all modules else - error(md ? md.loc : loc, "from file %s conflicts with package name %s", srcname, pkg.toChars()); + error(md ? md.loc : loc, "%s `%s` from file %s conflicts with package name %s", kind, toPrettyChars, srcname, pkg.toChars()); } else assert(global.errors); @@ -941,7 +943,7 @@ extern (C++) final class Module : Package return; // already done if (filetype == FileType.ddoc) { - error("is a Ddoc file, cannot import it"); + error(loc, "%s `%s` is a Ddoc file, cannot import it", kind, toPrettyChars); return; } @@ -1026,11 +1028,11 @@ extern (C++) final class Module : Package const slice = se.peekString(); if (slice.length) { - deprecation(loc, "is deprecated - %.*s", cast(int)slice.length, slice.ptr); + deprecation(loc, "%s `%s` is deprecated - %.*s", kind, toPrettyChars, cast(int)slice.length, slice.ptr); return; } } - deprecation(loc, "is deprecated"); + deprecation(loc, "%s `%s` is deprecated", kind, toPrettyChars); } } @@ -1479,7 +1481,8 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) if (buf.length & 3) { - mod.error("odd length of UTF-32 char source %llu", cast(ulong) buf.length); + .error(mod.loc, "%s `%s` odd length of UTF-32 char source %llu", + mod.kind, mod.toPrettyChars, cast(ulong) buf.length); return null; } @@ -1495,7 +1498,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) { if (u > 0x10FFFF) { - mod.error("UTF-32 value %08x greater than 0x10FFFF", u); + .error(mod.loc, "%s `%s` UTF-32 value %08x greater than 0x10FFFF", mod.kind, mod.toPrettyChars, u); return null; } dbuf.writeUTF8(u); @@ -1525,7 +1528,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) if (buf.length & 1) { - mod.error("odd length of UTF-16 char source %llu", cast(ulong) buf.length); + .error(mod.loc, "%s `%s` odd length of UTF-16 char source %llu", mod.kind, mod.toPrettyChars, cast(ulong) buf.length); return null; } @@ -1545,13 +1548,13 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) i++; if (i >= eBuf.length) { - mod.error("surrogate UTF-16 high value %04x at end of file", u); + .error(mod.loc, "%s `%s` surrogate UTF-16 high value %04x at end of file", mod.kind, mod.toPrettyChars, u); return null; } const u2 = readNext(&eBuf[i]); if (u2 < 0xDC00 || 0xE000 <= u2) { - mod.error("surrogate UTF-16 low value %04x out of range", u2); + .error(mod.loc, "%s `%s` surrogate UTF-16 low value %04x out of range", mod.kind, mod.toPrettyChars, u2); return null; } u = (u - 0xD7C0) << 10; @@ -1559,12 +1562,12 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) } else if (u >= 0xDC00 && u <= 0xDFFF) { - mod.error("unpaired surrogate UTF-16 value %04x", u); + .error(mod.loc, "%s `%s` unpaired surrogate UTF-16 value %04x", mod.kind, mod.toPrettyChars, u); return null; } else if (u == 0xFFFE || u == 0xFFFF) { - mod.error("illegal UTF-16 value %04x", u); + .error(mod.loc, "%s `%s` illegal UTF-16 value %04x", mod.kind, mod.toPrettyChars, u); return null; } dbuf.writeUTF8(u); @@ -1623,7 +1626,8 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) // It's UTF-8 if (buf[0] >= 0x80) { - mod.error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]); + auto loc = mod.getLoc(); + .error(loc, "%s `%s` source file must start with BOM or ASCII character, not \\x%02X", mod.kind, mod.toPrettyChars, buf[0]); return null; } diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index 5488d5a0008f..b1a4c2fe504b 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -438,7 +438,7 @@ void gendocfile(Module m, const char[] ddoctext, const char* datetime, ErrorSink if (!loc.filename) loc.filename = srcfilename.ptr; - size_t commentlen = m.comment ? strlen(cast(char*)m.comment) : 0; + size_t commentlen = strlen(cast(char*)m.comment); Dsymbols a; // https://issues.dlang.org/show_bug.cgi?id=9764 // Don't push m in a, to prevent emphasize ddoc file name. diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index a131a8a721c4..56aad3eece3b 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -273,7 +273,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration { // .stringof is always defined (but may be hidden by some other symbol) if(ident != Id.stringof && !(flags & IgnoreErrors) && semanticRun < PASS.semanticdone) - error("is forward referenced when looking for `%s`", ident.toChars()); + .error(loc, "%s `%s` is forward referenced when looking for `%s`", kind, toPrettyChars, ident.toChars()); return null; } diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index c9a2c92194b8..1f4a4664c3ef 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -375,79 +375,6 @@ extern (C++) class Dsymbol : ASTNode return '`' ~ cstr.toDString() ~ "`\0"; } - static if (__VERSION__ < 2092) - { - final void error(const ref Loc loc, const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.error, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - final void error(const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - const loc = getLoc(); - .verrorReport(loc, format, ap, ErrorKind.error, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - final void deprecation(const ref Loc loc, const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.deprecation, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - final void deprecation(const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - const loc = getLoc(); - .verrorReport(loc, format, ap, ErrorKind.deprecation, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - } - else - { - pragma(printf) final void error(const ref Loc loc, const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.error, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - pragma(printf) final void error(const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - const loc = getLoc(); - .verrorReport(loc, format, ap, ErrorKind.error, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - pragma(printf) final void deprecation(const ref Loc loc, const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.deprecation, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - - pragma(printf) final void deprecation(const(char)* format, ...) - { - va_list ap; - va_start(ap, format); - const loc = getLoc(); - .verrorReport(loc, format, ap, ErrorKind.deprecation, kind(), prettyFormatHelper().ptr); - va_end(ap); - } - } - final bool checkDeprecated(const ref Loc loc, Scope* sc) { if (global.params.useDeprecated == DiagnosticReporting.off) @@ -470,9 +397,9 @@ extern (C++) class Dsymbol : ASTNode break; } if (message) - deprecation(loc, "is deprecated - %s", message); + deprecation(loc, "%s `%s` is deprecated - %s", kind, toPrettyChars, message); else - deprecation(loc, "is deprecated"); + deprecation(loc, "%s `%s` is deprecated", kind, toPrettyChars); if (auto ti = sc.parent ? sc.parent.isInstantiated() : null) ti.printInstantiationTrace(Classification.deprecation); @@ -886,7 +813,7 @@ extern (C++) class Dsymbol : ASTNode if (ident == Id.__sizeof || !(sc && sc.flags & SCOPE.Cfile) && (ident == Id.__xalignof || ident == Id._mangleof)) { - error("`.%s` property cannot be redefined", ident.toChars()); + .error(loc, "%s `%s` `.%s` property cannot be redefined", kind, toPrettyChars, ident.toChars()); errors = true; } } @@ -1026,7 +953,7 @@ extern (C++) class Dsymbol : ASTNode */ uinteger_t size(const ref Loc loc) { - error("symbol `%s` has no size", toChars()); + .error(loc, "%s `%s` symbol `%s` has no size", kind, toPrettyChars, toChars()); return SIZE_INVALID; } @@ -1776,7 +1703,7 @@ public: } else { - s1.error(s1.loc, "conflicts with %s `%s` at %s", s2.kind(), s2.toPrettyChars(), s2.locToChars()); + .error(s1.loc, "%s `%s` conflicts with %s `%s` at %s", s1.kind, s1.toPrettyChars, s2.kind(), s2.toPrettyChars(), s2.locToChars()); } } @@ -2140,7 +2067,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol */ if (exp.op == EXP.array && (cast(ArrayExp)exp).arguments.length != 1) { - exp.error("`%s` only defines opDollar for one dimension", ad.toChars()); + error(exp.loc, "`%s` only defines opDollar for one dimension", ad.toChars()); return null; } Declaration d = s.isDeclaration(); @@ -2149,7 +2076,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol } e = e.expressionSemantic(sc); if (!e.type) - exp.error("`%s` has no value", e.toChars()); + error(exp.loc, "`%s` has no value", e.toChars()); t = e.type.toBasetype(); if (t && t.ty == Tfunction) e = new CallExp(e.loc, e); diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index 96fa8fdd6400..027897532d1f 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -205,10 +205,6 @@ public: const char *locToChars(); bool equals(const RootObject * const o) const override; bool isAnonymous() const; - void error(const Loc &loc, const char *format, ...); - void error(const char *format, ...); - void deprecation(const Loc &loc, const char *format, ...); - void deprecation(const char *format, ...); bool checkDeprecated(const Loc &loc, Scope *sc); Module *getModule(); bool isCsymbol(); diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index ebdd3a8566d9..65c07952e00a 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -205,7 +205,7 @@ const(char)* getMessage(DeprecatedDeclaration dd) if (auto se = dd.msg.toStringExp()) dd.msgstr = se.toStringz().ptr; else - dd.msg.error("compile time constant expected, not `%s`", dd.msg.toChars()); + error(dd.msg.loc, "compile time constant expected, not `%s`", dd.msg.toChars()); } return dd.msgstr; } @@ -289,7 +289,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(Dsymbol dsym) { - dsym.error("%p has no semantic routine", dsym); + .error(dsym.loc, "%s `%s` %p has no semantic routine", dsym.kind, dsym.toPrettyChars, dsym); } override void visit(ScopeDsymbol) { } @@ -467,7 +467,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (dsym.storage_class & STC.extern_ && dsym._init) - dsym.error("extern symbols cannot have initializers"); + .error(dsym.loc, "%s `%s` extern symbols cannot have initializers", dsym.kind, dsym.toPrettyChars); AggregateDeclaration ad = dsym.isThis(); if (ad) @@ -553,16 +553,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (inferred) { - dsym.error("- type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", dsym.type.toChars(), dsym._init.toChars()); + .error(dsym.loc, "%s `%s` - type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", + dsym.kind, dsym.toPrettyChars, dsym.type.toChars(), toChars(dsym._init)); } else - dsym.error("- variables cannot be of type `void`"); + .error(dsym.loc, "%s `%s` - variables cannot be of type `void`", dsym.kind, dsym.toPrettyChars); dsym.type = Type.terror; tb = dsym.type; } if (tb.ty == Tfunction) { - dsym.error("cannot be declared to be a function"); + .error(dsym.loc, "%s `%s` cannot be declared to be a function", dsym.kind, dsym.toPrettyChars); dsym.type = Type.terror; tb = dsym.type; } @@ -572,7 +573,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // or when the variable is defined externally if (!ts.sym.members && !(dsym.storage_class & (STC.ref_ | STC.extern_))) { - dsym.error("- no definition of struct `%s`", ts.toChars()); + .error(dsym.loc, "%s `%s` - no definition of struct `%s`", dsym.kind, dsym.toPrettyChars, ts.toChars()); // Explain why the definition is required when it's part of another type if (!dsym.type.isTypeStruct()) @@ -590,7 +591,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } if ((dsym.storage_class & STC.auto_) && !inferred) - dsym.error("- storage class `auto` has no effect if type is not inferred, did you mean `scope`?"); + .error(dsym.loc, "%s `%s` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?", dsym.kind, dsym.toPrettyChars); if (auto tt = tb.isTypeTuple()) { @@ -762,12 +763,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_)) { if (stc == STC.final_) - dsym.error("cannot be `final`, perhaps you meant `const`?"); + .error(dsym.loc, "%s `%s` cannot be `final`, perhaps you meant `const`?", dsym.kind, dsym.toPrettyChars); else { OutBuffer buf; stcToBuffer(buf, stc); - dsym.error("cannot be `%s`", buf.peekChars()); + .error(dsym.loc, "%s `%s` cannot be `%s`", dsym.kind, dsym.toPrettyChars, buf.peekChars()); } dsym.storage_class &= ~stc; // strip off } @@ -784,7 +785,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { OutBuffer buf; stcToBuffer(buf, stc); - dsym.error("cannot be `scope` and `%s`", buf.peekChars()); + .error(dsym.loc, "%s `%s` cannot be `scope` and `%s`", dsym.kind, dsym.toPrettyChars, buf.peekChars()); } else if (dsym.isMember()) { @@ -809,7 +810,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor AggregateDeclaration aad = parent.isAggregateDeclaration(); if (aad) { - if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer()) + if (global.params.v.field && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer()) { const(char)* s = (dsym.storage_class & STC.immutable_) ? "immutable" : "const"; message(dsym.loc, "`%s.%s` is `%s` field", ad.toPrettyChars(), dsym.toChars(), s); @@ -850,7 +851,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor AggregateDeclaration ad2 = ti.tempdecl.isMember(); if (ad2 && dsym.storage_class != STC.undefined_) { - dsym.error("- cannot use template to add field to aggregate `%s`", ad2.toChars()); + .error(dsym.loc, "%s `%s` - cannot use template to add field to aggregate `%s`", dsym.kind, dsym.toPrettyChars, ad2.toChars()); } } } @@ -873,14 +874,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This) { - dsym.error("- only parameters, functions and `foreach` declarations can be `ref`"); + .error(dsym.loc, "%s `%s` - only parameters, functions and `foreach` declarations can be `ref`", dsym.kind, dsym.toPrettyChars); } if (dsym.type.hasWild()) { if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg()) { - dsym.error("- only parameters or stack-based variables can be `inout`"); + .error(dsym.loc, "%s `%s` - only parameters or stack-based variables can be `inout`", dsym.kind, dsym.toPrettyChars); } FuncDeclaration func = sc.func; if (func) @@ -898,7 +899,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (!isWild) { - dsym.error("- `inout` variables can only be declared inside `inout` functions"); + .error(dsym.loc, "%s `%s` - `inout` variables can only be declared inside `inout` functions", dsym.kind, dsym.toPrettyChars); } } } @@ -918,7 +919,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { } else - dsym.error("- default construction is disabled for type `%s`", dsym.type.toChars()); + .error(dsym.loc, "%s `%s` - default construction is disabled for type `%s`", dsym.kind, dsym.toPrettyChars, dsym.type.toChars()); } } @@ -927,7 +928,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.gshared) || !fd) { - dsym.error("globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`"); + .error(dsym.loc, "%s `%s` globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`", dsym.kind, dsym.toPrettyChars); } // @@@DEPRECATED_2.097@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint @@ -936,7 +937,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!(dsym.storage_class & STC.scope_)) { if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym) - dsym.error("reference to `scope class` must be `scope`"); + .error(dsym.loc, "%s `%s` reference to `scope class` must be `scope`", dsym.kind, dsym.toPrettyChars); } } @@ -973,13 +974,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (dsym._init) { } // remember we had an explicit initializer else if (dsym.storage_class & STC.manifest) - dsym.error("- manifest constants must have initializers"); + .error(dsym.loc, "%s `%s` - manifest constants must have initializers", dsym.kind, dsym.toPrettyChars); // Don't allow non-extern, non-__gshared variables to be interfaced with C++ if (dsym._linkage == LINK.cpp && !(dsym.storage_class & (STC.ctfe | STC.extern_ | STC.gshared)) && dsym.isDataseg()) { const char* p = (dsym.storage_class & STC.shared_) ? "shared" : "static"; - dsym.error("cannot have `extern(C++)` linkage because it is `%s`", p); + .error(dsym.loc, "%s `%s` cannot have `extern(C++)` linkage because it is `%s`", dsym.kind, dsym.toPrettyChars, p); errorSupplemental(dsym.loc, "perhaps declare it as `__gshared` instead"); dsym.errors = true; } @@ -1001,7 +1002,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor //printf("Providing default initializer for '%s'\n", dsym.toChars()); if (sz == SIZE_INVALID && dsym.type.ty != Terror) - dsym.error("- size of type `%s` is invalid", dsym.type.toChars()); + .error(dsym.loc, "%s `%s` - size of type `%s` is invalid", dsym.kind, dsym.toPrettyChars, dsym.type.toChars()); Type tv = dsym.type; while (tv.ty == Tsarray) // Don't skip Tenum @@ -1036,7 +1037,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (dsym.type.baseElemOf().ty == Tvoid) { - dsym.error("of type `%s` does not have a default initializer", dsym.type.toChars()); + .error(dsym.loc, "%s `%s` of type `%s` does not have a default initializer", dsym.kind, dsym.toPrettyChars, dsym.type.toChars()); } else if (auto e = dsym.type.defaultInit(dsym.loc)) { @@ -1057,7 +1058,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor dsym._init.isVoidInitializer() && !(dsym.storage_class & STC.field)) { - dsym.error("- incomplete array type must have initializer"); + .error(dsym.loc, "%s `%s` - incomplete array type must have initializer", dsym.kind, dsym.toPrettyChars); } ExpInitializer ei = dsym._init.isExpInitializer(); @@ -1089,7 +1090,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0); if (!e) { - dsym.error("is not a static and cannot have static initializer"); + .error(dsym.loc, "%s `%s` is not a static and cannot have static initializer", dsym.kind, dsym.toPrettyChars); e = ErrorExp.get(); } } @@ -1249,7 +1250,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { // The only allowable initializer is a (non-copy) constructor if (ei.exp.isLvalue()) - dsym.error("of type struct `%s` uses `this(this)`, which is not allowed in static initialization", tb2.toChars()); + .error(dsym.loc, "%s `%s` of type struct `%s` uses `this(this)`, which is not allowed in static initialization", dsym.kind, dsym.toPrettyChars, tb2.toChars()); } } } @@ -1286,7 +1287,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { // currently disabled because of std.stdio.stdin, stdout and stderr if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_)) - dsym.error("static storage variables cannot have destructors"); + .error(dsym.loc, "%s `%s` static storage variables cannot have destructors", dsym.kind, dsym.toPrettyChars); } } @@ -1319,11 +1320,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor return; if (!(global.params.bitfields || sc.flags & SCOPE.Cfile)) - dsym.error("use -preview=bitfields for bitfield support"); + .error(dsym.loc, "%s `%s` use -preview=bitfields for bitfield support", dsym.kind, dsym.toPrettyChars); if (!dsym.parent.isStructDeclaration() && !dsym.parent.isClassDeclaration()) { - dsym.error("- bit-field must be member of struct, union, or class"); + .error(dsym.loc, "%s `%s` - bit-field must be member of struct, union, or class", dsym.kind, dsym.toPrettyChars); } sc = sc.startCTFE(); @@ -1333,18 +1334,18 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!dsym.type.isintegral()) { // C11 6.7.2.1-5 - width.error("bit-field type `%s` is not an integer type", dsym.type.toChars()); + error(width.loc, "bit-field type `%s` is not an integer type", dsym.type.toChars()); dsym.errors = true; } if (!width.isIntegerExp()) { - width.error("bit-field width `%s` is not an integer constant", dsym.width.toChars()); + error(width.loc, "bit-field width `%s` is not an integer constant", dsym.width.toChars()); dsym.errors = true; } const uwidth = width.toInteger(); // uwidth is unsigned if (uwidth == 0 && !dsym.isAnonymous()) { - width.error("bit-field `%s` has zero width", dsym.toChars()); + error(width.loc, "bit-field `%s` has zero width", dsym.toChars()); dsym.errors = true; } const sz = dsym.type.size(); @@ -1353,7 +1354,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const max_width = sz * 8; if (uwidth > max_width) { - width.error("width `%lld` of bit-field `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars()); + error(width.loc, "width `%lld` of bit-field `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars()); dsym.errors = true; } dsym.fieldWidth = cast(uint)uwidth; @@ -1453,7 +1454,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor import dmd.access : symbolIsVisible; if (!symbolIsVisible(sc, sym) && !sym.errors) { - imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`", + .error(imp.loc, "%s `%s` member `%s` is not visible from module `%s`", imp.mod.kind, imp.mod.toPrettyChars, imp.names[i].toChars(), sc._module.toChars()); sym.errors = true; } @@ -1468,9 +1469,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // https://issues.dlang.org/show_bug.cgi?id=23908 // Don't suggest symbols from the importer's module if (s && s.parent != importer) - imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars()); + .error(imp.loc, "%s `%s` import `%s` not found, did you mean %s `%s`?", imp.mod.kind, imp.mod.toPrettyChars, imp.names[i].toChars(), s.kind(), s.toPrettyChars()); else - imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars()); + .error(imp.loc, "%s `%s` import `%s` not found", imp.mod.kind, imp.mod.toPrettyChars, imp.names[i].toChars()); ad.type = Type.terror; } } @@ -1621,12 +1622,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = se; if (!se.len) { - pd.error("- zero-length string not allowed for mangled name"); + .error(pd.loc, "%s `%s` - zero-length string not allowed for mangled name", pd.kind, pd.toPrettyChars); return null; } if (se.sz != 1) { - pd.error("- mangled name characters can only be of type `char`"); + .error(pd.loc, "%s `%s` - mangled name characters can only be of type `char`", pd.kind, pd.toPrettyChars); return null; } version (all) @@ -1649,18 +1650,18 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else { - pd.error("char 0x%02x not allowed in mangled name", c); + .error(pd.loc, "%s `%s` char 0x%02x not allowed in mangled name", pd.kind, pd.toPrettyChars, c); break; } } if (const msg = utf_decodeChar(slice, i, c)) { - pd.error("%.*s", cast(int)msg.length, msg.ptr); + .error(pd.loc, "%s `%s` %.*s", pd.kind, pd.toPrettyChars, cast(int)msg.length, msg.ptr); break; } if (!isUniAlpha(c)) { - pd.error("char `0x%04x` not allowed in mangled name", c); + .error(pd.loc, "%s `%s` char `0x%04x` not allowed in mangled name", pd.kind, pd.toPrettyChars, c); break; } } @@ -1712,7 +1713,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = se; } else - e.error("must be a string"); + error(e.loc, "must be a string"); } if (agg) { @@ -1729,7 +1730,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (auto td = s.isTemplateDeclaration()) { - pd.error("cannot apply to a template declaration"); + .error(pd.loc, "%s `%s` cannot apply to a template declaration", pd.kind, pd.toPrettyChars); errorSupplemental(pd.loc, "use `template Class(Args...){ pragma(mangle, \"other_name\") class Class {} }`"); } else if (auto se = verifyMangleString((*pd.args)[0])) @@ -1737,7 +1738,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const name = (cast(const(char)[])se.peekData()).xarraydup; uint cnt = setMangleOverride(s, name); if (cnt > 1) - pd.error("can only apply to a single declaration"); + .error(pd.loc, "%s `%s` can only apply to a single declaration", pd.kind, pd.toPrettyChars); } } } @@ -1746,7 +1747,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (pd.decl) { - pd.error("is missing a terminating `;`"); + .error(pd.loc, "%s `%s` is missing a terminating `;`", pd.kind, pd.toPrettyChars); declarations(); // do them anyway, to avoid segfaults. } @@ -1759,14 +1760,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (pd.ident == Id.linkerDirective) { if (!pd.args || pd.args.length != 1) - pd.error("one string argument expected for pragma(linkerDirective)"); + .error(pd.loc, "%s `%s` one string argument expected for pragma(linkerDirective)", pd.kind, pd.toPrettyChars); else { auto se = semanticString(sc, (*pd.args)[0], "linker directive"); if (!se) return noDeclarations(); (*pd.args)[0] = se; - if (global.params.verbose) + if (global.params.v.verbose) message("linkopt %.*s", cast(int)se.len, se.peekString().ptr); } return noDeclarations(); @@ -1785,7 +1786,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else if (pd.ident == Id.lib) { if (!pd.args || pd.args.length != 1) - pd.error("string expected for library name"); + .error(pd.loc, "%s `%s` string expected for library name", pd.kind, pd.toPrettyChars); else { auto se = semanticString(sc, (*pd.args)[0], "library name"); @@ -1794,7 +1795,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor (*pd.args)[0] = se; auto name = se.peekString().xarraydup; - if (global.params.verbose) + if (global.params.v.verbose) message("library %s", name.ptr); if (global.params.moduleDeps.buffer && !global.params.moduleDeps.name) { @@ -1829,8 +1830,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor pd.args = new Expressions(); if (pd.args.length == 0 || pd.args.length > 2) { - pd.error(pd.args.length == 0 ? "- string expected for mangled name" - : "expected 1 or 2 arguments"); + .error(pd.loc, pd.args.length == 0 ? "%s `%s` - string expected for mangled name" + : "%s `%s` expected 1 or 2 arguments", pd.kind, pd.toPrettyChars); pd.args.setDim(1); (*pd.args)[0] = ErrorExp.get(); // error recovery } @@ -1839,7 +1840,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor) { if (pd.args && pd.args.length != 0) - pd.error("takes no argument"); + .error(pd.loc, "%s `%s` takes no argument", pd.kind, pd.toPrettyChars); else { immutable isCtor = pd.ident == Id.crt_constructor; @@ -1872,14 +1873,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (recurse(pd, isCtor) > 1) - pd.error("can only apply to a single declaration"); + .error(pd.loc, "%s `%s` can only apply to a single declaration", pd.kind, pd.toPrettyChars); } return declarations(); } else if (pd.ident == Id.printf || pd.ident == Id.scanf) { if (pd.args && pd.args.length != 0) - pd.error("takes no argument"); + .error(pd.loc, "%s `%s` takes no argument", pd.kind, pd.toPrettyChars); return declarations(); } else if (!global.params.ignoreUnsupportedPragmas) @@ -1888,7 +1889,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor return declarations(); } - if (!global.params.verbose) + if (!global.params.v.verbose) return declarations(); /* Print unrecognized pragmas @@ -1944,7 +1945,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; auto loc = adjustLocForMixin(str, cd.loc, global.params.mixinOut); scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); - p.transitionIn = global.params.vin; + p.transitionIn = global.params.v.vin; p.nextToken(); auto d = p.parseDeclDefs(0); @@ -1953,7 +1954,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (p.token.value != TOK.endOfFile) { - cd.error("incomplete mixin declaration `%s`", str.ptr); + .error(cd.loc, "%s `%s` incomplete mixin declaration `%s`", cd.kind, cd.toPrettyChars, str.ptr); return null; } return d; @@ -1990,7 +1991,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const sident = se.toStringz(); if (!sident.length || !Identifier.isValidIdentifier(sident)) { - ns.exp.error("expected valid identifier for C++ namespace but got `%.*s`", + error(ns.exp.loc, "expected valid identifier for C++ namespace but got `%.*s`", cast(int)sident.length, sident.ptr); return null; } @@ -2028,7 +2029,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor return; // An error happened in `identFromSE` } else - ns.exp.error("`%s`: index %llu is not a string constant, it is a `%s`", + error(ns.exp.loc, "`%s`: index %llu is not a string constant, it is a `%s`", ns.exp.toChars(), cast(ulong) d, ns.exp.type.toChars()); } } @@ -2038,8 +2039,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else if (ns.exp.isTypeExp() && ns.exp.isTypeExp().type.toBasetype().isTypeTuple()) { } - else - ns.exp.error("compile time string constant (or sequence) expected, not `%s`", + else if (!ns.exp.type.isTypeError()) + error(ns.exp.loc, "compile time string constant (or sequence) expected, not `%s`", ns.exp.toChars()); attribSemantic(ns); } @@ -2196,7 +2197,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (ed.memtype.ty == Tvoid) { - ed.error("base type must not be `void`"); + .error(ed.loc, "%s `%s` base type must not be `void`", ed.kind, ed.toPrettyChars); ed.memtype = Type.terror; } if (ed.memtype.ty == Terror) @@ -2217,7 +2218,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (ed.members.length == 0) { - ed.error("enum `%s` must have at least one member", ed.toChars()); + .error(ed.loc, "%s `%s enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars()); ed.errors = true; ed.semanticRun = PASS.semanticdone; return; @@ -2308,13 +2309,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!ie) { // C11 6.7.2.2-2 - em.error("enum member must be an integral constant expression, not `%s` of type `%s`", e.toChars(), e.type.toChars()); + .error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars()); return errorReturn(em); } if (ed.memtype && !ir.contains(getIntRange(ie))) { // C11 6.7.2.2-2 - em.error("enum member value `%s` does not fit in `%s`", e.toChars(), commonType.toChars()); + .error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars()); return errorReturn(em); } nextValue = ie.toInteger(); @@ -2331,7 +2332,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor Expression max = getProperty(commonType, null, em.loc, Id.max, 0); if (nextValue == max.toInteger()) { - em.error("initialization with `%s+1` causes overflow for type `%s`", max.toChars(), commonType.toChars()); + .error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars()); return errorReturn(em); } nextValue += 1; @@ -2391,7 +2392,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor return; if (em.semanticRun == PASS.semantic) { - em.error("circular reference to `enum` member"); + .error(em.loc, "%s `%s` circular reference to `enum` member", em.kind, em.toPrettyChars); return errorReturn(); } assert(em.ed); @@ -2605,7 +2606,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto mt = em.ed.memtype; if (!mt) mt = eprev.type; - em.error("initialization with `%s.%s+1` causes overflow for type `%s`", + .error(em.loc, "%s `%s` initialization with `%s.%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, emprev.ed.toChars(), emprev.toChars(), mt.toChars()); return errorReturn(); } @@ -2643,7 +2644,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor etest = etest.ctfeInterpret(); if (etest.toInteger()) { - em.error("has inexact value due to loss of precision"); + .error(em.loc, "%s `%s` has inexact value due to loss of precision", em.kind, em.toPrettyChars); return errorReturn(); } } @@ -2738,7 +2739,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter()) { - tempdecl.error("template sequence parameter must be the last one"); + .error(tempdecl.loc, "%s `%s` template sequence parameter must be the last one", tempdecl.kind, tempdecl.toPrettyChars); tempdecl.errors = true; } } @@ -2925,7 +2926,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else assert(0); } - tm.error("recursive mixin instantiation"); + .error(tm.loc, "%s `%s` recursive mixin instantiation", tm.kind, tm.toPrettyChars); return; Lcontinue: @@ -2982,7 +2983,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (++nest > global.recursionLimit) { global.gag = 0; // ensure error message gets printed - tm.error("recursive expansion"); + .error(tm.loc, "%s `%s` recursive expansion", tm.kind, tm.toPrettyChars); fatal(); } @@ -3010,7 +3011,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Give additional context info if error occurred during instantiation if (global.errors != errorsave) { - tm.error("error instantiating"); + .error(tm.loc, "%s `%s` error instantiating", tm.kind, tm.toPrettyChars); tm.errors = true; } @@ -3238,7 +3239,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!fd.type.isTypeError()) { - fd.error("`%s` must be a function instead of `%s`", fd.toChars(), fd.type.toChars()); + .error(fd.loc, "%s `%s` `%s` must be a function instead of `%s`", fd.kind, fd.toPrettyChars, fd.toChars(), fd.type.toChars()); fd.type = Type.terror; } fd.errors = true; @@ -3376,7 +3377,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { OutBuffer buf; MODtoBuffer(buf, tf.mod); - funcdecl.error("without `this` cannot be `%s`", buf.peekChars()); + .error(funcdecl.loc, "%s `%s` without `this` cannot be `%s`", funcdecl.kind, funcdecl.toPrettyChars, buf.peekChars()); tf.mod = 0; // remove qualifiers } @@ -3425,11 +3426,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { const idStr = funcdecl.isCrtCtor ? "crt_constructor" : "crt_destructor"; if (f.nextOf().ty != Tvoid) - funcdecl.error("must return `void` for `pragma(%s)`", idStr.ptr); + .error(funcdecl.loc, "%s `%s` must return `void` for `pragma(%s)`", funcdecl.kind, funcdecl.toPrettyChars, idStr.ptr); if (funcdecl._linkage != LINK.c && f.parameterList.length != 0) - funcdecl.error("must be `extern(C)` for `pragma(%s)` when taking parameters", idStr.ptr); + .error(funcdecl.loc, "%s `%s` must be `extern(C)` for `pragma(%s)` when taking parameters", funcdecl.kind, funcdecl.toPrettyChars, idStr.ptr); if (funcdecl.isThis()) - funcdecl.error("cannot be a non-static member function for `pragma(%s)`", idStr.ptr); + .error(funcdecl.loc, "%s `%s` cannot be a non-static member function for `pragma(%s)`", funcdecl.kind, funcdecl.toPrettyChars, idStr.ptr); } if (funcdecl.overnext && funcdecl.isCsymbol()) @@ -3443,7 +3444,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto fn = fnext.type.isTypeFunction(); if (!fn || !cFuncEquivalence(f, fn)) { - funcdecl.error("redeclaration with different type"); + .error(funcdecl.loc, "%s `%s` redeclaration with different type", funcdecl.kind, funcdecl.toPrettyChars); //printf("t1: %s\n", f.toChars()); //printf("t2: %s\n", fn.toChars()); } @@ -3451,7 +3452,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType) - funcdecl.error("storage class `auto` has no effect if return type is not inferred"); + .error(funcdecl.loc, "%s `%s` storage class `auto` has no effect if return type is not inferred", funcdecl.kind, funcdecl.toPrettyChars); if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested()) { @@ -3459,7 +3460,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor * the 'return' applies */ if (sc.scopesym && sc.scopesym.isAggregateDeclaration()) - funcdecl.error("`static` member has no `this` to which `return` can apply"); + .error(funcdecl.loc, "%s `%s` `static` member has no `this` to which `return` can apply", funcdecl.kind, funcdecl.toPrettyChars); else error(funcdecl.loc, "top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars()); } @@ -3473,20 +3474,20 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor sfunc = visibilityToChars(funcdecl.visibility.kind); else sfunc = "final"; - funcdecl.error("`%s` functions cannot be `abstract`", sfunc); + .error(funcdecl.loc, "%s `%s` `%s` functions cannot be `abstract`", funcdecl.kind, funcdecl.toPrettyChars, sfunc); } if (funcdecl.isOverride() && !funcdecl.isVirtual() && !funcdecl.isFuncLiteralDeclaration()) { Visibility.Kind kind = funcdecl.visible().kind; if ((kind == Visibility.Kind.private_ || kind == Visibility.Kind.package_) && funcdecl.isMember()) - funcdecl.error("`%s` method is not virtual and cannot override", visibilityToChars(kind)); + .error(funcdecl.loc, "%s `%s` `%s` method is not virtual and cannot override", funcdecl.kind, funcdecl.toPrettyChars, visibilityToChars(kind)); else - funcdecl.error("cannot override a non-virtual function"); + .error(funcdecl.loc, "%s `%s` cannot override a non-virtual function", funcdecl.kind, funcdecl.toPrettyChars); } if (funcdecl.isAbstract() && funcdecl.isFinalFunc()) - funcdecl.error("cannot be both `final` and `abstract`"); + .error(funcdecl.loc, "%s `%s` cannot be both `final` and `abstract`", funcdecl.kind, funcdecl.toPrettyChars); if (funcdecl.printf || funcdecl.scanf) { @@ -3497,15 +3498,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { funcdecl.storage_class |= STC.abstract_; if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete()) - funcdecl.error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", id.toChars()); + .error(funcdecl.loc, "%s `%s` constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", funcdecl.kind, funcdecl.toPrettyChars, id.toChars()); if (funcdecl.fbody && funcdecl.isVirtual()) - funcdecl.error("function body only allowed in `final` functions in interface `%s`", id.toChars()); + .error(funcdecl.loc, "%s `%s` function body only allowed in `final` functions in interface `%s`", funcdecl.kind, funcdecl.toPrettyChars, id.toChars()); } if (UnionDeclaration ud = parent.isUnionDeclaration()) { if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration()) - funcdecl.error("destructors, postblits and invariants are not allowed in union `%s`", ud.toChars()); + .error(funcdecl.loc, "%s `%s` destructors, postblits and invariants are not allowed in union `%s`", funcdecl.kind, funcdecl.toPrettyChars, ud.toChars()); } if (StructDeclaration sd = parent.isStructDeclaration()) @@ -3563,7 +3564,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor /* If same name function exists in base class but 'this' is auto return, * cannot find index of base class's vtbl[] to override. */ - funcdecl.error("return type inference is not supported if may override base class function"); + .error(funcdecl.loc, "%s `%s` return type inference is not supported if may override base class function", funcdecl.kind, funcdecl.toPrettyChars); } /* Find index of existing function in base class's vtbl[] to override @@ -3591,7 +3592,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { f2 = f2.overloadExactMatch(funcdecl.type); if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_) - funcdecl.error("cannot override `final` function `%s`", f2.toPrettyChars()); + .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, f2.toPrettyChars()); } } } @@ -3681,7 +3682,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor /* the derived class cd doesn't have its vtbl[] allocated yet. * https://issues.dlang.org/show_bug.cgi?id=21008 */ - funcdecl.error("circular reference to class `%s`", cd.toChars()); + .error(funcdecl.loc, "%s `%s` circular reference to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars()); funcdecl.errors = true; return; } @@ -3697,7 +3698,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto vtf = getFunctionType(fdv); if (vtf.trust > TRUST.system && f.trust == TRUST.system) - funcdecl.error("cannot override `@safe` method `%s` with a `@system` attribute", + .error(funcdecl.loc, "%s `%s` cannot override `@safe` method `%s` with a `@system` attribute", funcdecl.kind, funcdecl.toPrettyChars, fdv.toPrettyChars); if (fdc.toParent() == parent) @@ -3718,7 +3719,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // This function overrides fdv if (fdv.isFinalFunc()) - funcdecl.error("cannot override `final` function `%s`", fdv.toPrettyChars()); + .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, fdv.toPrettyChars()); if (!funcdecl.isOverride()) { @@ -3744,7 +3745,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor bool fdcmixin = fdc.parent.isClassDeclaration() !is null; if (thismixin == fdcmixin) { - funcdecl.error("multiple overrides of same function"); + .error(funcdecl.loc, "%s `%s` multiple overrides of same function", funcdecl.kind, funcdecl.toPrettyChars); } /* * https://issues.dlang.org/show_bug.cgi?id=711 @@ -3878,7 +3879,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null)) { - funcdecl.error("incompatible covariant types `%s` and `%s`", funcdecl.tintro.toChars(), ti.toChars()); + .error(funcdecl.loc, "%s `%s` incompatible covariant types `%s` and `%s`", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.tintro.toChars(), ti.toChars()); } } else @@ -3951,7 +3952,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } else - funcdecl.error("does not override any function"); + .error(funcdecl.loc, "%s `%s` does not override any function", funcdecl.kind, funcdecl.toPrettyChars); } L2: @@ -3973,7 +3974,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { f2 = f2.overloadExactMatch(funcdecl.type); if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_) - funcdecl.error("cannot override `final` function `%s.%s`", b.sym.toChars(), f2.toPrettyChars()); + .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s.%s`", funcdecl.kind, funcdecl.toPrettyChars, b.sym.toChars(), f2.toPrettyChars()); } } } @@ -3994,7 +3995,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (funcdecl.isOverride() && !parent.isTemplateInstance()) - funcdecl.error("`override` only applies to class member functions"); + .error(funcdecl.loc, "%s `%s` `override` only applies to class member functions", funcdecl.kind, funcdecl.toPrettyChars); if (auto ti = parent.isTemplateInstance) { @@ -4009,7 +4010,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor Ldone: if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody()) - funcdecl.error("`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract"); + .error(funcdecl.loc, "%s `%s` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract", funcdecl.kind, funcdecl.toPrettyChars); /* Do not allow template instances to add virtual functions * to a class. @@ -4031,7 +4032,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor ClassDeclaration cd = ti.tempdecl.isClassMember(); if (cd) { - funcdecl.error("cannot use template to add virtual function to class `%s`", cd.toChars()); + .error(funcdecl.loc, "%s `%s` cannot use template to add virtual function to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars()); } } } @@ -4053,7 +4054,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor funcdecl._scope.setNoFree(); __gshared bool printedMain = false; // semantic might run more than once - if (global.params.verbose && !printedMain) + if (global.params.v.verbose && !printedMain) { const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null; Module mod = sc._module; @@ -4171,8 +4172,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (ctd.fbody || !(ctd.storage_class & STC.disable)) { - ctd.error("default constructor for structs only allowed " ~ - "with `@disable`, no body, and no parameters"); + .error(ctd.loc, "%s `%s` default constructor for structs only allowed " ~ + "with `@disable`, no body, and no parameters", ctd.kind, ctd.toPrettyChars); ctd.storage_class |= STC.disable; ctd.fbody = null; } @@ -4185,13 +4186,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (ctd.storage_class & STC.disable) { - ctd.error("is marked `@disable`, so it cannot have default "~ - "arguments for all parameters."); + .error(ctd.loc, "%s `%s` is marked `@disable`, so it cannot have default "~ + "arguments for all parameters.", ctd.kind, ctd.toPrettyChars); errorSupplemental(ctd.loc, "Use `@disable this();` if you want to disable default initialization."); } else - ctd.error("all parameters have default arguments, "~ - "but structs cannot have default constructors."); + .error(ctd.loc, "%s `%s` all parameters have default arguments, "~ + "but structs cannot have default constructors.", ctd.kind, ctd.toPrettyChars); } else if ((dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg))) { @@ -4369,7 +4370,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = doAtomicOp("+=", v.ident, IntegerExp.literal!(1)); if (e is null) { - scd.error("shared static constructor within a template require `core.atomic : atomicOp` to be present"); + .error(scd.loc, "%s `%s` shared static constructor within a template require `core.atomic : atomicOp` to be present", scd.kind, scd.toPrettyChars); return; } } @@ -4465,7 +4466,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = doAtomicOp("-=", v.ident, IntegerExp.literal!(1)); if (e is null) { - sdd.error("shared static destructo within a template require `core.atomic : atomicOp` to be present"); + .error(sdd.loc, "%s `%s` shared static destructo within a template require `core.atomic : atomicOp` to be present", sdd.kind, sdd.toPrettyChars); return; } } @@ -4666,7 +4667,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor sd.storage_class |= sc.stc; if (sd.storage_class & STC.abstract_) - sd.error("structs, unions cannot be `abstract`"); + .error(sd.loc, "%s `%s` structs, unions cannot be `abstract`", sd.kind, sd.toPrettyChars); sd.userAttribDecl = sc.userAttribDecl; @@ -4712,7 +4713,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (sd.type.ty != Terror) { - sd.error(sd.loc, "circular or forward reference"); + .error(sd.loc, "%s `%s` circular or forward reference", sd.kind, sd.toPrettyChars); sd.errors = true; sd.type = Type.terror; } @@ -4786,7 +4787,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (fcall && fcall.isStatic()) { - sd.error(fcall.loc, "`static opCall` is hidden by constructors and can never be called"); + .error(fcall.loc, "%s `%s` `static opCall` is hidden by constructors and can never be called", sd.kind, sd.toPrettyChars); errorSupplemental(fcall.loc, "Please use a factory method instead, or replace all constructors with `static opCall`."); } } @@ -4810,7 +4811,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars()); } // https://issues.dlang.org/show_bug.cgi?id=19024 - sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars()); + .error(sd.loc, "%s `%s` already exists at %s. Perhaps in another function with the same name?", sd.kind, sd.toPrettyChars, sym.loc.toChars()); } } @@ -4901,7 +4902,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor cldec.storage_class |= sc.stc; if (cldec.storage_class & STC.auto_) - cldec.error("storage class `auto` is invalid when declaring a class, did you mean to use `scope`?"); + .error(cldec.loc, "%s `%s` storage class `auto` is invalid when declaring a class, did you mean to use `scope`?", cldec.kind, cldec.toPrettyChars); if (cldec.storage_class & STC.scope_) cldec.stack = true; if (cldec.storage_class & STC.abstract_) @@ -4998,7 +4999,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!tc) { if (b.type != Type.terror) - cldec.error("base type must be `class` or `interface`, not `%s`", b.type.toChars()); + .error(cldec.loc, "%s `%s` base type must be `class` or `interface`, not `%s`", cldec.kind, cldec.toPrettyChars, b.type.toChars()); cldec.baseclasses.remove(0); goto L7; } @@ -5018,7 +5019,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (cdb == cldec) { - cldec.error("circular inheritance"); + .error(cldec.loc, "%s `%s` circular inheritance", cldec.kind, cldec.toPrettyChars); cldec.baseclasses.remove(0); goto L7; } @@ -5062,14 +5063,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (multiClassError == 0) { - error(cldec.loc,"`%s`: base class must be specified first, " ~ + .error(cldec.loc,"`%s`: base class must be specified first, " ~ "before any interfaces.", cldec.toPrettyChars()); multiClassError += 1; } else if (multiClassError >= 1) { if(multiClassError == 1) - error(cldec.loc,"`%s`: multiple class inheritance is not supported." ~ + .error(cldec.loc, "`%s`: multiple class inheritance is not supported." ~ " Use multiple interface inheritance and/or composition.", cldec.toPrettyChars()); multiClassError += 1; @@ -5097,7 +5098,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor BaseClass* b2 = (*cldec.baseclasses)[j]; if (b2.sym == tc.sym) { - cldec.error("inherits from duplicate interface `%s`", b2.sym.toChars()); + .error(cldec.loc, "%s `%s` inherits from duplicate interface `%s`", cldec.kind, cldec.toPrettyChars, b2.sym.toChars()); cldec.baseclasses.remove(i); continue BCLoop; } @@ -5141,7 +5142,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { void badObjectDotD() { - cldec.error("missing or corrupt object.d"); + .error(cldec.loc, "%s `%s` missing or corrupt object.d", cldec.kind, cldec.toPrettyChars); fatal(); } @@ -5165,7 +5166,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (cldec.baseClass) { if (cldec.baseClass.storage_class & STC.final_) - cldec.error("cannot inherit from class `%s` because it is `final`", cldec.baseClass.toChars()); + .error(cldec.loc, "%s `%s` cannot inherit from class `%s` because it is `final`", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toChars()); // Inherit properties from base class if (cldec.baseClass.isCOMclass()) @@ -5173,7 +5174,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (cldec.baseClass.isCPPclass()) cldec.classKind = ClassKind.cpp; if (cldec.classKind != cldec.baseClass.classKind) - cldec.error("with %s linkage cannot inherit from class `%s` with %s linkage", + .error(cldec.loc, "%s `%s` with %s linkage cannot inherit from class `%s` with %s linkage", cldec.kind, cldec.toPrettyChars, cldec.classKind.toChars(), cldec.baseClass.toChars(), cldec.baseClass.classKind.toChars()); if (cldec.baseClass.stack) @@ -5191,7 +5192,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor cldec.com = true; if (cldec.classKind == ClassKind.cpp && !b.sym.isCPPinterface()) { - error(cldec.loc, "C++ class `%s` cannot implement D interface `%s`", + .error(cldec.loc, "C++ class `%s` cannot implement D interface `%s`", cldec.toPrettyChars(), b.sym.toPrettyChars()); } } @@ -5253,7 +5254,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.length == 0) { - cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars()); + .error(cldec.loc, "%s `%s` C++ base class `%s` needs at least one virtual function", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toChars()); } // Copy vtbl[] from base class @@ -5279,7 +5280,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { // Use the base class's 'this' member if (cldec.storage_class & STC.static_) - cldec.error("static class cannot inherit from nested class `%s`", cldec.baseClass.toChars()); + .error(cldec.loc, "%s `%s` static class cannot inherit from nested class `%s`", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toChars()); if (cldec.toParentLocal() != cldec.baseClass.toParentLocal() && (!cldec.toParentLocal() || !cldec.baseClass.toParentLocal().getType() || @@ -5287,14 +5288,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (cldec.toParentLocal()) { - cldec.error("is nested within `%s`, but super class `%s` is nested within `%s`", + .error(cldec.loc, "%s `%s` is nested within `%s`, but super class `%s` is nested within `%s`", cldec.kind, cldec.toPrettyChars, cldec.toParentLocal().toChars(), cldec.baseClass.toChars(), cldec.baseClass.toParentLocal().toChars()); } else { - cldec.error("is not nested, but super class `%s` is nested within `%s`", + .error(cldec.loc, "%s `%s` is not nested, but super class `%s` is nested within `%s`", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toChars(), cldec.baseClass.toParentLocal().toChars()); } @@ -5308,14 +5309,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (cldec.toParent2() && cldec.toParent2() != cldec.toParentLocal()) { - cldec.error("needs the frame pointer of `%s`, but super class `%s` needs the frame pointer of `%s`", + .error(cldec.loc, "%s `%s` needs the frame pointer of `%s`, but super class `%s` needs the frame pointer of `%s`", cldec.kind, cldec.toPrettyChars, cldec.toParent2().toChars(), cldec.baseClass.toChars(), cldec.baseClass.toParent2().toChars()); } else { - cldec.error("doesn't need a frame pointer, but super class `%s` needs the frame pointer of `%s`", + .error(cldec.loc, "%s `%s` doesn't need a frame pointer, but super class `%s` needs the frame pointer of `%s`", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toChars(), cldec.baseClass.toParent2().toChars()); } @@ -5410,7 +5411,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else { - cldec.error("cannot implicitly generate a default constructor when base class `%s` is missing a default constructor", + .error(cldec.loc, "%s `%s` cannot implicitly generate a default constructor when base class `%s` is missing a default constructor", cldec.kind, cldec.toPrettyChars, cldec.baseClass.toPrettyChars()); } } @@ -5434,7 +5435,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (auto f = hasIdentityOpAssign(cldec, sc2)) { if (!(f.storage_class & STC.disable)) - cldec.error(f.loc, "identity assignment operator overload is illegal"); + .error(f.loc, "%s `%s` identity assignment operator overload is illegal", cldec.kind, cldec.toPrettyChars); } cldec.inv = buildInv(cldec, sc2); @@ -5454,7 +5455,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor cldec.isAbstract(); // recalculate if (cldec.isabstract != isabstractsave) { - cldec.error("cannot infer `abstract` attribute due to circular dependencies"); + .error(cldec.loc, "%s `%s` cannot infer `abstract` attribute due to circular dependencies", cldec.kind, cldec.toPrettyChars); } } @@ -5467,7 +5468,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("this = %p %s\n", cldec, cldec.toPrettyChars()); printf("type = %d sym = %p, %s\n", cldec.type.ty, cd, cd.toPrettyChars()); } - cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars()); + .error(cldec.loc, "%s `%s` already exists at %s. Perhaps in another function with the same name?", cldec.kind, cldec.toPrettyChars, cd.loc.toChars()); } if (global.errors != errors || (cldec.baseClass && cldec.baseClass.errors)) @@ -5488,7 +5489,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!vd.isThisDeclaration() && vd.visible() >= Visibility(Visibility.Kind.public_)) { - vd.error("Field members of a `synchronized` class cannot be `%s`", + .error(vd.loc, "%s `%s` Field members of a `synchronized` class cannot be `%s`", vd.kind, vd.toPrettyChars, visibilityToChars(vd.visible().kind)); } } @@ -5650,7 +5651,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!tc || !tc.sym.isInterfaceDeclaration()) { if (b.type != Type.terror) - idec.error("base type must be `interface`, not `%s`", b.type.toChars()); + .error(idec.loc, "%s `%s` base type must be `interface`, not `%s`", idec.kind, idec.toPrettyChars, b.type.toChars()); idec.baseclasses.remove(i); continue; } @@ -5661,14 +5662,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor BaseClass* b2 = (*idec.baseclasses)[j]; if (b2.sym == tc.sym) { - idec.error("inherits from duplicate interface `%s`", b2.sym.toChars()); + .error(idec.loc, "%s `%s` inherits from duplicate interface `%s`", idec.kind, idec.toPrettyChars, b2.sym.toChars()); idec.baseclasses.remove(i); continue BCLoop; } } if (tc.sym == idec || idec.isBaseOf2(tc.sym)) { - idec.error("circular inheritance of interface"); + .error(idec.loc, "%s `%s` circular inheritance of interface", idec.kind, idec.toPrettyChars); idec.baseclasses.remove(i); continue; } @@ -5931,7 +5932,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList auto ungag = Ungag(global.gag); if (!tempinst.gagged) global.gag = 0; - tempinst.error(tempinst.loc, "recursive template expansion"); + .error(tempinst.loc, "%s `%s` recursive template expansion", tempinst.kind, tempinst.toPrettyChars); if (tempinst.gagged) tempinst.semanticRun = PASS.initial; else @@ -5989,7 +5990,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList // If tempdecl is a mixin, disallow it if (tempdecl.ismixin) { - tempinst.error("mixin templates are not regular templates"); + .error(tempinst.loc, "%s `%s` mixin templates are not regular templates", tempinst.kind, tempinst.toPrettyChars); goto Lerror; } @@ -6210,7 +6211,8 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList Scope* _scope = tempdecl._scope; if (tempdecl.semanticRun == PASS.initial) { - tempinst.error("template instantiation `%s` forward references template declaration `%s`", tempinst.toChars(), tempdecl.toChars()); + .error(tempinst.loc, "%s `%s` template instantiation `%s` forward references template declaration `%s`", + tempinst.kind, tempinst.toPrettyChars, tempinst.toChars(), tempdecl.toChars()); return; } @@ -6454,7 +6456,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList if (++nest > global.recursionLimit) { global.gag = 0; // ensure error message gets printed - tempinst.error("recursive expansion"); + .error(tempinst.loc, "%s `%s` recursive expansion", tempinst.kind, tempinst.toPrettyChars); fatal(); } } @@ -6502,7 +6504,7 @@ Laftersemantic: if (!tempinst.errors) { if (!tempdecl.literal) - tempinst.error(tempinst.loc, "error instantiating"); + .error(tempinst.loc, "%s `%s` error instantiating", tempinst.kind, tempinst.toPrettyChars); if (tempinst.tinst) tempinst.tinst.printInstantiationTrace(); } @@ -6712,7 +6714,7 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc) return errorRet(); if (s == ds) { - ds.error("cannot resolve"); + .error(ds.loc, "%s `%s` cannot resolve", ds.kind, ds.toPrettyChars); return errorRet(); } if (!s || !s.isEnumMember()) @@ -6743,7 +6745,7 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc) if (!s) { if (e.op != EXP.error) - ds.error("cannot alias an expression `%s`", e.toChars()); + .error(ds.loc, "%s `%s` cannot alias an expression `%s`", ds.kind, ds.toPrettyChars, e.toChars()); return errorRet(); } } @@ -6799,7 +6801,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc) Dsymbol as = sc.search(ds.loc, ds.ident, &scopesym); if (!as) { - ds.error("undefined identifier `%s`", ds.ident.toChars()); + .error(ds.loc, "%s `%s` undefined identifier `%s`", ds.kind, ds.toPrettyChars, ds.ident.toChars()); return null; } if (as.errors) @@ -6808,13 +6810,13 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc) auto ad = as.isAliasDeclaration(); if (!ad) { - ds.error("identifier `%s` must be an alias declaration", as.toChars()); + .error(ds.loc, "%s `%s` identifier `%s` must be an alias declaration", ds.kind, ds.toPrettyChars, as.toChars()); return null; } if (ad.overnext) { - ds.error("cannot reassign overloaded alias"); + error(ds.loc, "%s `%s` cannot reassign overloaded alias", ds.kind, ds.toPrettyChars); return null; } @@ -6824,12 +6826,12 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc) { if (!adParent) adParent = ds.toParent(); - error(ds.loc, "`%s` must have same parent `%s` as alias `%s`", ds.ident.toChars(), adParent.toChars(), ad.toChars()); + .error(ds.loc, "`%s` must have same parent `%s` as alias `%s`", ds.ident.toChars(), adParent.toChars(), ad.toChars()); return null; } if (!adParent.isTemplateInstance()) { - ds.error("must be a member of a template"); + .error(ds.loc, "%s `%s` must be a member of a template", ds.kind, ds.toPrettyChars); return null; } @@ -6910,7 +6912,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc) return errorRet(); if (s == aliassym) { - ds.error("cannot resolve"); + .error(ds.loc, "%s `%s` cannot resolve", ds.kind, ds.toPrettyChars); return errorRet(); } @@ -6942,7 +6944,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc) if (!s) { if (e.op != EXP.error) - ds.error("cannot alias an expression `%s`", e.toChars()); + .error(ds.loc, "%s `%s` cannot alias an expression `%s`", ds.kind, ds.toPrettyChars, e.toChars()); return errorRet(); } } @@ -7175,7 +7177,7 @@ bool determineFields(AggregateDeclaration ad) if (ad == tvs.sym) { const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? "static array of " : ""; - ad.error("cannot have field `%s` with %ssame struct type", v.toChars(), psz); + .error(ad.loc, "%s `%s` cannot have field `%s` with %ssame struct type", ad.kind, ad.toPrettyChars, v.toChars(), psz); ad.type = Type.terror; ad.errors = true; return 1; diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 67ca2ef66a4b..23d1140fe381 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -872,7 +872,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol if (!ti.symtab) ti.symtab = new DsymbolTable(); if (!scx.insert(v)) - error("parameter `%s.%s` is already defined", toChars(), v.toChars()); + .error(loc, "%s `%s` parameter `%s.%s` is already defined", kind, toPrettyChars, toChars(), v.toChars()); else v.parent = fd; } @@ -916,7 +916,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol import dmd.staticcond; // there will be a full tree view in verbose mode, and more compact list in the usual - const full = global.params.verbose; + const full = global.params.v.verbose; uint count; const msg = visualizeStaticCondition(constraint, lastConstraint, lastConstraintNegs[], full, count); scope (exit) @@ -1769,7 +1769,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol if (m2 < matchTiargs) matchTiargs = m2; // pick worst match if (!(*dedtypes)[i].equals(oded)) - error("specialization not allowed for deduced parameter `%s`", tparam.ident.toChars()); + .error(loc, "%s `%s` specialization not allowed for deduced parameter `%s`", kind, toPrettyChars, kind, toPrettyChars, tparam.ident.toChars()); } else { @@ -2147,7 +2147,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol if (m2 < matchTiargs) matchTiargs = m2; // pick worst match if (!(*dedtypes)[i].equals(oded)) - error("specialization not allowed for deduced parameter `%s`", tparam.ident.toChars()); + .error(loc, "%s `%s` specialization not allowed for deduced parameter `%s`", kind, toPrettyChars, tparam.ident.toChars()); } else { @@ -2194,7 +2194,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol if (m2 < matchTiargs) matchTiargs = m2; // pick worst match if (!(*dedtypes)[i].equals(oded)) - error("specialization not allowed for deduced parameter `%s`", tparam.ident.toChars()); + .error(loc, "%s `%s` specialization not allowed for deduced parameter `%s`", kind, toPrettyChars, tparam.ident.toChars()); } } oded = declareParameter(paramscope, tparam, oded); @@ -2346,7 +2346,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } if (!sc.insert(d)) - error("declaration `%s` is already defined", tp.ident.toChars()); + .error(loc, "%s `%s` declaration `%s` is already defined", kind, toPrettyChars, tp.ident.toChars()); d.dsymbolSemantic(sc); /* So the caller's o gets updated with the result of semantic() being run on o */ @@ -5629,7 +5629,8 @@ extern (C++) final class TemplateValueParameter : TemplateParameter // i.e: `template T(int arg = T)` // Raise error now before calling resolveProperties otherwise we'll // start looping on the expansion of the template instance. - sc.tinst.tempdecl.error("recursive template expansion"); + auto td = sc.tinst.tempdecl; + .error(td.loc, "%s `%s` recursive template expansion", td.kind, td.toPrettyChars); return ErrorExp.get(); } } @@ -5993,7 +5994,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol } if (!inst) { - error("cannot resolve forward reference"); + .error(loc, "%s `%s` cannot resolve forward reference", kind, toPrettyChars); errors = true; return this; } @@ -6039,17 +6040,17 @@ extern (C++) class TemplateInstance : ScopeDsymbol * Given an error instantiating the TemplateInstance, * give the nested TemplateInstance instantiations that got * us here. Those are a list threaded into the nested scopes. + * Params: + * cl = classification of this trace as printing either errors or deprecations + * max_shown = maximum number of trace elements printed (controlled with -v/-verror-limit) */ - extern(D) final void printInstantiationTrace(Classification cl = Classification.error) + extern(D) final void printInstantiationTrace(Classification cl = Classification.error, + const(uint) max_shown = global.params.v.errorSupplementCount()) { if (global.gag) return; // Print full trace for verbose mode, otherwise only short traces - const(uint) max_shown = !global.params.verbose ? - (global.params.errorSupplementLimit ? global.params.errorSupplementLimit : uint.max) - : uint.max; - const(char)* format = "instantiated from here: `%s`"; // This returns a function pointer @@ -6456,9 +6457,9 @@ extern (C++) class TemplateInstance : ScopeDsymbol { s = sc.search_correct(id); if (s) - error("template `%s` is not defined, did you mean %s?", id.toChars(), s.toChars()); + .error(loc, "%s `%s` template `%s` is not defined, did you mean %s?", kind, toPrettyChars, id.toChars(), s.toChars()); else - error("template `%s` is not defined", id.toChars()); + .error(loc, "%s `%s` template `%s` is not defined", kind, toPrettyChars, id.toChars()); return false; } static if (LOG) @@ -6526,7 +6527,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol } if (td.semanticRun == PASS.initial) { - error("`%s` forward references template declaration `%s`", + .error(loc, "%s `%s` `%s` forward references template declaration `%s`", kind, toPrettyChars, toChars(), td.toChars()); return 1; } @@ -6581,7 +6582,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol } if (!s) { - error("template `%s` is not defined", id.toChars()); + .error(loc, "%s `%s` template `%s` is not defined", kind, toPrettyChars, id.toChars()); return false; } } @@ -6652,7 +6653,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol } else { - error("`%s` is not a template declaration, it is a %s", id.toChars(), s.kind()); + .error(loc, "%s `%s` `%s` is not a template declaration, it is a %s", kind, toPrettyChars, id.toChars(), s.kind()); return false; } } @@ -6970,7 +6971,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol tdtypes.setDim(tempdecl.parameters.length); if (!tempdecl.matchWithInstance(sc, this, &tdtypes, argumentList, 2)) { - error("incompatible arguments for template instantiation"); + .error(loc, "%s `%s` incompatible arguments for template instantiation", kind, toPrettyChars); return false; } // TODO: Normalizing tiargs for https://issues.dlang.org/show_bug.cgi?id=7469 is necessary? @@ -7130,13 +7131,13 @@ extern (C++) class TemplateInstance : ScopeDsymbol const cmsg = tdecl.getConstraintEvalError(tip); if (cmsg) { - error("%s `%s`\n%s", msg, tmsg, cmsg); + .error(loc, "%s `%s` %s `%s`\n%s", kind, toPrettyChars, msg, tmsg, cmsg); if (tip) .tip(tip); } else { - error("%s `%s`", msg, tmsg); + .error(loc, "%s `%s` %s `%s`", kind, toPrettyChars, msg, tmsg); if (tdecl.parameters.length == tiargs.length) { @@ -7290,7 +7291,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol } if (td.semanticRun == PASS.initial) { - error("`%s` forward references template declaration `%s`", toChars(), td.toChars()); + .error(loc, "%s `%s` `%s` forward references template declaration `%s`", kind, toPrettyChars, toChars(), td.toChars()); return 1; } } @@ -7370,7 +7371,8 @@ extern (C++) class TemplateInstance : ScopeDsymbol // Emulate Expression.toMangleBuffer call that had exist in TemplateInstance.genIdent. if (ea.op != EXP.int64 && ea.op != EXP.float64 && ea.op != EXP.complex80 && ea.op != EXP.null_ && ea.op != EXP.string_ && ea.op != EXP.arrayLiteral && ea.op != EXP.assocArrayLiteral && ea.op != EXP.structLiteral) { - ea.error("expression `%s` is not a valid template value argument", ea.toChars()); + if (!ea.type.isTypeError()) + .error(ea.loc, "%s `%s` expression `%s` is not a valid template value argument", kind, toPrettyChars, ea.toChars()); errors = true; } } @@ -7425,7 +7427,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol goto L1; } } - error("`%s` is nested in both `%s` and `%s`", toChars(), enclosing.toChars(), dparent.toChars()); + .error(loc, "%s `%s` `%s` is nested in both `%s` and `%s`", kind, toPrettyChars, toChars(), enclosing.toChars(), dparent.toChars()); errors = true; } L1: @@ -7611,7 +7613,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol if (++nest > global.recursionLimit) { global.gag = 0; // ensure error message gets printed - error("recursive expansion exceeded allowed nesting limit"); + .error(loc, "%s `%s` recursive expansion exceeded allowed nesting limit", kind, toPrettyChars); fatal(); } @@ -7628,7 +7630,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol if (++nest > global.recursionLimit) { global.gag = 0; // ensure error message gets printed - error("recursive expansion exceeded allowed nesting limit"); + .error(loc, "%s `%s` recursive expansion exceeded allowed nesting limit", kind, toPrettyChars); fatal(); } @@ -7838,7 +7840,7 @@ extern (C++) final class TemplateMixin : TemplateInstance tqual.resolve(loc, sc, e, t, s); if (!s) { - error("is not defined"); + .error(loc, "%s `%s` is not defined", kind, toPrettyChars); return false; } s = s.toAlias(); @@ -7866,7 +7868,7 @@ extern (C++) final class TemplateMixin : TemplateInstance } if (!tempdecl) { - error("- `%s` is a %s, not a template", s.toChars(), s.kind()); + .error(loc, "%s `%s` - `%s` is a %s, not a template", kind, toPrettyChars, s.toChars(), s.kind()); return false; } } @@ -8270,6 +8272,7 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ */ if (tap.specType) { + tap.specType = typeSemantic(tap.specType, tap.loc, sc); Declaration d = (cast(Dsymbol)sa).isDeclaration(); if (!d) return matchArgNoMatch(); @@ -8453,12 +8456,12 @@ struct TemplateStats { if (ts.allInstances is null) ts.allInstances = new TemplateInstances(); - if (global.params.vtemplatesListInstances) + if (global.params.v.templatesListInstances) ts.allInstances.push(cast() ti); } // message(ti.loc, "incInstance %p %p", td, ti); - if (!global.params.vtemplates) + if (!global.params.v.templates) return; if (!td) return; @@ -8482,7 +8485,7 @@ struct TemplateStats const TemplateInstance ti) { // message(ti.loc, "incUnique %p %p", td, ti); - if (!global.params.vtemplates) + if (!global.params.v.templates) return; if (!td) return; @@ -8511,7 +8514,7 @@ extern (C++) void printTemplateStats() } } - if (!global.params.vtemplates) + if (!global.params.v.templates) return; Array!(TemplateDeclarationStats) sortedStats; @@ -8525,7 +8528,7 @@ extern (C++) void printTemplateStats() foreach (const ref ss; sortedStats[]) { - if (global.params.vtemplatesListInstances && + if (global.params.v.templatesListInstances && ss.ts.allInstances) { message(ss.td.loc, diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index d5f658a8a424..f906ee127892 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -23,6 +23,7 @@ import dmd.dsymbol; import dmd.errors; import dmd.globals; import dmd.hdrgen; +import dmd.id; import dmd.identifier; import dmd.location; import dmd.root.filename; @@ -1046,6 +1047,10 @@ public: { debug (Debug_DtoH) mixin(traceVisit!ad); + // Declared in object.d but already included in `#include`s + if (ad.ident == Id._size_t || ad.ident == Id._ptrdiff_t) + return; + if (!shouldEmitAndMarkVisited(ad)) return; @@ -3211,6 +3216,21 @@ const(char*) keywordClass(const Identifier ident) if (global.params.cplusplus >= CppStdRevision.cpp20) return "keyword in C++20"; return null; + case "restrict": + case "_Alignas": + case "_Alignof": + case "_Atomic": + case "_Bool": + //case "_Complex": // handled above in C++ + case "_Generic": + case "_Imaginary": + case "_Noreturn": + case "_Static_assert": + case "_Thread_local": + case "_assert": + case "_import": + //case "__...": handled in default case below + return "Keyword in C"; default: // Identifiers starting with __ are reserved diff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d index 0945b5424b58..aa22532061ef 100644 --- a/gcc/d/dmd/dversion.d +++ b/gcc/d/dmd/dversion.d @@ -20,6 +20,7 @@ import dmd.dmodule; import dmd.dscope; import dmd.dsymbol; import dmd.dsymbolsem; +import dmd.errors; import dmd.globals; import dmd.identifier; import dmd.location; @@ -77,14 +78,14 @@ extern (C++) final class DebugSymbol : Dsymbol { if (!m) { - error("declaration must be at module level"); + .error(loc, "%s `%s` declaration must be at module level", kind, toPrettyChars); errors = true; } else { if (findCondition(m.debugidsNot, ident)) { - error("defined after use"); + .error(loc, "%s `%s` defined after use", kind, toPrettyChars); errors = true; } if (!m.debugids) @@ -96,7 +97,7 @@ extern (C++) final class DebugSymbol : Dsymbol { if (!m) { - error("level declaration must be at module level"); + .error(loc, "%s `%s` level declaration must be at module level", kind, toPrettyChars); errors = true; } else @@ -172,14 +173,14 @@ extern (C++) final class VersionSymbol : Dsymbol VersionCondition.checkReserved(loc, ident.toString()); if (!m) { - error("declaration must be at module level"); + .error(loc, "%s `%s` declaration must be at module level", kind, toPrettyChars); errors = true; } else { if (findCondition(m.versionidsNot, ident)) { - error("defined after use"); + .error(loc, "%s `%s` defined after use", kind, toPrettyChars); errors = true; } if (!m.versionids) @@ -191,7 +192,7 @@ extern (C++) final class VersionSymbol : Dsymbol { if (!m) { - error("level declaration must be at module level"); + .error(loc, "%s `%s` level declaration must be at module level", kind, toPrettyChars); errors = true; } else diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 99f65879046f..720523174b77 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -238,17 +238,6 @@ bool isNeedThisScope(Scope* sc, Declaration d) return true; } -/****************************** - * check e is exp.opDispatch!(tiargs) or not - * It's used to switch to UFCS the semantic analysis path - */ -bool isDotOpDispatch(Expression e) -{ - if (auto dtie = e.isDotTemplateInstanceExp()) - return dtie.ti.name == Id.opDispatch; - return false; -} - /**************************************** * Expand tuples in-place. * @@ -379,41 +368,6 @@ TupleDeclaration isAliasThisTuple(Expression e) } } -int expandAliasThisTuples(Expressions* exps, size_t starti = 0) -{ - if (!exps || exps.length == 0) - return -1; - - for (size_t u = starti; u < exps.length; u++) - { - Expression exp = (*exps)[u]; - if (TupleDeclaration td = exp.isAliasThisTuple) - { - exps.remove(u); - size_t i; - td.foreachVar((s) - { - auto d = s.isDeclaration(); - auto e = new DotVarExp(exp.loc, exp, d); - assert(d.type); - e.type = d.type; - exps.insert(u + i, e); - ++i; - }); - version (none) - { - printf("expansion ->\n"); - foreach (e; exps) - { - printf("\texps[%d] e = %s %s\n", i, EXPtoString(e.op), e.toChars()); - } - } - return cast(int)u; - } - } - return -1; -} - /**************************************** * If `s` is a function template, i.e. the only member of a template * and that member is a function, return that template. @@ -602,7 +556,7 @@ extern (C++) struct UnionExp private: // Ensure that the union is suitably aligned. - align(8) union __AnonStruct__u + align(8) union _AnonStruct_u { char[__traits(classInstanceSize, Expression)] exp; char[__traits(classInstanceSize, IntegerExp)] integerexp; @@ -623,23 +577,7 @@ private: char[__traits(classInstanceSize, VectorExp)] vectorexp; } - __AnonStruct__u u; -} - -/******************************** - * Test to see if two reals are the same. - * Regard NaN's as equivalent. - * Regard +0 and -0 as different. - * Params: - * x1 = first operand - * x2 = second operand - * Returns: - * true if x1 is x2 - * else false - */ -bool RealIdentical(real_t x1, real_t x2) @safe -{ - return (CTFloat.isNaN(x1) && CTFloat.isNaN(x2)) || CTFloat.isIdentical(x1, x2); + _AnonStruct_u u; } /************************ TypeDotIdExp ************************************/ @@ -818,99 +756,6 @@ extern (C++) abstract class Expression : ASTNode return buf.extractChars(); } - static if (__VERSION__ < 2092) - { - final void error(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.error); - va_end(ap); - } - } - - final void errorSupplemental(const(char)* format, ...) - { - if (type == Type.terror) - return; - - va_list ap; - va_start(ap, format); - .verrorReportSupplemental(loc, format, ap, ErrorKind.error); - va_end(ap); - } - - final void warning(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.warning); - va_end(ap); - } - } - - final void deprecation(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.deprecation); - va_end(ap); - } - } - } - else - { - pragma(printf) final void error(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.error); - va_end(ap); - } - } - - pragma(printf) final void errorSupplemental(const(char)* format, ...) - { - if (type == Type.terror) - return; - - va_list ap; - va_start(ap, format); - .verrorReportSupplemental(loc, format, ap, ErrorKind.error); - va_end(ap); - } - - pragma(printf) final void warning(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.warning); - va_end(ap); - } - } - - pragma(printf) final void deprecation(const(char)* format, ...) const - { - if (type != Type.terror) - { - va_list ap; - va_start(ap, format); - .verrorReport(loc, format, ap, ErrorKind.deprecation); - va_end(ap); - } - } - } - /********************************** * Combine e1 and e2 by CommaExp if both are not NULL. */ @@ -992,7 +837,8 @@ extern (C++) abstract class Expression : ASTNode dinteger_t toInteger() { //printf("Expression %s\n", EXPtoString(op).ptr); - error("integer constant expression expected instead of `%s`", toChars()); + if (!type.isTypeError()) + error(loc, "integer constant expression expected instead of `%s`", toChars()); return 0; } @@ -1004,19 +850,19 @@ extern (C++) abstract class Expression : ASTNode real_t toReal() { - error("floating point constant expression expected instead of `%s`", toChars()); + error(loc, "floating point constant expression expected instead of `%s`", toChars()); return CTFloat.zero; } real_t toImaginary() { - error("floating point constant expression expected instead of `%s`", toChars()); + error(loc, "floating point constant expression expected instead of `%s`", toChars()); return CTFloat.zero; } complex_t toComplex() { - error("floating point constant expression expected instead of `%s`", toChars()); + error(loc, "floating point constant expression expected instead of `%s`", toChars()); return complex_t(CTFloat.zero); } @@ -1045,9 +891,9 @@ extern (C++) abstract class Expression : ASTNode loc = e.loc; if (e.op == EXP.type) - error("`%s` is a `%s` definition and cannot be modified", e.type.toChars(), e.type.kind()); + error(loc, "`%s` is a `%s` definition and cannot be modified", e.type.toChars(), e.type.kind()); else - error("`%s` is not an lvalue and cannot be modified", e.toChars()); + error(loc, "`%s` is not an lvalue and cannot be modified", e.toChars()); return ErrorExp.get(); } @@ -1071,17 +917,17 @@ extern (C++) abstract class Expression : ASTNode break; if (!ff.type.isMutable) { - error("cannot modify `%s` in `%s` function", toChars(), MODtoChars(type.mod)); + error(loc, "cannot modify `%s` in `%s` function", toChars(), MODtoChars(type.mod)); return ErrorExp.get(); } } } - error("cannot modify `%s` expression `%s`", MODtoChars(type.mod), toChars()); + error(loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), toChars()); return ErrorExp.get(); } else if (!type.isAssignable()) { - error("cannot modify struct instance `%s` of type `%s` because it contains `const` or `immutable` members", + error(loc, "cannot modify struct instance `%s` of type `%s` because it contains `const` or `immutable` members", toChars(), type.toChars()); return ErrorExp.get(); } @@ -1136,7 +982,7 @@ extern (C++) abstract class Expression : ASTNode { if (type && type.toBasetype().ty == Tvoid) { - error("expression `%s` is `void` and has no value", toChars()); + error(loc, "expression `%s` is `void` and has no value", toChars()); //print(); assert(0); if (!global.gag) type = Type.terror; @@ -1153,7 +999,7 @@ extern (C++) abstract class Expression : ASTNode return true; if (!type.isscalar()) { - error("`%s` is not a scalar, it is a `%s`", toChars(), type.toChars()); + error(loc, "`%s` is not a scalar, it is a `%s`", toChars(), type.toChars()); return true; } return checkValue(); @@ -1167,7 +1013,7 @@ extern (C++) abstract class Expression : ASTNode return true; if (type.toBasetype().ty == Tbool) { - error("operation not allowed on `bool` `%s`", toChars()); + error(loc, "operation not allowed on `bool` `%s`", toChars()); return true; } return false; @@ -1181,7 +1027,7 @@ extern (C++) abstract class Expression : ASTNode return true; if (!type.isintegral()) { - error("`%s` is not of integral type, it is a `%s`", toChars(), type.toChars()); + error(loc, "`%s` is not of integral type, it is a `%s`", toChars(), type.toChars()); return true; } return checkValue(); @@ -1199,7 +1045,7 @@ extern (C++) abstract class Expression : ASTNode const char* msg = type.isAggregate() ? "operator `%s` is not defined for `%s` of type `%s`" : "illegal operator `%s` for `%s` of type `%s`"; - error(msg, EXPtoString(op).ptr, toChars(), type.toChars()); + error(loc, msg, EXPtoString(op).ptr, toChars(), type.toChars()); return true; } return checkValue(); @@ -1240,7 +1086,7 @@ extern (C++) abstract class Expression : ASTNode // If the call has a pure parent, then the called func must be pure. if (!f.isPure() && checkImpure(sc, loc, null, f)) { - error("`pure` %s `%s` cannot call impure %s `%s`", + error(loc, "`pure` %s `%s` cannot call impure %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars()); @@ -1379,7 +1225,7 @@ extern (C++) abstract class Expression : ASTNode if (checkImpure(sc, loc, "`pure` %s `%s` cannot access mutable static data `%s`", v)) { - error("`pure` %s `%s` cannot access mutable static data `%s`", + error(loc, "`pure` %s `%s` cannot access mutable static data `%s`", sc.func.kind(), sc.func.toPrettyChars(), v.toChars()); err = true; } @@ -1424,7 +1270,7 @@ extern (C++) abstract class Expression : ASTNode OutBuffer vbuf; MODMatchToBuffer(&ffbuf, ff.type.mod, v.type.mod); MODMatchToBuffer(&vbuf, v.type.mod, ff.type.mod); - error("%s%s `%s` cannot access %sdata `%s`", + error(loc, "%s%s `%s` cannot access %sdata `%s`", ffbuf.peekChars(), ff.kind(), ff.toPrettyChars(), vbuf.peekChars(), v.toChars()); err = true; break; @@ -1483,7 +1329,7 @@ extern (C++) abstract class Expression : ASTNode { if (sc.varDecl.storage_class & STC.safe) { - error("`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`", + error(loc, "`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`", sc.varDecl.toChars(), f.toChars()); return true; } @@ -1504,7 +1350,7 @@ extern (C++) abstract class Expression : ASTNode loc = sc.func.loc; const prettyChars = f.toPrettyChars(); - error("`@safe` %s `%s` cannot call `@system` %s `%s`", + error(loc, "`@safe` %s `%s` cannot call `@system` %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), prettyChars); if (!f.isDtorDeclaration) @@ -1568,7 +1414,7 @@ extern (C++) abstract class Expression : ASTNode || f.ident == Id._d_arrayappendT || f.ident == Id._d_arrayappendcTX || f.ident == Id._d_arraycatnTX || f.ident == Id._d_newclassT)) { - error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`", + error(loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars()); if (!f.isDtorDeclaration) @@ -1628,7 +1474,7 @@ extern (C++) abstract class Expression : ASTNode // sc.intypeof, sc.getStructClassScope(), func, fdthis); auto t = ve.var.isThis(); assert(t); - error("accessing non-static variable `%s` requires an instance of `%s`", ve.var.toChars(), t.toChars()); + error(loc, "accessing non-static variable `%s` requires an instance of `%s`", ve.var.toChars(), t.toChars()); return true; } } @@ -1661,8 +1507,8 @@ extern (C++) abstract class Expression : ASTNode break; } - error("read-modify-write operations are not allowed for `shared` variables"); - errorSupplemental("Use `core.atomic.atomicOp!\"%s\"(%s, %s)` instead", + error(loc, "read-modify-write operations are not allowed for `shared` variables"); + errorSupplemental(loc, "Use `core.atomic.atomicOp!\"%s\"(%s, %s)` instead", EXPtoString(rmwOp).ptr, toChars(), ex ? ex.toChars() : "1"); return true; } @@ -1862,7 +1708,10 @@ extern (C++) abstract class Expression : ASTNode inout(IdentityExp) isIdentityExp() { return (op == EXP.identity || op == EXP.notIdentity) ? cast(typeof(return))this : null; } inout(CondExp) isCondExp() { return op == EXP.question ? cast(typeof(return))this : null; } inout(GenericExp) isGenericExp() { return op == EXP._Generic ? cast(typeof(return))this : null; } - inout(DefaultInitExp) isDefaultInitExp() { return isDefaultInitOp(op) ? cast(typeof(return))this: null; } + inout(DefaultInitExp) isDefaultInitExp() { return + (op == EXP.prettyFunction || op == EXP.functionString || + op == EXP.line || op == EXP.moduleString || + op == EXP.file || op == EXP.fileFullPath ) ? cast(typeof(return))this : null; } inout(FileInitExp) isFileInitExp() { return (op == EXP.file || op == EXP.fileFullPath) ? cast(typeof(return))this : null; } inout(LineInitExp) isLineInitExp() { return op == EXP.line ? cast(typeof(return))this : null; } inout(ModuleInitExp) isModuleInitExp() { return op == EXP.moduleString ? cast(typeof(return))this : null; } @@ -1910,7 +1759,7 @@ extern (C++) final class IntegerExp : Expression { //printf("%s, loc = %d\n", toChars(), loc.linnum); if (type.ty != Terror) - error("integral constant must be scalar type, not `%s`", type.toChars()); + error(loc, "integral constant must be scalar type, not `%s`", type.toChars()); type = Type.terror; } this.type = type; @@ -1988,7 +1837,7 @@ extern (C++) final class IntegerExp : Expression e = this; else if (!loc.isValid()) loc = e.loc; - e.error("cannot modify constant `%s`", e.toChars()); + error(e.loc, "cannot modify constant `%s`", e.toChars()); return ErrorExp.get(); } @@ -2172,11 +2021,6 @@ extern (C++) final class VoidInitExp : Expression this.type = var.type; } - override const(char)* toChars() const - { - return "void"; - } - override void accept(Visitor v) { v.visit(this); @@ -2210,6 +2054,21 @@ extern (C++) final class RealExp : Expression emplaceExp!(RealExp)(pue, loc, value, type); } + /******************************** + * Test to see if two reals are the same. + * Regard NaN's as equivalent. + * Regard +0 and -0 as different. + * Params: + * x1 = first operand + * x2 = second operand + * Returns: + * true if x1 is x2 + * else false + */ + private static bool RealIdentical(real_t x1, real_t x2) @safe + { + return (CTFloat.isNaN(x1) && CTFloat.isNaN(x2)) || CTFloat.isIdentical(x1, x2); + } override bool equals(const RootObject o) const { if (this == o) @@ -2299,7 +2158,9 @@ extern (C++) final class ComplexExp : Expression return true; if (auto ne = (cast(Expression)o).isComplexExp()) { - if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && RealIdentical(creall(value), creall(ne.value)) && RealIdentical(cimagl(value), cimagl(ne.value))) + if (type.toHeadMutable().equals(ne.type.toHeadMutable()) && + RealExp.RealIdentical(creall(value), creall(ne.value)) && + RealExp.RealIdentical(cimagl(value), cimagl(ne.value))) { return true; } @@ -2594,6 +2455,9 @@ extern (C++) final class StringExp : Expression */ bool committed; + /// If the string is parsed from a hex string literal + bool hexString = false; + enum char NoPostfix = 0; extern (D) this(const ref Loc loc, const(void)[] string) scope @@ -2685,7 +2549,7 @@ extern (C++) final class StringExp : Expression { if (const s = utf_decodeChar(string[0 .. len], u, c)) { - error("%.*s", cast(int)s.length, s.ptr); + error(loc, "%.*s", cast(int)s.length, s.ptr); return 0; } result += utf_codeLength(encSize, c); @@ -2697,7 +2561,7 @@ extern (C++) final class StringExp : Expression { if (const s = utf_decodeWchar(wstring[0 .. len], u, c)) { - error("%.*s", cast(int)s.length, s.ptr); + error(loc, "%.*s", cast(int)s.length, s.ptr); return 0; } result += utf_codeLength(encSize, c); @@ -2902,7 +2766,7 @@ extern (C++) final class StringExp : Expression override Expression modifiableLvalue(Scope* sc, Expression e) { - error("cannot modify string literal `%s`", toChars()); + error(loc, "cannot modify string literal `%s`", toChars()); return ErrorExp.get(); } @@ -3035,7 +2899,7 @@ extern (C++) final class TupleExp : Expression } else { - error("`%s` is not an expression", o.toChars()); + error(loc, "`%s` is not an expression", o.toChars()); } } } @@ -3571,13 +3435,13 @@ extern (C++) final class TypeExp : Expression override bool checkType() { - error("type `%s` is not an expression", toChars()); + error(loc, "type `%s` is not an expression", toChars()); return true; } override bool checkValue() { - error("type `%s` has no value", toChars()); + error(loc, "type `%s` has no value", toChars()); return true; } @@ -3617,7 +3481,7 @@ extern (C++) final class ScopeExp : Expression { if (sds.isPackage()) { - error("%s `%s` has no type", sds.kind(), sds.toChars()); + error(loc, "%s `%s` has no type", sds.kind(), sds.toChars()); return true; } if (auto ti = sds.isTemplateInstance()) @@ -3627,7 +3491,7 @@ extern (C++) final class ScopeExp : Expression ti.semantictiargsdone && ti.semanticRun == PASS.initial) { - error("partial %s `%s` has no type", sds.kind(), toChars()); + error(loc, "partial %s `%s` has no type", sds.kind(), toChars()); return true; } } @@ -3636,7 +3500,7 @@ extern (C++) final class ScopeExp : Expression override bool checkValue() { - error("%s `%s` has no value", sds.kind(), sds.toChars()); + error(loc, "%s `%s` has no value", sds.kind(), sds.toChars()); return true; } @@ -3678,13 +3542,13 @@ extern (C++) final class TemplateExp : Expression override bool checkType() { - error("%s `%s` has no type", td.kind(), toChars()); + error(loc, "%s `%s` has no type", td.kind(), toChars()); return true; } override bool checkValue() { - error("%s `%s` has no value", td.kind(), toChars()); + error(loc, "%s `%s` has no value", td.kind(), toChars()); return true; } @@ -3877,22 +3741,22 @@ extern (C++) final class VarExp : SymbolExp { if (var.storage_class & STC.manifest) { - error("manifest constant `%s` cannot be modified", var.toChars()); + error(loc, "manifest constant `%s` cannot be modified", var.toChars()); return ErrorExp.get(); } if (var.storage_class & STC.lazy_ && !delegateWasExtracted) { - error("lazy variable `%s` cannot be modified", var.toChars()); + error(loc, "lazy variable `%s` cannot be modified", var.toChars()); return ErrorExp.get(); } if (var.ident == Id.ctfe) { - error("cannot modify compiler-generated variable `__ctfe`"); + error(loc, "cannot modify compiler-generated variable `__ctfe`"); return ErrorExp.get(); } if (var.ident == Id.dollar) // https://issues.dlang.org/show_bug.cgi?id=13574 { - error("cannot modify operator `$`"); + error(loc, "cannot modify operator `$`"); return ErrorExp.get(); } return this; @@ -3903,7 +3767,7 @@ extern (C++) final class VarExp : SymbolExp //printf("VarExp::modifiableLvalue('%s')\n", var.toChars()); if (var.storage_class & STC.manifest) { - error("cannot modify manifest constant `%s`", toChars()); + error(loc, "cannot modify manifest constant `%s`", toChars()); return ErrorExp.get(); } // See if this expression is a modifiable lvalue (i.e. not const) @@ -4219,7 +4083,7 @@ extern (C++) final class FuncExp : Expression { if (td) { - error("template lambda has no type"); + error(loc, "template lambda has no type"); return true; } return false; @@ -4229,7 +4093,7 @@ extern (C++) final class FuncExp : Expression { if (td) { - error("template lambda has no value"); + error(loc, "template lambda has no value"); return true; } return false; @@ -4425,11 +4289,11 @@ extern (C++) abstract class UnaExp : Expression if (e1.op == EXP.type) { - error("incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(op).ptr, e1.toChars(), EXPtoString(op).ptr); + error(loc, "incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(op).ptr, e1.toChars(), EXPtoString(op).ptr); } else { - error("incompatible type for `%s(%s)`: `%s`", EXPtoString(op).ptr, e1.toChars(), e1.type.toChars()); + error(loc, "incompatible type for `%s(%s)`: `%s`", EXPtoString(op).ptr, e1.toChars(), e1.type.toChars()); } return ErrorExp.get(); } @@ -4504,18 +4368,18 @@ extern (C++) abstract class BinExp : Expression const(char)* thisOp = (op == EXP.question) ? ":" : EXPtoString(op).ptr; if (e1.op == EXP.type || e2.op == EXP.type) { - error("incompatible types for `(%s) %s (%s)`: cannot use `%s` with types", + error(loc, "incompatible types for `(%s) %s (%s)`: cannot use `%s` with types", e1.toChars(), thisOp, e2.toChars(), EXPtoString(op).ptr); } else if (e1.type.equals(e2.type)) { - error("incompatible types for `(%s) %s (%s)`: both operands are of type `%s`", + error(loc, "incompatible types for `(%s) %s (%s)`: both operands are of type `%s`", e1.toChars(), thisOp, e2.toChars(), e1.type.toChars()); } else { auto ts = toAutoQualChars(e1.type, e2.type); - error("incompatible types for `(%s) %s (%s)`: `%s` and `%s`", + error(loc, "incompatible types for `(%s) %s (%s)`: `%s` and `%s`", e1.toChars(), thisOp, e2.toChars(), ts[0], ts[1]); } return ErrorExp.get(); @@ -4536,7 +4400,7 @@ extern (C++) abstract class BinExp : Expression { if ((type.isintegral() && t2.isfloating())) { - warning("`%s %s %s` is performing truncating conversion", type.toChars(), EXPtoString(op).ptr, t2.toChars()); + warning(loc, "`%s %s %s` is performing truncating conversion", type.toChars(), EXPtoString(op).ptr, t2.toChars()); } } @@ -4548,17 +4412,17 @@ extern (C++) abstract class BinExp : Expression const(char)* opstr = EXPtoString(op).ptr; if (t1.isreal() && t2.iscomplex()) { - error("`%s %s %s` is undefined. Did you mean `%s %s %s.re`?", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars()); + error(loc, "`%s %s %s` is undefined. Did you mean `%s %s %s.re`?", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars()); return ErrorExp.get(); } else if (t1.isimaginary() && t2.iscomplex()) { - error("`%s %s %s` is undefined. Did you mean `%s %s %s.im`?", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars()); + error(loc, "`%s %s %s` is undefined. Did you mean `%s %s %s.im`?", t1.toChars(), opstr, t2.toChars(), t1.toChars(), opstr, t2.toChars()); return ErrorExp.get(); } else if ((t1.isreal() || t1.isimaginary()) && t2.isimaginary()) { - error("`%s %s %s` is an undefined operation", t1.toChars(), opstr, t2.toChars()); + error(loc, "`%s %s %s` is an undefined operation", t1.toChars(), opstr, t2.toChars()); return ErrorExp.get(); } } @@ -4570,7 +4434,7 @@ extern (C++) abstract class BinExp : Expression // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. if ((t1.isreal() && (t2.isimaginary() || t2.iscomplex())) || (t1.isimaginary() && (t2.isreal() || t2.iscomplex()))) { - error("`%s %s %s` is undefined (result is complex)", t1.toChars(), EXPtoString(op).ptr, t2.toChars()); + error(loc, "`%s %s %s` is undefined (result is complex)", t1.toChars(), EXPtoString(op).ptr, t2.toChars()); return ErrorExp.get(); } if (type.isreal() || type.isimaginary()) @@ -4661,7 +4525,7 @@ extern (C++) abstract class BinExp : Expression { if (t2.iscomplex()) { - error("cannot perform modulo complex arithmetic"); + error(loc, "cannot perform modulo complex arithmetic"); return ErrorExp.get(); } } @@ -4950,13 +4814,13 @@ extern (C++) final class DotTemplateExp : UnaExp override bool checkType() { - error("%s `%s` has no type", td.kind(), toChars()); + error(loc, "%s `%s` has no type", td.kind(), toChars()); return true; } override bool checkValue() { - error("%s `%s` has no value", td.kind(), toChars()); + error(loc, "%s `%s` has no value", td.kind(), toChars()); return true; } @@ -5125,7 +4989,7 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp ti.semantictiargsdone && ti.semanticRun == PASS.initial) { - error("partial %s `%s` has no type", ti.kind(), toChars()); + error(loc, "partial %s `%s` has no type", ti.kind(), toChars()); return true; } return false; @@ -5137,9 +5001,9 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp ti.semantictiargsdone && ti.semanticRun == PASS.initial) - error("partial %s `%s` has no value", ti.kind(), toChars()); + error(loc, "partial %s `%s` has no value", ti.kind(), toChars()); else - error("%s `%s` has no value", ti.kind(), ti.toChars()); + error(loc, "%s `%s` has no value", ti.kind(), ti.toChars()); return true; } @@ -5484,9 +5348,9 @@ extern (C++) final class PtrExp : UnaExp if (var && var.type.isFunction_Delegate_PtrToFunction()) { if (var.type.isTypeFunction()) - error("function `%s` is not an lvalue and cannot be modified", var.toChars()); + error(loc, "function `%s` is not an lvalue and cannot be modified", var.toChars()); else - error("function pointed to by `%s` is not an lvalue and cannot be modified", var.toChars()); + error(loc, "function pointed to by `%s` is not an lvalue and cannot be modified", var.toChars()); return ErrorExp.get(); } return Expression.modifiableLvalue(sc, e); @@ -5774,7 +5638,7 @@ extern (C++) final class SliceExp : UnaExp override Expression modifiableLvalue(Scope* sc, Expression e) { - error("slice expression `%s` is not a modifiable lvalue", toChars()); + error(loc, "slice expression `%s` is not a modifiable lvalue", toChars()); return this; } @@ -5848,7 +5712,7 @@ extern (C++) final class ArrayExp : UnaExp override Expression toLvalue(Scope* sc, Expression e) { if (type && type.toBasetype().ty == Tvoid) - error("`void`s have no value"); + error(loc, "`void`s have no value"); return this; } @@ -6116,7 +5980,7 @@ extern (C++) final class IndexExp : BinExp Type t2b = e2.type.toBasetype(); if (t2b.ty == Tarray && t2b.nextOf().isMutable()) { - error("associative arrays can only be assigned values with immutable keys, not `%s`", e2.type.toChars()); + error(loc, "associative arrays can only be assigned values with immutable keys, not `%s`", e2.type.toChars()); return ErrorExp.get(); } modifiable = true; @@ -6975,7 +6839,7 @@ extern (C++) final class CondExp : BinExp { if (!e1.isLvalue() && !e2.isLvalue()) { - error("conditional expression `%s` is not a modifiable lvalue", toChars()); + error(loc, "conditional expression `%s` is not a modifiable lvalue", toChars()); return ErrorExp.get(); } e1 = e1.modifiableLvalue(sc, e1); @@ -7061,14 +6925,6 @@ extern (C++) final class CondExp : BinExp } } -/// Returns: if this token is the `op` for a derived `DefaultInitExp` class. -bool isDefaultInitOp(EXP op) pure nothrow @safe @nogc -{ - return op == EXP.prettyFunction || op == EXP.functionString || - op == EXP.line || op == EXP.moduleString || - op == EXP.file || op == EXP.fileFullPath ; -} - /*********************************************************** * A special keyword when used as a function's default argument * @@ -7085,6 +6941,12 @@ bool isDefaultInitOp(EXP op) pure nothrow @safe @nogc */ extern (C++) class DefaultInitExp : Expression { + /************************* + * Params: + * loc = location + * op = EXP.prettyFunction, EXP.functionString, EXP.moduleString, + * EXP.line, EXP.file, EXP.fileFullPath + */ extern (D) this(const ref Loc loc, EXP op) @safe { super(loc, op); diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 2189757e61f3..5c656ee9353c 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -51,7 +51,7 @@ bool isTrivialExp(Expression *e); bool hasSideEffect(Expression *e, bool assumeImpureCalls = false); enum BE : int32_t; -BE canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow); +BE canThrow(Expression *e, FuncDeclaration *func, ErrorSink *eSink); typedef unsigned char OwnedBy; enum @@ -93,9 +93,6 @@ public: DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; } const char *toChars() const override; - void error(const char *format, ...) const; - void warning(unsigned flag, const char *format, ...) const; - void deprecation(const char *format, ...) const; virtual dinteger_t toInteger(); virtual uinteger_t toUInteger(); @@ -380,6 +377,7 @@ public: size_t len; // number of chars, wchars, or dchars unsigned char sz; // 1: char, 2: wchar, 4: dchar bool committed; // if type is committed + bool hexString; // if string is parsed from a hex string literal static StringExp *create(const Loc &loc, const char *s); static StringExp *create(const Loc &loc, const void *s, d_size_t len); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 30382bbc6bb5..0bdcda9fe6ea 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -171,7 +171,7 @@ StringExp semanticString(Scope *sc, Expression exp, const char* s) auto se = e.toStringExp(); if (!se) { - exp.error("`string` expected for %s, not `(%s)` of type `%s`", + error(exp.loc, "`string` expected for %s, not `(%s)` of type `%s`", s, exp.toChars(), exp.type.toChars()); return null; } @@ -224,7 +224,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0) Lfallback: if (ae.arguments.length == 1) return null; - ae.error("multi-dimensional slicing requires template `opSlice`"); + error(ae.loc, "multi-dimensional slicing requires template `opSlice`"); return ErrorExp.get(); } //printf("[%d] e = %s\n", i, e.toChars()); @@ -274,7 +274,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0) if (!e.type) { - ae.error("`%s` has no value", e.toChars()); + error(ae.loc, "`%s` has no value", e.toChars()); e = ErrorExp.get(); } if (e.op == EXP.error) @@ -311,7 +311,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* p e = resolveProperties(sc, e); if (!e.type) { - ae.error("`%s` has no value", e.toChars()); + error(ae.loc, "`%s` has no value", e.toChars()); errors = true; } return e; @@ -482,6 +482,18 @@ private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident) } } +/****************************** + * check e is exp.opDispatch!(tiargs) or not + * It's used to switch to UFCS the semantic analysis path + */ +private bool isDotOpDispatch(Expression e) +{ + if (auto dtie = e.isDotTemplateInstanceExp()) + return dtie.ti.name == Id.opDispatch; + return false; +} + + /****************************** * Pull out callable entity with UFCS. */ @@ -519,12 +531,12 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) */ if (!ce.arguments || ce.arguments.length != 1) { - ce.error("expected key as argument to `aa.remove()`"); + error(ce.loc, "expected key as argument to `aa.remove()`"); return ErrorExp.get(); } if (!eleft.type.isMutable()) { - ce.error("cannot remove key from `%s` associative array `%s`", MODtoChars(t.mod), eleft.toChars()); + error(ce.loc, "cannot remove key from `%s` associative array `%s`", MODtoChars(t.mod), eleft.toChars()); return ErrorExp.get(); } Expression key = (*ce.arguments)[0]; @@ -638,6 +650,41 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) return null; } +int expandAliasThisTuples(Expressions* exps, size_t starti = 0) +{ + if (!exps || exps.length == 0) + return -1; + + for (size_t u = starti; u < exps.length; u++) + { + Expression exp = (*exps)[u]; + if (TupleDeclaration td = exp.isAliasThisTuple) + { + exps.remove(u); + size_t i; + td.foreachVar((s) + { + auto d = s.isDeclaration(); + auto e = new DotVarExp(exp.loc, exp, d); + assert(d.type); + e.type = d.type; + exps.insert(u + i, e); + ++i; + }); + version (none) + { + printf("expansion ->\n"); + foreach (e; exps) + { + printf("\texps[%d] e = %s %s\n", i, EXPtoString(e.op), e.toChars()); + } + } + return cast(int)u; + } + } + return -1; +} + /****************************** * Pull out property with UFCS. */ @@ -1137,7 +1184,7 @@ L1: */ if (flag) return null; - e1.error("`this` for `%s` needs to be type `%s` not type `%s`", var.toChars(), ad.toChars(), t.toChars()); + error(e1.loc, "`this` for `%s` needs to be type `%s` not type `%s`", var.toChars(), ad.toChars(), t.toChars()); return ErrorExp.get(); } } @@ -1510,7 +1557,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps) e = resolveProperties(sc, e); if (!e.type) { - e.error("`%s` has no value", e.toChars()); + error(e.loc, "`%s` has no value", e.toChars()); t0 = Type.terror; continue; } @@ -1706,7 +1753,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, const b { if (reportErrors) { - arg.error("cannot pass type `%s` as a function argument", arg.toChars()); + error(arg.loc, "cannot pass type `%s` as a function argument", arg.toChars()); arg = ErrorExp.get(); } err = true; @@ -1716,7 +1763,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, const b { if (reportErrors) { - arg.error("cannot pass function `%s` as a function argument", arg.toChars()); + error(arg.loc, "cannot pass function `%s` as a function argument", arg.toChars()); arg = ErrorExp.get(); } err = true; @@ -1745,7 +1792,7 @@ private bool checkDefCtor(Loc loc, Type t) StructDeclaration sd = ts.sym; if (sd.noDefaultCtor) { - sd.error(loc, "default construction is disabled"); + .error(loc, "%s `%s` default construction is disabled", sd.kind, sd.toPrettyChars); return true; } } @@ -1887,7 +1934,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } else { - if (isDefaultInitOp(arg.op)) + if (arg.isDefaultInitExp()) { arg = arg.resolveLoc(loc, sc); (*arguments)[i] = arg; @@ -2138,7 +2185,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, Type t = arg.type; if (!t.isMutable() || !t.isAssignable()) // check blit assignable { - arg.error("cannot modify struct `%s` with immutable members", arg.toChars()); + error(arg.loc, "cannot modify struct `%s` with immutable members", arg.toChars()); err = true; } else @@ -2270,12 +2317,12 @@ private bool functionParameters(const ref Loc loc, Scope* sc, const(char)* p = tf.linkage == LINK.c ? "extern(C)" : "extern(C++)"; if (arg.type.ty == Tarray) { - arg.error("cannot pass dynamic arrays to `%s` vararg functions", p); + error(arg.loc, "cannot pass dynamic arrays to `%s` vararg functions", p); err = true; } if (arg.type.ty == Tsarray) { - arg.error("cannot pass static arrays to `%s` vararg functions", p); + error(arg.loc, "cannot pass static arrays to `%s` vararg functions", p); err = true; } } @@ -2284,12 +2331,12 @@ private bool functionParameters(const ref Loc loc, Scope* sc, // Do not allow types that need destructors or copy constructors. if (arg.type.needsDestruction()) { - arg.error("cannot pass types that need destruction as variadic arguments"); + error(arg.loc, "cannot pass types that need destruction as variadic arguments"); err = true; } if (arg.type.needsCopyOrPostblit()) { - arg.error("cannot pass types with postblits or copy constructors as variadic arguments"); + error(arg.loc, "cannot pass types with postblits or copy constructors as variadic arguments"); err = true; } @@ -2313,7 +2360,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, { if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique()) { - arg.error("function `%s` is overloaded", arg.toChars()); + error(arg.loc, "function `%s` is overloaded", arg.toChars()); err = true; } } @@ -2370,7 +2417,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, for (ptrdiff_t i = 0; i != nargs; i++) { Expression arg = (*arguments)[i]; - if (canThrow(arg, sc.func, false)) + if (canThrow(arg, sc.func, null)) lastthrow = i; if (arg.type.needsDestruction()) { @@ -2752,7 +2799,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Dsymbol s2; if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2) { - exp.error("with symbol `%s` is shadowing local symbol `%s`", s.toPrettyChars(), s2.toPrettyChars()); + error(exp.loc, "with symbol `%s` is shadowing local symbol `%s`", s.toPrettyChars(), s2.toPrettyChars()); return setError(); } } @@ -2852,7 +2899,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (sc.flags & SCOPE.ctfe) { - exp.error("variable `__ctfe` cannot be read at compile time"); + error(exp.loc, "variable `__ctfe` cannot be read at compile time"); return setError(); } @@ -2914,15 +2961,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* Look for what user might have meant */ if (const n = importHint(exp.ident.toString())) - exp.error("`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr); + error(exp.loc, "`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr); else if (auto s2 = sc.search_correct(exp.ident)) - exp.error("undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars()); + error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars()); else if (const p = Scope.search_correct_C(exp.ident)) - exp.error("undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p); + error(exp.loc, "undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p); else if (exp.ident == Id.dollar) - exp.error("undefined identifier `$`"); + error(exp.loc, "undefined identifier `$`"); else - exp.error("undefined identifier `%s`", exp.ident.toChars()); + error(exp.loc, "undefined identifier `%s`", exp.ident.toChars()); result = ErrorExp.get(); } @@ -2957,7 +3004,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!s) { - e.error("`%s` is not in a class or struct scope", e.toChars()); + error(e.loc, "`%s` is not in a class or struct scope", e.toChars()); return setError(); } ClassDeclaration cd = s.isClassDeclaration(); @@ -2978,7 +3025,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (!fd) { - e.error("`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars()); + error(e.loc, "`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars()); return setError(); } @@ -3023,7 +3070,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!s) { - e.error("`%s` is not in a class scope", e.toChars()); + error(e.loc, "`%s` is not in a class scope", e.toChars()); return setError(); } cd = s.isClassDeclaration(); @@ -3032,7 +3079,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor cd = cd.baseClass; if (!cd) { - e.error("class `%s` has no `super`", s.toChars()); + error(e.loc, "class `%s` has no `super`", s.toChars()); return setError(); } e.type = cd.type; @@ -3057,7 +3104,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor goto Lerr; if (!cd.baseClass) { - e.error("no base class for `%s`", cd.toChars()); + error(e.loc, "no base class for `%s`", cd.toChars()); e.type = cd.type.addMod(e.var.type.mod); } else @@ -3073,7 +3120,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; Lerr: - e.error("`super` is only allowed in non-static class member functions"); + error(e.loc, "`super` is only allowed in non-static class member functions"); result = ErrorExp.get(); } @@ -3117,7 +3164,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (const p = utf_decodeChar(e.peekString(), u, c)) { - e.error("%.*s", cast(int)p.length, p.ptr); + error(e.loc, "%.*s", cast(int)p.length, p.ptr); return setError(); } else @@ -3140,7 +3187,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (const p = utf_decodeChar(e.peekString(), u, c)) { - e.error("%.*s", cast(int)p.length, p.ptr); + error(e.loc, "%.*s", cast(int)p.length, p.ptr); return setError(); } else @@ -3201,7 +3248,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e = e.expressionSemantic(sc); if (!e.type) { - exp.error("`%s` has no value", e.toChars()); + error(exp.loc, "`%s` has no value", e.toChars()); err = true; } else if (e.op == EXP.error) @@ -3257,7 +3304,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (e.elements.length > 0 && t0.ty == Tvoid) { - e.error("`%s` of type `%s` has no value", e.toChars(), e.type.toChars()); + error(e.loc, "`%s` of type `%s` has no value", e.toChars(), e.type.toChars()); return setError(); } @@ -3289,7 +3336,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor expandTuples(e.values); if (e.keys.length != e.values.length) { - e.error("number of keys is %llu, must match number of values %llu", + error(e.loc, "number of keys is %llu, must match number of values %llu", cast(ulong) e.keys.length, cast(ulong) e.values.length); return setError(); } @@ -3500,7 +3547,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!v.type) { - exp.error("forward reference of %s `%s`", v.kind(), v.toChars()); + error(exp.loc, "forward reference of %s `%s`", v.kind(), v.toChars()); return setError(); } if ((v.storage_class & STC.manifest) && v._init) @@ -3521,7 +3568,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (ti.inuse) { - exp.error("recursive expansion of %s `%s`", ti.kind(), ti.toPrettyChars()); + error(exp.loc, "recursive expansion of %s `%s`", ti.kind(), ti.toPrettyChars()); return setError(); } v.checkDeprecated(exp.loc, sc); @@ -3658,7 +3705,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor cdthis = exp.thisexp.type.isClassHandle(); if (!cdthis) { - exp.error("`this` for nested class must be a class type, not `%s`", exp.thisexp.type.toChars()); + error(exp.loc, "`this` for nested class must be a class type, not `%s`", exp.thisexp.type.toChars()); return setError(); } @@ -3706,7 +3753,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.thisexp && tb.ty != Tclass) { - exp.error("`.new` is only for allocating nested classes, not `%s`", tb.toChars()); + error(exp.loc, "`.new` is only for allocating nested classes, not `%s`", tb.toChars()); return setError(); } @@ -3725,19 +3772,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor cd.ctor = cd.searchCtor(); if (cd.noDefaultCtor && !nargs && !cd.defaultCtor) { - exp.error("default construction is disabled for type `%s`", cd.type.toChars()); + error(exp.loc, "default construction is disabled for type `%s`", cd.type.toChars()); return setError(); } if (cd.isInterfaceDeclaration()) { - exp.error("cannot create instance of interface `%s`", cd.toChars()); + error(exp.loc, "cannot create instance of interface `%s`", cd.toChars()); return setError(); } if (cd.isAbstract()) { - exp.error("cannot create instance of abstract class `%s`", cd.toChars()); + error(exp.loc, "cannot create instance of abstract class `%s`", cd.toChars()); errorSupplemental(cd.loc, "class `%s` is declared here", cd.toChars()); for (size_t i = 0; i < cd.vtbl.length; i++) { @@ -3767,9 +3814,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor void noReferenceToOuterClass() { if (cd.isAnonymous) - exp.error("cannot construct anonymous nested class because no implicit `this` reference to outer class is available"); + error(exp.loc, "cannot construct anonymous nested class because no implicit `this` reference to outer class is available"); else - exp.error("cannot construct nested class `%s` because no implicit `this` reference to outer class `%s` is available", + error(exp.loc, "cannot construct nested class `%s` because no implicit `this` reference to outer class `%s` is available", cd.toChars(), cdn.toChars()); return setError(); } @@ -3800,20 +3847,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (cdthis != cdn && !cdn.isBaseOf(cdthis, null)) { //printf("cdthis = %s\n", cdthis.toChars()); - exp.error("`this` for nested class must be of type `%s`, not `%s`", + error(exp.loc, "`this` for nested class must be of type `%s`, not `%s`", cdn.toChars(), exp.thisexp.type.toChars()); return setError(); } if (!MODimplicitConv(exp.thisexp.type.mod, exp.newtype.mod)) { - exp.error("nested type `%s` should have the same or weaker constancy as enclosing type `%s`", + error(exp.loc, "nested type `%s` should have the same or weaker constancy as enclosing type `%s`", exp.newtype.toChars(), exp.thisexp.type.toChars()); return setError(); } } else if (exp.thisexp) { - exp.error("`.new` is only for allocating nested classes"); + error(exp.loc, "`.new` is only for allocating nested classes"); return setError(); } else if (auto fdn = s.isFuncDeclaration()) @@ -3821,7 +3868,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // make sure the parent context fdn of cd is reachable from sc if (!ensureStaticLinkTo(sc.parent, fdn)) { - exp.error("outer function context of `%s` is needed to `new` nested class `%s`", + error(exp.loc, "outer function context of `%s` is needed to `new` nested class `%s`", fdn.toPrettyChars(), cd.toPrettyChars()); return setError(); } @@ -3831,7 +3878,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (exp.thisexp) { - exp.error("`.new` is only for allocating nested classes"); + error(exp.loc, "`.new` is only for allocating nested classes"); return setError(); } @@ -3844,7 +3891,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor te = getRightThis(exp.loc, sc, ad2, te, cd); if (te.op == EXP.error) { - exp.error("need `this` of type `%s` needed to `new` nested class `%s`", ad2.toChars(), cd.toChars()); + error(exp.loc, "need `this` of type `%s` needed to `new` nested class `%s`", ad2.toChars(), cd.toChars()); return setError(); } } @@ -3852,7 +3899,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (cd.disableNew && !exp.onstack) { - exp.error("cannot allocate `class %s` with `new` because it is annotated with `@disable new()`", + error(exp.loc, "cannot allocate `class %s` with `new` because it is annotated with `@disable new()`", originalNewtype.toChars()); return setError(); } @@ -3879,7 +3926,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (nargs) { - exp.error("no constructor for `%s`", cd.toChars()); + error(exp.loc, "no constructor for `%s`", cd.toChars()); return setError(); } @@ -3972,14 +4019,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor sd.ctor = sd.searchCtor(); if (sd.noDefaultCtor && !nargs) { - exp.error("default construction is disabled for type `%s`", sd.type.toChars()); + error(exp.loc, "default construction is disabled for type `%s`", sd.type.toChars()); return setError(); } // checkDeprecated() is already done in newtype.typeSemantic(). if (sd.disableNew) { - exp.error("cannot allocate `struct %s` with `new` because it is annotated with `@disable new()`", + error(exp.loc, "cannot allocate `struct %s` with `new` because it is annotated with `@disable new()`", originalNewtype.toChars()); return setError(); } @@ -4053,7 +4100,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { // https://issues.dlang.org/show_bug.cgi?id=20422 // Without this check the compiler would give a misleading error - exp.error("missing length argument for array"); + error(exp.loc, "missing length argument for array"); return setError(); } @@ -4062,21 +4109,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor AggregateDeclaration ad = s ? s.isAggregateDeclaration() : null; if (ad && ad.noDefaultCtor) { - exp.error("default construction is disabled for type `%s`", tb.nextOf().toChars()); + error(exp.loc, "default construction is disabled for type `%s`", tb.nextOf().toChars()); return setError(); } for (size_t i = 0; i < nargs; i++) { if (tb.ty != Tarray) { - exp.error("too many arguments for array"); + error(exp.loc, "too many arguments for array"); return setError(); } Expression arg = (*exp.arguments)[i]; if (exp.names && (*exp.names)[i]) { - exp.error("no named argument `%s` allowed for array dimension", (*exp.names)[i].toChars()); + error(exp.loc, "no named argument `%s` allowed for array dimension", (*exp.names)[i].toChars()); return setError(); } @@ -4088,7 +4135,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (arg.op == EXP.int64 && (target.isLP64 ? cast(sinteger_t)arg.toInteger() : cast(int)arg.toInteger()) < 0) { - exp.error("negative array dimension `%s`", (*exp.arguments)[i].toChars()); + error(exp.loc, "negative array dimension `%s`", (*exp.arguments)[i].toChars()); return setError(); } (*exp.arguments)[i] = arg; @@ -4104,7 +4151,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (exp.names && (*exp.names)[0]) { - exp.error("no named argument `%s` allowed for scalar", (*exp.names)[0].toChars()); + error(exp.loc, "no named argument `%s` allowed for scalar", (*exp.names)[0].toChars()); return setError(); } Expression e = (*exp.arguments)[0]; @@ -4113,7 +4160,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - exp.error("more than one argument for construction of `%s`", exp.type.toChars()); + error(exp.loc, "more than one argument for construction of `%s`", exp.type.toChars()); return setError(); } @@ -4125,13 +4172,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // e.g. `new Alias(args)` if (nargs) { - exp.error("`new` cannot take arguments for an associative array"); + error(exp.loc, "`new` cannot take arguments for an associative array"); return setError(); } } else { - exp.error("cannot create a `%s` with `new`", exp.type.toChars()); + error(exp.loc, "cannot create a `%s` with `new`", exp.type.toChars()); return setError(); } @@ -4425,10 +4472,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor OutBuffer buf; foreach (idx, ref arg; *arguments) buf.printf("%s%s", (idx ? ", ".ptr : "".ptr), arg.type.toChars()); - exp.error("function literal `%s%s` is not callable using argument types `(%s)`", + error(exp.loc, "function literal `%s%s` is not callable using argument types `(%s)`", exp.fd.toChars(), parametersTypeToChars(tfl.parameterList), buf.peekChars()); - exp.errorSupplemental("too %s arguments, expected %d, got %d", + errorSupplemental(exp.loc, "too %s arguments, expected %d, got %d", arguments.length < dim ? "few".ptr : "many".ptr, cast(int)dim, cast(int)arguments.length); return ErrorExp.get(); @@ -4638,7 +4685,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor __gshared int nest; if (++nest > global.recursionLimit) { - exp.error("recursive evaluation of `%s`", exp.toChars()); + error(exp.loc, "recursive evaluation of `%s`", exp.toChars()); --nest; return setError(); } @@ -4717,12 +4764,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - arg.error("identifier or `(` expected"); + error(arg.loc, "identifier or `(` expected"); result = ErrorExp.get(); } return; } - exp.error("identifier or `(` expected before `)`"); + error(exp.loc, "identifier or `(` expected before `)`"); result = ErrorExp.get(); return; } @@ -4827,7 +4874,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e1 = resolveAliasThis(sc, exp.e1); goto Lagain; } - exp.error("%s `%s` does not overload ()", sd.kind(), sd.toChars()); + error(exp.loc, "%s `%s` does not overload ()", sd.kind(), sd.toChars()); return setError(); } @@ -4888,7 +4935,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - exp.error("more than one argument for construction of `%s`", t1.toChars()); + error(exp.loc, "more than one argument for construction of `%s`", t1.toChars()); return setError(); } e = e.expressionSemantic(sc); @@ -5012,7 +5059,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (sc.func && sc.func.isInvariantDeclaration() && ue.e1.op == EXP.this_ && exp.f.addPostInvariant()) { - exp.error("cannot call `public`/`export` function `%s` from invariant", exp.f.toChars()); + error(exp.loc, "cannot call `public`/`export` function `%s` from invariant", exp.f.toChars()); return setError(); } @@ -5028,7 +5075,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (!checkSymbolAccess(sc, exp.f)) { - exp.error("%s `%s` of type `%s` is not accessible from module `%s`", + error(exp.loc, "%s `%s` of type `%s` is not accessible from module `%s`", exp.f.kind(), exp.f.toPrettyChars(), exp.f.type.toChars(), sc._module.toChars); return setError(); } @@ -5106,12 +5153,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // Base class constructor call if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration()) { - exp.error("super class constructor call must be in a constructor"); + error(exp.loc, "super class constructor call must be in a constructor"); return setError(); } if (!cd.baseClass.ctor) { - exp.error("no super class constructor for `%s`", cd.baseClass.toChars()); + error(exp.loc, "no super class constructor for `%s`", cd.baseClass.toChars()); return setError(); } } @@ -5121,7 +5168,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // constructor if (!ad || !sc.func.isCtorDeclaration()) { - exp.error("constructor call must be in a constructor"); + error(exp.loc, "constructor call must be in a constructor"); return setError(); } @@ -5138,11 +5185,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!sc.intypeof && !(sc.ctorflow.callSuper & CSX.halt)) { if (sc.inLoop || sc.ctorflow.callSuper & CSX.label) - exp.error("constructor calls not allowed in loops or after labels"); + error(exp.loc, "constructor calls not allowed in loops or after labels"); if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor)) - exp.error("multiple constructor calls"); + error(exp.loc, "multiple constructor calls"); if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor)) - exp.error("an earlier `return` statement skips constructor"); + error(exp.loc, "an earlier `return` statement skips constructor"); sc.ctorflow.callSuper |= CSX.any_ctor | (isSuper ? CSX.super_ctor : CSX.this_ctor); } @@ -5170,7 +5217,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // call graph if (exp.f == sc.func) { - exp.error("cyclic constructor call"); + error(exp.loc, "cyclic constructor call"); return setError(); } } @@ -5187,7 +5234,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (!t1) { - exp.error("function expected before `()`, not `%s`", exp.e1.toChars()); + error(exp.loc, "function expected before `()`, not `%s`", exp.e1.toChars()); return setError(); } else if (t1.ty == Terror) @@ -5270,7 +5317,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - exp.error("function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars()); + error(exp.loc, "function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars()); return setError(); } @@ -5305,20 +5352,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor bool err = false; if (!tf.purity && sc.func.setImpure(exp.loc, "`pure` %s `%s` cannot call impure `%s`", exp.e1)) { - exp.error("`pure` %s `%s` cannot call impure %s `%s`", + error(exp.loc, "`pure` %s `%s` cannot call impure %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars()); err = true; } if (!tf.isnogc && sc.func.setGC(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc `%s`", exp.e1)) { - exp.error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`", + error(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars()); err = true; } if (tf.trust <= TRUST.system && sc.setUnsafe(true, exp.loc, "`@safe` function `%s` cannot call `@system` `%s`", sc.func, exp.e1)) { - exp.error("`@safe` %s `%s` cannot call `@system` %s `%s`", + error(exp.loc, "`@safe` %s `%s` cannot call `@system` %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars()); err = true; } @@ -5436,7 +5483,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { exp.e1 = e1org; // https://issues.dlang.org/show_bug.cgi?id=10922 // avoid recursive expression printing - exp.error("forward reference to inferred return type of function call `%s`", exp.toChars()); + error(exp.loc, "forward reference to inferred return type of function call `%s`", exp.toChars()); return setError(); } @@ -5488,6 +5535,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } + // `super.fun()` with fun being abstract and unimplemented + auto supDotFun = exp.e1.isDotVarExp(); + if (supDotFun && supDotFun.e1.isSuperExp() && exp.f && exp.f.isAbstract() && !exp.f.fbody) + { + error(exp.loc, "call to unimplemented abstract function `%s`", exp.f.toFullSignature()); + errorSupplemental(exp.loc, "declared here: %s", exp.f.loc.toChars()); + } + // declare dual-context container if (exp.f && exp.f.hasDualContext() && !sc.intypeof && sc.func) { @@ -5499,7 +5554,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor te = getRightThis(exp.loc, sc, ad2, te, exp.f); if (te.op == EXP.error) { - exp.error("need `this` of type `%s` to call function `%s`", ad2.toChars(), exp.f.toChars()); + error(exp.loc, "need `this` of type `%s` to call function `%s`", ad2.toChars(), exp.f.toChars()); return setError(); } } @@ -5579,7 +5634,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!sc.insert(s)) { auto conflict = sc.search(Loc.initial, s.ident, null); - e.error("declaration `%s` is already defined", s.toPrettyChars()); + error(e.loc, "declaration `%s` is already defined", s.toPrettyChars()); errorSupplemental(conflict.loc, "`%s` `%s` is defined here", conflict.kind(), conflict.toChars()); return setError(); @@ -5613,7 +5668,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // 65535 should be enough for anyone if (!s.localNum) { - e.error("more than 65535 symbols with name `%s` generated", s.ident.toChars()); + error(e.loc, "more than 65535 symbols with name `%s` generated", s.ident.toChars()); return setError(); } @@ -5646,11 +5701,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (sc.func.fes) { - e.deprecation("%s `%s` is shadowing %s `%s`. Rename the `foreach` variable.", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars()); + deprecation(e.loc, "%s `%s` is shadowing %s `%s`. Rename the `foreach` variable.", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars()); } else { - e.error("%s `%s` is shadowing %s `%s`", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars()); + error(e.loc, "%s `%s` is shadowing %s `%s`", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars()); return setError(); } } @@ -5715,7 +5770,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!ta) { //printf("ta %p ea %p sa %p\n", ta, ea, sa); - exp.error("no type for `typeid(%s)`", ea ? ea.toChars() : (sa ? sa.toChars() : "")); + error(exp.loc, "no type for `typeid(%s)`", ea ? ea.toChars() : (sa ? sa.toChars() : "")); return setError(); } @@ -5821,7 +5876,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!tup && !sc.insert(s)) { auto conflict = sc.search(Loc.initial, s.ident, null); - e.error("declaration `%s` is already defined", s.toPrettyChars()); + error(e.loc, "declaration `%s` is already defined", s.toPrettyChars()); errorSupplemental(conflict.loc, "`%s` `%s` is defined here", conflict.kind(), conflict.toChars()); } @@ -5842,7 +5897,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (e.id && !(sc.flags & SCOPE.condition)) { - e.error("can only declare type aliases within `static if` conditionals or `static assert`s"); + error(e.loc, "can only declare type aliases within `static if` conditionals or `static assert`s"); return setError(); } @@ -6128,7 +6183,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!sc.insert(s)) { auto conflict = sc.search(Loc.initial, s.ident, null); - e.error("declaration `%s` is already defined", s.toPrettyChars()); + error(e.loc, "declaration `%s` is already defined", s.toPrettyChars()); errorSupplemental(conflict.loc, "`%s` `%s` is defined here", conflict.kind(), conflict.toChars()); } @@ -6277,7 +6332,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; auto loc = adjustLocForMixin(str, exp.loc, global.params.mixinOut); scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); - p.transitionIn = global.params.vin; + p.transitionIn = global.params.v.vin; p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); @@ -6287,9 +6342,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (p.token.value != TOK.endOfFile) { - e.error("unexpected token `%s` after %s expression", + error(e.loc, "unexpected token `%s` after %s expression", p.token.toChars(), EXPtoString(e.op).ptr); - e.errorSupplemental("while parsing string mixin expression `%s`", + errorSupplemental(e.loc, "while parsing string mixin expression `%s`", str.ptr); return null; } @@ -6327,7 +6382,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor auto namez = se.toStringz(); if (!global.filePath) { - e.error("need `-J` switch to import text file `%s`", namez.ptr); + error(e.loc, "need `-J` switch to import text file `%s`", namez.ptr); return setError(); } @@ -6338,41 +6393,41 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (FileName.absolute(namez)) { - e.error("absolute path is not allowed in import expression: `%s`", se.toChars()); + error(e.loc, "absolute path is not allowed in import expression: `%s`", se.toChars()); return setError(); } auto idxReserved = FileName.findReservedChar(namez); if (idxReserved != size_t.max) { - e.error("`%s` is not a valid filename on this platform", se.toChars()); - e.errorSupplemental("Character `'%c'` is reserved and cannot be used", namez[idxReserved]); + error(e.loc, "`%s` is not a valid filename on this platform", se.toChars()); + errorSupplemental(e.loc, "Character `'%c'` is reserved and cannot be used", namez[idxReserved]); return setError(); } if (FileName.refersToParentDir(namez)) { - e.error("path refers to parent (`..`) directory: `%s`", se.toChars()); + error(e.loc, "path refers to parent (`..`) directory: `%s`", se.toChars()); return setError(); } auto resolvedNamez = FileName.searchPath(global.filePath, namez, false); if (!resolvedNamez) { - e.error("file `%s` cannot be found or not in a path specified with `-J`", se.toChars()); - e.errorSupplemental("Path(s) searched (as provided by `-J`):"); + error(e.loc, "file `%s` cannot be found or not in a path specified with `-J`", se.toChars()); + errorSupplemental(e.loc, "Path(s) searched (as provided by `-J`):"); foreach (idx, path; *global.filePath) { const attr = FileName.exists(path); const(char)* err = attr == 2 ? "" : (attr == 1 ? " (not a directory)" : " (path not found)"); - e.errorSupplemental("[%llu]: `%s`%s", cast(ulong)idx, path, err); + errorSupplemental(e.loc, "[%llu]: `%s`%s", cast(ulong)idx, path, err); } return setError(); } sc._module.contentImportedFiles.push(resolvedNamez.ptr); - if (global.params.verbose) + if (global.params.v.verbose) { const slice = se.peekString(); message("file %.*s\t(%s)", cast(int)slice.length, slice.ptr, resolvedNamez.ptr); @@ -6409,7 +6464,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - e.error("cannot read file `%s`", resolvedNamez.ptr); + error(e.loc, "cannot read file `%s`", resolvedNamez.ptr); return setError(); } } @@ -6427,7 +6482,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor const generateMsg = !exp.msg && sc.needsCodegen() && // let ctfe interpreter handle the error message global.params.checkAction == CHECKACTION.context && - global.params.useAssert == CHECKENABLE.on; + global.params.useAssert == CHECKENABLE.on && + !((exp.e1.isIntegerExp() && (exp.e1.toInteger() == 0)) || + exp.e1.isNullExp()); Expression temporariesPrefix; if (generateMsg) @@ -6776,7 +6833,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor dmd.typesem.resolve(exp.e1.type, exp.e1.loc, sc, e, t, s, true); if (e) { - exp.e1.error("argument to `_Alignof` must be a type"); + error(exp.e1.loc, "argument to `_Alignof` must be a type"); return setError(); } else if (t) @@ -6789,7 +6846,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (s) { - exp.e1.error("argument to `_Alignof` must be a type"); + error(exp.e1.loc, "argument to `_Alignof` must be a type"); return setError(); } else @@ -6908,7 +6965,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e = new TypeExp(exp.loc, cast(Type)o); break; default: - exp.error("`%s` is not an expression", o.toChars()); + error(exp.loc, "`%s` is not an expression", o.toChars()); return setError(); } if (var) @@ -7071,7 +7128,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor OutBuffer thisBuf, funcBuf; MODMatchToBuffer(&thisBuf, e.e1.type.mod, tf.mod); MODMatchToBuffer(&funcBuf, tf.mod, e.e1.type.mod); - e.error("%smethod `%s` is not callable using a %s`%s`", + error(e.loc, "%smethod `%s` is not callable using a %s`%s`", funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toChars()); return setError(); } @@ -7095,7 +7152,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor te = getRightThis(e.loc, sc, ad2, te, f); if (te.op == EXP.error) { - e.error("need `this` of type `%s` to make delegate from function `%s`", ad2.toChars(), f.toChars()); + error(e.loc, "need `this` of type `%s` to make delegate from function `%s`", ad2.toChars(), f.toChars()); return setError(); } } @@ -7267,7 +7324,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!exp.e1.type) { - exp.error("cannot take address of `%s`", exp.e1.toChars()); + error(exp.loc, "cannot take address of `%s`", exp.e1.toChars()); return setError(); } if (!checkAddressable(exp, sc)) @@ -7288,10 +7345,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (auto ve = exp.e1.isVarExp()) { Declaration d = ve.var; - exp.error("forward reference to %s `%s`", d.kind(), d.toChars()); + error(exp.loc, "forward reference to %s `%s`", d.kind(), d.toChars()); } else - exp.error("forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toChars()); + error(exp.loc, "forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toChars()); return setError(); } } @@ -7461,7 +7518,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor case Tarray: if (isNonAssignmentArrayOp(exp.e1)) goto default; - exp.error("using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toChars()); + error(exp.loc, "using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toChars()); exp.type = (cast(TypeArray)tb).next; exp.e1 = exp.e1.castTo(sc, exp.type.pointerTo()); break; @@ -7474,7 +7531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor break; default: - exp.error("can only `*` a pointer, not a `%s`", exp.e1.type.toChars()); + error(exp.loc, "can only `*` a pointer, not a `%s`", exp.e1.type.toChars()); goto case Terror; } @@ -7688,7 +7745,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor * `isRAII` has been set to true for the deletion of a `scope class`. */ if (tb.ty != Tclass) { - exp.error("cannot delete type `%s`", exp.e1.type.toChars()); + error(exp.loc, "cannot delete type `%s`", exp.e1.type.toChars()); return setError(); } @@ -7697,7 +7754,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { /* Because COM classes are deleted by IUnknown.Release() */ - exp.error("cannot `delete` instance of COM interface `%s`", cd.toChars()); + error(exp.loc, "cannot `delete` instance of COM interface `%s`", cd.toChars()); return setError(); } @@ -7801,7 +7858,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!exp.e1.type) { - exp.error("cannot cast `%s`", exp.e1.toChars()); + error(exp.loc, "cannot cast `%s`", exp.e1.toChars()); return setError(); } @@ -7839,7 +7896,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.to.ty == Ttuple) { - exp.error("cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars()); + error(exp.loc, "cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars()); return setError(); } @@ -8022,7 +8079,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (elem.isConst() == 1) return false; - exp.error("constant expression expected, not `%s`", elem.toChars()); + error(exp.loc, "constant expression expected, not `%s`", elem.toChars()); return true; } @@ -8087,7 +8144,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (exp.lwr || exp.upr) { - exp.error("cannot slice type `%s`", exp.e1.toChars()); + error(exp.loc, "cannot slice type `%s`", exp.e1.toChars()); return setError(); } Expression e = new TypeExp(exp.loc, exp.e1.type.arrayOf()); @@ -8139,12 +8196,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (t1b.isPtrToFunction()) { - exp.error("cannot slice function pointer `%s`", exp.e1.toChars()); + error(exp.loc, "cannot slice function pointer `%s`", exp.e1.toChars()); return setError(); } if (!exp.lwr || !exp.upr) { - exp.error("upper and lower bounds are needed to slice a pointer"); + error(exp.loc, "upper and lower bounds are needed to slice a pointer"); if (auto ad = isAggregate(tp.next.toBasetype())) { auto s = search_function(ad, Id.index); @@ -8154,7 +8211,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor auto fd = s.isFuncDeclaration(); if ((fd && !fd.getParameterList().length) || s.isTemplateDeclaration()) { - exp.errorSupplemental( + errorSupplemental(exp.loc, "pointer `%s` points to an aggregate that defines an `%s`, perhaps you meant `(*%s)[]`", exp.e1.toChars(), s.ident.toChars(), @@ -8185,7 +8242,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (!exp.lwr || !exp.upr) { - exp.error("need upper and lower bound to slice a sequence"); + error(exp.loc, "need upper and lower bound to slice a sequence"); return setError(); } } @@ -8199,7 +8256,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - exp.error("`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars()); + error(exp.loc, "`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars()); return setError(); } @@ -8265,7 +8322,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (i2 < i1 || length < i2) { - exp.error("string slice `[%llu .. %llu]` is out of bounds", i1, i2); + error(exp.loc, "string slice `[%llu .. %llu]` is out of bounds", i1, i2); return setError(); } @@ -8405,13 +8462,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (isAggregate(exp.e1.type)) - exp.error("no `[]` operator overload for type `%s`", exp.e1.type.toChars()); + error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars()); else if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple) - exp.error("static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars()); + error(exp.loc, "static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars()); else if (isIndexableNonAggregate(exp.e1.type)) - exp.error("only one index allowed to index `%s`", exp.e1.type.toChars()); + error(exp.loc, "only one index allowed to index `%s`", exp.e1.type.toChars()); else - exp.error("cannot use `[]` operator on expression of type `%s`", exp.e1.type.toChars()); + error(exp.loc, "cannot use `[]` operator on expression of type `%s`", exp.e1.type.toChars()); result = ErrorExp.get(); } @@ -8489,7 +8546,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor discardValue(e.e1); } else if (!e.allowCommaExp && !e.isGenerated) - e.error("using the result of a comma expression is not allowed"); + error(e.loc, "using the result of a comma expression is not allowed"); } override void visit(IntervalExp e) @@ -8660,7 +8717,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor case Tpointer: if (t1b.isPtrToFunction()) { - exp.error("cannot index function pointer `%s`", exp.e1.toChars()); + error(exp.loc, "cannot index function pointer `%s`", exp.e1.toChars()); return setError(); } exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t); @@ -8742,7 +8799,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (length <= index) { - exp.error("array index `[%llu]` is outside array bounds `[0 .. %llu]`", index, cast(ulong)length); + error(exp.loc, "array index `[%llu]` is outside array bounds `[0 .. %llu]`", index, cast(ulong)length); return setError(); } Expression e; @@ -8757,7 +8814,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } default: - exp.error("`%s` must be an array or pointer type, not `%s`", exp.e1.toChars(), exp.e1.type.toChars()); + error(exp.loc, "`%s` must be an array or pointer type, not `%s`", exp.e1.toChars(), exp.e1.type.toChars()); return setError(); } @@ -8847,7 +8904,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e1.op == EXP.slice) { const(char)* s = exp.op == EXP.plusPlus ? "increment" : "decrement"; - exp.error("cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toChars(), s); + error(exp.loc, "cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toChars(), s); return setError(); } @@ -8987,7 +9044,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (auto e2comma = exp.e2.isCommaExp()) { if (!e2comma.isGenerated && !(sc.flags & SCOPE.Cfile)) - exp.error("using the result of a comma expression is not allowed"); + error(exp.loc, "using the result of a comma expression is not allowed"); /* Rewrite to get rid of the comma from rvalue * e1=(e0,e2) => e0,(e1=e2) @@ -9230,7 +9287,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Expression e = null; if (dim != tup2.exps.length) { - exp.error("mismatched sequence lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length); + error(exp.loc, "mismatched sequence lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length); return setError(); } if (dim == 0) @@ -9462,7 +9519,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!e2x.type.implicitConvTo(e1x.type)) { - exp.error("conversion error from `%s` to `%s`", + error(exp.loc, "conversion error from `%s` to `%s`", e2x.type.toChars(), e1x.type.toChars()); return setError(); } @@ -9780,7 +9837,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (dim1 != dim2) { - exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); + error(exp.loc, "mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); return setError(); } } @@ -9810,7 +9867,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (overflow || dim >= uint.max) { // dym exceeds maximum array size - exp.error("static array `%s` size overflowed to %llu", + error(exp.loc, "static array `%s` size overflowed to %llu", e1x.type.toChars(), cast(ulong) dim); return setError(); } @@ -9914,13 +9971,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // https://issues.dlang.org/show_bug.cgi?id=9884 (!fun || (fun && !fun.isStaticCtorDeclaration()))) { - exp.error("slice `%s` is not mutable", se.toChars()); + error(exp.loc, "slice `%s` is not mutable", se.toChars()); return setError(); } if (exp.op == EXP.assign && !tn.baseElemOf().isAssignable()) { - exp.error("slice `%s` is not mutable, struct `%s` has immutable members", + error(exp.loc, "slice `%s` is not mutable, struct `%s` has immutable members", exp.e1.toChars(), tn.baseElemOf().toChars()); result = ErrorExp.get(); return; @@ -9943,7 +10000,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type tn = exp.e1.type.nextOf(); if (tn && !tn.baseElemOf().isAssignable()) { - exp.error("array `%s` is not mutable, struct `%s` has immutable members", + error(exp.loc, "array `%s` is not mutable, struct `%s` has immutable members", exp.e1.toChars(), tn.baseElemOf().toChars()); result = ErrorExp.get(); return; @@ -10014,7 +10071,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor uinteger_t dim2 = tsa2.dim.toInteger(); if (dim1 != dim2) { - exp.error("mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars()); + error(exp.loc, "mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars()); return setError(); } } @@ -10179,13 +10236,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (vd && vd.onstack) { assert(t1.ty == Tclass); - exp.error("cannot rebind scope variables"); + error(exp.loc, "cannot rebind scope variables"); } } if (exp.e1.op == EXP.variable && (cast(VarExp)exp.e1).var.ident == Id.ctfe) { - exp.error("cannot modify compiler-generated variable `__ctfe`"); + error(exp.loc, "cannot modify compiler-generated variable `__ctfe`"); } exp.type = exp.e1.type; @@ -10287,7 +10344,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor res = Expression.combine(e0, ce).expressionSemantic(sc); } - if (global.params.verbose) + if (global.params.v.verbose) message("lowered %s =>\n %s", exp.toChars(), res.toChars()); } } @@ -10377,7 +10434,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (isArrayAssign) res = Expression.combine(res, ae.e1).expressionSemantic(sc); - if (global.params.verbose) + if (global.params.v.verbose) message("lowered %s =>\n %s", ae.toChars(), res.toChars()); res = new LoweredAssignExp(ae, res); @@ -10490,7 +10547,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (se.e1.type.toBasetype().ty == Tsarray) { - exp.error("cannot append to static array `%s`", se.e1.type.toChars()); + error(exp.loc, "cannot append to static array `%s`", se.e1.type.toChars()); return setError(); } } @@ -10614,7 +10671,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (result) return; - exp.error("cannot append type `%s` to type `%s`", tb2.toChars(), tb1.toChars()); + error(exp.loc, "cannot append type `%s` to type `%s`", tb2.toChars(), tb1.toChars()); return setError(); } @@ -10960,7 +11017,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e = scaleFactor(exp, sc); else { - exp.error("can't subtract `%s` from pointer", t2.toChars()); + error(exp.loc, "can't subtract `%s` from pointer", t2.toChars()); e = ErrorExp.get(); } result = e; @@ -10969,7 +11026,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (t2.ty == Tpointer) { exp.type = exp.e2.type; - exp.error("can't subtract pointer from `%s`", exp.e1.type.toChars()); + error(exp.loc, "can't subtract pointer from `%s`", exp.e1.type.toChars()); return setError(); } @@ -11546,7 +11603,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.type = exp.e1.type; if (exp.e2.type.iscomplex()) { - exp.error("cannot perform modulo complex arithmetic"); + error(exp.loc, "cannot perform modulo complex arithmetic"); return setError(); } } @@ -11613,7 +11670,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Module mmath = Module.loadStdMath(); if (!mmath) { - e.error("`%s` requires `std.math` for `^^` operators", e.toChars()); + error(e.loc, "`%s` requires `std.math` for `^^` operators", e.toChars()); return setError(); } e = new ScopeExp(exp.loc, mmath); @@ -11968,7 +12025,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (e2x.op == EXP.type || e2x.op == EXP.scope_) { - exp.error("`%s` is not an expression", exp.e2.toChars()); + error(exp.loc, "`%s` is not an expression", exp.e2.toChars()); return setError(); } if (e1x.op == EXP.error || e1x.type.ty == Tnoreturn) @@ -12017,7 +12074,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type t2 = exp.e2.type.toBasetype(); if (t1.ty == Tclass && exp.e2.op == EXP.null_ || t2.ty == Tclass && exp.e1.op == EXP.null_) { - exp.error("do not use `null` when comparing class types"); + error(exp.loc, "do not use `null` when comparing class types"); return setError(); } @@ -12027,7 +12084,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!e.type.isscalar() && e.type.equals(exp.e1.type)) { - exp.error("recursive `opCmp` expansion"); + error(exp.loc, "recursive `opCmp` expansion"); return setError(); } if (e.op == EXP.call) @@ -12095,7 +12152,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type t2next = t2.nextOf(); if (t1next.implicitConvTo(t2next) < MATCH.constant && t2next.implicitConvTo(t1next) < MATCH.constant && (t1next.ty != Tvoid && t2next.ty != Tvoid)) { - exp.error("array comparison type mismatch, `%s` vs `%s`", t1next.toChars(), t2next.toChars()); + error(exp.loc, "array comparison type mismatch, `%s` vs `%s`", t1next.toChars(), t2next.toChars()); return setError(); } @@ -12124,19 +12181,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (t1.ty == Tstruct || t2.ty == Tstruct || (t1.ty == Tclass && t2.ty == Tclass)) { if (t2.ty == Tstruct) - exp.error("need member function `opCmp()` for %s `%s` to compare", t2.toDsymbol(sc).kind(), t2.toChars()); + error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t2.toDsymbol(sc).kind(), t2.toChars()); else - exp.error("need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars()); + error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars()); return setError(); } else if (t1.iscomplex() || t2.iscomplex()) { - exp.error("compare not defined for complex operands"); + error(exp.loc, "compare not defined for complex operands"); return setError(); } else if (t1.ty == Taarray || t2.ty == Taarray) { - exp.error("`%s` is not defined for associative arrays", EXPtoString(exp.op).ptr); + error(exp.loc, "`%s` is not defined for associative arrays", EXPtoString(exp.op).ptr); return setError(); } else if (!target.isVectorOpSupported(t1, exp.op, t2)) @@ -12213,9 +12270,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor case Tarray, Tsarray: result = exp.incompatibleTypes(); - exp.errorSupplemental("`in` is only allowed on associative arrays"); + errorSupplemental(exp.loc, "`in` is only allowed on associative arrays"); const(char)* slice = (t2b.ty == Tsarray) ? "[]" : ""; - exp.errorSupplemental("perhaps use `std.algorithm.find(%s, %s%s)` instead", + errorSupplemental(exp.loc, "perhaps use `std.algorithm.find(%s, %s%s)` instead", exp.e1.toChars(), exp.e2.toChars(), slice); return; @@ -12293,7 +12350,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor auto t1 = exp.e1.type; auto t2 = exp.e2.type; if (t1.ty == Tenum && t2.ty == Tenum && !t1.equivalent(t2)) - exp.error("comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`", + error(exp.loc, "comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`", t1.toChars(), t2.toChars()); } @@ -12435,7 +12492,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor __equals = __equals.trySemantic(sc); // for better error message if (!__equals) { - exp.error("incompatible types for array comparison: `%s` and `%s`", + error(exp.loc, "incompatible types for array comparison: `%s` and `%s`", exp.e1.type.toChars(), exp.e2.type.toChars()); __equals = ErrorExp.get(); } @@ -12517,7 +12574,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e1.type.toBasetype().ty == Tsarray || exp.e2.type.toBasetype().ty == Tsarray) - exp.deprecation("identity comparison of static arrays " + deprecation(exp.loc, "identity comparison of static arrays " ~ "implicitly coerces them to slices, " ~ "which are compared by reference"); @@ -12936,7 +12993,7 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) if (f.purityInprocess || f.safetyInprocess || f.nothrowInprocess || f.nogcInprocess) { - f.error(loc, "cannot retrieve its `.mangleof` while inferring attributes"); + error(loc, "%s `%s` cannot retrieve its `.mangleof` while inferring attributes", f.kind, f.toPrettyChars); return ErrorExp.get(); } } @@ -13002,12 +13059,12 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) // Template has no built-in properties except for 'stringof'. if ((exp.e1.isDotTemplateExp() || exp.e1.isTemplateExp()) && exp.ident != Id.stringof) { - exp.error("template `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars()); + error(exp.loc, "template `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars()); return ErrorExp.get(); } if (!exp.e1.type) { - exp.error("expression `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars()); + error(exp.loc, "expression `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars()); return ErrorExp.get(); } @@ -13121,9 +13178,9 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) !v.type.deco && v.inuse) { if (v.inuse) - exp.error("circular reference to %s `%s`", v.kind(), v.toPrettyChars()); + error(exp.loc, "circular reference to %s `%s`", v.kind(), v.toPrettyChars()); else - exp.error("forward reference to %s `%s`", v.kind(), v.toPrettyChars()); + error(exp.loc, "forward reference to %s `%s`", v.kind(), v.toPrettyChars()); return ErrorExp.get(); } if (v.type.isTypeError()) @@ -13284,12 +13341,12 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) if (s && symbolIsVisible(sc, s)) { if (s.isPackage()) - exp.error("undefined identifier `%s` in %s `%s`, perhaps add `static import %s;`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.toPrettyChars()); + error(exp.loc, "undefined identifier `%s` in %s `%s`, perhaps add `static import %s;`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.toPrettyChars()); else - exp.error("undefined identifier `%s` in %s `%s`, did you mean %s `%s`?", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.kind(), s.toChars()); + error(exp.loc, "undefined identifier `%s` in %s `%s`, did you mean %s `%s`?", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.kind(), s.toChars()); } else - exp.error("undefined identifier `%s` in %s `%s`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars()); + error(exp.loc, "undefined identifier `%s` in %s `%s`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars()); return ErrorExp.get(); } else if (t1b.ty == Tpointer && exp.e1.type.ty != Tenum && @@ -13544,7 +13601,7 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool g } Lerr: - exp.error("`%s` isn't a template", e.toChars()); + error(exp.loc, "`%s` isn't a template", e.toChars()); return errorExp(); } @@ -13578,7 +13635,7 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) bool sharedError(Expression e) { // https://dlang.org/phobos/core_atomic.html - e.error("direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars()); + error(e.loc, "direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars()); return true; } @@ -13737,7 +13794,7 @@ bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v) if (!v.canTakeAddressOf()) { - exp.error("cannot take address of `%s`", exp.toChars()); + error(exp.loc, "cannot take address of `%s`", exp.toChars()); return false; } if (sc.func && !sc.intypeof && !v.isDataseg()) @@ -13774,7 +13831,7 @@ bool checkAddressable(Expression e, Scope* sc) // whether SCOPE.Cfile is set. if (auto bf = ex.isDotVarExp().var.isBitFieldDeclaration()) { - e.error("cannot take address of bit-field `%s`", bf.toChars()); + error(e.loc, "cannot take address of bit-field `%s`", bf.toChars()); return false; } goto case EXP.cast_; @@ -13799,9 +13856,9 @@ bool checkAddressable(Expression e, Scope* sc) if (ex.isVarExp().var.storage_class & STC.register) { if (e.isIndexExp()) - e.error("cannot index through register variable `%s`", ex.toChars()); + error(e.loc, "cannot index through register variable `%s`", ex.toChars()); else - e.error("cannot take address of register variable `%s`", ex.toChars()); + error(e.loc, "cannot take address of register variable `%s`", ex.toChars()); return false; } } @@ -13881,7 +13938,7 @@ Expression getThisSkipNestedFuncs(const ref Loc loc, Scope* sc, Dsymbol s, Aggre { if (flag) return null; - e1.error("need `this` of type `%s` to access member `%s` from static function `%s`", ad.toChars(), var.toChars(), f.toChars()); + error(e1.loc, "need `this` of type `%s` to access member `%s` from static function `%s`", ad.toChars(), var.toChars(), f.toChars()); e1 = ErrorExp.get(); return e1; } @@ -14116,7 +14173,7 @@ Expression toBoolean(Expression exp, Scope* sc) switch(exp.op) { case EXP.delete_: - exp.error("`delete` does not give a boolean result"); + error(exp.loc, "`delete` does not give a boolean result"); return ErrorExp.get(); case EXP.comma: @@ -14137,7 +14194,7 @@ Expression toBoolean(Expression exp, Scope* sc) // Things like: // if (a = b) ... // are usually mistakes. - exp.error("assignment cannot be used as a condition, perhaps `==` was meant?"); + error(exp.loc, "assignment cannot be used as a condition, perhaps `==` was meant?"); return ErrorExp.get(); //LogicalExp @@ -14201,7 +14258,7 @@ Expression toBoolean(Expression exp, Scope* sc) if (!t.isBoolean()) { if (tb != Type.terror) - exp.error("expression `%s` of type `%s` does not have a boolean value", + error(exp.loc, "expression `%s` of type `%s` does not have a boolean value", exp.toChars(), t.toChars()); return ErrorExp.get(); } diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index bf7ad7ee8d5d..81bb028964fb 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -744,7 +744,7 @@ extern (C++) class FuncDeclaration : Declaration if (exactvi >= 0) { - error("cannot determine overridden function"); + .error(loc, "%s `%s` cannot determine overridden function", kind, toPrettyChars); return exactvi; } exactvi = vi; @@ -1057,7 +1057,7 @@ extern (C++) class FuncDeclaration : Declaration OutBuffer thisBuf, funcBuf; MODMatchToBuffer(&thisBuf, tthis.mod, tf.mod); MODMatchToBuffer(&funcBuf, tf.mod, tthis.mod); - .error(loc, "%smethod %s is not callable using a %sobject", + .error(loc, "%smethod %s is not callable using a %sobject", kind, toPrettyChars, funcBuf.peekChars(), this.toPrettyChars(), thisBuf.peekChars()); } } @@ -1696,7 +1696,7 @@ extern (C++) class FuncDeclaration : Declaration extern (D) final void printGCUsage(const ref Loc loc, const(char)* warn) { - if (!global.params.vgc) + if (!global.params.v.gc) return; Module m = getModule(); @@ -2240,13 +2240,13 @@ extern (C++) class FuncDeclaration : Declaration if (setGC(loc, "%s `%s` is `@nogc` yet allocates closure for `%s()` with the GC", this)) { - error("is `@nogc` yet allocates closure for `%s()` with the GC", toChars()); + .error(loc, "%s `%s` is `@nogc` yet allocates closure for `%s()` with the GC", kind, toPrettyChars, toChars()); if (global.gag) // need not report supplemental errors return true; } else if (!global.params.useGC) { - error("is `-betterC` yet allocates closure for `%s()` with the GC", toChars()); + .error(loc, "%s `%s` is `-betterC` yet allocates closure for `%s()` with the GC", kind, toPrettyChars, toChars()); if (global.gag) // need not report supplemental errors return true; } @@ -2370,7 +2370,7 @@ extern (C++) class FuncDeclaration : Declaration vresult.dsymbolSemantic(sc); if (!sc.insert(vresult)) - error("out result %s is already defined", vresult.toChars()); + .error(loc, "%s `%s` out result %s is already defined", kind, toPrettyChars, vresult.toChars()); assert(vresult.parent == this); } } @@ -2877,7 +2877,7 @@ extern (C++) class FuncDeclaration : Declaration } if (tf.parameterList.varargs || nparams >= 2 || argerr) - error("parameter list must be empty or accept one parameter of type `string[]`"); + .error(loc, "%s `%s` parameter list must be empty or accept one parameter of type `string[]`", kind, toPrettyChars); } else if (linkage == LINK.c) @@ -2912,7 +2912,7 @@ extern (C++) class FuncDeclaration : Declaration if (argerr) { - error("parameters must match one of the following signatures"); + .error(loc, "%s `%s` parameters must match one of the following signatures", kind, toPrettyChars); loc.errorSupplemental("`main()`"); loc.errorSupplemental("`main(int argc, char** argv)`"); loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]"); @@ -2925,7 +2925,7 @@ extern (C++) class FuncDeclaration : Declaration retType = retType.toBasetype(); if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn) - error("must return `int`, `void` or `noreturn`, not `%s`", tf.nextOf().toChars()); + .error(loc, "%s `%s` must return `int`, `void` or `noreturn`, not `%s`", kind, toPrettyChars, tf.nextOf().toChars()); } /*********************************************** @@ -3110,7 +3110,7 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Sco } else { - d.error("is aliased to a function"); + .error(d.loc, "%s `%s` is aliased to a function", d.kind, d.toPrettyChars); break; } next = fa.overnext; @@ -3149,7 +3149,7 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Sco } else { - d.error("is aliased to a function"); + .error(d.loc, "%s `%s` is aliased to a function", d.kind, d.toPrettyChars); break; // BUG: should print error message? } @@ -3391,7 +3391,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, td.kind(), td.parent.toPrettyChars(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars()); - if (!global.gag || global.params.showGaggedErrors) + if (!global.gag || global.params.v.showGaggedErrors) printCandidates(loc, td, sc.isDeprecated()); return null; } @@ -3430,7 +3430,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, { .error(loc, "none of the overloads of `%s` are callable using a %sobject", fd.ident.toChars(), thisBuf.peekChars()); - if (!global.gag || global.params.showGaggedErrors) + if (!global.gag || global.params.v.showGaggedErrors) printCandidates(loc, fd, sc.isDeprecated()); return null; } @@ -3461,7 +3461,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, { .error(loc, "none of the overloads of `%s` are callable using argument types `%s`", fd.toChars(), fargsBuf.peekChars()); - if (!global.gag || global.params.showGaggedErrors) + if (!global.gag || global.params.v.showGaggedErrors) printCandidates(loc, fd, sc.isDeprecated()); return null; } @@ -3471,7 +3471,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, tf.modToChars(), fargsBuf.peekChars()); // re-resolve to check for supplemental message - if (!global.gag || global.params.showGaggedErrors) + if (!global.gag || global.params.v.showGaggedErrors) { if (tthis) { @@ -3514,9 +3514,7 @@ private void printCandidates(Decl)(const ref Loc loc, Decl declaration, bool sho if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) { // max num of overloads to print (-v or -verror-supplements overrides this). - const int DisplayLimit = !global.params.verbose ? - (global.params.errorSupplementLimit ? global.params.errorSupplementLimit : int.max) - : int.max; + const uint DisplayLimit = global.params.v.errorSupplementCount(); const(char)* constraintsTip; // determine if the first candidate was printed int printed; @@ -3580,7 +3578,7 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) }); int skipped = 0; overloadApply(declaration, (s) { - if (global.params.verbose || printed < DisplayLimit) + if (global.params.v.verbose || printed < DisplayLimit) { if (matchSymbol(s, true, count == 1)) printed++; diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 840074e5d8f3..2f6fae3a1ab0 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -118,6 +118,38 @@ extern(C++) struct Help bool hc; // -HC } +extern(C++) struct Verbose +{ + bool verbose; // verbose compile + bool showColumns; // print character (column) numbers in diagnostics + bool tls; // identify thread local variables + bool templates; // collect and list statistics on template instantiations + // collect and list statistics on template instantiations origins. + // TODO: make this an enum when we want to list other kinds of instances + bool templatesListInstances; + bool gc; // identify gc usage + bool field; // identify non-mutable field variables + bool complex = true; // identify complex/imaginary type usage + bool vin; // identify 'in' parameters + bool showGaggedErrors; // print gagged errors anyway + bool printErrorContext; // print errors with the error context (the error line in the source file) + bool logo; // print compiler logo + bool color; // use ANSI colors in console output + bool cov; // generate code coverage data + MessageStyle messageStyle = MessageStyle.digitalmars; // style of file/line annotations on messages + uint errorLimit = 20; + uint errorSupplementLimit = 6; // Limit the number of supplemental messages for each error (0 means unlimited) + + uint errorSupplementCount() + { + if (verbose) + return uint.max; + if (errorSupplementLimit == 0) + return uint.max; + return errorSupplementLimit; + } +} + /// Put command line switches in here extern (C++) struct Param { @@ -125,23 +157,13 @@ extern (C++) struct Param bool multiobj; // break one object file into multiple ones bool trace; // insert profiling hooks bool tracegc; // instrument calls to 'new' - bool verbose; // verbose compile bool vcg_ast; // write-out codegen-ast - bool showColumns; // print character (column) numbers in diagnostics - bool vtls; // identify thread local variables - bool vtemplates; // collect and list statistics on template instantiations - 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 = true; // identify complex/imaginary type usage - bool vin; // identify 'in' parameters DiagnosticReporting useDeprecated = DiagnosticReporting.inform; // how use of deprecated features are handled bool useUnitTests; // generate unittest code bool useInline = false; // inline expand functions bool release; // build release version bool preservePaths; // true means don't strip path from source file DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled - bool color; // use ANSI colors in console output bool cov; // generate code coverage data ubyte covPercent; // 0..100 code coverage percentage required bool ctfe_cov = false; // generate coverage data for ctfe @@ -157,10 +179,8 @@ extern (C++) struct Param CppStdRevision cplusplus = CppStdRevision.cpp11; // version of C++ standard to support - bool showGaggedErrors; // print gagged errors anyway - bool printErrorContext; // print errors with the error context (the error line in the source file) Help help; - bool logo; // print compiler logo + Verbose v; // Options for `-preview=/-revert=` FeatureState useDIP25 = FeatureState.enabled; // implement https://wiki.dlang.org/DIP25 @@ -195,9 +215,6 @@ extern (C++) struct Param CHECKACTION checkAction = CHECKACTION.D; // action to take when bounds, asserts or switch defaults are violated - uint errorLimit = 20; - uint errorSupplementLimit = 6; // Limit the number of supplemental messages for each error (0 means unlimited) - const(char)[] argv0; // program name Array!(const(char)*) modFileAliasStrings; // array of char*'s of -I module filename alias strings Array!(const(char)*)* imppath; // array of char*'s of where to look for import modules @@ -216,13 +233,7 @@ extern (C++) struct Param Output moduleDeps; // Generate `.deps` module dependencies uint debuglevel; // debug level - Array!(const(char)*)* debugids; // debug identifiers - uint versionlevel; // version level - Array!(const(char)*)* versionids; // version identifiers - - - MessageStyle messageStyle = MessageStyle.digitalmars; // style of file/line annotations on messages bool run; // run resulting executable Strings runargs; // arguments for executable @@ -355,7 +366,7 @@ extern (C++) struct Global // -color=auto is the default value import dmd.console : detectTerminal, detectColorPreference; - params.color = detectTerminal() && detectColorPreference(); + params.v.color = detectTerminal() && detectColorPreference(); } else version (IN_GCC) { diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index e24042a4f21d..4048286ce715 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -112,6 +112,30 @@ struct Help d_bool hc; // -HC }; +struct Verbose +{ + d_bool verbose; // verbose compile + d_bool showColumns; // print character (column) numbers in diagnostics + d_bool tls; // identify thread local variables + d_bool templates; // collect and list statistics on template instantiations + // collect and list statistics on template instantiations origins. + // TODO: make this an enum when we want to list other kinds of instances + d_bool templatesListInstances; + d_bool gc; // identify gc usage + d_bool field; // identify non-mutable field variables + d_bool complex = true; // identify complex/imaginary type usage + d_bool vin; // identify 'in' parameters + d_bool showGaggedErrors; // print gagged errors anyway + d_bool printErrorContext; // print errors with the error context (the error line in the source file) + d_bool logo; // print compiler logo + d_bool color; // use ANSI colors in console output + d_bool cov; // generate code coverage data + MessageStyle messageStyle; // style of file/line annotations on messages + unsigned errorLimit; + unsigned errorSupplementLimit; // Limit the number of supplemental messages for each error (0 means unlimited) + unsigned errorSupplementCount(); +}; + // Put command line switches in here struct Param { @@ -119,23 +143,13 @@ struct Param d_bool multiobj; // break one object file into multiple ones d_bool trace; // insert profiling hooks d_bool tracegc; // instrument calls to 'new' - d_bool verbose; // verbose compile d_bool vcg_ast; // write-out codegen-ast - d_bool showColumns; // print character (column) numbers in diagnostics - d_bool vtls; // identify thread local variables - d_bool vtemplates; // collect and list statistics on template instantiations - d_bool vtemplatesListInstances; // collect and list statistics on template instantiations origins - d_bool vgc; // identify gc usage - d_bool vfield; // identify non-mutable field variables - d_bool vcomplex; // identify complex/imaginary type usage - d_bool vin; // identify 'in' parameters Diagnostic useDeprecated; d_bool useUnitTests; // generate unittest code d_bool useInline; // inline expand functions d_bool release; // build release version d_bool preservePaths; // true means don't strip path from source file Diagnostic warnings; - d_bool color; // use ANSI colors in console output d_bool cov; // generate code coverage data unsigned char covPercent; // 0..100 code coverage percentage required d_bool ctfe_cov; // generate coverage data for ctfe @@ -149,10 +163,9 @@ struct Param d_bool allInst; // generate code for all template instantiations d_bool bitfields; // support C style bit fields CppStdRevision cplusplus; // version of C++ name mangling to support - d_bool showGaggedErrors; // print gagged errors anyway - d_bool printErrorContext; // print errors with the error context (the error line in the source file) + Help help; - d_bool logo; // print logo; + Verbose v; // Options for `-preview=/-revert=` FeatureState useDIP25; // implement https://wiki.dlang.org/DIP25 @@ -187,9 +200,6 @@ struct Param CHECKACTION checkAction; // action to take when bounds, asserts or switch defaults are violated - unsigned errorLimit; - unsigned errorSupplementLimit; // Limit the number of supplemental messages for each error (0 means unlimited) - DString argv0; // program name Array modFileAliasStrings; // array of char*'s of -I module filename alias strings Array *imppath; // array of char*'s of where to look for import modules @@ -208,13 +218,7 @@ struct Param Output moduleDeps; // Generate `.deps` module dependencies unsigned debuglevel; // debug level - Array *debugids; // debug identifiers - unsigned versionlevel; // version level - Array *versionids; // version identifiers - - - MessageStyle messageStyle; // style of file/line annotations on messages d_bool run; // run resulting executable Strings runargs; // arguments for executable diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index b4c8e8b899b5..056e486e927a 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -88,6 +88,39 @@ extern (C++) void genhdrfile(Module m, ref OutBuffer buf) toCBuffer(m, buf, hgs); } +/*************************************** + * Turn a Statement into a string suitable for printf. + * Leaks memory. + * Params: + * s = Statement to convert + * Returns: + * 0-terminated string + */ +public extern (C++) const(char)* toChars(const Statement s) +{ + HdrGenState hgs; + OutBuffer buf; + toCBuffer(s, buf, hgs); + buf.writeByte(0); + return buf.extractSlice().ptr; +} + +public extern (C++) const(char)* toChars(const Initializer i) +{ + OutBuffer buf; + HdrGenState hgs; + toCBuffer(i, buf, hgs); + return buf.extractChars(); +} + +public const(char)[] toString(const Initializer i) +{ + OutBuffer buf; + HdrGenState hgs; + toCBuffer(i, buf, hgs); + return buf.extractSlice(); +} + /** * Dumps the full contents of module `m` to `buf`. * Params: @@ -510,6 +543,20 @@ private void statementToBuffer(Statement s, ref OutBuffer buf, HdrGenState* hgs) void visitSwitch(SwitchStatement s) { buf.writestring(s.isFinal ? "final switch (" : "switch ("); + if (auto p = s.param) + { + // Print condition assignment + StorageClass stc = p.storageClass; + if (!p.type && !stc) + stc = STC.auto_; + if (stcToBuffer(buf, stc)) + buf.writeByte(' '); + if (p.type) + typeToBuffer(p.type, p.ident, buf, hgs); + else + buf.writestring(p.ident.toString()); + buf.writestring(" = "); + } s.condition.expressionToBuffer(buf, hgs); buf.writeByte(')'); buf.writenl(); @@ -796,48 +843,34 @@ private void statementToBuffer(Statement s, ref OutBuffer buf, HdrGenState* hgs) private void dsymbolToBuffer(Dsymbol s, ref OutBuffer buf, HdrGenState* hgs) { - scope v = new DsymbolPrettyPrintVisitor(&buf, hgs); - s.accept(v); + toCBuffer(s, buf, *hgs); } -private extern (C++) final class DsymbolPrettyPrintVisitor : Visitor +void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) { - alias visit = Visitor.visit; -public: - OutBuffer* buf; - HdrGenState* hgs; - - extern (D) this(OutBuffer* buf, HdrGenState* hgs) scope @safe - { - this.buf = buf; - this.hgs = hgs; - } - - //////////////////////////////////////////////////////////////////////////// - - override void visit(Dsymbol s) + void visitDsymbol(Dsymbol s) { buf.writestring(s.toChars()); } - override void visit(StaticAssert s) + void visitStaticAssert(StaticAssert s) { buf.writestring(s.kind()); buf.writeByte('('); - s.exp.expressionToBuffer(*buf, hgs); + s.exp.expressionToBuffer(buf, &hgs); if (s.msgs) { foreach (m; (*s.msgs)[]) { buf.writestring(", "); - m.expressionToBuffer(*buf, hgs); + m.expressionToBuffer(buf, &hgs); } } buf.writestring(");"); buf.writenl(); } - override void visit(DebugSymbol s) + void visitDebugSymbol(DebugSymbol s) { buf.writestring("debug = "); if (s.ident) @@ -848,7 +881,7 @@ public: buf.writenl(); } - override void visit(VersionSymbol s) + void visitVersionSymbol(VersionSymbol s) { buf.writestring("version = "); if (s.ident) @@ -859,20 +892,20 @@ public: buf.writenl(); } - override void visit(EnumMember em) + void visitEnumMember(EnumMember em) { if (em.type) - typeToBuffer(em.type, em.ident, *buf, hgs); + typeToBuffer(em.type, em.ident, buf, &hgs); else buf.writestring(em.ident.toString()); if (em.value) { buf.writestring(" = "); - em.value.expressionToBuffer(*buf, hgs); + em.value.expressionToBuffer(buf, &hgs); } } - override void visit(Import imp) + void visitImport(Import imp) { if (hgs.hdrgen && imp.id == Id.object) return; // object is imported by default @@ -906,19 +939,19 @@ public: buf.writenl(); } - override void visit(AliasThis d) + void visitAliasThis(AliasThis d) { buf.writestring("alias "); buf.writestring(d.ident.toString()); buf.writestring(" this;\n"); } - override void visit(AttribDeclaration d) + void visitAttribDeclaration(AttribDeclaration d) { bool hasSTC; if (auto stcd = d.isStorageClassDeclaration) { - hasSTC = stcToBuffer(*buf, stcd.stc); + hasSTC = stcToBuffer(buf, stcd.stc); } if (!d.decl) @@ -936,7 +969,7 @@ public: else if (d.decl.length == 1) { if (hasSTC) buf.writeByte(' '); - (*d.decl)[0].accept(this); + toCBuffer((*d.decl)[0], buf, hgs); return; } else @@ -946,35 +979,35 @@ public: buf.writenl(); buf.level++; foreach (de; *d.decl) - de.accept(this); + toCBuffer(de, buf, hgs); buf.level--; buf.writeByte('}'); } buf.writenl(); } - override void visit(StorageClassDeclaration d) + void visitStorageClassDeclaration(StorageClassDeclaration d) { - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(DeprecatedDeclaration d) + void visitDeprecatedDeclaration(DeprecatedDeclaration d) { buf.writestring("deprecated("); - d.msg.expressionToBuffer(*buf, hgs); + d.msg.expressionToBuffer(buf, &hgs); buf.writestring(") "); - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(LinkDeclaration d) + void visitLinkDeclaration(LinkDeclaration d) { buf.writestring("extern ("); buf.writestring(linkageToString(d.linkage)); buf.writestring(") "); - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(CPPMangleDeclaration d) + void visitCPPMangleDeclaration(CPPMangleDeclaration d) { string s; final switch (d.cppmangle) @@ -991,22 +1024,22 @@ public: buf.writestring("extern (C++, "); buf.writestring(s); buf.writestring(") "); - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(VisibilityDeclaration d) + void visitVisibilityDeclaration(VisibilityDeclaration d) { - visibilityToBuffer(*buf, d.visibility); + visibilityToBuffer(buf, d.visibility); AttribDeclaration ad = cast(AttribDeclaration)d; if (ad.decl.length <= 1) buf.writeByte(' '); if (ad.decl.length == 1 && (*ad.decl)[0].isVisibilityDeclaration) - visit(cast(AttribDeclaration)(*ad.decl)[0]); + visitAttribDeclaration((*ad.decl)[0].isVisibilityDeclaration); else - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(AlignDeclaration d) + void visitAlignDeclaration(AlignDeclaration d) { if (d.exps) { @@ -1022,10 +1055,10 @@ public: else buf.writestring("align "); - visit(d.isAttribDeclaration()); + visitAttribDeclaration(d.isAttribDeclaration()); } - override void visit(AnonDeclaration d) + void visitAnonDeclaration(AnonDeclaration d) { buf.writestring(d.isunion ? "union" : "struct"); buf.writenl(); @@ -1035,21 +1068,21 @@ public: if (d.decl) { foreach (de; *d.decl) - de.accept(this); + toCBuffer(de, buf, hgs); } buf.level--; buf.writestring("}"); buf.writenl(); } - override void visit(PragmaDeclaration d) + void visitPragmaDeclaration(PragmaDeclaration d) { buf.writestring("pragma ("); buf.writestring(d.ident.toString()); if (d.args && d.args.length) { buf.writestring(", "); - argsToBuffer(d.args, *buf, hgs); + argsToBuffer(d.args, buf, &hgs); } buf.writeByte(')'); @@ -1061,13 +1094,13 @@ public: if (d.ident == Id.Pinline) global.params.dihdr.fullOutput = true; - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); global.params.dihdr.fullOutput = savedFullDump; } - override void visit(ConditionalDeclaration d) + void visitConditionalDeclaration(ConditionalDeclaration d) { - d.condition.conditionToBuffer(*buf, hgs); + d.condition.conditionToBuffer(buf, &hgs); if (d.decl || d.elsedecl) { buf.writenl(); @@ -1077,7 +1110,7 @@ public: if (d.decl) { foreach (de; *d.decl) - de.accept(this); + toCBuffer(de, buf, hgs); } buf.level--; buf.writeByte('}'); @@ -1090,7 +1123,7 @@ public: buf.writenl(); buf.level++; foreach (de; *d.elsedecl) - de.accept(this); + toCBuffer(de, buf, hgs); buf.level--; buf.writeByte('}'); } @@ -1100,7 +1133,7 @@ public: buf.writenl(); } - override void visit(StaticForeachDeclaration s) + void visitStaticForeachDeclaration(StaticForeachDeclaration s) { void foreachWithoutBody(ForeachStatement s) { @@ -1110,15 +1143,15 @@ public: { if (i) buf.writestring(", "); - if (stcToBuffer(*buf, p.storageClass)) + if (stcToBuffer(buf, p.storageClass)) buf.writeByte(' '); if (p.type) - typeToBuffer(p.type, p.ident, *buf, hgs); + typeToBuffer(p.type, p.ident, buf, &hgs); else buf.writestring(p.ident.toString()); } buf.writestring("; "); - s.aggr.expressionToBuffer(*buf, hgs); + s.aggr.expressionToBuffer(buf, &hgs); buf.writeByte(')'); buf.writenl(); } @@ -1130,13 +1163,13 @@ public: buf.writestring(Token.toString(s.op)); buf.writestring(" ("); if (s.prm.type) - typeToBuffer(s.prm.type, s.prm.ident, *buf, hgs); + typeToBuffer(s.prm.type, s.prm.ident, buf, &hgs); else buf.writestring(s.prm.ident.toString()); buf.writestring("; "); - s.lwr.expressionToBuffer(*buf, hgs); + s.lwr.expressionToBuffer(buf, &hgs); buf.writestring(" .. "); - s.upr.expressionToBuffer(*buf, hgs); + s.upr.expressionToBuffer(buf, &hgs); buf.writeByte(')'); buf.writenl(); } @@ -1154,62 +1187,161 @@ public: buf.writeByte('{'); buf.writenl(); buf.level++; - visit(cast(AttribDeclaration)s); + visitAttribDeclaration(s); buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(MixinDeclaration d) + void visitMixinDeclaration(MixinDeclaration d) { buf.writestring("mixin("); - argsToBuffer(d.exps, *buf, hgs, null); + argsToBuffer(d.exps, buf, &hgs, null); buf.writestring(");"); buf.writenl(); } - override void visit(UserAttributeDeclaration d) + void visitUserAttributeDeclaration(UserAttributeDeclaration d) { buf.writestring("@("); - argsToBuffer(d.atts, *buf, hgs); + argsToBuffer(d.atts, buf, &hgs); buf.writeByte(')'); - visit(cast(AttribDeclaration)d); + visitAttribDeclaration(d); } - override void visit(TemplateDeclaration d) + void visitTemplateConstraint(Expression constraint) { - version (none) - { - // Should handle template functions for doc generation - if (onemember && onemember.isFuncDeclaration()) - buf.writestring("foo "); - } - if ((hgs.hdrgen || hgs.fullDump) && visitEponymousMember(d)) + if (!constraint) return; - if (hgs.ddoc) - buf.writestring(d.kind()); - else - buf.writestring("template"); - buf.writeByte(' '); - buf.writestring(d.ident.toString()); - buf.writeByte('('); - visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters); + buf.writestring(" if ("); + constraint.expressionToBuffer(buf, &hgs); buf.writeByte(')'); - visitTemplateConstraint(d.constraint); - if (hgs.hdrgen || hgs.fullDump) + } + + /// Returns: whether `do` is needed to write the function body + bool contractsToBuffer(FuncDeclaration f) + { + bool requireDo = false; + // in{} + if (f.frequires) { - hgs.tpltMember++; - buf.writenl(); - buf.writeByte('{'); + foreach (frequire; *f.frequires) + { + buf.writestring("in"); + if (auto es = frequire.isExpStatement()) + { + assert(es.exp && es.exp.op == EXP.assert_); + buf.writestring(" ("); + (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, &hgs); + buf.writeByte(')'); + buf.writenl(); + requireDo = false; + } + else + { + buf.writenl(); + frequire.statementToBuffer(buf, &hgs); + requireDo = true; + } + } + } + // out{} + if (f.fensures) + { + foreach (fensure; *f.fensures) + { + buf.writestring("out"); + if (auto es = fensure.ensure.isExpStatement()) + { + assert(es.exp && es.exp.op == EXP.assert_); + buf.writestring(" ("); + if (fensure.id) + { + buf.writestring(fensure.id.toString()); + } + buf.writestring("; "); + (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, &hgs); + buf.writeByte(')'); + buf.writenl(); + requireDo = false; + } + else + { + if (fensure.id) + { + buf.writeByte('('); + buf.writestring(fensure.id.toString()); + buf.writeByte(')'); + } + buf.writenl(); + fensure.ensure.statementToBuffer(buf, &hgs); + requireDo = true; + } + } + } + return requireDo; + } + + void bodyToBuffer(FuncDeclaration f) + { + if (!f.fbody || (hgs.hdrgen && global.params.dihdr.fullOutput == false && !hgs.autoMember && !hgs.tpltMember && !hgs.insideFuncBody)) + { + if (!f.fbody && (f.fensures || f.frequires)) + { + buf.writenl(); + contractsToBuffer(f); + } + buf.writeByte(';'); buf.writenl(); - buf.level++; - foreach (s; *d.members) - s.accept(this); - buf.level--; - buf.writeByte('}'); + return; + } + + // there is no way to know if a function is nested + // or not after parsing. We need scope information + // for that, which is avaible during semantic + // analysis. To overcome that, a simple mechanism + // is implemented: everytime we print a function + // body (templated or not) we increment a counter. + // We decredement the counter when we stop + // printing the function body. + ++hgs.insideFuncBody; + scope(exit) { --hgs.insideFuncBody; } + + const savetlpt = hgs.tpltMember; + const saveauto = hgs.autoMember; + hgs.tpltMember = 0; + hgs.autoMember = 0; + buf.writenl(); + bool requireDo = contractsToBuffer(f); + + if (requireDo) + { + buf.writestring("do"); buf.writenl(); - hgs.tpltMember--; + } + buf.writeByte('{'); + buf.writenl(); + buf.level++; + f.fbody.statementToBuffer(buf, &hgs); + buf.level--; + buf.writeByte('}'); + buf.writenl(); + hgs.tpltMember = savetlpt; + hgs.autoMember = saveauto; + } + + void visitBaseClasses(ClassDeclaration d) + { + if (!d || !d.baseclasses.length) + return; + if (!d.isAnonymous()) + buf.writestring(" : "); + foreach (i, b; *d.baseclasses) + { + if (i) + buf.writestring(", "); + typeToBuffer(b.type, null, buf, &hgs); } } @@ -1223,9 +1355,9 @@ public: if (FuncDeclaration fd = onemember.isFuncDeclaration()) { assert(fd.type); - if (stcToBuffer(*buf, fd.storage_class)) + if (stcToBuffer(buf, fd.storage_class)) buf.writeByte(' '); - functionToBufferFull(cast(TypeFunction)fd.type, *buf, d.ident, hgs, d); + functionToBufferFull(cast(TypeFunction)fd.type, buf, d.ident, &hgs, d); visitTemplateConstraint(d.constraint); hgs.tpltMember++; bodyToBuffer(fd); @@ -1238,7 +1370,7 @@ public: buf.writeByte(' '); buf.writestring(ad.ident.toString()); buf.writeByte('('); - visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters); + visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters, buf, hgs); buf.writeByte(')'); visitTemplateConstraint(d.constraint); visitBaseClasses(ad.isClassDeclaration()); @@ -1250,7 +1382,7 @@ public: buf.writenl(); buf.level++; foreach (s; *ad.members) - s.accept(this); + toCBuffer(s, buf, hgs); buf.level--; buf.writeByte('}'); } @@ -1264,23 +1396,23 @@ public: { if (d.constraint) return false; - if (stcToBuffer(*buf, vd.storage_class)) + if (stcToBuffer(buf, vd.storage_class)) buf.writeByte(' '); if (vd.type) - typeToBuffer(vd.type, vd.ident, *buf, hgs); + typeToBuffer(vd.type, vd.ident, buf, &hgs); else buf.writestring(vd.ident.toString()); buf.writeByte('('); - visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters); + visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters, buf, hgs); buf.writeByte(')'); if (vd._init) { buf.writestring(" = "); ExpInitializer ie = vd._init.isExpInitializer(); if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit)) - (cast(AssignExp)ie.exp).e2.expressionToBuffer(*buf, hgs); + (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, &hgs); else - vd._init.initializerToBuffer(*buf, hgs); + vd._init.initializerToBuffer(buf, &hgs); } buf.writeByte(';'); buf.writenl(); @@ -1289,44 +1421,59 @@ public: return false; } - void visitTemplateParameters(TemplateParameters* parameters) + void visitTemplateDeclaration(TemplateDeclaration d) { - if (!parameters || !parameters.length) - return; - foreach (i, p; *parameters) + version (none) { - if (i) - buf.writestring(", "); - p.templateParameterToBuffer(*buf, hgs); + // Should handle template functions for doc generation + if (onemember && onemember.isFuncDeclaration()) + buf.writestring("foo "); } - } - - void visitTemplateConstraint(Expression constraint) - { - if (!constraint) + if ((hgs.hdrgen || hgs.fullDump) && visitEponymousMember(d)) return; - buf.writestring(" if ("); - constraint.expressionToBuffer(*buf, hgs); + if (hgs.ddoc) + buf.writestring(d.kind()); + else + buf.writestring("template"); + buf.writeByte(' '); + buf.writestring(d.ident.toString()); + buf.writeByte('('); + visitTemplateParameters(hgs.ddoc ? d.origParameters : d.parameters, buf, hgs); buf.writeByte(')'); + visitTemplateConstraint(d.constraint); + if (hgs.hdrgen || hgs.fullDump) + { + hgs.tpltMember++; + buf.writenl(); + buf.writeByte('{'); + buf.writenl(); + buf.level++; + foreach (s; *d.members) + toCBuffer(s, buf, hgs); + buf.level--; + buf.writeByte('}'); + buf.writenl(); + hgs.tpltMember--; + } } - override void visit(TemplateInstance ti) + void visitTemplateInstance(TemplateInstance ti) { buf.writestring(ti.name.toChars()); - tiargsToBuffer(ti, *buf, hgs); + tiargsToBuffer(ti, buf, &hgs); if (hgs.fullDump) { buf.writenl(); - dumpTemplateInstance(ti, *buf, hgs); + dumpTemplateInstance(ti, buf, &hgs); } } - override void visit(TemplateMixin tm) + void visitTemplateMixin(TemplateMixin tm) { buf.writestring("mixin "); - typeToBuffer(tm.tqual, null, *buf, hgs); - tiargsToBuffer(tm, *buf, hgs); + typeToBuffer(tm.tqual, null, buf, &hgs); + tiargsToBuffer(tm, buf, &hgs); if (tm.ident && memcmp(tm.ident.toChars(), cast(const(char)*)"__mixin", 7) != 0) { buf.writeByte(' '); @@ -1335,10 +1482,10 @@ public: buf.writeByte(';'); buf.writenl(); if (hgs.fullDump) - dumpTemplateInstance(tm, *buf, hgs); + dumpTemplateInstance(tm, buf, &hgs); } - override void visit(EnumDeclaration d) + void visitEnumDeclaration(EnumDeclaration d) { auto oldInEnumDecl = hgs.inEnumDecl; scope(exit) hgs.inEnumDecl = oldInEnumDecl; @@ -1351,7 +1498,7 @@ public: if (d.memtype) { buf.writestring(" : "); - typeToBuffer(d.memtype, null, *buf, hgs); + typeToBuffer(d.memtype, null, buf, &hgs); } if (!d.members) { @@ -1367,7 +1514,7 @@ public: { if (!em) continue; - em.accept(this); + toCBuffer(em, buf, hgs); buf.writeByte(','); buf.writenl(); } @@ -1376,7 +1523,7 @@ public: buf.writenl(); } - override void visit(Nspace d) + void visitNspace(Nspace d) { buf.writestring("extern (C++, "); buf.writestring(d.ident.toString()); @@ -1386,13 +1533,13 @@ public: buf.writenl(); buf.level++; foreach (s; *d.members) - s.accept(this); + toCBuffer(s, buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(StructDeclaration d) + void visitStructDeclaration(StructDeclaration d) { buf.writestring(d.kind()); buf.writeByte(' '); @@ -1410,14 +1557,14 @@ public: buf.level++; hgs.insideAggregate++; foreach (s; *d.members) - s.accept(this); + toCBuffer(s, buf, hgs); hgs.insideAggregate--; buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(ClassDeclaration d) + void visitClassDeclaration(ClassDeclaration d) { if (!d.isAnonymous()) { @@ -1434,7 +1581,7 @@ public: buf.level++; hgs.insideAggregate++; foreach (s; *d.members) - s.accept(this); + toCBuffer(s, buf, hgs); hgs.insideAggregate--; buf.level--; buf.writeByte('}'); @@ -1444,21 +1591,7 @@ public: buf.writenl(); } - void visitBaseClasses(ClassDeclaration d) - { - if (!d || !d.baseclasses.length) - return; - if (!d.isAnonymous()) - buf.writestring(" : "); - foreach (i, b; *d.baseclasses) - { - if (i) - buf.writestring(", "); - typeToBuffer(b.type, null, *buf, hgs); - } - } - - override void visit(AliasDeclaration d) + void visitAliasDeclaration(AliasDeclaration d) { if (d.storage_class & STC.local) return; @@ -1467,7 +1600,7 @@ public: { buf.writestring(d.ident.toString()); buf.writestring(" = "); - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); /* https://issues.dlang.org/show_bug.cgi?id=23223 @@ -1481,57 +1614,57 @@ public: } else { - d.aliassym.accept(this); + toCBuffer(d.aliassym, buf, hgs); } } else if (d.type.ty == Tfunction) { - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); - typeToBuffer(d.type, d.ident, *buf, hgs); + typeToBuffer(d.type, d.ident, buf, &hgs); } else if (d.ident) { hgs.declstring = (d.ident == Id.string || d.ident == Id.wstring || d.ident == Id.dstring); buf.writestring(d.ident.toString()); buf.writestring(" = "); - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); - typeToBuffer(d.type, null, *buf, hgs); + typeToBuffer(d.type, null, buf, &hgs); hgs.declstring = false; } buf.writeByte(';'); buf.writenl(); } - override void visit(AliasAssign d) + void visitAliasAssign(AliasAssign d) { buf.writestring(d.ident.toString()); buf.writestring(" = "); if (d.aliassym) - d.aliassym.accept(this); + toCBuffer(d.aliassym, buf, hgs); else // d.type - typeToBuffer(d.type, null, *buf, hgs); + typeToBuffer(d.type, null, buf, &hgs); buf.writeByte(';'); buf.writenl(); } - override void visit(VarDeclaration d) + void visitVarDeclaration(VarDeclaration d) { if (d.storage_class & STC.local) return; - visitVarDecl(d, false, *buf, *hgs); + visitVarDecl(d, false, buf, hgs); buf.writeByte(';'); buf.writenl(); } - override void visit(FuncDeclaration f) + void visitFuncDeclaration(FuncDeclaration f) { //printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars()); - if (stcToBuffer(*buf, f.storage_class)) + if (stcToBuffer(buf, f.storage_class)) buf.writeByte(' '); auto tf = cast(TypeFunction)f.type; - typeToBuffer(tf, f.ident, *buf, hgs); + typeToBuffer(tf, f.ident, buf, &hgs); if (hgs.hdrgen) { @@ -1564,119 +1697,7 @@ public: bodyToBuffer(f); } - /// Returns: whether `do` is needed to write the function body - bool contractsToBuffer(FuncDeclaration f) - { - bool requireDo = false; - // in{} - if (f.frequires) - { - foreach (frequire; *f.frequires) - { - buf.writestring("in"); - if (auto es = frequire.isExpStatement()) - { - assert(es.exp && es.exp.op == EXP.assert_); - buf.writestring(" ("); - (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs); - buf.writeByte(')'); - buf.writenl(); - requireDo = false; - } - else - { - buf.writenl(); - frequire.statementToBuffer(*buf, hgs); - requireDo = true; - } - } - } - // out{} - if (f.fensures) - { - foreach (fensure; *f.fensures) - { - buf.writestring("out"); - if (auto es = fensure.ensure.isExpStatement()) - { - assert(es.exp && es.exp.op == EXP.assert_); - buf.writestring(" ("); - if (fensure.id) - { - buf.writestring(fensure.id.toString()); - } - buf.writestring("; "); - (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs); - buf.writeByte(')'); - buf.writenl(); - requireDo = false; - } - else - { - if (fensure.id) - { - buf.writeByte('('); - buf.writestring(fensure.id.toString()); - buf.writeByte(')'); - } - buf.writenl(); - fensure.ensure.statementToBuffer(*buf, hgs); - requireDo = true; - } - } - } - return requireDo; - } - - void bodyToBuffer(FuncDeclaration f) - { - if (!f.fbody || (hgs.hdrgen && global.params.dihdr.fullOutput == false && !hgs.autoMember && !hgs.tpltMember && !hgs.insideFuncBody)) - { - if (!f.fbody && (f.fensures || f.frequires)) - { - buf.writenl(); - contractsToBuffer(f); - } - buf.writeByte(';'); - buf.writenl(); - return; - } - - // there is no way to know if a function is nested - // or not after parsing. We need scope information - // for that, which is avaible during semantic - // analysis. To overcome that, a simple mechanism - // is implemented: everytime we print a function - // body (templated or not) we increment a counter. - // We decredement the counter when we stop - // printing the function body. - ++hgs.insideFuncBody; - scope(exit) { --hgs.insideFuncBody; } - - const savetlpt = hgs.tpltMember; - const saveauto = hgs.autoMember; - hgs.tpltMember = 0; - hgs.autoMember = 0; - buf.writenl(); - bool requireDo = contractsToBuffer(f); - - if (requireDo) - { - buf.writestring("do"); - buf.writenl(); - } - buf.writeByte('{'); - buf.writenl(); - buf.level++; - f.fbody.statementToBuffer(*buf, hgs); - buf.level--; - buf.writeByte('}'); - buf.writenl(); - hgs.tpltMember = savetlpt; - hgs.autoMember = saveauto; - } - - override void visit(FuncLiteralDeclaration f) + void visitFuncLiteralDeclaration(FuncLiteralDeclaration f) { if (f.type.ty == Terror) { @@ -1691,8 +1712,8 @@ public: TypeFunction tf = cast(TypeFunction)f.type; if (!f.inferRetType && tf.next) - typeToBuffer(tf.next, null, *buf, hgs); - parametersToBuffer(tf.parameterList, *buf, hgs); + typeToBuffer(tf.next, null, buf, &hgs); + parametersToBuffer(tf.parameterList, buf, &hgs); // https://issues.dlang.org/show_bug.cgi?id=20074 void printAttribute(string str) @@ -1715,7 +1736,7 @@ public: if (rs && rs.exp) { buf.writestring(" => "); - rs.exp.expressionToBuffer(*buf, hgs); + rs.exp.expressionToBuffer(buf, &hgs); } else { @@ -1725,25 +1746,25 @@ public: } } - override void visit(PostBlitDeclaration d) + void visitPostBlitDeclaration(PostBlitDeclaration d) { - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); buf.writestring("this(this)"); bodyToBuffer(d); } - override void visit(DtorDeclaration d) + void visitDtorDeclaration(DtorDeclaration d) { - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); buf.writestring("~this()"); bodyToBuffer(d); } - override void visit(StaticCtorDeclaration d) + void visitStaticCtorDeclaration(StaticCtorDeclaration d) { - if (stcToBuffer(*buf, d.storage_class & ~STC.static_)) + if (stcToBuffer(buf, d.storage_class & ~STC.static_)) buf.writeByte(' '); if (d.isSharedStaticCtorDeclaration()) buf.writestring("shared "); @@ -1757,9 +1778,9 @@ public: bodyToBuffer(d); } - override void visit(StaticDtorDeclaration d) + void visitStaticDtorDeclaration(StaticDtorDeclaration d) { - if (stcToBuffer(*buf, d.storage_class & ~STC.static_)) + if (stcToBuffer(buf, d.storage_class & ~STC.static_)) buf.writeByte(' '); if (d.isSharedStaticDtorDeclaration()) buf.writestring("shared "); @@ -1773,18 +1794,18 @@ public: bodyToBuffer(d); } - override void visit(InvariantDeclaration d) + void visitInvariantDeclaration(InvariantDeclaration d) { if (hgs.hdrgen) return; - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); buf.writestring("invariant"); if(auto es = d.fbody.isExpStatement()) { assert(es.exp && es.exp.op == EXP.assert_); buf.writestring(" ("); - (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs); + (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, &hgs); buf.writestring(");"); buf.writenl(); } @@ -1794,41 +1815,111 @@ public: } } - override void visit(UnitTestDeclaration d) + void visitUnitTestDeclaration(UnitTestDeclaration d) { if (hgs.hdrgen) return; - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); buf.writestring("unittest"); bodyToBuffer(d); } - override void visit(BitFieldDeclaration d) + void visitBitFieldDeclaration(BitFieldDeclaration d) { - if (stcToBuffer(*buf, d.storage_class)) + if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); Identifier id = d.isAnonymous() ? null : d.ident; - typeToBuffer(d.type, id, *buf, hgs); + typeToBuffer(d.type, id, buf, &hgs); buf.writestring(" : "); - d.width.expressionToBuffer(*buf, hgs); + d.width.expressionToBuffer(buf, &hgs); buf.writeByte(';'); buf.writenl(); } - override void visit(NewDeclaration d) + void visitNewDeclaration(NewDeclaration d) { - if (stcToBuffer(*buf, d.storage_class & ~STC.static_)) + if (stcToBuffer(buf, d.storage_class & ~STC.static_)) buf.writeByte(' '); buf.writestring("new();"); } - override void visit(Module m) + void visitModule(Module m) + { + moduleToBuffer2(m, buf, &hgs); + } + + extern (C++) + final class DsymbolPrettyPrintVisitor : Visitor + { + alias visit = Visitor.visit; + + public: + override: + void visit(Dsymbol s) { visitDsymbol(s); } + void visit(StaticAssert s) { visitStaticAssert(s); } + void visit(DebugSymbol s) { visitDebugSymbol(s); } + void visit(VersionSymbol s) { visitVersionSymbol(s); } + void visit(EnumMember em) { visitEnumMember(em); } + void visit(Import imp) { visitImport(imp); } + void visit(AliasThis d) { visitAliasThis(d); } + void visit(AttribDeclaration d) { visitAttribDeclaration(d); } + void visit(StorageClassDeclaration d) { visitStorageClassDeclaration(d); } + void visit(DeprecatedDeclaration d) { visitDeprecatedDeclaration(d); } + void visit(LinkDeclaration d) { visitLinkDeclaration(d); } + void visit(CPPMangleDeclaration d) { visitCPPMangleDeclaration(d); } + void visit(VisibilityDeclaration d) { visitVisibilityDeclaration(d); } + void visit(AlignDeclaration d) { visitAlignDeclaration(d); } + void visit(AnonDeclaration d) { visitAnonDeclaration(d); } + void visit(PragmaDeclaration d) { visitPragmaDeclaration(d); } + void visit(ConditionalDeclaration d) { visitConditionalDeclaration(d); } + void visit(StaticForeachDeclaration s) { visitStaticForeachDeclaration(s); } + void visit(MixinDeclaration d) { visitMixinDeclaration(d); } + void visit(UserAttributeDeclaration d) { visitUserAttributeDeclaration(d); } + void visit(TemplateDeclaration d) { visitTemplateDeclaration(d); } + void visit(TemplateInstance ti) { visitTemplateInstance(ti); } + void visit(TemplateMixin tm) { visitTemplateMixin(tm); } + void visit(EnumDeclaration d) { visitEnumDeclaration(d); } + void visit(Nspace d) { visitNspace(d); } + void visit(StructDeclaration d) { visitStructDeclaration(d); } + void visit(ClassDeclaration d) { visitClassDeclaration(d); } + void visit(AliasDeclaration d) { visitAliasDeclaration(d); } + void visit(AliasAssign d) { visitAliasAssign(d); } + void visit(VarDeclaration d) { visitVarDeclaration(d); } + void visit(FuncDeclaration f) { visitFuncDeclaration(f); } + void visit(FuncLiteralDeclaration f) { visitFuncLiteralDeclaration(f); } + void visit(PostBlitDeclaration d) { visitPostBlitDeclaration(d); } + void visit(DtorDeclaration d) { visitDtorDeclaration(d); } + void visit(StaticCtorDeclaration d) { visitStaticCtorDeclaration(d); } + void visit(StaticDtorDeclaration d) { visitStaticDtorDeclaration(d); } + void visit(InvariantDeclaration d) { visitInvariantDeclaration(d); } + void visit(UnitTestDeclaration d) { visitUnitTestDeclaration(d); } + void visit(BitFieldDeclaration d) { visitBitFieldDeclaration(d); } + void visit(NewDeclaration d) { visitNewDeclaration(d); } + void visit(Module m) { visitModule(m); } + } + + scope v = new DsymbolPrettyPrintVisitor(); + s.accept(v); +} + + +/***************************************** + * Pretty-print a template parameter list to a buffer. + */ +private void visitTemplateParameters(TemplateParameters* parameters, ref OutBuffer buf, ref HdrGenState hgs) +{ + if (!parameters) + return; + foreach (i, p; *parameters) { - moduleToBuffer2(m, *buf, hgs); + if (i) + buf.writestring(", "); + p.templateParameterToBuffer(buf, &hgs); } } + /******************************************* * Pretty-print a VarDeclaration to buf. */ @@ -2011,7 +2102,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, HdrGenState* void visitVoidInit(VoidInitExp e) { - buf.writestring("__void"); + buf.writestring("void"); } void floatToBuffer(Type type, real_t value) @@ -2313,8 +2404,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, HdrGenState* if (e.parameters && e.parameters.length) { buf.writestring(", "); - scope v = new DsymbolPrettyPrintVisitor(&buf, hgs); - v.visitTemplateParameters(e.parameters); + visitTemplateParameters(e.parameters, buf, *hgs); } buf.writeByte(')'); } @@ -2905,19 +2995,14 @@ void toCBuffer(const Type t, ref OutBuffer buf, const Identifier ident, ref HdrG typeToBuffer(cast() t, ident, buf, &hgs); } -void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) -{ - scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs); - s.accept(v); -} - // used from TemplateInstance::toChars() and TemplateMixin::toChars() void toCBufferInstance(const TemplateInstance ti, ref OutBuffer buf, bool qualifyTypes = false) { HdrGenState hgs; hgs.fullQual = qualifyTypes; - scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs); - v.visit(cast() ti); + + buf.writestring(ti.name.toChars()); + tiargsToBuffer(cast() ti, buf, &hgs); } void toCBuffer(const Initializer iz, ref OutBuffer buf, ref HdrGenState hgs) @@ -3063,22 +3148,17 @@ const(char)* linkageToChars(LINK linkage) string linkageToString(LINK linkage) pure nothrow @safe { - final switch (linkage) - { - case LINK.default_: - return null; - case LINK.d: - return "D"; - case LINK.c: - return "C"; - case LINK.cpp: - return "C++"; - case LINK.windows: - return "Windows"; - case LINK.objc: - return "Objective-C"; - case LINK.system: - return "System"; + with (LINK) + { + immutable string[7] a = [ + default_ : null, + d : "D", + c : "C", + cpp : "C++", + windows : "Windows", + objc : "Objective-C", + system : "System" ]; + return a[linkage]; } } @@ -3106,22 +3186,16 @@ const(char)* visibilityToChars(Visibility.Kind kind) /// Ditto extern (D) string visibilityToString(Visibility.Kind kind) nothrow pure @safe { - final switch (kind) - { - case Visibility.Kind.undefined: - return null; - case Visibility.Kind.none: - return "none"; - case Visibility.Kind.private_: - return "private"; - case Visibility.Kind.package_: - return "package"; - case Visibility.Kind.protected_: - return "protected"; - case Visibility.Kind.public_: - return "public"; - case Visibility.Kind.export_: - return "export"; + with (Visibility.Kind) + { + immutable string[7] a = [ + none : "none", + private_ : "private", + package_ : "package", + protected_ : "protected", + public_ : "public", + export_ : "export" ]; + return a[kind]; } } diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 1fdfe40765b8..c58224f7debd 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -64,6 +64,7 @@ extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc) return statementSemantic(se, sc); } auto ias = new InlineAsmStatement(s.loc, s.tokens); + ias.caseSensitive = s.caseSensitive; return inlineAsmSemantic(ias, sc); } else version (IN_GCC) diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index 62fb51f752e9..b506e6feb665 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -61,6 +61,8 @@ immutable Msgtable[] msgtable = { "IUnknown" }, { "Object" }, { "object" }, + { "_size_t", "size_t" }, + { "_ptrdiff_t", "ptrdiff_t" }, { "string" }, { "wstring" }, { "dstring" }, diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index fe0aa171d98c..98ac9038a0aa 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -20,6 +20,7 @@ import dmd.dcast; import dmd.declaration; import dmd.dscope; import dmd.dsymbol; +import dmd.errors; import dmd.expression; import dmd.expressionsem; import dmd.identifier; @@ -126,14 +127,14 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow) t = t.isTypePointer().next; auto pe = e.toChars(); if (!arrow) - e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars()); + error(e.loc, "since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars()); e = new PtrExp(e.loc, e); } if (auto ts = t.isTypeStruct()) s = ts.sym.search(e.loc, id, 0); if (!s) { - e.error("`%s` is not a member of `%s`", id.toChars(), t.toChars()); + error(e.loc, "`%s` is not a member of `%s`", id.toChars(), t.toChars()); return ErrorExp.get(); } Expression ef = new DotVarExp(e.loc, e, s.isDeclaration()); diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d index 4501185b393a..ecca55283524 100644 --- a/gcc/d/dmd/init.d +++ b/gcc/d/dmd/init.d @@ -57,14 +57,6 @@ extern (C++) class Initializer : ASTNode this.kind = kind; } - override final const(char)* toChars() const - { - OutBuffer buf; - HdrGenState hgs; - toCBuffer(this, buf, hgs); - return buf.extractChars(); - } - final inout(ErrorInitializer) isErrorInitializer() inout @nogc nothrow pure { // Use void* cast to skip dynamic casting call diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h index 9a6a56b68bbf..4ab5848454e0 100644 --- a/gcc/d/dmd/init.h +++ b/gcc/d/dmd/init.h @@ -35,8 +35,6 @@ public: DYNCAST dyncast() const override { return DYNCAST_INITIALIZER; } - const char *toChars() const override final; - ErrorInitializer *isErrorInitializer(); VoidInitializer *isVoidInitializer(); StructInitializer *isStructInitializer(); diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index 45f09af8733b..28c7c2bb52e9 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -29,6 +29,7 @@ import dmd.expression; import dmd.expressionsem; import dmd.func; import dmd.globals; +import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.importc; @@ -59,12 +60,12 @@ Expression toAssocArrayLiteral(ArrayInitializer ai) if (!dim) { error(ai.loc, "invalid associative array initializer `%s`, use `null` instead", - ai.toChars()); + toChars(ai)); return ErrorExp.get(); } auto no(const char* format, Initializer i) { - error(i.loc, format, i.toChars()); + error(i.loc, format, toChars(i)); return ErrorExp.get(); } Expression e; @@ -399,13 +400,13 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ } if (i.exp.op == EXP.type) { - i.exp.error("initializer must be an expression, not `%s`", i.exp.toChars()); + error(i.exp.loc, "initializer must be an expression, not `%s`", i.exp.toChars()); return err(); } // Make sure all pointers are constants if (needInterpret && hasNonConstPointers(i.exp)) { - i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars()); + error(i.exp.loc, "cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars()); return err(); } Type ti = i.exp.type.toBasetype(); @@ -563,7 +564,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ } if (dim1 != dim2) { - i.exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); + error(i.exp.loc, "mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); i.exp = ErrorExp.get(); } } @@ -571,7 +572,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ const errors = global.startGagging(); i.exp = i.exp.implicitCastTo(sc, t); if (global.endGagging(errors)) - currExp.error("cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars()); + error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars()); } } L1: @@ -791,12 +792,12 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ const length = (*dlist).length; if (length == 0 || !(*dlist)[0].ident) { - error(ci.loc, "`.identifier` expected for C struct field initializer `%s`", ci.toChars()); + error(ci.loc, "`.identifier` expected for C struct field initializer `%s`", toChars(ci)); return err(); } if (length > 1) { - error(ci.loc, "only 1 designator currently allowed for C struct field initializer `%s`", ci.toChars()); + error(ci.loc, "only 1 designator currently allowed for C struct field initializer `%s`", toChars(ci)); return err(); } auto id = (*dlist)[0].ident; @@ -912,12 +913,12 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ const length = (*dlist).length; if (length == 0 || !(*dlist)[0].exp) { - error(ci.loc, "`[ constant-expression ]` expected for C array element initializer `%s`", ci.toChars()); + error(ci.loc, "`[ constant-expression ]` expected for C array element initializer `%s`", toChars(ci)); return err(); } if (length > 1) { - error(ci.loc, "only 1 designator currently allowed for C array element initializer `%s`", ci.toChars()); + error(ci.loc, "only 1 designator currently allowed for C array element initializer `%s`", toChars(ci)); return err(); } //printf("tn: %s, di.initializer: %s\n", tn.toChars(), di.initializer.toChars()); @@ -988,7 +989,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ } else { - error(ci.loc, "unrecognized C initializer `%s`", ci.toChars()); + error(ci.loc, "unrecognized C initializer `%s`", toChars(ci)); return err(); } } @@ -1103,9 +1104,9 @@ Initializer inferType(Initializer init, Scope* sc) { TemplateInstance ti = se.sds.isTemplateInstance(); if (ti && ti.semanticRun == PASS.semantic && !ti.aliasdecl) - se.error("cannot infer type from %s `%s`, possible circular dependency", se.sds.kind(), se.toChars()); + error(se.loc, "cannot infer type from %s `%s`, possible circular dependency", se.sds.kind(), se.toChars()); else - se.error("cannot infer type from %s `%s`", se.sds.kind(), se.toChars()); + error(se.loc, "cannot infer type from %s `%s`", se.sds.kind(), se.toChars()); return new ErrorInitializer(); } @@ -1119,7 +1120,7 @@ Initializer inferType(Initializer init, Scope* sc) } if (hasOverloads && !f.isUnique()) { - init.exp.error("cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); + error(init.exp.loc, "cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); return new ErrorInitializer(); } } @@ -1127,7 +1128,7 @@ Initializer inferType(Initializer init, Scope* sc) { if (ae.e1.op == EXP.overloadSet) { - init.exp.error("cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); + error(init.exp.loc, "cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); return new ErrorInitializer(); } } diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index c803bf80cc0d..f1999fd458d3 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -788,7 +788,7 @@ public: objectStart(); jsonProperties(d); if (d._init) - property("init", d._init.toString()); + property("init", toString(d._init)); if (d.isField()) property("offset", d.offset); if (!d.alignment.isUnknown() && !d.alignment.isDefault()) @@ -815,7 +815,7 @@ public: arrayStart(); foreach (m; modules) { - if (global.params.verbose) + if (global.params.v.verbose) message("json gen %s", m.toChars()); m.accept(this); } diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 28ffbf8ed6d6..882f2eac06c7 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -1525,6 +1525,7 @@ class Lexer stringbuffer.writeByte(v); } t.setString(stringbuffer); + t.postfix = 'h'; stringPostfix(t); return TOK.hexadecimalString; default: @@ -2206,9 +2207,14 @@ class Lexer if (base == 2) goto Ldone; // if ".identifier" or ".unicode" goto Lreal; // otherwise as part of a floating point literal + + case 'i': + if (Ccompile) + goto Ldone; + goto Lreal; + case 'p': case 'P': - case 'i': Lreal: p = start; return inreal(t); @@ -2401,7 +2407,13 @@ class Lexer decimal = 2, // decimal unsigned = 4, // u or U suffix long_ = 8, // l or L suffix - llong = 0x10 // ll or LL + llong = 0x10, // ll or LL + + // Microsoft extensions + i8 = 0x20, + i16 = 0x40, + i32 = 0x80, + i64 = 0x100, } FLAGS flags = (base == 10) ? FLAGS.decimal : FLAGS.octalhex; bool err; @@ -2427,6 +2439,37 @@ class Lexer } break; + case 'i': + case 'I': + if (p[1] == '8') + { + f = FLAGS.i8; + ++p; + } + else if (p[1] == '1' && p[2] == '6') + { + f = FLAGS.i16; + p += 2; + } + else if (p[1] == '3' && p[2] == '2') + { + f = FLAGS.i32; + p += 2; + } + else if (p[1] == '6' && p[2] == '4') + { + f = FLAGS.i64; + p += 2; + } + else + break Lsuffixes; + if (p[1] >= '0' && p[1] <= '9' && !err) + { + error("invalid integer suffix"); + err = true; + } + break; + default: break Lsuffixes; } @@ -2559,6 +2602,34 @@ class Lexer result = TOK.uns64Literal; break; + case FLAGS.octalhex | FLAGS.i8: + case FLAGS.octalhex | FLAGS.i16: + case FLAGS.octalhex | FLAGS.i32: + case FLAGS.octalhex | FLAGS.unsigned | FLAGS.i8: + case FLAGS.octalhex | FLAGS.unsigned | FLAGS.i16: + case FLAGS.octalhex | FLAGS.unsigned | FLAGS.i32: + case FLAGS.decimal | FLAGS.unsigned | FLAGS.i8: + case FLAGS.decimal | FLAGS.unsigned | FLAGS.i16: + case FLAGS.decimal | FLAGS.unsigned | FLAGS.i32: + result = TOK.uns32Literal; + break; + + case FLAGS.decimal | FLAGS.i8: + case FLAGS.decimal | FLAGS.i16: + case FLAGS.decimal | FLAGS.i32: + result = TOK.int32Literal; + break; + + case FLAGS.octalhex | FLAGS.i64: + case FLAGS.octalhex | FLAGS.unsigned | FLAGS.i64: + case FLAGS.decimal | FLAGS.unsigned | FLAGS.i64: + result = TOK.uns64Literal; + break; + + case FLAGS.decimal | FLAGS.i64: + result = TOK.int64Literal; + break; + default: debug printf("%x\n",flags); assert(0); diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 63e20ed89d0d..01f94a7b04d3 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -4592,7 +4592,7 @@ extern (C++) final class TypeFunction : TypeNext // arguments get specially formatted private const(char)* getParamError(Expression arg, Parameter par) { - if (global.gag && !global.params.showGaggedErrors) + if (global.gag && !global.params.v.showGaggedErrors) return null; // show qualification when toChars() is the same but types are different // https://issues.dlang.org/show_bug.cgi?id=19948 @@ -4611,7 +4611,7 @@ extern (C++) final class TypeFunction : TypeNext private extern(D) const(char)* getMatchError(A...)(const(char)* format, A args) { - if (global.gag && !global.params.showGaggedErrors) + if (global.gag && !global.params.v.showGaggedErrors) return null; OutBuffer buf; buf.printf(format, args); @@ -6217,7 +6217,7 @@ extern (C++) final class TypeTuple : Type { Expression e = (*exps)[i]; if (e.type.ty == Ttuple) - e.error("cannot form sequence of sequences"); + error(e.loc, "cannot form sequence of sequences"); auto arg = new Parameter(e.loc, STC.undefined_, e.type, null, null, null); (*arguments)[i] = arg; } diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d index 844f719e0b81..1d831bbed6b3 100644 --- a/gcc/d/dmd/mustuse.d +++ b/gcc/d/dmd/mustuse.d @@ -12,6 +12,7 @@ module dmd.mustuse; import dmd.dscope; import dmd.dsymbol; +import dmd.errors; import dmd.expression; import dmd.globals; import dmd.identifier; @@ -49,7 +50,7 @@ bool checkMustUse(Expression e, Scope* sc) // isStructDeclaration returns non-null for both structs and unions if (sd && hasMustUseAttribute(sd, sc) && !isAssignment(e) && !isIncrementOrDecrement(e)) { - e.error("ignored value of `@%s` type `%s`; prepend a `cast(void)` if intentional", + error(e.loc, "ignored value of `@%s` type `%s`; prepend a `cast(void)` if intentional", Id.udaMustUse.toChars(), e.type.toPrettyChars(true)); return true; } diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 01a6832a97be..560606190e06 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -86,7 +86,7 @@ public: } if (f.setGC(e.loc, format)) { - e.error(format, f.kind(), f.toPrettyChars()); + error(e.loc, format, f.kind(), f.toPrettyChars()); err = true; return true; } @@ -225,7 +225,7 @@ Expression checkGC(Scope* sc, Expression e) if (e && e.op != EXP.error && f && sc.intypeof != 1 && (!(sc.flags & SCOPE.ctfe) || betterC) && (f.type.ty == Tfunction && - (cast(TypeFunction)f.type).isnogc || f.nogcInprocess || global.params.vgc) && + (cast(TypeFunction)f.type).isnogc || f.nogcInprocess || global.params.v.gc) && !(sc.flags & SCOPE.debug_)) { scope NOGCVisitor gcv = new NOGCVisitor(f); diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d index 551db5b74754..2d3367af804b 100644 --- a/gcc/d/dmd/nspace.d +++ b/gcc/d/dmd/nspace.d @@ -52,6 +52,7 @@ import dmd.astenums; import dmd.dscope; import dmd.dsymbol; import dmd.dsymbolsem; +import dmd.errors; import dmd.expression; import dmd.globals; import dmd.identifier; @@ -134,7 +135,7 @@ extern (C++) final class Nspace : ScopeDsymbol if (!members || !symtab) // opaque or semantic() is not yet called { if (!(flags & IgnoreErrors)) - error("is forward referenced when looking for `%s`", ident.toChars()); + .error(loc, "%s `%s` is forward referenced when looking for `%s`", kind, toPrettyChars, ident.toChars()); return null; } diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 4774d1f5243c..8b30681afc08 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -1970,7 +1970,7 @@ void checkObErrors(ref ObState obstate) else { if (pvs.state == PtrState.Owner && v.type.hasPointersToMutableFields()) - v.error(e.loc, "assigning to Owner without disposing of owned value"); + .error(e.loc, "%s `%s` assigning to Owner without disposing of owned value", v.kind, v.toPrettyChars); pvs.state = PtrState.Owner; } @@ -1993,12 +1993,12 @@ void checkObErrors(ref ObState obstate) if (pvsr.state == Undefined) { - v.error(e.loc, "is reading from `%s` which is Undefined", r.toChars()); + .error(e.loc, "%s `%s` is reading from `%s` which is Undefined", v.kind, v.toPrettyChars, r.toChars()); } else if (isBorrowedPtr(v)) // v is going to borrow from r { if (pvsr.state == Readonly) - v.error(e.loc, "is borrowing from `%s` which is Readonly", r.toChars()); + .error(e.loc, "%s `%s` is borrowing from `%s` which is Readonly", v.kind, v.toPrettyChars, r.toChars()); pvs.state = Borrowed; } @@ -2039,7 +2039,7 @@ void checkObErrors(ref ObState obstate) assert(vi != size_t.max); auto pvs = &gen[vi]; if (pvs.state == PtrState.Undefined) - v.error(loc, "has undefined state and cannot be read"); + .error(loc, "%s `%s` has undefined state and cannot be read", v.kind, v.toPrettyChars); readVar(ob, vi, mutable, gen); } @@ -2187,7 +2187,7 @@ void checkObErrors(ref ObState obstate) { // move (i.e. consume arg) if (pvs.state != PtrState.Owner) - v.error(arg.loc, "is not Owner, cannot consume its value"); + .error(arg.loc, "%s `%s` is not Owner, cannot consume its value", v.kind, v.toPrettyChars); makeUndefined(vi, cpvs); } } @@ -2226,7 +2226,7 @@ void checkObErrors(ref ObState obstate) { // move (i.e. consume arg) if (pvs.state != PtrState.Owner) - v.error(arg.loc, "is not Owner, cannot consume its value"); + .error(arg.loc, "%s `%s` is not Owner, cannot consume its value", v.kind, v.toPrettyChars); makeUndefined(vi, cpvs); } } @@ -2261,7 +2261,7 @@ void checkObErrors(ref ObState obstate) { if (obstate.mutableStack[vi] || obstate.mutableStack[vk]) { - v.error(ce.loc, "is passed as Owner more than once"); + .error(ce.loc, "%s `%s` is passed as Owner more than once", v.kind, v.toPrettyChars); break; // no need to continue } } @@ -2490,7 +2490,7 @@ void checkObErrors(ref ObState obstate) if (s1 != s2 && (s1 == PtrState.Owner || s2 == PtrState.Owner)) { auto v = obstate.vars[i]; - v.error(ob.exp ? ob.exp.loc : v.loc, "is both %s and %s", s1.toChars(), s2.toChars()); + .error(ob.exp ? ob.exp.loc : v.loc, "%s `%s` is both %s and %s", v.kind, v.toPrettyChars, s1.toChars(), s2.toChars()); } pvs1.combine(*pvs2, i, ob.gen); } @@ -2536,7 +2536,7 @@ void checkObErrors(ref ObState obstate) switch (pvsr.state) { case Undefined: - r.error(ob.exp.loc, "is returned but is Undefined"); + .error(ob.exp.loc, "%s `%s` is returned but is Undefined", r.kind, r.toPrettyChars); break; case Owner: @@ -2568,7 +2568,7 @@ void checkObErrors(ref ObState obstate) { auto v = obstate.vars[i]; if (v.type.hasPointers()) - v.error(v.loc, "is not disposed of before return"); + .error(v.loc, "%s `%s` is not disposed of before return", v.kind, v.toPrettyChars); } } } diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d index 623a362907eb..359474c588ad 100644 --- a/gcc/d/dmd/objc.d +++ b/gcc/d/dmd/objc.d @@ -410,12 +410,12 @@ extern(C++) private final class Unsupported : Objc override void setObjc(ClassDeclaration cd) { - cd.error("Objective-C classes not supported"); + .error(cd.loc, "%s `%s` Objective-C classes not supported", cd.kind, cd.toPrettyChars); } override void setObjc(InterfaceDeclaration id) { - id.error("Objective-C interfaces not supported"); + .error(id.loc, "%s `%s` Objective-C interfaces not supported", id.kind, id.toPrettyChars); } override const(char)* toPrettyChars(ClassDeclaration, bool qualifyTypes) const @@ -552,7 +552,7 @@ extern(C++) private final class Supported : Objc if (fd.objc.selector) { - fd.error("can only have one Objective-C selector per method"); + .error(fd.loc, "%s `%s` can only have one Objective-C selector per method", fd.kind, fd.toPrettyChars); return 1; } @@ -572,15 +572,15 @@ extern(C++) private final class Supported : Objc return; TypeFunction tf = cast(TypeFunction)fd.type; if (fd.objc.selector.paramCount != tf.parameterList.parameters.length) - fd.error("number of colons in Objective-C selector must match number of parameters"); + .error(fd.loc, "%s `%s` number of colons in Objective-C selector must match number of parameters", fd.kind, fd.toPrettyChars); if (fd.parent && fd.parent.isTemplateInstance()) - fd.error("template cannot have an Objective-C selector attached"); + .error(fd.loc, "%s `%s` template cannot have an Objective-C selector attached", fd.kind, fd.toPrettyChars); } override void checkLinkage(FuncDeclaration fd) { if (fd._linkage != LINK.objc && fd.objc.selector) - fd.error("must have Objective-C linkage to attach a selector"); + .error(fd.loc, "%s `%s` must have Objective-C linkage to attach a selector", fd.kind, fd.toPrettyChars); } override bool isVirtual(const FuncDeclaration fd) const @@ -608,7 +608,7 @@ extern(C++) private final class Supported : Objc fd.objc.isOptional = count > 0; if (count > 1) - fd.error("can only declare a function as optional once"); + .error(fd.loc, "%s `%s` can only declare a function as optional once", fd.kind, fd.toPrettyChars); } /// Returns: the number of times `fd` has been declared as optional. @@ -643,7 +643,7 @@ extern(C++) private final class Supported : Objc if (fd._linkage != LINK.objc) { - fd.error("only functions with Objective-C linkage can be declared as optional"); + .error(fd.loc, "%s `%s` only functions with Objective-C linkage can be declared as optional", fd.kind, fd.toPrettyChars); const linkage = linkageToString(fd._linkage); @@ -655,14 +655,14 @@ extern(C++) private final class Supported : Objc if (parent && parent.isTemplateInstance()) { - fd.error("template cannot be optional"); + .error(fd.loc, "%s `%s` template cannot be optional", fd.kind, fd.toPrettyChars); parent = parent.parent; assert(parent); } if (parent && !parent.isInterfaceDeclaration()) { - fd.error("only functions declared inside interfaces can be optional"); + .error(fd.loc, "%s `%s` only functions declared inside interfaces can be optional", fd.kind, fd.toPrettyChars); errorSupplemental(fd.loc, "function is declared inside %s", fd.parent.kind); } } @@ -805,9 +805,9 @@ extern(C++) private final class Supported : Objc enum supplementalMessage = "`offsetof` is not available for members " ~ "of Objective-C classes. Please use the Objective-C runtime instead"; - expression.error(errorMessage, expression.toChars(), + error(expression.loc, errorMessage, expression.toChars(), expression.type.toChars()); - expression.errorSupplemental(supplementalMessage); + errorSupplemental(expression.loc, supplementalMessage); } override void checkTupleof(Expression expression, TypeClass type) const @@ -815,8 +815,8 @@ extern(C++) private final class Supported : Objc if (type.sym.classKind != ClassKind.objc) return; - expression.error("no property `tupleof` for type `%s`", type.toChars()); - expression.errorSupplemental("`tupleof` is not available for members " ~ + error(expression.loc, "no property `tupleof` for type `%s`", type.toChars()); + errorSupplemental(expression.loc, "`tupleof` is not available for members " ~ "of Objective-C classes. Please use the Objective-C runtime instead"); } } @@ -866,8 +866,8 @@ if (is(T == ClassDeclaration) || is(T == InterfaceDeclaration)) } else { - error("base " ~ errorType ~ " for an Objective-C " ~ - errorType ~ " must be `extern (Objective-C)`"); + .error(classDeclaration.loc, "%s `%s` base " ~ errorType ~ " for an Objective-C " ~ + errorType ~ " must be `extern (Objective-C)`", classDeclaration.kind, classDeclaration.toPrettyChars); } } diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index f9de1ee5a119..addcd0103d05 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -405,7 +405,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { // @@@DEPRECATED_2.110@@@. // Deprecated in 2.088, made an error in 2.100 - e.error("`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); + error(e.loc, "`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); return ErrorExp.get(); } } @@ -644,7 +644,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) s = search_function(ad1, Id.opBinary); if (s && !s.isTemplateDeclaration()) { - e.e1.error("`%s.opBinary` isn't a template", e.e1.toChars()); + error(e.e1.loc, "`%s.opBinary` isn't a template", e.e1.toChars()); return ErrorExp.get(); } } @@ -653,7 +653,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) s_r = search_function(ad2, Id.opBinaryRight); if (s_r && !s_r.isTemplateDeclaration()) { - e.e2.error("`%s.opBinaryRight` isn't a template", e.e2.toChars()); + error(e.e2.loc, "`%s.opBinaryRight` isn't a template", e.e2.toChars()); return ErrorExp.get(); } if (s_r && s_r == s) // https://issues.dlang.org/show_bug.cgi?id=12778 @@ -678,9 +678,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) // @@@DEPRECATED_2.110@@@. // Deprecated in 2.088, made an error in 2.100 if (id == Id.postinc || id == Id.postdec) - e.error("`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); + error(e.loc, "`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); else - e.error("`%s` is obsolete. Use `opBinary(string op)(...) if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); + error(e.loc, "`%s` is obsolete. Use `opBinary(string op)(...) if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr); return ErrorExp.get(); } } @@ -696,7 +696,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { // @@@DEPRECATED_2.110@@@. // Deprecated in 2.088, made an error in 2.100 - e.error("`%s` is obsolete. Use `opBinaryRight(string op)(...) if (op == \"%s\")` instead.", id_r.toChars(), EXPtoString(e.op).ptr); + error(e.loc, "`%s` is obsolete. Use `opBinaryRight(string op)(...) if (op == \"%s\")` instead.", id_r.toChars(), EXPtoString(e.op).ptr); return ErrorExp.get(); } } @@ -738,7 +738,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (m.count > 1) { // Error, ambiguous - e.error("overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); + error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); } else if (m.last == MATCH.nomatch) { @@ -820,7 +820,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (m.count > 1) { // Error, ambiguous - e.error("overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); + error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); } else if (m.last == MATCH.nomatch) { @@ -890,7 +890,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) } if (rewrittenLhs) { - e.error("cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`", + error(e.loc, "cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`", e.e1.toChars(), ad1.toChars(), rewrittenLhs.toChars()); return ErrorExp.get(); } @@ -918,7 +918,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (t1.ty == Tclass && e.e2.op == EXP.null_ || t2.ty == Tclass && e.e1.op == EXP.null_) { - e.error("use `%s` instead of `%s` when comparing with `null`", + error(e.loc, "use `%s` instead of `%s` when comparing with `null`", EXPtoString(e.op == EXP.equal ? EXP.identity : EXP.notIdentity).ptr, EXPtoString(e.op).ptr); return ErrorExp.get(); @@ -943,7 +943,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) */ if (!ClassDeclaration.object) { - e.error("cannot compare classes for equality because `object.Object` was not declared"); + error(e.loc, "cannot compare classes for equality because `object.Object` was not declared"); return null; } @@ -1045,7 +1045,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) size_t dim = tup1.exps.length; if (dim != tup2.exps.length) { - e.error("mismatched sequence lengths, `%d` and `%d`", + error(e.loc, "mismatched sequence lengths, `%d` and `%d`", cast(int)dim, cast(int)tup2.exps.length); return ErrorExp.get(); } @@ -1210,7 +1210,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) s = search_function(ad1, Id.opOpAssign); if (s && !s.isTemplateDeclaration()) { - e.error("`%s.opOpAssign` isn't a template", e.e1.toChars()); + error(e.loc, "`%s.opOpAssign` isn't a template", e.e1.toChars()); return ErrorExp.get(); } } @@ -1231,7 +1231,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) // Deprecated in 2.088, made an error in 2.100 scope char[] op = EXPtoString(e.op).dup; op[$-1] = '\0'; // remove trailing `=` - e.error("`%s` is obsolete. Use `opOpAssign(string op)(...) if (op == \"%s\")` instead.", id.toChars(), op.ptr); + error(e.loc, "`%s` is obsolete. Use `opOpAssign(string op)(...) if (op == \"%s\")` instead.", id.toChars(), op.ptr); return ErrorExp.get(); } } @@ -1253,7 +1253,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (m.count > 1) { // Error, ambiguous - e.error("overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); + error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); } else if (m.last == MATCH.nomatch) { @@ -1366,7 +1366,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop if (!(m.lastf == lastf && m.count == 2 && count == 1)) { // Error, ambiguous - e.error("overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); + error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars()); } } else if (m.last == MATCH.nomatch) diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 37563826a2d2..d108cffd392d 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -24,6 +24,7 @@ import dmd.errors; import dmd.expression; import dmd.expressionsem; import dmd.globals; +import dmd.hdrgen; import dmd.init; import dmd.location; import dmd.mtype; @@ -90,7 +91,7 @@ Expression expandVar(int result, VarDeclaration v) { if (v.storage_class & STC.manifest) { - v.error("recursive initialization of constant"); + .error(v.loc, "%s `%s` recursive initialization of constant", v.kind, v.toPrettyChars); return errorReturn(); } return nullReturn(); @@ -100,7 +101,7 @@ Expression expandVar(int result, VarDeclaration v) { if (v.storage_class & STC.manifest) { - v.error("enum cannot be initialized with `%s`", v._init.toChars()); + .error(v.loc, "%s `%s` enum cannot be initialized with `%s`", v.kind, v.toPrettyChars, dmd.hdrgen.toChars(v._init)); return errorReturn(); } return nullReturn(); @@ -275,7 +276,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) //printf("Expression_optimize() e: %s result: %d keepLvalue %d\n", e.toChars(), result, keepLvalue); Expression ret = e; - void error() + void errorReturn() { ret = ErrorExp.get(); } @@ -571,8 +572,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) if (index < 0 || index > dim) { - e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); - return error(); + error(e.loc, "array index %lld is out of bounds `[0..%lld]`", index, dim); + return errorReturn(); } import core.checkedint : mulu; @@ -580,8 +581,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) const offset = mulu(index, ts.nextOf().size(e.loc), overflow); // offset = index*size if (overflow) { - e.error("array offset overflow"); - return error(); + error(e.loc, "array offset overflow"); + return errorReturn(); } Expression ex = new AddrExp(ae1.loc, ae1); // &a[i] @@ -610,8 +611,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) */ if (!((dim == 0 || dim == index) && ve.var.isCsymbol())) { - e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); - return error(); + error(e.loc, "array index %lld is out of bounds `[0..%lld]`", index, dim); + return errorReturn(); } } @@ -620,8 +621,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) const offset = mulu(index, ts.nextOf().size(e.loc), overflow); if (overflow) { - e.error("array offset overflow"); - return error(); + error(e.loc, "array offset overflow"); + return errorReturn(); } ret = new SymOffExp(e.loc, ve.var, offset); @@ -645,8 +646,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) */ if (!((dim == 0 || dim == index) && ve.var.isCsymbol())) { - e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); - return error(); + error(e.loc, "array index %lld is out of bounds `[0..%lld]`", index, dim); + return errorReturn(); } } @@ -655,8 +656,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) const offset = mulu(index, ts.nextOf().size(e.loc), overflow); // index*elementsize if (overflow) { - e.error("array offset overflow"); - return error(); + error(e.loc, "array offset overflow"); + return errorReturn(); } auto pe = new AddrExp(e.loc, ve); @@ -808,7 +809,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) const esz = e.type.nextOf().size(e.loc); const e1sz = e.e1.type.toBasetype().nextOf().size(e.e1.loc); if (esz == SIZE_INVALID || e1sz == SIZE_INVALID) - return error(); + return errorReturn(); if (e1sz == esz) { @@ -855,13 +856,13 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) ClassDeclaration cdfrom = e.e1.type.isClassHandle(); ClassDeclaration cdto = e.type.isClassHandle(); if (cdfrom.errors || cdto.errors) - return error(); + return errorReturn(); if (cdto == ClassDeclaration.object && !cdfrom.isInterfaceDeclaration()) return returnE_e1(); // can always convert a class to Object // Need to determine correct offset before optimizing away the cast. // https://issues.dlang.org/show_bug.cgi?id=16980 if (cdfrom.size(e.loc) == SIZE_INVALID) - return error(); + return errorReturn(); assert(cdfrom.sizeok == Sizeok.done); assert(cdto.sizeok == Sizeok.done || !cdto.isBaseOf(cdfrom, null)); int offset; @@ -886,7 +887,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) const e1sz = e.e1.type.size(e.e1.loc); if (esz == SIZE_INVALID || e1sz == SIZE_INVALID) - return error(); + return errorReturn(); if (esz == e1sz) return returnE_e1(); @@ -919,8 +920,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) sz *= 8; if (i2 < 0 || i2 >= sz) { - e.error("shift assign by %lld is outside the range `0..%llu`", i2, cast(ulong)sz - 1); - return error(); + error(e.loc, "shift assign by %lld is outside the range `0..%llu`", i2, cast(ulong)sz - 1); + return errorReturn(); } } } @@ -1005,8 +1006,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) sz *= 8; if (i2 < 0 || i2 >= sz) { - e.error("shift by %lld is outside the range `0..%llu`", i2, cast(ulong)sz - 1); - return error(); + error(e.loc, "shift by %lld is outside the range `0..%llu`", i2, cast(ulong)sz - 1); + return errorReturn(); } if (e.e1.isConst() == 1) ret = (*shift)(e.loc, e.type, e.e1, e.e2).copy(); @@ -1062,8 +1063,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) // All negative integral powers are illegal. if (e.e1.type.isintegral() && (e.e2.op == EXP.int64) && cast(sinteger_t)e.e2.toInteger() < 0) { - e.error("cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars()); - return error(); + error(e.loc, "cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars()); + return errorReturn(); } // If e2 *could* have been an integer, make it one. if (e.e2.op == EXP.float64 && e.e2.toReal() == real_t(cast(sinteger_t)e.e2.toReal())) @@ -1337,7 +1338,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) { if (b++ == global.recursionLimit) { - e.error("infinite loop while optimizing expression"); + error(e.loc, "infinite loop while optimizing expression"); fatal(); } diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 2a964151be50..3821f947a97e 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -6247,9 +6247,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (auto ds = parseDebugSpecification()) { if (ds.ident) - ds.error("declaration must be at module level"); + eSink.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars); else - ds.error("level declaration must be at module level"); + eSink.error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars); } break; } @@ -6263,9 +6263,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (auto vs = parseVersionSpecification()) { if (vs.ident) - vs.error("declaration must be at module level"); + eSink.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars); else - vs.error("level declaration must be at module level"); + eSink.error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars); } break; } @@ -6329,10 +6329,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { nextToken(); check(TOK.leftParenthesis); + auto param = parseAssignCondition(); AST.Expression condition = parseExpression(); closeCondition("switch", null, condition); AST.Statement _body = parseStatement(ParseStatementFlags.scope_); - s = new AST.SwitchStatement(loc, condition, _body, isfinal); + s = new AST.SwitchStatement(loc, param, condition, _body, isfinal, token.loc); break; } case TOK.case_: @@ -8200,6 +8201,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.string_: case TOK.hexadecimalString: + const bool hexString = token.value == TOK.hexadecimalString; { // cat adjacent strings auto s = token.ustring; @@ -8235,6 +8237,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer break; } e = new AST.StringExp(loc, s[0 .. len], len, 1, postfix); + e.isStringExp().hexString = hexString; break; } case TOK.void_: @@ -8899,7 +8902,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { e = parseUnaryExp(); e = new AST.CastExp(loc, e, t); - error("C style cast illegal, use `%s`", e.toChars()); + error(loc, "C style cast illegal, use `%s`", e.toChars()); } return e; } diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d index 987c79391ccd..631c08c44d27 100644 --- a/gcc/d/dmd/root/filename.d +++ b/gcc/d/dmd/root/filename.d @@ -14,13 +14,14 @@ module dmd.root.filename; import core.stdc.ctype; import core.stdc.errno; import core.stdc.string; + +import dmd.common.file; +import dmd.common.outbuffer; + import dmd.root.array; import dmd.root.file; -import dmd.common.outbuffer; -import dmd.common.file; import dmd.root.port; import dmd.root.rmem; -import dmd.root.rootobject; import dmd.root.string; version (Posix) diff --git a/gcc/d/dmd/root/rootobject.d b/gcc/d/dmd/root/rootobject.d index 7138841caa02..65c499ddf4ea 100644 --- a/gcc/d/dmd/root/rootobject.d +++ b/gcc/d/dmd/root/rootobject.d @@ -1,5 +1,5 @@ /** - * Provide the root object that classes in dmd inherit from. + * Provide the root object that AST classes in dmd inherit from. * * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com @@ -11,10 +11,6 @@ module dmd.root.rootobject; -import core.stdc.stdio; - -import dmd.common.outbuffer; - /*********************************************************** */ diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index e2d2e0411621..6a3795178d30 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -195,7 +195,7 @@ private extern(C++) final class Semantic2Visitor : Visitor if (!tempinst.errors) { if (!tempdecl.literal) - tempinst.error(tempinst.loc, "error instantiating"); + .error(tempinst.loc, "%s `%s` error instantiating", tempinst.kind, tempinst.toPrettyChars); if (tempinst.tinst) tempinst.tinst.printInstantiationTrace(); } @@ -315,7 +315,7 @@ private extern(C++) final class Semantic2Visitor : Visitor } if (hasInvalidEnumInitializer(ei.exp)) - vd.error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead."); + .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.", vd.kind, vd.toPrettyChars); } } else if (vd._init && vd.isThreadlocal()) @@ -326,13 +326,13 @@ private extern(C++) final class Semantic2Visitor : Visitor { ExpInitializer ei = vd._init.isExpInitializer(); if (ei && ei.exp.op == EXP.classReference) - vd.error("is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead."); + .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars); } else if (vd.type.ty == Tpointer && vd.type.nextOf().ty == Tstruct && vd.type.nextOf().isMutable() && !vd.type.nextOf().isShared()) { ExpInitializer ei = vd._init.isExpInitializer(); if (ei && ei.exp.op == EXP.address && (cast(AddrExp)ei.exp).e1.op == EXP.structLiteral) - vd.error("is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead."); + .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars); } } vd.semanticRun = PASS.semantic2done; @@ -454,7 +454,7 @@ private extern(C++) final class Semantic2Visitor : Visitor (!sameAttr || !sameParams) ) { - f2.error("cannot overload `extern(%s)` function at %s", + .error(f2.loc, "%s `%s` cannot overload `extern(%s)` function at %s", f2.kind, f2.toPrettyChars, linkageToChars(f1._linkage), f1.loc.toChars()); return 0; @@ -473,14 +473,14 @@ private extern(C++) final class Semantic2Visitor : Visitor // this condition, as well as the error for extern(C) functions above. if (sameAttr != tf1.attributesEqual(tf2)) { - f2.deprecation("cannot overload `extern(%s)` function at %s", + .deprecation(f2.loc, "%s `%s` cannot overload `extern(%s)` function at %s", f2.kind, f2.toPrettyChars, linkageToChars(f1._linkage), f1.loc.toChars()); } return 0; } - error(f2.loc, "%s `%s%s` conflicts with previous declaration at %s", + .error(f2.loc, "%s `%s%s` conflicts with previous declaration at %s", f2.kind(), f2.toPrettyChars(), parametersTypeToChars(tf2.parameterList), @@ -631,7 +631,7 @@ private extern(C++) final class Semantic2Visitor : Visitor if (ad._scope) { - ad.error("has forward references"); + .error(ad.loc, "%s `%s` has forward references", ad.kind, ad.toPrettyChars); return; } @@ -685,20 +685,20 @@ private extern(C++) final class Semantic2Visitor : Visitor //printf(" found\n"); // Check that calling conventions match if (fd._linkage != ifd._linkage) - fd.error("linkage doesn't match interface function"); + .error(fd.loc, "%s `%s` linkage doesn't match interface function", fd.kind, fd.toPrettyChars); // Check that it is current //printf("newinstance = %d fd.toParent() = %s ifd.toParent() = %s\n", //newinstance, fd.toParent().toChars(), ifd.toParent().toChars()); if (fd.toParent() != cd && ifd.toParent() == base.sym) - cd.error("interface function `%s` is not implemented", ifd.toFullSignature()); + .error(cd.loc, "%s `%s` interface function `%s` is not implemented", cd.kind, cd.toPrettyChars, ifd.toFullSignature()); } else { //printf(" not found %p\n", fd); // BUG: should mark this class as abstract? if (!cd.isAbstract()) - cd.error("interface function `%s` is not implemented", ifd.toFullSignature()); + .error(cd.loc, "%s `%s` interface function `%s` is not implemented", cd.kind, cd.toPrettyChars, ifd.toFullSignature()); } } } @@ -748,7 +748,7 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag) // When `@gnuAbiTag` is used, the type will be the UDA, not the struct literal if (e.op == EXP.type) { - e.error("`@%s` at least one argument expected", Id.udaGNUAbiTag.toChars()); + error(e.loc, "`@%s` at least one argument expected", Id.udaGNUAbiTag.toChars()); return; } @@ -766,7 +766,7 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag) auto ale = (*sle.elements)[0].isArrayLiteralExp(); if (ale is null) { - e.error("`@%s` at least one argument expected", Id.udaGNUAbiTag.toChars()); + error(e.loc, "`@%s` at least one argument expected", Id.udaGNUAbiTag.toChars()); return; } @@ -775,8 +775,8 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag) { const str1 = (*lastTag.isStructLiteralExp().elements)[0].toString(); const str2 = ale.toString(); - e.error("only one `@%s` allowed per symbol", Id.udaGNUAbiTag.toChars()); - e.errorSupplemental("instead of `@%s @%s`, use `@%s(%.*s, %.*s)`", + error(e.loc, "only one `@%s` allowed per symbol", Id.udaGNUAbiTag.toChars()); + errorSupplemental(e.loc, "instead of `@%s @%s`, use `@%s(%.*s, %.*s)`", lastTag.toChars(), e.toChars(), Id.udaGNUAbiTag.toChars(), // Avoid [ ... ] cast(int)str1.length - 2, str1.ptr + 1, @@ -792,7 +792,7 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag) const str = elem.toStringExp().peekString(); if (!str.length) { - e.error("argument `%d` to `@%s` cannot be %s", cast(int)(idx + 1), + error(e.loc, "argument `%d` to `@%s` cannot be %s", cast(int)(idx + 1), Id.udaGNUAbiTag.toChars(), elem.isNullExp() ? "`null`".ptr : "empty".ptr); continue; @@ -802,7 +802,7 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag) { if (!c.isValidMangling()) { - e.error("`@%s` char `0x%02x` not allowed in mangling", + error(e.loc, "`@%s` char `0x%02x` not allowed in mangling", Id.udaGNUAbiTag.toChars(), c); break; } diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 04f57a4c0213..e0931409df89 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -141,7 +141,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (!tempinst.errors) { if (!tempdecl.literal) - tempinst.error(tempinst.loc, "error instantiating"); + .error(tempinst.loc, "%s `%s` error instantiating", tempinst.kind, tempinst.toPrettyChars); if (tempinst.tinst) tempinst.tinst.printInstantiationTrace(); } @@ -303,7 +303,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (!funcdecl.fbody && funcdecl.inferRetType && !f.next) { - funcdecl.error("has no function body with return type inference"); + .error(funcdecl.loc, "%s `%s` has no function body with return type inference", funcdecl.kind, funcdecl.toPrettyChars); return; } @@ -371,7 +371,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (!sc.intypeof) { if (fld.tok == TOK.delegate_) - funcdecl.error("cannot be %s members", ad.kind()); + .error(funcdecl.loc, "%s `%s` cannot be %s members", funcdecl.kind, funcdecl.toPrettyChars, ad.kind()); else fld.tok = TOK.function_; } @@ -395,7 +395,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // functions to be reworked as a frontend-only feature. if (funcdecl.hasDualContext()) { - funcdecl.deprecation("function requires a dual-context, which is deprecated"); + .deprecation(funcdecl.loc, "%s `%s` function requires a dual-context, which is deprecated", funcdecl.kind, funcdecl.toPrettyChars); if (auto ti = sc2.parent ? sc2.parent.isInstantiated() : null) ti.printInstantiationTrace(Classification.deprecation); } @@ -412,11 +412,11 @@ private extern(C++) final class Semantic3Visitor : Visitor if (!global.params.useTypeInfo || !Type.dtypeinfo || !Type.typeinfotypelist) { if (!global.params.useTypeInfo) - funcdecl.error("D-style variadic functions cannot be used with -betterC"); + .error(funcdecl.loc, "%s `%s` D-style variadic functions cannot be used with -betterC", funcdecl.kind, funcdecl.toPrettyChars); else if (!Type.typeinfotypelist) - funcdecl.error("`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions"); + .error(funcdecl.loc, "%s `%s` `object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions", funcdecl.kind, funcdecl.toPrettyChars); else - funcdecl.error("`object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions"); + .error(funcdecl.loc, "%s `%s` `object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions", funcdecl.kind, funcdecl.toPrettyChars); fatal(); } @@ -484,7 +484,7 @@ private extern(C++) final class Semantic3Visitor : Visitor v.dsymbolSemantic(sc2); if (!sc2.insert(v)) { - funcdecl.error("parameter `%s.%s` is already defined", funcdecl.toChars(), v.toChars()); + .error(funcdecl.loc, "%s `%s` parameter `%s.%s` is already defined", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.toChars(), v.toChars()); funcdecl.errors = true; } else @@ -523,7 +523,7 @@ private extern(C++) final class Semantic3Visitor : Visitor //printf("declaring tuple %s\n", v.toChars()); v.isexp = true; if (!sc2.insert(v)) - funcdecl.error("parameter `%s.%s` is already defined", funcdecl.toChars(), v.toChars()); + .error(funcdecl.loc, "%s `%s` parameter `%s.%s` is already defined", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.toChars(), v.toChars()); funcdecl.localsymtab.insert(v); v.parent = funcdecl; } @@ -687,7 +687,7 @@ private extern(C++) final class Semantic3Visitor : Visitor * as delegating calls to other constructors */ if (v.isCtorinit() && !v.type.isMutable() && cd) - funcdecl.error("missing initializer for %s field `%s`", MODtoChars(v.type.mod), v.toChars()); + .error(funcdecl.loc, "%s `%s` missing initializer for %s field `%s`", funcdecl.kind, funcdecl.toPrettyChars, MODtoChars(v.type.mod), v.toChars()); else if (v.storage_class & STC.nodefaultctor) error(funcdecl.loc, "field `%s` must be initialized in constructor", v.toChars()); else if (v.type.needsNested()) @@ -698,7 +698,7 @@ private extern(C++) final class Semantic3Visitor : Visitor bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested()); if (mustInit && !(sc2.ctorflow.fieldinit[i].csx & CSX.this_ctor)) { - funcdecl.error("field `%s` must be initialized but skipped", v.toChars()); + .error(funcdecl.loc, "%s `%s` field `%s` must be initialized but skipped", funcdecl.kind, funcdecl.toPrettyChars, v.toChars()); } } } @@ -714,11 +714,11 @@ private extern(C++) final class Semantic3Visitor : Visitor FuncDeclaration fd = resolveFuncCall(Loc.initial, sc2, cd.baseClass.ctor, null, tthis, ArgumentList(), FuncResolveFlag.quiet); if (!fd) { - funcdecl.error("no match for implicit `super()` call in constructor"); + .error(funcdecl.loc, "%s `%s` no match for implicit `super()` call in constructor", funcdecl.kind, funcdecl.toPrettyChars); } else if (fd.storage_class & STC.disable) { - funcdecl.error("cannot call `super()` implicitly because it is annotated with `@disable`"); + .error(funcdecl.loc, "%s `%s` cannot call `super()` implicitly because it is annotated with `@disable`", funcdecl.kind, funcdecl.toPrettyChars); } else { @@ -802,7 +802,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // Fallthrough despite being declared as noreturn? return is already rejected when evaluating the ReturnStatement if (blockexit & BE.fallthru) { - funcdecl.error("is typed as `%s` but does return", f.next.toChars()); + .error(funcdecl.loc, "%s `%s` is typed as `%s` but does return", funcdecl.kind, funcdecl.toPrettyChars, f.next.toChars()); funcdecl.loc.errorSupplemental("`noreturn` functions must either throw, abort or loop indefinitely"); } } @@ -812,9 +812,9 @@ private extern(C++) final class Semantic3Visitor : Visitor if ((blockexit & BE.fallthru) && f.next.ty != Tvoid && !inlineAsm && !(sc.flags & SCOPE.Cfile)) { if (!funcdecl.hasReturnExp) - funcdecl.error("has no `return` statement, but is expected to return a value of type `%s`", f.next.toChars()); + .error(funcdecl.loc, "%s `%s` has no `return` statement, but is expected to return a value of type `%s`", funcdecl.kind, funcdecl.toPrettyChars, f.next.toChars()); else - funcdecl.error("no `return exp;` or `assert(0);` at end of function"); + .error(funcdecl.loc, "%s `%s` no `return exp;` or `assert(0);` at end of function", funcdecl.kind, funcdecl.toPrettyChars); } } @@ -1023,7 +1023,7 @@ private extern(C++) final class Semantic3Visitor : Visitor { if (e.id) { - funcdecl.error(e.ensure.loc, "`void` functions have no result"); + .error(e.ensure.loc, "%s `%s` `void` functions have no result", funcdecl.kind, funcdecl.toPrettyChars); //fens = null; } } @@ -1075,7 +1075,7 @@ private extern(C++) final class Semantic3Visitor : Visitor { if (!v._init) { - v.error("zero-length `out` parameters are not allowed."); + .error(v.loc, "%s `%s` zero-length `out` parameters are not allowed.", v.kind, v.toPrettyChars); return; } ExpInitializer ie = v._init.isExpInitializer(); @@ -1229,7 +1229,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } else { - funcdecl.error("synchronized function `%s` must be a member of a class", funcdecl.toChars()); + .error(funcdecl.loc, "%s `%s` synchronized function `%s` must be a member of a class", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.toChars()); } } @@ -1246,7 +1246,7 @@ private extern(C++) final class Semantic3Visitor : Visitor LabelDsymbol label = cast(LabelDsymbol)keyValue.value; if (!label.statement && (!label.deleted || label.iasm)) { - funcdecl.error(label.loc, "label `%s` is undefined", label.toChars()); + .error(label.loc, "%s `%s` label `%s` is undefined", funcdecl.kind, funcdecl.toPrettyChars, label.toChars()); } } @@ -1260,7 +1260,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } if (funcdecl.isNaked() && (funcdecl.fensures || funcdecl.frequires)) - funcdecl.error("naked assembly functions with contracts are not supported"); + .error(funcdecl.loc, "%s `%s` naked assembly functions with contracts are not supported", funcdecl.kind, funcdecl.toPrettyChars); sc2.ctorflow.callSuper = CSX.none; sc2.pop(); @@ -1366,7 +1366,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } if (isCppNonMappableType(f.next.toBasetype())) { - funcdecl.error("cannot return type `%s` because its linkage is `extern(C++)`", f.next.toChars()); + .error(funcdecl.loc, "%s `%s` cannot return type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, f.next.toChars()); if (f.next.isTypeDArray()) errorSupplemental(funcdecl.loc, "slices are specific to D and do not have a counterpart representation in C++", f.next.toChars()); funcdecl.errors = true; @@ -1375,7 +1375,7 @@ private extern(C++) final class Semantic3Visitor : Visitor { if (isCppNonMappableType(param.type.toBasetype(), param)) { - funcdecl.error("cannot have parameter of type `%s` because its linkage is `extern(C++)`", param.type.toChars()); + .error(funcdecl.loc, "%s `%s` cannot have parameter of type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, param.type.toChars()); if (param.type.toBasetype().isTypeSArray()) errorSupplemental(funcdecl.loc, "perhaps use a `%s*` type instead", param.type.nextOf().mutableOf().unSharedOf().toChars()); @@ -1620,7 +1620,7 @@ private struct FuncDeclSem3 FuncDeclaration fdv = funcdecl.foverrides[i]; if (fdv.fbody && !fdv.frequires) { - funcdecl.error("cannot have an in contract when overridden function `%s` does not have an in contract", fdv.toPrettyChars()); + .error(funcdecl.loc, "%s `%s` cannot have an in contract when overridden function `%s` does not have an in contract", funcdecl.kind, funcdecl.toPrettyChars, fdv.toPrettyChars()); break; } } diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 30921c6b92ce..de92b294c140 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -14,6 +14,7 @@ module dmd.sideeffect; import dmd.astenums; import dmd.declaration; import dmd.dscope; +import dmd.errors; import dmd.expression; import dmd.expressionsem; import dmd.func; @@ -299,7 +300,7 @@ bool discardValue(Expression e) } else s = ce.e1.toChars(); - e.warning("calling `%s` without side effects discards return value of type `%s`; prepend a `cast(void)` if intentional", s, e.type.toChars()); + warning(e.loc, "calling `%s` without side effects discards return value of type `%s`; prepend a `cast(void)` if intentional", s, e.type.toChars()); } } } @@ -368,12 +369,12 @@ bool discardValue(Expression e) BinExp tmp = e.isBinExp(); assert(tmp); - e.error("the result of the equality expression `%s` is discarded", e.toChars()); + error(e.loc, "the result of the equality expression `%s` is discarded", e.toChars()); bool seenSideEffect = false; foreach(expr; [tmp.e1, tmp.e2]) { if (hasSideEffect(expr)) { - expr.errorSupplemental("note that `%s` may have a side effect", expr.toChars()); + errorSupplemental(expr.loc, "note that `%s` may have a side effect", expr.toChars()); seenSideEffect |= true; } } @@ -381,7 +382,7 @@ bool discardValue(Expression e) default: break; } - e.error("`%s` has no effect", e.toChars()); + error(e.loc, "`%s` has no effect", e.toChars()); return true; } diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 58550fe6ca4b..da26bc980e87 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -82,15 +82,6 @@ extern (C++) abstract class Statement : ASTNode return b; } - override final const(char)* toChars() const - { - HdrGenState hgs; - OutBuffer buf; - toCBuffer(this, buf, hgs); - buf.writeByte(0); - return buf.extractSlice().ptr; - } - Statement getRelatedLabeled() { return this; @@ -571,12 +562,7 @@ extern (C++) final class CompoundDeclarationStatement : CompoundStatement override CompoundDeclarationStatement syntaxCopy() { - auto a = new Statements(statements.length); - foreach (i, s; *statements) - { - (*a)[i] = s ? s.syntaxCopy() : null; - } - return new CompoundDeclarationStatement(loc, a); + return new CompoundDeclarationStatement(loc, Statement.arraySyntaxCopy(statements)); } override void accept(Visitor v) @@ -601,12 +587,7 @@ extern (C++) final class UnrolledLoopStatement : Statement override UnrolledLoopStatement syntaxCopy() { - auto a = new Statements(statements.length); - foreach (i, s; *statements) - { - (*a)[i] = s ? s.syntaxCopy() : null; - } - return new UnrolledLoopStatement(loc, a); + return new UnrolledLoopStatement(loc, Statement.arraySyntaxCopy(statements)); } override bool hasBreak() const pure nothrow @@ -1117,30 +1098,39 @@ extern (C++) final class StaticAssertStatement : Statement */ extern (C++) final class SwitchStatement : Statement { + Parameter param; Expression condition; /// switch(condition) Statement _body; /// bool isFinal; /// https://dlang.org/spec/statement.html#final-switch-statement + Loc endloc; + bool hasDefault; /// true if has default statement + bool hasVars; /// true if has variable case values DefaultStatement sdefault; /// default: Statement tryBody; /// set to TryCatchStatement or TryFinallyStatement if in _body portion TryFinallyStatement tf; /// set if in the 'finally' block of a TryFinallyStatement GotoCaseStatements gotoCases; /// array of unresolved GotoCaseStatement's CaseStatements* cases; /// array of CaseStatement's - int hasNoDefault; /// !=0 if no default statement - int hasVars; /// !=0 if has variable case values VarDeclaration lastVar; /// last observed variable declaration in this statement - extern (D) this(const ref Loc loc, Expression condition, Statement _body, bool isFinal) + extern (D) this(const ref Loc loc, Parameter param, Expression condition, Statement _body, bool isFinal, Loc endloc) { super(loc, STMT.Switch); + this.param = param; this.condition = condition; this._body = _body; this.isFinal = isFinal; + this.endloc = endloc; } override SwitchStatement syntaxCopy() { - return new SwitchStatement(loc, condition.syntaxCopy(), _body.syntaxCopy(), isFinal); + return new SwitchStatement(loc, + param ? param.syntaxCopy() : null, + condition.syntaxCopy(), + _body.syntaxCopy(), + isFinal, + endloc); } override bool hasBreak() const pure nothrow @@ -1148,47 +1138,6 @@ extern (C++) final class SwitchStatement : Statement return true; } - /************************************ - * Returns: - * true if error - */ - extern (D) bool checkLabel() - { - /* - * Checks the scope of a label for existing variable declaration. - * Params: - * vd = last variable declared before this case/default label - * Returns: `true` if the variables declared in this label would be skipped. - */ - bool checkVar(VarDeclaration vd) - { - for (auto v = vd; v && v != lastVar; v = v.lastVar) - { - if (v.isDataseg() || (v.storage_class & (STC.manifest | STC.temp) && vd.ident != Id.withSym) || v._init.isVoidInitializer()) - continue; - if (vd.ident == Id.withSym) - error(loc, "`switch` skips declaration of `with` temporary"); - else - error(loc, "`switch` skips declaration of variable `%s`", v.toPrettyChars()); - errorSupplemental(v.loc, "declared here"); - return true; - } - return false; - } - - enum error = true; - - if (sdefault && checkVar(sdefault.lastVar)) - return !error; // return error once fully deprecated - - foreach (scase; *cases) - { - if (scase && checkVar(scase.lastVar)) - return !error; // return error once fully deprecated - } - return !error; - } - override void accept(Visitor v) { v.visit(this); @@ -1712,85 +1661,6 @@ extern (C++) final class GotoStatement : Statement return new GotoStatement(loc, ident); } - /************** - * Returns: true for error - */ - extern (D) bool checkLabel() - { - if (!label.statement) - return true; // error should have been issued for this already - - if (label.statement.os != os) - { - if (os && os.tok == TOK.onScopeFailure && !label.statement.os) - { - // Jump out from scope(failure) block is allowed. - } - else - { - if (label.statement.os) - error(loc, "cannot `goto` in to `%s` block", Token.toChars(label.statement.os.tok)); - else - error(loc, "cannot `goto` out of `%s` block", Token.toChars(os.tok)); - return true; - } - } - - if (label.statement.tf != tf) - { - error(loc, "cannot `goto` in or out of `finally` block"); - return true; - } - - if (label.statement.inCtfeBlock && !inCtfeBlock) - { - error(loc, "cannot `goto` into `if (__ctfe)` block"); - return true; - } - - Statement stbnext; - for (auto stb = tryBody; stb != label.statement.tryBody; stb = stbnext) - { - if (!stb) - { - error(loc, "cannot `goto` into `try` block"); - return true; - } - if (auto stf = stb.isTryFinallyStatement()) - stbnext = stf.tryBody; - else if (auto stc = stb.isTryCatchStatement()) - stbnext = stc.tryBody; - else - assert(0); - } - - VarDeclaration vd = label.statement.lastVar; - if (!vd || vd.isDataseg() || (vd.storage_class & STC.manifest)) - return false; - - VarDeclaration last = lastVar; - while (last && last != vd) - last = last.lastVar; - if (last == vd) - { - // All good, the label's scope has no variables - } - else if (vd.storage_class & STC.exptemp) - { - // Lifetime ends at end of expression, so no issue with skipping the statement - } - else - { - if (vd.ident == Id.withSym) - error(loc, "`goto` skips declaration of `with` temporary"); - else - error(loc, "`goto` skips declaration of variable `%s`", vd.toPrettyChars()); - errorSupplemental(vd.loc, "declared here"); - return true; - } - return false; - } - override void accept(Visitor v) { v.visit(this); @@ -1972,12 +1842,7 @@ extern (C++) final class CompoundAsmStatement : CompoundStatement override CompoundAsmStatement syntaxCopy() { - auto a = new Statements(statements.length); - foreach (i, s; *statements) - { - (*a)[i] = s ? s.syntaxCopy() : null; - } - return new CompoundAsmStatement(loc, a, stc); + return new CompoundAsmStatement(loc, Statement.arraySyntaxCopy(statements), stc); } override void accept(Visitor v) diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h index dd8b9f21c056..fe899c6a4963 100644 --- a/gcc/d/dmd/statement.h +++ b/gcc/d/dmd/statement.h @@ -113,8 +113,6 @@ public: virtual Statement *syntaxCopy(); - const char *toChars() const override final; - void error(const char *format, ...); void warning(unsigned flag, const char *format, ...); void deprecation(const char *format, ...); @@ -431,17 +429,19 @@ public: class SwitchStatement final : public Statement { public: + Parameter *param; Expression *condition; Statement *_body; d_bool isFinal; + Loc endloc; + d_bool hasDefault; // true if default statement + d_bool hasVars; // true if has variable case values DefaultStatement *sdefault; Statement *tryBody; // set to TryCatchStatement or TryFinallyStatement if in _body portion TryFinallyStatement *tf; GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's CaseStatements *cases; // array of CaseStatement's - int hasNoDefault; // !=0 if no default statement - int hasVars; // !=0 if has variable case values VarDeclaration *lastVar; SwitchStatement *syntaxCopy() override; diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 304cb862f327..962ef625f5be 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -45,6 +45,7 @@ import dmd.expressionsem; import dmd.func; import dmd.globals; import dmd.gluelayer; +import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.importc; @@ -130,7 +131,7 @@ private Expression checkAssignmentAsCondition(Expression e, Scope* sc) auto ec = lastComma(e); if (ec.op == EXP.assign) { - ec.error("assignment cannot be used as a condition, perhaps `==` was meant?"); + error(ec.loc, "assignment cannot be used as a condition, perhaps `==` was meant?"); return ErrorExp.get(); } return e; @@ -665,7 +666,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) const olderrors = global.startGagging(); discardValue(fs.increment); if (global.endGagging(olderrors)) - fs.increment.deprecation("`%s` has no effect", fs.increment.toChars()); + deprecation(fs.increment.loc, "`%s` has no effect", fs.increment.toChars()); if (checkNonAssignmentArrayOp(fs.increment)) fs.increment = ErrorExp.get(); fs.increment = fs.increment.optimize(WANTvalue); @@ -1391,7 +1392,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) version (none) { - printf("init: %s\n", _init.toChars()); + printf("init: %s\n", toChars(_init)); printf("condition: %s\n", condition.toChars()); printf("increment: %s\n", increment.toChars()); printf("body: %s\n", forbody.toChars()); @@ -1779,7 +1780,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) if (!se) return setError(); - if (global.params.verbose) + if (global.params.v.verbose) { message("library %.*s", cast(int)se.len, se.string); } @@ -1868,6 +1869,37 @@ Statement statementSemanticVisit(Statement s, Scope* sc) return; } + if (ss.param) + { + /** + * If the switch statement is of form `switch(auto a = exp) { body }`, + * rewrite to the following inside it's own scope: + * + * auto a = exp + * switch(a) + * { body } + */ + auto statements = new Statements(); + auto vardecl = new VarDeclaration(ss.param.loc, + ss.param.type, + ss.param.ident, + new ExpInitializer(ss.condition.loc, ss.condition), + ss.param.storageClass); + + statements.push(new ExpStatement(ss.param.loc, vardecl)); + + ss.condition = new VarExp(ss.param.loc, vardecl, false); + ss.param = null; + + statements.push(ss); + + Statement s = new CompoundStatement(ss.loc, statements); + s = new ScopeStatement(ss.loc, s, ss.endloc); + s = s.statementSemantic(sc); + result = s; + return; + } + bool conditionError = false; ss.condition = ss.condition.expressionSemantic(sc); ss.condition = resolveProperties(sc, ss.condition); @@ -1979,9 +2011,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) if (ed && ss.cases.length < ed.members.length) { int missingMembers = 0; - const maxShown = !global.params.verbose ? - (global.params.errorSupplementLimit ? global.params.errorSupplementLimit : int.max) - : int.max; + const maxShown = global.params.v.errorSupplementCount(); Lmembers: foreach (es; *ed.members) { @@ -2014,11 +2044,10 @@ Statement statementSemanticVisit(Statement s, Scope* sc) needswitcherror = true; } - if (!sc.sw.sdefault && - (!ss.isFinal || needswitcherror || global.params.useAssert == CHECKENABLE.on || sc.func.isSafe)) + ss.hasDefault = sc.sw.sdefault || + !(!ss.isFinal || needswitcherror || global.params.useAssert == CHECKENABLE.on || sc.func.isSafe); + if (!ss.hasDefault) { - ss.hasNoDefault = 1; - if (!ss.isFinal && (!ss._body || !ss._body.isErrorStatement()) && !(sc.flags & SCOPE.Cfile)) error(ss.loc, "`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`"); @@ -2207,7 +2236,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) /* Flag that we need to do special code generation * for this, i.e. generate a sequence of if-then-else */ - sw.hasVars = 1; + sw.hasVars = true; /* TODO check if v can be uninitialized at that point. */ @@ -2633,7 +2662,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) //errors = true; } if (global.endGagging(olderrors)) - rs.exp.deprecation("`%s` has no effect", rs.exp.toChars()); + deprecation(rs.exp.loc, "`%s` has no effect", rs.exp.toChars()); /* Replace: * return exp; @@ -2708,7 +2737,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) // checking for `shared`, make sure we were right if (global.params.noSharedAccess == FeatureState.enabled && rs.exp.type.isShared()) { - fd.error("function returns `shared` but cannot be inferred `ref`"); + .error(fd.loc, "%s `%s` function returns `shared` but cannot be inferred `ref`", fd.kind, fd.toPrettyChars); supplemental(); } } @@ -3992,7 +4021,7 @@ private extern(D) Statement loopReturn(Expression e, Statements* cases, const re } s = new CompoundStatement(loc, a); - return new SwitchStatement(loc, e, s, false); + return new SwitchStatement(loc, null, e, s, false, loc); } /************************************* @@ -4547,13 +4576,13 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState { if (!isStatic) { - error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars()); + error(fs.loc, "constant value `%s` cannot be `ref`", toChars(ie)); } else { if (!needExpansion) { - error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars()); + error(fs.loc, "constant value `%s` cannot be `ref`", toChars(ie)); } else { @@ -4858,7 +4887,7 @@ private Statements* flatten(Statement statement, Scope* sc) const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; auto loc = adjustLocForMixin(str, cs.loc, global.params.mixinOut); scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); - p.transitionIn = global.params.vin; + p.transitionIn = global.params.v.vin; p.nextToken(); auto a = new Statements(); @@ -5053,3 +5082,130 @@ bool pragmaStartAddressSemantic(Loc loc, Scope* sc, Expressions* args) } return true; } + +/************************************ + * Check for skipped variable declarations. + * Params: + * ss = statement to check + * Returns: + * true if error + */ +private bool checkLabel(SwitchStatement ss) +{ + /* + * Checks the scope of a label for existing variable declaration. + * Params: + * vd = last variable declared before this case/default label + * Returns: `true` if the variables declared in this label would be skipped. + */ + bool checkVar(VarDeclaration vd) + { + for (auto v = vd; v && v != ss.lastVar; v = v.lastVar) + { + if (v.isDataseg() || (v.storage_class & (STC.manifest | STC.temp) && vd.ident != Id.withSym) || v._init.isVoidInitializer()) + continue; + if (vd.ident == Id.withSym) + error(ss.loc, "`switch` skips declaration of `with` temporary"); + else + error(ss.loc, "`switch` skips declaration of variable `%s`", v.toPrettyChars()); + errorSupplemental(v.loc, "declared here"); + return true; + } + return false; + } + + enum error = true; + + if (ss.sdefault && checkVar(ss.sdefault.lastVar)) + return !error; // return error once fully deprecated + + foreach (scase; *ss.cases) + { + if (scase && checkVar(scase.lastVar)) + return !error; // return error once fully deprecated + } + return !error; +} + + +/************** + * Check for skipped variable declarations. + * Params: + * gs = statement to check + * Returns: true for error + */ +bool checkLabel(GotoStatement gs) +{ + if (!gs.label.statement) + return true; // error should have been issued for this already + + if (gs.label.statement.os != gs.os) + { + if (gs.os && gs.os.tok == TOK.onScopeFailure && !gs.label.statement.os) + { + // Jump out from scope(failure) block is allowed. + } + else + { + if (gs.label.statement.os) + error(gs.loc, "cannot `goto` in to `%s` block", Token.toChars(gs.label.statement.os.tok)); + else + error(gs.loc, "cannot `goto` out of `%s` block", Token.toChars(gs.os.tok)); + return true; + } + } + + if (gs.label.statement.tf != gs.tf) + { + error(gs.loc, "cannot `goto` in or out of `finally` block"); + return true; + } + + if (gs.label.statement.inCtfeBlock && !gs.inCtfeBlock) + { + error(gs.loc, "cannot `goto` into `if (__ctfe)` block"); + return true; + } + + Statement stbnext; + for (auto stb = gs.tryBody; stb != gs.label.statement.tryBody; stb = stbnext) + { + if (!stb) + { + error(gs.loc, "cannot `goto` into `try` block"); + return true; + } + if (auto stf = stb.isTryFinallyStatement()) + stbnext = stf.tryBody; + else if (auto stc = stb.isTryCatchStatement()) + stbnext = stc.tryBody; + else + assert(0); + } + + VarDeclaration vd = gs.label.statement.lastVar; + if (!vd || vd.isDataseg() || (vd.storage_class & STC.manifest)) + return false; + + VarDeclaration last = gs.lastVar; + while (last && last != vd) + last = last.lastVar; + if (last == vd) + { + // All good, the label's scope has no variables + } + else if (vd.storage_class & STC.exptemp) + { + // Lifetime ends at end of expression, so no issue with skipping the statement + } + else + { + if (vd.ident == Id.withSym) + error(gs.loc, "`goto` skips declaration of `with` temporary"); + else + error(gs.loc, "`goto` skips declaration of variable `%s`", vd.toPrettyChars()); + errorSupplemental(vd.loc, "declared here"); + return true; + } + return false; +} diff --git a/gcc/d/dmd/staticcond.d b/gcc/d/dmd/staticcond.d index aa6f37ca67b4..45e777375a04 100644 --- a/gcc/d/dmd/staticcond.d +++ b/gcc/d/dmd/staticcond.d @@ -111,7 +111,8 @@ bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool const opt = e.toBool(); if (opt.isEmpty()) { - e.error("expression `%s` is not constant", e.toChars()); + if (!e.type.isTypeError()) + error(e.loc, "expression `%s` is not constant", e.toChars()); errors = true; return false; } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 2bde9f2aee9b..bdc569c87259 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -337,7 +337,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Expression dimError(int expected) { - e.error("expected %d arguments for `%s` but had %d", expected, e.ident.toChars(), cast(int)dim); + error(e.loc, "expected %d arguments for `%s` but had %d", expected, e.ident.toChars(), cast(int)dim); return ErrorExp.get(); } @@ -500,7 +500,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto t = isType(o); if (!t) { - e.error("type expected as second argument of __traits `%s` instead of `%s`", + error(e.loc, "type expected as second argument of __traits `%s` instead of `%s`", e.ident.toChars(), o.toChars()); return ErrorExp.get(); } @@ -521,7 +521,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto t = isType(o); if (!t) { - e.error("type expected as second argument of __traits `%s` instead of `%s`", + error(e.loc, "type expected as second argument of __traits `%s` instead of `%s`", e.ident.toChars(), o.toChars()); return ErrorExp.get(); } @@ -543,7 +543,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto t = isType(o); if (!t) { - e.error("type expected as second argument of __traits `%s` instead of `%s`", + error(e.loc, "type expected as second argument of __traits `%s` instead of `%s`", e.ident.toChars(), o.toChars()); return ErrorExp.get(); } @@ -577,7 +577,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) return fd.isNested() ? True() : False(); } - e.error("aggregate or function expected instead of `%s`", o.toChars()); + error(e.loc, "aggregate or function expected instead of `%s`", o.toChars()); return ErrorExp.get(); } if (e.ident == Id.isDisabled) @@ -598,7 +598,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { // @@@DEPRECATED2.121@@@ // Deprecated in 2.101 - Can be removed from 2.121 - e.deprecation("`traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead"); + deprecation(e.loc, "`traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead"); if (dim != 1) return dimError(1); @@ -686,7 +686,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (!po.ident) { - e.error("argument `%s` has no identifier", po.type.toChars()); + error(e.loc, "argument `%s` has no identifier", po.type.toChars()); return ErrorExp.get(); } id = po.ident; @@ -696,7 +696,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Dsymbol s = getDsymbolWithoutExpCtx(o); if (!s || !s.ident) { - e.error("argument `%s` has no identifier", o.toChars()); + error(e.loc, "argument `%s` has no identifier", o.toChars()); return ErrorExp.get(); } id = s.ident; @@ -733,7 +733,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) else { if (!isError(o)) - e.error("argument `%s` has no identifier", o.toChars()); + error(e.loc, "argument `%s` has no identifier", o.toChars()); return ErrorExp.get(); } assert(fqn); @@ -758,7 +758,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (!s) { if (!isError(o)) - e.error("argument `%s` has no visibility", o.toChars()); + error(e.loc, "argument `%s` has no visibility", o.toChars()); return ErrorExp.get(); } if (s.semanticRun == PASS.initial) @@ -809,7 +809,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } if (!s || s.isImport()) { - e.error("argument `%s` has no parent", o.toChars()); + error(e.loc, "argument `%s` has no parent", o.toChars()); return ErrorExp.get(); } @@ -845,7 +845,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) ex = exp; else { - e.error("symbol or expression expected as first argument of __traits `child` instead of `%s`", op.toChars()); + error(e.loc, "symbol or expression expected as first argument of __traits `child` instead of `%s`", op.toChars()); return ErrorExp.get(); } @@ -854,7 +854,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto symc = getDsymbol(oc); if (!symc) { - e.error("symbol expected as second argument of __traits `child` instead of `%s`", oc.toChars()); + error(e.loc, "symbol expected as second argument of __traits `child` instead of `%s`", oc.toChars()); return ErrorExp.get(); } @@ -878,7 +878,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto ex = isExpression((*e.args)[0]); if (!ex) { - e.error("expression expected as second argument of __traits `%s`", e.ident.toChars()); + error(e.loc, "expression expected as second argument of __traits `%s`", e.ident.toChars()); return ErrorExp.get(); } ex = ex.ctfeInterpret(); @@ -891,7 +891,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Type t = decoToType(se.toUTF8(sc).peekString()); if (!t) { - e.error("cannot determine `%s`", e.toChars()); + error(e.loc, "cannot determine `%s`", e.toChars()); return ErrorExp.get(); } return (new TypeExp(e.loc, t)).expressionSemantic(sc); @@ -909,7 +909,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto ex = isExpression((*e.args)[1]); if (!ex) { - e.error("expression expected as second argument of __traits `%s`", e.ident.toChars()); + error(e.loc, "expression expected as second argument of __traits `%s`", e.ident.toChars()); return ErrorExp.get(); } ex = ex.ctfeInterpret(); @@ -921,7 +921,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) b = b.ctfeInterpret(); if (!b.type.equals(Type.tbool)) { - e.error("`bool` expected as third argument of `__traits(getOverloads)`, not `%s` of type `%s`", b.toChars(), b.type.toChars()); + error(e.loc, "`bool` expected as third argument of `__traits(getOverloads)`, not `%s` of type `%s`", b.toChars(), b.type.toChars()); return ErrorExp.get(); } includeTemplates = b.toBool().get(); @@ -930,14 +930,14 @@ Expression semanticTraits(TraitsExp e, Scope* sc) StringExp se = ex.toStringExp(); if (!se || se.len == 0) { - e.error("string expected as second argument of __traits `%s` instead of `%s`", e.ident.toChars(), ex.toChars()); + error(e.loc, "string expected as second argument of __traits `%s` instead of `%s`", e.ident.toChars(), ex.toChars()); return ErrorExp.get(); } se = se.toUTF8(sc); if (se.sz != 1) { - e.error("string must be chars"); + error(e.loc, "string must be chars"); return ErrorExp.get(); } auto id = Identifier.idPool(se.peekString()); @@ -972,7 +972,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) ex = new DotIdExp(e.loc, ex2, id); else { - e.error("invalid first argument"); + error(e.loc, "invalid first argument"); return ErrorExp.get(); } doSemantic: @@ -1004,13 +1004,13 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Expression eorig = ex; ex = ex.expressionSemantic(scx); if (errors < global.errors) - e.error("`%s` cannot be resolved", eorig.toChars()); + error(e.loc, "`%s` cannot be resolved", eorig.toChars()); if (e.ident == Id.getVirtualFunctions) { // @@@DEPRECATED2.121@@@ // Deprecated in 2.101 - Can be removed from 2.121 - e.deprecation("`traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead"); + deprecation(e.loc, "`traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead"); } /* Create tuple of functions of ex @@ -1165,7 +1165,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto cd = s ? s.isClassDeclaration() : null; if (!cd) { - e.error("first argument is not a class"); + error(e.loc, "first argument is not a class"); return ErrorExp.get(); } if (cd.sizeok != Sizeok.done) @@ -1174,7 +1174,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } if (cd.sizeok != Sizeok.done) { - e.error("%s `%s` is forward referenced", cd.kind(), cd.toChars()); + error(e.loc, "%s `%s` is forward referenced", cd.kind(), cd.toChars()); return ErrorExp.get(); } @@ -1260,7 +1260,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (t) printf("t = %d %s\n", t.ty, t.toChars()); } - e.error("first argument is not a symbol"); + error(e.loc, "first argument is not a symbol"); return ErrorExp.get(); } @@ -1281,7 +1281,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (!tf) { - e.error("first argument is not a function"); + error(e.loc, "first argument is not a function"); return ErrorExp.get(); } @@ -1324,7 +1324,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (!tf) { - e.error("argument to `__traits(isReturnOnStack, %s)` is not a function", o.toChars()); + error(e.loc, "argument to `__traits(isReturnOnStack, %s)` is not a function", o.toChars()); return ErrorExp.get(); } @@ -1360,7 +1360,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (!fd) { - e.error("argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars()); + error(e.loc, "argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars()); return ErrorExp.get(); } link = fd._linkage; @@ -1411,7 +1411,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) fparams = fd.getParameterList(); else { - e.error("first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function or a function call", + error(e.loc, "first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function or a function call", o.toChars(), o1.toChars()); return ErrorExp.get(); } @@ -1427,7 +1427,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto ex = isExpression((*e.args)[1]); if (!ex) { - e.error("expression expected as second argument of `__traits(getParameterStorageClasses, %s, %s)`", + error(e.loc, "expression expected as second argument of `__traits(getParameterStorageClasses, %s, %s)`", o.toChars(), o1.toChars()); return ErrorExp.get(); } @@ -1435,7 +1435,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto ii = ex.toUInteger(); if (ii >= fparams.length) { - e.error("parameter index must be in range 0..%u not %s", cast(uint)fparams.length, ex.toChars()); + error(e.loc, "parameter index must be in range 0..%u not %s", cast(uint)fparams.length, ex.toChars()); return ErrorExp.get(); } @@ -1507,7 +1507,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) AggregateDeclaration agg; if (!s || ((d = s.isDeclaration()) is null && (agg = s.isAggregateDeclaration()) is null)) { - e.error("argument to `__traits(getLinkage, %s)` is not a declaration", o.toChars()); + error(e.loc, "argument to `__traits(getLinkage, %s)` is not a declaration", o.toChars()); return ErrorExp.get(); } @@ -1521,7 +1521,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) agg.size(e.loc); if (agg.sizeok != Sizeok.done) { - e.error("%s `%s` is forward referenced", agg.kind(), agg.toChars()); + error(e.loc, "%s `%s` is forward referenced", agg.kind(), agg.toChars()); return ErrorExp.get(); } } @@ -1557,8 +1557,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto s = getDsymbol(o); if (!s) { - e.error("in expression `%s` `%s` can't have members", e.toChars(), o.toChars()); - e.errorSupplemental("`%s` must evaluate to either a module, a struct, an union, a class, an interface or a template instantiation", o.toChars()); + error(e.loc, "in expression `%s` `%s` can't have members", e.toChars(), o.toChars()); + errorSupplemental(e.loc, "`%s` must evaluate to either a module, a struct, an union, a class, an interface or a template instantiation", o.toChars()); return ErrorExp.get(); } @@ -1580,8 +1580,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto sds = s.isScopeDsymbol(); if (!sds || sds.isTemplateDeclaration()) { - e.error("in expression `%s` %s `%s` has no members", e.toChars(), s.kind(), s.toChars()); - e.errorSupplemental("`%s` must evaluate to either a module, a struct, an union, a class, an interface or a template instantiation", s.toChars()); + error(e.loc, "in expression `%s` %s `%s` has no members", e.toChars(), s.kind(), s.toChars()); + errorSupplemental(e.loc, "`%s` must evaluate to either a module, a struct, an union, a class, an interface or a template instan[...] [diff truncated at 524288 bytes]